blob: 91a5f7aa1ef1c1f80112eacc50cd6cd7ddeeefdb [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
Lars-Peter Clausen2edb7692012-11-21 16:27:00 +0000109#define AD7798_ID 0x8
110#define AD7799_ID 0x9
Lars-Peter Clausen891c8bc2012-11-21 16:27:00 +0000111#define AD7793_ID_MASK 0xF
112
113/* IO (Excitation Current Sources) Register Bit Designations (AD7793_REG_IO) */
114#define AD7793_IO_IEXC1_IOUT1_IEXC2_IOUT2 0 /* IEXC1 connect to IOUT1,
115 * IEXC2 connect to IOUT2 */
116#define AD7793_IO_IEXC1_IOUT2_IEXC2_IOUT1 1 /* IEXC1 connect to IOUT2,
117 * IEXC2 connect to IOUT1 */
118#define AD7793_IO_IEXC1_IEXC2_IOUT1 2 /* Both current sources
119 * IEXC1,2 connect to IOUT1 */
120#define AD7793_IO_IEXC1_IEXC2_IOUT2 3 /* Both current sources
121 * IEXC1,2 connect to IOUT2 */
122
123#define AD7793_IO_IXCEN_10uA (1 << 0) /* Excitation Current 10uA */
124#define AD7793_IO_IXCEN_210uA (2 << 0) /* Excitation Current 210uA */
125#define AD7793_IO_IXCEN_1mA (3 << 0) /* Excitation Current 1mA */
126
Michael Hennerich88bc3052011-06-08 16:12:44 +0200127/* NOTE:
128 * The AD7792/AD7793 features a dual use data out ready DOUT/RDY output.
129 * In order to avoid contentions on the SPI bus, it's therefore necessary
130 * to use spi bus locking.
131 *
132 * The DOUT/RDY output must also be wired to an interrupt capable GPIO.
133 */
134
Lars-Peter Clausen2edb7692012-11-21 16:27:00 +0000135#define AD7793_FLAG_HAS_CLKSEL BIT(0)
136#define AD7793_FLAG_HAS_REFSEL BIT(1)
137#define AD7793_FLAG_HAS_VBIAS BIT(2)
138#define AD7793_HAS_EXITATION_CURRENT BIT(3)
139
Michael Hennerich88bc3052011-06-08 16:12:44 +0200140struct ad7793_chip_info {
Lars-Peter Clausene786cc22012-11-21 16:27:00 +0000141 unsigned int id;
Lars-Peter Clausen525e6432012-08-10 17:36:00 +0100142 const struct iio_chan_spec *channels;
143 unsigned int num_channels;
Lars-Peter Clausen2edb7692012-11-21 16:27:00 +0000144 unsigned int flags;
Michael Hennerich88bc3052011-06-08 16:12:44 +0200145};
146
147struct ad7793_state {
Michael Hennerich88bc3052011-06-08 16:12:44 +0200148 const struct ad7793_chip_info *chip_info;
149 struct regulator *reg;
Michael Hennerich88bc3052011-06-08 16:12:44 +0200150 u16 int_vref_mv;
151 u16 mode;
152 u16 conf;
153 u32 scale_avail[8][2];
Lars-Peter Clausen8c2c6ba2012-07-09 10:00:00 +0100154
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100155 struct ad_sigma_delta sd;
156
Michael Hennerich88bc3052011-06-08 16:12:44 +0200157};
158
159enum ad7793_supported_device_ids {
Lars-Peter Clausen8c29ecd2012-08-10 17:36:00 +0100160 ID_AD7785,
Michael Hennerich88bc3052011-06-08 16:12:44 +0200161 ID_AD7792,
162 ID_AD7793,
Lars-Peter Clausen525e6432012-08-10 17:36:00 +0100163 ID_AD7794,
164 ID_AD7795,
Lars-Peter Clausen2edb7692012-11-21 16:27:00 +0000165 ID_AD7798,
166 ID_AD7799,
Michael Hennerich88bc3052011-06-08 16:12:44 +0200167};
168
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100169static struct ad7793_state *ad_sigma_delta_to_ad7793(struct ad_sigma_delta *sd)
Michael Hennerich88bc3052011-06-08 16:12:44 +0200170{
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100171 return container_of(sd, struct ad7793_state, sd);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200172}
173
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100174static int ad7793_set_channel(struct ad_sigma_delta *sd, unsigned int channel)
Michael Hennerich88bc3052011-06-08 16:12:44 +0200175{
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100176 struct ad7793_state *st = ad_sigma_delta_to_ad7793(sd);
177
178 st->conf &= ~AD7793_CONF_CHAN_MASK;
179 st->conf |= AD7793_CONF_CHAN(channel);
180
181 return ad_sd_write_reg(&st->sd, AD7793_REG_CONF, 2, st->conf);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200182}
183
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100184static int ad7793_set_mode(struct ad_sigma_delta *sd,
185 enum ad_sigma_delta_mode mode)
Michael Hennerich88bc3052011-06-08 16:12:44 +0200186{
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100187 struct ad7793_state *st = ad_sigma_delta_to_ad7793(sd);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200188
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100189 st->mode &= ~AD7793_MODE_SEL_MASK;
190 st->mode |= AD7793_MODE_SEL(mode);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200191
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100192 return ad_sd_write_reg(&st->sd, AD7793_REG_MODE, 2, st->mode);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200193}
194
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100195static const struct ad_sigma_delta_info ad7793_sigma_delta_info = {
196 .set_channel = ad7793_set_channel,
197 .set_mode = ad7793_set_mode,
198 .has_registers = true,
199 .addr_shift = 3,
200 .read_mask = BIT(6),
201};
Michael Hennerich88bc3052011-06-08 16:12:44 +0200202
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100203static const struct ad_sd_calib_data ad7793_calib_arr[6] = {
Michael Hennerich88bc3052011-06-08 16:12:44 +0200204 {AD7793_MODE_CAL_INT_ZERO, AD7793_CH_AIN1P_AIN1M},
205 {AD7793_MODE_CAL_INT_FULL, AD7793_CH_AIN1P_AIN1M},
206 {AD7793_MODE_CAL_INT_ZERO, AD7793_CH_AIN2P_AIN2M},
207 {AD7793_MODE_CAL_INT_FULL, AD7793_CH_AIN2P_AIN2M},
208 {AD7793_MODE_CAL_INT_ZERO, AD7793_CH_AIN3P_AIN3M},
209 {AD7793_MODE_CAL_INT_FULL, AD7793_CH_AIN3P_AIN3M}
210};
211
212static int ad7793_calibrate_all(struct ad7793_state *st)
213{
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100214 return ad_sd_calibrate_all(&st->sd, ad7793_calib_arr,
215 ARRAY_SIZE(ad7793_calib_arr));
Michael Hennerich88bc3052011-06-08 16:12:44 +0200216}
217
Lars-Peter Clausen2edb7692012-11-21 16:27:00 +0000218static int ad7793_check_platform_data(struct ad7793_state *st,
219 const struct ad7793_platform_data *pdata)
220{
221 if ((pdata->current_source_direction == AD7793_IEXEC1_IEXEC2_IOUT1 ||
222 pdata->current_source_direction == AD7793_IEXEC1_IEXEC2_IOUT2) &&
223 ((pdata->exitation_current != AD7793_IX_10uA) &&
224 (pdata->exitation_current != AD7793_IX_210uA)))
225 return -EINVAL;
226
227 if (!(st->chip_info->flags & AD7793_FLAG_HAS_CLKSEL) &&
228 pdata->clock_src != AD7793_CLK_SRC_INT)
229 return -EINVAL;
230
231 if (!(st->chip_info->flags & AD7793_FLAG_HAS_REFSEL) &&
232 pdata->refsel != AD7793_REFSEL_REFIN1)
233 return -EINVAL;
234
235 if (!(st->chip_info->flags & AD7793_FLAG_HAS_VBIAS) &&
236 pdata->bias_voltage != AD7793_BIAS_VOLTAGE_DISABLED)
237 return -EINVAL;
238
239 if (!(st->chip_info->flags & AD7793_HAS_EXITATION_CURRENT) &&
240 pdata->exitation_current != AD7793_IX_DISABLED)
241 return -EINVAL;
242
243 return 0;
244}
245
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100246static int ad7793_setup(struct iio_dev *indio_dev,
Lars-Peter Clausendd2c1012012-11-21 16:27:00 +0000247 const struct ad7793_platform_data *pdata,
248 unsigned int vref_mv)
Michael Hennerich88bc3052011-06-08 16:12:44 +0200249{
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100250 struct ad7793_state *st = iio_priv(indio_dev);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200251 int i, ret = -1;
252 unsigned long long scale_uv;
253 u32 id;
254
Lars-Peter Clausen2edb7692012-11-21 16:27:00 +0000255 ret = ad7793_check_platform_data(st, pdata);
256 if (ret)
257 return ret;
Lars-Peter Clausend21f30c2012-11-21 16:27:00 +0000258
Michael Hennerich88bc3052011-06-08 16:12:44 +0200259 /* reset the serial interface */
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100260 ret = spi_write(st->sd.spi, (u8 *)&ret, sizeof(ret));
Michael Hennerich88bc3052011-06-08 16:12:44 +0200261 if (ret < 0)
262 goto out;
Lars-Peter Clausen3e4334f2012-11-21 16:27:00 +0000263 usleep_range(500, 2000); /* Wait for at least 500us */
Michael Hennerich88bc3052011-06-08 16:12:44 +0200264
265 /* write/read test for device presence */
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100266 ret = ad_sd_read_reg(&st->sd, AD7793_REG_ID, 1, &id);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200267 if (ret)
268 goto out;
269
270 id &= AD7793_ID_MASK;
271
Lars-Peter Clausene786cc22012-11-21 16:27:00 +0000272 if (id != st->chip_info->id) {
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100273 dev_err(&st->sd.spi->dev, "device ID query failed\n");
Michael Hennerich88bc3052011-06-08 16:12:44 +0200274 goto out;
275 }
276
Lars-Peter Clausend21f30c2012-11-21 16:27:00 +0000277 st->mode = AD7793_MODE_RATE(1);
Lars-Peter Clausen2edb7692012-11-21 16:27:00 +0000278 st->conf = 0;
279
280 if (st->chip_info->flags & AD7793_FLAG_HAS_CLKSEL)
281 st->mode |= AD7793_MODE_CLKSRC(pdata->clock_src);
282 if (st->chip_info->flags & AD7793_FLAG_HAS_REFSEL)
283 st->conf |= AD7793_CONF_REFSEL(pdata->refsel);
284 if (st->chip_info->flags & AD7793_FLAG_HAS_VBIAS)
285 st->conf |= AD7793_CONF_VBIAS(pdata->bias_voltage);
Lars-Peter Clausend21f30c2012-11-21 16:27:00 +0000286 if (pdata->buffered)
287 st->conf |= AD7793_CONF_BUF;
Lars-Peter Clausen2edb7692012-11-21 16:27:00 +0000288 if (pdata->boost_enable &&
289 (st->chip_info->flags & AD7793_FLAG_HAS_VBIAS))
Lars-Peter Clausend21f30c2012-11-21 16:27:00 +0000290 st->conf |= AD7793_CONF_BOOST;
291 if (pdata->burnout_current)
292 st->conf |= AD7793_CONF_BO_EN;
293 if (pdata->unipolar)
294 st->conf |= AD7793_CONF_UNIPOLAR;
Michael Hennerich88bc3052011-06-08 16:12:44 +0200295
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100296 ret = ad7793_set_mode(&st->sd, AD_SD_MODE_IDLE);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200297 if (ret)
298 goto out;
299
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100300 ret = ad7793_set_channel(&st->sd, 0);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200301 if (ret)
302 goto out;
303
Lars-Peter Clausen2edb7692012-11-21 16:27:00 +0000304 if (st->chip_info->flags & AD7793_HAS_EXITATION_CURRENT) {
305 ret = ad_sd_write_reg(&st->sd, AD7793_REG_IO, 1,
306 pdata->exitation_current |
307 (pdata->current_source_direction << 2));
308 if (ret)
309 goto out;
310 }
Michael Hennerich88bc3052011-06-08 16:12:44 +0200311
312 ret = ad7793_calibrate_all(st);
313 if (ret)
314 goto out;
315
316 /* Populate available ADC input ranges */
317 for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++) {
Lars-Peter Clausendd2c1012012-11-21 16:27:00 +0000318 scale_uv = ((u64)vref_mv * 100000000)
Lars-Peter Clausen525e6432012-08-10 17:36:00 +0100319 >> (st->chip_info->channels[0].scan_type.realbits -
Michael Hennerich88bc3052011-06-08 16:12:44 +0200320 (!!(st->conf & AD7793_CONF_UNIPOLAR) ? 0 : 1));
321 scale_uv >>= i;
322
323 st->scale_avail[i][1] = do_div(scale_uv, 100000000) * 10;
324 st->scale_avail[i][0] = scale_uv;
325 }
326
327 return 0;
328out:
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100329 dev_err(&st->sd.spi->dev, "setup failed\n");
Michael Hennerich88bc3052011-06-08 16:12:44 +0200330 return ret;
331}
332
Michael Hennerich88bc3052011-06-08 16:12:44 +0200333static const u16 sample_freq_avail[16] = {0, 470, 242, 123, 62, 50, 39, 33, 19,
334 17, 16, 12, 10, 8, 6, 4};
335
336static ssize_t ad7793_read_frequency(struct device *dev,
337 struct device_attribute *attr,
338 char *buf)
339{
Lars-Peter Clausen62c51832012-05-12 15:39:42 +0200340 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200341 struct ad7793_state *st = iio_priv(indio_dev);
342
343 return sprintf(buf, "%d\n",
344 sample_freq_avail[AD7793_MODE_RATE(st->mode)]);
345}
346
347static ssize_t ad7793_write_frequency(struct device *dev,
348 struct device_attribute *attr,
349 const char *buf,
350 size_t len)
351{
Lars-Peter Clausen62c51832012-05-12 15:39:42 +0200352 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200353 struct ad7793_state *st = iio_priv(indio_dev);
354 long lval;
355 int i, ret;
356
357 mutex_lock(&indio_dev->mlock);
Jonathan Cameron14555b12011-09-21 11:15:57 +0100358 if (iio_buffer_enabled(indio_dev)) {
Michael Hennerich88bc3052011-06-08 16:12:44 +0200359 mutex_unlock(&indio_dev->mlock);
360 return -EBUSY;
361 }
362 mutex_unlock(&indio_dev->mlock);
363
Lars-Peter Clausenfe2e0d52012-11-21 16:27:00 +0000364 ret = kstrtol(buf, 10, &lval);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200365 if (ret)
366 return ret;
367
368 ret = -EINVAL;
369
370 for (i = 0; i < ARRAY_SIZE(sample_freq_avail); i++)
371 if (lval == sample_freq_avail[i]) {
372 mutex_lock(&indio_dev->mlock);
373 st->mode &= ~AD7793_MODE_RATE(-1);
374 st->mode |= AD7793_MODE_RATE(i);
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100375 ad_sd_write_reg(&st->sd, AD7793_REG_MODE,
Michael Hennerich88bc3052011-06-08 16:12:44 +0200376 sizeof(st->mode), st->mode);
377 mutex_unlock(&indio_dev->mlock);
378 ret = 0;
379 }
380
381 return ret ? ret : len;
382}
383
384static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
385 ad7793_read_frequency,
386 ad7793_write_frequency);
387
388static IIO_CONST_ATTR_SAMP_FREQ_AVAIL(
389 "470 242 123 62 50 39 33 19 17 16 12 10 8 6 4");
390
391static ssize_t ad7793_show_scale_available(struct device *dev,
392 struct device_attribute *attr, char *buf)
393{
Lars-Peter Clausen62c51832012-05-12 15:39:42 +0200394 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200395 struct ad7793_state *st = iio_priv(indio_dev);
396 int i, len = 0;
397
398 for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++)
399 len += sprintf(buf + len, "%d.%09u ", st->scale_avail[i][0],
400 st->scale_avail[i][1]);
401
402 len += sprintf(buf + len, "\n");
403
404 return len;
405}
406
Lars-Peter Clausen08ca3b72012-08-10 17:36:00 +0100407static IIO_DEVICE_ATTR_NAMED(in_m_in_scale_available,
408 in_voltage-voltage_scale_available, S_IRUGO,
409 ad7793_show_scale_available, NULL, 0);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200410
411static struct attribute *ad7793_attributes[] = {
412 &iio_dev_attr_sampling_frequency.dev_attr.attr,
413 &iio_const_attr_sampling_frequency_available.dev_attr.attr,
414 &iio_dev_attr_in_m_in_scale_available.dev_attr.attr,
415 NULL
416};
417
418static const struct attribute_group ad7793_attribute_group = {
419 .attrs = ad7793_attributes,
420};
421
422static int ad7793_read_raw(struct iio_dev *indio_dev,
423 struct iio_chan_spec const *chan,
424 int *val,
425 int *val2,
426 long m)
427{
428 struct ad7793_state *st = iio_priv(indio_dev);
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100429 int ret;
Michael Hennerich88bc3052011-06-08 16:12:44 +0200430 unsigned long long scale_uv;
431 bool unipolar = !!(st->conf & AD7793_CONF_UNIPOLAR);
432
433 switch (m) {
Jonathan Cameronb11f98f2012-04-15 17:41:18 +0100434 case IIO_CHAN_INFO_RAW:
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100435 ret = ad_sigma_delta_single_conversion(indio_dev, chan, val);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200436 if (ret < 0)
437 return ret;
438
Michael Hennerich88bc3052011-06-08 16:12:44 +0200439 return IIO_VAL_INT;
440
Jonathan Cameronc8a9f802011-10-26 17:41:36 +0100441 case IIO_CHAN_INFO_SCALE:
Michael Hennerich88bc3052011-06-08 16:12:44 +0200442 switch (chan->type) {
Jonathan Cameron6835cb62011-09-27 09:56:41 +0100443 case IIO_VOLTAGE:
Jonathan Cameronc8a9f802011-10-26 17:41:36 +0100444 if (chan->differential) {
445 *val = st->
446 scale_avail[(st->conf >> 8) & 0x7][0];
447 *val2 = st->
448 scale_avail[(st->conf >> 8) & 0x7][1];
449 return IIO_VAL_INT_PLUS_NANO;
450 } else {
451 /* 1170mV / 2^23 * 6 */
Lars-Peter Clausen24b27fa2012-11-21 16:27:00 +0000452 scale_uv = (1170ULL * 1000000000ULL * 6ULL);
Jonathan Cameronc8a9f802011-10-26 17:41:36 +0100453 }
Michael Hennerich88bc3052011-06-08 16:12:44 +0200454 break;
455 case IIO_TEMP:
Lars-Peter Clausen2a9e0662012-08-10 17:36:00 +0100456 /* 1170mV / 0.81 mV/C / 2^23 */
Lars-Peter Clausene4ac7282012-11-21 16:27:00 +0000457 scale_uv = 1444444444444444ULL;
Michael Hennerich88bc3052011-06-08 16:12:44 +0200458 break;
459 default:
460 return -EINVAL;
461 }
462
Lars-Peter Clausen2a9e0662012-08-10 17:36:00 +0100463 scale_uv >>= (chan->scan_type.realbits - (unipolar ? 0 : 1));
464 *val = 0;
465 *val2 = scale_uv;
Michael Hennerich88bc3052011-06-08 16:12:44 +0200466 return IIO_VAL_INT_PLUS_NANO;
Lars-Peter Clausen680f8ea2012-08-10 17:36:00 +0100467 case IIO_CHAN_INFO_OFFSET:
468 if (!unipolar)
Lars-Peter Clausen2a9e0662012-08-10 17:36:00 +0100469 *val = -(1 << (chan->scan_type.realbits - 1));
Lars-Peter Clausen680f8ea2012-08-10 17:36:00 +0100470 else
471 *val = 0;
Lars-Peter Clausen2a9e0662012-08-10 17:36:00 +0100472
473 /* Kelvin to Celsius */
474 if (chan->type == IIO_TEMP) {
475 unsigned long long offset;
476 unsigned int shift;
477
478 shift = chan->scan_type.realbits - (unipolar ? 0 : 1);
479 offset = 273ULL << shift;
480 do_div(offset, 1444);
481 *val -= offset;
482 }
Lars-Peter Clausen680f8ea2012-08-10 17:36:00 +0100483 return IIO_VAL_INT;
Michael Hennerich88bc3052011-06-08 16:12:44 +0200484 }
485 return -EINVAL;
486}
487
488static int ad7793_write_raw(struct iio_dev *indio_dev,
489 struct iio_chan_spec const *chan,
490 int val,
491 int val2,
492 long mask)
493{
494 struct ad7793_state *st = iio_priv(indio_dev);
495 int ret, i;
496 unsigned int tmp;
497
498 mutex_lock(&indio_dev->mlock);
Jonathan Cameron14555b12011-09-21 11:15:57 +0100499 if (iio_buffer_enabled(indio_dev)) {
Michael Hennerich88bc3052011-06-08 16:12:44 +0200500 mutex_unlock(&indio_dev->mlock);
501 return -EBUSY;
502 }
503
504 switch (mask) {
Jonathan Cameronc8a9f802011-10-26 17:41:36 +0100505 case IIO_CHAN_INFO_SCALE:
Michael Hennerich88bc3052011-06-08 16:12:44 +0200506 ret = -EINVAL;
507 for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++)
508 if (val2 == st->scale_avail[i][1]) {
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100509 ret = 0;
Michael Hennerich88bc3052011-06-08 16:12:44 +0200510 tmp = st->conf;
511 st->conf &= ~AD7793_CONF_GAIN(-1);
512 st->conf |= AD7793_CONF_GAIN(i);
513
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100514 if (tmp == st->conf)
515 break;
516
517 ad_sd_write_reg(&st->sd, AD7793_REG_CONF,
518 sizeof(st->conf), st->conf);
519 ad7793_calibrate_all(st);
520 break;
Michael Hennerich88bc3052011-06-08 16:12:44 +0200521 }
Lars-Peter Clausen421afe52012-08-10 17:36:00 +0100522 break;
Michael Hennerich88bc3052011-06-08 16:12:44 +0200523 default:
524 ret = -EINVAL;
525 }
526
527 mutex_unlock(&indio_dev->mlock);
528 return ret;
529}
530
Michael Hennerich88bc3052011-06-08 16:12:44 +0200531static int ad7793_write_raw_get_fmt(struct iio_dev *indio_dev,
532 struct iio_chan_spec const *chan,
533 long mask)
534{
535 return IIO_VAL_INT_PLUS_NANO;
536}
537
538static const struct iio_info ad7793_info = {
539 .read_raw = &ad7793_read_raw,
540 .write_raw = &ad7793_write_raw,
541 .write_raw_get_fmt = &ad7793_write_raw_get_fmt,
542 .attrs = &ad7793_attribute_group,
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100543 .validate_trigger = ad_sd_validate_trigger,
Michael Hennerich88bc3052011-06-08 16:12:44 +0200544 .driver_module = THIS_MODULE,
545};
546
Lars-Peter Clausen8c29ecd2012-08-10 17:36:00 +0100547#define DECLARE_AD7793_CHANNELS(_name, _b, _sb, _s) \
Lars-Peter Clausen525e6432012-08-10 17:36:00 +0100548const struct iio_chan_spec _name##_channels[] = { \
Lars-Peter Clausen8c29ecd2012-08-10 17:36:00 +0100549 AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), (_s)), \
550 AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), (_s)), \
551 AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), (_s)), \
552 AD_SD_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), (_s)), \
553 AD_SD_TEMP_CHANNEL(4, AD7793_CH_TEMP, (_b), (_sb), (_s)), \
554 AD_SD_SUPPLY_CHANNEL(5, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), (_s)), \
Lars-Peter Clausen525e6432012-08-10 17:36:00 +0100555 IIO_CHAN_SOFT_TIMESTAMP(6), \
556}
557
558#define DECLARE_AD7795_CHANNELS(_name, _b, _sb) \
559const struct iio_chan_spec _name##_channels[] = { \
560 AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0), \
561 AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), 0), \
562 AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), 0), \
563 AD_SD_DIFF_CHANNEL(3, 3, 3, AD7795_CH_AIN4P_AIN4M, (_b), (_sb), 0), \
564 AD_SD_DIFF_CHANNEL(4, 4, 4, AD7795_CH_AIN5P_AIN5M, (_b), (_sb), 0), \
565 AD_SD_DIFF_CHANNEL(5, 5, 5, AD7795_CH_AIN6P_AIN6M, (_b), (_sb), 0), \
566 AD_SD_SHORTED_CHANNEL(6, 0, AD7795_CH_AIN1M_AIN1M, (_b), (_sb), 0), \
567 AD_SD_TEMP_CHANNEL(7, AD7793_CH_TEMP, (_b), (_sb), 0), \
568 AD_SD_SUPPLY_CHANNEL(8, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0), \
569 IIO_CHAN_SOFT_TIMESTAMP(9), \
570}
571
Lars-Peter Clausen2edb7692012-11-21 16:27:00 +0000572#define DECLARE_AD7799_CHANNELS(_name, _b, _sb) \
573const struct iio_chan_spec _name##_channels[] = { \
574 AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0), \
575 AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), 0), \
576 AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), 0), \
577 AD_SD_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), 0), \
578 AD_SD_SUPPLY_CHANNEL(4, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0), \
579 IIO_CHAN_SOFT_TIMESTAMP(5), \
580}
581
Lars-Peter Clausen8c29ecd2012-08-10 17:36:00 +0100582static DECLARE_AD7793_CHANNELS(ad7785, 20, 32, 4);
583static DECLARE_AD7793_CHANNELS(ad7792, 16, 32, 0);
584static DECLARE_AD7793_CHANNELS(ad7793, 24, 32, 0);
Lars-Peter Clausen525e6432012-08-10 17:36:00 +0100585static DECLARE_AD7795_CHANNELS(ad7794, 16, 32);
586static DECLARE_AD7795_CHANNELS(ad7795, 24, 32);
Lars-Peter Clausen2edb7692012-11-21 16:27:00 +0000587static DECLARE_AD7799_CHANNELS(ad7798, 16, 16);
588static DECLARE_AD7799_CHANNELS(ad7799, 24, 32);
Lars-Peter Clausen525e6432012-08-10 17:36:00 +0100589
Michael Hennerich88bc3052011-06-08 16:12:44 +0200590static const struct ad7793_chip_info ad7793_chip_info_tbl[] = {
Lars-Peter Clausen8c29ecd2012-08-10 17:36:00 +0100591 [ID_AD7785] = {
Lars-Peter Clausene786cc22012-11-21 16:27:00 +0000592 .id = AD7785_ID,
Lars-Peter Clausen8c29ecd2012-08-10 17:36:00 +0100593 .channels = ad7785_channels,
594 .num_channels = ARRAY_SIZE(ad7785_channels),
Lars-Peter Clausen2edb7692012-11-21 16:27:00 +0000595 .flags = AD7793_FLAG_HAS_CLKSEL |
596 AD7793_FLAG_HAS_REFSEL |
597 AD7793_FLAG_HAS_VBIAS |
598 AD7793_HAS_EXITATION_CURRENT,
Lars-Peter Clausen8c29ecd2012-08-10 17:36:00 +0100599 },
Michael Hennerich88bc3052011-06-08 16:12:44 +0200600 [ID_AD7792] = {
Lars-Peter Clausene786cc22012-11-21 16:27:00 +0000601 .id = AD7792_ID,
Lars-Peter Clausen525e6432012-08-10 17:36:00 +0100602 .channels = ad7792_channels,
603 .num_channels = ARRAY_SIZE(ad7792_channels),
Lars-Peter Clausen2edb7692012-11-21 16:27:00 +0000604 .flags = AD7793_FLAG_HAS_CLKSEL |
605 AD7793_FLAG_HAS_REFSEL |
606 AD7793_FLAG_HAS_VBIAS |
607 AD7793_HAS_EXITATION_CURRENT,
Lars-Peter Clausen525e6432012-08-10 17:36:00 +0100608 },
609 [ID_AD7793] = {
Lars-Peter Clausene786cc22012-11-21 16:27:00 +0000610 .id = AD7793_ID,
Lars-Peter Clausen525e6432012-08-10 17:36:00 +0100611 .channels = ad7793_channels,
612 .num_channels = ARRAY_SIZE(ad7793_channels),
Lars-Peter Clausen2edb7692012-11-21 16:27:00 +0000613 .flags = AD7793_FLAG_HAS_CLKSEL |
614 AD7793_FLAG_HAS_REFSEL |
615 AD7793_FLAG_HAS_VBIAS |
616 AD7793_HAS_EXITATION_CURRENT,
Lars-Peter Clausen525e6432012-08-10 17:36:00 +0100617 },
618 [ID_AD7794] = {
Lars-Peter Clausene786cc22012-11-21 16:27:00 +0000619 .id = AD7794_ID,
Lars-Peter Clausen525e6432012-08-10 17:36:00 +0100620 .channels = ad7794_channels,
621 .num_channels = ARRAY_SIZE(ad7794_channels),
Lars-Peter Clausen2edb7692012-11-21 16:27:00 +0000622 .flags = AD7793_FLAG_HAS_CLKSEL |
623 AD7793_FLAG_HAS_REFSEL |
624 AD7793_FLAG_HAS_VBIAS |
625 AD7793_HAS_EXITATION_CURRENT,
Lars-Peter Clausen525e6432012-08-10 17:36:00 +0100626 },
627 [ID_AD7795] = {
Lars-Peter Clausene786cc22012-11-21 16:27:00 +0000628 .id = AD7795_ID,
Lars-Peter Clausen525e6432012-08-10 17:36:00 +0100629 .channels = ad7795_channels,
630 .num_channels = ARRAY_SIZE(ad7795_channels),
Lars-Peter Clausen2edb7692012-11-21 16:27:00 +0000631 .flags = AD7793_FLAG_HAS_CLKSEL |
632 AD7793_FLAG_HAS_REFSEL |
633 AD7793_FLAG_HAS_VBIAS |
634 AD7793_HAS_EXITATION_CURRENT,
635 },
636 [ID_AD7798] = {
637 .id = AD7798_ID,
638 .channels = ad7798_channels,
639 .num_channels = ARRAY_SIZE(ad7798_channels),
640 },
641 [ID_AD7799] = {
642 .id = AD7799_ID,
643 .channels = ad7799_channels,
644 .num_channels = ARRAY_SIZE(ad7799_channels),
Michael Hennerich88bc3052011-06-08 16:12:44 +0200645 },
646};
647
Bill Pemberton4ae1c61f2012-11-19 13:21:57 -0500648static int ad7793_probe(struct spi_device *spi)
Michael Hennerich88bc3052011-06-08 16:12:44 +0200649{
Lars-Peter Clausenc8c194d2012-08-10 17:36:00 +0100650 const struct ad7793_platform_data *pdata = spi->dev.platform_data;
Michael Hennerich88bc3052011-06-08 16:12:44 +0200651 struct ad7793_state *st;
652 struct iio_dev *indio_dev;
Lars-Peter Clausendd2c1012012-11-21 16:27:00 +0000653 int ret, vref_mv = 0;
Michael Hennerich88bc3052011-06-08 16:12:44 +0200654
655 if (!pdata) {
656 dev_err(&spi->dev, "no platform data?\n");
657 return -ENODEV;
658 }
659
660 if (!spi->irq) {
661 dev_err(&spi->dev, "no IRQ?\n");
662 return -ENODEV;
663 }
664
Lars-Peter Clausen7cbb7532012-04-26 13:35:01 +0200665 indio_dev = iio_device_alloc(sizeof(*st));
Michael Hennerich88bc3052011-06-08 16:12:44 +0200666 if (indio_dev == NULL)
667 return -ENOMEM;
668
669 st = iio_priv(indio_dev);
670
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100671 ad_sd_init(&st->sd, indio_dev, spi, &ad7793_sigma_delta_info);
672
Lars-Peter Clausendd2c1012012-11-21 16:27:00 +0000673 if (pdata->refsel != AD7793_REFSEL_INTERNAL) {
674 st->reg = regulator_get(&spi->dev, "refin");
675 if (IS_ERR(st->reg)) {
676 ret = PTR_ERR(st->reg);
677 goto error_device_free;
678 }
679
Michael Hennerich88bc3052011-06-08 16:12:44 +0200680 ret = regulator_enable(st->reg);
681 if (ret)
682 goto error_put_reg;
683
Lars-Peter Clausendd2c1012012-11-21 16:27:00 +0000684 vref_mv = regulator_get_voltage(st->reg);
685 if (vref_mv < 0) {
686 ret = vref_mv;
687 goto error_disable_reg;
688 }
689
690 vref_mv /= 1000;
691 } else {
692 vref_mv = 1170; /* Build-in ref */
Michael Hennerich88bc3052011-06-08 16:12:44 +0200693 }
694
695 st->chip_info =
696 &ad7793_chip_info_tbl[spi_get_device_id(spi)->driver_data];
697
Michael Hennerich88bc3052011-06-08 16:12:44 +0200698 spi_set_drvdata(spi, indio_dev);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200699
700 indio_dev->dev.parent = &spi->dev;
701 indio_dev->name = spi_get_device_id(spi)->name;
702 indio_dev->modes = INDIO_DIRECT_MODE;
Lars-Peter Clausen525e6432012-08-10 17:36:00 +0100703 indio_dev->channels = st->chip_info->channels;
704 indio_dev->num_channels = st->chip_info->num_channels;
Michael Hennerich88bc3052011-06-08 16:12:44 +0200705 indio_dev->info = &ad7793_info;
706
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100707 ret = ad_sd_setup_buffer_and_trigger(indio_dev);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200708 if (ret)
709 goto error_disable_reg;
710
Lars-Peter Clausendd2c1012012-11-21 16:27:00 +0000711 ret = ad7793_setup(indio_dev, pdata, vref_mv);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200712 if (ret)
713 goto error_remove_trigger;
714
Jonathan Cameron26d25ae2011-09-02 17:14:40 +0100715 ret = iio_device_register(indio_dev);
716 if (ret)
Lars-Peter Clausen82796ed2012-06-18 18:33:54 +0200717 goto error_remove_trigger;
Jonathan Cameron26d25ae2011-09-02 17:14:40 +0100718
Michael Hennerich88bc3052011-06-08 16:12:44 +0200719 return 0;
720
Michael Hennerich88bc3052011-06-08 16:12:44 +0200721error_remove_trigger:
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100722 ad_sd_cleanup_buffer_and_trigger(indio_dev);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200723error_disable_reg:
Lars-Peter Clausendd2c1012012-11-21 16:27:00 +0000724 if (pdata->refsel != AD7793_REFSEL_INTERNAL)
Michael Hennerich88bc3052011-06-08 16:12:44 +0200725 regulator_disable(st->reg);
726error_put_reg:
Lars-Peter Clausendd2c1012012-11-21 16:27:00 +0000727 if (pdata->refsel != AD7793_REFSEL_INTERNAL)
Michael Hennerich88bc3052011-06-08 16:12:44 +0200728 regulator_put(st->reg);
Lars-Peter Clausendd2c1012012-11-21 16:27:00 +0000729error_device_free:
Lars-Peter Clausen7cbb7532012-04-26 13:35:01 +0200730 iio_device_free(indio_dev);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200731
732 return ret;
733}
734
Bill Pemberton447d4f22012-11-19 13:26:37 -0500735static int ad7793_remove(struct spi_device *spi)
Michael Hennerich88bc3052011-06-08 16:12:44 +0200736{
Lars-Peter Clausendd2c1012012-11-21 16:27:00 +0000737 const struct ad7793_platform_data *pdata = spi->dev.platform_data;
Michael Hennerich88bc3052011-06-08 16:12:44 +0200738 struct iio_dev *indio_dev = spi_get_drvdata(spi);
739 struct ad7793_state *st = iio_priv(indio_dev);
740
Jonathan Camerond2fffd62011-10-14 14:46:58 +0100741 iio_device_unregister(indio_dev);
Lars-Peter Clausen1abec6a2012-08-10 17:36:00 +0100742 ad_sd_cleanup_buffer_and_trigger(indio_dev);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200743
Lars-Peter Clausendd2c1012012-11-21 16:27:00 +0000744 if (pdata->refsel != AD7793_REFSEL_INTERNAL) {
Michael Hennerich88bc3052011-06-08 16:12:44 +0200745 regulator_disable(st->reg);
746 regulator_put(st->reg);
747 }
748
Lars-Peter Clausen7cbb7532012-04-26 13:35:01 +0200749 iio_device_free(indio_dev);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200750
751 return 0;
752}
753
754static const struct spi_device_id ad7793_id[] = {
Lars-Peter Clausen8c29ecd2012-08-10 17:36:00 +0100755 {"ad7785", ID_AD7785},
Michael Hennerich88bc3052011-06-08 16:12:44 +0200756 {"ad7792", ID_AD7792},
757 {"ad7793", ID_AD7793},
Lars-Peter Clausen525e6432012-08-10 17:36:00 +0100758 {"ad7794", ID_AD7794},
759 {"ad7795", ID_AD7795},
Lars-Peter Clausen2edb7692012-11-21 16:27:00 +0000760 {"ad7798", ID_AD7798},
761 {"ad7799", ID_AD7799},
Michael Hennerich88bc3052011-06-08 16:12:44 +0200762 {}
763};
Lars-Peter Clausen55e43902011-11-16 08:53:31 +0100764MODULE_DEVICE_TABLE(spi, ad7793_id);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200765
766static struct spi_driver ad7793_driver = {
767 .driver = {
768 .name = "ad7793",
Michael Hennerich88bc3052011-06-08 16:12:44 +0200769 .owner = THIS_MODULE,
770 },
771 .probe = ad7793_probe,
Bill Pembertone543acf2012-11-19 13:21:38 -0500772 .remove = ad7793_remove,
Michael Hennerich88bc3052011-06-08 16:12:44 +0200773 .id_table = ad7793_id,
774};
Lars-Peter Clausenae6ae6f2011-11-16 10:13:39 +0100775module_spi_driver(ad7793_driver);
Michael Hennerich88bc3052011-06-08 16:12:44 +0200776
777MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
Lars-Peter Clausen525e6432012-08-10 17:36:00 +0100778MODULE_DESCRIPTION("Analog Devices AD7793 and simialr ADCs");
Michael Hennerich88bc3052011-06-08 16:12:44 +0200779MODULE_LICENSE("GPL v2");