aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iio
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2012-11-05 04:56:00 -0500
committerJonathan Cameron <jic23@kernel.org>2012-11-05 15:39:54 -0500
commit4eb3ccf157639a9d9c7829de94017c46c73d9cc4 (patch)
tree51bca152c333deca4f48662c32ed766956623c4d /drivers/iio
parent98efb70adde96d86df29b4754f265b2c8bba01b2 (diff)
staging:iio: Move the ad7887 driver out of staging
The driver does not expose any custom API to userspace and none of the standard static code checker tools report any issues, so move it out of staging. 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/Kconfig13
-rw-r--r--drivers/iio/adc/Makefile1
-rw-r--r--drivers/iio/adc/ad7887.c378
3 files changed, 392 insertions, 0 deletions
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 492758120338..706386ba02e3 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -45,6 +45,19 @@ config AD7476
45 To compile this driver as a module, choose M here: the 45 To compile this driver as a module, choose M here: the
46 module will be called ad7476. 46 module will be called ad7476.
47 47
48config AD7887
49 tristate "Analog Devices AD7887 ADC driver"
50 depends on SPI
51 select IIO_BUFFER
52 select IIO_TRIGGERED_BUFFER
53 help
54 Say yes here to build support for Analog Devices
55 AD7887 SPI analog to digital converter (ADC).
56 If unsure, say N (but it's safe to say "Y").
57
58 To compile this driver as a module, choose M here: the
59 module will be called ad7887.
60
48config AT91_ADC 61config AT91_ADC
49 tristate "Atmel AT91 ADC" 62 tristate "Atmel AT91 ADC"
50 depends on ARCH_AT91 63 depends on ARCH_AT91
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 900995d5e179..034eacb8f7c9 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -6,5 +6,6 @@ obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o
6obj-$(CONFIG_AD7266) += ad7266.o 6obj-$(CONFIG_AD7266) += ad7266.o
7obj-$(CONFIG_AD7476) += ad7476.o 7obj-$(CONFIG_AD7476) += ad7476.o
8obj-$(CONFIG_AD7791) += ad7791.o 8obj-$(CONFIG_AD7791) += ad7791.o
9obj-$(CONFIG_AD7887) += ad7887.o
9obj-$(CONFIG_AT91_ADC) += at91_adc.o 10obj-$(CONFIG_AT91_ADC) += at91_adc.o
10obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o 11obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
diff --git a/drivers/iio/adc/ad7887.c b/drivers/iio/adc/ad7887.c
new file mode 100644
index 000000000000..fd62309b4d3d
--- /dev/null
+++ b/drivers/iio/adc/ad7887.c
@@ -0,0 +1,378 @@
1/*
2 * AD7887 SPI ADC driver
3 *
4 * Copyright 2010-2011 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2.
7 */
8
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/module.h>
17#include <linux/interrupt.h>
18
19#include <linux/iio/iio.h>
20#include <linux/iio/sysfs.h>
21#include <linux/iio/buffer.h>
22
23#include <linux/iio/trigger_consumer.h>
24#include <linux/iio/triggered_buffer.h>
25
26#include <linux/platform_data/ad7887.h>
27
28#define AD7887_REF_DIS (1 << 5) /* on-chip reference disable */
29#define AD7887_DUAL (1 << 4) /* dual-channel mode */
30#define AD7887_CH_AIN1 (1 << 3) /* convert on channel 1, DUAL=1 */
31#define AD7887_CH_AIN0 (0 << 3) /* convert on channel 0, DUAL=0,1 */
32#define AD7887_PM_MODE1 (0) /* CS based shutdown */
33#define AD7887_PM_MODE2 (1) /* full on */
34#define AD7887_PM_MODE3 (2) /* auto shutdown after conversion */
35#define AD7887_PM_MODE4 (3) /* standby mode */
36
37enum ad7887_channels {
38 AD7887_CH0,
39 AD7887_CH0_CH1,
40 AD7887_CH1,
41};
42
43#define RES_MASK(bits) ((1 << (bits)) - 1)
44
45/**
46 * struct ad7887_chip_info - chip specifc information
47 * @int_vref_mv: the internal reference voltage
48 * @channel: channel specification
49 */
50struct ad7887_chip_info {
51 u16 int_vref_mv;
52 struct iio_chan_spec channel[3];
53};
54
55struct ad7887_state {
56 struct spi_device *spi;
57 const struct ad7887_chip_info *chip_info;
58 struct regulator *reg;
59 struct spi_transfer xfer[4];
60 struct spi_message msg[3];
61 struct spi_message *ring_msg;
62 unsigned char tx_cmd_buf[4];
63
64 /*
65 * DMA (thus cache coherency maintenance) requires the
66 * transfer buffers to live in their own cache lines.
67 * Buffer needs to be large enough to hold two 16 bit samples and a
68 * 64 bit aligned 64 bit timestamp.
69 */
70 unsigned char data[ALIGN(4, sizeof(s64)) + sizeof(s64)]
71 ____cacheline_aligned;
72};
73
74enum ad7887_supported_device_ids {
75 ID_AD7887
76};
77
78static int ad7887_ring_preenable(struct iio_dev *indio_dev)
79{
80 struct ad7887_state *st = iio_priv(indio_dev);
81 int ret;
82
83 ret = iio_sw_buffer_preenable(indio_dev);
84 if (ret < 0)
85 return ret;
86
87 /* We know this is a single long so can 'cheat' */
88 switch (*indio_dev->active_scan_mask) {
89 case (1 << 0):
90 st->ring_msg = &st->msg[AD7887_CH0];
91 break;
92 case (1 << 1):
93 st->ring_msg = &st->msg[AD7887_CH1];
94 /* Dummy read: push CH1 setting down to hardware */
95 spi_sync(st->spi, st->ring_msg);
96 break;
97 case ((1 << 1) | (1 << 0)):
98 st->ring_msg = &st->msg[AD7887_CH0_CH1];
99 break;
100 }
101
102 return 0;
103}
104
105static int ad7887_ring_postdisable(struct iio_dev *indio_dev)
106{
107 struct ad7887_state *st = iio_priv(indio_dev);
108
109 /* dummy read: restore default CH0 settin */
110 return spi_sync(st->spi, &st->msg[AD7887_CH0]);
111}
112
113/**
114 * ad7887_trigger_handler() bh of trigger launched polling to ring buffer
115 *
116 * Currently there is no option in this driver to disable the saving of
117 * timestamps within the ring.
118 **/
119static irqreturn_t ad7887_trigger_handler(int irq, void *p)
120{
121 struct iio_poll_func *pf = p;
122 struct iio_dev *indio_dev = pf->indio_dev;
123 struct ad7887_state *st = iio_priv(indio_dev);
124 s64 time_ns;
125 int b_sent;
126
127 b_sent = spi_sync(st->spi, st->ring_msg);
128 if (b_sent)
129 goto done;
130
131 time_ns = iio_get_time_ns();
132
133 if (indio_dev->scan_timestamp)
134 memcpy(st->data + indio_dev->scan_bytes - sizeof(s64),
135 &time_ns, sizeof(time_ns));
136
137 iio_push_to_buffer(indio_dev->buffer, st->data);
138done:
139 iio_trigger_notify_done(indio_dev->trig);
140
141 return IRQ_HANDLED;
142}
143
144static const struct iio_buffer_setup_ops ad7887_ring_setup_ops = {
145 .preenable = &ad7887_ring_preenable,
146 .postenable = &iio_triggered_buffer_postenable,
147 .predisable = &iio_triggered_buffer_predisable,
148 .postdisable = &ad7887_ring_postdisable,
149};
150
151static int ad7887_scan_direct(struct ad7887_state *st, unsigned ch)
152{
153 int ret = spi_sync(st->spi, &st->msg[ch]);
154 if (ret)
155 return ret;
156
157 return (st->data[(ch * 2)] << 8) | st->data[(ch * 2) + 1];
158}
159
160static int ad7887_read_raw(struct iio_dev *indio_dev,
161 struct iio_chan_spec const *chan,
162 int *val,
163 int *val2,
164 long m)
165{
166 int ret;
167 struct ad7887_state *st = iio_priv(indio_dev);
168
169 switch (m) {
170 case IIO_CHAN_INFO_RAW:
171 mutex_lock(&indio_dev->mlock);
172 if (iio_buffer_enabled(indio_dev))
173 ret = -EBUSY;
174 else
175 ret = ad7887_scan_direct(st, chan->address);
176 mutex_unlock(&indio_dev->mlock);
177
178 if (ret < 0)
179 return ret;
180 *val = ret >> chan->scan_type.shift;
181 *val &= RES_MASK(chan->scan_type.realbits);
182 return IIO_VAL_INT;
183 case IIO_CHAN_INFO_SCALE:
184 if (st->reg) {
185 *val = regulator_get_voltage(st->reg);
186 if (*val < 0)
187 return *val;
188 *val /= 1000;
189 } else {
190 *val = st->chip_info->int_vref_mv;
191 }
192
193 *val2 = chan->scan_type.realbits;
194
195 return IIO_VAL_FRACTIONAL_LOG2;
196 }
197 return -EINVAL;
198}
199
200
201static const struct ad7887_chip_info ad7887_chip_info_tbl[] = {
202 /*
203 * More devices added in future
204 */
205 [ID_AD7887] = {
206 .channel[0] = {
207 .type = IIO_VOLTAGE,
208 .indexed = 1,
209 .channel = 1,
210 .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
211 IIO_CHAN_INFO_SCALE_SHARED_BIT,
212 .address = 1,
213 .scan_index = 1,
214 .scan_type = IIO_ST('u', 12, 16, 0),
215 },
216 .channel[1] = {
217 .type = IIO_VOLTAGE,
218 .indexed = 1,
219 .channel = 0,
220 .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
221 IIO_CHAN_INFO_SCALE_SHARED_BIT,
222 .address = 0,
223 .scan_index = 0,
224 .scan_type = IIO_ST('u', 12, 16, 0),
225 },
226 .channel[2] = IIO_CHAN_SOFT_TIMESTAMP(2),
227 .int_vref_mv = 2500,
228 },
229};
230
231static const struct iio_info ad7887_info = {
232 .read_raw = &ad7887_read_raw,
233 .driver_module = THIS_MODULE,
234};
235
236static int __devinit ad7887_probe(struct spi_device *spi)
237{
238 struct ad7887_platform_data *pdata = spi->dev.platform_data;
239 struct ad7887_state *st;
240 struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
241 uint8_t mode;
242 int ret;
243
244 if (indio_dev == NULL)
245 return -ENOMEM;
246
247 st = iio_priv(indio_dev);
248
249 if (!pdata || !pdata->use_onchip_ref) {
250 st->reg = regulator_get(&spi->dev, "vref");
251 if (IS_ERR(st->reg)) {
252 ret = PTR_ERR(st->reg);
253 goto error_free;
254 }
255
256 ret = regulator_enable(st->reg);
257 if (ret)
258 goto error_put_reg;
259 }
260
261 st->chip_info =
262 &ad7887_chip_info_tbl[spi_get_device_id(spi)->driver_data];
263
264 spi_set_drvdata(spi, indio_dev);
265 st->spi = spi;
266
267 /* Estabilish that the iio_dev is a child of the spi device */
268 indio_dev->dev.parent = &spi->dev;
269 indio_dev->name = spi_get_device_id(spi)->name;
270 indio_dev->info = &ad7887_info;
271 indio_dev->modes = INDIO_DIRECT_MODE;
272
273 /* Setup default message */
274
275 mode = AD7887_PM_MODE4;
276 if (!pdata || !pdata->use_onchip_ref)
277 mode |= AD7887_REF_DIS;
278 if (pdata && pdata->en_dual)
279 mode |= AD7887_DUAL;
280
281 st->tx_cmd_buf[0] = AD7887_CH_AIN0 | mode;
282
283 st->xfer[0].rx_buf = &st->data[0];
284 st->xfer[0].tx_buf = &st->tx_cmd_buf[0];
285 st->xfer[0].len = 2;
286
287 spi_message_init(&st->msg[AD7887_CH0]);
288 spi_message_add_tail(&st->xfer[0], &st->msg[AD7887_CH0]);
289
290 if (pdata && pdata->en_dual) {
291 st->tx_cmd_buf[2] = AD7887_CH_AIN1 | mode;
292
293 st->xfer[1].rx_buf = &st->data[0];
294 st->xfer[1].tx_buf = &st->tx_cmd_buf[2];
295 st->xfer[1].len = 2;
296
297 st->xfer[2].rx_buf = &st->data[2];
298 st->xfer[2].tx_buf = &st->tx_cmd_buf[0];
299 st->xfer[2].len = 2;
300
301 spi_message_init(&st->msg[AD7887_CH0_CH1]);
302 spi_message_add_tail(&st->xfer[1], &st->msg[AD7887_CH0_CH1]);
303 spi_message_add_tail(&st->xfer[2], &st->msg[AD7887_CH0_CH1]);
304
305 st->xfer[3].rx_buf = &st->data[2];
306 st->xfer[3].tx_buf = &st->tx_cmd_buf[2];
307 st->xfer[3].len = 2;
308
309 spi_message_init(&st->msg[AD7887_CH1]);
310 spi_message_add_tail(&st->xfer[3], &st->msg[AD7887_CH1]);
311
312 indio_dev->channels = st->chip_info->channel;
313 indio_dev->num_channels = 3;
314 } else {
315 indio_dev->channels = &st->chip_info->channel[1];
316 indio_dev->num_channels = 2;
317 }
318
319 ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
320 &ad7887_trigger_handler, &ad7887_ring_setup_ops);
321 if (ret)
322 goto error_disable_reg;
323
324 ret = iio_device_register(indio_dev);
325 if (ret)
326 goto error_unregister_ring;
327
328 return 0;
329error_unregister_ring:
330 iio_triggered_buffer_cleanup(indio_dev);
331error_disable_reg:
332 if (st->reg)
333 regulator_disable(st->reg);
334error_put_reg:
335 if (st->reg)
336 regulator_put(st->reg);
337error_free:
338 iio_device_free(indio_dev);
339
340 return ret;
341}
342
343static int __devexit ad7887_remove(struct spi_device *spi)
344{
345 struct iio_dev *indio_dev = spi_get_drvdata(spi);
346 struct ad7887_state *st = iio_priv(indio_dev);
347
348 iio_device_unregister(indio_dev);
349 iio_triggered_buffer_cleanup(indio_dev);
350 if (st->reg) {
351 regulator_disable(st->reg);
352 regulator_put(st->reg);
353 }
354 iio_device_free(indio_dev);
355
356 return 0;
357}
358
359static const struct spi_device_id ad7887_id[] = {
360 {"ad7887", ID_AD7887},
361 {}
362};
363MODULE_DEVICE_TABLE(spi, ad7887_id);
364
365static struct spi_driver ad7887_driver = {
366 .driver = {
367 .name = "ad7887",
368 .owner = THIS_MODULE,
369 },
370 .probe = ad7887_probe,
371 .remove = __devexit_p(ad7887_remove),
372 .id_table = ad7887_id,
373};
374module_spi_driver(ad7887_driver);
375
376MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
377MODULE_DESCRIPTION("Analog Devices AD7887 ADC");
378MODULE_LICENSE("GPL v2");