blob: ce715225eff37be125731901019de5bf116de1a6 [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>
Paul Gortmaker99c97852011-07-03 15:49:50 -040016#include <linux/module.h>
Michael Hennerich349282d2010-10-11 18:05:37 +020017
18#include "../iio.h"
19#include "../sysfs.h"
Jonathan Cameronaf5046a2011-10-26 17:41:32 +010020#include "../buffer.h"
Michael Hennerich349282d2010-10-11 18:05:37 +020021
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 Cameron84f79ec2011-10-06 17:14:37 +010035static int ad7476_read_raw(struct iio_dev *indio_dev,
Jonathan Cameronc5e08192011-05-18 14:41:24 +010036 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 Cameron84f79ec2011-10-06 17:14:37 +010042 struct ad7476_state *st = iio_priv(indio_dev);
Jonathan Cameronc5e08192011-05-18 14:41:24 +010043 unsigned int scale_uv;
Michael Hennerich349282d2010-10-11 18:05:37 +020044
Jonathan Cameronc5e08192011-05-18 14:41:24 +010045 switch (m) {
Jonathan Cameronb11f98f2012-04-15 17:41:18 +010046 case IIO_CHAN_INFO_RAW:
Jonathan Cameron84f79ec2011-10-06 17:14:37 +010047 mutex_lock(&indio_dev->mlock);
48 if (iio_buffer_enabled(indio_dev))
Jonathan Cameron78c32ed2011-12-05 22:18:20 +000049 ret = -EBUSY;
Jonathan Cameronc5e08192011-05-18 14:41:24 +010050 else
51 ret = ad7476_scan_direct(st);
Jonathan Cameron84f79ec2011-10-06 17:14:37 +010052 mutex_unlock(&indio_dev->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;
Jonathan Cameronc8a9f802011-10-26 17:41:36 +010059 case IIO_CHAN_INFO_SCALE:
Jonathan Cameronc5e08192011-05-18 14:41:24 +010060 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
Jonathan Cameron85871cd2012-04-13 10:42:55 +010069#define AD7476_CHAN(bits) \
70 { \
71 .type = IIO_VOLTAGE, \
72 .indexed = 1, \
Jonathan Cameronb11f98f2012-04-15 17:41:18 +010073 .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
74 IIO_CHAN_INFO_SCALE_SHARED_BIT, \
Jonathan Cameron85871cd2012-04-13 10:42:55 +010075 .scan_type = { \
76 .sign = 'u', \
77 .realbits = bits, \
78 .storagebits = 16, \
79 .shift = 12 - bits, \
80 }, \
81}
82
Michael Hennerich349282d2010-10-11 18:05:37 +020083static const struct ad7476_chip_info ad7476_chip_info_tbl[] = {
84 [ID_AD7466] = {
Jonathan Cameron85871cd2012-04-13 10:42:55 +010085 .channel[0] = AD7476_CHAN(12),
Jonathan Cameronc5e08192011-05-18 14:41:24 +010086 .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
Michael Hennerich349282d2010-10-11 18:05:37 +020087 },
88 [ID_AD7467] = {
Jonathan Cameron85871cd2012-04-13 10:42:55 +010089 .channel[0] = AD7476_CHAN(10),
Jonathan Cameronc5e08192011-05-18 14:41:24 +010090 .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
Michael Hennerich349282d2010-10-11 18:05:37 +020091 },
92 [ID_AD7468] = {
Jonathan Cameron85871cd2012-04-13 10:42:55 +010093 .channel[0] = AD7476_CHAN(8),
Jonathan Cameronc5e08192011-05-18 14:41:24 +010094 .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
Michael Hennerich349282d2010-10-11 18:05:37 +020095 },
96 [ID_AD7475] = {
Jonathan Cameron85871cd2012-04-13 10:42:55 +010097 .channel[0] = AD7476_CHAN(12),
Jonathan Cameronc5e08192011-05-18 14:41:24 +010098 .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
Michael Hennerich349282d2010-10-11 18:05:37 +020099 },
100 [ID_AD7476] = {
Jonathan Cameron85871cd2012-04-13 10:42:55 +0100101 .channel[0] = AD7476_CHAN(12),
Jonathan Cameronc5e08192011-05-18 14:41:24 +0100102 .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
Michael Hennerich349282d2010-10-11 18:05:37 +0200103 },
104 [ID_AD7477] = {
Jonathan Cameron85871cd2012-04-13 10:42:55 +0100105 .channel[0] = AD7476_CHAN(10),
Jonathan Cameronc5e08192011-05-18 14:41:24 +0100106 .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
Michael Hennerich349282d2010-10-11 18:05:37 +0200107 },
108 [ID_AD7478] = {
Jonathan Cameron85871cd2012-04-13 10:42:55 +0100109 .channel[0] = AD7476_CHAN(8),
Jonathan Cameronc5e08192011-05-18 14:41:24 +0100110 .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
Michael Hennerich349282d2010-10-11 18:05:37 +0200111 },
112 [ID_AD7495] = {
Jonathan Cameron85871cd2012-04-13 10:42:55 +0100113 .channel[0] = AD7476_CHAN(12),
Jonathan Cameronc5e08192011-05-18 14:41:24 +0100114 .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
Michael Hennerich349282d2010-10-11 18:05:37 +0200115 .int_vref_mv = 2500,
Michael Hennerich349282d2010-10-11 18:05:37 +0200116 },
117};
118
Jonathan Cameron6fe81352011-05-18 14:42:37 +0100119static const struct iio_info ad7476_info = {
120 .driver_module = THIS_MODULE,
121 .read_raw = &ad7476_read_raw,
122};
123
Michael Hennerich349282d2010-10-11 18:05:37 +0200124static int __devinit ad7476_probe(struct spi_device *spi)
125{
126 struct ad7476_platform_data *pdata = spi->dev.platform_data;
127 struct ad7476_state *st;
Jonathan Cameron67688102011-06-27 13:07:18 +0100128 struct iio_dev *indio_dev;
Michael Hennerich349282d2010-10-11 18:05:37 +0200129 int ret, voltage_uv = 0;
130
Jonathan Cameron67688102011-06-27 13:07:18 +0100131 indio_dev = iio_allocate_device(sizeof(*st));
132 if (indio_dev == NULL) {
Michael Hennerich349282d2010-10-11 18:05:37 +0200133 ret = -ENOMEM;
134 goto error_ret;
135 }
Jonathan Cameron67688102011-06-27 13:07:18 +0100136 st = iio_priv(indio_dev);
Jonathan Cameron26a54792011-08-30 12:41:19 +0100137 st->reg = regulator_get(&spi->dev, "vcc");
138 if (!IS_ERR(st->reg)) {
139 ret = regulator_enable(st->reg);
Michael Hennerich349282d2010-10-11 18:05:37 +0200140 if (ret)
141 goto error_put_reg;
142
Jonathan Cameron26a54792011-08-30 12:41:19 +0100143 voltage_uv = regulator_get_voltage(st->reg);
Michael Hennerich349282d2010-10-11 18:05:37 +0200144 }
Michael Hennerich349282d2010-10-11 18:05:37 +0200145 st->chip_info =
146 &ad7476_chip_info_tbl[spi_get_device_id(spi)->driver_data];
147
148 if (st->chip_info->int_vref_mv)
149 st->int_vref_mv = st->chip_info->int_vref_mv;
150 else if (pdata && pdata->vref_mv)
151 st->int_vref_mv = pdata->vref_mv;
152 else if (voltage_uv)
153 st->int_vref_mv = voltage_uv / 1000;
154 else
155 dev_warn(&spi->dev, "reference voltage unspecified\n");
156
Jonathan Cameron38f71aa2011-07-13 13:42:47 +0100157 spi_set_drvdata(spi, indio_dev);
Michael Hennerich349282d2010-10-11 18:05:37 +0200158
Michael Hennerich349282d2010-10-11 18:05:37 +0200159 st->spi = spi;
160
Roland Stiggeae639832011-01-29 16:27:17 +0100161 /* Establish that the iio_dev is a child of the spi device */
Jonathan Cameron67688102011-06-27 13:07:18 +0100162 indio_dev->dev.parent = &spi->dev;
163 indio_dev->name = spi_get_device_id(spi)->name;
164 indio_dev->modes = INDIO_DIRECT_MODE;
165 indio_dev->channels = st->chip_info->channel;
166 indio_dev->num_channels = 2;
167 indio_dev->info = &ad7476_info;
Michael Hennerich349282d2010-10-11 18:05:37 +0200168 /* Setup default message */
169
170 st->xfer.rx_buf = &st->data;
Jonathan Cameronc5e08192011-05-18 14:41:24 +0100171 st->xfer.len = st->chip_info->channel[0].scan_type.storagebits / 8;
Michael Hennerich349282d2010-10-11 18:05:37 +0200172
173 spi_message_init(&st->msg);
174 spi_message_add_tail(&st->xfer, &st->msg);
175
Jonathan Cameron67688102011-06-27 13:07:18 +0100176 ret = ad7476_register_ring_funcs_and_init(indio_dev);
Michael Hennerich349282d2010-10-11 18:05:37 +0200177 if (ret)
Jonathan Cameron67688102011-06-27 13:07:18 +0100178 goto error_disable_reg;
Michael Hennerich349282d2010-10-11 18:05:37 +0200179
Jonathan Cameron14555b12011-09-21 11:15:57 +0100180 ret = iio_buffer_register(indio_dev,
181 st->chip_info->channel,
182 ARRAY_SIZE(st->chip_info->channel));
Michael Hennerich349282d2010-10-11 18:05:37 +0200183 if (ret)
184 goto error_cleanup_ring;
Jonathan Cameron26d25ae2011-09-02 17:14:40 +0100185
186 ret = iio_device_register(indio_dev);
187 if (ret)
188 goto error_ring_unregister;
Michael Hennerich349282d2010-10-11 18:05:37 +0200189 return 0;
190
Jonathan Cameron26d25ae2011-09-02 17:14:40 +0100191error_ring_unregister:
Jonathan Cameron14555b12011-09-21 11:15:57 +0100192 iio_buffer_unregister(indio_dev);
Michael Hennerich349282d2010-10-11 18:05:37 +0200193error_cleanup_ring:
Jonathan Cameron67688102011-06-27 13:07:18 +0100194 ad7476_ring_cleanup(indio_dev);
Michael Hennerich349282d2010-10-11 18:05:37 +0200195error_disable_reg:
Jonathan Cameron26a54792011-08-30 12:41:19 +0100196 if (!IS_ERR(st->reg))
Michael Hennerich349282d2010-10-11 18:05:37 +0200197 regulator_disable(st->reg);
198error_put_reg:
Jonathan Cameron26a54792011-08-30 12:41:19 +0100199 if (!IS_ERR(st->reg))
200 regulator_put(st->reg);
Jonathan Cameron26d25ae2011-09-02 17:14:40 +0100201 iio_free_device(indio_dev);
202
Michael Hennerich349282d2010-10-11 18:05:37 +0200203error_ret:
204 return ret;
205}
206
207static int ad7476_remove(struct spi_device *spi)
208{
Jonathan Cameron67688102011-06-27 13:07:18 +0100209 struct iio_dev *indio_dev = spi_get_drvdata(spi);
210 struct ad7476_state *st = iio_priv(indio_dev);
Jonathan Cameron67688102011-06-27 13:07:18 +0100211
Jonathan Camerond2fffd62011-10-14 14:46:58 +0100212 iio_device_unregister(indio_dev);
Jonathan Cameron14555b12011-09-21 11:15:57 +0100213 iio_buffer_unregister(indio_dev);
Michael Hennerich349282d2010-10-11 18:05:37 +0200214 ad7476_ring_cleanup(indio_dev);
Jonathan Cameron26a54792011-08-30 12:41:19 +0100215 if (!IS_ERR(st->reg)) {
216 regulator_disable(st->reg);
217 regulator_put(st->reg);
Michael Hennerich349282d2010-10-11 18:05:37 +0200218 }
Jonathan Camerond2fffd62011-10-14 14:46:58 +0100219 iio_free_device(indio_dev);
Jonathan Cameron67688102011-06-27 13:07:18 +0100220
Michael Hennerich349282d2010-10-11 18:05:37 +0200221 return 0;
222}
223
224static const struct spi_device_id ad7476_id[] = {
225 {"ad7466", ID_AD7466},
226 {"ad7467", ID_AD7467},
227 {"ad7468", ID_AD7468},
228 {"ad7475", ID_AD7475},
229 {"ad7476", ID_AD7476},
230 {"ad7476a", ID_AD7476},
231 {"ad7477", ID_AD7477},
232 {"ad7477a", ID_AD7477},
233 {"ad7478", ID_AD7478},
234 {"ad7478a", ID_AD7478},
235 {"ad7495", ID_AD7495},
236 {}
237};
Lars-Peter Clausen55e43902011-11-16 08:53:31 +0100238MODULE_DEVICE_TABLE(spi, ad7476_id);
Michael Hennerich349282d2010-10-11 18:05:37 +0200239
240static struct spi_driver ad7476_driver = {
241 .driver = {
242 .name = "ad7476",
Michael Hennerich349282d2010-10-11 18:05:37 +0200243 .owner = THIS_MODULE,
244 },
245 .probe = ad7476_probe,
246 .remove = __devexit_p(ad7476_remove),
247 .id_table = ad7476_id,
248};
Lars-Peter Clausenae6ae6f2011-11-16 10:13:39 +0100249module_spi_driver(ad7476_driver);
Michael Hennerich349282d2010-10-11 18:05:37 +0200250
251MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
252MODULE_DESCRIPTION("Analog Devices AD7475/6/7/8(A) AD7466/7/8 ADC");
253MODULE_LICENSE("GPL v2");