blob: a109e686b9f70c712d961f91dc26cc4616837dc8 [file] [log] [blame]
Michael Hennerich88bc3052011-06-08 16:12:44 +02001/*
Lars-Peter Clausen8c29ecd2012-08-10 17:36:00 +01002 * AD7785/AD7792/AD7793/AD7794/AD7795 SPI ADC driver
Michael Hennerich88bc3052011-06-08 16:12:44 +02003 *
Michael Hennerichf3169832012-04-30 16:06:12 +02004 * Copyright 2011-2012 Analog Devices Inc.
Michael Hennerich88bc3052011-06-08 16:12:44 +02005 *
6 * Licensed under the GPL-2.
7 */
8
9#include <linux/interrupt.h>
10#include <linux/device.h>
11#include <linux/kernel.h>
12#include <linux/slab.h>
13#include <linux/sysfs.h>
14#include <linux/spi/spi.h>
15#include <linux/regulator/consumer.h>
16#include <linux/err.h>
17#include <linux/sched.h>
18#include <linux/delay.h>
Paul Gortmaker45296232011-08-30 17:50:46 -040019#include <linux/module.h>
Michael Hennerich88bc3052011-06-08 16:12:44 +020020
Jonathan Cameron06458e22012-04-25 15:54:58 +010021#include <linux/iio/iio.h>
22#include <linux/iio/sysfs.h>
23#include <linux/iio/buffer.h>
Jonathan Cameron06458e22012-04-25 15:54:58 +010024#include <linux/iio/trigger.h>
25#include <linux/iio/trigger_consumer.h>
Lars-Peter Clausen82796ed2012-06-18 18:33:54 +020026#include <linux/iio/triggered_buffer.h>
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +010027#include <linux/iio/adc/ad_sigma_delta.h>
Lars-Peter Clausenf87f1a22012-11-21 16:27:00 +000028#include <linux/platform_data/ad7793.h>
Michael Hennerich88bc3052011-06-08 16:12:44 +020029
Lars-Peter Clausen891c8bc2012-11-21 16:27:00 +000030/* Registers */
31#define AD7793_REG_COMM 0 /* Communications Register (WO, 8-bit) */
32#define AD7793_REG_STAT 0 /* Status Register (RO, 8-bit) */
33#define AD7793_REG_MODE 1 /* Mode Register (RW, 16-bit */
34#define AD7793_REG_CONF 2 /* Configuration Register (RW, 16-bit) */
35#define AD7793_REG_DATA 3 /* Data Register (RO, 16-/24-bit) */
36#define AD7793_REG_ID 4 /* ID Register (RO, 8-bit) */
37#define AD7793_REG_IO 5 /* IO Register (RO, 8-bit) */
38#define AD7793_REG_OFFSET 6 /* Offset Register (RW, 16-bit
39 * (AD7792)/24-bit (AD7793)) */
40#define AD7793_REG_FULLSALE 7 /* Full-Scale Register
41 * (RW, 16-bit (AD7792)/24-bit (AD7793)) */
42
43/* Communications Register Bit Designations (AD7793_REG_COMM) */
44#define AD7793_COMM_WEN (1 << 7) /* Write Enable */
45#define AD7793_COMM_WRITE (0 << 6) /* Write Operation */
46#define AD7793_COMM_READ (1 << 6) /* Read Operation */
47#define AD7793_COMM_ADDR(x) (((x) & 0x7) << 3) /* Register Address */
48#define AD7793_COMM_CREAD (1 << 2) /* Continuous Read of Data Register */
49
50/* Status Register Bit Designations (AD7793_REG_STAT) */
51#define AD7793_STAT_RDY (1 << 7) /* Ready */
52#define AD7793_STAT_ERR (1 << 6) /* Error (Overrange, Underrange) */
53#define AD7793_STAT_CH3 (1 << 2) /* Channel 3 */
54#define AD7793_STAT_CH2 (1 << 1) /* Channel 2 */
55#define AD7793_STAT_CH1 (1 << 0) /* Channel 1 */
56
57/* Mode Register Bit Designations (AD7793_REG_MODE) */
58#define AD7793_MODE_SEL(x) (((x) & 0x7) << 13) /* Operation Mode Select */
59#define AD7793_MODE_SEL_MASK (0x7 << 13) /* Operation Mode Select mask */
60#define AD7793_MODE_CLKSRC(x) (((x) & 0x3) << 6) /* ADC Clock Source Select */
61#define AD7793_MODE_RATE(x) ((x) & 0xF) /* Filter Update Rate Select */
62
63#define AD7793_MODE_CONT 0 /* Continuous Conversion Mode */
64#define AD7793_MODE_SINGLE 1 /* Single Conversion Mode */
65#define AD7793_MODE_IDLE 2 /* Idle Mode */
66#define AD7793_MODE_PWRDN 3 /* Power-Down Mode */
67#define AD7793_MODE_CAL_INT_ZERO 4 /* Internal Zero-Scale Calibration */
68#define AD7793_MODE_CAL_INT_FULL 5 /* Internal Full-Scale Calibration */
69#define AD7793_MODE_CAL_SYS_ZERO 6 /* System Zero-Scale Calibration */
70#define AD7793_MODE_CAL_SYS_FULL 7 /* System Full-Scale Calibration */
71
72#define AD7793_CLK_INT 0 /* Internal 64 kHz Clock not
73 * available at the CLK pin */
74#define AD7793_CLK_INT_CO 1 /* Internal 64 kHz Clock available
75 * at the CLK pin */
76#define AD7793_CLK_EXT 2 /* External 64 kHz Clock */
77#define AD7793_CLK_EXT_DIV2 3 /* External Clock divided by 2 */
78
79/* Configuration Register Bit Designations (AD7793_REG_CONF) */
80#define AD7793_CONF_VBIAS(x) (((x) & 0x3) << 14) /* Bias Voltage
81 * Generator Enable */
82#define AD7793_CONF_BO_EN (1 << 13) /* Burnout Current Enable */
83#define AD7793_CONF_UNIPOLAR (1 << 12) /* Unipolar/Bipolar Enable */
84#define AD7793_CONF_BOOST (1 << 11) /* Boost Enable */
85#define AD7793_CONF_GAIN(x) (((x) & 0x7) << 8) /* Gain Select */
86#define AD7793_CONF_REFSEL(x) ((x) << 6) /* INT/EXT Reference Select */
87#define AD7793_CONF_BUF (1 << 4) /* Buffered Mode Enable */
88#define AD7793_CONF_CHAN(x) ((x) & 0xf) /* Channel select */
89#define AD7793_CONF_CHAN_MASK 0xf /* Channel select mask */
90
91#define AD7793_CH_AIN1P_AIN1M 0 /* AIN1(+) - AIN1(-) */
92#define AD7793_CH_AIN2P_AIN2M 1 /* AIN2(+) - AIN2(-) */
93#define AD7793_CH_AIN3P_AIN3M 2 /* AIN3(+) - AIN3(-) */
94#define AD7793_CH_AIN1M_AIN1M 3 /* AIN1(-) - AIN1(-) */
95#define AD7793_CH_TEMP 6 /* Temp Sensor */
96#define AD7793_CH_AVDD_MONITOR 7 /* AVDD Monitor */
97
98#define AD7795_CH_AIN4P_AIN4M 4 /* AIN4(+) - AIN4(-) */
99#define AD7795_CH_AIN5P_AIN5M 5 /* AIN5(+) - AIN5(-) */
100#define AD7795_CH_AIN6P_AIN6M 6 /* AIN6(+) - AIN6(-) */
101#define AD7795_CH_AIN1M_AIN1M 8 /* AIN1(-) - AIN1(-) */
102
103/* ID Register Bit Designations (AD7793_REG_ID) */
Lars-Peter Clausene786cc22012-11-21 16:27:00 +0000104#define AD7785_ID 0xB
Lars-Peter Clausen891c8bc2012-11-21 16:27:00 +0000105#define AD7792_ID 0xA
106#define AD7793_ID 0xB
Lars-Peter Clausene786cc22012-11-21 16:27:00 +0000107#define AD7794_ID 0xF
Lars-Peter Clausen891c8bc2012-11-21 16:27:00 +0000108#define AD7795_ID 0xF
109#define AD7793_ID_MASK 0xF
110
111/* IO (Excitation Current Sources) Register Bit Designations (AD7793_REG_IO) */
112#define AD7793_IO_IEXC1_IOUT1_IEXC2_IOUT2 0 /* IEXC1 connect to IOUT1,
113 * IEXC2 connect to IOUT2 */
114#define AD7793_IO_IEXC1_IOUT2_IEXC2_IOUT1 1 /* IEXC1 connect to IOUT2,
115 * IEXC2 connect to IOUT1 */
116#define AD7793_IO_IEXC1_IEXC2_IOUT1 2 /* Both current sources
117 * IEXC1,2 connect to IOUT1 */
118#define AD7793_IO_IEXC1_IEXC2_IOUT2 3 /* Both current sources
119 * IEXC1,2 connect to IOUT2 */
120
121#define AD7793_IO_IXCEN_10uA (1 << 0) /* Excitation Current 10uA */
122#define AD7793_IO_IXCEN_210uA (2 << 0) /* Excitation Current 210uA */
123#define AD7793_IO_IXCEN_1mA (3 << 0) /* Excitation Current 1mA */
124
Michael Hennerich88bc3052011-06-08 16:12:44 +0200125/* NOTE:
126 * The AD7792/AD7793 features a dual use data out ready DOUT/RDY output.
127 * In order to avoid contentions on the SPI bus, it's therefore necessary
128 * to use spi bus locking.
129 *
130 * The DOUT/RDY output must also be wired to an interrupt capable GPIO.
131 */
132
133struct ad7793_chip_info {
Lars-Peter Clausene786cc22012-11-21 16:27:00 +0000134 unsigned int id;
Lars-Peter Clausen525e6432012-08-10 17:36:00 +0100135 const struct iio_chan_spec *channels;
136 unsigned int num_channels;
Michael Hennerich88bc3052011-06-08 16:12:44 +0200137};
138
139struct ad7793_state {
Michael Hennerich88bc3052011-06-08 16:12:44 +0200140 const struct ad7793_chip_info *chip_info;
141 struct regulator *reg;
Michael Hennerich88bc3052011-06-08 16:12:44 +0200142 u16 int_vref_mv;
143 u16 mode;
144 u16 conf;
145 u32 scale_avail[8][2];
Lars-Peter Clausen8c2c6ba2012-07-09 10:00:00 +0100146
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100147 struct ad_sigma_delta sd;
148
Michael Hennerich88bc3052011-06-08 16:12:44 +0200149};
150
151enum ad7793_supported_device_ids {
Lars-Peter Clausen8c29ecd2012-08-10 17:36:00 +0100152 ID_AD7785,
Michael Hennerich88bc3052011-06-08 16:12:44 +0200153 ID_AD7792,
154 ID_AD7793,
Lars-Peter Clausen525e6432012-08-10 17:36:00 +0100155 ID_AD7794,
156 ID_AD7795,
Michael Hennerich88bc3052011-06-08 16:12:44 +0200157};
158
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100159static struct ad7793_state *ad_sigma_delta_to_ad7793(struct ad_sigma_delta *sd)
Michael Hennerich88bc3052011-06-08 16:12:44 +0200160{
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100161 return container_of(sd, struct ad7793_state, sd);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200162}
163
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100164static int ad7793_set_channel(struct ad_sigma_delta *sd, unsigned int channel)
Michael Hennerich88bc3052011-06-08 16:12:44 +0200165{
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100166 struct ad7793_state *st = ad_sigma_delta_to_ad7793(sd);
167
168 st->conf &= ~AD7793_CONF_CHAN_MASK;
169 st->conf |= AD7793_CONF_CHAN(channel);
170
171 return ad_sd_write_reg(&st->sd, AD7793_REG_CONF, 2, st->conf);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200172}
173
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100174static int ad7793_set_mode(struct ad_sigma_delta *sd,
175 enum ad_sigma_delta_mode mode)
Michael Hennerich88bc3052011-06-08 16:12:44 +0200176{
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100177 struct ad7793_state *st = ad_sigma_delta_to_ad7793(sd);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200178
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100179 st->mode &= ~AD7793_MODE_SEL_MASK;
180 st->mode |= AD7793_MODE_SEL(mode);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200181
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100182 return ad_sd_write_reg(&st->sd, AD7793_REG_MODE, 2, st->mode);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200183}
184
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100185static const struct ad_sigma_delta_info ad7793_sigma_delta_info = {
186 .set_channel = ad7793_set_channel,
187 .set_mode = ad7793_set_mode,
188 .has_registers = true,
189 .addr_shift = 3,
190 .read_mask = BIT(6),
191};
Michael Hennerich88bc3052011-06-08 16:12:44 +0200192
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100193static const struct ad_sd_calib_data ad7793_calib_arr[6] = {
Michael Hennerich88bc3052011-06-08 16:12:44 +0200194 {AD7793_MODE_CAL_INT_ZERO, AD7793_CH_AIN1P_AIN1M},
195 {AD7793_MODE_CAL_INT_FULL, AD7793_CH_AIN1P_AIN1M},
196 {AD7793_MODE_CAL_INT_ZERO, AD7793_CH_AIN2P_AIN2M},
197 {AD7793_MODE_CAL_INT_FULL, AD7793_CH_AIN2P_AIN2M},
198 {AD7793_MODE_CAL_INT_ZERO, AD7793_CH_AIN3P_AIN3M},
199 {AD7793_MODE_CAL_INT_FULL, AD7793_CH_AIN3P_AIN3M}
200};
201
202static int ad7793_calibrate_all(struct ad7793_state *st)
203{
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100204 return ad_sd_calibrate_all(&st->sd, ad7793_calib_arr,
205 ARRAY_SIZE(ad7793_calib_arr));
Michael Hennerich88bc3052011-06-08 16:12:44 +0200206}
207
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100208static int ad7793_setup(struct iio_dev *indio_dev,
Lars-Peter Clausendd2c1012012-11-21 16:27:00 +0000209 const struct ad7793_platform_data *pdata,
210 unsigned int vref_mv)
Michael Hennerich88bc3052011-06-08 16:12:44 +0200211{
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100212 struct ad7793_state *st = iio_priv(indio_dev);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200213 int i, ret = -1;
214 unsigned long long scale_uv;
215 u32 id;
216
Lars-Peter Clausend21f30c2012-11-21 16:27:00 +0000217 if ((pdata->current_source_direction == AD7793_IEXEC1_IEXEC2_IOUT1 ||
218 pdata->current_source_direction == AD7793_IEXEC1_IEXEC2_IOUT2) &&
219 ((pdata->exitation_current != AD7793_IX_10uA) &&
220 (pdata->exitation_current != AD7793_IX_210uA)))
221 return -EINVAL;
222
Michael Hennerich88bc3052011-06-08 16:12:44 +0200223 /* reset the serial interface */
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100224 ret = spi_write(st->sd.spi, (u8 *)&ret, sizeof(ret));
Michael Hennerich88bc3052011-06-08 16:12:44 +0200225 if (ret < 0)
226 goto out;
Lars-Peter Clausen3e4334f2012-11-21 16:27:00 +0000227 usleep_range(500, 2000); /* Wait for at least 500us */
Michael Hennerich88bc3052011-06-08 16:12:44 +0200228
229 /* write/read test for device presence */
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100230 ret = ad_sd_read_reg(&st->sd, AD7793_REG_ID, 1, &id);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200231 if (ret)
232 goto out;
233
234 id &= AD7793_ID_MASK;
235
Lars-Peter Clausene786cc22012-11-21 16:27:00 +0000236 if (id != st->chip_info->id) {
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100237 dev_err(&st->sd.spi->dev, "device ID query failed\n");
Michael Hennerich88bc3052011-06-08 16:12:44 +0200238 goto out;
239 }
240
Lars-Peter Clausend21f30c2012-11-21 16:27:00 +0000241 st->mode = AD7793_MODE_RATE(1);
242 st->mode |= AD7793_MODE_CLKSRC(pdata->clock_src);
243 st->conf = AD7793_CONF_REFSEL(pdata->refsel);
244 st->conf |= AD7793_CONF_VBIAS(pdata->bias_voltage);
245 if (pdata->buffered)
246 st->conf |= AD7793_CONF_BUF;
247 if (pdata->boost_enable)
248 st->conf |= AD7793_CONF_BOOST;
249 if (pdata->burnout_current)
250 st->conf |= AD7793_CONF_BO_EN;
251 if (pdata->unipolar)
252 st->conf |= AD7793_CONF_UNIPOLAR;
Michael Hennerich88bc3052011-06-08 16:12:44 +0200253
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100254 ret = ad7793_set_mode(&st->sd, AD_SD_MODE_IDLE);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200255 if (ret)
256 goto out;
257
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100258 ret = ad7793_set_channel(&st->sd, 0);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200259 if (ret)
260 goto out;
261
Lars-Peter Clausend21f30c2012-11-21 16:27:00 +0000262 ret = ad_sd_write_reg(&st->sd, AD7793_REG_IO, 1,
263 pdata->exitation_current |
264 (pdata->current_source_direction << 2));
Michael Hennerich88bc3052011-06-08 16:12:44 +0200265 if (ret)
266 goto out;
267
268 ret = ad7793_calibrate_all(st);
269 if (ret)
270 goto out;
271
272 /* Populate available ADC input ranges */
273 for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++) {
Lars-Peter Clausendd2c1012012-11-21 16:27:00 +0000274 scale_uv = ((u64)vref_mv * 100000000)
Lars-Peter Clausen525e6432012-08-10 17:36:00 +0100275 >> (st->chip_info->channels[0].scan_type.realbits -
Michael Hennerich88bc3052011-06-08 16:12:44 +0200276 (!!(st->conf & AD7793_CONF_UNIPOLAR) ? 0 : 1));
277 scale_uv >>= i;
278
279 st->scale_avail[i][1] = do_div(scale_uv, 100000000) * 10;
280 st->scale_avail[i][0] = scale_uv;
281 }
282
283 return 0;
284out:
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100285 dev_err(&st->sd.spi->dev, "setup failed\n");
Michael Hennerich88bc3052011-06-08 16:12:44 +0200286 return ret;
287}
288
Michael Hennerich88bc3052011-06-08 16:12:44 +0200289static const u16 sample_freq_avail[16] = {0, 470, 242, 123, 62, 50, 39, 33, 19,
290 17, 16, 12, 10, 8, 6, 4};
291
292static ssize_t ad7793_read_frequency(struct device *dev,
293 struct device_attribute *attr,
294 char *buf)
295{
Lars-Peter Clausen62c51832012-05-12 15:39:42 +0200296 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200297 struct ad7793_state *st = iio_priv(indio_dev);
298
299 return sprintf(buf, "%d\n",
300 sample_freq_avail[AD7793_MODE_RATE(st->mode)]);
301}
302
303static ssize_t ad7793_write_frequency(struct device *dev,
304 struct device_attribute *attr,
305 const char *buf,
306 size_t len)
307{
Lars-Peter Clausen62c51832012-05-12 15:39:42 +0200308 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200309 struct ad7793_state *st = iio_priv(indio_dev);
310 long lval;
311 int i, ret;
312
313 mutex_lock(&indio_dev->mlock);
Jonathan Cameron14555b12011-09-21 11:15:57 +0100314 if (iio_buffer_enabled(indio_dev)) {
Michael Hennerich88bc3052011-06-08 16:12:44 +0200315 mutex_unlock(&indio_dev->mlock);
316 return -EBUSY;
317 }
318 mutex_unlock(&indio_dev->mlock);
319
Lars-Peter Clausenfe2e0d52012-11-21 16:27:00 +0000320 ret = kstrtol(buf, 10, &lval);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200321 if (ret)
322 return ret;
323
324 ret = -EINVAL;
325
326 for (i = 0; i < ARRAY_SIZE(sample_freq_avail); i++)
327 if (lval == sample_freq_avail[i]) {
328 mutex_lock(&indio_dev->mlock);
329 st->mode &= ~AD7793_MODE_RATE(-1);
330 st->mode |= AD7793_MODE_RATE(i);
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100331 ad_sd_write_reg(&st->sd, AD7793_REG_MODE,
Michael Hennerich88bc3052011-06-08 16:12:44 +0200332 sizeof(st->mode), st->mode);
333 mutex_unlock(&indio_dev->mlock);
334 ret = 0;
335 }
336
337 return ret ? ret : len;
338}
339
340static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
341 ad7793_read_frequency,
342 ad7793_write_frequency);
343
344static IIO_CONST_ATTR_SAMP_FREQ_AVAIL(
345 "470 242 123 62 50 39 33 19 17 16 12 10 8 6 4");
346
347static ssize_t ad7793_show_scale_available(struct device *dev,
348 struct device_attribute *attr, char *buf)
349{
Lars-Peter Clausen62c51832012-05-12 15:39:42 +0200350 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200351 struct ad7793_state *st = iio_priv(indio_dev);
352 int i, len = 0;
353
354 for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++)
355 len += sprintf(buf + len, "%d.%09u ", st->scale_avail[i][0],
356 st->scale_avail[i][1]);
357
358 len += sprintf(buf + len, "\n");
359
360 return len;
361}
362
Lars-Peter Clausen08ca3b72012-08-10 17:36:00 +0100363static IIO_DEVICE_ATTR_NAMED(in_m_in_scale_available,
364 in_voltage-voltage_scale_available, S_IRUGO,
365 ad7793_show_scale_available, NULL, 0);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200366
367static struct attribute *ad7793_attributes[] = {
368 &iio_dev_attr_sampling_frequency.dev_attr.attr,
369 &iio_const_attr_sampling_frequency_available.dev_attr.attr,
370 &iio_dev_attr_in_m_in_scale_available.dev_attr.attr,
371 NULL
372};
373
374static const struct attribute_group ad7793_attribute_group = {
375 .attrs = ad7793_attributes,
376};
377
378static int ad7793_read_raw(struct iio_dev *indio_dev,
379 struct iio_chan_spec const *chan,
380 int *val,
381 int *val2,
382 long m)
383{
384 struct ad7793_state *st = iio_priv(indio_dev);
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100385 int ret;
Michael Hennerich88bc3052011-06-08 16:12:44 +0200386 unsigned long long scale_uv;
387 bool unipolar = !!(st->conf & AD7793_CONF_UNIPOLAR);
388
389 switch (m) {
Jonathan Cameronb11f98f2012-04-15 17:41:18 +0100390 case IIO_CHAN_INFO_RAW:
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100391 ret = ad_sigma_delta_single_conversion(indio_dev, chan, val);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200392 if (ret < 0)
393 return ret;
394
Michael Hennerich88bc3052011-06-08 16:12:44 +0200395 return IIO_VAL_INT;
396
Jonathan Cameronc8a9f802011-10-26 17:41:36 +0100397 case IIO_CHAN_INFO_SCALE:
Michael Hennerich88bc3052011-06-08 16:12:44 +0200398 switch (chan->type) {
Jonathan Cameron6835cb62011-09-27 09:56:41 +0100399 case IIO_VOLTAGE:
Jonathan Cameronc8a9f802011-10-26 17:41:36 +0100400 if (chan->differential) {
401 *val = st->
402 scale_avail[(st->conf >> 8) & 0x7][0];
403 *val2 = st->
404 scale_avail[(st->conf >> 8) & 0x7][1];
405 return IIO_VAL_INT_PLUS_NANO;
406 } else {
407 /* 1170mV / 2^23 * 6 */
Lars-Peter Clausen24b27fa2012-11-21 16:27:00 +0000408 scale_uv = (1170ULL * 1000000000ULL * 6ULL);
Jonathan Cameronc8a9f802011-10-26 17:41:36 +0100409 }
Michael Hennerich88bc3052011-06-08 16:12:44 +0200410 break;
411 case IIO_TEMP:
Lars-Peter Clausen2a9e0662012-08-10 17:36:00 +0100412 /* 1170mV / 0.81 mV/C / 2^23 */
Lars-Peter Clausene4ac7282012-11-21 16:27:00 +0000413 scale_uv = 1444444444444444ULL;
Michael Hennerich88bc3052011-06-08 16:12:44 +0200414 break;
415 default:
416 return -EINVAL;
417 }
418
Lars-Peter Clausen2a9e0662012-08-10 17:36:00 +0100419 scale_uv >>= (chan->scan_type.realbits - (unipolar ? 0 : 1));
420 *val = 0;
421 *val2 = scale_uv;
Michael Hennerich88bc3052011-06-08 16:12:44 +0200422 return IIO_VAL_INT_PLUS_NANO;
Lars-Peter Clausen680f8ea2012-08-10 17:36:00 +0100423 case IIO_CHAN_INFO_OFFSET:
424 if (!unipolar)
Lars-Peter Clausen2a9e0662012-08-10 17:36:00 +0100425 *val = -(1 << (chan->scan_type.realbits - 1));
Lars-Peter Clausen680f8ea2012-08-10 17:36:00 +0100426 else
427 *val = 0;
Lars-Peter Clausen2a9e0662012-08-10 17:36:00 +0100428
429 /* Kelvin to Celsius */
430 if (chan->type == IIO_TEMP) {
431 unsigned long long offset;
432 unsigned int shift;
433
434 shift = chan->scan_type.realbits - (unipolar ? 0 : 1);
435 offset = 273ULL << shift;
436 do_div(offset, 1444);
437 *val -= offset;
438 }
Lars-Peter Clausen680f8ea2012-08-10 17:36:00 +0100439 return IIO_VAL_INT;
Michael Hennerich88bc3052011-06-08 16:12:44 +0200440 }
441 return -EINVAL;
442}
443
444static int ad7793_write_raw(struct iio_dev *indio_dev,
445 struct iio_chan_spec const *chan,
446 int val,
447 int val2,
448 long mask)
449{
450 struct ad7793_state *st = iio_priv(indio_dev);
451 int ret, i;
452 unsigned int tmp;
453
454 mutex_lock(&indio_dev->mlock);
Jonathan Cameron14555b12011-09-21 11:15:57 +0100455 if (iio_buffer_enabled(indio_dev)) {
Michael Hennerich88bc3052011-06-08 16:12:44 +0200456 mutex_unlock(&indio_dev->mlock);
457 return -EBUSY;
458 }
459
460 switch (mask) {
Jonathan Cameronc8a9f802011-10-26 17:41:36 +0100461 case IIO_CHAN_INFO_SCALE:
Michael Hennerich88bc3052011-06-08 16:12:44 +0200462 ret = -EINVAL;
463 for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++)
464 if (val2 == st->scale_avail[i][1]) {
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100465 ret = 0;
Michael Hennerich88bc3052011-06-08 16:12:44 +0200466 tmp = st->conf;
467 st->conf &= ~AD7793_CONF_GAIN(-1);
468 st->conf |= AD7793_CONF_GAIN(i);
469
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100470 if (tmp == st->conf)
471 break;
472
473 ad_sd_write_reg(&st->sd, AD7793_REG_CONF,
474 sizeof(st->conf), st->conf);
475 ad7793_calibrate_all(st);
476 break;
Michael Hennerich88bc3052011-06-08 16:12:44 +0200477 }
Lars-Peter Clausen421afe52012-08-10 17:36:00 +0100478 break;
Michael Hennerich88bc3052011-06-08 16:12:44 +0200479 default:
480 ret = -EINVAL;
481 }
482
483 mutex_unlock(&indio_dev->mlock);
484 return ret;
485}
486
Michael Hennerich88bc3052011-06-08 16:12:44 +0200487static int ad7793_write_raw_get_fmt(struct iio_dev *indio_dev,
488 struct iio_chan_spec const *chan,
489 long mask)
490{
491 return IIO_VAL_INT_PLUS_NANO;
492}
493
494static const struct iio_info ad7793_info = {
495 .read_raw = &ad7793_read_raw,
496 .write_raw = &ad7793_write_raw,
497 .write_raw_get_fmt = &ad7793_write_raw_get_fmt,
498 .attrs = &ad7793_attribute_group,
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100499 .validate_trigger = ad_sd_validate_trigger,
Michael Hennerich88bc3052011-06-08 16:12:44 +0200500 .driver_module = THIS_MODULE,
501};
502
Lars-Peter Clausen8c29ecd2012-08-10 17:36:00 +0100503#define DECLARE_AD7793_CHANNELS(_name, _b, _sb, _s) \
Lars-Peter Clausen525e6432012-08-10 17:36:00 +0100504const struct iio_chan_spec _name##_channels[] = { \
Lars-Peter Clausen8c29ecd2012-08-10 17:36:00 +0100505 AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), (_s)), \
506 AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), (_s)), \
507 AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), (_s)), \
508 AD_SD_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), (_s)), \
509 AD_SD_TEMP_CHANNEL(4, AD7793_CH_TEMP, (_b), (_sb), (_s)), \
510 AD_SD_SUPPLY_CHANNEL(5, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), (_s)), \
Lars-Peter Clausen525e6432012-08-10 17:36:00 +0100511 IIO_CHAN_SOFT_TIMESTAMP(6), \
512}
513
514#define DECLARE_AD7795_CHANNELS(_name, _b, _sb) \
515const struct iio_chan_spec _name##_channels[] = { \
516 AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0), \
517 AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), 0), \
518 AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), 0), \
519 AD_SD_DIFF_CHANNEL(3, 3, 3, AD7795_CH_AIN4P_AIN4M, (_b), (_sb), 0), \
520 AD_SD_DIFF_CHANNEL(4, 4, 4, AD7795_CH_AIN5P_AIN5M, (_b), (_sb), 0), \
521 AD_SD_DIFF_CHANNEL(5, 5, 5, AD7795_CH_AIN6P_AIN6M, (_b), (_sb), 0), \
522 AD_SD_SHORTED_CHANNEL(6, 0, AD7795_CH_AIN1M_AIN1M, (_b), (_sb), 0), \
523 AD_SD_TEMP_CHANNEL(7, AD7793_CH_TEMP, (_b), (_sb), 0), \
524 AD_SD_SUPPLY_CHANNEL(8, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0), \
525 IIO_CHAN_SOFT_TIMESTAMP(9), \
526}
527
Lars-Peter Clausen8c29ecd2012-08-10 17:36:00 +0100528static DECLARE_AD7793_CHANNELS(ad7785, 20, 32, 4);
529static DECLARE_AD7793_CHANNELS(ad7792, 16, 32, 0);
530static DECLARE_AD7793_CHANNELS(ad7793, 24, 32, 0);
Lars-Peter Clausen525e6432012-08-10 17:36:00 +0100531static DECLARE_AD7795_CHANNELS(ad7794, 16, 32);
532static DECLARE_AD7795_CHANNELS(ad7795, 24, 32);
533
Michael Hennerich88bc3052011-06-08 16:12:44 +0200534static const struct ad7793_chip_info ad7793_chip_info_tbl[] = {
Lars-Peter Clausen8c29ecd2012-08-10 17:36:00 +0100535 [ID_AD7785] = {
Lars-Peter Clausene786cc22012-11-21 16:27:00 +0000536 .id = AD7785_ID,
Lars-Peter Clausen8c29ecd2012-08-10 17:36:00 +0100537 .channels = ad7785_channels,
538 .num_channels = ARRAY_SIZE(ad7785_channels),
539 },
Michael Hennerich88bc3052011-06-08 16:12:44 +0200540 [ID_AD7792] = {
Lars-Peter Clausene786cc22012-11-21 16:27:00 +0000541 .id = AD7792_ID,
Lars-Peter Clausen525e6432012-08-10 17:36:00 +0100542 .channels = ad7792_channels,
543 .num_channels = ARRAY_SIZE(ad7792_channels),
544 },
545 [ID_AD7793] = {
Lars-Peter Clausene786cc22012-11-21 16:27:00 +0000546 .id = AD7793_ID,
Lars-Peter Clausen525e6432012-08-10 17:36:00 +0100547 .channels = ad7793_channels,
548 .num_channels = ARRAY_SIZE(ad7793_channels),
549 },
550 [ID_AD7794] = {
Lars-Peter Clausene786cc22012-11-21 16:27:00 +0000551 .id = AD7794_ID,
Lars-Peter Clausen525e6432012-08-10 17:36:00 +0100552 .channels = ad7794_channels,
553 .num_channels = ARRAY_SIZE(ad7794_channels),
554 },
555 [ID_AD7795] = {
Lars-Peter Clausene786cc22012-11-21 16:27:00 +0000556 .id = AD7795_ID,
Lars-Peter Clausen525e6432012-08-10 17:36:00 +0100557 .channels = ad7795_channels,
558 .num_channels = ARRAY_SIZE(ad7795_channels),
Michael Hennerich88bc3052011-06-08 16:12:44 +0200559 },
560};
561
Bill Pemberton4ae1c61f2012-11-19 13:21:57 -0500562static int ad7793_probe(struct spi_device *spi)
Michael Hennerich88bc3052011-06-08 16:12:44 +0200563{
Lars-Peter Clausenc8c194d2012-08-10 17:36:00 +0100564 const struct ad7793_platform_data *pdata = spi->dev.platform_data;
Michael Hennerich88bc3052011-06-08 16:12:44 +0200565 struct ad7793_state *st;
566 struct iio_dev *indio_dev;
Lars-Peter Clausendd2c1012012-11-21 16:27:00 +0000567 int ret, vref_mv = 0;
Michael Hennerich88bc3052011-06-08 16:12:44 +0200568
569 if (!pdata) {
570 dev_err(&spi->dev, "no platform data?\n");
571 return -ENODEV;
572 }
573
574 if (!spi->irq) {
575 dev_err(&spi->dev, "no IRQ?\n");
576 return -ENODEV;
577 }
578
Lars-Peter Clausen7cbb7532012-04-26 13:35:01 +0200579 indio_dev = iio_device_alloc(sizeof(*st));
Michael Hennerich88bc3052011-06-08 16:12:44 +0200580 if (indio_dev == NULL)
581 return -ENOMEM;
582
583 st = iio_priv(indio_dev);
584
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100585 ad_sd_init(&st->sd, indio_dev, spi, &ad7793_sigma_delta_info);
586
Lars-Peter Clausendd2c1012012-11-21 16:27:00 +0000587 if (pdata->refsel != AD7793_REFSEL_INTERNAL) {
588 st->reg = regulator_get(&spi->dev, "refin");
589 if (IS_ERR(st->reg)) {
590 ret = PTR_ERR(st->reg);
591 goto error_device_free;
592 }
593
Michael Hennerich88bc3052011-06-08 16:12:44 +0200594 ret = regulator_enable(st->reg);
595 if (ret)
596 goto error_put_reg;
597
Lars-Peter Clausendd2c1012012-11-21 16:27:00 +0000598 vref_mv = regulator_get_voltage(st->reg);
599 if (vref_mv < 0) {
600 ret = vref_mv;
601 goto error_disable_reg;
602 }
603
604 vref_mv /= 1000;
605 } else {
606 vref_mv = 1170; /* Build-in ref */
Michael Hennerich88bc3052011-06-08 16:12:44 +0200607 }
608
609 st->chip_info =
610 &ad7793_chip_info_tbl[spi_get_device_id(spi)->driver_data];
611
Michael Hennerich88bc3052011-06-08 16:12:44 +0200612 spi_set_drvdata(spi, indio_dev);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200613
614 indio_dev->dev.parent = &spi->dev;
615 indio_dev->name = spi_get_device_id(spi)->name;
616 indio_dev->modes = INDIO_DIRECT_MODE;
Lars-Peter Clausen525e6432012-08-10 17:36:00 +0100617 indio_dev->channels = st->chip_info->channels;
618 indio_dev->num_channels = st->chip_info->num_channels;
Michael Hennerich88bc3052011-06-08 16:12:44 +0200619 indio_dev->info = &ad7793_info;
620
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100621 ret = ad_sd_setup_buffer_and_trigger(indio_dev);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200622 if (ret)
623 goto error_disable_reg;
624
Lars-Peter Clausendd2c1012012-11-21 16:27:00 +0000625 ret = ad7793_setup(indio_dev, pdata, vref_mv);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200626 if (ret)
627 goto error_remove_trigger;
628
Jonathan Cameron26d25ae2011-09-02 17:14:40 +0100629 ret = iio_device_register(indio_dev);
630 if (ret)
Lars-Peter Clausen82796ed2012-06-18 18:33:54 +0200631 goto error_remove_trigger;
Jonathan Cameron26d25ae2011-09-02 17:14:40 +0100632
Michael Hennerich88bc3052011-06-08 16:12:44 +0200633 return 0;
634
Michael Hennerich88bc3052011-06-08 16:12:44 +0200635error_remove_trigger:
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100636 ad_sd_cleanup_buffer_and_trigger(indio_dev);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200637error_disable_reg:
Lars-Peter Clausendd2c1012012-11-21 16:27:00 +0000638 if (pdata->refsel != AD7793_REFSEL_INTERNAL)
Michael Hennerich88bc3052011-06-08 16:12:44 +0200639 regulator_disable(st->reg);
640error_put_reg:
Lars-Peter Clausendd2c1012012-11-21 16:27:00 +0000641 if (pdata->refsel != AD7793_REFSEL_INTERNAL)
Michael Hennerich88bc3052011-06-08 16:12:44 +0200642 regulator_put(st->reg);
Lars-Peter Clausendd2c1012012-11-21 16:27:00 +0000643error_device_free:
Lars-Peter Clausen7cbb7532012-04-26 13:35:01 +0200644 iio_device_free(indio_dev);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200645
646 return ret;
647}
648
Bill Pemberton447d4f22012-11-19 13:26:37 -0500649static int ad7793_remove(struct spi_device *spi)
Michael Hennerich88bc3052011-06-08 16:12:44 +0200650{
Lars-Peter Clausendd2c1012012-11-21 16:27:00 +0000651 const struct ad7793_platform_data *pdata = spi->dev.platform_data;
Michael Hennerich88bc3052011-06-08 16:12:44 +0200652 struct iio_dev *indio_dev = spi_get_drvdata(spi);
653 struct ad7793_state *st = iio_priv(indio_dev);
654
Jonathan Camerond2fffd62011-10-14 14:46:58 +0100655 iio_device_unregister(indio_dev);
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100656 ad_sd_cleanup_buffer_and_trigger(indio_dev);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200657
Lars-Peter Clausendd2c1012012-11-21 16:27:00 +0000658 if (pdata->refsel != AD7793_REFSEL_INTERNAL) {
Michael Hennerich88bc3052011-06-08 16:12:44 +0200659 regulator_disable(st->reg);
660 regulator_put(st->reg);
661 }
662
Lars-Peter Clausen7cbb7532012-04-26 13:35:01 +0200663 iio_device_free(indio_dev);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200664
665 return 0;
666}
667
668static const struct spi_device_id ad7793_id[] = {
Lars-Peter Clausen8c29ecd2012-08-10 17:36:00 +0100669 {"ad7785", ID_AD7785},
Michael Hennerich88bc3052011-06-08 16:12:44 +0200670 {"ad7792", ID_AD7792},
671 {"ad7793", ID_AD7793},
Lars-Peter Clausen525e6432012-08-10 17:36:00 +0100672 {"ad7794", ID_AD7794},
673 {"ad7795", ID_AD7795},
Michael Hennerich88bc3052011-06-08 16:12:44 +0200674 {}
675};
Lars-Peter Clausen55e43902011-11-16 08:53:31 +0100676MODULE_DEVICE_TABLE(spi, ad7793_id);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200677
678static struct spi_driver ad7793_driver = {
679 .driver = {
680 .name = "ad7793",
Michael Hennerich88bc3052011-06-08 16:12:44 +0200681 .owner = THIS_MODULE,
682 },
683 .probe = ad7793_probe,
Bill Pembertone543acf2012-11-19 13:21:38 -0500684 .remove = ad7793_remove,
Michael Hennerich88bc3052011-06-08 16:12:44 +0200685 .id_table = ad7793_id,
686};
Lars-Peter Clausenae6ae6f2011-11-16 10:13:39 +0100687module_spi_driver(ad7793_driver);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200688
689MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
Lars-Peter Clausen525e6432012-08-10 17:36:00 +0100690MODULE_DESCRIPTION("Analog Devices AD7793 and simialr ADCs");
Michael Hennerich88bc3052011-06-08 16:12:44 +0200691MODULE_LICENSE("GPL v2");