blob: 50cedb42283978f98a70b09edd74f7706edd9d80 [file] [log] [blame]
Michael Hennerich349282d2010-10-11 18:05:37 +02001/*
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
Michael Hennerich349282d2010-10-11 18:05:37 +02009#include <linux/device.h>
10#include <linux/kernel.h>
11#include <linux/slab.h>
12#include <linux/sysfs.h>
Michael Hennerich349282d2010-10-11 18:05:37 +020013#include <linux/spi/spi.h>
14#include <linux/regulator/consumer.h>
15#include <linux/err.h>
16
17#include "../iio.h"
18#include "../sysfs.h"
19#include "../ring_generic.h"
20#include "adc.h"
21
22#include "ad7476.h"
23
24static int ad7476_scan_direct(struct ad7476_state *st)
25{
Michael Hennerich349282d2010-10-11 18:05:37 +020026 int ret;
27
Michael Hennerich668413e2010-10-11 18:05:56 +020028 ret = spi_sync(st->spi, &st->msg);
Michael Hennerich349282d2010-10-11 18:05:37 +020029 if (ret)
30 return ret;
31
32 return (st->data[0] << 8) | st->data[1];
33}
34
Jonathan Cameronc5e08192011-05-18 14:41:24 +010035static int ad7476_read_raw(struct iio_dev *dev_info,
36 struct iio_chan_spec const *chan,
37 int *val,
38 int *val2,
39 long m)
Michael Hennerich349282d2010-10-11 18:05:37 +020040{
Michael Hennerich349282d2010-10-11 18:05:37 +020041 int ret;
Jonathan Cameronc5e08192011-05-18 14:41:24 +010042 struct ad7476_state *st = dev_info->dev_data;
43 unsigned int scale_uv;
Michael Hennerich349282d2010-10-11 18:05:37 +020044
Jonathan Cameronc5e08192011-05-18 14:41:24 +010045 switch (m) {
46 case 0:
47 mutex_lock(&dev_info->mlock);
48 if (iio_ring_enabled(dev_info))
49 ret = ad7476_scan_from_ring(st);
50 else
51 ret = ad7476_scan_direct(st);
52 mutex_unlock(&dev_info->mlock);
Michael Hennerich349282d2010-10-11 18:05:37 +020053
Jonathan Cameronc5e08192011-05-18 14:41:24 +010054 if (ret < 0)
55 return ret;
56 *val = (ret >> st->chip_info->channel[0].scan_type.shift) &
57 RES_MASK(st->chip_info->channel[0].scan_type.realbits);
58 return IIO_VAL_INT;
59 case (1 << IIO_CHAN_INFO_SCALE_SHARED):
60 scale_uv = (st->int_vref_mv * 1000)
61 >> st->chip_info->channel[0].scan_type.realbits;
62 *val = scale_uv/1000;
63 *val2 = (scale_uv%1000)*1000;
64 return IIO_VAL_INT_PLUS_MICRO;
65 }
66 return -EINVAL;
Michael Hennerich349282d2010-10-11 18:05:37 +020067}
Michael Hennerich349282d2010-10-11 18:05:37 +020068
Michael Hennerich349282d2010-10-11 18:05:37 +020069static const struct ad7476_chip_info ad7476_chip_info_tbl[] = {
70 [ID_AD7466] = {
Jonathan Cameronc5e08192011-05-18 14:41:24 +010071 .channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
72 (1 << IIO_CHAN_INFO_SCALE_SHARED),
73 0, 0, IIO_ST('u', 12, 16, 0), 0),
74 .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
Michael Hennerich349282d2010-10-11 18:05:37 +020075 },
76 [ID_AD7467] = {
Jonathan Cameronc5e08192011-05-18 14:41:24 +010077 .channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
78 (1 << IIO_CHAN_INFO_SCALE_SHARED),
79 0, 0, IIO_ST('u', 10, 16, 2), 0),
80 .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
Michael Hennerich349282d2010-10-11 18:05:37 +020081 },
82 [ID_AD7468] = {
Jonathan Cameronc5e08192011-05-18 14:41:24 +010083 .channel[0] = IIO_CHAN(IIO_IN, 0, 1 , 0, NULL, 0, 0,
84 (1 << IIO_CHAN_INFO_SCALE_SHARED),
85 0, 0, IIO_ST('u', 8, 16, 4), 0),
86 .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
Michael Hennerich349282d2010-10-11 18:05:37 +020087 },
88 [ID_AD7475] = {
Jonathan Cameronc5e08192011-05-18 14:41:24 +010089 .channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
90 (1 << IIO_CHAN_INFO_SCALE_SHARED),
91 0, 0, IIO_ST('u', 12, 16, 0), 0),
92 .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
Michael Hennerich349282d2010-10-11 18:05:37 +020093 },
94 [ID_AD7476] = {
Jonathan Cameronc5e08192011-05-18 14:41:24 +010095 .channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
96 (1 << IIO_CHAN_INFO_SCALE_SHARED),
97 0, 0, IIO_ST('u', 12, 16, 0), 0),
98 .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
Michael Hennerich349282d2010-10-11 18:05:37 +020099 },
100 [ID_AD7477] = {
Jonathan Cameronc5e08192011-05-18 14:41:24 +0100101 .channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
102 (1 << IIO_CHAN_INFO_SCALE_SHARED),
103 0, 0, IIO_ST('u', 10, 16, 2), 0),
104 .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
Michael Hennerich349282d2010-10-11 18:05:37 +0200105 },
106 [ID_AD7478] = {
Jonathan Cameronc5e08192011-05-18 14:41:24 +0100107 .channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
108 (1 << IIO_CHAN_INFO_SCALE_SHARED),
109 0, 0, IIO_ST('u', 8, 16, 4), 0),
110 .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
Michael Hennerich349282d2010-10-11 18:05:37 +0200111 },
112 [ID_AD7495] = {
Jonathan Cameronc5e08192011-05-18 14:41:24 +0100113 .channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
114 (1 << IIO_CHAN_INFO_SCALE_SHARED),
115 0, 0, IIO_ST('u', 12, 16, 0), 0),
116 .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
Michael Hennerich349282d2010-10-11 18:05:37 +0200117 .int_vref_mv = 2500,
Michael Hennerich349282d2010-10-11 18:05:37 +0200118 },
119};
120
Jonathan Cameron6fe81352011-05-18 14:42:37 +0100121static const struct iio_info ad7476_info = {
122 .driver_module = THIS_MODULE,
123 .read_raw = &ad7476_read_raw,
124};
125
Michael Hennerich349282d2010-10-11 18:05:37 +0200126static int __devinit ad7476_probe(struct spi_device *spi)
127{
128 struct ad7476_platform_data *pdata = spi->dev.platform_data;
129 struct ad7476_state *st;
130 int ret, voltage_uv = 0;
131
132 st = kzalloc(sizeof(*st), GFP_KERNEL);
133 if (st == NULL) {
134 ret = -ENOMEM;
135 goto error_ret;
136 }
137
138 st->reg = regulator_get(&spi->dev, "vcc");
139 if (!IS_ERR(st->reg)) {
140 ret = regulator_enable(st->reg);
141 if (ret)
142 goto error_put_reg;
143
144 voltage_uv = regulator_get_voltage(st->reg);
145 }
146
147 st->chip_info =
148 &ad7476_chip_info_tbl[spi_get_device_id(spi)->driver_data];
149
150 if (st->chip_info->int_vref_mv)
151 st->int_vref_mv = st->chip_info->int_vref_mv;
152 else if (pdata && pdata->vref_mv)
153 st->int_vref_mv = pdata->vref_mv;
154 else if (voltage_uv)
155 st->int_vref_mv = voltage_uv / 1000;
156 else
157 dev_warn(&spi->dev, "reference voltage unspecified\n");
158
159 spi_set_drvdata(spi, st);
160
Michael Hennerich349282d2010-10-11 18:05:37 +0200161 st->spi = spi;
162
Jonathan Cameron6f7c8ee2011-04-15 18:55:56 +0100163 st->indio_dev = iio_allocate_device(0);
Michael Hennerich349282d2010-10-11 18:05:37 +0200164 if (st->indio_dev == NULL) {
165 ret = -ENOMEM;
166 goto error_disable_reg;
167 }
168
Roland Stiggeae639832011-01-29 16:27:17 +0100169 /* Establish that the iio_dev is a child of the spi device */
Michael Hennerich349282d2010-10-11 18:05:37 +0200170 st->indio_dev->dev.parent = &spi->dev;
Jonathan Cameron845bd122011-05-18 14:41:44 +0100171 st->indio_dev->name = spi_get_device_id(spi)->name;
Michael Hennerich349282d2010-10-11 18:05:37 +0200172 st->indio_dev->dev_data = (void *)(st);
Michael Hennerich349282d2010-10-11 18:05:37 +0200173 st->indio_dev->modes = INDIO_DIRECT_MODE;
Jonathan Cameronc5e08192011-05-18 14:41:24 +0100174 st->indio_dev->channels = st->chip_info->channel;
175 st->indio_dev->num_channels = 2;
Jonathan Cameron6fe81352011-05-18 14:42:37 +0100176 st->indio_dev->info = &ad7476_info;
Michael Hennerich349282d2010-10-11 18:05:37 +0200177 /* Setup default message */
178
179 st->xfer.rx_buf = &st->data;
Jonathan Cameronc5e08192011-05-18 14:41:24 +0100180 st->xfer.len = st->chip_info->channel[0].scan_type.storagebits / 8;
Michael Hennerich349282d2010-10-11 18:05:37 +0200181
182 spi_message_init(&st->msg);
183 spi_message_add_tail(&st->xfer, &st->msg);
184
185 ret = ad7476_register_ring_funcs_and_init(st->indio_dev);
186 if (ret)
187 goto error_free_device;
188
189 ret = iio_device_register(st->indio_dev);
190 if (ret)
191 goto error_free_device;
192
Jonathan Cameronc5e08192011-05-18 14:41:24 +0100193 ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0,
194 st->chip_info->channel,
195 ARRAY_SIZE(st->chip_info->channel));
Michael Hennerich349282d2010-10-11 18:05:37 +0200196 if (ret)
197 goto error_cleanup_ring;
198 return 0;
199
200error_cleanup_ring:
201 ad7476_ring_cleanup(st->indio_dev);
202 iio_device_unregister(st->indio_dev);
203error_free_device:
204 iio_free_device(st->indio_dev);
205error_disable_reg:
206 if (!IS_ERR(st->reg))
207 regulator_disable(st->reg);
208error_put_reg:
209 if (!IS_ERR(st->reg))
210 regulator_put(st->reg);
211 kfree(st);
212error_ret:
213 return ret;
214}
215
216static int ad7476_remove(struct spi_device *spi)
217{
218 struct ad7476_state *st = spi_get_drvdata(spi);
219 struct iio_dev *indio_dev = st->indio_dev;
220 iio_ring_buffer_unregister(indio_dev->ring);
221 ad7476_ring_cleanup(indio_dev);
222 iio_device_unregister(indio_dev);
223 if (!IS_ERR(st->reg)) {
224 regulator_disable(st->reg);
225 regulator_put(st->reg);
226 }
227 kfree(st);
228 return 0;
229}
230
231static const struct spi_device_id ad7476_id[] = {
232 {"ad7466", ID_AD7466},
233 {"ad7467", ID_AD7467},
234 {"ad7468", ID_AD7468},
235 {"ad7475", ID_AD7475},
236 {"ad7476", ID_AD7476},
237 {"ad7476a", ID_AD7476},
238 {"ad7477", ID_AD7477},
239 {"ad7477a", ID_AD7477},
240 {"ad7478", ID_AD7478},
241 {"ad7478a", ID_AD7478},
242 {"ad7495", ID_AD7495},
243 {}
244};
245
246static struct spi_driver ad7476_driver = {
247 .driver = {
248 .name = "ad7476",
249 .bus = &spi_bus_type,
250 .owner = THIS_MODULE,
251 },
252 .probe = ad7476_probe,
253 .remove = __devexit_p(ad7476_remove),
254 .id_table = ad7476_id,
255};
256
257static int __init ad7476_init(void)
258{
259 return spi_register_driver(&ad7476_driver);
260}
261module_init(ad7476_init);
262
263static void __exit ad7476_exit(void)
264{
265 spi_unregister_driver(&ad7476_driver);
266}
267module_exit(ad7476_exit);
268
269MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
270MODULE_DESCRIPTION("Analog Devices AD7475/6/7/8(A) AD7466/7/8 ADC");
271MODULE_LICENSE("GPL v2");
272MODULE_ALIAS("spi:ad7476");