1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * AD7606 SPI ADC driver |
4 | * |
5 | * Copyright 2011 Analog Devices Inc. |
6 | */ |
7 | |
8 | #include <linux/delay.h> |
9 | #include <linux/device.h> |
10 | #include <linux/err.h> |
11 | #include <linux/gpio/consumer.h> |
12 | #include <linux/interrupt.h> |
13 | #include <linux/kernel.h> |
14 | #include <linux/module.h> |
15 | #include <linux/property.h> |
16 | #include <linux/regulator/consumer.h> |
17 | #include <linux/sched.h> |
18 | #include <linux/slab.h> |
19 | #include <linux/sysfs.h> |
20 | #include <linux/util_macros.h> |
21 | |
22 | #include <linux/iio/iio.h> |
23 | #include <linux/iio/buffer.h> |
24 | #include <linux/iio/sysfs.h> |
25 | #include <linux/iio/trigger.h> |
26 | #include <linux/iio/triggered_buffer.h> |
27 | #include <linux/iio/trigger_consumer.h> |
28 | |
29 | #include "ad7606.h" |
30 | |
31 | /* |
32 | * Scales are computed as 5000/32768 and 10000/32768 respectively, |
33 | * so that when applied to the raw values they provide mV values |
34 | */ |
35 | static const unsigned int ad7606_scale_avail[2] = { |
36 | 152588, 305176 |
37 | }; |
38 | |
39 | |
40 | static const unsigned int ad7616_sw_scale_avail[3] = { |
41 | 76293, 152588, 305176 |
42 | }; |
43 | |
44 | static const unsigned int ad7606_oversampling_avail[7] = { |
45 | 1, 2, 4, 8, 16, 32, 64, |
46 | }; |
47 | |
48 | static const unsigned int ad7616_oversampling_avail[8] = { |
49 | 1, 2, 4, 8, 16, 32, 64, 128, |
50 | }; |
51 | |
52 | static int ad7606_reset(struct ad7606_state *st) |
53 | { |
54 | if (st->gpio_reset) { |
55 | gpiod_set_value(desc: st->gpio_reset, value: 1); |
56 | ndelay(100); /* t_reset >= 100ns */ |
57 | gpiod_set_value(desc: st->gpio_reset, value: 0); |
58 | return 0; |
59 | } |
60 | |
61 | return -ENODEV; |
62 | } |
63 | |
64 | static int ad7606_reg_access(struct iio_dev *indio_dev, |
65 | unsigned int reg, |
66 | unsigned int writeval, |
67 | unsigned int *readval) |
68 | { |
69 | struct ad7606_state *st = iio_priv(indio_dev); |
70 | int ret; |
71 | |
72 | mutex_lock(&st->lock); |
73 | if (readval) { |
74 | ret = st->bops->reg_read(st, reg); |
75 | if (ret < 0) |
76 | goto err_unlock; |
77 | *readval = ret; |
78 | ret = 0; |
79 | } else { |
80 | ret = st->bops->reg_write(st, reg, writeval); |
81 | } |
82 | err_unlock: |
83 | mutex_unlock(lock: &st->lock); |
84 | return ret; |
85 | } |
86 | |
87 | static int ad7606_read_samples(struct ad7606_state *st) |
88 | { |
89 | unsigned int num = st->chip_info->num_channels - 1; |
90 | u16 *data = st->data; |
91 | int ret; |
92 | |
93 | /* |
94 | * The frstdata signal is set to high while and after reading the sample |
95 | * of the first channel and low for all other channels. This can be used |
96 | * to check that the incoming data is correctly aligned. During normal |
97 | * operation the data should never become unaligned, but some glitch or |
98 | * electrostatic discharge might cause an extra read or clock cycle. |
99 | * Monitoring the frstdata signal allows to recover from such failure |
100 | * situations. |
101 | */ |
102 | |
103 | if (st->gpio_frstdata) { |
104 | ret = st->bops->read_block(st->dev, 1, data); |
105 | if (ret) |
106 | return ret; |
107 | |
108 | if (!gpiod_get_value(desc: st->gpio_frstdata)) { |
109 | ad7606_reset(st); |
110 | return -EIO; |
111 | } |
112 | |
113 | data++; |
114 | num--; |
115 | } |
116 | |
117 | return st->bops->read_block(st->dev, num, data); |
118 | } |
119 | |
120 | static irqreturn_t ad7606_trigger_handler(int irq, void *p) |
121 | { |
122 | struct iio_poll_func *pf = p; |
123 | struct iio_dev *indio_dev = pf->indio_dev; |
124 | struct ad7606_state *st = iio_priv(indio_dev); |
125 | int ret; |
126 | |
127 | mutex_lock(&st->lock); |
128 | |
129 | ret = ad7606_read_samples(st); |
130 | if (ret == 0) |
131 | iio_push_to_buffers_with_timestamp(indio_dev, data: st->data, |
132 | timestamp: iio_get_time_ns(indio_dev)); |
133 | |
134 | iio_trigger_notify_done(trig: indio_dev->trig); |
135 | /* The rising edge of the CONVST signal starts a new conversion. */ |
136 | gpiod_set_value(desc: st->gpio_convst, value: 1); |
137 | |
138 | mutex_unlock(lock: &st->lock); |
139 | |
140 | return IRQ_HANDLED; |
141 | } |
142 | |
143 | static int ad7606_scan_direct(struct iio_dev *indio_dev, unsigned int ch) |
144 | { |
145 | struct ad7606_state *st = iio_priv(indio_dev); |
146 | int ret; |
147 | |
148 | gpiod_set_value(desc: st->gpio_convst, value: 1); |
149 | ret = wait_for_completion_timeout(x: &st->completion, |
150 | timeout: msecs_to_jiffies(m: 1000)); |
151 | if (!ret) { |
152 | ret = -ETIMEDOUT; |
153 | goto error_ret; |
154 | } |
155 | |
156 | ret = ad7606_read_samples(st); |
157 | if (ret == 0) |
158 | ret = st->data[ch]; |
159 | |
160 | error_ret: |
161 | gpiod_set_value(desc: st->gpio_convst, value: 0); |
162 | |
163 | return ret; |
164 | } |
165 | |
166 | static int ad7606_read_raw(struct iio_dev *indio_dev, |
167 | struct iio_chan_spec const *chan, |
168 | int *val, |
169 | int *val2, |
170 | long m) |
171 | { |
172 | int ret, ch = 0; |
173 | struct ad7606_state *st = iio_priv(indio_dev); |
174 | |
175 | switch (m) { |
176 | case IIO_CHAN_INFO_RAW: |
177 | ret = iio_device_claim_direct_mode(indio_dev); |
178 | if (ret) |
179 | return ret; |
180 | |
181 | ret = ad7606_scan_direct(indio_dev, ch: chan->address); |
182 | iio_device_release_direct_mode(indio_dev); |
183 | |
184 | if (ret < 0) |
185 | return ret; |
186 | *val = (short)ret; |
187 | return IIO_VAL_INT; |
188 | case IIO_CHAN_INFO_SCALE: |
189 | if (st->sw_mode_en) |
190 | ch = chan->address; |
191 | *val = 0; |
192 | *val2 = st->scale_avail[st->range[ch]]; |
193 | return IIO_VAL_INT_PLUS_MICRO; |
194 | case IIO_CHAN_INFO_OVERSAMPLING_RATIO: |
195 | *val = st->oversampling; |
196 | return IIO_VAL_INT; |
197 | } |
198 | return -EINVAL; |
199 | } |
200 | |
201 | static ssize_t ad7606_show_avail(char *buf, const unsigned int *vals, |
202 | unsigned int n, bool micros) |
203 | { |
204 | size_t len = 0; |
205 | int i; |
206 | |
207 | for (i = 0; i < n; i++) { |
208 | len += scnprintf(buf: buf + len, PAGE_SIZE - len, |
209 | fmt: micros ? "0.%06u " : "%u " , vals[i]); |
210 | } |
211 | buf[len - 1] = '\n'; |
212 | |
213 | return len; |
214 | } |
215 | |
216 | static ssize_t in_voltage_scale_available_show(struct device *dev, |
217 | struct device_attribute *attr, |
218 | char *buf) |
219 | { |
220 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); |
221 | struct ad7606_state *st = iio_priv(indio_dev); |
222 | |
223 | return ad7606_show_avail(buf, vals: st->scale_avail, n: st->num_scales, micros: true); |
224 | } |
225 | |
226 | static IIO_DEVICE_ATTR_RO(in_voltage_scale_available, 0); |
227 | |
228 | static int ad7606_write_scale_hw(struct iio_dev *indio_dev, int ch, int val) |
229 | { |
230 | struct ad7606_state *st = iio_priv(indio_dev); |
231 | |
232 | gpiod_set_value(desc: st->gpio_range, value: val); |
233 | |
234 | return 0; |
235 | } |
236 | |
237 | static int ad7606_write_os_hw(struct iio_dev *indio_dev, int val) |
238 | { |
239 | struct ad7606_state *st = iio_priv(indio_dev); |
240 | DECLARE_BITMAP(values, 3); |
241 | |
242 | values[0] = val; |
243 | |
244 | gpiod_set_array_value(ARRAY_SIZE(values), desc_array: st->gpio_os->desc, |
245 | array_info: st->gpio_os->info, value_bitmap: values); |
246 | |
247 | /* AD7616 requires a reset to update value */ |
248 | if (st->chip_info->os_req_reset) |
249 | ad7606_reset(st); |
250 | |
251 | return 0; |
252 | } |
253 | |
254 | static int ad7606_write_raw(struct iio_dev *indio_dev, |
255 | struct iio_chan_spec const *chan, |
256 | int val, |
257 | int val2, |
258 | long mask) |
259 | { |
260 | struct ad7606_state *st = iio_priv(indio_dev); |
261 | int i, ret, ch = 0; |
262 | |
263 | switch (mask) { |
264 | case IIO_CHAN_INFO_SCALE: |
265 | mutex_lock(&st->lock); |
266 | i = find_closest(val2, st->scale_avail, st->num_scales); |
267 | if (st->sw_mode_en) |
268 | ch = chan->address; |
269 | ret = st->write_scale(indio_dev, ch, i); |
270 | if (ret < 0) { |
271 | mutex_unlock(lock: &st->lock); |
272 | return ret; |
273 | } |
274 | st->range[ch] = i; |
275 | mutex_unlock(lock: &st->lock); |
276 | |
277 | return 0; |
278 | case IIO_CHAN_INFO_OVERSAMPLING_RATIO: |
279 | if (val2) |
280 | return -EINVAL; |
281 | i = find_closest(val, st->oversampling_avail, |
282 | st->num_os_ratios); |
283 | mutex_lock(&st->lock); |
284 | ret = st->write_os(indio_dev, i); |
285 | if (ret < 0) { |
286 | mutex_unlock(lock: &st->lock); |
287 | return ret; |
288 | } |
289 | st->oversampling = st->oversampling_avail[i]; |
290 | mutex_unlock(lock: &st->lock); |
291 | |
292 | return 0; |
293 | default: |
294 | return -EINVAL; |
295 | } |
296 | } |
297 | |
298 | static ssize_t ad7606_oversampling_ratio_avail(struct device *dev, |
299 | struct device_attribute *attr, |
300 | char *buf) |
301 | { |
302 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); |
303 | struct ad7606_state *st = iio_priv(indio_dev); |
304 | |
305 | return ad7606_show_avail(buf, vals: st->oversampling_avail, |
306 | n: st->num_os_ratios, micros: false); |
307 | } |
308 | |
309 | static IIO_DEVICE_ATTR(oversampling_ratio_available, 0444, |
310 | ad7606_oversampling_ratio_avail, NULL, 0); |
311 | |
312 | static struct attribute *ad7606_attributes_os_and_range[] = { |
313 | &iio_dev_attr_in_voltage_scale_available.dev_attr.attr, |
314 | &iio_dev_attr_oversampling_ratio_available.dev_attr.attr, |
315 | NULL, |
316 | }; |
317 | |
318 | static const struct attribute_group ad7606_attribute_group_os_and_range = { |
319 | .attrs = ad7606_attributes_os_and_range, |
320 | }; |
321 | |
322 | static struct attribute *ad7606_attributes_os[] = { |
323 | &iio_dev_attr_oversampling_ratio_available.dev_attr.attr, |
324 | NULL, |
325 | }; |
326 | |
327 | static const struct attribute_group ad7606_attribute_group_os = { |
328 | .attrs = ad7606_attributes_os, |
329 | }; |
330 | |
331 | static struct attribute *ad7606_attributes_range[] = { |
332 | &iio_dev_attr_in_voltage_scale_available.dev_attr.attr, |
333 | NULL, |
334 | }; |
335 | |
336 | static const struct attribute_group ad7606_attribute_group_range = { |
337 | .attrs = ad7606_attributes_range, |
338 | }; |
339 | |
340 | static const struct iio_chan_spec ad7605_channels[] = { |
341 | IIO_CHAN_SOFT_TIMESTAMP(4), |
342 | AD7605_CHANNEL(0), |
343 | AD7605_CHANNEL(1), |
344 | AD7605_CHANNEL(2), |
345 | AD7605_CHANNEL(3), |
346 | }; |
347 | |
348 | static const struct iio_chan_spec ad7606_channels[] = { |
349 | IIO_CHAN_SOFT_TIMESTAMP(8), |
350 | AD7606_CHANNEL(0), |
351 | AD7606_CHANNEL(1), |
352 | AD7606_CHANNEL(2), |
353 | AD7606_CHANNEL(3), |
354 | AD7606_CHANNEL(4), |
355 | AD7606_CHANNEL(5), |
356 | AD7606_CHANNEL(6), |
357 | AD7606_CHANNEL(7), |
358 | }; |
359 | |
360 | /* |
361 | * The current assumption that this driver makes for AD7616, is that it's |
362 | * working in Hardware Mode with Serial, Burst and Sequencer modes activated. |
363 | * To activate them, following pins must be pulled high: |
364 | * -SER/PAR |
365 | * -SEQEN |
366 | * And following pins must be pulled low: |
367 | * -WR/BURST |
368 | * -DB4/SER1W |
369 | */ |
370 | static const struct iio_chan_spec ad7616_channels[] = { |
371 | IIO_CHAN_SOFT_TIMESTAMP(16), |
372 | AD7606_CHANNEL(0), |
373 | AD7606_CHANNEL(1), |
374 | AD7606_CHANNEL(2), |
375 | AD7606_CHANNEL(3), |
376 | AD7606_CHANNEL(4), |
377 | AD7606_CHANNEL(5), |
378 | AD7606_CHANNEL(6), |
379 | AD7606_CHANNEL(7), |
380 | AD7606_CHANNEL(8), |
381 | AD7606_CHANNEL(9), |
382 | AD7606_CHANNEL(10), |
383 | AD7606_CHANNEL(11), |
384 | AD7606_CHANNEL(12), |
385 | AD7606_CHANNEL(13), |
386 | AD7606_CHANNEL(14), |
387 | AD7606_CHANNEL(15), |
388 | }; |
389 | |
390 | static const struct ad7606_chip_info ad7606_chip_info_tbl[] = { |
391 | /* More devices added in future */ |
392 | [ID_AD7605_4] = { |
393 | .channels = ad7605_channels, |
394 | .num_channels = 5, |
395 | }, |
396 | [ID_AD7606_8] = { |
397 | .channels = ad7606_channels, |
398 | .num_channels = 9, |
399 | .oversampling_avail = ad7606_oversampling_avail, |
400 | .oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail), |
401 | }, |
402 | [ID_AD7606_6] = { |
403 | .channels = ad7606_channels, |
404 | .num_channels = 7, |
405 | .oversampling_avail = ad7606_oversampling_avail, |
406 | .oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail), |
407 | }, |
408 | [ID_AD7606_4] = { |
409 | .channels = ad7606_channels, |
410 | .num_channels = 5, |
411 | .oversampling_avail = ad7606_oversampling_avail, |
412 | .oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail), |
413 | }, |
414 | [ID_AD7606B] = { |
415 | .channels = ad7606_channels, |
416 | .num_channels = 9, |
417 | .oversampling_avail = ad7606_oversampling_avail, |
418 | .oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail), |
419 | }, |
420 | [ID_AD7616] = { |
421 | .channels = ad7616_channels, |
422 | .num_channels = 17, |
423 | .oversampling_avail = ad7616_oversampling_avail, |
424 | .oversampling_num = ARRAY_SIZE(ad7616_oversampling_avail), |
425 | .os_req_reset = true, |
426 | .init_delay_ms = 15, |
427 | }, |
428 | }; |
429 | |
430 | static int ad7606_request_gpios(struct ad7606_state *st) |
431 | { |
432 | struct device *dev = st->dev; |
433 | |
434 | st->gpio_convst = devm_gpiod_get(dev, con_id: "adi,conversion-start" , |
435 | flags: GPIOD_OUT_LOW); |
436 | if (IS_ERR(ptr: st->gpio_convst)) |
437 | return PTR_ERR(ptr: st->gpio_convst); |
438 | |
439 | st->gpio_reset = devm_gpiod_get_optional(dev, con_id: "reset" , flags: GPIOD_OUT_LOW); |
440 | if (IS_ERR(ptr: st->gpio_reset)) |
441 | return PTR_ERR(ptr: st->gpio_reset); |
442 | |
443 | st->gpio_range = devm_gpiod_get_optional(dev, con_id: "adi,range" , |
444 | flags: GPIOD_OUT_LOW); |
445 | if (IS_ERR(ptr: st->gpio_range)) |
446 | return PTR_ERR(ptr: st->gpio_range); |
447 | |
448 | st->gpio_standby = devm_gpiod_get_optional(dev, con_id: "standby" , |
449 | flags: GPIOD_OUT_HIGH); |
450 | if (IS_ERR(ptr: st->gpio_standby)) |
451 | return PTR_ERR(ptr: st->gpio_standby); |
452 | |
453 | st->gpio_frstdata = devm_gpiod_get_optional(dev, con_id: "adi,first-data" , |
454 | flags: GPIOD_IN); |
455 | if (IS_ERR(ptr: st->gpio_frstdata)) |
456 | return PTR_ERR(ptr: st->gpio_frstdata); |
457 | |
458 | if (!st->chip_info->oversampling_num) |
459 | return 0; |
460 | |
461 | st->gpio_os = devm_gpiod_get_array_optional(dev, |
462 | con_id: "adi,oversampling-ratio" , |
463 | flags: GPIOD_OUT_LOW); |
464 | return PTR_ERR_OR_ZERO(ptr: st->gpio_os); |
465 | } |
466 | |
467 | /* |
468 | * The BUSY signal indicates when conversions are in progress, so when a rising |
469 | * edge of CONVST is applied, BUSY goes logic high and transitions low at the |
470 | * end of the entire conversion process. The falling edge of the BUSY signal |
471 | * triggers this interrupt. |
472 | */ |
473 | static irqreturn_t ad7606_interrupt(int irq, void *dev_id) |
474 | { |
475 | struct iio_dev *indio_dev = dev_id; |
476 | struct ad7606_state *st = iio_priv(indio_dev); |
477 | |
478 | if (iio_buffer_enabled(indio_dev)) { |
479 | gpiod_set_value(desc: st->gpio_convst, value: 0); |
480 | iio_trigger_poll_nested(trig: st->trig); |
481 | } else { |
482 | complete(&st->completion); |
483 | } |
484 | |
485 | return IRQ_HANDLED; |
486 | }; |
487 | |
488 | static int ad7606_validate_trigger(struct iio_dev *indio_dev, |
489 | struct iio_trigger *trig) |
490 | { |
491 | struct ad7606_state *st = iio_priv(indio_dev); |
492 | |
493 | if (st->trig != trig) |
494 | return -EINVAL; |
495 | |
496 | return 0; |
497 | } |
498 | |
499 | static int ad7606_buffer_postenable(struct iio_dev *indio_dev) |
500 | { |
501 | struct ad7606_state *st = iio_priv(indio_dev); |
502 | |
503 | gpiod_set_value(desc: st->gpio_convst, value: 1); |
504 | |
505 | return 0; |
506 | } |
507 | |
508 | static int ad7606_buffer_predisable(struct iio_dev *indio_dev) |
509 | { |
510 | struct ad7606_state *st = iio_priv(indio_dev); |
511 | |
512 | gpiod_set_value(desc: st->gpio_convst, value: 0); |
513 | |
514 | return 0; |
515 | } |
516 | |
517 | static const struct iio_buffer_setup_ops ad7606_buffer_ops = { |
518 | .postenable = &ad7606_buffer_postenable, |
519 | .predisable = &ad7606_buffer_predisable, |
520 | }; |
521 | |
522 | static const struct iio_info ad7606_info_no_os_or_range = { |
523 | .read_raw = &ad7606_read_raw, |
524 | .validate_trigger = &ad7606_validate_trigger, |
525 | }; |
526 | |
527 | static const struct iio_info ad7606_info_os_and_range = { |
528 | .read_raw = &ad7606_read_raw, |
529 | .write_raw = &ad7606_write_raw, |
530 | .attrs = &ad7606_attribute_group_os_and_range, |
531 | .validate_trigger = &ad7606_validate_trigger, |
532 | }; |
533 | |
534 | static const struct iio_info ad7606_info_os_range_and_debug = { |
535 | .read_raw = &ad7606_read_raw, |
536 | .write_raw = &ad7606_write_raw, |
537 | .debugfs_reg_access = &ad7606_reg_access, |
538 | .attrs = &ad7606_attribute_group_os_and_range, |
539 | .validate_trigger = &ad7606_validate_trigger, |
540 | }; |
541 | |
542 | static const struct iio_info ad7606_info_os = { |
543 | .read_raw = &ad7606_read_raw, |
544 | .write_raw = &ad7606_write_raw, |
545 | .attrs = &ad7606_attribute_group_os, |
546 | .validate_trigger = &ad7606_validate_trigger, |
547 | }; |
548 | |
549 | static const struct iio_info ad7606_info_range = { |
550 | .read_raw = &ad7606_read_raw, |
551 | .write_raw = &ad7606_write_raw, |
552 | .attrs = &ad7606_attribute_group_range, |
553 | .validate_trigger = &ad7606_validate_trigger, |
554 | }; |
555 | |
556 | static const struct iio_trigger_ops ad7606_trigger_ops = { |
557 | .validate_device = iio_trigger_validate_own_device, |
558 | }; |
559 | |
560 | int ad7606_probe(struct device *dev, int irq, void __iomem *base_address, |
561 | const char *name, unsigned int id, |
562 | const struct ad7606_bus_ops *bops) |
563 | { |
564 | struct ad7606_state *st; |
565 | int ret; |
566 | struct iio_dev *indio_dev; |
567 | |
568 | indio_dev = devm_iio_device_alloc(parent: dev, sizeof_priv: sizeof(*st)); |
569 | if (!indio_dev) |
570 | return -ENOMEM; |
571 | |
572 | st = iio_priv(indio_dev); |
573 | dev_set_drvdata(dev, data: indio_dev); |
574 | |
575 | st->dev = dev; |
576 | mutex_init(&st->lock); |
577 | st->bops = bops; |
578 | st->base_address = base_address; |
579 | /* tied to logic low, analog input range is +/- 5V */ |
580 | st->range[0] = 0; |
581 | st->oversampling = 1; |
582 | st->scale_avail = ad7606_scale_avail; |
583 | st->num_scales = ARRAY_SIZE(ad7606_scale_avail); |
584 | |
585 | ret = devm_regulator_get_enable(dev, id: "avcc" ); |
586 | if (ret) |
587 | return dev_err_probe(dev, err: ret, |
588 | fmt: "Failed to enable specified AVcc supply\n" ); |
589 | |
590 | st->chip_info = &ad7606_chip_info_tbl[id]; |
591 | |
592 | if (st->chip_info->oversampling_num) { |
593 | st->oversampling_avail = st->chip_info->oversampling_avail; |
594 | st->num_os_ratios = st->chip_info->oversampling_num; |
595 | } |
596 | |
597 | ret = ad7606_request_gpios(st); |
598 | if (ret) |
599 | return ret; |
600 | |
601 | if (st->gpio_os) { |
602 | if (st->gpio_range) |
603 | indio_dev->info = &ad7606_info_os_and_range; |
604 | else |
605 | indio_dev->info = &ad7606_info_os; |
606 | } else { |
607 | if (st->gpio_range) |
608 | indio_dev->info = &ad7606_info_range; |
609 | else |
610 | indio_dev->info = &ad7606_info_no_os_or_range; |
611 | } |
612 | indio_dev->modes = INDIO_DIRECT_MODE; |
613 | indio_dev->name = name; |
614 | indio_dev->channels = st->chip_info->channels; |
615 | indio_dev->num_channels = st->chip_info->num_channels; |
616 | |
617 | init_completion(x: &st->completion); |
618 | |
619 | ret = ad7606_reset(st); |
620 | if (ret) |
621 | dev_warn(st->dev, "failed to RESET: no RESET GPIO specified\n" ); |
622 | |
623 | /* AD7616 requires al least 15ms to reconfigure after a reset */ |
624 | if (st->chip_info->init_delay_ms) { |
625 | if (msleep_interruptible(msecs: st->chip_info->init_delay_ms)) |
626 | return -ERESTARTSYS; |
627 | } |
628 | |
629 | st->write_scale = ad7606_write_scale_hw; |
630 | st->write_os = ad7606_write_os_hw; |
631 | |
632 | if (st->bops->sw_mode_config) |
633 | st->sw_mode_en = device_property_present(dev: st->dev, |
634 | propname: "adi,sw-mode" ); |
635 | |
636 | if (st->sw_mode_en) { |
637 | /* Scale of 0.076293 is only available in sw mode */ |
638 | st->scale_avail = ad7616_sw_scale_avail; |
639 | st->num_scales = ARRAY_SIZE(ad7616_sw_scale_avail); |
640 | |
641 | /* After reset, in software mode, ±10 V is set by default */ |
642 | memset32(s: st->range, v: 2, ARRAY_SIZE(st->range)); |
643 | indio_dev->info = &ad7606_info_os_range_and_debug; |
644 | |
645 | ret = st->bops->sw_mode_config(indio_dev); |
646 | if (ret < 0) |
647 | return ret; |
648 | } |
649 | |
650 | st->trig = devm_iio_trigger_alloc(dev, "%s-dev%d" , |
651 | indio_dev->name, |
652 | iio_device_id(indio_dev)); |
653 | if (!st->trig) |
654 | return -ENOMEM; |
655 | |
656 | st->trig->ops = &ad7606_trigger_ops; |
657 | iio_trigger_set_drvdata(trig: st->trig, data: indio_dev); |
658 | ret = devm_iio_trigger_register(dev, trig_info: st->trig); |
659 | if (ret) |
660 | return ret; |
661 | |
662 | indio_dev->trig = iio_trigger_get(trig: st->trig); |
663 | |
664 | ret = devm_request_threaded_irq(dev, irq, |
665 | NULL, |
666 | thread_fn: &ad7606_interrupt, |
667 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, |
668 | devname: name, dev_id: indio_dev); |
669 | if (ret) |
670 | return ret; |
671 | |
672 | ret = devm_iio_triggered_buffer_setup(dev, indio_dev, |
673 | &iio_pollfunc_store_time, |
674 | &ad7606_trigger_handler, |
675 | &ad7606_buffer_ops); |
676 | if (ret) |
677 | return ret; |
678 | |
679 | return devm_iio_device_register(dev, indio_dev); |
680 | } |
681 | EXPORT_SYMBOL_NS_GPL(ad7606_probe, IIO_AD7606); |
682 | |
683 | #ifdef CONFIG_PM_SLEEP |
684 | |
685 | static int ad7606_suspend(struct device *dev) |
686 | { |
687 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
688 | struct ad7606_state *st = iio_priv(indio_dev); |
689 | |
690 | if (st->gpio_standby) { |
691 | gpiod_set_value(desc: st->gpio_range, value: 1); |
692 | gpiod_set_value(desc: st->gpio_standby, value: 0); |
693 | } |
694 | |
695 | return 0; |
696 | } |
697 | |
698 | static int ad7606_resume(struct device *dev) |
699 | { |
700 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
701 | struct ad7606_state *st = iio_priv(indio_dev); |
702 | |
703 | if (st->gpio_standby) { |
704 | gpiod_set_value(desc: st->gpio_range, value: st->range[0]); |
705 | gpiod_set_value(desc: st->gpio_standby, value: 1); |
706 | ad7606_reset(st); |
707 | } |
708 | |
709 | return 0; |
710 | } |
711 | |
712 | SIMPLE_DEV_PM_OPS(ad7606_pm_ops, ad7606_suspend, ad7606_resume); |
713 | EXPORT_SYMBOL_NS_GPL(ad7606_pm_ops, IIO_AD7606); |
714 | |
715 | #endif |
716 | |
717 | MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>" ); |
718 | MODULE_DESCRIPTION("Analog Devices AD7606 ADC" ); |
719 | MODULE_LICENSE("GPL v2" ); |
720 | |