]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/iio/adc/ad7292.c
Merge tag 'dma-mapping-5.6' of git://git.infradead.org/users/hch/dma-mapping
[linux.git] / drivers / iio / adc / ad7292.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Analog Devices AD7292 SPI ADC driver
4  *
5  * Copyright 2019 Analog Devices Inc.
6  */
7
8 #include <linux/bitfield.h>
9 #include <linux/device.h>
10 #include <linux/module.h>
11 #include <linux/regulator/consumer.h>
12 #include <linux/spi/spi.h>
13
14 #include <linux/iio/iio.h>
15
16 #define ADI_VENDOR_ID 0x0018
17
18 /* AD7292 registers definition */
19 #define AD7292_REG_VENDOR_ID            0x00
20 #define AD7292_REG_CONF_BANK            0x05
21 #define AD7292_REG_CONV_COMM            0x0E
22 #define AD7292_REG_ADC_CH(x)            (0x10 + (x))
23
24 /* AD7292 configuration bank subregisters definition */
25 #define AD7292_BANK_REG_VIN_RNG0        0x10
26 #define AD7292_BANK_REG_VIN_RNG1        0x11
27 #define AD7292_BANK_REG_SAMP_MODE       0x12
28
29 #define AD7292_RD_FLAG_MSK(x)           (BIT(7) | ((x) & 0x3F))
30
31 /* AD7292_REG_ADC_CONVERSION */
32 #define AD7292_ADC_DATA_MASK            GENMASK(15, 6)
33 #define AD7292_ADC_DATA(x)              FIELD_GET(AD7292_ADC_DATA_MASK, x)
34
35 /* AD7292_CHANNEL_SAMPLING_MODE */
36 #define AD7292_CH_SAMP_MODE(reg, ch)    (((reg) >> 8) & BIT(ch))
37
38 /* AD7292_CHANNEL_VIN_RANGE */
39 #define AD7292_CH_VIN_RANGE(reg, ch)    ((reg) & BIT(ch))
40
41 #define AD7292_VOLTAGE_CHAN(_chan)                                      \
42 {                                                                       \
43         .type = IIO_VOLTAGE,                                            \
44         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |                  \
45                               BIT(IIO_CHAN_INFO_SCALE),                 \
46         .indexed = 1,                                                   \
47         .channel = _chan,                                               \
48 }
49
50 static const struct iio_chan_spec ad7292_channels[] = {
51         AD7292_VOLTAGE_CHAN(0),
52         AD7292_VOLTAGE_CHAN(1),
53         AD7292_VOLTAGE_CHAN(2),
54         AD7292_VOLTAGE_CHAN(3),
55         AD7292_VOLTAGE_CHAN(4),
56         AD7292_VOLTAGE_CHAN(5),
57         AD7292_VOLTAGE_CHAN(6),
58         AD7292_VOLTAGE_CHAN(7)
59 };
60
61 static const struct iio_chan_spec ad7292_channels_diff[] = {
62         {
63                 .type = IIO_VOLTAGE,
64                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
65                 .indexed = 1,
66                 .differential = 1,
67                 .channel = 0,
68                 .channel2 = 1,
69         },
70         AD7292_VOLTAGE_CHAN(2),
71         AD7292_VOLTAGE_CHAN(3),
72         AD7292_VOLTAGE_CHAN(4),
73         AD7292_VOLTAGE_CHAN(5),
74         AD7292_VOLTAGE_CHAN(6),
75         AD7292_VOLTAGE_CHAN(7)
76 };
77
78 struct ad7292_state {
79         struct spi_device *spi;
80         struct regulator *reg;
81         unsigned short vref_mv;
82
83         __be16 d16 ____cacheline_aligned;
84         u8 d8[2];
85 };
86
87 static int ad7292_spi_reg_read(struct ad7292_state *st, unsigned int addr)
88 {
89         int ret;
90
91         st->d8[0] = AD7292_RD_FLAG_MSK(addr);
92
93         ret = spi_write_then_read(st->spi, st->d8, 1, &st->d16, 2);
94         if (ret < 0)
95                 return ret;
96
97         return be16_to_cpu(st->d16);
98 }
99
100 static int ad7292_spi_subreg_read(struct ad7292_state *st, unsigned int addr,
101                                   unsigned int sub_addr, unsigned int len)
102 {
103         unsigned int shift = 16 - (8 * len);
104         int ret;
105
106         st->d8[0] = AD7292_RD_FLAG_MSK(addr);
107         st->d8[1] = sub_addr;
108
109         ret = spi_write_then_read(st->spi, st->d8, 2, &st->d16, len);
110         if (ret < 0)
111                 return ret;
112
113         return (be16_to_cpu(st->d16) >> shift);
114 }
115
116 static int ad7292_single_conversion(struct ad7292_state *st,
117                                     unsigned int chan_addr)
118 {
119         int ret;
120
121         struct spi_transfer t[] = {
122                 {
123                         .tx_buf = &st->d8,
124                         .len = 4,
125                         .delay_usecs = 6,
126                 }, {
127                         .rx_buf = &st->d16,
128                         .len = 2,
129                 },
130         };
131
132         st->d8[0] = chan_addr;
133         st->d8[1] = AD7292_RD_FLAG_MSK(AD7292_REG_CONV_COMM);
134
135         ret = spi_sync_transfer(st->spi, t, ARRAY_SIZE(t));
136
137         if (ret < 0)
138                 return ret;
139
140         return be16_to_cpu(st->d16);
141 }
142
143 static int ad7292_vin_range_multiplier(struct ad7292_state *st, int channel)
144 {
145         int samp_mode, range0, range1, factor = 1;
146
147         /*
148          * Every AD7292 ADC channel may have its input range adjusted according
149          * to the settings at the ADC sampling mode and VIN range subregisters.
150          * For a given channel, the minimum input range is equal to Vref, and it
151          * may be increased by a multiplier factor of 2 or 4 according to the
152          * following rule:
153          * If channel is being sampled with respect to AGND:
154          *      factor = 4 if VIN range0 and VIN range1 equal 0
155          *      factor = 2 if only one of VIN ranges equal 1
156          *      factor = 1 if both VIN range0 and VIN range1 equal 1
157          * If channel is being sampled with respect to AVDD:
158          *      factor = 4 if VIN range0 and VIN range1 equal 0
159          *      Behavior is undefined if any of VIN range doesn't equal 0
160          */
161
162         samp_mode = ad7292_spi_subreg_read(st, AD7292_REG_CONF_BANK,
163                                            AD7292_BANK_REG_SAMP_MODE, 2);
164
165         if (samp_mode < 0)
166                 return samp_mode;
167
168         range0 = ad7292_spi_subreg_read(st, AD7292_REG_CONF_BANK,
169                                         AD7292_BANK_REG_VIN_RNG0, 2);
170
171         if (range0 < 0)
172                 return range0;
173
174         range1 = ad7292_spi_subreg_read(st, AD7292_REG_CONF_BANK,
175                                         AD7292_BANK_REG_VIN_RNG1, 2);
176
177         if (range1 < 0)
178                 return range1;
179
180         if (AD7292_CH_SAMP_MODE(samp_mode, channel)) {
181                 /* Sampling with respect to AGND */
182                 if (!AD7292_CH_VIN_RANGE(range0, channel))
183                         factor *= 2;
184
185                 if (!AD7292_CH_VIN_RANGE(range1, channel))
186                         factor *= 2;
187
188         } else {
189                 /* Sampling with respect to AVDD */
190                 if (AD7292_CH_VIN_RANGE(range0, channel) ||
191                     AD7292_CH_VIN_RANGE(range1, channel))
192                         return -EPERM;
193
194                 factor = 4;
195         }
196
197         return factor;
198 }
199
200 static int ad7292_read_raw(struct iio_dev *indio_dev,
201                            const struct iio_chan_spec *chan,
202                            int *val, int *val2, long info)
203 {
204         struct ad7292_state *st = iio_priv(indio_dev);
205         unsigned int ch_addr;
206         int ret;
207
208         switch (info) {
209         case IIO_CHAN_INFO_RAW:
210                 ch_addr = AD7292_REG_ADC_CH(chan->channel);
211                 ret = ad7292_single_conversion(st, ch_addr);
212                 if (ret < 0)
213                         return ret;
214
215                 *val = AD7292_ADC_DATA(ret);
216
217                 return IIO_VAL_INT;
218         case IIO_CHAN_INFO_SCALE:
219                 /*
220                  * To convert a raw value to standard units, the IIO defines
221                  * this formula: Scaled value = (raw + offset) * scale.
222                  * For the scale to be a correct multiplier for (raw + offset),
223                  * it must be calculated as the input range divided by the
224                  * number of possible distinct input values. Given the ADC data
225                  * is 10 bit long, it may assume 2^10 distinct values.
226                  * Hence, scale = range / 2^10. The IIO_VAL_FRACTIONAL_LOG2
227                  * return type indicates to the IIO API to divide *val by 2 to
228                  * the power of *val2 when returning from read_raw.
229                  */
230
231                 ret = ad7292_vin_range_multiplier(st, chan->channel);
232                 if (ret < 0)
233                         return ret;
234
235                 *val = st->vref_mv * ret;
236                 *val2 = 10;
237                 return IIO_VAL_FRACTIONAL_LOG2;
238         default:
239                 break;
240         }
241         return -EINVAL;
242 }
243
244 static const struct iio_info ad7292_info = {
245         .read_raw = ad7292_read_raw,
246 };
247
248 static void ad7292_regulator_disable(void *data)
249 {
250         struct ad7292_state *st = data;
251
252         regulator_disable(st->reg);
253 }
254
255 static int ad7292_probe(struct spi_device *spi)
256 {
257         struct ad7292_state *st;
258         struct iio_dev *indio_dev;
259         struct device_node *child;
260         bool diff_channels = 0;
261         int ret;
262
263         indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
264         if (!indio_dev)
265                 return -ENOMEM;
266
267         st = iio_priv(indio_dev);
268         st->spi = spi;
269
270         ret = ad7292_spi_reg_read(st, AD7292_REG_VENDOR_ID);
271         if (ret != ADI_VENDOR_ID) {
272                 dev_err(&spi->dev, "Wrong vendor id 0x%x\n", ret);
273                 return -EINVAL;
274         }
275
276         spi_set_drvdata(spi, indio_dev);
277
278         st->reg = devm_regulator_get_optional(&spi->dev, "vref");
279         if (!IS_ERR(st->reg)) {
280                 ret = regulator_enable(st->reg);
281                 if (ret) {
282                         dev_err(&spi->dev,
283                                 "Failed to enable external vref supply\n");
284                         return ret;
285                 }
286
287                 ret = devm_add_action_or_reset(&spi->dev,
288                                                ad7292_regulator_disable, st);
289                 if (ret) {
290                         regulator_disable(st->reg);
291                         return ret;
292                 }
293
294                 ret = regulator_get_voltage(st->reg);
295                 if (ret < 0)
296                         return ret;
297
298                 st->vref_mv = ret / 1000;
299         } else {
300                 /* Use the internal voltage reference. */
301                 st->vref_mv = 1250;
302         }
303
304         indio_dev->dev.parent = &spi->dev;
305         indio_dev->name = spi_get_device_id(spi)->name;
306         indio_dev->modes = INDIO_DIRECT_MODE;
307         indio_dev->info = &ad7292_info;
308
309         for_each_available_child_of_node(spi->dev.of_node, child) {
310                 diff_channels = of_property_read_bool(child, "diff-channels");
311                 if (diff_channels)
312                         break;
313         }
314
315         if (diff_channels) {
316                 indio_dev->num_channels = ARRAY_SIZE(ad7292_channels_diff);
317                 indio_dev->channels = ad7292_channels_diff;
318         } else {
319                 indio_dev->num_channels = ARRAY_SIZE(ad7292_channels);
320                 indio_dev->channels = ad7292_channels;
321         }
322
323         return devm_iio_device_register(&spi->dev, indio_dev);
324 }
325
326 static const struct spi_device_id ad7292_id_table[] = {
327         { "ad7292", 0 },
328         {}
329 };
330 MODULE_DEVICE_TABLE(spi, ad7292_id_table);
331
332 static const struct of_device_id ad7292_of_match[] = {
333         { .compatible = "adi,ad7292" },
334         { },
335 };
336 MODULE_DEVICE_TABLE(of, ad7292_of_match);
337
338 static struct spi_driver ad7292_driver = {
339         .driver = {
340                 .name = "ad7292",
341                 .of_match_table = ad7292_of_match,
342         },
343         .probe = ad7292_probe,
344         .id_table = ad7292_id_table,
345 };
346 module_spi_driver(ad7292_driver);
347
348 MODULE_AUTHOR("Marcelo Schmitt <marcelo.schmitt1@gmail.com>");
349 MODULE_DESCRIPTION("Analog Devices AD7292 ADC driver");
350 MODULE_LICENSE("GPL v2");