Commit | Line | Data |
---|---|---|
88bc3054 MH |
1 | /* |
2 | * AD7792/AD7793 SPI ADC driver | |
3 | * | |
f316983f | 4 | * Copyright 2011-2012 Analog Devices Inc. |
88bc3054 MH |
5 | * |
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> | |
45296236 | 19 | #include <linux/module.h> |
88bc3054 | 20 | |
06458e27 JC |
21 | #include <linux/iio/iio.h> |
22 | #include <linux/iio/sysfs.h> | |
23 | #include <linux/iio/buffer.h> | |
06458e27 JC |
24 | #include <linux/iio/trigger.h> |
25 | #include <linux/iio/trigger_consumer.h> | |
82796edc | 26 | #include <linux/iio/triggered_buffer.h> |
1abec6ac | 27 | #include <linux/iio/adc/ad_sigma_delta.h> |
88bc3054 MH |
28 | |
29 | #include "ad7793.h" | |
30 | ||
31 | /* NOTE: | |
32 | * The AD7792/AD7793 features a dual use data out ready DOUT/RDY output. | |
33 | * In order to avoid contentions on the SPI bus, it's therefore necessary | |
34 | * to use spi bus locking. | |
35 | * | |
36 | * The DOUT/RDY output must also be wired to an interrupt capable GPIO. | |
37 | */ | |
38 | ||
39 | struct ad7793_chip_info { | |
1abec6ac | 40 | struct iio_chan_spec channel[7]; |
88bc3054 MH |
41 | }; |
42 | ||
43 | struct ad7793_state { | |
88bc3054 MH |
44 | const struct ad7793_chip_info *chip_info; |
45 | struct regulator *reg; | |
88bc3054 MH |
46 | u16 int_vref_mv; |
47 | u16 mode; | |
48 | u16 conf; | |
49 | u32 scale_avail[8][2]; | |
8c2c6ba6 | 50 | |
1abec6ac LPC |
51 | struct ad_sigma_delta sd; |
52 | ||
88bc3054 MH |
53 | }; |
54 | ||
55 | enum ad7793_supported_device_ids { | |
56 | ID_AD7792, | |
57 | ID_AD7793, | |
58 | }; | |
59 | ||
1abec6ac | 60 | static struct ad7793_state *ad_sigma_delta_to_ad7793(struct ad_sigma_delta *sd) |
88bc3054 | 61 | { |
1abec6ac | 62 | return container_of(sd, struct ad7793_state, sd); |
88bc3054 MH |
63 | } |
64 | ||
1abec6ac | 65 | static int ad7793_set_channel(struct ad_sigma_delta *sd, unsigned int channel) |
88bc3054 | 66 | { |
1abec6ac | 67 | struct ad7793_state *st = ad_sigma_delta_to_ad7793(sd); |
88bc3054 | 68 | |
1abec6ac LPC |
69 | st->conf &= ~AD7793_CONF_CHAN_MASK; |
70 | st->conf |= AD7793_CONF_CHAN(channel); | |
88bc3054 | 71 | |
1abec6ac | 72 | return ad_sd_write_reg(&st->sd, AD7793_REG_CONF, 2, st->conf); |
88bc3054 MH |
73 | } |
74 | ||
1abec6ac LPC |
75 | static int ad7793_set_mode(struct ad_sigma_delta *sd, |
76 | enum ad_sigma_delta_mode mode) | |
88bc3054 | 77 | { |
1abec6ac | 78 | struct ad7793_state *st = ad_sigma_delta_to_ad7793(sd); |
88bc3054 | 79 | |
1abec6ac LPC |
80 | st->mode &= ~AD7793_MODE_SEL_MASK; |
81 | st->mode |= AD7793_MODE_SEL(mode); | |
88bc3054 | 82 | |
1abec6ac | 83 | return ad_sd_write_reg(&st->sd, AD7793_REG_MODE, 2, st->mode); |
88bc3054 MH |
84 | } |
85 | ||
1abec6ac LPC |
86 | static const struct ad_sigma_delta_info ad7793_sigma_delta_info = { |
87 | .set_channel = ad7793_set_channel, | |
88 | .set_mode = ad7793_set_mode, | |
89 | .has_registers = true, | |
90 | .addr_shift = 3, | |
91 | .read_mask = BIT(6), | |
92 | }; | |
88bc3054 | 93 | |
1abec6ac | 94 | static const struct ad_sd_calib_data ad7793_calib_arr[6] = { |
88bc3054 MH |
95 | {AD7793_MODE_CAL_INT_ZERO, AD7793_CH_AIN1P_AIN1M}, |
96 | {AD7793_MODE_CAL_INT_FULL, AD7793_CH_AIN1P_AIN1M}, | |
97 | {AD7793_MODE_CAL_INT_ZERO, AD7793_CH_AIN2P_AIN2M}, | |
98 | {AD7793_MODE_CAL_INT_FULL, AD7793_CH_AIN2P_AIN2M}, | |
99 | {AD7793_MODE_CAL_INT_ZERO, AD7793_CH_AIN3P_AIN3M}, | |
100 | {AD7793_MODE_CAL_INT_FULL, AD7793_CH_AIN3P_AIN3M} | |
101 | }; | |
102 | ||
103 | static int ad7793_calibrate_all(struct ad7793_state *st) | |
104 | { | |
1abec6ac LPC |
105 | return ad_sd_calibrate_all(&st->sd, ad7793_calib_arr, |
106 | ARRAY_SIZE(ad7793_calib_arr)); | |
88bc3054 MH |
107 | } |
108 | ||
1abec6ac | 109 | static int ad7793_setup(struct iio_dev *indio_dev, |
c8c194d5 | 110 | const struct ad7793_platform_data *pdata) |
88bc3054 | 111 | { |
1abec6ac | 112 | struct ad7793_state *st = iio_priv(indio_dev); |
88bc3054 MH |
113 | int i, ret = -1; |
114 | unsigned long long scale_uv; | |
115 | u32 id; | |
116 | ||
117 | /* reset the serial interface */ | |
1abec6ac | 118 | ret = spi_write(st->sd.spi, (u8 *)&ret, sizeof(ret)); |
88bc3054 MH |
119 | if (ret < 0) |
120 | goto out; | |
121 | msleep(1); /* Wait for at least 500us */ | |
122 | ||
123 | /* write/read test for device presence */ | |
1abec6ac | 124 | ret = ad_sd_read_reg(&st->sd, AD7793_REG_ID, 1, &id); |
88bc3054 MH |
125 | if (ret) |
126 | goto out; | |
127 | ||
128 | id &= AD7793_ID_MASK; | |
129 | ||
130 | if (!((id == AD7792_ID) || (id == AD7793_ID))) { | |
1abec6ac | 131 | dev_err(&st->sd.spi->dev, "device ID query failed\n"); |
88bc3054 MH |
132 | goto out; |
133 | } | |
134 | ||
1abec6ac LPC |
135 | st->mode = pdata->mode; |
136 | st->conf = pdata->conf; | |
88bc3054 | 137 | |
1abec6ac | 138 | ret = ad7793_set_mode(&st->sd, AD_SD_MODE_IDLE); |
88bc3054 MH |
139 | if (ret) |
140 | goto out; | |
141 | ||
1abec6ac | 142 | ret = ad7793_set_channel(&st->sd, 0); |
88bc3054 MH |
143 | if (ret) |
144 | goto out; | |
145 | ||
1abec6ac | 146 | ret = ad_sd_write_reg(&st->sd, AD7793_REG_IO, |
c8c194d5 | 147 | sizeof(pdata->io), pdata->io); |
88bc3054 MH |
148 | if (ret) |
149 | goto out; | |
150 | ||
151 | ret = ad7793_calibrate_all(st); | |
152 | if (ret) | |
153 | goto out; | |
154 | ||
155 | /* Populate available ADC input ranges */ | |
156 | for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++) { | |
157 | scale_uv = ((u64)st->int_vref_mv * 100000000) | |
158 | >> (st->chip_info->channel[0].scan_type.realbits - | |
159 | (!!(st->conf & AD7793_CONF_UNIPOLAR) ? 0 : 1)); | |
160 | scale_uv >>= i; | |
161 | ||
162 | st->scale_avail[i][1] = do_div(scale_uv, 100000000) * 10; | |
163 | st->scale_avail[i][0] = scale_uv; | |
164 | } | |
165 | ||
166 | return 0; | |
167 | out: | |
1abec6ac | 168 | dev_err(&st->sd.spi->dev, "setup failed\n"); |
88bc3054 MH |
169 | return ret; |
170 | } | |
171 | ||
88bc3054 MH |
172 | static const u16 sample_freq_avail[16] = {0, 470, 242, 123, 62, 50, 39, 33, 19, |
173 | 17, 16, 12, 10, 8, 6, 4}; | |
174 | ||
175 | static ssize_t ad7793_read_frequency(struct device *dev, | |
176 | struct device_attribute *attr, | |
177 | char *buf) | |
178 | { | |
62c51839 | 179 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); |
88bc3054 MH |
180 | struct ad7793_state *st = iio_priv(indio_dev); |
181 | ||
182 | return sprintf(buf, "%d\n", | |
183 | sample_freq_avail[AD7793_MODE_RATE(st->mode)]); | |
184 | } | |
185 | ||
186 | static ssize_t ad7793_write_frequency(struct device *dev, | |
187 | struct device_attribute *attr, | |
188 | const char *buf, | |
189 | size_t len) | |
190 | { | |
62c51839 | 191 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); |
88bc3054 MH |
192 | struct ad7793_state *st = iio_priv(indio_dev); |
193 | long lval; | |
194 | int i, ret; | |
195 | ||
196 | mutex_lock(&indio_dev->mlock); | |
14555b14 | 197 | if (iio_buffer_enabled(indio_dev)) { |
88bc3054 MH |
198 | mutex_unlock(&indio_dev->mlock); |
199 | return -EBUSY; | |
200 | } | |
201 | mutex_unlock(&indio_dev->mlock); | |
202 | ||
203 | ret = strict_strtol(buf, 10, &lval); | |
204 | if (ret) | |
205 | return ret; | |
206 | ||
207 | ret = -EINVAL; | |
208 | ||
209 | for (i = 0; i < ARRAY_SIZE(sample_freq_avail); i++) | |
210 | if (lval == sample_freq_avail[i]) { | |
211 | mutex_lock(&indio_dev->mlock); | |
212 | st->mode &= ~AD7793_MODE_RATE(-1); | |
213 | st->mode |= AD7793_MODE_RATE(i); | |
1abec6ac | 214 | ad_sd_write_reg(&st->sd, AD7793_REG_MODE, |
88bc3054 MH |
215 | sizeof(st->mode), st->mode); |
216 | mutex_unlock(&indio_dev->mlock); | |
217 | ret = 0; | |
218 | } | |
219 | ||
220 | return ret ? ret : len; | |
221 | } | |
222 | ||
223 | static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, | |
224 | ad7793_read_frequency, | |
225 | ad7793_write_frequency); | |
226 | ||
227 | static IIO_CONST_ATTR_SAMP_FREQ_AVAIL( | |
228 | "470 242 123 62 50 39 33 19 17 16 12 10 8 6 4"); | |
229 | ||
230 | static ssize_t ad7793_show_scale_available(struct device *dev, | |
231 | struct device_attribute *attr, char *buf) | |
232 | { | |
62c51839 | 233 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); |
88bc3054 MH |
234 | struct ad7793_state *st = iio_priv(indio_dev); |
235 | int i, len = 0; | |
236 | ||
237 | for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++) | |
238 | len += sprintf(buf + len, "%d.%09u ", st->scale_avail[i][0], | |
239 | st->scale_avail[i][1]); | |
240 | ||
241 | len += sprintf(buf + len, "\n"); | |
242 | ||
243 | return len; | |
244 | } | |
245 | ||
08ca3b78 LPC |
246 | static IIO_DEVICE_ATTR_NAMED(in_m_in_scale_available, |
247 | in_voltage-voltage_scale_available, S_IRUGO, | |
248 | ad7793_show_scale_available, NULL, 0); | |
88bc3054 MH |
249 | |
250 | static struct attribute *ad7793_attributes[] = { | |
251 | &iio_dev_attr_sampling_frequency.dev_attr.attr, | |
252 | &iio_const_attr_sampling_frequency_available.dev_attr.attr, | |
253 | &iio_dev_attr_in_m_in_scale_available.dev_attr.attr, | |
254 | NULL | |
255 | }; | |
256 | ||
257 | static const struct attribute_group ad7793_attribute_group = { | |
258 | .attrs = ad7793_attributes, | |
259 | }; | |
260 | ||
261 | static int ad7793_read_raw(struct iio_dev *indio_dev, | |
262 | struct iio_chan_spec const *chan, | |
263 | int *val, | |
264 | int *val2, | |
265 | long m) | |
266 | { | |
267 | struct ad7793_state *st = iio_priv(indio_dev); | |
1abec6ac | 268 | int ret; |
88bc3054 MH |
269 | unsigned long long scale_uv; |
270 | bool unipolar = !!(st->conf & AD7793_CONF_UNIPOLAR); | |
271 | ||
272 | switch (m) { | |
b11f98ff | 273 | case IIO_CHAN_INFO_RAW: |
1abec6ac | 274 | ret = ad_sigma_delta_single_conversion(indio_dev, chan, val); |
88bc3054 MH |
275 | if (ret < 0) |
276 | return ret; | |
277 | ||
88bc3054 MH |
278 | return IIO_VAL_INT; |
279 | ||
c8a9f805 | 280 | case IIO_CHAN_INFO_SCALE: |
88bc3054 | 281 | switch (chan->type) { |
6835cb6b | 282 | case IIO_VOLTAGE: |
c8a9f805 JC |
283 | if (chan->differential) { |
284 | *val = st-> | |
285 | scale_avail[(st->conf >> 8) & 0x7][0]; | |
286 | *val2 = st-> | |
287 | scale_avail[(st->conf >> 8) & 0x7][1]; | |
288 | return IIO_VAL_INT_PLUS_NANO; | |
289 | } else { | |
290 | /* 1170mV / 2^23 * 6 */ | |
2a9e0662 | 291 | scale_uv = (1170ULL * 100000000ULL * 6ULL); |
c8a9f805 | 292 | } |
88bc3054 MH |
293 | break; |
294 | case IIO_TEMP: | |
2a9e0662 LPC |
295 | /* 1170mV / 0.81 mV/C / 2^23 */ |
296 | scale_uv = 1444444444444ULL; | |
88bc3054 MH |
297 | break; |
298 | default: | |
299 | return -EINVAL; | |
300 | } | |
301 | ||
2a9e0662 LPC |
302 | scale_uv >>= (chan->scan_type.realbits - (unipolar ? 0 : 1)); |
303 | *val = 0; | |
304 | *val2 = scale_uv; | |
88bc3054 | 305 | return IIO_VAL_INT_PLUS_NANO; |
680f8ea0 LPC |
306 | case IIO_CHAN_INFO_OFFSET: |
307 | if (!unipolar) | |
2a9e0662 | 308 | *val = -(1 << (chan->scan_type.realbits - 1)); |
680f8ea0 LPC |
309 | else |
310 | *val = 0; | |
2a9e0662 LPC |
311 | |
312 | /* Kelvin to Celsius */ | |
313 | if (chan->type == IIO_TEMP) { | |
314 | unsigned long long offset; | |
315 | unsigned int shift; | |
316 | ||
317 | shift = chan->scan_type.realbits - (unipolar ? 0 : 1); | |
318 | offset = 273ULL << shift; | |
319 | do_div(offset, 1444); | |
320 | *val -= offset; | |
321 | } | |
680f8ea0 | 322 | return IIO_VAL_INT; |
88bc3054 MH |
323 | } |
324 | return -EINVAL; | |
325 | } | |
326 | ||
327 | static int ad7793_write_raw(struct iio_dev *indio_dev, | |
328 | struct iio_chan_spec const *chan, | |
329 | int val, | |
330 | int val2, | |
331 | long mask) | |
332 | { | |
333 | struct ad7793_state *st = iio_priv(indio_dev); | |
334 | int ret, i; | |
335 | unsigned int tmp; | |
336 | ||
337 | mutex_lock(&indio_dev->mlock); | |
14555b14 | 338 | if (iio_buffer_enabled(indio_dev)) { |
88bc3054 MH |
339 | mutex_unlock(&indio_dev->mlock); |
340 | return -EBUSY; | |
341 | } | |
342 | ||
343 | switch (mask) { | |
c8a9f805 | 344 | case IIO_CHAN_INFO_SCALE: |
88bc3054 MH |
345 | ret = -EINVAL; |
346 | for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++) | |
347 | if (val2 == st->scale_avail[i][1]) { | |
1abec6ac | 348 | ret = 0; |
88bc3054 MH |
349 | tmp = st->conf; |
350 | st->conf &= ~AD7793_CONF_GAIN(-1); | |
351 | st->conf |= AD7793_CONF_GAIN(i); | |
352 | ||
1abec6ac LPC |
353 | if (tmp == st->conf) |
354 | break; | |
355 | ||
356 | ad_sd_write_reg(&st->sd, AD7793_REG_CONF, | |
357 | sizeof(st->conf), st->conf); | |
358 | ad7793_calibrate_all(st); | |
359 | break; | |
88bc3054 | 360 | } |
421afe58 | 361 | break; |
88bc3054 MH |
362 | default: |
363 | ret = -EINVAL; | |
364 | } | |
365 | ||
366 | mutex_unlock(&indio_dev->mlock); | |
367 | return ret; | |
368 | } | |
369 | ||
88bc3054 MH |
370 | static int ad7793_write_raw_get_fmt(struct iio_dev *indio_dev, |
371 | struct iio_chan_spec const *chan, | |
372 | long mask) | |
373 | { | |
374 | return IIO_VAL_INT_PLUS_NANO; | |
375 | } | |
376 | ||
377 | static const struct iio_info ad7793_info = { | |
378 | .read_raw = &ad7793_read_raw, | |
379 | .write_raw = &ad7793_write_raw, | |
380 | .write_raw_get_fmt = &ad7793_write_raw_get_fmt, | |
381 | .attrs = &ad7793_attribute_group, | |
1abec6ac | 382 | .validate_trigger = ad_sd_validate_trigger, |
88bc3054 MH |
383 | .driver_module = THIS_MODULE, |
384 | }; | |
385 | ||
386 | static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { | |
387 | [ID_AD7793] = { | |
1abec6ac LPC |
388 | .channel = { |
389 | AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, 24, 32, 0), | |
390 | AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, 24, 32, 0), | |
391 | AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, 24, 32, 0), | |
392 | AD_SD_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, 24, 32, 0), | |
393 | AD_SD_TEMP_CHANNEL(4, AD7793_CH_TEMP, 24, 32, 0), | |
394 | AD_SD_SUPPLY_CHANNEL(5, 3, AD7793_CH_AVDD_MONITOR, 24, 32, 0), | |
395 | IIO_CHAN_SOFT_TIMESTAMP(6), | |
ade7ef7b | 396 | }, |
88bc3054 MH |
397 | }, |
398 | [ID_AD7792] = { | |
1abec6ac LPC |
399 | .channel = { |
400 | AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, 16, 32, 0), | |
401 | AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, 16, 32, 0), | |
402 | AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, 16, 32, 0), | |
403 | AD_SD_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, 16, 32, 0), | |
404 | AD_SD_TEMP_CHANNEL(4, AD7793_CH_TEMP, 16, 32, 0), | |
405 | AD_SD_SUPPLY_CHANNEL(5, 3, AD7793_CH_AVDD_MONITOR, 16, 32, 0), | |
406 | IIO_CHAN_SOFT_TIMESTAMP(6), | |
ade7ef7b | 407 | }, |
88bc3054 MH |
408 | }, |
409 | }; | |
410 | ||
411 | static int __devinit ad7793_probe(struct spi_device *spi) | |
412 | { | |
c8c194d5 | 413 | const struct ad7793_platform_data *pdata = spi->dev.platform_data; |
88bc3054 MH |
414 | struct ad7793_state *st; |
415 | struct iio_dev *indio_dev; | |
8c2c6ba6 | 416 | int ret, voltage_uv = 0; |
88bc3054 MH |
417 | |
418 | if (!pdata) { | |
419 | dev_err(&spi->dev, "no platform data?\n"); | |
420 | return -ENODEV; | |
421 | } | |
422 | ||
423 | if (!spi->irq) { | |
424 | dev_err(&spi->dev, "no IRQ?\n"); | |
425 | return -ENODEV; | |
426 | } | |
427 | ||
7cbb7537 | 428 | indio_dev = iio_device_alloc(sizeof(*st)); |
88bc3054 MH |
429 | if (indio_dev == NULL) |
430 | return -ENOMEM; | |
431 | ||
432 | st = iio_priv(indio_dev); | |
433 | ||
1abec6ac LPC |
434 | ad_sd_init(&st->sd, indio_dev, spi, &ad7793_sigma_delta_info); |
435 | ||
88bc3054 MH |
436 | st->reg = regulator_get(&spi->dev, "vcc"); |
437 | if (!IS_ERR(st->reg)) { | |
438 | ret = regulator_enable(st->reg); | |
439 | if (ret) | |
440 | goto error_put_reg; | |
441 | ||
442 | voltage_uv = regulator_get_voltage(st->reg); | |
443 | } | |
444 | ||
445 | st->chip_info = | |
446 | &ad7793_chip_info_tbl[spi_get_device_id(spi)->driver_data]; | |
447 | ||
88bc3054 MH |
448 | if (pdata && pdata->vref_mv) |
449 | st->int_vref_mv = pdata->vref_mv; | |
450 | else if (voltage_uv) | |
451 | st->int_vref_mv = voltage_uv / 1000; | |
452 | else | |
87a0c157 | 453 | st->int_vref_mv = 1170; /* Build-in ref */ |
88bc3054 MH |
454 | |
455 | spi_set_drvdata(spi, indio_dev); | |
88bc3054 MH |
456 | |
457 | indio_dev->dev.parent = &spi->dev; | |
458 | indio_dev->name = spi_get_device_id(spi)->name; | |
459 | indio_dev->modes = INDIO_DIRECT_MODE; | |
460 | indio_dev->channels = st->chip_info->channel; | |
88bc3054 MH |
461 | indio_dev->num_channels = 7; |
462 | indio_dev->info = &ad7793_info; | |
463 | ||
1abec6ac | 464 | ret = ad_sd_setup_buffer_and_trigger(indio_dev); |
88bc3054 MH |
465 | if (ret) |
466 | goto error_disable_reg; | |
467 | ||
1abec6ac | 468 | ret = ad7793_setup(indio_dev, pdata); |
88bc3054 | 469 | if (ret) |
82796edc | 470 | goto error_remove_trigger; |
88bc3054 | 471 | |
26d25ae3 JC |
472 | ret = iio_device_register(indio_dev); |
473 | if (ret) | |
82796edc | 474 | goto error_remove_trigger; |
26d25ae3 | 475 | |
88bc3054 MH |
476 | return 0; |
477 | ||
88bc3054 | 478 | error_remove_trigger: |
1abec6ac | 479 | ad_sd_cleanup_buffer_and_trigger(indio_dev); |
88bc3054 MH |
480 | error_disable_reg: |
481 | if (!IS_ERR(st->reg)) | |
482 | regulator_disable(st->reg); | |
483 | error_put_reg: | |
484 | if (!IS_ERR(st->reg)) | |
485 | regulator_put(st->reg); | |
486 | ||
7cbb7537 | 487 | iio_device_free(indio_dev); |
88bc3054 MH |
488 | |
489 | return ret; | |
490 | } | |
491 | ||
492 | static int ad7793_remove(struct spi_device *spi) | |
493 | { | |
494 | struct iio_dev *indio_dev = spi_get_drvdata(spi); | |
495 | struct ad7793_state *st = iio_priv(indio_dev); | |
496 | ||
d2fffd6c | 497 | iio_device_unregister(indio_dev); |
1abec6ac | 498 | ad_sd_cleanup_buffer_and_trigger(indio_dev); |
88bc3054 MH |
499 | |
500 | if (!IS_ERR(st->reg)) { | |
501 | regulator_disable(st->reg); | |
502 | regulator_put(st->reg); | |
503 | } | |
504 | ||
7cbb7537 | 505 | iio_device_free(indio_dev); |
88bc3054 MH |
506 | |
507 | return 0; | |
508 | } | |
509 | ||
510 | static const struct spi_device_id ad7793_id[] = { | |
511 | {"ad7792", ID_AD7792}, | |
512 | {"ad7793", ID_AD7793}, | |
513 | {} | |
514 | }; | |
55e4390c | 515 | MODULE_DEVICE_TABLE(spi, ad7793_id); |
88bc3054 MH |
516 | |
517 | static struct spi_driver ad7793_driver = { | |
518 | .driver = { | |
519 | .name = "ad7793", | |
88bc3054 MH |
520 | .owner = THIS_MODULE, |
521 | }, | |
522 | .probe = ad7793_probe, | |
523 | .remove = __devexit_p(ad7793_remove), | |
524 | .id_table = ad7793_id, | |
525 | }; | |
ae6ae6fe | 526 | module_spi_driver(ad7793_driver); |
88bc3054 MH |
527 | |
528 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | |
529 | MODULE_DESCRIPTION("Analog Devices AD7792/3 ADC"); | |
530 | MODULE_LICENSE("GPL v2"); |