aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iio
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2013-05-29 11:39:02 -0400
committerSebastian Andrzej Siewior <bigeasy@linutronix.de>2013-06-12 12:50:23 -0400
commit18926edebcb82ca325abf843293801d4ff43436a (patch)
tree17b4966968b04bc4e61a8ca87ed21642e472f583 /drivers/iio
parent9a28b8834c55f7315fb1a7c487f836472fd37bf9 (diff)
iio: ti_am335x_adc: Allow to specify input line
The TSC part allows to specify the input lines. The IIO part assumes that it usues always the last few, that means if IIO has adc-channels set to 2 it will use channel 6 and 7. However it might make sense to use only 6. This patch changes the device property (which was introduced recently and was never in an official release) in a way that the user can specify which of the AIN lines should be used. In Addition to this, the name is now AINx where x is the channel number i.e. for AIN6 we would have 6. Prior this, it always started counting at 0 which is confusing. In addition to this, it also checks for correct step number during reading and does not rely on proper FIFO depth. Acked-by: Jonathan Cameron <jic23@kernel.org> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Diffstat (limited to 'drivers/iio')
-rw-r--r--drivers/iio/adc/ti_am335x_adc.c57
1 files changed, 37 insertions, 20 deletions
diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
index 307a7c07be47..8ffe52d58829 100644
--- a/drivers/iio/adc/ti_am335x_adc.c
+++ b/drivers/iio/adc/ti_am335x_adc.c
@@ -32,6 +32,8 @@
32struct tiadc_device { 32struct tiadc_device {
33 struct ti_tscadc_dev *mfd_tscadc; 33 struct ti_tscadc_dev *mfd_tscadc;
34 int channels; 34 int channels;
35 u8 channel_line[8];
36 u8 channel_step[8];
35}; 37};
36 38
37static unsigned int tiadc_readl(struct tiadc_device *adc, unsigned int reg) 39static unsigned int tiadc_readl(struct tiadc_device *adc, unsigned int reg)
@@ -57,7 +59,7 @@ static u32 get_adc_step_mask(struct tiadc_device *adc_dev)
57static void tiadc_step_config(struct tiadc_device *adc_dev) 59static void tiadc_step_config(struct tiadc_device *adc_dev)
58{ 60{
59 unsigned int stepconfig; 61 unsigned int stepconfig;
60 int i, channels = 0, steps; 62 int i, steps;
61 u32 step_en; 63 u32 step_en;
62 64
63 /* 65 /*
@@ -71,16 +73,18 @@ static void tiadc_step_config(struct tiadc_device *adc_dev)
71 */ 73 */
72 74
73 steps = TOTAL_STEPS - adc_dev->channels; 75 steps = TOTAL_STEPS - adc_dev->channels;
74 channels = TOTAL_CHANNELS - adc_dev->channels;
75
76 stepconfig = STEPCONFIG_AVG_16 | STEPCONFIG_FIFO1; 76 stepconfig = STEPCONFIG_AVG_16 | STEPCONFIG_FIFO1;
77 77
78 for (i = steps; i < TOTAL_STEPS; i++) { 78 for (i = 0; i < adc_dev->channels; i++) {
79 tiadc_writel(adc_dev, REG_STEPCONFIG(i), 79 int chan;
80 stepconfig | STEPCONFIG_INP(channels)); 80
81 tiadc_writel(adc_dev, REG_STEPDELAY(i), 81 chan = adc_dev->channel_line[i];
82 tiadc_writel(adc_dev, REG_STEPCONFIG(steps),
83 stepconfig | STEPCONFIG_INP(chan));
84 tiadc_writel(adc_dev, REG_STEPDELAY(steps),
82 STEPCONFIG_OPENDLY); 85 STEPCONFIG_OPENDLY);
83 channels++; 86 adc_dev->channel_step[i] = steps;
87 steps++;
84 } 88 }
85 step_en = get_adc_step_mask(adc_dev); 89 step_en = get_adc_step_mask(adc_dev);
86 am335x_tsc_se_set(adc_dev->mfd_tscadc, step_en); 90 am335x_tsc_se_set(adc_dev->mfd_tscadc, step_en);
@@ -115,9 +119,9 @@ static int tiadc_channel_init(struct iio_dev *indio_dev, int channels)
115 119
116 chan->type = IIO_VOLTAGE; 120 chan->type = IIO_VOLTAGE;
117 chan->indexed = 1; 121 chan->indexed = 1;
118 chan->channel = i; 122 chan->channel = adc_dev->channel_line[i];
119 chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW); 123 chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
120 chan->datasheet_name = chan_name_ain[i]; 124 chan->datasheet_name = chan_name_ain[chan->channel];
121 chan->scan_type.sign = 'u'; 125 chan->scan_type.sign = 'u';
122 chan->scan_type.realbits = 12; 126 chan->scan_type.realbits = 12;
123 chan->scan_type.storagebits = 32; 127 chan->scan_type.storagebits = 32;
@@ -139,7 +143,8 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
139{ 143{
140 struct tiadc_device *adc_dev = iio_priv(indio_dev); 144 struct tiadc_device *adc_dev = iio_priv(indio_dev);
141 int i; 145 int i;
142 unsigned int fifo1count, readx1; 146 unsigned int fifo1count, read;
147 u32 step = UINT_MAX;
143 148
144 /* 149 /*
145 * When the sub-system is first enabled, 150 * When the sub-system is first enabled,
@@ -152,11 +157,20 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
152 * Hence we need to flush out this data. 157 * Hence we need to flush out this data.
153 */ 158 */
154 159
160 for (i = 0; i < ARRAY_SIZE(adc_dev->channel_step); i++) {
161 if (chan->channel == adc_dev->channel_line[i]) {
162 step = adc_dev->channel_step[i];
163 break;
164 }
165 }
166 if (WARN_ON_ONCE(step == UINT_MAX))
167 return -EINVAL;
168
155 fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT); 169 fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
156 for (i = 0; i < fifo1count; i++) { 170 for (i = 0; i < fifo1count; i++) {
157 readx1 = tiadc_readl(adc_dev, REG_FIFO1); 171 read = tiadc_readl(adc_dev, REG_FIFO1);
158 if (i == chan->channel) 172 if (read >> 16 == step)
159 *val = readx1 & 0xfff; 173 *val = read & 0xfff;
160 } 174 }
161 am335x_tsc_se_update(adc_dev->mfd_tscadc); 175 am335x_tsc_se_update(adc_dev->mfd_tscadc);
162 176
@@ -172,8 +186,11 @@ static int tiadc_probe(struct platform_device *pdev)
172 struct iio_dev *indio_dev; 186 struct iio_dev *indio_dev;
173 struct tiadc_device *adc_dev; 187 struct tiadc_device *adc_dev;
174 struct device_node *node = pdev->dev.of_node; 188 struct device_node *node = pdev->dev.of_node;
189 struct property *prop;
190 const __be32 *cur;
175 int err; 191 int err;
176 u32 val32; 192 u32 val;
193 int channels = 0;
177 194
178 if (!node) { 195 if (!node) {
179 dev_err(&pdev->dev, "Could not find valid DT data.\n"); 196 dev_err(&pdev->dev, "Could not find valid DT data.\n");
@@ -190,11 +207,11 @@ static int tiadc_probe(struct platform_device *pdev)
190 207
191 adc_dev->mfd_tscadc = ti_tscadc_dev_get(pdev); 208 adc_dev->mfd_tscadc = ti_tscadc_dev_get(pdev);
192 209
193 err = of_property_read_u32(node, 210 of_property_for_each_u32(node, "ti,adc-channels", prop, cur, val) {
194 "ti,adc-channels", &val32); 211 adc_dev->channel_line[channels] = val;
195 if (err < 0) 212 channels++;
196 goto err_free_device; 213 }
197 adc_dev->channels = val32; 214 adc_dev->channels = channels;
198 215
199 indio_dev->dev.parent = &pdev->dev; 216 indio_dev->dev.parent = &pdev->dev;
200 indio_dev->name = dev_name(&pdev->dev); 217 indio_dev->name = dev_name(&pdev->dev);