Commit 18926edebcb82ca325abf843293801d4ff43436a

Authored by Sebastian Andrzej Siewior
1 parent 9a28b8834c

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>

Showing 3 changed files with 56 additions and 23 deletions Side-by-side Diff

arch/arm/boot/dts/am335x-evm.dts
... ... @@ -255,7 +255,7 @@
255 255 };
256 256  
257 257 adc {
258   - ti,adc-channels = <4>;
  258 + ti,adc-channels = <4 5 6 7>;
259 259 };
260 260 };
drivers/iio/adc/ti_am335x_adc.c
... ... @@ -32,6 +32,8 @@
32 32 struct tiadc_device {
33 33 struct ti_tscadc_dev *mfd_tscadc;
34 34 int channels;
  35 + u8 channel_line[8];
  36 + u8 channel_step[8];
35 37 };
36 38  
37 39 static unsigned int tiadc_readl(struct tiadc_device *adc, unsigned int reg)
... ... @@ -57,7 +59,7 @@
57 59 static void tiadc_step_config(struct tiadc_device *adc_dev)
58 60 {
59 61 unsigned int stepconfig;
60   - int i, channels = 0, steps;
  62 + int i, steps;
61 63 u32 step_en;
62 64  
63 65 /*
64 66  
65 67  
... ... @@ -71,16 +73,18 @@
71 73 */
72 74  
73 75 steps = TOTAL_STEPS - adc_dev->channels;
74   - channels = TOTAL_CHANNELS - adc_dev->channels;
75   -
76 76 stepconfig = STEPCONFIG_AVG_16 | STEPCONFIG_FIFO1;
77 77  
78   - for (i = steps; i < TOTAL_STEPS; i++) {
79   - tiadc_writel(adc_dev, REG_STEPCONFIG(i),
80   - stepconfig | STEPCONFIG_INP(channels));
81   - tiadc_writel(adc_dev, REG_STEPDELAY(i),
  78 + for (i = 0; i < adc_dev->channels; i++) {
  79 + int chan;
  80 +
  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 85 STEPCONFIG_OPENDLY);
83   - channels++;
  86 + adc_dev->channel_step[i] = steps;
  87 + steps++;
84 88 }
85 89 step_en = get_adc_step_mask(adc_dev);
86 90 am335x_tsc_se_set(adc_dev->mfd_tscadc, step_en);
87 91  
... ... @@ -115,9 +119,9 @@
115 119  
116 120 chan->type = IIO_VOLTAGE;
117 121 chan->indexed = 1;
118   - chan->channel = i;
  122 + chan->channel = adc_dev->channel_line[i];
119 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 125 chan->scan_type.sign = 'u';
122 126 chan->scan_type.realbits = 12;
123 127 chan->scan_type.storagebits = 32;
... ... @@ -139,7 +143,8 @@
139 143 {
140 144 struct tiadc_device *adc_dev = iio_priv(indio_dev);
141 145 int i;
142   - unsigned int fifo1count, readx1;
  146 + unsigned int fifo1count, read;
  147 + u32 step = UINT_MAX;
143 148  
144 149 /*
145 150 * When the sub-system is first enabled,
146 151  
... ... @@ -152,11 +157,20 @@
152 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 169 fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
156 170 for (i = 0; i < fifo1count; i++) {
157   - readx1 = tiadc_readl(adc_dev, REG_FIFO1);
158   - if (i == chan->channel)
159   - *val = readx1 & 0xfff;
  171 + read = tiadc_readl(adc_dev, REG_FIFO1);
  172 + if (read >> 16 == step)
  173 + *val = read & 0xfff;
160 174 }
161 175 am335x_tsc_se_update(adc_dev->mfd_tscadc);
162 176  
163 177  
... ... @@ -172,8 +186,11 @@
172 186 struct iio_dev *indio_dev;
173 187 struct tiadc_device *adc_dev;
174 188 struct device_node *node = pdev->dev.of_node;
  189 + struct property *prop;
  190 + const __be32 *cur;
175 191 int err;
176   - u32 val32;
  192 + u32 val;
  193 + int channels = 0;
177 194  
178 195 if (!node) {
179 196 dev_err(&pdev->dev, "Could not find valid DT data.\n");
... ... @@ -190,11 +207,11 @@
190 207  
191 208 adc_dev->mfd_tscadc = ti_tscadc_dev_get(pdev);
192 209  
193   - err = of_property_read_u32(node,
194   - "ti,adc-channels", &val32);
195   - if (err < 0)
196   - goto err_free_device;
197   - adc_dev->channels = val32;
  210 + of_property_for_each_u32(node, "ti,adc-channels", prop, cur, val) {
  211 + adc_dev->channel_line[channels] = val;
  212 + channels++;
  213 + }
  214 + adc_dev->channels = channels;
198 215  
199 216 indio_dev->dev.parent = &pdev->dev;
200 217 indio_dev->name = dev_name(&pdev->dev);
drivers/mfd/ti_am335x_tscadc.c
... ... @@ -91,9 +91,13 @@
91 91 struct clk *clk;
92 92 struct device_node *node = pdev->dev.of_node;
93 93 struct mfd_cell *cell;
  94 + struct property *prop;
  95 + const __be32 *cur;
  96 + u32 val;
94 97 int err, ctrl;
95 98 int clk_value, clock_rate;
96 99 int tsc_wires = 0, adc_channels = 0, total_channels;
  100 + int readouts = 0;
97 101  
98 102 if (!pdev->dev.of_node) {
99 103 dev_err(&pdev->dev, "Could not find valid DT data.\n");
100 104  
... ... @@ -102,10 +106,17 @@
102 106  
103 107 node = of_get_child_by_name(pdev->dev.of_node, "tsc");
104 108 of_property_read_u32(node, "ti,wires", &tsc_wires);
  109 + of_property_read_u32(node, "ti,coordiante-readouts", &readouts);
105 110  
106 111 node = of_get_child_by_name(pdev->dev.of_node, "adc");
107   - of_property_read_u32(node, "ti,adc-channels", &adc_channels);
108   -
  112 + of_property_for_each_u32(node, "ti,adc-channels", prop, cur, val) {
  113 + adc_channels++;
  114 + if (val > 7) {
  115 + dev_err(&pdev->dev, " PIN numbers are 0..7 (not %d)\n",
  116 + val);
  117 + return -EINVAL;
  118 + }
  119 + }
109 120 total_channels = tsc_wires + adc_channels;
110 121 if (total_channels > 8) {
111 122 dev_err(&pdev->dev, "Number of i/p channels more than 8\n");
... ... @@ -113,6 +124,11 @@
113 124 }
114 125 if (total_channels == 0) {
115 126 dev_err(&pdev->dev, "Need atleast one channel.\n");
  127 + return -EINVAL;
  128 + }
  129 +
  130 + if (readouts * 2 + 2 + adc_channels > 16) {
  131 + dev_err(&pdev->dev, "Too many step configurations requested\n");
116 132 return -EINVAL;
117 133 }
118 134