|
@@ -1,7 +1,7 @@
|
|
|
#include <linux/kernel.h>
|
|
|
-#include <linux/module.h>
|
|
|
-#include <linux/platform_device.h>
|
|
|
-#include <linux/io.h>
|
|
|
+#include <linux/module.h>
|
|
|
+#include <linux/platform_device.h>
|
|
|
+#include <linux/io.h>
|
|
|
#include <linux/iio/iio.h>
|
|
|
#include <linux/iio/machine.h>
|
|
|
#include <linux/iio/driver.h>
|
|
@@ -15,13 +15,8 @@
|
|
|
#include <linux/clk.h>
|
|
|
#include <linux/completion.h>
|
|
|
|
|
|
-
|
|
|
-enum ADC_MODE{
|
|
|
- ARK_ADC_MODE_NONE,
|
|
|
- ARK_ADC_MODE_BATTERY,
|
|
|
- ARK_ADC_MODE_KEY,
|
|
|
- ARK_ADC_MODE_END,
|
|
|
-};
|
|
|
+#define ADC_CHANNEL_MAX_NUMS 8
|
|
|
+#define ADC_ARK1668E_CHANNEL_NUM 4
|
|
|
|
|
|
struct ark_adc {
|
|
|
struct ark_adc_data *data;
|
|
@@ -31,9 +26,8 @@ struct ark_adc {
|
|
|
struct clk *clk;
|
|
|
struct completion completion;
|
|
|
u32 irq;
|
|
|
- u32 mode[4]; //adc channel[n] mode(battery, key, ...)
|
|
|
- u32 value1[4]; //adc channel[n] temp value
|
|
|
- u32 value2[4]; //adc channel[n] final value
|
|
|
+ bool pull_down;
|
|
|
+ u32 value[ADC_CHANNEL_MAX_NUMS];
|
|
|
};
|
|
|
|
|
|
struct ark_adc_data {
|
|
@@ -46,40 +40,29 @@ struct ark_adc_data {
|
|
|
void (*start_conv)(struct ark_adc *info, unsigned long addr);
|
|
|
};
|
|
|
|
|
|
-#define BAT_CHANNEL 1
|
|
|
-#define TOUCHPAN_CHANNEL 2
|
|
|
-#define AUX0_CHANNEL 3
|
|
|
-#define AUX1_CHANNEL 4
|
|
|
-#define AUX2_CHANNEL 5
|
|
|
-#define AUX3_CHANNEL 6
|
|
|
-
|
|
|
-#define AUX0_START_INT (1<<0)
|
|
|
-#define AUX0_STOP_INT (1<<1)
|
|
|
-#define AUX0_VALUE_INT (1<<2)
|
|
|
-#define AUX1_START_INT (1<<3)
|
|
|
-#define AUX1_STOP_INT (1<<4)
|
|
|
-#define AUX1_VALUE_INT (1<<5)
|
|
|
-#define AUX2_START_INT (1<<6)
|
|
|
-#define AUX2_STOP_INT (1<<7)
|
|
|
-#define AUX2_VALUE_INT (1<<8)
|
|
|
-#define AUX3_START_INT (1<<9)
|
|
|
-#define AUX3_STOP_INT (1<<10)
|
|
|
-#define AUX3_VALUE_INT (1<<11)
|
|
|
-
|
|
|
-#define AUX_START_INT(ch) (1 << ((ch)*3 + 0))
|
|
|
-#define AUX_STOP_INT(ch) (1 << ((ch)*3 + 1))
|
|
|
-#define AUX_VALUE_INT(ch) (1 << ((ch)*3 + 2))
|
|
|
-
|
|
|
-#define ARK1668_ADC_CHANNEL_MAX_NUMS 4
|
|
|
-#define ARK1668E_ADC_CHANNEL_MAX_NUMS 4
|
|
|
-#define ARKN141_ADC_CHANNEL_MAX_NUMS 2
|
|
|
+#define ADC_CTL0 0x0
|
|
|
+#define ADC_CTL1 0x4
|
|
|
+#define ADC_IMR 0x8
|
|
|
+#define ADC_STA 0xc
|
|
|
+#define ADC_INTER 0x10
|
|
|
+#define ADC_DBNCNT 0x14
|
|
|
+#define ADC_AUX10 0x18
|
|
|
+#define ADC_AUX32 0x1c
|
|
|
+#define ADC_AUX54 0x20
|
|
|
+#define ADC_AUX76 0x24
|
|
|
+
|
|
|
+#define AUX_START_INT(ch) (1 << ((ch) * 3 + 0))
|
|
|
+#define AUX_STOP_INT(ch) (1 << ((ch) * 3 + 1))
|
|
|
+#define AUX_VALUE_INT(ch) (1 << ((ch) * 3 + 2))
|
|
|
+
|
|
|
+#define AUX_START_INTMASK(ch) (1 << ((ch) + 0))
|
|
|
+#define AUX_STOP_INTMASK(ch) (1 << ((ch) + 8))
|
|
|
+#define AUX_VALUE_INTMASK(ch) (1 << ((ch) + 16))
|
|
|
+
|
|
|
#define ARK_ADC_DATX_MASK_12BIT 0xFFF
|
|
|
#define ARK_ADC_DATX_MASK_10BIT 0x3FF
|
|
|
-#define ARK_BATTERY_VOLTAGE_REF 3300// 3.3V
|
|
|
-#define ARK_ADC_TIMEOUT (msecs_to_jiffies(100))
|
|
|
-#define ARK_ADC_USE_PULL_UP_REGISTER //ADC connect pull up register, have interrupe when voltage in 0V ~ 3V
|
|
|
-//#define ARK_ADC_USE_PULL_DOWM_REGISTER //ADC connect pull dowm register, have interrupt when voltage in 0.3V ~ 3.3V
|
|
|
-
|
|
|
+#define ARK_ADC_VOLTAGE_REF 3300// 3.3V
|
|
|
+#define ARK_ADC_TIMEOUT (msecs_to_jiffies(20))
|
|
|
|
|
|
|
|
|
#define ADC_CHANNEL(_index, _id) { \
|
|
@@ -98,22 +81,60 @@ static const struct iio_chan_spec ark_adc_iio_channels[] = {
|
|
|
ADC_CHANNEL(3, "adc3"),
|
|
|
};
|
|
|
|
|
|
+static u32 ark1668e_get_aux_value(struct ark_adc *info, unsigned int ch)
|
|
|
+{
|
|
|
+ u32 val;
|
|
|
+
|
|
|
+ val = readl(info->adc_base + ADC_AUX10 + ch / 2 * 4);
|
|
|
+ if (ch & 1)
|
|
|
+ val = (val >> 16) & 0xfff;
|
|
|
+ else
|
|
|
+ val = val & 0xfff;
|
|
|
+
|
|
|
+ return val;
|
|
|
+}
|
|
|
+
|
|
|
+static void ark1668e_adc_disable_channel(struct ark_adc *info, unsigned int ch)
|
|
|
+{
|
|
|
+ u32 val;
|
|
|
+
|
|
|
+ if (ch >= ADC_CHANNEL_MAX_NUMS)
|
|
|
+ return;
|
|
|
+
|
|
|
+ val = readl(info->adc_base + ADC_CTL0);
|
|
|
+ val &= ~(1 << ch);
|
|
|
+ writel(val, info->adc_base + ADC_CTL0);
|
|
|
+}
|
|
|
+
|
|
|
+static void ark1668e_adc_enable_channel(struct ark_adc *info, unsigned int ch)
|
|
|
+{
|
|
|
+ u32 val;
|
|
|
+
|
|
|
+ if (ch >= ADC_CHANNEL_MAX_NUMS)
|
|
|
+ return;
|
|
|
+
|
|
|
+ val = readl(info->adc_base + ADC_CTL0);
|
|
|
+ val |= 1 << ch;
|
|
|
+ writel(val, info->adc_base + ADC_CTL0);
|
|
|
+}
|
|
|
+
|
|
|
static int ark_adc_reg_access(struct iio_dev *indio_dev,
|
|
|
unsigned reg, unsigned writeval,
|
|
|
unsigned *readval)
|
|
|
{
|
|
|
- //struct ark_adc *info = iio_priv(indio_dev);
|
|
|
- //printk(KERN_ALERT "### ark_adc_reg_access\n");
|
|
|
+ struct ark_adc *info = iio_priv(indio_dev);
|
|
|
+ u32 val;
|
|
|
|
|
|
- if (!readval)
|
|
|
- return -EINVAL;
|
|
|
-
|
|
|
- //*readval = readl(info->adc_base + reg);
|
|
|
+ if (readval != NULL) {
|
|
|
+ val = readl(info->adc_base + reg);
|
|
|
+ *readval = val;
|
|
|
+ } else {
|
|
|
+ writel(val, info->adc_base + reg);
|
|
|
+ }
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
static int ark_read_raw(struct iio_dev *indio_dev,
|
|
|
struct iio_chan_spec const *chan,
|
|
|
int *val,
|
|
@@ -123,28 +144,25 @@ static int ark_read_raw(struct iio_dev *indio_dev,
|
|
|
struct ark_adc *info = iio_priv(indio_dev);
|
|
|
unsigned long timeout;
|
|
|
int ret = 0;
|
|
|
-
|
|
|
+
|
|
|
mutex_lock(&indio_dev->mlock);
|
|
|
reinit_completion(&info->completion);
|
|
|
-
|
|
|
+
|
|
|
/* Select the channel to be used and Trigger conversion */
|
|
|
if (info->data->start_conv)
|
|
|
info->data->start_conv(info, chan->address);
|
|
|
|
|
|
timeout = wait_for_completion_timeout(&info->completion, ARK_ADC_TIMEOUT);
|
|
|
-
|
|
|
- if (timeout == 0) {
|
|
|
- dev_warn(&indio_dev->dev, "Conversion timed out! Resetting\n");
|
|
|
- if (info->data->init_hw)
|
|
|
- info->data->init_hw(info);
|
|
|
- ret = -ETIMEDOUT;
|
|
|
- } else {
|
|
|
- *val = info->value2[chan->address];
|
|
|
- *val2 = 0;
|
|
|
- ret = IIO_VAL_INT;
|
|
|
- }
|
|
|
+ if (timeout == 0)
|
|
|
+ dev_warn(&indio_dev->dev, "Conversion timed out!\n");
|
|
|
+
|
|
|
+ *val = info->value[chan->address];
|
|
|
+ *val2 = 0;
|
|
|
+ ret = IIO_VAL_INT;
|
|
|
+
|
|
|
+ ark1668e_adc_disable_channel(info, chan->address);
|
|
|
+
|
|
|
mutex_unlock(&indio_dev->mlock);
|
|
|
- //printk(KERN_ALERT "### READ :%d\n", readl(info->adc_base+0x14));
|
|
|
|
|
|
return ret;
|
|
|
}
|
|
@@ -158,60 +176,63 @@ static void ark1668e_adc_init_hw(struct ark_adc *info)
|
|
|
{
|
|
|
unsigned int val;
|
|
|
|
|
|
- val = readl(info->sys_base+0x74);
|
|
|
- val |= (1 << 2);
|
|
|
- writel(val, info->sys_base+0x74);
|
|
|
-
|
|
|
-
|
|
|
- val = readl(info->adc_base+0x4);
|
|
|
- val |= (0x3f<<16);
|
|
|
- writel(val, info->adc_base+0x4);
|
|
|
-
|
|
|
- val = readl(info->adc_base+0x0);
|
|
|
- val &=~(1<<31);
|
|
|
- writel(val, info->adc_base+0x0);
|
|
|
- val |=1<<26;
|
|
|
- writel(val, info->adc_base+0x0);
|
|
|
- val |=0xff;
|
|
|
- writel(val, info->adc_base+0x0);
|
|
|
- val |=0xff << 16;
|
|
|
- writel(val, info->adc_base+0x0);
|
|
|
-
|
|
|
- val = readl(info->adc_base+0x10);
|
|
|
- val |= 0xffff;
|
|
|
- writel(val, info->adc_base+0x10);
|
|
|
-
|
|
|
- val = readl(info->adc_base+0x08);
|
|
|
- val &=~0xffffff;
|
|
|
- writel(val, info->adc_base+0x08);
|
|
|
-
|
|
|
+ //soft reset
|
|
|
+ val = readl(info->sys_base + 0x74);
|
|
|
+ val &= ~(1 << 2);
|
|
|
+ writel(val, info->sys_base + 0x74);
|
|
|
+ udelay(1);
|
|
|
+ val |= 1 << 2;
|
|
|
+ writel(val, info->sys_base + 0x74);
|
|
|
+ udelay(1);
|
|
|
+
|
|
|
+ val = readl(info->adc_base + ADC_CTL1);
|
|
|
+ val |= 0x3f << 16;
|
|
|
+ writel(val, info->adc_base + ADC_CTL1);
|
|
|
+
|
|
|
+ val = readl(info->adc_base + ADC_CTL0);
|
|
|
+ val &= ~(1 << 31);
|
|
|
+ val &= ~0xff;
|
|
|
+ val |= 0xff << 16;
|
|
|
+ writel(val, info->adc_base + ADC_CTL0);
|
|
|
+
|
|
|
+ //set transform interval 10ms
|
|
|
+ val = readl(info->adc_base + ADC_INTER);
|
|
|
+ val &= ~0xffff;;
|
|
|
+ val |= 10000;
|
|
|
+ writel(val, info->adc_base + ADC_INTER);
|
|
|
+
|
|
|
+ //enable interrupt
|
|
|
+ writel(0x0, info->adc_base + ADC_IMR);
|
|
|
}
|
|
|
|
|
|
static void ark1668e_adc_exit_hw(struct ark_adc *info)
|
|
|
{
|
|
|
//printk(KERN_ALERT "### exit\n");
|
|
|
-
|
|
|
+
|
|
|
}
|
|
|
|
|
|
static void ark1668e_adc_start_conv(struct ark_adc *info, unsigned long addr)
|
|
|
{
|
|
|
- u32 value = info->value1[addr];
|
|
|
+ int i;
|
|
|
+
|
|
|
+ if (addr >= ADC_CHANNEL_MAX_NUMS)
|
|
|
+ return;
|
|
|
|
|
|
-#ifdef ARK_ADC_USE_PULL_UP_REGISTER
|
|
|
- if((value >= 0) && (value <= 3000))
|
|
|
- info->value2[addr] = value;
|
|
|
+ if (info->pull_down)
|
|
|
+ info->value[addr] = 0;
|
|
|
else
|
|
|
- info->value2[addr] = ARK_BATTERY_VOLTAGE_REF;
|
|
|
- info->value1[addr] = ARK_BATTERY_VOLTAGE_REF;
|
|
|
-#else
|
|
|
- info->value2[addr] = value;
|
|
|
-#endif
|
|
|
-
|
|
|
- complete(&info->completion);
|
|
|
+ info->value[addr] = ARK_ADC_VOLTAGE_REF;
|
|
|
+
|
|
|
+ for (i = 0; i < ADC_CHANNEL_MAX_NUMS; i++) {
|
|
|
+ if (i == addr)
|
|
|
+ ark1668e_adc_enable_channel(info, i);
|
|
|
+ else
|
|
|
+ ark1668e_adc_disable_channel(info, i);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
static const struct ark_adc_data ark1668e_adc_data = {
|
|
|
- .num_channels = ARK1668E_ADC_CHANNEL_MAX_NUMS,
|
|
|
+ .num_channels = ADC_ARK1668E_CHANNEL_NUM,
|
|
|
.mask = ARK_ADC_DATX_MASK_12BIT,
|
|
|
.init_hw = ark1668e_adc_init_hw,
|
|
|
.exit_hw = ark1668e_adc_exit_hw,
|
|
@@ -231,160 +252,40 @@ MODULE_DEVICE_TABLE(of, ark_adc_match);
|
|
|
static struct ark_adc_data *ark_adc_get_data(struct platform_device *pdev)
|
|
|
{
|
|
|
const struct of_device_id *match = of_match_node(ark_adc_match, pdev->dev.of_node);
|
|
|
-
|
|
|
+
|
|
|
return (struct ark_adc_data *)match->data;
|
|
|
}
|
|
|
|
|
|
static irqreturn_t ark_adc_intr_handler(int irq, void *dev_id)
|
|
|
{
|
|
|
struct ark_adc *info = (struct ark_adc *)dev_id;
|
|
|
- u32 val,range,status;
|
|
|
- //printk(KERN_ALERT "++++++ark_adc_intr_handler entry\n");
|
|
|
-
|
|
|
- status = readl(info->adc_base+0x0c);
|
|
|
-
|
|
|
- if(status&(1<<23))
|
|
|
- {
|
|
|
- val = readl(info->adc_base+0x24);
|
|
|
- //printk(KERN_ALERT "aux7 value is 0x%x\r\n",(val>>16)&0xfff);
|
|
|
- val = ~(1<<23);
|
|
|
- writel(val, info->adc_base+0x0c);
|
|
|
- }
|
|
|
- if(status&(1<<22))
|
|
|
- {
|
|
|
- val = ~(1<<22);
|
|
|
- writel(val, info->adc_base+0x0c);
|
|
|
- }
|
|
|
- if(status&(1<<21))
|
|
|
- {
|
|
|
- val = ~(1<<21);
|
|
|
- writel(val, info->adc_base+0x0c);
|
|
|
- }
|
|
|
- if(status&(1<<20))
|
|
|
- {
|
|
|
- val = readl(info->adc_base+0x24);
|
|
|
- //printk(KERN_ALERT "aux6 value is 0x%x\r\n",(val)&0xfff);
|
|
|
- val = ~(1<<20);
|
|
|
- writel(val, info->adc_base+0x0c);
|
|
|
- }
|
|
|
- if(status&(1<<19))
|
|
|
- {
|
|
|
- val = ~(1<<19);
|
|
|
- writel(val, info->adc_base+0x0c);
|
|
|
- }
|
|
|
- if(status&(1<<18))
|
|
|
- {
|
|
|
- val = ~(1<<18);
|
|
|
- writel(val, info->adc_base+0x0c);
|
|
|
- }
|
|
|
- if(status&(1<<17))
|
|
|
- {
|
|
|
- val = readl(info->adc_base+0x20);
|
|
|
- //printk(KERN_ALERT "aux5 value is 0x%x\r\n",(val>>16)&0xfff);
|
|
|
- val = ~(1<<17);
|
|
|
- writel(val, info->adc_base+0x0c);
|
|
|
- }
|
|
|
- if(status&(1<<16))
|
|
|
- {
|
|
|
- val = ~(1<<16);
|
|
|
- writel(val, info->adc_base+0x0c);
|
|
|
- }
|
|
|
- if(status&(1<<15))
|
|
|
- {
|
|
|
- val = ~(1<<15);
|
|
|
- writel(val, info->adc_base+0x0c);
|
|
|
- }
|
|
|
- if(status&(1<<14))
|
|
|
- {
|
|
|
- val = readl(info->adc_base+0x20);
|
|
|
- //printk(KERN_ALERT "aux4 value is 0x%x\r\n",(val)&0xfff);
|
|
|
- val = ~(1<<14);
|
|
|
- writel(val, info->adc_base+0x0c);
|
|
|
- }
|
|
|
- if(status&(1<<13))
|
|
|
- {
|
|
|
- val = ~(1<<13);
|
|
|
- writel(val, info->adc_base+0x0c);
|
|
|
- }
|
|
|
- if(status&(1<<12))
|
|
|
- {
|
|
|
- val = ~(1<<12);
|
|
|
- writel(val, info->adc_base+0x0c);
|
|
|
- }
|
|
|
- if(status&(1<<11))
|
|
|
- {
|
|
|
- val = readl(info->adc_base+0x1c);
|
|
|
- range = ((info->data->mask==ARK_ADC_DATX_MASK_12BIT) ? 4096 : 1024);
|
|
|
- info->value1[3] = ((val>>16)&0xfff) * ARK_BATTERY_VOLTAGE_REF / range;
|
|
|
- //printk(KERN_ALERT "aux3 value = %d \n",(val>>16)&0xfff);
|
|
|
- val = ~(1<<11);
|
|
|
- writel(val, info->adc_base+0x0c);
|
|
|
- }
|
|
|
- if(status&(1<<10))
|
|
|
- {
|
|
|
- val = ~(1<<10);
|
|
|
- writel(val, info->adc_base+0x0c);
|
|
|
- }
|
|
|
- if(status&(1<<9))
|
|
|
- {
|
|
|
- val = ~(1<<9);
|
|
|
- writel(val, info->adc_base+0x0c);
|
|
|
- }
|
|
|
- if(status&(1<<8))
|
|
|
- {
|
|
|
- val = readl(info->adc_base+0x1c);
|
|
|
- range = ((info->data->mask==ARK_ADC_DATX_MASK_12BIT) ? 4096 : 1024);
|
|
|
- info->value1[2] = ((val)&0xfff) * ARK_BATTERY_VOLTAGE_REF / range;
|
|
|
- val = ~(1<<8);
|
|
|
- writel(val, info->adc_base+0x0c);
|
|
|
-
|
|
|
- }
|
|
|
- if(status&(1<<7))
|
|
|
- {
|
|
|
- val = ~(1<<7);
|
|
|
- writel(val, info->adc_base+0x0c);
|
|
|
- }
|
|
|
- if(status&(1<<6))
|
|
|
- {
|
|
|
- val = ~(1<<6);
|
|
|
- writel(val, info->adc_base+0x0c);
|
|
|
- }
|
|
|
- if(status&(1<<5))
|
|
|
- {
|
|
|
- val = readl(info->adc_base+0x18);
|
|
|
- range = ((info->data->mask==ARK_ADC_DATX_MASK_12BIT) ? 4096 : 1024);
|
|
|
- info->value1[1] = ((val>>16)&0xfff) * ARK_BATTERY_VOLTAGE_REF / range;
|
|
|
- val = ~(1<<5);
|
|
|
- writel(val, info->adc_base+0x0c);
|
|
|
- }
|
|
|
- if(status&(1<<4))
|
|
|
- {
|
|
|
- val = ~(1<<4);
|
|
|
- writel(val, info->adc_base+0x0c);
|
|
|
- }
|
|
|
- if(status&(1<<3))
|
|
|
- {
|
|
|
- val = ~(1<<3);
|
|
|
- writel(val, info->adc_base+0x0c);
|
|
|
- }
|
|
|
- if(status&(1<<2))
|
|
|
- {
|
|
|
- val = readl(info->adc_base+0x18);
|
|
|
- range = ((info->data->mask==ARK_ADC_DATX_MASK_12BIT) ? 4096 : 1024);
|
|
|
- info->value1[0] = ((val)&0xfff) * ARK_BATTERY_VOLTAGE_REF / range;
|
|
|
- //printk(KERN_ALERT "aux0 value = 0x%x,info->value1[0] = %d\n",val&0xfff,info->value1[0]);
|
|
|
- val = ~(1<<2);
|
|
|
- writel(val, info->adc_base+0x0c);
|
|
|
- }
|
|
|
- if(status&(1<<1))
|
|
|
- {
|
|
|
- val = ~(1<<1);
|
|
|
- writel(val, info->adc_base+0x0c);
|
|
|
- }
|
|
|
- if(status&(1<<0))
|
|
|
- {
|
|
|
- val = ~(1<<0);
|
|
|
- writel(val, info->adc_base+0x0c);
|
|
|
+ u32 val, range, status;
|
|
|
+ int i;
|
|
|
+
|
|
|
+ status = readl(info->adc_base + ADC_STA);
|
|
|
+ writel(0, info->adc_base + ADC_STA);
|
|
|
+
|
|
|
+ //printk(KERN_ALERT "++++++ark_adc_intr_handler status=0x%x\n", status);
|
|
|
+ for (i = 0; i < ADC_CHANNEL_MAX_NUMS; i++) {
|
|
|
+ if (status & AUX_START_INT(i)) {
|
|
|
+ //printk(KERN_ALERT "ch%d start int.\n", i);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (status & AUX_STOP_INT(i)) {
|
|
|
+ //printk(KERN_ALERT "ch%d stop int.\n", i);
|
|
|
+ if (info->pull_down)
|
|
|
+ info->value[i] = 0;
|
|
|
+ else
|
|
|
+ info->value[i] = ARK_ADC_VOLTAGE_REF;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (status & AUX_VALUE_INT(i)) {
|
|
|
+ //printk(KERN_ALERT "ch%d value int.\n", i);
|
|
|
+ val = ark1668e_get_aux_value(info, i);
|
|
|
+ range = (info->data->mask == ARK_ADC_DATX_MASK_12BIT) ? 4096 : 1024;
|
|
|
+ info->value[i] = val * ARK_ADC_VOLTAGE_REF / range;
|
|
|
+ complete(&info->completion);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
return IRQ_HANDLED;
|
|
@@ -392,18 +293,19 @@ static irqreturn_t ark_adc_intr_handler(int irq, void *dev_id)
|
|
|
|
|
|
static int ark_adc_probe(struct platform_device *pdev)
|
|
|
{
|
|
|
- //struct device_node *np = pdev->dev.of_node;
|
|
|
+ struct device_node *np = pdev->dev.of_node;
|
|
|
struct iio_dev *indio_dev = NULL;
|
|
|
struct ark_adc *info = NULL;
|
|
|
struct resource *res = NULL;
|
|
|
int ret = -ENODEV;
|
|
|
+ int i;
|
|
|
|
|
|
indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(struct ark_adc));
|
|
|
if (!indio_dev) {
|
|
|
dev_err(&pdev->dev, "failed allocating iio device\n");
|
|
|
return -ENOMEM;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
info = iio_priv(indio_dev);
|
|
|
|
|
|
//get data
|
|
@@ -415,7 +317,7 @@ static int ark_adc_probe(struct platform_device *pdev)
|
|
|
|
|
|
//adc resource
|
|
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
|
|
- info->adc_base= devm_ioremap_resource(&pdev->dev, res);
|
|
|
+ info->adc_base = devm_ioremap_resource(&pdev->dev, res);
|
|
|
if (IS_ERR(info->adc_base)) {
|
|
|
ret = PTR_ERR(info->adc_base);
|
|
|
goto err_resource;
|
|
@@ -427,7 +329,7 @@ static int ark_adc_probe(struct platform_device *pdev)
|
|
|
ret = PTR_ERR(res);
|
|
|
goto err_resource;
|
|
|
}
|
|
|
- //info->sys_base = devm_ioremap_resource(&pdev->dev, res);
|
|
|
+
|
|
|
info->sys_base = ioremap(res->start, resource_size(res));
|
|
|
if (IS_ERR(info->sys_base)) {
|
|
|
ret = PTR_ERR(info->sys_base);
|
|
@@ -442,7 +344,6 @@ static int ark_adc_probe(struct platform_device *pdev)
|
|
|
goto err_irq;
|
|
|
}
|
|
|
|
|
|
- //ret = request_irq(info->irq, ark_adc_intr_handler, 0, dev_name(&pdev->dev), info);
|
|
|
ret = devm_request_irq(
|
|
|
&pdev->dev,
|
|
|
info->irq,
|
|
@@ -456,9 +357,16 @@ static int ark_adc_probe(struct platform_device *pdev)
|
|
|
goto err_irq;
|
|
|
}
|
|
|
|
|
|
+ info->pull_down = of_property_read_bool(np, "pull-down");
|
|
|
+ for (i = 0; i < ADC_CHANNEL_MAX_NUMS; i++) {
|
|
|
+ if (info->pull_down)
|
|
|
+ info->value[i] = 0;
|
|
|
+ else
|
|
|
+ info->value[i] = ARK_ADC_VOLTAGE_REF;
|
|
|
+ }
|
|
|
+
|
|
|
info->dev = &pdev->dev;
|
|
|
- info->value1[0] = info->value1[1] = info->value1[2] = info->value1[3] =ARK_BATTERY_VOLTAGE_REF;
|
|
|
-
|
|
|
+
|
|
|
platform_set_drvdata(pdev, indio_dev);
|
|
|
indio_dev->name = dev_name(&pdev->dev);
|
|
|
indio_dev->dev.parent = &pdev->dev;
|
|
@@ -483,24 +391,16 @@ static int ark_adc_probe(struct platform_device *pdev)
|
|
|
if (info->data->init_hw)
|
|
|
info->data->init_hw(info);
|
|
|
|
|
|
- printk(KERN_ALERT "++++++ark1668e_adc_probe success\n");
|
|
|
+ //printk(KERN_ALERT "++++++ark1668e_adc_probe success\n");
|
|
|
return 0;
|
|
|
|
|
|
-//err_iio:
|
|
|
- iio_device_unregister(indio_dev);
|
|
|
err_iio_device_register:
|
|
|
- //free_irq(info->irq, info);
|
|
|
- //devm_free_irq(&pdev->dev, info->irq, info);
|
|
|
-err_irq:
|
|
|
- //if(info->sys_base)
|
|
|
- // devm_iounmap(&pdev->dev, info->sys_base);
|
|
|
+err_irq:
|
|
|
+ if(info->sys_base)
|
|
|
+ devm_iounmap(&pdev->dev, info->sys_base);
|
|
|
err_resource:
|
|
|
- //if(info->adc_base)
|
|
|
- // devm_iounmap(&pdev->dev, info->adc_base);
|
|
|
err_devm_iio_device_alloc:
|
|
|
- //if(indio_dev)
|
|
|
- // devm_iio_device_free(&pdev->dev, indio_dev);
|
|
|
-
|
|
|
+
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
@@ -511,17 +411,10 @@ static int ark_adc_remove(struct platform_device *pdev)
|
|
|
|
|
|
if(!info)
|
|
|
return -ENODEV;
|
|
|
-
|
|
|
- //device_for_each_child(&indio_dev->dev, NULL, ark_adc_remove_devices);
|
|
|
+
|
|
|
iio_device_unregister(indio_dev);
|
|
|
- //free_irq(info->irq, info);
|
|
|
- //devm_free_irq(&pdev->dev, info->irq, info);
|
|
|
- //if(info->sys_base)
|
|
|
- // devm_iounmap(&pdev->dev, info->sys_base);
|
|
|
- //if(info->adc_base)
|
|
|
- // devm_iounmap(&pdev->dev, info->adc_base);
|
|
|
- //if(indio_dev)
|
|
|
- // devm_iio_device_free(&pdev->dev, indio_dev);
|
|
|
+ if(info->sys_base)
|
|
|
+ devm_iounmap(&pdev->dev, info->sys_base);
|
|
|
|
|
|
return 0;
|
|
|
}
|