]>
Commit | Line | Data |
---|---|---|
985dbe77 MH |
1 | /* |
2 | * iio/adc/ad799x.c | |
d22fd9c5 | 3 | * Copyright (C) 2010-1011 Michael Hennerich, Analog Devices Inc. |
985dbe77 MH |
4 | * |
5 | * based on iio/adc/max1363 | |
6 | * Copyright (C) 2008-2010 Jonathan Cameron | |
7 | * | |
8 | * based on linux/drivers/i2c/chips/max123x | |
9 | * Copyright (C) 2002-2004 Stefan Eletzhofer | |
10 | * | |
11 | * based on linux/drivers/acron/char/pcf8583.c | |
12 | * Copyright (C) 2000 Russell King | |
13 | * | |
14 | * This program is free software; you can redistribute it and/or modify | |
15 | * it under the terms of the GNU General Public License version 2 as | |
16 | * published by the Free Software Foundation. | |
17 | * | |
18 | * ad799x.c | |
19 | * | |
20 | * Support for ad7991, ad7995, ad7999, ad7992, ad7993, ad7994, ad7997, | |
21 | * ad7998 and similar chips. | |
22 | * | |
23 | */ | |
24 | ||
25 | #include <linux/interrupt.h> | |
985dbe77 MH |
26 | #include <linux/device.h> |
27 | #include <linux/kernel.h> | |
28 | #include <linux/sysfs.h> | |
985dbe77 MH |
29 | #include <linux/i2c.h> |
30 | #include <linux/regulator/consumer.h> | |
31 | #include <linux/slab.h> | |
32 | #include <linux/types.h> | |
33 | #include <linux/err.h> | |
99c97852 | 34 | #include <linux/module.h> |
985dbe77 MH |
35 | |
36 | #include "../iio.h" | |
37 | #include "../sysfs.h" | |
3811cd62 | 38 | #include "../buffer_generic.h" |
cdf38709 | 39 | |
985dbe77 MH |
40 | #include "ad799x.h" |
41 | ||
42 | /* | |
43 | * ad799x register access by I2C | |
44 | */ | |
45 | static int ad799x_i2c_read16(struct ad799x_state *st, u8 reg, u16 *data) | |
46 | { | |
47 | struct i2c_client *client = st->client; | |
48 | int ret = 0; | |
49 | ||
50 | ret = i2c_smbus_read_word_data(client, reg); | |
51 | if (ret < 0) { | |
52 | dev_err(&client->dev, "I2C read error\n"); | |
53 | return ret; | |
54 | } | |
55 | ||
56 | *data = swab16((u16)ret); | |
57 | ||
58 | return 0; | |
59 | } | |
60 | ||
61 | static int ad799x_i2c_read8(struct ad799x_state *st, u8 reg, u8 *data) | |
62 | { | |
63 | struct i2c_client *client = st->client; | |
64 | int ret = 0; | |
65 | ||
aecac191 | 66 | ret = i2c_smbus_read_byte_data(client, reg); |
985dbe77 MH |
67 | if (ret < 0) { |
68 | dev_err(&client->dev, "I2C read error\n"); | |
69 | return ret; | |
70 | } | |
71 | ||
aecac191 | 72 | *data = (u8)ret; |
985dbe77 MH |
73 | |
74 | return 0; | |
75 | } | |
76 | ||
77 | static int ad799x_i2c_write16(struct ad799x_state *st, u8 reg, u16 data) | |
78 | { | |
79 | struct i2c_client *client = st->client; | |
80 | int ret = 0; | |
81 | ||
82 | ret = i2c_smbus_write_word_data(client, reg, swab16(data)); | |
83 | if (ret < 0) | |
84 | dev_err(&client->dev, "I2C write error\n"); | |
85 | ||
86 | return ret; | |
87 | } | |
88 | ||
89 | static int ad799x_i2c_write8(struct ad799x_state *st, u8 reg, u8 data) | |
90 | { | |
91 | struct i2c_client *client = st->client; | |
92 | int ret = 0; | |
93 | ||
94 | ret = i2c_smbus_write_byte_data(client, reg, data); | |
95 | if (ret < 0) | |
96 | dev_err(&client->dev, "I2C write error\n"); | |
97 | ||
98 | return ret; | |
99 | } | |
100 | ||
d22fd9c5 | 101 | int ad7997_8_set_scan_mode(struct ad799x_state *st, unsigned mask) |
985dbe77 MH |
102 | { |
103 | return ad799x_i2c_write16(st, AD7998_CONF_REG, | |
104 | st->config | (mask << AD799X_CHANNEL_SHIFT)); | |
105 | } | |
106 | ||
d22fd9c5 | 107 | static int ad799x_scan_direct(struct ad799x_state *st, unsigned ch) |
985dbe77 | 108 | { |
d22fd9c5 MH |
109 | u16 rxbuf; |
110 | u8 cmd; | |
985dbe77 MH |
111 | int ret; |
112 | ||
d22fd9c5 MH |
113 | switch (st->id) { |
114 | case ad7991: | |
115 | case ad7995: | |
116 | case ad7999: | |
117 | cmd = st->config | ((1 << ch) << AD799X_CHANNEL_SHIFT); | |
118 | break; | |
119 | case ad7992: | |
120 | case ad7993: | |
121 | case ad7994: | |
122 | cmd = (1 << ch) << AD799X_CHANNEL_SHIFT; | |
123 | break; | |
124 | case ad7997: | |
125 | case ad7998: | |
126 | cmd = (ch << AD799X_CHANNEL_SHIFT) | AD7997_8_READ_SINGLE; | |
127 | break; | |
128 | default: | |
129 | return -EINVAL; | |
985dbe77 MH |
130 | } |
131 | ||
d22fd9c5 MH |
132 | ret = ad799x_i2c_read16(st, cmd, &rxbuf); |
133 | if (ret < 0) | |
134 | return ret; | |
135 | ||
136 | return rxbuf; | |
985dbe77 MH |
137 | } |
138 | ||
d22fd9c5 MH |
139 | static int ad799x_read_raw(struct iio_dev *dev_info, |
140 | struct iio_chan_spec const *chan, | |
141 | int *val, | |
142 | int *val2, | |
143 | long m) | |
985dbe77 | 144 | { |
d22fd9c5 | 145 | int ret; |
d8aea29b | 146 | struct ad799x_state *st = iio_priv(dev_info); |
d22fd9c5 MH |
147 | unsigned int scale_uv; |
148 | ||
149 | switch (m) { | |
150 | case 0: | |
151 | mutex_lock(&dev_info->mlock); | |
14555b14 | 152 | if (iio_buffer_enabled(dev_info)) |
f2a63429 | 153 | ret = ad799x_single_channel_from_ring(dev_info, |
7c626f58 | 154 | chan->scan_index); |
d22fd9c5 MH |
155 | else |
156 | ret = ad799x_scan_direct(st, chan->address); | |
157 | mutex_unlock(&dev_info->mlock); | |
985dbe77 | 158 | |
985dbe77 | 159 | if (ret < 0) |
d22fd9c5 | 160 | return ret; |
5357ba3d JC |
161 | *val = (ret >> chan->scan_type.shift) & |
162 | RES_MASK(chan->scan_type.realbits); | |
d22fd9c5 MH |
163 | return IIO_VAL_INT; |
164 | case (1 << IIO_CHAN_INFO_SCALE_SHARED): | |
5357ba3d | 165 | scale_uv = (st->int_vref_mv * 1000) >> chan->scan_type.realbits; |
d22fd9c5 MH |
166 | *val = scale_uv / 1000; |
167 | *val2 = (scale_uv % 1000) * 1000; | |
168 | return IIO_VAL_INT_PLUS_MICRO; | |
985dbe77 | 169 | } |
d22fd9c5 | 170 | return -EINVAL; |
985dbe77 | 171 | } |
24cba406 JC |
172 | static const unsigned int ad7998_frequencies[] = { |
173 | [AD7998_CYC_DIS] = 0, | |
174 | [AD7998_CYC_TCONF_32] = 15625, | |
175 | [AD7998_CYC_TCONF_64] = 7812, | |
176 | [AD7998_CYC_TCONF_128] = 3906, | |
177 | [AD7998_CYC_TCONF_512] = 976, | |
178 | [AD7998_CYC_TCONF_1024] = 488, | |
179 | [AD7998_CYC_TCONF_2048] = 244, | |
180 | }; | |
985dbe77 MH |
181 | static ssize_t ad799x_read_frequency(struct device *dev, |
182 | struct device_attribute *attr, | |
183 | char *buf) | |
184 | { | |
185 | struct iio_dev *dev_info = dev_get_drvdata(dev); | |
d8aea29b | 186 | struct ad799x_state *st = iio_priv(dev_info); |
985dbe77 | 187 | |
24cba406 | 188 | int ret; |
985dbe77 MH |
189 | u8 val; |
190 | ret = ad799x_i2c_read8(st, AD7998_CYCLE_TMR_REG, &val); | |
191 | if (ret) | |
192 | return ret; | |
193 | ||
194 | val &= AD7998_CYC_MASK; | |
195 | ||
24cba406 | 196 | return sprintf(buf, "%u\n", ad7998_frequencies[val]); |
985dbe77 MH |
197 | } |
198 | ||
199 | static ssize_t ad799x_write_frequency(struct device *dev, | |
200 | struct device_attribute *attr, | |
201 | const char *buf, | |
202 | size_t len) | |
203 | { | |
204 | struct iio_dev *dev_info = dev_get_drvdata(dev); | |
d8aea29b | 205 | struct ad799x_state *st = iio_priv(dev_info); |
985dbe77 MH |
206 | |
207 | long val; | |
24cba406 | 208 | int ret, i; |
985dbe77 MH |
209 | u8 t; |
210 | ||
211 | ret = strict_strtol(buf, 10, &val); | |
212 | if (ret) | |
213 | return ret; | |
214 | ||
215 | mutex_lock(&dev_info->mlock); | |
216 | ret = ad799x_i2c_read8(st, AD7998_CYCLE_TMR_REG, &t); | |
217 | if (ret) | |
218 | goto error_ret_mutex; | |
219 | /* Wipe the bits clean */ | |
220 | t &= ~AD7998_CYC_MASK; | |
221 | ||
24cba406 JC |
222 | for (i = 0; i < ARRAY_SIZE(ad7998_frequencies); i++) |
223 | if (val == ad7998_frequencies[i]) | |
224 | break; | |
225 | if (i == ARRAY_SIZE(ad7998_frequencies)) { | |
985dbe77 MH |
226 | ret = -EINVAL; |
227 | goto error_ret_mutex; | |
228 | } | |
24cba406 | 229 | t |= i; |
985dbe77 MH |
230 | ret = ad799x_i2c_write8(st, AD7998_CYCLE_TMR_REG, t); |
231 | ||
232 | error_ret_mutex: | |
233 | mutex_unlock(&dev_info->mlock); | |
234 | ||
235 | return ret ? ret : len; | |
236 | } | |
237 | ||
985dbe77 MH |
238 | static ssize_t ad799x_read_channel_config(struct device *dev, |
239 | struct device_attribute *attr, | |
240 | char *buf) | |
241 | { | |
242 | struct iio_dev *dev_info = dev_get_drvdata(dev); | |
d8aea29b | 243 | struct ad799x_state *st = iio_priv(dev_info); |
72148f6e | 244 | struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); |
985dbe77 MH |
245 | |
246 | int ret; | |
247 | u16 val; | |
72148f6e | 248 | ret = ad799x_i2c_read16(st, this_attr->address, &val); |
985dbe77 MH |
249 | if (ret) |
250 | return ret; | |
251 | ||
252 | return sprintf(buf, "%d\n", val); | |
253 | } | |
254 | ||
255 | static ssize_t ad799x_write_channel_config(struct device *dev, | |
256 | struct device_attribute *attr, | |
257 | const char *buf, | |
258 | size_t len) | |
259 | { | |
260 | struct iio_dev *dev_info = dev_get_drvdata(dev); | |
d8aea29b | 261 | struct ad799x_state *st = iio_priv(dev_info); |
72148f6e | 262 | struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); |
985dbe77 MH |
263 | |
264 | long val; | |
265 | int ret; | |
266 | ||
267 | ret = strict_strtol(buf, 10, &val); | |
268 | if (ret) | |
269 | return ret; | |
270 | ||
271 | mutex_lock(&dev_info->mlock); | |
72148f6e | 272 | ret = ad799x_i2c_write16(st, this_attr->address, val); |
985dbe77 MH |
273 | mutex_unlock(&dev_info->mlock); |
274 | ||
275 | return ret ? ret : len; | |
276 | } | |
277 | ||
72148f6e | 278 | static irqreturn_t ad799x_event_handler(int irq, void *private) |
985dbe77 | 279 | { |
72148f6e | 280 | struct iio_dev *indio_dev = private; |
d8aea29b | 281 | struct ad799x_state *st = iio_priv(private); |
985dbe77 | 282 | u8 status; |
72148f6e | 283 | int i, ret; |
985dbe77 | 284 | |
72148f6e JC |
285 | ret = ad799x_i2c_read8(st, AD7998_ALERT_STAT_REG, &status); |
286 | if (ret) | |
287 | return ret; | |
985dbe77 MH |
288 | |
289 | if (!status) | |
72148f6e | 290 | return -EIO; |
985dbe77 MH |
291 | |
292 | ad799x_i2c_write8(st, AD7998_ALERT_STAT_REG, AD7998_ALERT_STAT_CLEAR); | |
293 | ||
294 | for (i = 0; i < 8; i++) { | |
295 | if (status & (1 << i)) | |
5aa96188 | 296 | iio_push_event(indio_dev, |
72148f6e | 297 | i & 0x1 ? |
6835cb6b | 298 | IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, |
cdf38709 JC |
299 | (i >> 1), |
300 | IIO_EV_TYPE_THRESH, | |
301 | IIO_EV_DIR_RISING) : | |
6835cb6b | 302 | IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, |
cdf38709 JC |
303 | (i >> 1), |
304 | IIO_EV_TYPE_THRESH, | |
305 | IIO_EV_DIR_FALLING), | |
72148f6e | 306 | iio_get_time_ns()); |
985dbe77 MH |
307 | } |
308 | ||
72148f6e | 309 | return IRQ_HANDLED; |
985dbe77 MH |
310 | } |
311 | ||
322c9563 | 312 | static IIO_DEVICE_ATTR(in_voltage0_thresh_low_value, |
72148f6e JC |
313 | S_IRUGO | S_IWUSR, |
314 | ad799x_read_channel_config, | |
315 | ad799x_write_channel_config, | |
316 | AD7998_DATALOW_CH1_REG); | |
317 | ||
322c9563 | 318 | static IIO_DEVICE_ATTR(in_voltage0_thresh_high_value, |
72148f6e JC |
319 | S_IRUGO | S_IWUSR, |
320 | ad799x_read_channel_config, | |
321 | ad799x_write_channel_config, | |
322 | AD7998_DATAHIGH_CH1_REG); | |
323 | ||
322c9563 | 324 | static IIO_DEVICE_ATTR(in_voltage0_thresh_both_hyst_raw, |
72148f6e JC |
325 | S_IRUGO | S_IWUSR, |
326 | ad799x_read_channel_config, | |
327 | ad799x_write_channel_config, | |
328 | AD7998_HYST_CH1_REG); | |
329 | ||
322c9563 | 330 | static IIO_DEVICE_ATTR(in_voltage1_thresh_low_value, |
72148f6e JC |
331 | S_IRUGO | S_IWUSR, |
332 | ad799x_read_channel_config, | |
333 | ad799x_write_channel_config, | |
334 | AD7998_DATALOW_CH2_REG); | |
335 | ||
322c9563 | 336 | static IIO_DEVICE_ATTR(in_voltage1_thresh_high_value, |
72148f6e JC |
337 | S_IRUGO | S_IWUSR, |
338 | ad799x_read_channel_config, | |
339 | ad799x_write_channel_config, | |
340 | AD7998_DATAHIGH_CH2_REG); | |
341 | ||
322c9563 | 342 | static IIO_DEVICE_ATTR(in_voltage1_thresh_both_hyst_raw, |
72148f6e JC |
343 | S_IRUGO | S_IWUSR, |
344 | ad799x_read_channel_config, | |
345 | ad799x_write_channel_config, | |
346 | AD7998_HYST_CH2_REG); | |
347 | ||
322c9563 | 348 | static IIO_DEVICE_ATTR(in_voltage2_thresh_low_value, |
72148f6e JC |
349 | S_IRUGO | S_IWUSR, |
350 | ad799x_read_channel_config, | |
351 | ad799x_write_channel_config, | |
352 | AD7998_DATALOW_CH3_REG); | |
353 | ||
322c9563 | 354 | static IIO_DEVICE_ATTR(in_voltage2_thresh_high_value, |
72148f6e JC |
355 | S_IRUGO | S_IWUSR, |
356 | ad799x_read_channel_config, | |
357 | ad799x_write_channel_config, | |
358 | AD7998_DATAHIGH_CH3_REG); | |
359 | ||
322c9563 | 360 | static IIO_DEVICE_ATTR(in_voltage2_thresh_both_hyst_raw, |
72148f6e JC |
361 | S_IRUGO | S_IWUSR, |
362 | ad799x_read_channel_config, | |
363 | ad799x_write_channel_config, | |
364 | AD7998_HYST_CH3_REG); | |
365 | ||
322c9563 | 366 | static IIO_DEVICE_ATTR(in_voltage3_thresh_low_value, |
72148f6e JC |
367 | S_IRUGO | S_IWUSR, |
368 | ad799x_read_channel_config, | |
369 | ad799x_write_channel_config, | |
370 | AD7998_DATALOW_CH4_REG); | |
371 | ||
322c9563 | 372 | static IIO_DEVICE_ATTR(in_voltage3_thresh_high_value, |
72148f6e JC |
373 | S_IRUGO | S_IWUSR, |
374 | ad799x_read_channel_config, | |
375 | ad799x_write_channel_config, | |
376 | AD7998_DATAHIGH_CH4_REG); | |
377 | ||
322c9563 | 378 | static IIO_DEVICE_ATTR(in_voltage3_thresh_both_hyst_raw, |
72148f6e JC |
379 | S_IRUGO | S_IWUSR, |
380 | ad799x_read_channel_config, | |
381 | ad799x_write_channel_config, | |
382 | AD7998_HYST_CH4_REG); | |
985dbe77 MH |
383 | |
384 | static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, | |
385 | ad799x_read_frequency, | |
386 | ad799x_write_frequency); | |
387 | static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("15625 7812 3906 1953 976 488 244 0"); | |
388 | ||
389 | static struct attribute *ad7993_4_7_8_event_attributes[] = { | |
322c9563 JC |
390 | &iio_dev_attr_in_voltage0_thresh_low_value.dev_attr.attr, |
391 | &iio_dev_attr_in_voltage0_thresh_high_value.dev_attr.attr, | |
392 | &iio_dev_attr_in_voltage0_thresh_both_hyst_raw.dev_attr.attr, | |
393 | &iio_dev_attr_in_voltage1_thresh_low_value.dev_attr.attr, | |
394 | &iio_dev_attr_in_voltage1_thresh_high_value.dev_attr.attr, | |
395 | &iio_dev_attr_in_voltage1_thresh_both_hyst_raw.dev_attr.attr, | |
396 | &iio_dev_attr_in_voltage2_thresh_low_value.dev_attr.attr, | |
397 | &iio_dev_attr_in_voltage2_thresh_high_value.dev_attr.attr, | |
398 | &iio_dev_attr_in_voltage2_thresh_both_hyst_raw.dev_attr.attr, | |
399 | &iio_dev_attr_in_voltage3_thresh_low_value.dev_attr.attr, | |
400 | &iio_dev_attr_in_voltage3_thresh_high_value.dev_attr.attr, | |
401 | &iio_dev_attr_in_voltage3_thresh_both_hyst_raw.dev_attr.attr, | |
985dbe77 MH |
402 | &iio_dev_attr_sampling_frequency.dev_attr.attr, |
403 | &iio_const_attr_sampling_frequency_available.dev_attr.attr, | |
404 | NULL, | |
405 | }; | |
406 | ||
407 | static struct attribute_group ad7993_4_7_8_event_attrs_group = { | |
408 | .attrs = ad7993_4_7_8_event_attributes, | |
8e7d9672 | 409 | .name = "events", |
985dbe77 MH |
410 | }; |
411 | ||
412 | static struct attribute *ad7992_event_attributes[] = { | |
322c9563 JC |
413 | &iio_dev_attr_in_voltage0_thresh_low_value.dev_attr.attr, |
414 | &iio_dev_attr_in_voltage0_thresh_high_value.dev_attr.attr, | |
415 | &iio_dev_attr_in_voltage0_thresh_both_hyst_raw.dev_attr.attr, | |
416 | &iio_dev_attr_in_voltage1_thresh_low_value.dev_attr.attr, | |
417 | &iio_dev_attr_in_voltage1_thresh_high_value.dev_attr.attr, | |
418 | &iio_dev_attr_in_voltage1_thresh_both_hyst_raw.dev_attr.attr, | |
985dbe77 MH |
419 | &iio_dev_attr_sampling_frequency.dev_attr.attr, |
420 | &iio_const_attr_sampling_frequency_available.dev_attr.attr, | |
421 | NULL, | |
422 | }; | |
423 | ||
424 | static struct attribute_group ad7992_event_attrs_group = { | |
425 | .attrs = ad7992_event_attributes, | |
8e7d9672 | 426 | .name = "events", |
985dbe77 MH |
427 | }; |
428 | ||
6fe8135f JC |
429 | static const struct iio_info ad7991_info = { |
430 | .read_raw = &ad799x_read_raw, | |
431 | .driver_module = THIS_MODULE, | |
432 | }; | |
433 | ||
434 | static const struct iio_info ad7992_info = { | |
435 | .read_raw = &ad799x_read_raw, | |
6fe8135f JC |
436 | .event_attrs = &ad7992_event_attrs_group, |
437 | .driver_module = THIS_MODULE, | |
438 | }; | |
439 | ||
440 | static const struct iio_info ad7993_4_7_8_info = { | |
441 | .read_raw = &ad799x_read_raw, | |
6fe8135f JC |
442 | .event_attrs = &ad7993_4_7_8_event_attrs_group, |
443 | .driver_module = THIS_MODULE, | |
444 | }; | |
445 | ||
985dbe77 MH |
446 | static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { |
447 | [ad7991] = { | |
7c626f58 JC |
448 | .channel = { |
449 | [0] = { | |
450 | .type = IIO_VOLTAGE, | |
451 | .indexed = 1, | |
452 | .channel = 0, | |
453 | .address = 0, | |
454 | .scan_index = 0, | |
455 | .scan_type = IIO_ST('u', 12, 16, 0), | |
456 | }, | |
457 | [1] = { | |
458 | .type = IIO_VOLTAGE, | |
459 | .indexed = 1, | |
460 | .channel = 1, | |
461 | .address = 1, | |
462 | .scan_index = 1, | |
463 | .scan_type = IIO_ST('u', 12, 16, 0), | |
464 | }, | |
465 | [2] = { | |
466 | .type = IIO_VOLTAGE, | |
467 | .indexed = 1, | |
468 | .channel = 2, | |
469 | .address = 2, | |
470 | .scan_index = 2, | |
471 | .scan_type = IIO_ST('u', 12, 16, 0), | |
472 | }, | |
473 | [3] = { | |
474 | .type = IIO_VOLTAGE, | |
475 | .indexed = 1, | |
476 | .channel = 3, | |
477 | .address = 3, | |
478 | .scan_index = 3, | |
479 | .scan_type = IIO_ST('u', 12, 16, 0), | |
480 | }, | |
481 | [4] = IIO_CHAN_SOFT_TIMESTAMP(4), | |
482 | }, | |
d22fd9c5 | 483 | .num_channels = 5, |
985dbe77 | 484 | .int_vref_mv = 4096, |
6fe8135f | 485 | .info = &ad7991_info, |
985dbe77 MH |
486 | }, |
487 | [ad7995] = { | |
7c626f58 JC |
488 | .channel = { |
489 | [0] = { | |
490 | .type = IIO_VOLTAGE, | |
491 | .indexed = 1, | |
492 | .channel = 0, | |
493 | .address = 0, | |
494 | .scan_index = 0, | |
495 | .scan_type = IIO_ST('u', 10, 16, 2), | |
496 | }, | |
497 | [1] = { | |
498 | .type = IIO_VOLTAGE, | |
499 | .indexed = 1, | |
500 | .channel = 1, | |
501 | .address = 1, | |
502 | .scan_index = 1, | |
503 | .scan_type = IIO_ST('u', 10, 16, 2), | |
504 | }, | |
505 | [2] = { | |
506 | .type = IIO_VOLTAGE, | |
507 | .indexed = 1, | |
508 | .channel = 2, | |
509 | .address = 2, | |
510 | .scan_index = 2, | |
511 | .scan_type = IIO_ST('u', 10, 16, 2), | |
512 | }, | |
513 | [3] = { | |
514 | .type = IIO_VOLTAGE, | |
515 | .indexed = 1, | |
516 | .channel = 3, | |
517 | .address = 3, | |
518 | .scan_index = 3, | |
519 | .scan_type = IIO_ST('u', 10, 16, 2), | |
520 | }, | |
521 | [4] = IIO_CHAN_SOFT_TIMESTAMP(4), | |
522 | }, | |
d22fd9c5 | 523 | .num_channels = 5, |
985dbe77 | 524 | .int_vref_mv = 1024, |
6fe8135f | 525 | .info = &ad7991_info, |
985dbe77 MH |
526 | }, |
527 | [ad7999] = { | |
7c626f58 JC |
528 | .channel = { |
529 | [0] = { | |
530 | .type = IIO_VOLTAGE, | |
531 | .indexed = 1, | |
532 | .channel = 0, | |
533 | .address = 0, | |
534 | .scan_index = 0, | |
535 | .scan_type = IIO_ST('u', 8, 16, 4), | |
536 | }, | |
537 | [1] = { | |
538 | .type = IIO_VOLTAGE, | |
539 | .indexed = 1, | |
540 | .channel = 1, | |
541 | .address = 1, | |
542 | .scan_index = 1, | |
543 | .scan_type = IIO_ST('u', 8, 16, 4), | |
544 | }, | |
545 | [2] = { | |
546 | .type = IIO_VOLTAGE, | |
547 | .indexed = 1, | |
548 | .channel = 2, | |
549 | .address = 2, | |
550 | .scan_index = 2, | |
551 | .scan_type = IIO_ST('u', 8, 16, 4), | |
552 | }, | |
553 | [3] = { | |
554 | .type = IIO_VOLTAGE, | |
555 | .indexed = 1, | |
556 | .channel = 3, | |
557 | .address = 3, | |
558 | .scan_index = 3, | |
559 | .scan_type = IIO_ST('u', 8, 16, 4), | |
560 | }, | |
561 | [4] = IIO_CHAN_SOFT_TIMESTAMP(4), | |
562 | }, | |
d22fd9c5 | 563 | .num_channels = 5, |
985dbe77 | 564 | .int_vref_mv = 1024, |
6fe8135f | 565 | .info = &ad7991_info, |
985dbe77 MH |
566 | }, |
567 | [ad7992] = { | |
7c626f58 JC |
568 | .channel = { |
569 | [0] = { | |
570 | .type = IIO_VOLTAGE, | |
571 | .indexed = 1, | |
572 | .channel = 0, | |
573 | .address = 0, | |
574 | .scan_index = 0, | |
575 | .scan_type = IIO_ST('u', 12, 16, 0), | |
576 | }, | |
577 | [1] = { | |
578 | .type = IIO_VOLTAGE, | |
579 | .indexed = 1, | |
580 | .channel = 1, | |
581 | .address = 1, | |
582 | .scan_index = 1, | |
583 | .scan_type = IIO_ST('u', 12, 16, 0), | |
584 | }, | |
585 | [2] = IIO_CHAN_SOFT_TIMESTAMP(2), | |
586 | }, | |
d22fd9c5 | 587 | .num_channels = 3, |
985dbe77 | 588 | .int_vref_mv = 4096, |
985dbe77 | 589 | .default_config = AD7998_ALERT_EN, |
6fe8135f | 590 | .info = &ad7992_info, |
985dbe77 MH |
591 | }, |
592 | [ad7993] = { | |
7c626f58 JC |
593 | .channel = { |
594 | [0] = { | |
595 | .type = IIO_VOLTAGE, | |
596 | .indexed = 1, | |
597 | .channel = 0, | |
598 | .address = 0, | |
599 | .scan_index = 0, | |
600 | .scan_type = IIO_ST('u', 10, 16, 2), | |
601 | }, | |
602 | [1] = { | |
603 | .type = IIO_VOLTAGE, | |
604 | .indexed = 1, | |
605 | .channel = 1, | |
606 | .address = 1, | |
607 | .scan_index = 1, | |
608 | .scan_type = IIO_ST('u', 10, 16, 2), | |
609 | }, | |
610 | [2] = { | |
611 | .type = IIO_VOLTAGE, | |
612 | .indexed = 1, | |
613 | .channel = 2, | |
614 | .address = 2, | |
615 | .scan_index = 2, | |
616 | .scan_type = IIO_ST('u', 10, 16, 2), | |
617 | }, | |
618 | [3] = { | |
619 | .type = IIO_VOLTAGE, | |
620 | .indexed = 1, | |
621 | .channel = 3, | |
622 | .address = 3, | |
623 | .scan_index = 3, | |
624 | .scan_type = IIO_ST('u', 10, 16, 2), | |
625 | }, | |
626 | [4] = IIO_CHAN_SOFT_TIMESTAMP(4), | |
627 | }, | |
d22fd9c5 | 628 | .num_channels = 5, |
985dbe77 | 629 | .int_vref_mv = 1024, |
985dbe77 | 630 | .default_config = AD7998_ALERT_EN, |
6fe8135f | 631 | .info = &ad7993_4_7_8_info, |
985dbe77 MH |
632 | }, |
633 | [ad7994] = { | |
7c626f58 JC |
634 | .channel = { |
635 | [0] = { | |
636 | .type = IIO_VOLTAGE, | |
637 | .indexed = 1, | |
638 | .channel = 0, | |
639 | .address = 0, | |
640 | .scan_index = 0, | |
641 | .scan_type = IIO_ST('u', 12, 16, 0), | |
642 | }, | |
643 | [1] = { | |
644 | .type = IIO_VOLTAGE, | |
645 | .indexed = 1, | |
646 | .channel = 1, | |
647 | .address = 1, | |
648 | .scan_index = 1, | |
649 | .scan_type = IIO_ST('u', 12, 16, 0), | |
650 | }, | |
651 | [2] = { | |
652 | .type = IIO_VOLTAGE, | |
653 | .indexed = 1, | |
654 | .channel = 2, | |
655 | .address = 2, | |
656 | .scan_index = 2, | |
657 | .scan_type = IIO_ST('u', 12, 16, 0), | |
658 | }, | |
659 | [3] = { | |
660 | .type = IIO_VOLTAGE, | |
661 | .indexed = 1, | |
662 | .channel = 3, | |
663 | .address = 3, | |
664 | .scan_index = 3, | |
665 | .scan_type = IIO_ST('u', 12, 16, 0), | |
666 | }, | |
667 | [4] = IIO_CHAN_SOFT_TIMESTAMP(4), | |
668 | }, | |
d22fd9c5 | 669 | .num_channels = 5, |
985dbe77 | 670 | .int_vref_mv = 4096, |
985dbe77 | 671 | .default_config = AD7998_ALERT_EN, |
6fe8135f | 672 | .info = &ad7993_4_7_8_info, |
985dbe77 MH |
673 | }, |
674 | [ad7997] = { | |
7c626f58 JC |
675 | .channel = { |
676 | [0] = { | |
677 | .type = IIO_VOLTAGE, | |
678 | .indexed = 1, | |
679 | .channel = 0, | |
680 | .address = 0, | |
681 | .scan_index = 0, | |
682 | .scan_type = IIO_ST('u', 10, 16, 2), | |
683 | }, | |
684 | [1] = { | |
685 | .type = IIO_VOLTAGE, | |
686 | .indexed = 1, | |
687 | .channel = 1, | |
688 | .address = 1, | |
689 | .scan_index = 1, | |
690 | .scan_type = IIO_ST('u', 10, 16, 2), | |
691 | }, | |
692 | [2] = { | |
693 | .type = IIO_VOLTAGE, | |
694 | .indexed = 1, | |
695 | .channel = 2, | |
696 | .address = 2, | |
697 | .scan_index = 2, | |
698 | .scan_type = IIO_ST('u', 10, 16, 2), | |
699 | }, | |
700 | [3] = { | |
701 | .type = IIO_VOLTAGE, | |
702 | .indexed = 1, | |
703 | .channel = 3, | |
704 | .address = 3, | |
705 | .scan_index = 3, | |
706 | .scan_type = IIO_ST('u', 10, 16, 2), | |
707 | }, | |
708 | [4] = { | |
709 | .type = IIO_VOLTAGE, | |
710 | .indexed = 1, | |
711 | .channel = 4, | |
712 | .address = 4, | |
713 | .scan_index = 4, | |
714 | .scan_type = IIO_ST('u', 10, 16, 2), | |
715 | }, | |
716 | [5] = { | |
717 | .type = IIO_VOLTAGE, | |
718 | .indexed = 1, | |
719 | .channel = 5, | |
720 | .address = 5, | |
721 | .scan_index = 5, | |
722 | .scan_type = IIO_ST('u', 10, 16, 2), | |
723 | }, | |
724 | [6] = { | |
725 | .type = IIO_VOLTAGE, | |
726 | .indexed = 1, | |
727 | .channel = 6, | |
728 | .address = 6, | |
729 | .scan_index = 6, | |
730 | .scan_type = IIO_ST('u', 10, 16, 2), | |
731 | }, | |
732 | [7] = { | |
733 | .type = IIO_VOLTAGE, | |
734 | .indexed = 1, | |
735 | .channel = 7, | |
736 | .address = 7, | |
737 | .scan_index = 7, | |
738 | .scan_type = IIO_ST('u', 10, 16, 2), | |
739 | }, | |
740 | [8] = IIO_CHAN_SOFT_TIMESTAMP(8), | |
741 | }, | |
d22fd9c5 | 742 | .num_channels = 9, |
985dbe77 | 743 | .int_vref_mv = 1024, |
985dbe77 | 744 | .default_config = AD7998_ALERT_EN, |
6fe8135f | 745 | .info = &ad7993_4_7_8_info, |
985dbe77 MH |
746 | }, |
747 | [ad7998] = { | |
7c626f58 JC |
748 | .channel = { |
749 | [0] = { | |
750 | .type = IIO_VOLTAGE, | |
751 | .indexed = 1, | |
752 | .channel = 0, | |
753 | .address = 0, | |
754 | .scan_index = 0, | |
755 | .scan_type = IIO_ST('u', 12, 16, 0), | |
756 | }, | |
757 | [1] = { | |
758 | .type = IIO_VOLTAGE, | |
759 | .indexed = 1, | |
760 | .channel = 1, | |
761 | .address = 1, | |
762 | .scan_index = 1, | |
763 | .scan_type = IIO_ST('u', 12, 16, 0), | |
764 | }, | |
765 | [2] = { | |
766 | .type = IIO_VOLTAGE, | |
767 | .indexed = 1, | |
768 | .channel = 2, | |
769 | .address = 2, | |
770 | .scan_index = 2, | |
771 | .scan_type = IIO_ST('u', 12, 16, 0), | |
772 | }, | |
773 | [3] = { | |
774 | .type = IIO_VOLTAGE, | |
775 | .indexed = 1, | |
776 | .channel = 3, | |
777 | .address = 3, | |
778 | .scan_index = 3, | |
779 | .scan_type = IIO_ST('u', 12, 16, 0), | |
780 | }, | |
781 | [4] = { | |
782 | .type = IIO_VOLTAGE, | |
783 | .indexed = 1, | |
784 | .channel = 4, | |
785 | .address = 4, | |
786 | .scan_index = 4, | |
787 | .scan_type = IIO_ST('u', 12, 16, 0), | |
788 | }, | |
789 | [5] = { | |
790 | .type = IIO_VOLTAGE, | |
791 | .indexed = 1, | |
792 | .channel = 5, | |
793 | .address = 5, | |
794 | .scan_index = 5, | |
795 | .scan_type = IIO_ST('u', 12, 16, 0), | |
796 | }, | |
797 | [6] = { | |
798 | .type = IIO_VOLTAGE, | |
799 | .indexed = 1, | |
800 | .channel = 6, | |
801 | .address = 6, | |
802 | .scan_index = 6, | |
803 | .scan_type = IIO_ST('u', 12, 16, 0), | |
804 | }, | |
805 | [7] = { | |
806 | .type = IIO_VOLTAGE, | |
807 | .indexed = 1, | |
808 | .channel = 7, | |
809 | .address = 7, | |
810 | .scan_index = 7, | |
811 | .scan_type = IIO_ST('u', 12, 16, 0), | |
812 | }, | |
813 | [8] = IIO_CHAN_SOFT_TIMESTAMP(8), | |
814 | }, | |
d22fd9c5 | 815 | .num_channels = 9, |
985dbe77 | 816 | .int_vref_mv = 4096, |
985dbe77 | 817 | .default_config = AD7998_ALERT_EN, |
6fe8135f | 818 | .info = &ad7993_4_7_8_info, |
985dbe77 MH |
819 | }, |
820 | }; | |
821 | ||
822 | static int __devinit ad799x_probe(struct i2c_client *client, | |
823 | const struct i2c_device_id *id) | |
824 | { | |
26d25ae3 | 825 | int ret; |
985dbe77 | 826 | struct ad799x_platform_data *pdata = client->dev.platform_data; |
1bf7ac76 MH |
827 | struct ad799x_state *st; |
828 | struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st)); | |
829 | ||
830 | if (indio_dev == NULL) | |
831 | return -ENOMEM; | |
985dbe77 | 832 | |
1bf7ac76 | 833 | st = iio_priv(indio_dev); |
985dbe77 | 834 | /* this is only used for device removal purposes */ |
1bf7ac76 | 835 | i2c_set_clientdata(client, indio_dev); |
985dbe77 | 836 | |
985dbe77 MH |
837 | st->id = id->driver_data; |
838 | st->chip_info = &ad799x_chip_info_tbl[st->id]; | |
839 | st->config = st->chip_info->default_config; | |
840 | ||
841 | /* TODO: Add pdata options for filtering and bit delay */ | |
842 | ||
843 | if (pdata) | |
844 | st->int_vref_mv = pdata->vref_mv; | |
845 | else | |
846 | st->int_vref_mv = st->chip_info->int_vref_mv; | |
847 | ||
848 | st->reg = regulator_get(&client->dev, "vcc"); | |
849 | if (!IS_ERR(st->reg)) { | |
850 | ret = regulator_enable(st->reg); | |
851 | if (ret) | |
852 | goto error_put_reg; | |
853 | } | |
854 | st->client = client; | |
855 | ||
1bf7ac76 MH |
856 | indio_dev->dev.parent = &client->dev; |
857 | indio_dev->name = id->name; | |
6fe8135f | 858 | indio_dev->info = st->chip_info->info; |
1bf7ac76 | 859 | indio_dev->name = id->name; |
6fe8135f | 860 | |
1bf7ac76 | 861 | indio_dev->modes = INDIO_DIRECT_MODE; |
1bf7ac76 MH |
862 | indio_dev->channels = st->chip_info->channel; |
863 | indio_dev->num_channels = st->chip_info->num_channels; | |
1bf7ac76 MH |
864 | |
865 | ret = ad799x_register_ring_funcs_and_init(indio_dev); | |
985dbe77 | 866 | if (ret) |
1bf7ac76 | 867 | goto error_disable_reg; |
985dbe77 | 868 | |
14555b14 JC |
869 | ret = iio_buffer_register(indio_dev, |
870 | indio_dev->channels, | |
871 | indio_dev->num_channels); | |
985dbe77 MH |
872 | if (ret) |
873 | goto error_cleanup_ring; | |
874 | ||
6fe8135f | 875 | if (client->irq > 0) { |
72148f6e JC |
876 | ret = request_threaded_irq(client->irq, |
877 | NULL, | |
878 | ad799x_event_handler, | |
879 | IRQF_TRIGGER_FALLING | | |
880 | IRQF_ONESHOT, | |
881 | client->name, | |
1bf7ac76 | 882 | indio_dev); |
985dbe77 MH |
883 | if (ret) |
884 | goto error_cleanup_ring; | |
985dbe77 | 885 | } |
26d25ae3 JC |
886 | ret = iio_device_register(indio_dev); |
887 | if (ret) | |
888 | goto error_free_irq; | |
985dbe77 MH |
889 | |
890 | return 0; | |
1bf7ac76 | 891 | |
26d25ae3 JC |
892 | error_free_irq: |
893 | free_irq(client->irq, indio_dev); | |
985dbe77 | 894 | error_cleanup_ring: |
1bf7ac76 | 895 | ad799x_ring_cleanup(indio_dev); |
985dbe77 MH |
896 | error_disable_reg: |
897 | if (!IS_ERR(st->reg)) | |
898 | regulator_disable(st->reg); | |
899 | error_put_reg: | |
900 | if (!IS_ERR(st->reg)) | |
901 | regulator_put(st->reg); | |
26d25ae3 | 902 | iio_free_device(indio_dev); |
1bf7ac76 | 903 | |
985dbe77 MH |
904 | return ret; |
905 | } | |
906 | ||
907 | static __devexit int ad799x_remove(struct i2c_client *client) | |
908 | { | |
1bf7ac76 MH |
909 | struct iio_dev *indio_dev = i2c_get_clientdata(client); |
910 | struct ad799x_state *st = iio_priv(indio_dev); | |
985dbe77 | 911 | |
6fe8135f | 912 | if (client->irq > 0) |
72148f6e | 913 | free_irq(client->irq, indio_dev); |
985dbe77 | 914 | |
14555b14 | 915 | iio_buffer_unregister(indio_dev); |
985dbe77 | 916 | ad799x_ring_cleanup(indio_dev); |
985dbe77 MH |
917 | if (!IS_ERR(st->reg)) { |
918 | regulator_disable(st->reg); | |
919 | regulator_put(st->reg); | |
920 | } | |
1bf7ac76 | 921 | iio_device_unregister(indio_dev); |
985dbe77 MH |
922 | |
923 | return 0; | |
924 | } | |
925 | ||
926 | static const struct i2c_device_id ad799x_id[] = { | |
927 | { "ad7991", ad7991 }, | |
928 | { "ad7995", ad7995 }, | |
929 | { "ad7999", ad7999 }, | |
930 | { "ad7992", ad7992 }, | |
931 | { "ad7993", ad7993 }, | |
932 | { "ad7994", ad7994 }, | |
933 | { "ad7997", ad7997 }, | |
934 | { "ad7998", ad7998 }, | |
935 | {} | |
936 | }; | |
937 | ||
938 | MODULE_DEVICE_TABLE(i2c, ad799x_id); | |
939 | ||
940 | static struct i2c_driver ad799x_driver = { | |
941 | .driver = { | |
942 | .name = "ad799x", | |
943 | }, | |
944 | .probe = ad799x_probe, | |
945 | .remove = __devexit_p(ad799x_remove), | |
946 | .id_table = ad799x_id, | |
947 | }; | |
948 | ||
949 | static __init int ad799x_init(void) | |
950 | { | |
951 | return i2c_add_driver(&ad799x_driver); | |
952 | } | |
953 | ||
954 | static __exit void ad799x_exit(void) | |
955 | { | |
956 | i2c_del_driver(&ad799x_driver); | |
957 | } | |
958 | ||
959 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | |
960 | MODULE_DESCRIPTION("Analog Devices AD799x ADC"); | |
961 | MODULE_LICENSE("GPL v2"); | |
962 | MODULE_ALIAS("i2c:ad799x"); | |
963 | ||
964 | module_init(ad799x_init); | |
965 | module_exit(ad799x_exit); |