diff options
Diffstat (limited to 'drivers/iio')
-rw-r--r-- | drivers/iio/adc/Kconfig | 12 | ||||
-rw-r--r-- | drivers/iio/adc/Makefile | 1 | ||||
-rw-r--r-- | drivers/iio/adc/ad7298.c | 408 |
3 files changed, 421 insertions, 0 deletions
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index ef5200a6850e..cd5eed60be28 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig | |||
@@ -18,6 +18,18 @@ config AD7266 | |||
18 | Say yes here to build support for Analog Devices AD7265 and AD7266 | 18 | Say yes here to build support for Analog Devices AD7265 and AD7266 |
19 | ADCs. | 19 | ADCs. |
20 | 20 | ||
21 | config AD7298 | ||
22 | tristate "Analog Devices AD7298 ADC driver" | ||
23 | depends on SPI | ||
24 | select IIO_BUFFER | ||
25 | select IIO_TRIGGERED_BUFFER | ||
26 | help | ||
27 | Say yes here to build support for Analog Devices AD7298 | ||
28 | 8 Channel ADC with temperature sensor. | ||
29 | |||
30 | To compile this driver as a module, choose M here: the | ||
31 | module will be called ad7298. | ||
32 | |||
21 | config AD7791 | 33 | config AD7791 |
22 | tristate "Analog Devices AD7791 ADC driver" | 34 | tristate "Analog Devices AD7791 ADC driver" |
23 | depends on SPI | 35 | depends on SPI |
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index 54ac7bbcd01b..3256dc64a466 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile | |||
@@ -4,6 +4,7 @@ | |||
4 | 4 | ||
5 | obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o | 5 | obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o |
6 | obj-$(CONFIG_AD7266) += ad7266.o | 6 | obj-$(CONFIG_AD7266) += ad7266.o |
7 | obj-$(CONFIG_AD7298) += ad7298.o | ||
7 | obj-$(CONFIG_AD7476) += ad7476.o | 8 | obj-$(CONFIG_AD7476) += ad7476.o |
8 | obj-$(CONFIG_AD7791) += ad7791.o | 9 | obj-$(CONFIG_AD7791) += ad7791.o |
9 | obj-$(CONFIG_AD7887) += ad7887.o | 10 | obj-$(CONFIG_AD7887) += ad7887.o |
diff --git a/drivers/iio/adc/ad7298.c b/drivers/iio/adc/ad7298.c new file mode 100644 index 000000000000..441a9a265c12 --- /dev/null +++ b/drivers/iio/adc/ad7298.c | |||
@@ -0,0 +1,408 @@ | |||
1 | /* | ||
2 | * AD7298 SPI ADC driver | ||
3 | * | ||
4 | * Copyright 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/delay.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | |||
20 | #include <linux/iio/iio.h> | ||
21 | #include <linux/iio/sysfs.h> | ||
22 | #include <linux/iio/buffer.h> | ||
23 | #include <linux/iio/trigger_consumer.h> | ||
24 | #include <linux/iio/triggered_buffer.h> | ||
25 | |||
26 | #include <linux/platform_data/ad7298.h> | ||
27 | |||
28 | #define AD7298_WRITE (1 << 15) /* write to the control register */ | ||
29 | #define AD7298_REPEAT (1 << 14) /* repeated conversion enable */ | ||
30 | #define AD7298_CH(x) (1 << (13 - (x))) /* channel select */ | ||
31 | #define AD7298_TSENSE (1 << 5) /* temperature conversion enable */ | ||
32 | #define AD7298_EXTREF (1 << 2) /* external reference enable */ | ||
33 | #define AD7298_TAVG (1 << 1) /* temperature sensor averaging enable */ | ||
34 | #define AD7298_PDD (1 << 0) /* partial power down enable */ | ||
35 | |||
36 | #define AD7298_MAX_CHAN 8 | ||
37 | #define AD7298_BITS 12 | ||
38 | #define AD7298_STORAGE_BITS 16 | ||
39 | #define AD7298_INTREF_mV 2500 | ||
40 | |||
41 | #define AD7298_CH_TEMP 9 | ||
42 | |||
43 | #define RES_MASK(bits) ((1 << (bits)) - 1) | ||
44 | |||
45 | struct ad7298_state { | ||
46 | struct spi_device *spi; | ||
47 | struct regulator *reg; | ||
48 | unsigned ext_ref; | ||
49 | struct spi_transfer ring_xfer[10]; | ||
50 | struct spi_transfer scan_single_xfer[3]; | ||
51 | struct spi_message ring_msg; | ||
52 | struct spi_message scan_single_msg; | ||
53 | /* | ||
54 | * DMA (thus cache coherency maintenance) requires the | ||
55 | * transfer buffers to live in their own cache lines. | ||
56 | */ | ||
57 | unsigned short rx_buf[12] ____cacheline_aligned; | ||
58 | unsigned short tx_buf[2]; | ||
59 | }; | ||
60 | |||
61 | #define AD7298_V_CHAN(index) \ | ||
62 | { \ | ||
63 | .type = IIO_VOLTAGE, \ | ||
64 | .indexed = 1, \ | ||
65 | .channel = index, \ | ||
66 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ | ||
67 | IIO_CHAN_INFO_SCALE_SHARED_BIT, \ | ||
68 | .address = index, \ | ||
69 | .scan_index = index, \ | ||
70 | .scan_type = { \ | ||
71 | .sign = 'u', \ | ||
72 | .realbits = 12, \ | ||
73 | .storagebits = 16, \ | ||
74 | .endianness = IIO_BE, \ | ||
75 | }, \ | ||
76 | } | ||
77 | |||
78 | static const struct iio_chan_spec ad7298_channels[] = { | ||
79 | { | ||
80 | .type = IIO_TEMP, | ||
81 | .indexed = 1, | ||
82 | .channel = 0, | ||
83 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | ||
84 | IIO_CHAN_INFO_SCALE_SEPARATE_BIT | | ||
85 | IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, | ||
86 | .address = AD7298_CH_TEMP, | ||
87 | .scan_index = -1, | ||
88 | .scan_type = { | ||
89 | .sign = 's', | ||
90 | .realbits = 32, | ||
91 | .storagebits = 32, | ||
92 | }, | ||
93 | }, | ||
94 | AD7298_V_CHAN(0), | ||
95 | AD7298_V_CHAN(1), | ||
96 | AD7298_V_CHAN(2), | ||
97 | AD7298_V_CHAN(3), | ||
98 | AD7298_V_CHAN(4), | ||
99 | AD7298_V_CHAN(5), | ||
100 | AD7298_V_CHAN(6), | ||
101 | AD7298_V_CHAN(7), | ||
102 | IIO_CHAN_SOFT_TIMESTAMP(8), | ||
103 | }; | ||
104 | |||
105 | /** | ||
106 | * ad7298_update_scan_mode() setup the spi transfer buffer for the new scan mask | ||
107 | **/ | ||
108 | static int ad7298_update_scan_mode(struct iio_dev *indio_dev, | ||
109 | const unsigned long *active_scan_mask) | ||
110 | { | ||
111 | struct ad7298_state *st = iio_priv(indio_dev); | ||
112 | int i, m; | ||
113 | unsigned short command; | ||
114 | int scan_count; | ||
115 | |||
116 | /* Now compute overall size */ | ||
117 | scan_count = bitmap_weight(active_scan_mask, indio_dev->masklength); | ||
118 | |||
119 | command = AD7298_WRITE | st->ext_ref; | ||
120 | |||
121 | for (i = 0, m = AD7298_CH(0); i < AD7298_MAX_CHAN; i++, m >>= 1) | ||
122 | if (test_bit(i, active_scan_mask)) | ||
123 | command |= m; | ||
124 | |||
125 | st->tx_buf[0] = cpu_to_be16(command); | ||
126 | |||
127 | /* build spi ring message */ | ||
128 | st->ring_xfer[0].tx_buf = &st->tx_buf[0]; | ||
129 | st->ring_xfer[0].len = 2; | ||
130 | st->ring_xfer[0].cs_change = 1; | ||
131 | st->ring_xfer[1].tx_buf = &st->tx_buf[1]; | ||
132 | st->ring_xfer[1].len = 2; | ||
133 | st->ring_xfer[1].cs_change = 1; | ||
134 | |||
135 | spi_message_init(&st->ring_msg); | ||
136 | spi_message_add_tail(&st->ring_xfer[0], &st->ring_msg); | ||
137 | spi_message_add_tail(&st->ring_xfer[1], &st->ring_msg); | ||
138 | |||
139 | for (i = 0; i < scan_count; i++) { | ||
140 | st->ring_xfer[i + 2].rx_buf = &st->rx_buf[i]; | ||
141 | st->ring_xfer[i + 2].len = 2; | ||
142 | st->ring_xfer[i + 2].cs_change = 1; | ||
143 | spi_message_add_tail(&st->ring_xfer[i + 2], &st->ring_msg); | ||
144 | } | ||
145 | /* make sure last transfer cs_change is not set */ | ||
146 | st->ring_xfer[i + 1].cs_change = 0; | ||
147 | |||
148 | return 0; | ||
149 | } | ||
150 | |||
151 | /** | ||
152 | * ad7298_trigger_handler() bh of trigger launched polling to ring buffer | ||
153 | * | ||
154 | * Currently there is no option in this driver to disable the saving of | ||
155 | * timestamps within the ring. | ||
156 | **/ | ||
157 | static irqreturn_t ad7298_trigger_handler(int irq, void *p) | ||
158 | { | ||
159 | struct iio_poll_func *pf = p; | ||
160 | struct iio_dev *indio_dev = pf->indio_dev; | ||
161 | struct ad7298_state *st = iio_priv(indio_dev); | ||
162 | s64 time_ns = 0; | ||
163 | int b_sent; | ||
164 | |||
165 | b_sent = spi_sync(st->spi, &st->ring_msg); | ||
166 | if (b_sent) | ||
167 | goto done; | ||
168 | |||
169 | if (indio_dev->scan_timestamp) { | ||
170 | time_ns = iio_get_time_ns(); | ||
171 | memcpy((u8 *)st->rx_buf + indio_dev->scan_bytes - sizeof(s64), | ||
172 | &time_ns, sizeof(time_ns)); | ||
173 | } | ||
174 | |||
175 | iio_push_to_buffers(indio_dev, (u8 *)st->rx_buf); | ||
176 | |||
177 | done: | ||
178 | iio_trigger_notify_done(indio_dev->trig); | ||
179 | |||
180 | return IRQ_HANDLED; | ||
181 | } | ||
182 | |||
183 | static int ad7298_scan_direct(struct ad7298_state *st, unsigned ch) | ||
184 | { | ||
185 | int ret; | ||
186 | st->tx_buf[0] = cpu_to_be16(AD7298_WRITE | st->ext_ref | | ||
187 | (AD7298_CH(0) >> ch)); | ||
188 | |||
189 | ret = spi_sync(st->spi, &st->scan_single_msg); | ||
190 | if (ret) | ||
191 | return ret; | ||
192 | |||
193 | return be16_to_cpu(st->rx_buf[0]); | ||
194 | } | ||
195 | |||
196 | static int ad7298_scan_temp(struct ad7298_state *st, int *val) | ||
197 | { | ||
198 | int ret; | ||
199 | __be16 buf; | ||
200 | |||
201 | buf = cpu_to_be16(AD7298_WRITE | AD7298_TSENSE | | ||
202 | AD7298_TAVG | st->ext_ref); | ||
203 | |||
204 | ret = spi_write(st->spi, (u8 *)&buf, 2); | ||
205 | if (ret) | ||
206 | return ret; | ||
207 | |||
208 | buf = cpu_to_be16(0); | ||
209 | |||
210 | ret = spi_write(st->spi, (u8 *)&buf, 2); | ||
211 | if (ret) | ||
212 | return ret; | ||
213 | |||
214 | usleep_range(101, 1000); /* sleep > 100us */ | ||
215 | |||
216 | ret = spi_read(st->spi, (u8 *)&buf, 2); | ||
217 | if (ret) | ||
218 | return ret; | ||
219 | |||
220 | *val = sign_extend32(be16_to_cpu(buf), 11); | ||
221 | |||
222 | return 0; | ||
223 | } | ||
224 | |||
225 | static int ad7298_get_ref_voltage(struct ad7298_state *st) | ||
226 | { | ||
227 | int vref; | ||
228 | |||
229 | if (st->ext_ref) { | ||
230 | vref = regulator_get_voltage(st->reg); | ||
231 | if (vref < 0) | ||
232 | return vref; | ||
233 | |||
234 | return vref / 1000; | ||
235 | } else { | ||
236 | return AD7298_INTREF_mV; | ||
237 | } | ||
238 | } | ||
239 | |||
240 | static int ad7298_read_raw(struct iio_dev *indio_dev, | ||
241 | struct iio_chan_spec const *chan, | ||
242 | int *val, | ||
243 | int *val2, | ||
244 | long m) | ||
245 | { | ||
246 | int ret; | ||
247 | struct ad7298_state *st = iio_priv(indio_dev); | ||
248 | |||
249 | switch (m) { | ||
250 | case IIO_CHAN_INFO_RAW: | ||
251 | mutex_lock(&indio_dev->mlock); | ||
252 | if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) { | ||
253 | ret = -EBUSY; | ||
254 | } else { | ||
255 | if (chan->address == AD7298_CH_TEMP) | ||
256 | ret = ad7298_scan_temp(st, val); | ||
257 | else | ||
258 | ret = ad7298_scan_direct(st, chan->address); | ||
259 | } | ||
260 | mutex_unlock(&indio_dev->mlock); | ||
261 | |||
262 | if (ret < 0) | ||
263 | return ret; | ||
264 | |||
265 | if (chan->address != AD7298_CH_TEMP) | ||
266 | *val = ret & RES_MASK(AD7298_BITS); | ||
267 | |||
268 | return IIO_VAL_INT; | ||
269 | case IIO_CHAN_INFO_SCALE: | ||
270 | switch (chan->type) { | ||
271 | case IIO_VOLTAGE: | ||
272 | *val = ad7298_get_ref_voltage(st); | ||
273 | *val2 = chan->scan_type.realbits; | ||
274 | return IIO_VAL_FRACTIONAL_LOG2; | ||
275 | case IIO_TEMP: | ||
276 | *val = ad7298_get_ref_voltage(st); | ||
277 | *val2 = 10; | ||
278 | return IIO_VAL_FRACTIONAL; | ||
279 | default: | ||
280 | return -EINVAL; | ||
281 | } | ||
282 | case IIO_CHAN_INFO_OFFSET: | ||
283 | *val = 1093 - 2732500 / ad7298_get_ref_voltage(st); | ||
284 | return IIO_VAL_INT; | ||
285 | } | ||
286 | return -EINVAL; | ||
287 | } | ||
288 | |||
289 | static const struct iio_info ad7298_info = { | ||
290 | .read_raw = &ad7298_read_raw, | ||
291 | .update_scan_mode = ad7298_update_scan_mode, | ||
292 | .driver_module = THIS_MODULE, | ||
293 | }; | ||
294 | |||
295 | static int __devinit ad7298_probe(struct spi_device *spi) | ||
296 | { | ||
297 | struct ad7298_platform_data *pdata = spi->dev.platform_data; | ||
298 | struct ad7298_state *st; | ||
299 | struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st)); | ||
300 | int ret; | ||
301 | |||
302 | if (indio_dev == NULL) | ||
303 | return -ENOMEM; | ||
304 | |||
305 | st = iio_priv(indio_dev); | ||
306 | |||
307 | if (pdata && pdata->ext_ref) | ||
308 | st->ext_ref = AD7298_EXTREF; | ||
309 | |||
310 | if (st->ext_ref) { | ||
311 | st->reg = regulator_get(&spi->dev, "vref"); | ||
312 | if (IS_ERR(st->reg)) { | ||
313 | ret = PTR_ERR(st->reg); | ||
314 | goto error_free; | ||
315 | } | ||
316 | ret = regulator_enable(st->reg); | ||
317 | if (ret) | ||
318 | goto error_put_reg; | ||
319 | } | ||
320 | |||
321 | spi_set_drvdata(spi, indio_dev); | ||
322 | |||
323 | st->spi = spi; | ||
324 | |||
325 | indio_dev->name = spi_get_device_id(spi)->name; | ||
326 | indio_dev->dev.parent = &spi->dev; | ||
327 | indio_dev->modes = INDIO_DIRECT_MODE; | ||
328 | indio_dev->channels = ad7298_channels; | ||
329 | indio_dev->num_channels = ARRAY_SIZE(ad7298_channels); | ||
330 | indio_dev->info = &ad7298_info; | ||
331 | |||
332 | /* Setup default message */ | ||
333 | |||
334 | st->scan_single_xfer[0].tx_buf = &st->tx_buf[0]; | ||
335 | st->scan_single_xfer[0].len = 2; | ||
336 | st->scan_single_xfer[0].cs_change = 1; | ||
337 | st->scan_single_xfer[1].tx_buf = &st->tx_buf[1]; | ||
338 | st->scan_single_xfer[1].len = 2; | ||
339 | st->scan_single_xfer[1].cs_change = 1; | ||
340 | st->scan_single_xfer[2].rx_buf = &st->rx_buf[0]; | ||
341 | st->scan_single_xfer[2].len = 2; | ||
342 | |||
343 | spi_message_init(&st->scan_single_msg); | ||
344 | spi_message_add_tail(&st->scan_single_xfer[0], &st->scan_single_msg); | ||
345 | spi_message_add_tail(&st->scan_single_xfer[1], &st->scan_single_msg); | ||
346 | spi_message_add_tail(&st->scan_single_xfer[2], &st->scan_single_msg); | ||
347 | |||
348 | ret = iio_triggered_buffer_setup(indio_dev, NULL, | ||
349 | &ad7298_trigger_handler, NULL); | ||
350 | if (ret) | ||
351 | goto error_disable_reg; | ||
352 | |||
353 | ret = iio_device_register(indio_dev); | ||
354 | if (ret) | ||
355 | goto error_cleanup_ring; | ||
356 | |||
357 | return 0; | ||
358 | |||
359 | error_cleanup_ring: | ||
360 | iio_triggered_buffer_cleanup(indio_dev); | ||
361 | error_disable_reg: | ||
362 | if (st->ext_ref) | ||
363 | regulator_disable(st->reg); | ||
364 | error_put_reg: | ||
365 | if (st->ext_ref) | ||
366 | regulator_put(st->reg); | ||
367 | error_free: | ||
368 | iio_device_free(indio_dev); | ||
369 | |||
370 | return ret; | ||
371 | } | ||
372 | |||
373 | static int __devexit ad7298_remove(struct spi_device *spi) | ||
374 | { | ||
375 | struct iio_dev *indio_dev = spi_get_drvdata(spi); | ||
376 | struct ad7298_state *st = iio_priv(indio_dev); | ||
377 | |||
378 | iio_device_unregister(indio_dev); | ||
379 | iio_triggered_buffer_cleanup(indio_dev); | ||
380 | if (st->ext_ref) { | ||
381 | regulator_disable(st->reg); | ||
382 | regulator_put(st->reg); | ||
383 | } | ||
384 | iio_device_free(indio_dev); | ||
385 | |||
386 | return 0; | ||
387 | } | ||
388 | |||
389 | static const struct spi_device_id ad7298_id[] = { | ||
390 | {"ad7298", 0}, | ||
391 | {} | ||
392 | }; | ||
393 | MODULE_DEVICE_TABLE(spi, ad7298_id); | ||
394 | |||
395 | static struct spi_driver ad7298_driver = { | ||
396 | .driver = { | ||
397 | .name = "ad7298", | ||
398 | .owner = THIS_MODULE, | ||
399 | }, | ||
400 | .probe = ad7298_probe, | ||
401 | .remove = __devexit_p(ad7298_remove), | ||
402 | .id_table = ad7298_id, | ||
403 | }; | ||
404 | module_spi_driver(ad7298_driver); | ||
405 | |||
406 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | ||
407 | MODULE_DESCRIPTION("Analog Devices AD7298 ADC"); | ||
408 | MODULE_LICENSE("GPL v2"); | ||