aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iio
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2012-09-10 04:34:00 -0400
committerJonathan Cameron <jic23@kernel.org>2012-09-15 05:02:14 -0400
commit968f3d5ba006d21677145739d8b3f864b5af15c6 (patch)
tree0c407b188a0516da9acbd29715957fbf9eb3fd22 /drivers/iio
parent610a407cdc5a8ab5358fb253b3c5457452ff1d75 (diff)
iio: Move ad7476 driver out of staging
The ad7476 driver is a driver for simple single channel ADCs. The driver does not export any experimental or custom ABI files nor do the static code check tools report any issues, so move the driver 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/Kconfig14
-rw-r--r--drivers/iio/adc/Makefile1
-rw-r--r--drivers/iio/adc/ad7476.c278
3 files changed, 293 insertions, 0 deletions
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index d0ae71ec2aa0..f98c493efff8 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -30,6 +30,20 @@ config AD7791
30 To compile this driver as a module, choose M here: the module will be 30 To compile this driver as a module, choose M here: the module will be
31 called ad7791. 31 called ad7791.
32 32
33config AD7476
34 tristate "Analog Devices AD7475/6/7/8 AD7466/7/8 and AD7495 ADC driver"
35 depends on SPI
36 select IIO_BUFFER
37 select IIO_TRIGGERED_BUFFER
38 help
39 Say yes here to build support for Analog Devices
40 AD7475, AD7476, AD7477, AD7478, AD7466, AD7467, AD7468, AD7495
41 SPI analog to digital converters (ADC).
42 If unsure, say N (but it's safe to say "Y").
43
44 To compile this driver as a module, choose M here: the
45 module will be called ad7476.
46
33config AT91_ADC 47config AT91_ADC
34 tristate "Atmel AT91 ADC" 48 tristate "Atmel AT91 ADC"
35 depends on ARCH_AT91 49 depends on ARCH_AT91
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index f187ff6c2a16..9824a70f4fd8 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -4,5 +4,6 @@
4 4
5obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o 5obj-$(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_AD7791) += ad7791.o 8obj-$(CONFIG_AD7791) += ad7791.o
8obj-$(CONFIG_AT91_ADC) += at91_adc.o 9obj-$(CONFIG_AT91_ADC) += at91_adc.o
diff --git a/drivers/iio/adc/ad7476.c b/drivers/iio/adc/ad7476.c
new file mode 100644
index 000000000000..a33a4066ebe2
--- /dev/null
+++ b/drivers/iio/adc/ad7476.c
@@ -0,0 +1,278 @@
1/*
2 * AD7466/7/8 AD7476/5/7/8 (A) SPI ADC driver
3 *
4 * Copyright 2010 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
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
18#include <linux/iio/iio.h>
19#include <linux/iio/sysfs.h>
20#include <linux/iio/buffer.h>
21#include <linux/iio/trigger_consumer.h>
22#include <linux/iio/triggered_buffer.h>
23
24#define RES_MASK(bits) ((1 << (bits)) - 1)
25
26struct ad7476_chip_info {
27 unsigned int int_vref_uv;
28 struct iio_chan_spec channel[2];
29};
30
31struct ad7476_state {
32 struct spi_device *spi;
33 const struct ad7476_chip_info *chip_info;
34 struct regulator *reg;
35 struct spi_transfer xfer;
36 struct spi_message msg;
37 /*
38 * DMA (thus cache coherency maintenance) requires the
39 * transfer buffers to live in their own cache lines.
40 * Make the buffer large enough for one 16 bit sample and one 64 bit
41 * aligned 64 bit timestamp.
42 */
43 unsigned char data[ALIGN(2, sizeof(s64)) + sizeof(s64)]
44 ____cacheline_aligned;
45};
46
47enum ad7476_supported_device_ids {
48 ID_AD7466,
49 ID_AD7467,
50 ID_AD7468,
51 ID_AD7495
52};
53
54static irqreturn_t ad7476_trigger_handler(int irq, void *p)
55{
56 struct iio_poll_func *pf = p;
57 struct iio_dev *indio_dev = pf->indio_dev;
58 struct ad7476_state *st = iio_priv(indio_dev);
59 s64 time_ns;
60 int b_sent;
61
62 b_sent = spi_sync(st->spi, &st->msg);
63 if (b_sent < 0)
64 goto done;
65
66 time_ns = iio_get_time_ns();
67
68 if (indio_dev->scan_timestamp)
69 ((s64 *)st->data)[1] = time_ns;
70
71 iio_push_to_buffer(indio_dev->buffer, st->data);
72done:
73 iio_trigger_notify_done(indio_dev->trig);
74
75 return IRQ_HANDLED;
76}
77
78static int ad7476_scan_direct(struct ad7476_state *st)
79{
80 int ret;
81
82 ret = spi_sync(st->spi, &st->msg);
83 if (ret)
84 return ret;
85
86 return be16_to_cpup((__be16 *)st->data);
87}
88
89static int ad7476_read_raw(struct iio_dev *indio_dev,
90 struct iio_chan_spec const *chan,
91 int *val,
92 int *val2,
93 long m)
94{
95 int ret;
96 struct ad7476_state *st = iio_priv(indio_dev);
97 int scale_uv;
98
99 switch (m) {
100 case IIO_CHAN_INFO_RAW:
101 mutex_lock(&indio_dev->mlock);
102 if (iio_buffer_enabled(indio_dev))
103 ret = -EBUSY;
104 else
105 ret = ad7476_scan_direct(st);
106 mutex_unlock(&indio_dev->mlock);
107
108 if (ret < 0)
109 return ret;
110 *val = (ret >> st->chip_info->channel[0].scan_type.shift) &
111 RES_MASK(st->chip_info->channel[0].scan_type.realbits);
112 return IIO_VAL_INT;
113 case IIO_CHAN_INFO_SCALE:
114 if (!st->chip_info->int_vref_uv) {
115 scale_uv = regulator_get_voltage(st->reg);
116 if (scale_uv < 0)
117 return scale_uv;
118 } else {
119 scale_uv = st->chip_info->int_vref_uv;
120 }
121 scale_uv >>= chan->scan_type.realbits;
122 *val = scale_uv / 1000;
123 *val2 = (scale_uv % 1000) * 1000;
124 return IIO_VAL_INT_PLUS_MICRO;
125 }
126 return -EINVAL;
127}
128
129#define AD7476_CHAN(bits) \
130 { \
131 .type = IIO_VOLTAGE, \
132 .indexed = 1, \
133 .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
134 IIO_CHAN_INFO_SCALE_SHARED_BIT, \
135 .scan_type = { \
136 .sign = 'u', \
137 .realbits = bits, \
138 .storagebits = 16, \
139 .shift = 13 - bits, \
140 }, \
141}
142
143static const struct ad7476_chip_info ad7476_chip_info_tbl[] = {
144 [ID_AD7466] = {
145 .channel[0] = AD7476_CHAN(12),
146 .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
147 },
148 [ID_AD7467] = {
149 .channel[0] = AD7476_CHAN(10),
150 .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
151 },
152 [ID_AD7468] = {
153 .channel[0] = AD7476_CHAN(8),
154 .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
155 },
156 [ID_AD7495] = {
157 .channel[0] = AD7476_CHAN(12),
158 .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
159 .int_vref_uv = 2500000,
160 },
161};
162
163static const struct iio_info ad7476_info = {
164 .driver_module = THIS_MODULE,
165 .read_raw = &ad7476_read_raw,
166};
167
168static int __devinit ad7476_probe(struct spi_device *spi)
169{
170 struct ad7476_state *st;
171 struct iio_dev *indio_dev;
172 int ret;
173
174 indio_dev = iio_device_alloc(sizeof(*st));
175 if (indio_dev == NULL) {
176 ret = -ENOMEM;
177 goto error_ret;
178 }
179 st = iio_priv(indio_dev);
180 st->chip_info =
181 &ad7476_chip_info_tbl[spi_get_device_id(spi)->driver_data];
182
183 st->reg = regulator_get(&spi->dev, "vcc");
184 if (IS_ERR(st->reg)) {
185 ret = PTR_ERR(st->reg);
186 goto error_free_dev;
187 }
188
189 ret = regulator_enable(st->reg);
190 if (ret)
191 goto error_put_reg;
192
193 spi_set_drvdata(spi, indio_dev);
194
195 st->spi = spi;
196
197 /* Establish that the iio_dev is a child of the spi device */
198 indio_dev->dev.parent = &spi->dev;
199 indio_dev->name = spi_get_device_id(spi)->name;
200 indio_dev->modes = INDIO_DIRECT_MODE;
201 indio_dev->channels = st->chip_info->channel;
202 indio_dev->num_channels = 2;
203 indio_dev->info = &ad7476_info;
204 /* Setup default message */
205
206 st->xfer.rx_buf = &st->data;
207 st->xfer.len = st->chip_info->channel[0].scan_type.storagebits / 8;
208
209 spi_message_init(&st->msg);
210 spi_message_add_tail(&st->xfer, &st->msg);
211
212 ret = iio_triggered_buffer_setup(indio_dev, NULL,
213 &ad7476_trigger_handler, NULL);
214 if (ret)
215 goto error_disable_reg;
216
217 ret = iio_device_register(indio_dev);
218 if (ret)
219 goto error_ring_unregister;
220 return 0;
221
222error_ring_unregister:
223 iio_triggered_buffer_cleanup(indio_dev);
224error_disable_reg:
225 regulator_disable(st->reg);
226error_put_reg:
227 regulator_put(st->reg);
228error_free_dev:
229 iio_device_free(indio_dev);
230
231error_ret:
232 return ret;
233}
234
235static int __devexit ad7476_remove(struct spi_device *spi)
236{
237 struct iio_dev *indio_dev = spi_get_drvdata(spi);
238 struct ad7476_state *st = iio_priv(indio_dev);
239
240 iio_device_unregister(indio_dev);
241 iio_triggered_buffer_cleanup(indio_dev);
242 regulator_disable(st->reg);
243 regulator_put(st->reg);
244 iio_device_free(indio_dev);
245
246 return 0;
247}
248
249static const struct spi_device_id ad7476_id[] = {
250 {"ad7466", ID_AD7466},
251 {"ad7467", ID_AD7467},
252 {"ad7468", ID_AD7468},
253 {"ad7475", ID_AD7466},
254 {"ad7476", ID_AD7466},
255 {"ad7476a", ID_AD7466},
256 {"ad7477", ID_AD7467},
257 {"ad7477a", ID_AD7467},
258 {"ad7478", ID_AD7468},
259 {"ad7478a", ID_AD7468},
260 {"ad7495", ID_AD7495},
261 {}
262};
263MODULE_DEVICE_TABLE(spi, ad7476_id);
264
265static struct spi_driver ad7476_driver = {
266 .driver = {
267 .name = "ad7476",
268 .owner = THIS_MODULE,
269 },
270 .probe = ad7476_probe,
271 .remove = __devexit_p(ad7476_remove),
272 .id_table = ad7476_id,
273};
274module_spi_driver(ad7476_driver);
275
276MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
277MODULE_DESCRIPTION("Analog Devices AD7475/6/7/8(A) AD7466/7/8 ADC");
278MODULE_LICENSE("GPL v2");