aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iio
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2012-08-10 12:36:00 -0400
committerJonathan Cameron <jic23@kernel.org>2012-08-27 12:53:12 -0400
commitaf3008485ea0372fb9ce1f69f3768617d39eb4e6 (patch)
treed6c6ca6ed6f6ec0a84e43827503870fd05bb7fac /drivers/iio
parent2d66f389ccf2c3ffea93c0270ef34186e4995333 (diff)
iio:adc: Add common code for ADI Sigma Delta devices
Most devices from the Analog Devices Sigma Delta family use a similar scheme for communication with the device. This includes register access, as well as trigger handling. But each device sub-family has different features and different register layouts (some even have no registers at all) and thus it is impractical to try to support all of the devices by the same driver. This patch adds a common base library for Sigma Delta converter devices. It will be used by individual drivers. This code is mostly based on the three existing Sigma Delta drivers the AD7192, AD7780 and AD7793, but has been improved for more robustness and flexibility. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Diffstat (limited to 'drivers/iio')
-rw-r--r--drivers/iio/adc/Kconfig5
-rw-r--r--drivers/iio/adc/Makefile1
-rw-r--r--drivers/iio/adc/ad_sigma_delta.c558
3 files changed, 564 insertions, 0 deletions
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 8a78b4f3ef58..a2c50713b0b6 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -3,6 +3,11 @@
3# 3#
4menu "Analog to digital converters" 4menu "Analog to digital converters"
5 5
6config AD_SIGMA_DELTA
7 tristate
8 select IIO_BUFFER
9 select IIO_TRIGGERED_BUFFER
10
6config AD7266 11config AD7266
7 tristate "Analog Devices AD7265/AD7266 ADC driver" 12 tristate "Analog Devices AD7265/AD7266 ADC driver"
8 depends on SPI_MASTER 13 depends on SPI_MASTER
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 52eec254c38c..5989356c5735 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -2,5 +2,6 @@
2# Makefile for IIO ADC drivers 2# Makefile for IIO ADC drivers
3# 3#
4 4
5obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o
5obj-$(CONFIG_AD7266) += ad7266.o 6obj-$(CONFIG_AD7266) += ad7266.o
6obj-$(CONFIG_AT91_ADC) += at91_adc.o 7obj-$(CONFIG_AT91_ADC) += at91_adc.o
diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c
new file mode 100644
index 000000000000..ae847c5a1361
--- /dev/null
+++ b/drivers/iio/adc/ad_sigma_delta.c
@@ -0,0 +1,558 @@
1/*
2 * Support code for Analog Devices Sigma-Delta ADCs
3 *
4 * Copyright 2012 Analog Devices Inc.
5 * Author: Lars-Peter Clausen <lars@metafoo.de>
6 *
7 * Licensed under the GPL-2.
8 */
9
10#include <linux/interrupt.h>
11#include <linux/device.h>
12#include <linux/kernel.h>
13#include <linux/slab.h>
14#include <linux/spi/spi.h>
15#include <linux/err.h>
16#include <linux/module.h>
17
18#include <linux/iio/iio.h>
19#include <linux/iio/sysfs.h>
20#include <linux/iio/buffer.h>
21#include <linux/iio/trigger.h>
22#include <linux/iio/trigger_consumer.h>
23#include <linux/iio/triggered_buffer.h>
24#include <linux/iio/adc/ad_sigma_delta.h>
25
26#include <asm/unaligned.h>
27
28
29#define AD_SD_COMM_CHAN_MASK 0x3
30
31#define AD_SD_REG_COMM 0x00
32#define AD_SD_REG_DATA 0x03
33
34/**
35 * ad_sd_set_comm() - Set communications register
36 *
37 * @sigma_delta: The sigma delta device
38 * @comm: New value for the communications register
39 */
40void ad_sd_set_comm(struct ad_sigma_delta *sigma_delta, uint8_t comm)
41{
42 /* Some variants use the lower two bits of the communications register
43 * to select the channel */
44 sigma_delta->comm = comm & AD_SD_COMM_CHAN_MASK;
45}
46EXPORT_SYMBOL_GPL(ad_sd_set_comm);
47
48/**
49 * ad_sd_write_reg() - Write a register
50 *
51 * @sigma_delta: The sigma delta device
52 * @reg: Address of the register
53 * @size: Size of the register (0-3)
54 * @val: Value to write to the register
55 *
56 * Returns 0 on success, an error code otherwise.
57 **/
58int ad_sd_write_reg(struct ad_sigma_delta *sigma_delta, unsigned int reg,
59 unsigned int size, unsigned int val)
60{
61 uint8_t *data = sigma_delta->data;
62 struct spi_transfer t = {
63 .tx_buf = data,
64 .len = size + 1,
65 .cs_change = sigma_delta->bus_locked,
66 };
67 struct spi_message m;
68 int ret;
69
70 data[0] = (reg << sigma_delta->info->addr_shift) | sigma_delta->comm;
71
72 switch (size) {
73 case 3:
74 data[1] = val >> 16;
75 data[2] = val >> 8;
76 data[3] = val;
77 break;
78 case 2:
79 put_unaligned_be16(val, &data[1]);
80 break;
81 case 1:
82 data[1] = val;
83 break;
84 case 0:
85 break;
86 default:
87 return -EINVAL;
88 }
89
90 spi_message_init(&m);
91 spi_message_add_tail(&t, &m);
92
93 if (sigma_delta->bus_locked)
94 ret = spi_sync_locked(sigma_delta->spi, &m);
95 else
96 ret = spi_sync(sigma_delta->spi, &m);
97
98 return ret;
99}
100EXPORT_SYMBOL_GPL(ad_sd_write_reg);
101
102static int ad_sd_read_reg_raw(struct ad_sigma_delta *sigma_delta,
103 unsigned int reg, unsigned int size, uint8_t *val)
104{
105 uint8_t *data = sigma_delta->data;
106 int ret;
107 struct spi_transfer t[] = {
108 {
109 .tx_buf = data,
110 .len = 1,
111 }, {
112 .rx_buf = val,
113 .len = size,
114 .cs_change = sigma_delta->bus_locked,
115 },
116 };
117 struct spi_message m;
118
119 spi_message_init(&m);
120
121 if (sigma_delta->info->has_registers) {
122 data[0] = reg << sigma_delta->info->addr_shift;
123 data[0] |= sigma_delta->info->read_mask;
124 spi_message_add_tail(&t[0], &m);
125 }
126 spi_message_add_tail(&t[1], &m);
127
128 if (sigma_delta->bus_locked)
129 ret = spi_sync_locked(sigma_delta->spi, &m);
130 else
131 ret = spi_sync(sigma_delta->spi, &m);
132
133 return ret;
134}
135
136/**
137 * ad_sd_read_reg() - Read a register
138 *
139 * @sigma_delta: The sigma delta device
140 * @reg: Address of the register
141 * @size: Size of the register (1-4)
142 * @val: Read value
143 *
144 * Returns 0 on success, an error code otherwise.
145 **/
146int ad_sd_read_reg(struct ad_sigma_delta *sigma_delta,
147 unsigned int reg, unsigned int size, unsigned int *val)
148{
149 int ret;
150
151 ret = ad_sd_read_reg_raw(sigma_delta, reg, size, sigma_delta->data);
152 if (ret < 0)
153 goto out;
154
155 switch (size) {
156 case 4:
157 *val = get_unaligned_be32(sigma_delta->data);
158 break;
159 case 3:
160 *val = (sigma_delta->data[0] << 16) |
161 (sigma_delta->data[1] << 8) |
162 sigma_delta->data[2];
163 break;
164 case 2:
165 *val = get_unaligned_be16(sigma_delta->data);
166 break;
167 case 1:
168 *val = sigma_delta->data[0];
169 break;
170 default:
171 ret = -EINVAL;
172 break;
173 }
174
175out:
176 return ret;
177}
178EXPORT_SYMBOL_GPL(ad_sd_read_reg);
179
180static int ad_sd_calibrate(struct ad_sigma_delta *sigma_delta,
181 unsigned int mode, unsigned int channel)
182{
183 int ret;
184
185 ret = ad_sigma_delta_set_channel(sigma_delta, channel);
186 if (ret)
187 return ret;
188
189 spi_bus_lock(sigma_delta->spi->master);
190 sigma_delta->bus_locked = true;
191 INIT_COMPLETION(sigma_delta->completion);
192
193 ret = ad_sigma_delta_set_mode(sigma_delta, mode);
194 if (ret < 0)
195 goto out;
196
197 sigma_delta->irq_dis = false;
198 enable_irq(sigma_delta->spi->irq);
199 ret = wait_for_completion_timeout(&sigma_delta->completion, 2*HZ);
200 if (ret == 0) {
201 sigma_delta->irq_dis = true;
202 disable_irq_nosync(sigma_delta->spi->irq);
203 ret = -EIO;
204 } else {
205 ret = 0;
206 }
207out:
208 sigma_delta->bus_locked = false;
209 spi_bus_unlock(sigma_delta->spi->master);
210 ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE);
211
212 return ret;
213}
214
215/**
216 * ad_sd_calibrate_all() - Performs channel calibration
217 * @sigma_delta: The sigma delta device
218 * @cb: Array of channels and calibration type to perform
219 * @n: Number of items in cb
220 *
221 * Returns 0 on success, an error code otherwise.
222 **/
223int ad_sd_calibrate_all(struct ad_sigma_delta *sigma_delta,
224 const struct ad_sd_calib_data *cb, unsigned int n)
225{
226 unsigned int i;
227 int ret;
228
229 for (i = 0; i < n; i++) {
230 ret = ad_sd_calibrate(sigma_delta, cb[i].mode, cb[i].channel);
231 if (ret)
232 return ret;
233 }
234
235 return 0;
236}
237EXPORT_SYMBOL_GPL(ad_sd_calibrate_all);
238
239/**
240 * ad_sigma_delta_single_conversion() - Performs a single data conversion
241 * @indio_dev: The IIO device
242 * @chan: The conversion is done for this channel
243 * @val: Pointer to the location where to store the read value
244 *
245 * Returns: 0 on success, an error value otherwise.
246 */
247int ad_sigma_delta_single_conversion(struct iio_dev *indio_dev,
248 const struct iio_chan_spec *chan, int *val)
249{
250 struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
251 unsigned int sample, raw_sample;
252 int ret = 0;
253
254 if (iio_buffer_enabled(indio_dev))
255 return -EBUSY;
256
257 mutex_lock(&indio_dev->mlock);
258 ad_sigma_delta_set_channel(sigma_delta, chan->address);
259
260 spi_bus_lock(sigma_delta->spi->master);
261 sigma_delta->bus_locked = true;
262 INIT_COMPLETION(sigma_delta->completion);
263
264 ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_SINGLE);
265
266 sigma_delta->irq_dis = false;
267 enable_irq(sigma_delta->spi->irq);
268 ret = wait_for_completion_interruptible_timeout(
269 &sigma_delta->completion, HZ);
270
271 sigma_delta->bus_locked = false;
272 spi_bus_unlock(sigma_delta->spi->master);
273
274 if (ret == 0)
275 ret = -EIO;
276 if (ret < 0)
277 goto out;
278
279 ret = ad_sd_read_reg(sigma_delta, AD_SD_REG_DATA,
280 DIV_ROUND_UP(chan->scan_type.realbits + chan->scan_type.shift, 8),
281 &raw_sample);
282
283out:
284 if (!sigma_delta->irq_dis) {
285 disable_irq_nosync(sigma_delta->spi->irq);
286 sigma_delta->irq_dis = true;
287 }
288
289 ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE);
290 mutex_unlock(&indio_dev->mlock);
291
292 if (ret)
293 return ret;
294
295 sample = raw_sample >> chan->scan_type.shift;
296 sample &= (1 << chan->scan_type.realbits) - 1;
297 *val = sample;
298
299 ret = ad_sigma_delta_postprocess_sample(sigma_delta, raw_sample);
300 if (ret)
301 return ret;
302
303 return IIO_VAL_INT;
304}
305EXPORT_SYMBOL_GPL(ad_sigma_delta_single_conversion);
306
307static int ad_sd_buffer_postenable(struct iio_dev *indio_dev)
308{
309 struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
310 unsigned int channel;
311 int ret;
312
313 ret = iio_triggered_buffer_postenable(indio_dev);
314 if (ret < 0)
315 return ret;
316
317 channel = find_first_bit(indio_dev->active_scan_mask,
318 indio_dev->masklength);
319 ret = ad_sigma_delta_set_channel(sigma_delta,
320 indio_dev->channels[channel].address);
321 if (ret)
322 goto err_predisable;
323
324 spi_bus_lock(sigma_delta->spi->master);
325 sigma_delta->bus_locked = true;
326 ret = ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_CONTINUOUS);
327 if (ret)
328 goto err_unlock;
329
330 sigma_delta->irq_dis = false;
331 enable_irq(sigma_delta->spi->irq);
332
333 return 0;
334
335err_unlock:
336 spi_bus_unlock(sigma_delta->spi->master);
337err_predisable:
338
339 return ret;
340}
341
342static int ad_sd_buffer_postdisable(struct iio_dev *indio_dev)
343{
344 struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
345
346 INIT_COMPLETION(sigma_delta->completion);
347 wait_for_completion_timeout(&sigma_delta->completion, HZ);
348
349 if (!sigma_delta->irq_dis) {
350 disable_irq_nosync(sigma_delta->spi->irq);
351 sigma_delta->irq_dis = true;
352 }
353
354 ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE);
355
356 sigma_delta->bus_locked = false;
357 return spi_bus_unlock(sigma_delta->spi->master);
358}
359
360static irqreturn_t ad_sd_trigger_handler(int irq, void *p)
361{
362 struct iio_poll_func *pf = p;
363 struct iio_dev *indio_dev = pf->indio_dev;
364 struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
365 unsigned int reg_size;
366 uint8_t data[16];
367 int ret;
368
369 memset(data, 0x00, 16);
370
371 /* Guaranteed to be aligned with 8 byte boundary */
372 if (indio_dev->scan_timestamp)
373 ((s64 *)data)[1] = pf->timestamp;
374
375 reg_size = indio_dev->channels[0].scan_type.realbits +
376 indio_dev->channels[0].scan_type.shift;
377 reg_size = DIV_ROUND_UP(reg_size, 8);
378
379 switch (reg_size) {
380 case 4:
381 case 2:
382 case 1:
383 ret = ad_sd_read_reg_raw(sigma_delta, AD_SD_REG_DATA,
384 reg_size, &data[0]);
385 break;
386 case 3:
387 /* We store 24 bit samples in a 32 bit word. Keep the upper
388 * byte set to zero. */
389 ret = ad_sd_read_reg_raw(sigma_delta, AD_SD_REG_DATA,
390 reg_size, &data[1]);
391 break;
392 }
393
394 iio_push_to_buffer(indio_dev->buffer, (uint8_t *)data, pf->timestamp);
395
396 iio_trigger_notify_done(indio_dev->trig);
397 sigma_delta->irq_dis = false;
398 enable_irq(sigma_delta->spi->irq);
399
400 return IRQ_HANDLED;
401}
402
403static const struct iio_buffer_setup_ops ad_sd_buffer_setup_ops = {
404 .preenable = &iio_sw_buffer_preenable,
405 .postenable = &ad_sd_buffer_postenable,
406 .predisable = &iio_triggered_buffer_predisable,
407 .postdisable = &ad_sd_buffer_postdisable,
408 .validate_scan_mask = &iio_validate_scan_mask_onehot,
409};
410
411static irqreturn_t ad_sd_data_rdy_trig_poll(int irq, void *private)
412{
413 struct ad_sigma_delta *sigma_delta = private;
414
415 complete(&sigma_delta->completion);
416 disable_irq_nosync(irq);
417 sigma_delta->irq_dis = true;
418 iio_trigger_poll(sigma_delta->trig, iio_get_time_ns());
419
420 return IRQ_HANDLED;
421}
422
423/**
424 * ad_sd_validate_trigger() - validate_trigger callback for ad_sigma_delta devices
425 * @indio_dev: The IIO device
426 * @trig: The new trigger
427 *
428 * Returns: 0 if the 'trig' matches the trigger registered by the ad_sigma_delta
429 * device, -EINVAL otherwise.
430 */
431int ad_sd_validate_trigger(struct iio_dev *indio_dev, struct iio_trigger *trig)
432{
433 struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
434
435 if (sigma_delta->trig != trig)
436 return -EINVAL;
437
438 return 0;
439}
440EXPORT_SYMBOL_GPL(ad_sd_validate_trigger);
441
442static const struct iio_trigger_ops ad_sd_trigger_ops = {
443 .owner = THIS_MODULE,
444};
445
446static int ad_sd_probe_trigger(struct iio_dev *indio_dev)
447{
448 struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
449 int ret;
450
451 sigma_delta->trig = iio_trigger_alloc("%s-dev%d", indio_dev->name,
452 indio_dev->id);
453 if (sigma_delta->trig == NULL) {
454 ret = -ENOMEM;
455 goto error_ret;
456 }
457 sigma_delta->trig->ops = &ad_sd_trigger_ops;
458 init_completion(&sigma_delta->completion);
459
460 ret = request_irq(sigma_delta->spi->irq,
461 ad_sd_data_rdy_trig_poll,
462 IRQF_TRIGGER_LOW,
463 indio_dev->name,
464 sigma_delta);
465 if (ret)
466 goto error_free_trig;
467
468 if (!sigma_delta->irq_dis) {
469 sigma_delta->irq_dis = true;
470 disable_irq_nosync(sigma_delta->spi->irq);
471 }
472 sigma_delta->trig->dev.parent = &sigma_delta->spi->dev;
473 sigma_delta->trig->private_data = sigma_delta;
474
475 ret = iio_trigger_register(sigma_delta->trig);
476 if (ret)
477 goto error_free_irq;
478
479 /* select default trigger */
480 indio_dev->trig = sigma_delta->trig;
481
482 return 0;
483
484error_free_irq:
485 free_irq(sigma_delta->spi->irq, sigma_delta);
486error_free_trig:
487 iio_trigger_free(sigma_delta->trig);
488error_ret:
489 return ret;
490}
491
492static void ad_sd_remove_trigger(struct iio_dev *indio_dev)
493{
494 struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
495
496 iio_trigger_unregister(sigma_delta->trig);
497 free_irq(sigma_delta->spi->irq, sigma_delta);
498 iio_trigger_free(sigma_delta->trig);
499}
500
501/**
502 * ad_sd_setup_buffer_and_trigger() -
503 * @indio_dev: The IIO device
504 */
505int ad_sd_setup_buffer_and_trigger(struct iio_dev *indio_dev)
506{
507 int ret;
508
509 ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
510 &ad_sd_trigger_handler, &ad_sd_buffer_setup_ops);
511 if (ret)
512 return ret;
513
514 ret = ad_sd_probe_trigger(indio_dev);
515 if (ret) {
516 iio_triggered_buffer_cleanup(indio_dev);
517 return ret;
518 }
519
520 return 0;
521}
522EXPORT_SYMBOL_GPL(ad_sd_setup_buffer_and_trigger);
523
524/**
525 * ad_sd_cleanup_buffer_and_trigger() -
526 * @indio_dev: The IIO device
527 */
528void ad_sd_cleanup_buffer_and_trigger(struct iio_dev *indio_dev)
529{
530 ad_sd_remove_trigger(indio_dev);
531 iio_triggered_buffer_cleanup(indio_dev);
532}
533EXPORT_SYMBOL_GPL(ad_sd_cleanup_buffer_and_trigger);
534
535/**
536 * ad_sd_init() - Initializes a ad_sigma_delta struct
537 * @sigma_delta: The ad_sigma_delta device
538 * @indio_dev: The IIO device which the Sigma Delta device is used for
539 * @spi: The SPI device for the ad_sigma_delta device
540 * @info: Device specific callbacks and options
541 *
542 * This function needs to be called before any other operations are performed on
543 * the ad_sigma_delta struct.
544 */
545int ad_sd_init(struct ad_sigma_delta *sigma_delta, struct iio_dev *indio_dev,
546 struct spi_device *spi, const struct ad_sigma_delta_info *info)
547{
548 sigma_delta->spi = spi;
549 sigma_delta->info = info;
550 iio_device_set_drvdata(indio_dev, sigma_delta);
551
552 return 0;
553}
554EXPORT_SYMBOL_GPL(ad_sd_init);
555
556MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
557MODULE_DESCRIPTION("Analog Devices Sigma-Delta ADCs");
558MODULE_LICENSE("GPL v2");