1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * AD7785/AD7792/AD7793/AD7794/AD7795 SPI ADC driver |
4 | * |
5 | * Copyright 2011-2012 Analog Devices Inc. |
6 | */ |
7 | |
8 | #include <linux/interrupt.h> |
9 | #include <linux/device.h> |
10 | #include <linux/kernel.h> |
11 | #include <linux/slab.h> |
12 | #include <linux/sysfs.h> |
13 | #include <linux/spi/spi.h> |
14 | #include <linux/regulator/consumer.h> |
15 | #include <linux/err.h> |
16 | #include <linux/sched.h> |
17 | #include <linux/delay.h> |
18 | #include <linux/module.h> |
19 | |
20 | #include <linux/iio/iio.h> |
21 | #include <linux/iio/sysfs.h> |
22 | #include <linux/iio/buffer.h> |
23 | #include <linux/iio/trigger.h> |
24 | #include <linux/iio/trigger_consumer.h> |
25 | #include <linux/iio/triggered_buffer.h> |
26 | #include <linux/iio/adc/ad_sigma_delta.h> |
27 | #include <linux/platform_data/ad7793.h> |
28 | |
29 | /* Registers */ |
30 | #define AD7793_REG_COMM 0 /* Communications Register (WO, 8-bit) */ |
31 | #define AD7793_REG_STAT 0 /* Status Register (RO, 8-bit) */ |
32 | #define AD7793_REG_MODE 1 /* Mode Register (RW, 16-bit */ |
33 | #define AD7793_REG_CONF 2 /* Configuration Register (RW, 16-bit) */ |
34 | #define AD7793_REG_DATA 3 /* Data Register (RO, 16-/24-bit) */ |
35 | #define AD7793_REG_ID 4 /* ID Register (RO, 8-bit) */ |
36 | #define AD7793_REG_IO 5 /* IO Register (RO, 8-bit) */ |
37 | #define AD7793_REG_OFFSET 6 /* Offset Register (RW, 16-bit |
38 | * (AD7792)/24-bit (AD7793)) */ |
39 | #define AD7793_REG_FULLSALE 7 /* Full-Scale Register |
40 | * (RW, 16-bit (AD7792)/24-bit (AD7793)) */ |
41 | |
42 | /* Communications Register Bit Designations (AD7793_REG_COMM) */ |
43 | #define AD7793_COMM_WEN (1 << 7) /* Write Enable */ |
44 | #define AD7793_COMM_WRITE (0 << 6) /* Write Operation */ |
45 | #define AD7793_COMM_READ (1 << 6) /* Read Operation */ |
46 | #define AD7793_COMM_ADDR(x) (((x) & 0x7) << 3) /* Register Address */ |
47 | #define AD7793_COMM_CREAD (1 << 2) /* Continuous Read of Data Register */ |
48 | |
49 | /* Status Register Bit Designations (AD7793_REG_STAT) */ |
50 | #define AD7793_STAT_RDY (1 << 7) /* Ready */ |
51 | #define AD7793_STAT_ERR (1 << 6) /* Error (Overrange, Underrange) */ |
52 | #define AD7793_STAT_CH3 (1 << 2) /* Channel 3 */ |
53 | #define AD7793_STAT_CH2 (1 << 1) /* Channel 2 */ |
54 | #define AD7793_STAT_CH1 (1 << 0) /* Channel 1 */ |
55 | |
56 | /* Mode Register Bit Designations (AD7793_REG_MODE) */ |
57 | #define AD7793_MODE_SEL(x) (((x) & 0x7) << 13) /* Operation Mode Select */ |
58 | #define AD7793_MODE_SEL_MASK (0x7 << 13) /* Operation Mode Select mask */ |
59 | #define AD7793_MODE_CLKSRC(x) (((x) & 0x3) << 6) /* ADC Clock Source Select */ |
60 | #define AD7793_MODE_RATE(x) ((x) & 0xF) /* Filter Update Rate Select */ |
61 | |
62 | #define AD7793_MODE_CONT 0 /* Continuous Conversion Mode */ |
63 | #define AD7793_MODE_SINGLE 1 /* Single Conversion Mode */ |
64 | #define AD7793_MODE_IDLE 2 /* Idle Mode */ |
65 | #define AD7793_MODE_PWRDN 3 /* Power-Down Mode */ |
66 | #define AD7793_MODE_CAL_INT_ZERO 4 /* Internal Zero-Scale Calibration */ |
67 | #define AD7793_MODE_CAL_INT_FULL 5 /* Internal Full-Scale Calibration */ |
68 | #define AD7793_MODE_CAL_SYS_ZERO 6 /* System Zero-Scale Calibration */ |
69 | #define AD7793_MODE_CAL_SYS_FULL 7 /* System Full-Scale Calibration */ |
70 | |
71 | #define AD7793_CLK_INT 0 /* Internal 64 kHz Clock not |
72 | * available at the CLK pin */ |
73 | #define AD7793_CLK_INT_CO 1 /* Internal 64 kHz Clock available |
74 | * at the CLK pin */ |
75 | #define AD7793_CLK_EXT 2 /* External 64 kHz Clock */ |
76 | #define AD7793_CLK_EXT_DIV2 3 /* External Clock divided by 2 */ |
77 | |
78 | /* Configuration Register Bit Designations (AD7793_REG_CONF) */ |
79 | #define AD7793_CONF_VBIAS(x) (((x) & 0x3) << 14) /* Bias Voltage |
80 | * Generator Enable */ |
81 | #define AD7793_CONF_BO_EN (1 << 13) /* Burnout Current Enable */ |
82 | #define AD7793_CONF_UNIPOLAR (1 << 12) /* Unipolar/Bipolar Enable */ |
83 | #define AD7793_CONF_BOOST (1 << 11) /* Boost Enable */ |
84 | #define AD7793_CONF_GAIN(x) (((x) & 0x7) << 8) /* Gain Select */ |
85 | #define AD7793_CONF_REFSEL(x) ((x) << 6) /* INT/EXT Reference Select */ |
86 | #define AD7793_CONF_BUF (1 << 4) /* Buffered Mode Enable */ |
87 | #define AD7793_CONF_CHAN(x) ((x) & 0xf) /* Channel select */ |
88 | #define AD7793_CONF_CHAN_MASK 0xf /* Channel select mask */ |
89 | |
90 | #define AD7793_CH_AIN1P_AIN1M 0 /* AIN1(+) - AIN1(-) */ |
91 | #define AD7793_CH_AIN2P_AIN2M 1 /* AIN2(+) - AIN2(-) */ |
92 | #define AD7793_CH_AIN3P_AIN3M 2 /* AIN3(+) - AIN3(-) */ |
93 | #define AD7793_CH_AIN1M_AIN1M 3 /* AIN1(-) - AIN1(-) */ |
94 | #define AD7793_CH_TEMP 6 /* Temp Sensor */ |
95 | #define AD7793_CH_AVDD_MONITOR 7 /* AVDD Monitor */ |
96 | |
97 | #define AD7795_CH_AIN4P_AIN4M 4 /* AIN4(+) - AIN4(-) */ |
98 | #define AD7795_CH_AIN5P_AIN5M 5 /* AIN5(+) - AIN5(-) */ |
99 | #define AD7795_CH_AIN6P_AIN6M 6 /* AIN6(+) - AIN6(-) */ |
100 | #define AD7795_CH_AIN1M_AIN1M 8 /* AIN1(-) - AIN1(-) */ |
101 | |
102 | /* ID Register Bit Designations (AD7793_REG_ID) */ |
103 | #define AD7785_ID 0x3 |
104 | #define AD7792_ID 0xA |
105 | #define AD7793_ID 0xB |
106 | #define AD7794_ID 0xF |
107 | #define AD7795_ID 0xF |
108 | #define AD7796_ID 0xA |
109 | #define AD7797_ID 0xB |
110 | #define AD7798_ID 0x8 |
111 | #define AD7799_ID 0x9 |
112 | #define AD7793_ID_MASK 0xF |
113 | |
114 | /* IO (Excitation Current Sources) Register Bit Designations (AD7793_REG_IO) */ |
115 | #define AD7793_IO_IEXC1_IOUT1_IEXC2_IOUT2 0 /* IEXC1 connect to IOUT1, |
116 | * IEXC2 connect to IOUT2 */ |
117 | #define AD7793_IO_IEXC1_IOUT2_IEXC2_IOUT1 1 /* IEXC1 connect to IOUT2, |
118 | * IEXC2 connect to IOUT1 */ |
119 | #define AD7793_IO_IEXC1_IEXC2_IOUT1 2 /* Both current sources |
120 | * IEXC1,2 connect to IOUT1 */ |
121 | #define AD7793_IO_IEXC1_IEXC2_IOUT2 3 /* Both current sources |
122 | * IEXC1,2 connect to IOUT2 */ |
123 | |
124 | #define AD7793_IO_IXCEN_10uA (1 << 0) /* Excitation Current 10uA */ |
125 | #define AD7793_IO_IXCEN_210uA (2 << 0) /* Excitation Current 210uA */ |
126 | #define AD7793_IO_IXCEN_1mA (3 << 0) /* Excitation Current 1mA */ |
127 | |
128 | /* NOTE: |
129 | * The AD7792/AD7793 features a dual use data out ready DOUT/RDY output. |
130 | * In order to avoid contentions on the SPI bus, it's therefore necessary |
131 | * to use spi bus locking. |
132 | * |
133 | * The DOUT/RDY output must also be wired to an interrupt capable GPIO. |
134 | */ |
135 | |
136 | #define AD7793_FLAG_HAS_CLKSEL BIT(0) |
137 | #define AD7793_FLAG_HAS_REFSEL BIT(1) |
138 | #define AD7793_FLAG_HAS_VBIAS BIT(2) |
139 | #define AD7793_HAS_EXITATION_CURRENT BIT(3) |
140 | #define AD7793_FLAG_HAS_GAIN BIT(4) |
141 | #define AD7793_FLAG_HAS_BUFFER BIT(5) |
142 | |
143 | struct ad7793_chip_info { |
144 | unsigned int id; |
145 | const struct iio_chan_spec *channels; |
146 | unsigned int num_channels; |
147 | unsigned int flags; |
148 | |
149 | const struct iio_info *iio_info; |
150 | const u16 *sample_freq_avail; |
151 | }; |
152 | |
153 | struct ad7793_state { |
154 | const struct ad7793_chip_info *chip_info; |
155 | struct regulator *reg; |
156 | u16 int_vref_mv; |
157 | u16 mode; |
158 | u16 conf; |
159 | u32 scale_avail[8][2]; |
160 | |
161 | struct ad_sigma_delta sd; |
162 | |
163 | }; |
164 | |
165 | enum ad7793_supported_device_ids { |
166 | ID_AD7785, |
167 | ID_AD7792, |
168 | ID_AD7793, |
169 | ID_AD7794, |
170 | ID_AD7795, |
171 | ID_AD7796, |
172 | ID_AD7797, |
173 | ID_AD7798, |
174 | ID_AD7799, |
175 | }; |
176 | |
177 | static struct ad7793_state *ad_sigma_delta_to_ad7793(struct ad_sigma_delta *sd) |
178 | { |
179 | return container_of(sd, struct ad7793_state, sd); |
180 | } |
181 | |
182 | static int ad7793_set_channel(struct ad_sigma_delta *sd, unsigned int channel) |
183 | { |
184 | struct ad7793_state *st = ad_sigma_delta_to_ad7793(sd); |
185 | |
186 | st->conf &= ~AD7793_CONF_CHAN_MASK; |
187 | st->conf |= AD7793_CONF_CHAN(channel); |
188 | |
189 | return ad_sd_write_reg(sigma_delta: &st->sd, AD7793_REG_CONF, size: 2, val: st->conf); |
190 | } |
191 | |
192 | static int ad7793_set_mode(struct ad_sigma_delta *sd, |
193 | enum ad_sigma_delta_mode mode) |
194 | { |
195 | struct ad7793_state *st = ad_sigma_delta_to_ad7793(sd); |
196 | |
197 | st->mode &= ~AD7793_MODE_SEL_MASK; |
198 | st->mode |= AD7793_MODE_SEL(mode); |
199 | |
200 | return ad_sd_write_reg(sigma_delta: &st->sd, AD7793_REG_MODE, size: 2, val: st->mode); |
201 | } |
202 | |
203 | static const struct ad_sigma_delta_info ad7793_sigma_delta_info = { |
204 | .set_channel = ad7793_set_channel, |
205 | .set_mode = ad7793_set_mode, |
206 | .has_registers = true, |
207 | .addr_shift = 3, |
208 | .read_mask = BIT(6), |
209 | .irq_flags = IRQF_TRIGGER_FALLING, |
210 | }; |
211 | |
212 | static const struct ad_sd_calib_data ad7793_calib_arr[6] = { |
213 | {AD7793_MODE_CAL_INT_ZERO, AD7793_CH_AIN1P_AIN1M}, |
214 | {AD7793_MODE_CAL_INT_FULL, AD7793_CH_AIN1P_AIN1M}, |
215 | {AD7793_MODE_CAL_INT_ZERO, AD7793_CH_AIN2P_AIN2M}, |
216 | {AD7793_MODE_CAL_INT_FULL, AD7793_CH_AIN2P_AIN2M}, |
217 | {AD7793_MODE_CAL_INT_ZERO, AD7793_CH_AIN3P_AIN3M}, |
218 | {AD7793_MODE_CAL_INT_FULL, AD7793_CH_AIN3P_AIN3M} |
219 | }; |
220 | |
221 | static int ad7793_calibrate_all(struct ad7793_state *st) |
222 | { |
223 | return ad_sd_calibrate_all(sigma_delta: &st->sd, cd: ad7793_calib_arr, |
224 | ARRAY_SIZE(ad7793_calib_arr)); |
225 | } |
226 | |
227 | static int ad7793_check_platform_data(struct ad7793_state *st, |
228 | const struct ad7793_platform_data *pdata) |
229 | { |
230 | if ((pdata->current_source_direction == AD7793_IEXEC1_IEXEC2_IOUT1 || |
231 | pdata->current_source_direction == AD7793_IEXEC1_IEXEC2_IOUT2) && |
232 | ((pdata->exitation_current != AD7793_IX_10uA) && |
233 | (pdata->exitation_current != AD7793_IX_210uA))) |
234 | return -EINVAL; |
235 | |
236 | if (!(st->chip_info->flags & AD7793_FLAG_HAS_CLKSEL) && |
237 | pdata->clock_src != AD7793_CLK_SRC_INT) |
238 | return -EINVAL; |
239 | |
240 | if (!(st->chip_info->flags & AD7793_FLAG_HAS_REFSEL) && |
241 | pdata->refsel != AD7793_REFSEL_REFIN1) |
242 | return -EINVAL; |
243 | |
244 | if (!(st->chip_info->flags & AD7793_FLAG_HAS_VBIAS) && |
245 | pdata->bias_voltage != AD7793_BIAS_VOLTAGE_DISABLED) |
246 | return -EINVAL; |
247 | |
248 | if (!(st->chip_info->flags & AD7793_HAS_EXITATION_CURRENT) && |
249 | pdata->exitation_current != AD7793_IX_DISABLED) |
250 | return -EINVAL; |
251 | |
252 | return 0; |
253 | } |
254 | |
255 | static int ad7793_setup(struct iio_dev *indio_dev, |
256 | const struct ad7793_platform_data *pdata, |
257 | unsigned int vref_mv) |
258 | { |
259 | struct ad7793_state *st = iio_priv(indio_dev); |
260 | int i, ret; |
261 | unsigned long long scale_uv; |
262 | u32 id; |
263 | |
264 | ret = ad7793_check_platform_data(st, pdata); |
265 | if (ret) |
266 | return ret; |
267 | |
268 | /* reset the serial interface */ |
269 | ret = ad_sd_reset(sigma_delta: &st->sd, reset_length: 32); |
270 | if (ret < 0) |
271 | goto out; |
272 | usleep_range(min: 500, max: 2000); /* Wait for at least 500us */ |
273 | |
274 | /* write/read test for device presence */ |
275 | ret = ad_sd_read_reg(sigma_delta: &st->sd, AD7793_REG_ID, size: 1, val: &id); |
276 | if (ret) |
277 | goto out; |
278 | |
279 | id &= AD7793_ID_MASK; |
280 | |
281 | if (id != st->chip_info->id) { |
282 | ret = -ENODEV; |
283 | dev_err(&st->sd.spi->dev, "device ID query failed\n" ); |
284 | goto out; |
285 | } |
286 | |
287 | st->mode = AD7793_MODE_RATE(1); |
288 | st->conf = 0; |
289 | |
290 | if (st->chip_info->flags & AD7793_FLAG_HAS_CLKSEL) |
291 | st->mode |= AD7793_MODE_CLKSRC(pdata->clock_src); |
292 | if (st->chip_info->flags & AD7793_FLAG_HAS_REFSEL) |
293 | st->conf |= AD7793_CONF_REFSEL(pdata->refsel); |
294 | if (st->chip_info->flags & AD7793_FLAG_HAS_VBIAS) |
295 | st->conf |= AD7793_CONF_VBIAS(pdata->bias_voltage); |
296 | if (pdata->buffered || !(st->chip_info->flags & AD7793_FLAG_HAS_BUFFER)) |
297 | st->conf |= AD7793_CONF_BUF; |
298 | if (pdata->boost_enable && |
299 | (st->chip_info->flags & AD7793_FLAG_HAS_VBIAS)) |
300 | st->conf |= AD7793_CONF_BOOST; |
301 | if (pdata->burnout_current) |
302 | st->conf |= AD7793_CONF_BO_EN; |
303 | if (pdata->unipolar) |
304 | st->conf |= AD7793_CONF_UNIPOLAR; |
305 | |
306 | if (!(st->chip_info->flags & AD7793_FLAG_HAS_GAIN)) |
307 | st->conf |= AD7793_CONF_GAIN(7); |
308 | |
309 | ret = ad7793_set_mode(sd: &st->sd, mode: AD_SD_MODE_IDLE); |
310 | if (ret) |
311 | goto out; |
312 | |
313 | ret = ad7793_set_channel(sd: &st->sd, channel: 0); |
314 | if (ret) |
315 | goto out; |
316 | |
317 | if (st->chip_info->flags & AD7793_HAS_EXITATION_CURRENT) { |
318 | ret = ad_sd_write_reg(sigma_delta: &st->sd, AD7793_REG_IO, size: 1, |
319 | val: pdata->exitation_current | |
320 | (pdata->current_source_direction << 2)); |
321 | if (ret) |
322 | goto out; |
323 | } |
324 | |
325 | ret = ad7793_calibrate_all(st); |
326 | if (ret) |
327 | goto out; |
328 | |
329 | /* Populate available ADC input ranges */ |
330 | for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++) { |
331 | scale_uv = ((u64)vref_mv * 100000000) |
332 | >> (st->chip_info->channels[0].scan_type.realbits - |
333 | (!!(st->conf & AD7793_CONF_UNIPOLAR) ? 0 : 1)); |
334 | scale_uv >>= i; |
335 | |
336 | st->scale_avail[i][1] = do_div(scale_uv, 100000000) * 10; |
337 | st->scale_avail[i][0] = scale_uv; |
338 | } |
339 | |
340 | return 0; |
341 | out: |
342 | dev_err(&st->sd.spi->dev, "setup failed\n" ); |
343 | return ret; |
344 | } |
345 | |
346 | static const u16 ad7793_sample_freq_avail[16] = {0, 470, 242, 123, 62, 50, 39, |
347 | 33, 19, 17, 16, 12, 10, 8, 6, 4}; |
348 | |
349 | static const u16 ad7797_sample_freq_avail[16] = {0, 0, 0, 123, 62, 50, 0, |
350 | 33, 0, 17, 16, 12, 10, 8, 6, 4}; |
351 | |
352 | static IIO_CONST_ATTR_SAMP_FREQ_AVAIL( |
353 | "470 242 123 62 50 39 33 19 17 16 12 10 8 6 4" ); |
354 | |
355 | static IIO_CONST_ATTR_NAMED(sampling_frequency_available_ad7797, |
356 | sampling_frequency_available, "123 62 50 33 17 16 12 10 8 6 4" ); |
357 | |
358 | static int ad7793_read_avail(struct iio_dev *indio_dev, |
359 | struct iio_chan_spec const *chan, |
360 | const int **vals, int *type, int *length, |
361 | long mask) |
362 | { |
363 | struct ad7793_state *st = iio_priv(indio_dev); |
364 | |
365 | switch (mask) { |
366 | case IIO_CHAN_INFO_SCALE: |
367 | *vals = (int *)st->scale_avail; |
368 | *type = IIO_VAL_INT_PLUS_NANO; |
369 | /* Values are stored in a 2D matrix */ |
370 | *length = ARRAY_SIZE(st->scale_avail) * 2; |
371 | |
372 | return IIO_AVAIL_LIST; |
373 | default: |
374 | return -EINVAL; |
375 | } |
376 | } |
377 | |
378 | static struct attribute *ad7793_attributes[] = { |
379 | &iio_const_attr_sampling_frequency_available.dev_attr.attr, |
380 | NULL |
381 | }; |
382 | |
383 | static const struct attribute_group ad7793_attribute_group = { |
384 | .attrs = ad7793_attributes, |
385 | }; |
386 | |
387 | static struct attribute *ad7797_attributes[] = { |
388 | &iio_const_attr_sampling_frequency_available_ad7797.dev_attr.attr, |
389 | NULL |
390 | }; |
391 | |
392 | static const struct attribute_group ad7797_attribute_group = { |
393 | .attrs = ad7797_attributes, |
394 | }; |
395 | |
396 | static int ad7793_read_raw(struct iio_dev *indio_dev, |
397 | struct iio_chan_spec const *chan, |
398 | int *val, |
399 | int *val2, |
400 | long m) |
401 | { |
402 | struct ad7793_state *st = iio_priv(indio_dev); |
403 | int ret; |
404 | unsigned long long scale_uv; |
405 | bool unipolar = !!(st->conf & AD7793_CONF_UNIPOLAR); |
406 | |
407 | switch (m) { |
408 | case IIO_CHAN_INFO_RAW: |
409 | ret = ad_sigma_delta_single_conversion(indio_dev, chan, val); |
410 | if (ret < 0) |
411 | return ret; |
412 | |
413 | return IIO_VAL_INT; |
414 | |
415 | case IIO_CHAN_INFO_SCALE: |
416 | switch (chan->type) { |
417 | case IIO_VOLTAGE: |
418 | if (chan->differential) { |
419 | *val = st-> |
420 | scale_avail[(st->conf >> 8) & 0x7][0]; |
421 | *val2 = st-> |
422 | scale_avail[(st->conf >> 8) & 0x7][1]; |
423 | return IIO_VAL_INT_PLUS_NANO; |
424 | } |
425 | /* 1170mV / 2^23 * 6 */ |
426 | scale_uv = (1170ULL * 1000000000ULL * 6ULL); |
427 | break; |
428 | case IIO_TEMP: |
429 | /* 1170mV / 0.81 mV/C / 2^23 */ |
430 | scale_uv = 1444444444444444ULL; |
431 | break; |
432 | default: |
433 | return -EINVAL; |
434 | } |
435 | |
436 | scale_uv >>= (chan->scan_type.realbits - (unipolar ? 0 : 1)); |
437 | *val = 0; |
438 | *val2 = scale_uv; |
439 | return IIO_VAL_INT_PLUS_NANO; |
440 | case IIO_CHAN_INFO_OFFSET: |
441 | if (!unipolar) |
442 | *val = -(1 << (chan->scan_type.realbits - 1)); |
443 | else |
444 | *val = 0; |
445 | |
446 | /* Kelvin to Celsius */ |
447 | if (chan->type == IIO_TEMP) { |
448 | unsigned long long offset; |
449 | unsigned int shift; |
450 | |
451 | shift = chan->scan_type.realbits - (unipolar ? 0 : 1); |
452 | offset = 273ULL << shift; |
453 | do_div(offset, 1444); |
454 | *val -= offset; |
455 | } |
456 | return IIO_VAL_INT; |
457 | case IIO_CHAN_INFO_SAMP_FREQ: |
458 | *val = st->chip_info |
459 | ->sample_freq_avail[AD7793_MODE_RATE(st->mode)]; |
460 | return IIO_VAL_INT; |
461 | } |
462 | return -EINVAL; |
463 | } |
464 | |
465 | static int ad7793_write_raw(struct iio_dev *indio_dev, |
466 | struct iio_chan_spec const *chan, |
467 | int val, |
468 | int val2, |
469 | long mask) |
470 | { |
471 | struct ad7793_state *st = iio_priv(indio_dev); |
472 | int ret, i; |
473 | unsigned int tmp; |
474 | |
475 | ret = iio_device_claim_direct_mode(indio_dev); |
476 | if (ret) |
477 | return ret; |
478 | |
479 | switch (mask) { |
480 | case IIO_CHAN_INFO_SCALE: |
481 | ret = -EINVAL; |
482 | for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++) |
483 | if (val2 == st->scale_avail[i][1]) { |
484 | ret = 0; |
485 | tmp = st->conf; |
486 | st->conf &= ~AD7793_CONF_GAIN(-1); |
487 | st->conf |= AD7793_CONF_GAIN(i); |
488 | |
489 | if (tmp == st->conf) |
490 | break; |
491 | |
492 | ad_sd_write_reg(sigma_delta: &st->sd, AD7793_REG_CONF, |
493 | size: sizeof(st->conf), val: st->conf); |
494 | ad7793_calibrate_all(st); |
495 | break; |
496 | } |
497 | break; |
498 | case IIO_CHAN_INFO_SAMP_FREQ: |
499 | if (!val) { |
500 | ret = -EINVAL; |
501 | break; |
502 | } |
503 | |
504 | for (i = 0; i < 16; i++) |
505 | if (val == st->chip_info->sample_freq_avail[i]) |
506 | break; |
507 | |
508 | if (i == 16) { |
509 | ret = -EINVAL; |
510 | break; |
511 | } |
512 | |
513 | st->mode &= ~AD7793_MODE_RATE(-1); |
514 | st->mode |= AD7793_MODE_RATE(i); |
515 | ad_sd_write_reg(sigma_delta: &st->sd, AD7793_REG_MODE, size: sizeof(st->mode), |
516 | val: st->mode); |
517 | break; |
518 | default: |
519 | ret = -EINVAL; |
520 | } |
521 | |
522 | iio_device_release_direct_mode(indio_dev); |
523 | return ret; |
524 | } |
525 | |
526 | static int ad7793_write_raw_get_fmt(struct iio_dev *indio_dev, |
527 | struct iio_chan_spec const *chan, |
528 | long mask) |
529 | { |
530 | return IIO_VAL_INT_PLUS_NANO; |
531 | } |
532 | |
533 | static const struct iio_info ad7793_info = { |
534 | .read_raw = &ad7793_read_raw, |
535 | .write_raw = &ad7793_write_raw, |
536 | .write_raw_get_fmt = &ad7793_write_raw_get_fmt, |
537 | .read_avail = ad7793_read_avail, |
538 | .attrs = &ad7793_attribute_group, |
539 | .validate_trigger = ad_sd_validate_trigger, |
540 | }; |
541 | |
542 | static const struct iio_info ad7797_info = { |
543 | .read_raw = &ad7793_read_raw, |
544 | .write_raw = &ad7793_write_raw, |
545 | .write_raw_get_fmt = &ad7793_write_raw_get_fmt, |
546 | .attrs = &ad7797_attribute_group, |
547 | .validate_trigger = ad_sd_validate_trigger, |
548 | }; |
549 | |
550 | #define __AD7793_CHANNEL(_si, _channel1, _channel2, _address, _bits, \ |
551 | _storagebits, _shift, _extend_name, _type, _mask_type_av, _mask_all) \ |
552 | { \ |
553 | .type = (_type), \ |
554 | .differential = (_channel2 == -1 ? 0 : 1), \ |
555 | .indexed = 1, \ |
556 | .channel = (_channel1), \ |
557 | .channel2 = (_channel2), \ |
558 | .address = (_address), \ |
559 | .extend_name = (_extend_name), \ |
560 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ |
561 | BIT(IIO_CHAN_INFO_OFFSET), \ |
562 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ |
563 | .info_mask_shared_by_type_available = (_mask_type_av), \ |
564 | .info_mask_shared_by_all = _mask_all, \ |
565 | .scan_index = (_si), \ |
566 | .scan_type = { \ |
567 | .sign = 'u', \ |
568 | .realbits = (_bits), \ |
569 | .storagebits = (_storagebits), \ |
570 | .shift = (_shift), \ |
571 | .endianness = IIO_BE, \ |
572 | }, \ |
573 | } |
574 | |
575 | #define AD7793_DIFF_CHANNEL(_si, _channel1, _channel2, _address, _bits, \ |
576 | _storagebits, _shift) \ |
577 | __AD7793_CHANNEL(_si, _channel1, _channel2, _address, _bits, \ |
578 | _storagebits, _shift, NULL, IIO_VOLTAGE, \ |
579 | BIT(IIO_CHAN_INFO_SCALE), \ |
580 | BIT(IIO_CHAN_INFO_SAMP_FREQ)) |
581 | |
582 | #define AD7793_SHORTED_CHANNEL(_si, _channel, _address, _bits, \ |
583 | _storagebits, _shift) \ |
584 | __AD7793_CHANNEL(_si, _channel, _channel, _address, _bits, \ |
585 | _storagebits, _shift, "shorted", IIO_VOLTAGE, \ |
586 | BIT(IIO_CHAN_INFO_SCALE), \ |
587 | BIT(IIO_CHAN_INFO_SAMP_FREQ)) |
588 | |
589 | #define AD7793_TEMP_CHANNEL(_si, _address, _bits, _storagebits, _shift) \ |
590 | __AD7793_CHANNEL(_si, 0, -1, _address, _bits, \ |
591 | _storagebits, _shift, NULL, IIO_TEMP, \ |
592 | 0, \ |
593 | BIT(IIO_CHAN_INFO_SAMP_FREQ)) |
594 | |
595 | #define AD7793_SUPPLY_CHANNEL(_si, _channel, _address, _bits, _storagebits, \ |
596 | _shift) \ |
597 | __AD7793_CHANNEL(_si, _channel, -1, _address, _bits, \ |
598 | _storagebits, _shift, "supply", IIO_VOLTAGE, \ |
599 | 0, \ |
600 | BIT(IIO_CHAN_INFO_SAMP_FREQ)) |
601 | |
602 | #define AD7797_DIFF_CHANNEL(_si, _channel1, _channel2, _address, _bits, \ |
603 | _storagebits, _shift) \ |
604 | __AD7793_CHANNEL(_si, _channel1, _channel2, _address, _bits, \ |
605 | _storagebits, _shift, NULL, IIO_VOLTAGE, \ |
606 | 0, \ |
607 | BIT(IIO_CHAN_INFO_SAMP_FREQ)) |
608 | |
609 | #define AD7797_SHORTED_CHANNEL(_si, _channel, _address, _bits, \ |
610 | _storagebits, _shift) \ |
611 | __AD7793_CHANNEL(_si, _channel, _channel, _address, _bits, \ |
612 | _storagebits, _shift, "shorted", IIO_VOLTAGE, \ |
613 | 0, \ |
614 | BIT(IIO_CHAN_INFO_SAMP_FREQ)) |
615 | |
616 | #define DECLARE_AD7793_CHANNELS(_name, _b, _sb, _s) \ |
617 | const struct iio_chan_spec _name##_channels[] = { \ |
618 | AD7793_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), (_s)), \ |
619 | AD7793_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), (_s)), \ |
620 | AD7793_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), (_s)), \ |
621 | AD7793_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), (_s)), \ |
622 | AD7793_TEMP_CHANNEL(4, AD7793_CH_TEMP, (_b), (_sb), (_s)), \ |
623 | AD7793_SUPPLY_CHANNEL(5, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), (_s)), \ |
624 | IIO_CHAN_SOFT_TIMESTAMP(6), \ |
625 | } |
626 | |
627 | #define DECLARE_AD7795_CHANNELS(_name, _b, _sb) \ |
628 | const struct iio_chan_spec _name##_channels[] = { \ |
629 | AD7793_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0), \ |
630 | AD7793_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), 0), \ |
631 | AD7793_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), 0), \ |
632 | AD7793_DIFF_CHANNEL(3, 3, 3, AD7795_CH_AIN4P_AIN4M, (_b), (_sb), 0), \ |
633 | AD7793_DIFF_CHANNEL(4, 4, 4, AD7795_CH_AIN5P_AIN5M, (_b), (_sb), 0), \ |
634 | AD7793_DIFF_CHANNEL(5, 5, 5, AD7795_CH_AIN6P_AIN6M, (_b), (_sb), 0), \ |
635 | AD7793_SHORTED_CHANNEL(6, 0, AD7795_CH_AIN1M_AIN1M, (_b), (_sb), 0), \ |
636 | AD7793_TEMP_CHANNEL(7, AD7793_CH_TEMP, (_b), (_sb), 0), \ |
637 | AD7793_SUPPLY_CHANNEL(8, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0), \ |
638 | IIO_CHAN_SOFT_TIMESTAMP(9), \ |
639 | } |
640 | |
641 | #define DECLARE_AD7797_CHANNELS(_name, _b, _sb) \ |
642 | const struct iio_chan_spec _name##_channels[] = { \ |
643 | AD7797_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0), \ |
644 | AD7797_SHORTED_CHANNEL(1, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), 0), \ |
645 | AD7793_TEMP_CHANNEL(2, AD7793_CH_TEMP, (_b), (_sb), 0), \ |
646 | AD7793_SUPPLY_CHANNEL(3, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0), \ |
647 | IIO_CHAN_SOFT_TIMESTAMP(4), \ |
648 | } |
649 | |
650 | #define DECLARE_AD7799_CHANNELS(_name, _b, _sb) \ |
651 | const struct iio_chan_spec _name##_channels[] = { \ |
652 | AD7793_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0), \ |
653 | AD7793_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), 0), \ |
654 | AD7793_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), 0), \ |
655 | AD7793_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), 0), \ |
656 | AD7793_SUPPLY_CHANNEL(4, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0), \ |
657 | IIO_CHAN_SOFT_TIMESTAMP(5), \ |
658 | } |
659 | |
660 | static DECLARE_AD7793_CHANNELS(ad7785, 20, 32, 4); |
661 | static DECLARE_AD7793_CHANNELS(ad7792, 16, 32, 0); |
662 | static DECLARE_AD7793_CHANNELS(ad7793, 24, 32, 0); |
663 | static DECLARE_AD7795_CHANNELS(ad7794, 16, 32); |
664 | static DECLARE_AD7795_CHANNELS(ad7795, 24, 32); |
665 | static DECLARE_AD7797_CHANNELS(ad7796, 16, 16); |
666 | static DECLARE_AD7797_CHANNELS(ad7797, 24, 32); |
667 | static DECLARE_AD7799_CHANNELS(ad7798, 16, 16); |
668 | static DECLARE_AD7799_CHANNELS(ad7799, 24, 32); |
669 | |
670 | static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { |
671 | [ID_AD7785] = { |
672 | .id = AD7785_ID, |
673 | .channels = ad7785_channels, |
674 | .num_channels = ARRAY_SIZE(ad7785_channels), |
675 | .iio_info = &ad7793_info, |
676 | .sample_freq_avail = ad7793_sample_freq_avail, |
677 | .flags = AD7793_FLAG_HAS_CLKSEL | |
678 | AD7793_FLAG_HAS_REFSEL | |
679 | AD7793_FLAG_HAS_VBIAS | |
680 | AD7793_HAS_EXITATION_CURRENT | |
681 | AD7793_FLAG_HAS_GAIN | |
682 | AD7793_FLAG_HAS_BUFFER, |
683 | }, |
684 | [ID_AD7792] = { |
685 | .id = AD7792_ID, |
686 | .channels = ad7792_channels, |
687 | .num_channels = ARRAY_SIZE(ad7792_channels), |
688 | .iio_info = &ad7793_info, |
689 | .sample_freq_avail = ad7793_sample_freq_avail, |
690 | .flags = AD7793_FLAG_HAS_CLKSEL | |
691 | AD7793_FLAG_HAS_REFSEL | |
692 | AD7793_FLAG_HAS_VBIAS | |
693 | AD7793_HAS_EXITATION_CURRENT | |
694 | AD7793_FLAG_HAS_GAIN | |
695 | AD7793_FLAG_HAS_BUFFER, |
696 | }, |
697 | [ID_AD7793] = { |
698 | .id = AD7793_ID, |
699 | .channels = ad7793_channels, |
700 | .num_channels = ARRAY_SIZE(ad7793_channels), |
701 | .iio_info = &ad7793_info, |
702 | .sample_freq_avail = ad7793_sample_freq_avail, |
703 | .flags = AD7793_FLAG_HAS_CLKSEL | |
704 | AD7793_FLAG_HAS_REFSEL | |
705 | AD7793_FLAG_HAS_VBIAS | |
706 | AD7793_HAS_EXITATION_CURRENT | |
707 | AD7793_FLAG_HAS_GAIN | |
708 | AD7793_FLAG_HAS_BUFFER, |
709 | }, |
710 | [ID_AD7794] = { |
711 | .id = AD7794_ID, |
712 | .channels = ad7794_channels, |
713 | .num_channels = ARRAY_SIZE(ad7794_channels), |
714 | .iio_info = &ad7793_info, |
715 | .sample_freq_avail = ad7793_sample_freq_avail, |
716 | .flags = AD7793_FLAG_HAS_CLKSEL | |
717 | AD7793_FLAG_HAS_REFSEL | |
718 | AD7793_FLAG_HAS_VBIAS | |
719 | AD7793_HAS_EXITATION_CURRENT | |
720 | AD7793_FLAG_HAS_GAIN | |
721 | AD7793_FLAG_HAS_BUFFER, |
722 | }, |
723 | [ID_AD7795] = { |
724 | .id = AD7795_ID, |
725 | .channels = ad7795_channels, |
726 | .num_channels = ARRAY_SIZE(ad7795_channels), |
727 | .iio_info = &ad7793_info, |
728 | .sample_freq_avail = ad7793_sample_freq_avail, |
729 | .flags = AD7793_FLAG_HAS_CLKSEL | |
730 | AD7793_FLAG_HAS_REFSEL | |
731 | AD7793_FLAG_HAS_VBIAS | |
732 | AD7793_HAS_EXITATION_CURRENT | |
733 | AD7793_FLAG_HAS_GAIN | |
734 | AD7793_FLAG_HAS_BUFFER, |
735 | }, |
736 | [ID_AD7796] = { |
737 | .id = AD7796_ID, |
738 | .channels = ad7796_channels, |
739 | .num_channels = ARRAY_SIZE(ad7796_channels), |
740 | .iio_info = &ad7797_info, |
741 | .sample_freq_avail = ad7797_sample_freq_avail, |
742 | .flags = AD7793_FLAG_HAS_CLKSEL, |
743 | }, |
744 | [ID_AD7797] = { |
745 | .id = AD7797_ID, |
746 | .channels = ad7797_channels, |
747 | .num_channels = ARRAY_SIZE(ad7797_channels), |
748 | .iio_info = &ad7797_info, |
749 | .sample_freq_avail = ad7797_sample_freq_avail, |
750 | .flags = AD7793_FLAG_HAS_CLKSEL, |
751 | }, |
752 | [ID_AD7798] = { |
753 | .id = AD7798_ID, |
754 | .channels = ad7798_channels, |
755 | .num_channels = ARRAY_SIZE(ad7798_channels), |
756 | .iio_info = &ad7793_info, |
757 | .sample_freq_avail = ad7793_sample_freq_avail, |
758 | .flags = AD7793_FLAG_HAS_GAIN | |
759 | AD7793_FLAG_HAS_BUFFER, |
760 | }, |
761 | [ID_AD7799] = { |
762 | .id = AD7799_ID, |
763 | .channels = ad7799_channels, |
764 | .num_channels = ARRAY_SIZE(ad7799_channels), |
765 | .iio_info = &ad7793_info, |
766 | .sample_freq_avail = ad7793_sample_freq_avail, |
767 | .flags = AD7793_FLAG_HAS_GAIN | |
768 | AD7793_FLAG_HAS_BUFFER, |
769 | }, |
770 | }; |
771 | |
772 | static void ad7793_reg_disable(void *reg) |
773 | { |
774 | regulator_disable(regulator: reg); |
775 | } |
776 | |
777 | static int ad7793_probe(struct spi_device *spi) |
778 | { |
779 | const struct ad7793_platform_data *pdata = spi->dev.platform_data; |
780 | struct ad7793_state *st; |
781 | struct iio_dev *indio_dev; |
782 | int ret, vref_mv = 0; |
783 | |
784 | if (!pdata) { |
785 | dev_err(&spi->dev, "no platform data?\n" ); |
786 | return -ENODEV; |
787 | } |
788 | |
789 | if (!spi->irq) { |
790 | dev_err(&spi->dev, "no IRQ?\n" ); |
791 | return -ENODEV; |
792 | } |
793 | |
794 | indio_dev = devm_iio_device_alloc(parent: &spi->dev, sizeof_priv: sizeof(*st)); |
795 | if (indio_dev == NULL) |
796 | return -ENOMEM; |
797 | |
798 | st = iio_priv(indio_dev); |
799 | |
800 | ad_sd_init(sigma_delta: &st->sd, indio_dev, spi, info: &ad7793_sigma_delta_info); |
801 | |
802 | if (pdata->refsel != AD7793_REFSEL_INTERNAL) { |
803 | st->reg = devm_regulator_get(dev: &spi->dev, id: "refin" ); |
804 | if (IS_ERR(ptr: st->reg)) |
805 | return PTR_ERR(ptr: st->reg); |
806 | |
807 | ret = regulator_enable(regulator: st->reg); |
808 | if (ret) |
809 | return ret; |
810 | |
811 | ret = devm_add_action_or_reset(&spi->dev, ad7793_reg_disable, st->reg); |
812 | if (ret) |
813 | return ret; |
814 | |
815 | vref_mv = regulator_get_voltage(regulator: st->reg); |
816 | if (vref_mv < 0) |
817 | return vref_mv; |
818 | |
819 | vref_mv /= 1000; |
820 | } else { |
821 | vref_mv = 1170; /* Build-in ref */ |
822 | } |
823 | |
824 | st->chip_info = |
825 | &ad7793_chip_info_tbl[spi_get_device_id(sdev: spi)->driver_data]; |
826 | |
827 | indio_dev->name = spi_get_device_id(sdev: spi)->name; |
828 | indio_dev->modes = INDIO_DIRECT_MODE; |
829 | indio_dev->channels = st->chip_info->channels; |
830 | indio_dev->num_channels = st->chip_info->num_channels; |
831 | indio_dev->info = st->chip_info->iio_info; |
832 | |
833 | ret = devm_ad_sd_setup_buffer_and_trigger(dev: &spi->dev, indio_dev); |
834 | if (ret) |
835 | return ret; |
836 | |
837 | ret = ad7793_setup(indio_dev, pdata, vref_mv); |
838 | if (ret) |
839 | return ret; |
840 | |
841 | return devm_iio_device_register(&spi->dev, indio_dev); |
842 | } |
843 | |
844 | static const struct spi_device_id ad7793_id[] = { |
845 | {"ad7785" , ID_AD7785}, |
846 | {"ad7792" , ID_AD7792}, |
847 | {"ad7793" , ID_AD7793}, |
848 | {"ad7794" , ID_AD7794}, |
849 | {"ad7795" , ID_AD7795}, |
850 | {"ad7796" , ID_AD7796}, |
851 | {"ad7797" , ID_AD7797}, |
852 | {"ad7798" , ID_AD7798}, |
853 | {"ad7799" , ID_AD7799}, |
854 | {} |
855 | }; |
856 | MODULE_DEVICE_TABLE(spi, ad7793_id); |
857 | |
858 | static struct spi_driver ad7793_driver = { |
859 | .driver = { |
860 | .name = "ad7793" , |
861 | }, |
862 | .probe = ad7793_probe, |
863 | .id_table = ad7793_id, |
864 | }; |
865 | module_spi_driver(ad7793_driver); |
866 | |
867 | MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>" ); |
868 | MODULE_DESCRIPTION("Analog Devices AD7793 and similar ADCs" ); |
869 | MODULE_LICENSE("GPL v2" ); |
870 | MODULE_IMPORT_NS(IIO_AD_SIGMA_DELTA); |
871 | |