diff options
Diffstat (limited to 'drivers/iio/adc')
-rw-r--r-- | drivers/iio/adc/Kconfig | 13 | ||||
-rw-r--r-- | drivers/iio/adc/Makefile | 1 | ||||
-rw-r--r-- | drivers/iio/adc/ad7887.c | 378 |
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 | ||
48 | config 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 | |||
48 | config AT91_ADC | 61 | config 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 | |||
6 | obj-$(CONFIG_AD7266) += ad7266.o | 6 | obj-$(CONFIG_AD7266) += ad7266.o |
7 | obj-$(CONFIG_AD7476) += ad7476.o | 7 | obj-$(CONFIG_AD7476) += ad7476.o |
8 | obj-$(CONFIG_AD7791) += ad7791.o | 8 | obj-$(CONFIG_AD7791) += ad7791.o |
9 | obj-$(CONFIG_AD7887) += ad7887.o | ||
9 | obj-$(CONFIG_AT91_ADC) += at91_adc.o | 10 | obj-$(CONFIG_AT91_ADC) += at91_adc.o |
10 | obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o | 11 | obj-$(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 | |||
37 | enum 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 | */ | ||
50 | struct ad7887_chip_info { | ||
51 | u16 int_vref_mv; | ||
52 | struct iio_chan_spec channel[3]; | ||
53 | }; | ||
54 | |||
55 | struct 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 | |||
74 | enum ad7887_supported_device_ids { | ||
75 | ID_AD7887 | ||
76 | }; | ||
77 | |||
78 | static 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 | |||
105 | static 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 | **/ | ||
119 | static 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); | ||
138 | done: | ||
139 | iio_trigger_notify_done(indio_dev->trig); | ||
140 | |||
141 | return IRQ_HANDLED; | ||
142 | } | ||
143 | |||
144 | static 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 | |||
151 | static 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 | |||
160 | static 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 | |||
201 | static 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 | |||
231 | static const struct iio_info ad7887_info = { | ||
232 | .read_raw = &ad7887_read_raw, | ||
233 | .driver_module = THIS_MODULE, | ||
234 | }; | ||
235 | |||
236 | static 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; | ||
329 | error_unregister_ring: | ||
330 | iio_triggered_buffer_cleanup(indio_dev); | ||
331 | error_disable_reg: | ||
332 | if (st->reg) | ||
333 | regulator_disable(st->reg); | ||
334 | error_put_reg: | ||
335 | if (st->reg) | ||
336 | regulator_put(st->reg); | ||
337 | error_free: | ||
338 | iio_device_free(indio_dev); | ||
339 | |||
340 | return ret; | ||
341 | } | ||
342 | |||
343 | static 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 | |||
359 | static const struct spi_device_id ad7887_id[] = { | ||
360 | {"ad7887", ID_AD7887}, | ||
361 | {} | ||
362 | }; | ||
363 | MODULE_DEVICE_TABLE(spi, ad7887_id); | ||
364 | |||
365 | static 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 | }; | ||
374 | module_spi_driver(ad7887_driver); | ||
375 | |||
376 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | ||
377 | MODULE_DESCRIPTION("Analog Devices AD7887 ADC"); | ||
378 | MODULE_LICENSE("GPL v2"); | ||