blob: f22f668c6bcfc22450358f72961ccb5477172fe7 [file] [log] [blame]
Michael Hennerichb9618c02011-02-22 21:46:18 +01001/*
2 * AD7606 SPI ADC driver
3 *
4 * Copyright 2011 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2.
7 */
8
9#include <linux/interrupt.h>
Michael Hennerichb9618c02011-02-22 21:46:18 +010010#include <linux/device.h>
11#include <linux/kernel.h>
12#include <linux/slab.h>
13#include <linux/sysfs.h>
Michael Hennerichb9618c02011-02-22 21:46:18 +010014#include <linux/regulator/consumer.h>
15#include <linux/err.h>
16#include <linux/gpio.h>
17#include <linux/delay.h>
18#include <linux/sched.h>
Paul Gortmaker99c97852011-07-03 15:49:50 -040019#include <linux/module.h>
Michael Hennerichb9618c02011-02-22 21:46:18 +010020
21#include "../iio.h"
22#include "../sysfs.h"
23#include "../ring_generic.h"
Michael Hennerichb9618c02011-02-22 21:46:18 +010024
25#include "ad7606.h"
26
27int ad7606_reset(struct ad7606_state *st)
28{
29 if (st->have_reset) {
30 gpio_set_value(st->pdata->gpio_reset, 1);
31 ndelay(100); /* t_reset >= 100ns */
32 gpio_set_value(st->pdata->gpio_reset, 0);
33 return 0;
34 }
35
36 return -ENODEV;
37}
38
Michael Hennerich44039a62011-05-18 14:42:28 +010039static int ad7606_scan_direct(struct iio_dev *indio_dev, unsigned ch)
Michael Hennerichb9618c02011-02-22 21:46:18 +010040{
Michael Hennerich44039a62011-05-18 14:42:28 +010041 struct ad7606_state *st = iio_priv(indio_dev);
Michael Hennerichb9618c02011-02-22 21:46:18 +010042 int ret;
43
44 st->done = false;
45 gpio_set_value(st->pdata->gpio_convst, 1);
46
47 ret = wait_event_interruptible(st->wq_data_avail, st->done);
48 if (ret)
49 goto error_ret;
50
51 if (st->have_frstdata) {
52 ret = st->bops->read_block(st->dev, 1, st->data);
53 if (ret)
54 goto error_ret;
55 if (!gpio_get_value(st->pdata->gpio_frstdata)) {
56 /* This should never happen */
57 ad7606_reset(st);
58 ret = -EIO;
59 goto error_ret;
60 }
61 ret = st->bops->read_block(st->dev,
62 st->chip_info->num_channels - 1, &st->data[1]);
63 if (ret)
64 goto error_ret;
65 } else {
66 ret = st->bops->read_block(st->dev,
67 st->chip_info->num_channels, st->data);
68 if (ret)
69 goto error_ret;
70 }
71
72 ret = st->data[ch];
73
74error_ret:
75 gpio_set_value(st->pdata->gpio_convst, 0);
76
77 return ret;
78}
79
Michael Hennerichb9c44512011-05-18 14:42:27 +010080static int ad7606_read_raw(struct iio_dev *indio_dev,
Michael Hennerich1caf7cb2011-05-18 14:42:00 +010081 struct iio_chan_spec const *chan,
82 int *val,
83 int *val2,
84 long m)
Michael Hennerichb9618c02011-02-22 21:46:18 +010085{
Michael Hennerichb9618c02011-02-22 21:46:18 +010086 int ret;
Michael Hennerich44039a62011-05-18 14:42:28 +010087 struct ad7606_state *st = iio_priv(indio_dev);
Michael Hennerich1caf7cb2011-05-18 14:42:00 +010088 unsigned int scale_uv;
Michael Hennerichb9618c02011-02-22 21:46:18 +010089
Michael Hennerich1caf7cb2011-05-18 14:42:00 +010090 switch (m) {
91 case 0:
Michael Hennerichb9c44512011-05-18 14:42:27 +010092 mutex_lock(&indio_dev->mlock);
93 if (iio_ring_enabled(indio_dev))
Michael Hennerich44039a62011-05-18 14:42:28 +010094 ret = ad7606_scan_from_ring(indio_dev, chan->address);
Michael Hennerich1caf7cb2011-05-18 14:42:00 +010095 else
Michael Hennerich44039a62011-05-18 14:42:28 +010096 ret = ad7606_scan_direct(indio_dev, chan->address);
Michael Hennerichb9c44512011-05-18 14:42:27 +010097 mutex_unlock(&indio_dev->mlock);
Michael Hennerichb9618c02011-02-22 21:46:18 +010098
Michael Hennerich1caf7cb2011-05-18 14:42:00 +010099 if (ret < 0)
100 return ret;
101 *val = (short) ret;
102 return IIO_VAL_INT;
103 case (1 << IIO_CHAN_INFO_SCALE_SHARED):
104 scale_uv = (st->range * 1000 * 2)
105 >> st->chip_info->channels[0].scan_type.realbits;
106 *val = scale_uv / 1000;
107 *val2 = (scale_uv % 1000) * 1000;
108 return IIO_VAL_INT_PLUS_MICRO;
109 }
110 return -EINVAL;
Michael Hennerichb9618c02011-02-22 21:46:18 +0100111}
112
Michael Hennerichb9618c02011-02-22 21:46:18 +0100113static ssize_t ad7606_show_range(struct device *dev,
114 struct device_attribute *attr, char *buf)
115{
Michael Hennerichb9c44512011-05-18 14:42:27 +0100116 struct iio_dev *indio_dev = dev_get_drvdata(dev);
Michael Hennerich44039a62011-05-18 14:42:28 +0100117 struct ad7606_state *st = iio_priv(indio_dev);
Michael Hennerichb9618c02011-02-22 21:46:18 +0100118
119 return sprintf(buf, "%u\n", st->range);
120}
121
122static ssize_t ad7606_store_range(struct device *dev,
123 struct device_attribute *attr, const char *buf, size_t count)
124{
Michael Hennerichb9c44512011-05-18 14:42:27 +0100125 struct iio_dev *indio_dev = dev_get_drvdata(dev);
Michael Hennerich44039a62011-05-18 14:42:28 +0100126 struct ad7606_state *st = iio_priv(indio_dev);
Michael Hennerichb9618c02011-02-22 21:46:18 +0100127 unsigned long lval;
128
129 if (strict_strtoul(buf, 10, &lval))
130 return -EINVAL;
131 if (!(lval == 5000 || lval == 10000)) {
132 dev_err(dev, "range is not supported\n");
133 return -EINVAL;
134 }
Michael Hennerichb9c44512011-05-18 14:42:27 +0100135 mutex_lock(&indio_dev->mlock);
Michael Hennerichb9618c02011-02-22 21:46:18 +0100136 gpio_set_value(st->pdata->gpio_range, lval == 10000);
137 st->range = lval;
Michael Hennerichb9c44512011-05-18 14:42:27 +0100138 mutex_unlock(&indio_dev->mlock);
Michael Hennerichb9618c02011-02-22 21:46:18 +0100139
140 return count;
141}
142
Jonathan Cameroncedd1a12011-09-14 13:01:24 +0100143static IIO_DEVICE_ATTR(in_voltage_range, S_IRUGO | S_IWUSR, \
Michael Hennerichb9618c02011-02-22 21:46:18 +0100144 ad7606_show_range, ad7606_store_range, 0);
Jonathan Cameroncedd1a12011-09-14 13:01:24 +0100145static IIO_CONST_ATTR(in_voltage_range_available, "5000 10000");
Michael Hennerichb9618c02011-02-22 21:46:18 +0100146
147static ssize_t ad7606_show_oversampling_ratio(struct device *dev,
148 struct device_attribute *attr, char *buf)
149{
Michael Hennerichb9c44512011-05-18 14:42:27 +0100150 struct iio_dev *indio_dev = dev_get_drvdata(dev);
Michael Hennerich44039a62011-05-18 14:42:28 +0100151 struct ad7606_state *st = iio_priv(indio_dev);
Michael Hennerichb9618c02011-02-22 21:46:18 +0100152
153 return sprintf(buf, "%u\n", st->oversampling);
154}
155
156static int ad7606_oversampling_get_index(unsigned val)
157{
158 unsigned char supported[] = {0, 2, 4, 8, 16, 32, 64};
159 int i;
160
161 for (i = 0; i < ARRAY_SIZE(supported); i++)
162 if (val == supported[i])
163 return i;
164
165 return -EINVAL;
166}
167
168static ssize_t ad7606_store_oversampling_ratio(struct device *dev,
169 struct device_attribute *attr, const char *buf, size_t count)
170{
Michael Hennerichb9c44512011-05-18 14:42:27 +0100171 struct iio_dev *indio_dev = dev_get_drvdata(dev);
Michael Hennerich44039a62011-05-18 14:42:28 +0100172 struct ad7606_state *st = iio_priv(indio_dev);
Michael Hennerichb9618c02011-02-22 21:46:18 +0100173 unsigned long lval;
174 int ret;
175
176 if (strict_strtoul(buf, 10, &lval))
177 return -EINVAL;
178
179 ret = ad7606_oversampling_get_index(lval);
180 if (ret < 0) {
181 dev_err(dev, "oversampling %lu is not supported\n", lval);
182 return ret;
183 }
184
Michael Hennerichb9c44512011-05-18 14:42:27 +0100185 mutex_lock(&indio_dev->mlock);
Michael Hennerichb9618c02011-02-22 21:46:18 +0100186 gpio_set_value(st->pdata->gpio_os0, (ret >> 0) & 1);
187 gpio_set_value(st->pdata->gpio_os1, (ret >> 1) & 1);
188 gpio_set_value(st->pdata->gpio_os1, (ret >> 2) & 1);
189 st->oversampling = lval;
Michael Hennerichb9c44512011-05-18 14:42:27 +0100190 mutex_unlock(&indio_dev->mlock);
Michael Hennerichb9618c02011-02-22 21:46:18 +0100191
192 return count;
193}
194
195static IIO_DEVICE_ATTR(oversampling_ratio, S_IRUGO | S_IWUSR,
196 ad7606_show_oversampling_ratio,
197 ad7606_store_oversampling_ratio, 0);
198static IIO_CONST_ATTR(oversampling_ratio_available, "0 2 4 8 16 32 64");
199
200static struct attribute *ad7606_attributes[] = {
Jonathan Cameroncedd1a12011-09-14 13:01:24 +0100201 &iio_dev_attr_in_voltage_range.dev_attr.attr,
202 &iio_const_attr_in_voltage_range_available.dev_attr.attr,
Michael Hennerichb9618c02011-02-22 21:46:18 +0100203 &iio_dev_attr_oversampling_ratio.dev_attr.attr,
204 &iio_const_attr_oversampling_ratio_available.dev_attr.attr,
205 NULL,
206};
207
208static mode_t ad7606_attr_is_visible(struct kobject *kobj,
209 struct attribute *attr, int n)
210{
211 struct device *dev = container_of(kobj, struct device, kobj);
Michael Hennerichb9c44512011-05-18 14:42:27 +0100212 struct iio_dev *indio_dev = dev_get_drvdata(dev);
Michael Hennerich44039a62011-05-18 14:42:28 +0100213 struct ad7606_state *st = iio_priv(indio_dev);
Michael Hennerichb9618c02011-02-22 21:46:18 +0100214
215 mode_t mode = attr->mode;
216
Michael Hennerich1caf7cb2011-05-18 14:42:00 +0100217 if (!st->have_os &&
Michael Hennerichb9618c02011-02-22 21:46:18 +0100218 (attr == &iio_dev_attr_oversampling_ratio.dev_attr.attr ||
219 attr ==
220 &iio_const_attr_oversampling_ratio_available.dev_attr.attr))
221 mode = 0;
222 else if (!st->have_range &&
Jonathan Cameroncedd1a12011-09-14 13:01:24 +0100223 (attr == &iio_dev_attr_in_voltage_range.dev_attr.attr ||
224 attr ==
225 &iio_const_attr_in_voltage_range_available.dev_attr.attr))
226 mode = 0;
Michael Hennerichb9618c02011-02-22 21:46:18 +0100227
228 return mode;
229}
230
231static const struct attribute_group ad7606_attribute_group = {
232 .attrs = ad7606_attributes,
233 .is_visible = ad7606_attr_is_visible,
234};
235
Michael Hennerich1caf7cb2011-05-18 14:42:00 +0100236static struct iio_chan_spec ad7606_8_channels[] = {
237 IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
238 (1 << IIO_CHAN_INFO_SCALE_SHARED),
239 0, 0, IIO_ST('s', 16, 16, 0), 0),
240 IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
241 (1 << IIO_CHAN_INFO_SCALE_SHARED),
242 1, 1, IIO_ST('s', 16, 16, 0), 0),
243 IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 2, 0,
244 (1 << IIO_CHAN_INFO_SCALE_SHARED),
245 2, 2, IIO_ST('s', 16, 16, 0), 0),
246 IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 3, 0,
247 (1 << IIO_CHAN_INFO_SCALE_SHARED),
248 3, 3, IIO_ST('s', 16, 16, 0), 0),
249 IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 4, 0,
250 (1 << IIO_CHAN_INFO_SCALE_SHARED),
251 4, 4, IIO_ST('s', 16, 16, 0), 0),
252 IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 5, 0,
253 (1 << IIO_CHAN_INFO_SCALE_SHARED),
254 5, 5, IIO_ST('s', 16, 16, 0), 0),
255 IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 6, 0,
256 (1 << IIO_CHAN_INFO_SCALE_SHARED),
257 6, 6, IIO_ST('s', 16, 16, 0), 0),
258 IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 7, 0,
259 (1 << IIO_CHAN_INFO_SCALE_SHARED),
260 7, 7, IIO_ST('s', 16, 16, 0), 0),
261 IIO_CHAN_SOFT_TIMESTAMP(8),
262};
263
264static struct iio_chan_spec ad7606_6_channels[] = {
265 IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
266 (1 << IIO_CHAN_INFO_SCALE_SHARED),
267 0, 0, IIO_ST('s', 16, 16, 0), 0),
268 IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
269 (1 << IIO_CHAN_INFO_SCALE_SHARED),
270 1, 1, IIO_ST('s', 16, 16, 0), 0),
271 IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 2, 0,
272 (1 << IIO_CHAN_INFO_SCALE_SHARED),
273 2, 2, IIO_ST('s', 16, 16, 0), 0),
274 IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 3, 0,
275 (1 << IIO_CHAN_INFO_SCALE_SHARED),
276 3, 3, IIO_ST('s', 16, 16, 0), 0),
277 IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 4, 0,
278 (1 << IIO_CHAN_INFO_SCALE_SHARED),
279 4, 4, IIO_ST('s', 16, 16, 0), 0),
280 IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 5, 0,
281 (1 << IIO_CHAN_INFO_SCALE_SHARED),
282 5, 5, IIO_ST('s', 16, 16, 0), 0),
283 IIO_CHAN_SOFT_TIMESTAMP(6),
284};
285
286static struct iio_chan_spec ad7606_4_channels[] = {
287 IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
288 (1 << IIO_CHAN_INFO_SCALE_SHARED),
289 0, 0, IIO_ST('s', 16, 16, 0), 0),
290 IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
291 (1 << IIO_CHAN_INFO_SCALE_SHARED),
292 1, 1, IIO_ST('s', 16, 16, 0), 0),
293 IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 2, 0,
294 (1 << IIO_CHAN_INFO_SCALE_SHARED),
295 2, 2, IIO_ST('s', 16, 16, 0), 0),
296 IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 3, 0,
297 (1 << IIO_CHAN_INFO_SCALE_SHARED),
298 3, 3, IIO_ST('s', 16, 16, 0), 0),
299 IIO_CHAN_SOFT_TIMESTAMP(4),
300};
301
Michael Hennerichb9618c02011-02-22 21:46:18 +0100302static const struct ad7606_chip_info ad7606_chip_info_tbl[] = {
303 /*
304 * More devices added in future
305 */
306 [ID_AD7606_8] = {
307 .name = "ad7606",
Michael Hennerichb9618c02011-02-22 21:46:18 +0100308 .int_vref_mv = 2500,
Michael Hennerich1caf7cb2011-05-18 14:42:00 +0100309 .channels = ad7606_8_channels,
Michael Hennerichb9618c02011-02-22 21:46:18 +0100310 .num_channels = 8,
311 },
312 [ID_AD7606_6] = {
313 .name = "ad7606-6",
Michael Hennerichb9618c02011-02-22 21:46:18 +0100314 .int_vref_mv = 2500,
Michael Hennerich1caf7cb2011-05-18 14:42:00 +0100315 .channels = ad7606_6_channels,
Michael Hennerichb9618c02011-02-22 21:46:18 +0100316 .num_channels = 6,
317 },
318 [ID_AD7606_4] = {
319 .name = "ad7606-4",
Michael Hennerichb9618c02011-02-22 21:46:18 +0100320 .int_vref_mv = 2500,
Michael Hennerich1caf7cb2011-05-18 14:42:00 +0100321 .channels = ad7606_4_channels,
Michael Hennerichb9618c02011-02-22 21:46:18 +0100322 .num_channels = 4,
323 },
324};
325
326static int ad7606_request_gpios(struct ad7606_state *st)
327{
328 struct gpio gpio_array[3] = {
329 [0] = {
330 .gpio = st->pdata->gpio_os0,
331 .flags = GPIOF_DIR_OUT | ((st->oversampling & 1) ?
332 GPIOF_INIT_HIGH : GPIOF_INIT_LOW),
333 .label = "AD7606_OS0",
334 },
335 [1] = {
336 .gpio = st->pdata->gpio_os1,
337 .flags = GPIOF_DIR_OUT | ((st->oversampling & 2) ?
338 GPIOF_INIT_HIGH : GPIOF_INIT_LOW),
339 .label = "AD7606_OS1",
340 },
341 [2] = {
342 .gpio = st->pdata->gpio_os2,
343 .flags = GPIOF_DIR_OUT | ((st->oversampling & 4) ?
344 GPIOF_INIT_HIGH : GPIOF_INIT_LOW),
345 .label = "AD7606_OS2",
346 },
347 };
348 int ret;
349
350 ret = gpio_request_one(st->pdata->gpio_convst, GPIOF_OUT_INIT_LOW,
351 "AD7606_CONVST");
352 if (ret) {
353 dev_err(st->dev, "failed to request GPIO CONVST\n");
354 return ret;
355 }
356
357 ret = gpio_request_array(gpio_array, ARRAY_SIZE(gpio_array));
358 if (!ret) {
359 st->have_os = true;
360 }
361
362 ret = gpio_request_one(st->pdata->gpio_reset, GPIOF_OUT_INIT_LOW,
363 "AD7606_RESET");
364 if (!ret)
365 st->have_reset = true;
366
367 ret = gpio_request_one(st->pdata->gpio_range, GPIOF_DIR_OUT |
Michael Henneriche61181d2011-05-18 14:42:01 +0100368 ((st->range == 10000) ? GPIOF_INIT_HIGH :
369 GPIOF_INIT_LOW), "AD7606_RANGE");
Michael Hennerichb9618c02011-02-22 21:46:18 +0100370 if (!ret)
371 st->have_range = true;
372
373 ret = gpio_request_one(st->pdata->gpio_stby, GPIOF_OUT_INIT_HIGH,
374 "AD7606_STBY");
375 if (!ret)
376 st->have_stby = true;
377
378 if (gpio_is_valid(st->pdata->gpio_frstdata)) {
379 ret = gpio_request_one(st->pdata->gpio_frstdata, GPIOF_IN,
380 "AD7606_FRSTDATA");
381 if (!ret)
382 st->have_frstdata = true;
383 }
384
385 return 0;
386}
387
388static void ad7606_free_gpios(struct ad7606_state *st)
389{
390 if (st->have_range)
391 gpio_free(st->pdata->gpio_range);
392
393 if (st->have_stby)
394 gpio_free(st->pdata->gpio_stby);
395
396 if (st->have_os) {
397 gpio_free(st->pdata->gpio_os0);
398 gpio_free(st->pdata->gpio_os1);
399 gpio_free(st->pdata->gpio_os2);
400 }
401
402 if (st->have_reset)
403 gpio_free(st->pdata->gpio_reset);
404
405 if (st->have_frstdata)
406 gpio_free(st->pdata->gpio_frstdata);
407
408 gpio_free(st->pdata->gpio_convst);
409}
410
411/**
412 * Interrupt handler
413 */
414static irqreturn_t ad7606_interrupt(int irq, void *dev_id)
415{
Michael Henneriche61181d2011-05-18 14:42:01 +0100416 struct iio_dev *indio_dev = dev_id;
417 struct ad7606_state *st = iio_priv(indio_dev);
Michael Hennerichb9618c02011-02-22 21:46:18 +0100418
Michael Henneriche61181d2011-05-18 14:42:01 +0100419 if (iio_ring_enabled(indio_dev)) {
Michael Hennerichb9618c02011-02-22 21:46:18 +0100420 if (!work_pending(&st->poll_work))
421 schedule_work(&st->poll_work);
422 } else {
423 st->done = true;
424 wake_up_interruptible(&st->wq_data_avail);
425 }
426
427 return IRQ_HANDLED;
428};
429
Jonathan Cameron6fe81352011-05-18 14:42:37 +0100430static const struct iio_info ad7606_info = {
431 .driver_module = THIS_MODULE,
432 .read_raw = &ad7606_read_raw,
433 .attrs = &ad7606_attribute_group,
434};
435
Michael Henneriche61181d2011-05-18 14:42:01 +0100436struct iio_dev *ad7606_probe(struct device *dev, int irq,
Michael Hennerichb9618c02011-02-22 21:46:18 +0100437 void __iomem *base_address,
438 unsigned id,
439 const struct ad7606_bus_ops *bops)
440{
441 struct ad7606_platform_data *pdata = dev->platform_data;
442 struct ad7606_state *st;
Jonathan Cameron26d25ae2011-09-02 17:14:40 +0100443 int ret;
Michael Henneriche61181d2011-05-18 14:42:01 +0100444 struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st));
Michael Hennerichb9618c02011-02-22 21:46:18 +0100445
Michael Henneriche61181d2011-05-18 14:42:01 +0100446 if (indio_dev == NULL) {
Michael Hennerichb9618c02011-02-22 21:46:18 +0100447 ret = -ENOMEM;
448 goto error_ret;
449 }
450
Michael Henneriche61181d2011-05-18 14:42:01 +0100451 st = iio_priv(indio_dev);
452
Michael Hennerichb9618c02011-02-22 21:46:18 +0100453 st->dev = dev;
454 st->id = id;
455 st->irq = irq;
456 st->bops = bops;
457 st->base_address = base_address;
458 st->range = pdata->default_range == 10000 ? 10000 : 5000;
459
460 ret = ad7606_oversampling_get_index(pdata->default_os);
461 if (ret < 0) {
462 dev_warn(dev, "oversampling %d is not supported\n",
463 pdata->default_os);
464 st->oversampling = 0;
465 } else {
466 st->oversampling = pdata->default_os;
467 }
468
469 st->reg = regulator_get(dev, "vcc");
470 if (!IS_ERR(st->reg)) {
471 ret = regulator_enable(st->reg);
472 if (ret)
473 goto error_put_reg;
474 }
475
476 st->pdata = pdata;
477 st->chip_info = &ad7606_chip_info_tbl[id];
478
Michael Henneriche61181d2011-05-18 14:42:01 +0100479 indio_dev->dev.parent = dev;
Jonathan Cameron6fe81352011-05-18 14:42:37 +0100480 indio_dev->info = &ad7606_info;
Michael Henneriche61181d2011-05-18 14:42:01 +0100481 indio_dev->modes = INDIO_DIRECT_MODE;
482 indio_dev->name = st->chip_info->name;
483 indio_dev->channels = st->chip_info->channels;
484 indio_dev->num_channels = st->chip_info->num_channels;
Michael Hennerichb9618c02011-02-22 21:46:18 +0100485
486 init_waitqueue_head(&st->wq_data_avail);
487
488 ret = ad7606_request_gpios(st);
489 if (ret)
Michael Henneriche61181d2011-05-18 14:42:01 +0100490 goto error_disable_reg;
Michael Hennerichb9618c02011-02-22 21:46:18 +0100491
492 ret = ad7606_reset(st);
493 if (ret)
494 dev_warn(st->dev, "failed to RESET: no RESET GPIO specified\n");
495
496 ret = request_irq(st->irq, ad7606_interrupt,
Michael Henneriche61181d2011-05-18 14:42:01 +0100497 IRQF_TRIGGER_FALLING, st->chip_info->name, indio_dev);
Michael Hennerichb9618c02011-02-22 21:46:18 +0100498 if (ret)
499 goto error_free_gpios;
500
Michael Henneriche61181d2011-05-18 14:42:01 +0100501 ret = ad7606_register_ring_funcs_and_init(indio_dev);
Michael Hennerichb9618c02011-02-22 21:46:18 +0100502 if (ret)
503 goto error_free_irq;
504
Jonathan Cameronc009f7e2011-08-30 12:41:14 +0100505 ret = iio_ring_buffer_register(indio_dev,
506 indio_dev->channels,
507 indio_dev->num_channels);
Michael Hennerichb9618c02011-02-22 21:46:18 +0100508 if (ret)
509 goto error_cleanup_ring;
Jonathan Cameron26d25ae2011-09-02 17:14:40 +0100510 ret = iio_device_register(indio_dev);
511 if (ret)
512 goto error_unregister_ring;
Michael Hennerichb9618c02011-02-22 21:46:18 +0100513
Michael Henneriche61181d2011-05-18 14:42:01 +0100514 return indio_dev;
Jonathan Cameron26d25ae2011-09-02 17:14:40 +0100515error_unregister_ring:
516 iio_ring_buffer_unregister(indio_dev);
Michael Hennerichb9618c02011-02-22 21:46:18 +0100517
518error_cleanup_ring:
Michael Henneriche61181d2011-05-18 14:42:01 +0100519 ad7606_ring_cleanup(indio_dev);
Michael Hennerichb9618c02011-02-22 21:46:18 +0100520
521error_free_irq:
Michael Henneriche61181d2011-05-18 14:42:01 +0100522 free_irq(st->irq, indio_dev);
Michael Hennerichb9618c02011-02-22 21:46:18 +0100523
524error_free_gpios:
525 ad7606_free_gpios(st);
526
Michael Hennerichb9618c02011-02-22 21:46:18 +0100527error_disable_reg:
528 if (!IS_ERR(st->reg))
529 regulator_disable(st->reg);
530error_put_reg:
531 if (!IS_ERR(st->reg))
532 regulator_put(st->reg);
Jonathan Cameron26d25ae2011-09-02 17:14:40 +0100533 iio_free_device(indio_dev);
Michael Hennerichb9618c02011-02-22 21:46:18 +0100534error_ret:
535 return ERR_PTR(ret);
536}
537
Michael Henneriche61181d2011-05-18 14:42:01 +0100538int ad7606_remove(struct iio_dev *indio_dev)
Michael Hennerichb9618c02011-02-22 21:46:18 +0100539{
Michael Henneriche61181d2011-05-18 14:42:01 +0100540 struct ad7606_state *st = iio_priv(indio_dev);
541
Jonathan Cameron1aa04272011-08-30 12:32:47 +0100542 iio_ring_buffer_unregister(indio_dev);
Michael Hennerichb9618c02011-02-22 21:46:18 +0100543 ad7606_ring_cleanup(indio_dev);
Michael Henneriche61181d2011-05-18 14:42:01 +0100544
545 free_irq(st->irq, indio_dev);
Michael Hennerichb9618c02011-02-22 21:46:18 +0100546 if (!IS_ERR(st->reg)) {
547 regulator_disable(st->reg);
548 regulator_put(st->reg);
549 }
550
551 ad7606_free_gpios(st);
Michael Henneriche61181d2011-05-18 14:42:01 +0100552 iio_device_unregister(indio_dev);
Michael Hennerichb9618c02011-02-22 21:46:18 +0100553
Michael Hennerichb9618c02011-02-22 21:46:18 +0100554 return 0;
555}
556
Michael Henneriche61181d2011-05-18 14:42:01 +0100557void ad7606_suspend(struct iio_dev *indio_dev)
Michael Hennerichb9618c02011-02-22 21:46:18 +0100558{
Michael Henneriche61181d2011-05-18 14:42:01 +0100559 struct ad7606_state *st = iio_priv(indio_dev);
560
Michael Hennerichb9618c02011-02-22 21:46:18 +0100561 if (st->have_stby) {
562 if (st->have_range)
563 gpio_set_value(st->pdata->gpio_range, 1);
564 gpio_set_value(st->pdata->gpio_stby, 0);
565 }
566}
567
Michael Henneriche61181d2011-05-18 14:42:01 +0100568void ad7606_resume(struct iio_dev *indio_dev)
Michael Hennerichb9618c02011-02-22 21:46:18 +0100569{
Michael Henneriche61181d2011-05-18 14:42:01 +0100570 struct ad7606_state *st = iio_priv(indio_dev);
571
Michael Hennerichb9618c02011-02-22 21:46:18 +0100572 if (st->have_stby) {
573 if (st->have_range)
574 gpio_set_value(st->pdata->gpio_range,
575 st->range == 10000);
576
577 gpio_set_value(st->pdata->gpio_stby, 1);
578 ad7606_reset(st);
579 }
580}
581
582MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
583MODULE_DESCRIPTION("Analog Devices AD7606 ADC");
584MODULE_LICENSE("GPL v2");