Commit | Line | Data |
---|---|---|
ddaecd5b | 1 | /* |
f22c1cf0 | 2 | * AD7291 8-Channel, I2C, 12-Bit SAR ADC with Temperature Sensor |
ddaecd5b | 3 | * |
f22c1cf0 | 4 | * Copyright 2010-2011 Analog Devices Inc. |
ddaecd5b SZ |
5 | * |
6 | * Licensed under the GPL-2 or later. | |
7 | */ | |
8 | ||
9 | #include <linux/interrupt.h> | |
ddaecd5b SZ |
10 | #include <linux/device.h> |
11 | #include <linux/kernel.h> | |
12 | #include <linux/slab.h> | |
13 | #include <linux/sysfs.h> | |
ddaecd5b | 14 | #include <linux/i2c.h> |
99c97852 | 15 | #include <linux/module.h> |
4fd24247 | 16 | #include <linux/mutex.h> |
3b424f33 MH |
17 | #include <linux/regulator/consumer.h> |
18 | #include <linux/err.h> | |
ddaecd5b | 19 | |
06458e27 JC |
20 | #include <linux/iio/iio.h> |
21 | #include <linux/iio/sysfs.h> | |
22 | #include <linux/iio/events.h> | |
ddaecd5b | 23 | |
1df9d1d4 LPC |
24 | #include "ad7291.h" |
25 | ||
4fd24247 JC |
26 | /* |
27 | * Simplified handling | |
28 | * | |
29 | * If no events enabled - single polled channel read | |
30 | * If event enabled direct reads disable unless channel | |
31 | * is in the read mask. | |
32 | * | |
33 | * The noise-delayed bit as per datasheet suggestion is always enabled. | |
34 | * | |
4fd24247 | 35 | */ |
3b424f33 | 36 | |
ddaecd5b SZ |
37 | /* |
38 | * AD7291 registers definition | |
39 | */ | |
81e2edbe MH |
40 | #define AD7291_COMMAND 0x00 |
41 | #define AD7291_VOLTAGE 0x01 | |
42 | #define AD7291_T_SENSE 0x02 | |
43 | #define AD7291_T_AVERAGE 0x03 | |
3f8db0d4 LPC |
44 | #define AD7291_DATA_HIGH(x) ((x) * 3 + 0x4) |
45 | #define AD7291_DATA_LOW(x) ((x) * 3 + 0x5) | |
46 | #define AD7291_HYST(x) ((x) * 3 + 0x6) | |
00feefbb | 47 | #define AD7291_VOLTAGE_ALERT_STATUS 0x1F |
ddaecd5b SZ |
48 | #define AD7291_T_ALERT_STATUS 0x20 |
49 | ||
81e2edbe MH |
50 | #define AD7291_VOLTAGE_LIMIT_COUNT 8 |
51 | ||
52 | ||
ddaecd5b SZ |
53 | /* |
54 | * AD7291 command | |
55 | */ | |
00feefbb MH |
56 | #define AD7291_AUTOCYCLE (1 << 0) |
57 | #define AD7291_RESET (1 << 1) | |
58 | #define AD7291_ALERT_CLEAR (1 << 2) | |
59 | #define AD7291_ALERT_POLARITY (1 << 3) | |
60 | #define AD7291_EXT_REF (1 << 4) | |
61 | #define AD7291_NOISE_DELAY (1 << 5) | |
62 | #define AD7291_T_SENSE_MASK (1 << 7) | |
63 | #define AD7291_VOLTAGE_MASK 0xFF00 | |
ddaecd5b SZ |
64 | #define AD7291_VOLTAGE_OFFSET 0x8 |
65 | ||
66 | /* | |
67 | * AD7291 value masks | |
68 | */ | |
00feefbb | 69 | #define AD7291_CHANNEL_MASK 0xF000 |
3b424f33 | 70 | #define AD7291_BITS 12 |
00feefbb | 71 | #define AD7291_VALUE_MASK 0xFFF |
ddaecd5b SZ |
72 | #define AD7291_T_VALUE_SIGN 0x400 |
73 | #define AD7291_T_VALUE_FLOAT_OFFSET 2 | |
74 | #define AD7291_T_VALUE_FLOAT_MASK 0x2 | |
75 | ||
3b424f33 MH |
76 | #define AD7291_BITS 12 |
77 | ||
ddaecd5b | 78 | struct ad7291_chip_info { |
3b424f33 MH |
79 | struct i2c_client *client; |
80 | struct regulator *reg; | |
3b424f33 | 81 | u16 command; |
06420c2d | 82 | u16 c_mask; /* Active voltage channels for events */ |
e68b1db1 | 83 | struct mutex state_lock; |
ddaecd5b SZ |
84 | }; |
85 | ||
ddaecd5b SZ |
86 | static int ad7291_i2c_read(struct ad7291_chip_info *chip, u8 reg, u16 *data) |
87 | { | |
88 | struct i2c_client *client = chip->client; | |
89 | int ret = 0; | |
90 | ||
7bd49fe1 | 91 | ret = i2c_smbus_read_word_swapped(client, reg); |
ddaecd5b SZ |
92 | if (ret < 0) { |
93 | dev_err(&client->dev, "I2C read error\n"); | |
94 | return ret; | |
95 | } | |
96 | ||
7bd49fe1 | 97 | *data = ret; |
ddaecd5b SZ |
98 | |
99 | return 0; | |
100 | } | |
101 | ||
102 | static int ad7291_i2c_write(struct ad7291_chip_info *chip, u8 reg, u16 data) | |
103 | { | |
7bd49fe1 | 104 | return i2c_smbus_write_word_swapped(chip->client, reg, data); |
ddaecd5b SZ |
105 | } |
106 | ||
58c0323c | 107 | static irqreturn_t ad7291_event_handler(int irq, void *private) |
ddaecd5b | 108 | { |
58c0323c | 109 | struct iio_dev *indio_dev = private; |
d4397972 | 110 | struct ad7291_chip_info *chip = iio_priv(private); |
ddaecd5b SZ |
111 | u16 t_status, v_status; |
112 | u16 command; | |
113 | int i; | |
58c0323c | 114 | s64 timestamp = iio_get_time_ns(); |
ddaecd5b SZ |
115 | |
116 | if (ad7291_i2c_read(chip, AD7291_T_ALERT_STATUS, &t_status)) | |
58c0323c | 117 | return IRQ_HANDLED; |
ddaecd5b SZ |
118 | |
119 | if (ad7291_i2c_read(chip, AD7291_VOLTAGE_ALERT_STATUS, &v_status)) | |
58c0323c | 120 | return IRQ_HANDLED; |
ddaecd5b SZ |
121 | |
122 | if (!(t_status || v_status)) | |
58c0323c | 123 | return IRQ_HANDLED; |
ddaecd5b | 124 | |
f22c1cf0 | 125 | command = chip->command | AD7291_ALERT_CLEAR; |
ddaecd5b SZ |
126 | ad7291_i2c_write(chip, AD7291_COMMAND, command); |
127 | ||
f22c1cf0 | 128 | command = chip->command & ~AD7291_ALERT_CLEAR; |
ddaecd5b SZ |
129 | ad7291_i2c_write(chip, AD7291_COMMAND, command); |
130 | ||
4fd24247 JC |
131 | /* For now treat t_sense and t_sense_average the same */ |
132 | if ((t_status & (1 << 0)) || (t_status & (1 << 2))) | |
5aa96188 | 133 | iio_push_event(indio_dev, |
b206c3bb JC |
134 | IIO_UNMOD_EVENT_CODE(IIO_TEMP, |
135 | 0, | |
136 | IIO_EV_TYPE_THRESH, | |
137 | IIO_EV_DIR_FALLING), | |
138 | timestamp); | |
4fd24247 | 139 | if ((t_status & (1 << 1)) || (t_status & (1 << 3))) |
5aa96188 | 140 | iio_push_event(indio_dev, |
b206c3bb JC |
141 | IIO_UNMOD_EVENT_CODE(IIO_TEMP, |
142 | 0, | |
143 | IIO_EV_TYPE_THRESH, | |
144 | IIO_EV_DIR_RISING), | |
145 | timestamp); | |
146 | ||
147 | for (i = 0; i < AD7291_VOLTAGE_LIMIT_COUNT*2; i += 2) { | |
ddaecd5b | 148 | if (v_status & (1 << i)) |
5aa96188 | 149 | iio_push_event(indio_dev, |
6835cb6b | 150 | IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, |
b206c3bb JC |
151 | i/2, |
152 | IIO_EV_TYPE_THRESH, | |
153 | IIO_EV_DIR_FALLING), | |
154 | timestamp); | |
155 | if (v_status & (1 << (i + 1))) | |
5aa96188 | 156 | iio_push_event(indio_dev, |
6835cb6b | 157 | IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, |
b206c3bb JC |
158 | i/2, |
159 | IIO_EV_TYPE_THRESH, | |
160 | IIO_EV_DIR_RISING), | |
161 | timestamp); | |
ddaecd5b | 162 | } |
ddaecd5b | 163 | |
58c0323c | 164 | return IRQ_HANDLED; |
ddaecd5b SZ |
165 | } |
166 | ||
4fd24247 | 167 | static inline ssize_t ad7291_show_hyst(struct device *dev, |
ddaecd5b | 168 | struct device_attribute *attr, |
ddaecd5b SZ |
169 | char *buf) |
170 | { | |
62c51839 | 171 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); |
84f79ecb | 172 | struct ad7291_chip_info *chip = iio_priv(indio_dev); |
58c0323c | 173 | struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); |
ddaecd5b | 174 | u16 data; |
ddaecd5b SZ |
175 | int ret; |
176 | ||
58c0323c | 177 | ret = ad7291_i2c_read(chip, this_attr->address, &data); |
4fd24247 JC |
178 | if (ret < 0) |
179 | return ret; | |
ddaecd5b | 180 | |
81e2edbe | 181 | return sprintf(buf, "%d\n", data & AD7291_VALUE_MASK); |
ddaecd5b SZ |
182 | } |
183 | ||
4fd24247 JC |
184 | static inline ssize_t ad7291_set_hyst(struct device *dev, |
185 | struct device_attribute *attr, | |
186 | const char *buf, | |
187 | size_t len) | |
ddaecd5b | 188 | { |
62c51839 | 189 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); |
84f79ecb | 190 | struct ad7291_chip_info *chip = iio_priv(indio_dev); |
58c0323c | 191 | struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); |
ddaecd5b | 192 | u16 data; |
ddaecd5b SZ |
193 | int ret; |
194 | ||
4fd24247 | 195 | ret = kstrtou16(buf, 10, &data); |
ddaecd5b | 196 | |
4fd24247 JC |
197 | if (ret < 0) |
198 | return ret; | |
a3ef65d3 | 199 | if (data > AD7291_VALUE_MASK) |
ddaecd5b SZ |
200 | return -EINVAL; |
201 | ||
a3ef65d3 MH |
202 | ret = ad7291_i2c_write(chip, this_attr->address, data); |
203 | if (ret < 0) | |
204 | return ret; | |
205 | ||
206 | return len; | |
4fd24247 | 207 | } |
ddaecd5b | 208 | |
4fd24247 JC |
209 | static IIO_DEVICE_ATTR(in_temp0_thresh_both_hyst_raw, |
210 | S_IRUGO | S_IWUSR, | |
211 | ad7291_show_hyst, ad7291_set_hyst, | |
3f8db0d4 | 212 | AD7291_HYST(8)); |
4fd24247 JC |
213 | static IIO_DEVICE_ATTR(in_voltage0_thresh_both_hyst_raw, |
214 | S_IRUGO | S_IWUSR, | |
3f8db0d4 | 215 | ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(0)); |
4fd24247 JC |
216 | static IIO_DEVICE_ATTR(in_voltage1_thresh_both_hyst_raw, |
217 | S_IRUGO | S_IWUSR, | |
3f8db0d4 | 218 | ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(1)); |
4fd24247 JC |
219 | static IIO_DEVICE_ATTR(in_voltage2_thresh_both_hyst_raw, |
220 | S_IRUGO | S_IWUSR, | |
3f8db0d4 | 221 | ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(2)); |
4fd24247 JC |
222 | static IIO_DEVICE_ATTR(in_voltage3_thresh_both_hyst_raw, |
223 | S_IRUGO | S_IWUSR, | |
3f8db0d4 | 224 | ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(3)); |
4fd24247 JC |
225 | static IIO_DEVICE_ATTR(in_voltage4_thresh_both_hyst_raw, |
226 | S_IRUGO | S_IWUSR, | |
3f8db0d4 | 227 | ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(4)); |
4fd24247 JC |
228 | static IIO_DEVICE_ATTR(in_voltage5_thresh_both_hyst_raw, |
229 | S_IRUGO | S_IWUSR, | |
3f8db0d4 | 230 | ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(5)); |
4fd24247 JC |
231 | static IIO_DEVICE_ATTR(in_voltage6_thresh_both_hyst_raw, |
232 | S_IRUGO | S_IWUSR, | |
3f8db0d4 | 233 | ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(6)); |
4fd24247 JC |
234 | static IIO_DEVICE_ATTR(in_voltage7_thresh_both_hyst_raw, |
235 | S_IRUGO | S_IWUSR, | |
3f8db0d4 | 236 | ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(7)); |
ddaecd5b | 237 | |
4fd24247 JC |
238 | static struct attribute *ad7291_event_attributes[] = { |
239 | &iio_dev_attr_in_temp0_thresh_both_hyst_raw.dev_attr.attr, | |
240 | &iio_dev_attr_in_voltage0_thresh_both_hyst_raw.dev_attr.attr, | |
241 | &iio_dev_attr_in_voltage1_thresh_both_hyst_raw.dev_attr.attr, | |
242 | &iio_dev_attr_in_voltage2_thresh_both_hyst_raw.dev_attr.attr, | |
243 | &iio_dev_attr_in_voltage3_thresh_both_hyst_raw.dev_attr.attr, | |
244 | &iio_dev_attr_in_voltage4_thresh_both_hyst_raw.dev_attr.attr, | |
245 | &iio_dev_attr_in_voltage5_thresh_both_hyst_raw.dev_attr.attr, | |
246 | &iio_dev_attr_in_voltage6_thresh_both_hyst_raw.dev_attr.attr, | |
247 | &iio_dev_attr_in_voltage7_thresh_both_hyst_raw.dev_attr.attr, | |
248 | NULL, | |
249 | }; | |
ddaecd5b | 250 | |
3f8db0d4 LPC |
251 | static unsigned int ad7291_threshold_reg(u64 event_code) |
252 | { | |
253 | unsigned int offset; | |
254 | ||
255 | switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) { | |
256 | case IIO_VOLTAGE: | |
257 | offset = IIO_EVENT_CODE_EXTRACT_CHAN(event_code); | |
258 | break; | |
259 | case IIO_TEMP: | |
260 | offset = 8; | |
261 | break; | |
262 | default: | |
263 | return 0; | |
264 | } | |
265 | ||
266 | if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_FALLING) | |
267 | return AD7291_DATA_LOW(offset); | |
268 | else | |
269 | return AD7291_DATA_HIGH(offset); | |
270 | } | |
ddaecd5b | 271 | |
4fd24247 JC |
272 | static int ad7291_read_event_value(struct iio_dev *indio_dev, |
273 | u64 event_code, | |
274 | int *val) | |
ddaecd5b | 275 | { |
4fd24247 | 276 | struct ad7291_chip_info *chip = iio_priv(indio_dev); |
4fd24247 | 277 | int ret; |
4fd24247 | 278 | u16 uval; |
4fd24247 | 279 | |
3f8db0d4 LPC |
280 | ret = ad7291_i2c_read(chip, ad7291_threshold_reg(event_code), &uval); |
281 | if (ret < 0) | |
282 | return ret; | |
283 | ||
b576590d | 284 | switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) { |
4fd24247 | 285 | case IIO_VOLTAGE: |
81e2edbe | 286 | *val = uval & AD7291_VALUE_MASK; |
4fd24247 | 287 | return 0; |
4fd24247 | 288 | case IIO_TEMP: |
88198d2b | 289 | *val = sign_extend32(uval, 11); |
4fd24247 JC |
290 | return 0; |
291 | default: | |
ddaecd5b | 292 | return -EINVAL; |
4fd24247 JC |
293 | }; |
294 | } | |
ddaecd5b | 295 | |
4fd24247 JC |
296 | static int ad7291_write_event_value(struct iio_dev *indio_dev, |
297 | u64 event_code, | |
298 | int val) | |
299 | { | |
300 | struct ad7291_chip_info *chip = iio_priv(indio_dev); | |
4fd24247 | 301 | |
b576590d | 302 | switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) { |
4fd24247 | 303 | case IIO_VOLTAGE: |
a3ef65d3 | 304 | if (val > AD7291_VALUE_MASK || val < 0) |
4fd24247 | 305 | return -EINVAL; |
3f8db0d4 | 306 | break; |
4fd24247 JC |
307 | case IIO_TEMP: |
308 | if (val > 2047 || val < -2048) | |
309 | return -EINVAL; | |
3f8db0d4 | 310 | break; |
4fd24247 JC |
311 | default: |
312 | return -EINVAL; | |
3f8db0d4 LPC |
313 | } |
314 | ||
315 | return ad7291_i2c_write(chip, ad7291_threshold_reg(event_code), val); | |
ddaecd5b SZ |
316 | } |
317 | ||
4fd24247 JC |
318 | static int ad7291_read_event_config(struct iio_dev *indio_dev, |
319 | u64 event_code) | |
ddaecd5b | 320 | { |
4fd24247 JC |
321 | struct ad7291_chip_info *chip = iio_priv(indio_dev); |
322 | /* To be enabled the channel must simply be on. If any are enabled | |
323 | we are in continuous sampling mode */ | |
324 | ||
b576590d | 325 | switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) { |
4fd24247 JC |
326 | case IIO_VOLTAGE: |
327 | if (chip->c_mask & | |
da367160 | 328 | (1 << (15 - IIO_EVENT_CODE_EXTRACT_CHAN(event_code)))) |
4fd24247 JC |
329 | return 1; |
330 | else | |
331 | return 0; | |
332 | case IIO_TEMP: | |
333 | /* always on */ | |
334 | return 1; | |
335 | default: | |
ddaecd5b | 336 | return -EINVAL; |
4fd24247 | 337 | } |
ddaecd5b | 338 | |
4fd24247 | 339 | } |
ddaecd5b | 340 | |
4fd24247 JC |
341 | static int ad7291_write_event_config(struct iio_dev *indio_dev, |
342 | u64 event_code, | |
343 | int state) | |
344 | { | |
345 | int ret = 0; | |
346 | struct ad7291_chip_info *chip = iio_priv(indio_dev); | |
347 | u16 regval; | |
348 | ||
349 | mutex_lock(&chip->state_lock); | |
350 | regval = chip->command; | |
351 | /* | |
352 | * To be enabled the channel must simply be on. If any are enabled | |
353 | * use continuous sampling mode. | |
354 | * Possible to disable temp as well but that makes single read tricky. | |
355 | */ | |
81e2edbe | 356 | |
4fd24247 JC |
357 | switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) { |
358 | case IIO_VOLTAGE: | |
06420c2d | 359 | if ((!state) && (chip->c_mask & (1 << (15 - |
da367160 LPC |
360 | IIO_EVENT_CODE_EXTRACT_CHAN(event_code))))) |
361 | chip->c_mask &= ~(1 << (15 - IIO_EVENT_CODE_EXTRACT_CHAN | |
06420c2d MH |
362 | (event_code))); |
363 | else if (state && (!(chip->c_mask & (1 << (15 - | |
da367160 LPC |
364 | IIO_EVENT_CODE_EXTRACT_CHAN(event_code)))))) |
365 | chip->c_mask |= (1 << (15 - IIO_EVENT_CODE_EXTRACT_CHAN | |
06420c2d | 366 | (event_code))); |
4fd24247 JC |
367 | else |
368 | break; | |
369 | ||
81e2edbe | 370 | regval &= ~AD7291_AUTOCYCLE; |
06420c2d | 371 | regval |= chip->c_mask; |
4fd24247 JC |
372 | if (chip->c_mask) /* Enable autocycle? */ |
373 | regval |= AD7291_AUTOCYCLE; | |
374 | ||
375 | ret = ad7291_i2c_write(chip, AD7291_COMMAND, regval); | |
376 | if (ret < 0) | |
377 | goto error_ret; | |
378 | ||
379 | chip->command = regval; | |
380 | break; | |
381 | default: | |
382 | ret = -EINVAL; | |
383 | } | |
ddaecd5b | 384 | |
4fd24247 JC |
385 | error_ret: |
386 | mutex_unlock(&chip->state_lock); | |
ddaecd5b SZ |
387 | return ret; |
388 | } | |
389 | ||
4fd24247 JC |
390 | static int ad7291_read_raw(struct iio_dev *indio_dev, |
391 | struct iio_chan_spec const *chan, | |
392 | int *val, | |
393 | int *val2, | |
394 | long mask) | |
395 | { | |
396 | int ret; | |
397 | struct ad7291_chip_info *chip = iio_priv(indio_dev); | |
398 | u16 regval; | |
4fd24247 JC |
399 | |
400 | switch (mask) { | |
b11f98ff | 401 | case IIO_CHAN_INFO_RAW: |
4fd24247 JC |
402 | switch (chan->type) { |
403 | case IIO_VOLTAGE: | |
404 | mutex_lock(&chip->state_lock); | |
405 | /* If in autocycle mode drop through */ | |
06420c2d | 406 | if (chip->command & AD7291_AUTOCYCLE) { |
4fd24247 JC |
407 | mutex_unlock(&chip->state_lock); |
408 | return -EBUSY; | |
409 | } | |
410 | /* Enable this channel alone */ | |
411 | regval = chip->command & (~AD7291_VOLTAGE_MASK); | |
e70ab218 | 412 | regval |= 1 << (15 - chan->channel); |
4fd24247 JC |
413 | ret = ad7291_i2c_write(chip, AD7291_COMMAND, regval); |
414 | if (ret < 0) { | |
415 | mutex_unlock(&chip->state_lock); | |
416 | return ret; | |
417 | } | |
418 | /* Read voltage */ | |
7bd49fe1 | 419 | ret = i2c_smbus_read_word_swapped(chip->client, |
4fd24247 JC |
420 | AD7291_VOLTAGE); |
421 | if (ret < 0) { | |
422 | mutex_unlock(&chip->state_lock); | |
423 | return ret; | |
424 | } | |
7bd49fe1 | 425 | *val = ret & AD7291_VALUE_MASK; |
4fd24247 JC |
426 | mutex_unlock(&chip->state_lock); |
427 | return IIO_VAL_INT; | |
428 | case IIO_TEMP: | |
429 | /* Assumes tsense bit of command register always set */ | |
7bd49fe1 | 430 | ret = i2c_smbus_read_word_swapped(chip->client, |
4fd24247 JC |
431 | AD7291_T_SENSE); |
432 | if (ret < 0) | |
433 | return ret; | |
88198d2b | 434 | *val = sign_extend32(ret, 11); |
4fd24247 JC |
435 | return IIO_VAL_INT; |
436 | default: | |
437 | return -EINVAL; | |
438 | } | |
c8a9f805 | 439 | case IIO_CHAN_INFO_AVERAGE_RAW: |
7bd49fe1 | 440 | ret = i2c_smbus_read_word_swapped(chip->client, |
4fd24247 JC |
441 | AD7291_T_AVERAGE); |
442 | if (ret < 0) | |
443 | return ret; | |
88198d2b | 444 | *val = sign_extend32(ret, 11); |
4fd24247 | 445 | return IIO_VAL_INT; |
c8a9f805 JC |
446 | case IIO_CHAN_INFO_SCALE: |
447 | switch (chan->type) { | |
448 | case IIO_VOLTAGE: | |
1df9d1d4 LPC |
449 | if (chip->reg) { |
450 | int vref; | |
451 | vref = regulator_get_voltage(chip->reg); | |
452 | if (vref < 0) | |
453 | return vref; | |
454 | *val = vref / 1000; | |
455 | } else { | |
456 | *val = 2500; | |
457 | } | |
73a4445f LPC |
458 | *val2 = AD7291_BITS; |
459 | return IIO_VAL_FRACTIONAL_LOG2; | |
c8a9f805 JC |
460 | case IIO_TEMP: |
461 | /* | |
462 | * One LSB of the ADC corresponds to 0.25 deg C. | |
463 | * The temperature reading is in 12-bit twos | |
464 | * complement format | |
465 | */ | |
466 | *val = 250; | |
467 | return IIO_VAL_INT; | |
468 | default: | |
469 | return -EINVAL; | |
470 | } | |
4fd24247 JC |
471 | default: |
472 | return -EINVAL; | |
473 | } | |
474 | } | |
ddaecd5b | 475 | |
4fd24247 JC |
476 | #define AD7291_VOLTAGE_CHAN(_chan) \ |
477 | { \ | |
478 | .type = IIO_VOLTAGE, \ | |
0325948a JC |
479 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ |
480 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ | |
4fd24247 JC |
481 | .indexed = 1, \ |
482 | .channel = _chan, \ | |
483 | .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING)|\ | |
484 | IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING) \ | |
485 | } | |
486 | ||
487 | static const struct iio_chan_spec ad7291_channels[] = { | |
488 | AD7291_VOLTAGE_CHAN(0), | |
489 | AD7291_VOLTAGE_CHAN(1), | |
490 | AD7291_VOLTAGE_CHAN(2), | |
491 | AD7291_VOLTAGE_CHAN(3), | |
492 | AD7291_VOLTAGE_CHAN(4), | |
493 | AD7291_VOLTAGE_CHAN(5), | |
494 | AD7291_VOLTAGE_CHAN(6), | |
495 | AD7291_VOLTAGE_CHAN(7), | |
496 | { | |
497 | .type = IIO_TEMP, | |
0325948a JC |
498 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | |
499 | BIT(IIO_CHAN_INFO_AVERAGE_RAW) | | |
500 | BIT(IIO_CHAN_INFO_SCALE), | |
4fd24247 JC |
501 | .indexed = 1, |
502 | .channel = 0, | |
503 | .event_mask = | |
504 | IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING)| | |
505 | IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING) | |
506 | } | |
ddaecd5b SZ |
507 | }; |
508 | ||
509 | static struct attribute_group ad7291_event_attribute_group = { | |
510 | .attrs = ad7291_event_attributes, | |
511 | }; | |
512 | ||
6fe8135f | 513 | static const struct iio_info ad7291_info = { |
4fd24247 JC |
514 | .read_raw = &ad7291_read_raw, |
515 | .read_event_config = &ad7291_read_event_config, | |
516 | .write_event_config = &ad7291_write_event_config, | |
517 | .read_event_value = &ad7291_read_event_value, | |
518 | .write_event_value = &ad7291_write_event_value, | |
6fe8135f | 519 | .event_attrs = &ad7291_event_attribute_group, |
bb377961 | 520 | .driver_module = THIS_MODULE, |
6fe8135f JC |
521 | }; |
522 | ||
4ae1c61f | 523 | static int ad7291_probe(struct i2c_client *client, |
ddaecd5b SZ |
524 | const struct i2c_device_id *id) |
525 | { | |
1df9d1d4 | 526 | struct ad7291_platform_data *pdata = client->dev.platform_data; |
ddaecd5b | 527 | struct ad7291_chip_info *chip; |
d4397972 | 528 | struct iio_dev *indio_dev; |
1df9d1d4 | 529 | int ret = 0; |
ddaecd5b | 530 | |
7cbb7537 | 531 | indio_dev = iio_device_alloc(sizeof(*chip)); |
d4397972 JC |
532 | if (indio_dev == NULL) { |
533 | ret = -ENOMEM; | |
534 | goto error_ret; | |
535 | } | |
03bda05d | 536 | chip = iio_priv(indio_dev); |
3b424f33 | 537 | |
1df9d1d4 LPC |
538 | if (pdata && pdata->use_external_ref) { |
539 | chip->reg = regulator_get(&client->dev, "vref"); | |
540 | if (IS_ERR(chip->reg)) | |
541 | goto error_free; | |
542 | ||
3b424f33 MH |
543 | ret = regulator_enable(chip->reg); |
544 | if (ret) | |
545 | goto error_put_reg; | |
3b424f33 MH |
546 | } |
547 | ||
4fd24247 | 548 | mutex_init(&chip->state_lock); |
ddaecd5b | 549 | /* this is only used for device removal purposes */ |
d4397972 | 550 | i2c_set_clientdata(client, indio_dev); |
ddaecd5b SZ |
551 | |
552 | chip->client = client; | |
c11f02ed MH |
553 | |
554 | chip->command = AD7291_NOISE_DELAY | | |
555 | AD7291_T_SENSE_MASK | /* Tsense always enabled */ | |
556 | AD7291_ALERT_POLARITY; /* set irq polarity low level */ | |
ddaecd5b | 557 | |
1df9d1d4 | 558 | if (pdata && pdata->use_external_ref) |
3b424f33 | 559 | chip->command |= AD7291_EXT_REF; |
3b424f33 | 560 | |
d4397972 | 561 | indio_dev->name = id->name; |
4fd24247 JC |
562 | indio_dev->channels = ad7291_channels; |
563 | indio_dev->num_channels = ARRAY_SIZE(ad7291_channels); | |
564 | ||
d4397972 JC |
565 | indio_dev->dev.parent = &client->dev; |
566 | indio_dev->info = &ad7291_info; | |
567 | indio_dev->modes = INDIO_DIRECT_MODE; | |
ddaecd5b | 568 | |
c11f02ed MH |
569 | ret = ad7291_i2c_write(chip, AD7291_COMMAND, AD7291_RESET); |
570 | if (ret) { | |
571 | ret = -EIO; | |
572 | goto error_disable_reg; | |
573 | } | |
574 | ||
575 | ret = ad7291_i2c_write(chip, AD7291_COMMAND, chip->command); | |
576 | if (ret) { | |
577 | ret = -EIO; | |
578 | goto error_disable_reg; | |
579 | } | |
580 | ||
ddaecd5b | 581 | if (client->irq > 0) { |
58c0323c JC |
582 | ret = request_threaded_irq(client->irq, |
583 | NULL, | |
584 | &ad7291_event_handler, | |
585 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, | |
845bd12a | 586 | id->name, |
d4397972 | 587 | indio_dev); |
ddaecd5b | 588 | if (ret) |
3b424f33 | 589 | goto error_disable_reg; |
ddaecd5b SZ |
590 | } |
591 | ||
26d25ae3 JC |
592 | ret = iio_device_register(indio_dev); |
593 | if (ret) | |
594 | goto error_unreg_irq; | |
595 | ||
ddaecd5b SZ |
596 | return 0; |
597 | ||
598 | error_unreg_irq: | |
4fd24247 JC |
599 | if (client->irq) |
600 | free_irq(client->irq, indio_dev); | |
3b424f33 | 601 | error_disable_reg: |
1df9d1d4 | 602 | if (chip->reg) |
3b424f33 MH |
603 | regulator_disable(chip->reg); |
604 | error_put_reg: | |
1df9d1d4 | 605 | if (chip->reg) |
3b424f33 | 606 | regulator_put(chip->reg); |
1df9d1d4 | 607 | error_free: |
7cbb7537 | 608 | iio_device_free(indio_dev); |
d4397972 | 609 | error_ret: |
ddaecd5b SZ |
610 | return ret; |
611 | } | |
612 | ||
447d4f29 | 613 | static int ad7291_remove(struct i2c_client *client) |
ddaecd5b | 614 | { |
d4397972 | 615 | struct iio_dev *indio_dev = i2c_get_clientdata(client); |
3b424f33 | 616 | struct ad7291_chip_info *chip = iio_priv(indio_dev); |
ddaecd5b | 617 | |
d2fffd6c JC |
618 | iio_device_unregister(indio_dev); |
619 | ||
ddaecd5b | 620 | if (client->irq) |
d4397972 | 621 | free_irq(client->irq, indio_dev); |
3b424f33 | 622 | |
1df9d1d4 | 623 | if (chip->reg) { |
3b424f33 MH |
624 | regulator_disable(chip->reg); |
625 | regulator_put(chip->reg); | |
626 | } | |
627 | ||
7cbb7537 | 628 | iio_device_free(indio_dev); |
ddaecd5b SZ |
629 | |
630 | return 0; | |
631 | } | |
632 | ||
633 | static const struct i2c_device_id ad7291_id[] = { | |
634 | { "ad7291", 0 }, | |
635 | {} | |
636 | }; | |
637 | ||
638 | MODULE_DEVICE_TABLE(i2c, ad7291_id); | |
639 | ||
640 | static struct i2c_driver ad7291_driver = { | |
641 | .driver = { | |
e68b1db1 | 642 | .name = KBUILD_MODNAME, |
ddaecd5b SZ |
643 | }, |
644 | .probe = ad7291_probe, | |
e543acf0 | 645 | .remove = ad7291_remove, |
ddaecd5b SZ |
646 | .id_table = ad7291_id, |
647 | }; | |
6e5af184 | 648 | module_i2c_driver(ad7291_driver); |
ddaecd5b SZ |
649 | |
650 | MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>"); | |
e68b1db1 | 651 | MODULE_DESCRIPTION("Analog Devices AD7291 ADC driver"); |
ddaecd5b | 652 | MODULE_LICENSE("GPL v2"); |