diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
commit | fcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch) | |
tree | a57612d1888735a2ec7972891b68c1ac5ec8faea /drivers/staging/iio/adc | |
parent | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff) |
Diffstat (limited to 'drivers/staging/iio/adc')
21 files changed, 8524 insertions, 0 deletions
diff --git a/drivers/staging/iio/adc/ad7150.c b/drivers/staging/iio/adc/ad7150.c new file mode 100644 index 00000000000..04017ef6688 --- /dev/null +++ b/drivers/staging/iio/adc/ad7150.c | |||
@@ -0,0 +1,812 @@ | |||
1 | /* | ||
2 | * AD7150 capacitive sensor driver supporting AD7150/1/6 | ||
3 | * | ||
4 | * Copyright 2010 Analog Devices Inc. | ||
5 | * | ||
6 | * Licensed under the GPL-2 or later. | ||
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/i2c.h> | ||
14 | |||
15 | #include "../iio.h" | ||
16 | #include "../sysfs.h" | ||
17 | |||
18 | /* | ||
19 | * AD7150 registers definition | ||
20 | */ | ||
21 | |||
22 | #define AD7150_STATUS 0 | ||
23 | #define AD7150_STATUS_OUT1 (1 << 3) | ||
24 | #define AD7150_STATUS_OUT2 (1 << 5) | ||
25 | #define AD7150_CH1_DATA_HIGH 1 | ||
26 | #define AD7150_CH1_DATA_LOW 2 | ||
27 | #define AD7150_CH2_DATA_HIGH 3 | ||
28 | #define AD7150_CH2_DATA_LOW 4 | ||
29 | #define AD7150_CH1_AVG_HIGH 5 | ||
30 | #define AD7150_CH1_AVG_LOW 6 | ||
31 | #define AD7150_CH2_AVG_HIGH 7 | ||
32 | #define AD7150_CH2_AVG_LOW 8 | ||
33 | #define AD7150_CH1_SENSITIVITY 9 | ||
34 | #define AD7150_CH1_THR_HOLD_H 9 | ||
35 | #define AD7150_CH1_TIMEOUT 10 | ||
36 | #define AD7150_CH1_THR_HOLD_L 10 | ||
37 | #define AD7150_CH1_SETUP 11 | ||
38 | #define AD7150_CH2_SENSITIVITY 12 | ||
39 | #define AD7150_CH2_THR_HOLD_H 12 | ||
40 | #define AD7150_CH2_TIMEOUT 13 | ||
41 | #define AD7150_CH2_THR_HOLD_L 13 | ||
42 | #define AD7150_CH2_SETUP 14 | ||
43 | #define AD7150_CFG 15 | ||
44 | #define AD7150_CFG_FIX (1 << 7) | ||
45 | #define AD7150_PD_TIMER 16 | ||
46 | #define AD7150_CH1_CAPDAC 17 | ||
47 | #define AD7150_CH2_CAPDAC 18 | ||
48 | #define AD7150_SN3 19 | ||
49 | #define AD7150_SN2 20 | ||
50 | #define AD7150_SN1 21 | ||
51 | #define AD7150_SN0 22 | ||
52 | #define AD7150_ID 23 | ||
53 | |||
54 | #define AD7150_MAX_CONV_MODE 4 | ||
55 | |||
56 | /* | ||
57 | * struct ad7150_chip_info - chip specifc information | ||
58 | */ | ||
59 | |||
60 | struct ad7150_chip_info { | ||
61 | struct i2c_client *client; | ||
62 | bool inter; | ||
63 | u16 ch1_threshold; /* Ch1 Threshold (in fixed threshold mode) */ | ||
64 | u8 ch1_sensitivity; /* Ch1 Sensitivity (in adaptive threshold mode) */ | ||
65 | u8 ch1_timeout; /* Ch1 Timeout (in adaptive threshold mode) */ | ||
66 | u8 ch1_setup; | ||
67 | u16 ch2_threshold; /* Ch2 Threshold (in fixed threshold mode) */ | ||
68 | u8 ch2_sensitivity; /* Ch1 Sensitivity (in adaptive threshold mode) */ | ||
69 | u8 ch2_timeout; /* Ch1 Timeout (in adaptive threshold mode) */ | ||
70 | u8 ch2_setup; | ||
71 | u8 powerdown_timer; | ||
72 | char threshold_mode[10]; /* adaptive/fixed threshold mode */ | ||
73 | int old_state; | ||
74 | char *conversion_mode; | ||
75 | }; | ||
76 | |||
77 | struct ad7150_conversion_mode { | ||
78 | char *name; | ||
79 | u8 reg_cfg; | ||
80 | }; | ||
81 | |||
82 | static struct ad7150_conversion_mode | ||
83 | ad7150_conv_mode_table[AD7150_MAX_CONV_MODE] = { | ||
84 | { "idle", 0 }, | ||
85 | { "continuous-conversion", 1 }, | ||
86 | { "single-conversion", 2 }, | ||
87 | { "power-down", 3 }, | ||
88 | }; | ||
89 | |||
90 | /* | ||
91 | * ad7150 register access by I2C | ||
92 | */ | ||
93 | |||
94 | static int ad7150_i2c_read(struct ad7150_chip_info *chip, u8 reg, u8 *data, int len) | ||
95 | { | ||
96 | struct i2c_client *client = chip->client; | ||
97 | int ret = 0; | ||
98 | |||
99 | ret = i2c_master_send(client, ®, 1); | ||
100 | if (ret < 0) { | ||
101 | dev_err(&client->dev, "I2C write error\n"); | ||
102 | return ret; | ||
103 | } | ||
104 | |||
105 | ret = i2c_master_recv(client, data, len); | ||
106 | if (ret < 0) { | ||
107 | dev_err(&client->dev, "I2C read error\n"); | ||
108 | return ret; | ||
109 | } | ||
110 | |||
111 | return ret; | ||
112 | } | ||
113 | |||
114 | static int ad7150_i2c_write(struct ad7150_chip_info *chip, u8 reg, u8 data) | ||
115 | { | ||
116 | struct i2c_client *client = chip->client; | ||
117 | int ret = 0; | ||
118 | |||
119 | u8 tx[2] = { | ||
120 | reg, | ||
121 | data, | ||
122 | }; | ||
123 | |||
124 | ret = i2c_master_send(client, tx, 2); | ||
125 | if (ret < 0) | ||
126 | dev_err(&client->dev, "I2C write error\n"); | ||
127 | |||
128 | return ret; | ||
129 | } | ||
130 | |||
131 | /* | ||
132 | * sysfs nodes | ||
133 | */ | ||
134 | |||
135 | #define IIO_DEV_ATTR_AVAIL_CONVERSION_MODES(_show) \ | ||
136 | IIO_DEVICE_ATTR(available_conversion_modes, S_IRUGO, _show, NULL, 0) | ||
137 | #define IIO_DEV_ATTR_CONVERSION_MODE(_mode, _show, _store) \ | ||
138 | IIO_DEVICE_ATTR(conversion_mode, _mode, _show, _store, 0) | ||
139 | #define IIO_DEV_ATTR_AVAIL_THRESHOLD_MODES(_show) \ | ||
140 | IIO_DEVICE_ATTR(available_threshold_modes, S_IRUGO, _show, NULL, 0) | ||
141 | #define IIO_DEV_ATTR_THRESHOLD_MODE(_mode, _show, _store) \ | ||
142 | IIO_DEVICE_ATTR(threshold_mode, _mode, _show, _store, 0) | ||
143 | #define IIO_DEV_ATTR_CH1_THRESHOLD(_mode, _show, _store) \ | ||
144 | IIO_DEVICE_ATTR(ch1_threshold, _mode, _show, _store, 0) | ||
145 | #define IIO_DEV_ATTR_CH2_THRESHOLD(_mode, _show, _store) \ | ||
146 | IIO_DEVICE_ATTR(ch2_threshold, _mode, _show, _store, 0) | ||
147 | #define IIO_DEV_ATTR_CH1_SENSITIVITY(_mode, _show, _store) \ | ||
148 | IIO_DEVICE_ATTR(ch1_sensitivity, _mode, _show, _store, 0) | ||
149 | #define IIO_DEV_ATTR_CH2_SENSITIVITY(_mode, _show, _store) \ | ||
150 | IIO_DEVICE_ATTR(ch2_sensitivity, _mode, _show, _store, 0) | ||
151 | #define IIO_DEV_ATTR_CH1_TIMEOUT(_mode, _show, _store) \ | ||
152 | IIO_DEVICE_ATTR(ch1_timeout, _mode, _show, _store, 0) | ||
153 | #define IIO_DEV_ATTR_CH2_TIMEOUT(_mode, _show, _store) \ | ||
154 | IIO_DEVICE_ATTR(ch2_timeout, _mode, _show, _store, 0) | ||
155 | #define IIO_DEV_ATTR_CH1_VALUE(_show) \ | ||
156 | IIO_DEVICE_ATTR(ch1_value, S_IRUGO, _show, NULL, 0) | ||
157 | #define IIO_DEV_ATTR_CH2_VALUE(_show) \ | ||
158 | IIO_DEVICE_ATTR(ch2_value, S_IRUGO, _show, NULL, 0) | ||
159 | #define IIO_DEV_ATTR_CH1_SETUP(_mode, _show, _store) \ | ||
160 | IIO_DEVICE_ATTR(ch1_setup, _mode, _show, _store, 0) | ||
161 | #define IIO_DEV_ATTR_CH2_SETUP(_mode, _show, _store) \ | ||
162 | IIO_DEVICE_ATTR(ch2_setup, _mode, _show, _store, 0) | ||
163 | #define IIO_DEV_ATTR_POWERDOWN_TIMER(_mode, _show, _store) \ | ||
164 | IIO_DEVICE_ATTR(powerdown_timer, _mode, _show, _store, 0) | ||
165 | |||
166 | static ssize_t ad7150_show_conversion_modes(struct device *dev, | ||
167 | struct device_attribute *attr, | ||
168 | char *buf) | ||
169 | { | ||
170 | int i; | ||
171 | int len = 0; | ||
172 | |||
173 | for (i = 0; i < AD7150_MAX_CONV_MODE; i++) | ||
174 | len += sprintf(buf + len, "%s\n", ad7150_conv_mode_table[i].name); | ||
175 | |||
176 | return len; | ||
177 | } | ||
178 | |||
179 | static IIO_DEV_ATTR_AVAIL_CONVERSION_MODES(ad7150_show_conversion_modes); | ||
180 | |||
181 | static ssize_t ad7150_show_conversion_mode(struct device *dev, | ||
182 | struct device_attribute *attr, | ||
183 | char *buf) | ||
184 | { | ||
185 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
186 | struct ad7150_chip_info *chip = iio_priv(dev_info); | ||
187 | |||
188 | return sprintf(buf, "%s\n", chip->conversion_mode); | ||
189 | } | ||
190 | |||
191 | static ssize_t ad7150_store_conversion_mode(struct device *dev, | ||
192 | struct device_attribute *attr, | ||
193 | const char *buf, | ||
194 | size_t len) | ||
195 | { | ||
196 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
197 | struct ad7150_chip_info *chip = iio_priv(dev_info); | ||
198 | u8 cfg; | ||
199 | int i; | ||
200 | |||
201 | ad7150_i2c_read(chip, AD7150_CFG, &cfg, 1); | ||
202 | |||
203 | for (i = 0; i < AD7150_MAX_CONV_MODE; i++) { | ||
204 | if (strncmp(buf, ad7150_conv_mode_table[i].name, | ||
205 | strlen(ad7150_conv_mode_table[i].name) - 1) == 0) { | ||
206 | chip->conversion_mode = ad7150_conv_mode_table[i].name; | ||
207 | cfg |= 0x18 | ad7150_conv_mode_table[i].reg_cfg; | ||
208 | ad7150_i2c_write(chip, AD7150_CFG, cfg); | ||
209 | return len; | ||
210 | } | ||
211 | } | ||
212 | |||
213 | dev_err(dev, "not supported conversion mode\n"); | ||
214 | |||
215 | return -EINVAL; | ||
216 | } | ||
217 | |||
218 | static IIO_DEV_ATTR_CONVERSION_MODE(S_IRUGO | S_IWUSR, | ||
219 | ad7150_show_conversion_mode, | ||
220 | ad7150_store_conversion_mode); | ||
221 | |||
222 | static ssize_t ad7150_show_threshold_modes(struct device *dev, | ||
223 | struct device_attribute *attr, | ||
224 | char *buf) | ||
225 | { | ||
226 | return sprintf(buf, "adaptive\nfixed\n"); | ||
227 | } | ||
228 | |||
229 | static IIO_DEV_ATTR_AVAIL_THRESHOLD_MODES(ad7150_show_threshold_modes); | ||
230 | |||
231 | static ssize_t ad7150_show_ch1_value(struct device *dev, | ||
232 | struct device_attribute *attr, | ||
233 | char *buf) | ||
234 | { | ||
235 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
236 | struct ad7150_chip_info *chip = iio_priv(dev_info); | ||
237 | u8 data[2]; | ||
238 | |||
239 | ad7150_i2c_read(chip, AD7150_CH1_DATA_HIGH, data, 2); | ||
240 | return sprintf(buf, "%d\n", ((int) data[0] << 8) | data[1]); | ||
241 | } | ||
242 | |||
243 | static IIO_DEV_ATTR_CH1_VALUE(ad7150_show_ch1_value); | ||
244 | |||
245 | static ssize_t ad7150_show_ch2_value(struct device *dev, | ||
246 | struct device_attribute *attr, | ||
247 | char *buf) | ||
248 | { | ||
249 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
250 | struct ad7150_chip_info *chip = iio_priv(dev_info); | ||
251 | u8 data[2]; | ||
252 | |||
253 | ad7150_i2c_read(chip, AD7150_CH2_DATA_HIGH, data, 2); | ||
254 | return sprintf(buf, "%d\n", ((int) data[0] << 8) | data[1]); | ||
255 | } | ||
256 | |||
257 | static IIO_DEV_ATTR_CH2_VALUE(ad7150_show_ch2_value); | ||
258 | |||
259 | static ssize_t ad7150_show_threshold_mode(struct device *dev, | ||
260 | struct device_attribute *attr, | ||
261 | char *buf) | ||
262 | { | ||
263 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
264 | struct ad7150_chip_info *chip = iio_priv(dev_info); | ||
265 | |||
266 | return sprintf(buf, "%s\n", chip->threshold_mode); | ||
267 | } | ||
268 | |||
269 | static ssize_t ad7150_store_threshold_mode(struct device *dev, | ||
270 | struct device_attribute *attr, | ||
271 | const char *buf, | ||
272 | size_t len) | ||
273 | { | ||
274 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
275 | struct ad7150_chip_info *chip = iio_priv(dev_info); | ||
276 | u8 cfg; | ||
277 | |||
278 | ad7150_i2c_read(chip, AD7150_CFG, &cfg, 1); | ||
279 | |||
280 | if (strncmp(buf, "fixed", 5) == 0) { | ||
281 | strcpy(chip->threshold_mode, "fixed"); | ||
282 | cfg |= AD7150_CFG_FIX; | ||
283 | ad7150_i2c_write(chip, AD7150_CFG, cfg); | ||
284 | |||
285 | return len; | ||
286 | } else if (strncmp(buf, "adaptive", 8) == 0) { | ||
287 | strcpy(chip->threshold_mode, "adaptive"); | ||
288 | cfg &= ~AD7150_CFG_FIX; | ||
289 | ad7150_i2c_write(chip, AD7150_CFG, cfg); | ||
290 | |||
291 | return len; | ||
292 | } | ||
293 | |||
294 | dev_err(dev, "not supported threshold mode\n"); | ||
295 | return -EINVAL; | ||
296 | } | ||
297 | |||
298 | static IIO_DEV_ATTR_THRESHOLD_MODE(S_IRUGO | S_IWUSR, | ||
299 | ad7150_show_threshold_mode, | ||
300 | ad7150_store_threshold_mode); | ||
301 | |||
302 | static ssize_t ad7150_show_ch1_threshold(struct device *dev, | ||
303 | struct device_attribute *attr, | ||
304 | char *buf) | ||
305 | { | ||
306 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
307 | struct ad7150_chip_info *chip = iio_priv(dev_info); | ||
308 | |||
309 | return sprintf(buf, "%d\n", chip->ch1_threshold); | ||
310 | } | ||
311 | |||
312 | static ssize_t ad7150_store_ch1_threshold(struct device *dev, | ||
313 | struct device_attribute *attr, | ||
314 | const char *buf, | ||
315 | size_t len) | ||
316 | { | ||
317 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
318 | struct ad7150_chip_info *chip = iio_priv(dev_info); | ||
319 | unsigned long data; | ||
320 | int ret; | ||
321 | |||
322 | ret = strict_strtoul(buf, 10, &data); | ||
323 | |||
324 | if ((!ret) && (data < 0x10000)) { | ||
325 | ad7150_i2c_write(chip, AD7150_CH1_THR_HOLD_H, data >> 8); | ||
326 | ad7150_i2c_write(chip, AD7150_CH1_THR_HOLD_L, data); | ||
327 | chip->ch1_threshold = data; | ||
328 | return len; | ||
329 | } | ||
330 | |||
331 | return -EINVAL; | ||
332 | } | ||
333 | |||
334 | static IIO_DEV_ATTR_CH1_THRESHOLD(S_IRUGO | S_IWUSR, | ||
335 | ad7150_show_ch1_threshold, | ||
336 | ad7150_store_ch1_threshold); | ||
337 | |||
338 | static ssize_t ad7150_show_ch2_threshold(struct device *dev, | ||
339 | struct device_attribute *attr, | ||
340 | char *buf) | ||
341 | { | ||
342 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
343 | struct ad7150_chip_info *chip = iio_priv(dev_info); | ||
344 | |||
345 | return sprintf(buf, "%d\n", chip->ch2_threshold); | ||
346 | } | ||
347 | |||
348 | static ssize_t ad7150_store_ch2_threshold(struct device *dev, | ||
349 | struct device_attribute *attr, | ||
350 | const char *buf, | ||
351 | size_t len) | ||
352 | { | ||
353 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
354 | struct ad7150_chip_info *chip = iio_priv(dev_info); | ||
355 | unsigned long data; | ||
356 | int ret; | ||
357 | |||
358 | ret = strict_strtoul(buf, 10, &data); | ||
359 | |||
360 | if ((!ret) && (data < 0x10000)) { | ||
361 | ad7150_i2c_write(chip, AD7150_CH2_THR_HOLD_H, data >> 8); | ||
362 | ad7150_i2c_write(chip, AD7150_CH2_THR_HOLD_L, data); | ||
363 | chip->ch2_threshold = data; | ||
364 | return len; | ||
365 | } | ||
366 | |||
367 | return -EINVAL; | ||
368 | } | ||
369 | |||
370 | static IIO_DEV_ATTR_CH2_THRESHOLD(S_IRUGO | S_IWUSR, | ||
371 | ad7150_show_ch2_threshold, | ||
372 | ad7150_store_ch2_threshold); | ||
373 | |||
374 | static ssize_t ad7150_show_ch1_sensitivity(struct device *dev, | ||
375 | struct device_attribute *attr, | ||
376 | char *buf) | ||
377 | { | ||
378 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
379 | struct ad7150_chip_info *chip = iio_priv(dev_info); | ||
380 | |||
381 | return sprintf(buf, "%d\n", chip->ch1_sensitivity); | ||
382 | } | ||
383 | |||
384 | static ssize_t ad7150_store_ch1_sensitivity(struct device *dev, | ||
385 | struct device_attribute *attr, | ||
386 | const char *buf, | ||
387 | size_t len) | ||
388 | { | ||
389 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
390 | struct ad7150_chip_info *chip = iio_priv(dev_info); | ||
391 | unsigned long data; | ||
392 | int ret; | ||
393 | |||
394 | ret = strict_strtoul(buf, 10, &data); | ||
395 | |||
396 | if ((!ret) && (data < 0x100)) { | ||
397 | ad7150_i2c_write(chip, AD7150_CH1_SENSITIVITY, data); | ||
398 | chip->ch1_sensitivity = data; | ||
399 | return len; | ||
400 | } | ||
401 | |||
402 | return -EINVAL; | ||
403 | } | ||
404 | |||
405 | static IIO_DEV_ATTR_CH1_SENSITIVITY(S_IRUGO | S_IWUSR, | ||
406 | ad7150_show_ch1_sensitivity, | ||
407 | ad7150_store_ch1_sensitivity); | ||
408 | |||
409 | static ssize_t ad7150_show_ch2_sensitivity(struct device *dev, | ||
410 | struct device_attribute *attr, | ||
411 | char *buf) | ||
412 | { | ||
413 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
414 | struct ad7150_chip_info *chip = iio_priv(dev_info); | ||
415 | |||
416 | return sprintf(buf, "%d\n", chip->ch2_sensitivity); | ||
417 | } | ||
418 | |||
419 | static ssize_t ad7150_store_ch2_sensitivity(struct device *dev, | ||
420 | struct device_attribute *attr, | ||
421 | const char *buf, | ||
422 | size_t len) | ||
423 | { | ||
424 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
425 | struct ad7150_chip_info *chip = iio_priv(dev_info); | ||
426 | unsigned long data; | ||
427 | int ret; | ||
428 | |||
429 | ret = strict_strtoul(buf, 10, &data); | ||
430 | |||
431 | if ((!ret) && (data < 0x100)) { | ||
432 | ad7150_i2c_write(chip, AD7150_CH2_SENSITIVITY, data); | ||
433 | chip->ch2_sensitivity = data; | ||
434 | return len; | ||
435 | } | ||
436 | |||
437 | return -EINVAL; | ||
438 | } | ||
439 | |||
440 | static IIO_DEV_ATTR_CH2_SENSITIVITY(S_IRUGO | S_IWUSR, | ||
441 | ad7150_show_ch2_sensitivity, | ||
442 | ad7150_store_ch2_sensitivity); | ||
443 | |||
444 | static ssize_t ad7150_show_ch1_timeout(struct device *dev, | ||
445 | struct device_attribute *attr, | ||
446 | char *buf) | ||
447 | { | ||
448 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
449 | struct ad7150_chip_info *chip = iio_priv(dev_info); | ||
450 | |||
451 | return sprintf(buf, "%d\n", chip->ch1_timeout); | ||
452 | } | ||
453 | |||
454 | static ssize_t ad7150_store_ch1_timeout(struct device *dev, | ||
455 | struct device_attribute *attr, | ||
456 | const char *buf, | ||
457 | size_t len) | ||
458 | { | ||
459 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
460 | struct ad7150_chip_info *chip = iio_priv(dev_info); | ||
461 | unsigned long data; | ||
462 | int ret; | ||
463 | |||
464 | ret = strict_strtoul(buf, 10, &data); | ||
465 | |||
466 | if ((!ret) && (data < 0x100)) { | ||
467 | ad7150_i2c_write(chip, AD7150_CH1_TIMEOUT, data); | ||
468 | chip->ch1_timeout = data; | ||
469 | return len; | ||
470 | } | ||
471 | |||
472 | return -EINVAL; | ||
473 | } | ||
474 | |||
475 | static IIO_DEV_ATTR_CH1_TIMEOUT(S_IRUGO | S_IWUSR, | ||
476 | ad7150_show_ch1_timeout, | ||
477 | ad7150_store_ch1_timeout); | ||
478 | |||
479 | static ssize_t ad7150_show_ch2_timeout(struct device *dev, | ||
480 | struct device_attribute *attr, | ||
481 | char *buf) | ||
482 | { | ||
483 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
484 | struct ad7150_chip_info *chip = iio_priv(dev_info); | ||
485 | |||
486 | return sprintf(buf, "%d\n", chip->ch2_timeout); | ||
487 | } | ||
488 | |||
489 | static ssize_t ad7150_store_ch2_timeout(struct device *dev, | ||
490 | struct device_attribute *attr, | ||
491 | const char *buf, | ||
492 | size_t len) | ||
493 | { | ||
494 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
495 | struct ad7150_chip_info *chip = iio_priv(dev_info); | ||
496 | unsigned long data; | ||
497 | int ret; | ||
498 | |||
499 | ret = strict_strtoul(buf, 10, &data); | ||
500 | |||
501 | if ((!ret) && (data < 0x100)) { | ||
502 | ad7150_i2c_write(chip, AD7150_CH2_TIMEOUT, data); | ||
503 | chip->ch2_timeout = data; | ||
504 | return len; | ||
505 | } | ||
506 | |||
507 | return -EINVAL; | ||
508 | } | ||
509 | |||
510 | static IIO_DEV_ATTR_CH2_TIMEOUT(S_IRUGO | S_IWUSR, | ||
511 | ad7150_show_ch2_timeout, | ||
512 | ad7150_store_ch2_timeout); | ||
513 | |||
514 | static ssize_t ad7150_show_ch1_setup(struct device *dev, | ||
515 | struct device_attribute *attr, | ||
516 | char *buf) | ||
517 | { | ||
518 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
519 | struct ad7150_chip_info *chip = iio_priv(dev_info); | ||
520 | |||
521 | return sprintf(buf, "0x%02x\n", chip->ch1_setup); | ||
522 | } | ||
523 | |||
524 | static ssize_t ad7150_store_ch1_setup(struct device *dev, | ||
525 | struct device_attribute *attr, | ||
526 | const char *buf, | ||
527 | size_t len) | ||
528 | { | ||
529 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
530 | struct ad7150_chip_info *chip = iio_priv(dev_info); | ||
531 | unsigned long data; | ||
532 | int ret; | ||
533 | |||
534 | ret = strict_strtoul(buf, 10, &data); | ||
535 | |||
536 | if ((!ret) && (data < 0x100)) { | ||
537 | ad7150_i2c_write(chip, AD7150_CH1_SETUP, data); | ||
538 | chip->ch1_setup = data; | ||
539 | return len; | ||
540 | } | ||
541 | |||
542 | |||
543 | return -EINVAL; | ||
544 | } | ||
545 | |||
546 | static IIO_DEV_ATTR_CH1_SETUP(S_IRUGO | S_IWUSR, | ||
547 | ad7150_show_ch1_setup, | ||
548 | ad7150_store_ch1_setup); | ||
549 | |||
550 | static ssize_t ad7150_show_ch2_setup(struct device *dev, | ||
551 | struct device_attribute *attr, | ||
552 | char *buf) | ||
553 | { | ||
554 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
555 | struct ad7150_chip_info *chip = iio_priv(dev_info); | ||
556 | |||
557 | return sprintf(buf, "0x%02x\n", chip->ch2_setup); | ||
558 | } | ||
559 | |||
560 | static ssize_t ad7150_store_ch2_setup(struct device *dev, | ||
561 | struct device_attribute *attr, | ||
562 | const char *buf, | ||
563 | size_t len) | ||
564 | { | ||
565 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
566 | struct ad7150_chip_info *chip = iio_priv(dev_info); | ||
567 | unsigned long data; | ||
568 | int ret; | ||
569 | |||
570 | ret = strict_strtoul(buf, 10, &data); | ||
571 | |||
572 | if ((!ret) && (data < 0x100)) { | ||
573 | ad7150_i2c_write(chip, AD7150_CH2_SETUP, data); | ||
574 | chip->ch2_setup = data; | ||
575 | return len; | ||
576 | } | ||
577 | |||
578 | return -EINVAL; | ||
579 | } | ||
580 | |||
581 | static IIO_DEV_ATTR_CH2_SETUP(S_IRUGO | S_IWUSR, | ||
582 | ad7150_show_ch2_setup, | ||
583 | ad7150_store_ch2_setup); | ||
584 | |||
585 | static ssize_t ad7150_show_powerdown_timer(struct device *dev, | ||
586 | struct device_attribute *attr, | ||
587 | char *buf) | ||
588 | { | ||
589 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
590 | struct ad7150_chip_info *chip = iio_priv(dev_info); | ||
591 | |||
592 | return sprintf(buf, "0x%02x\n", chip->powerdown_timer); | ||
593 | } | ||
594 | |||
595 | static ssize_t ad7150_store_powerdown_timer(struct device *dev, | ||
596 | struct device_attribute *attr, | ||
597 | const char *buf, | ||
598 | size_t len) | ||
599 | { | ||
600 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
601 | struct ad7150_chip_info *chip = iio_priv(dev_info); | ||
602 | unsigned long data; | ||
603 | int ret; | ||
604 | |||
605 | ret = strict_strtoul(buf, 10, &data); | ||
606 | |||
607 | if ((!ret) && (data < 0x40)) { | ||
608 | chip->powerdown_timer = data; | ||
609 | return len; | ||
610 | } | ||
611 | |||
612 | return -EINVAL; | ||
613 | } | ||
614 | |||
615 | static IIO_DEV_ATTR_POWERDOWN_TIMER(S_IRUGO | S_IWUSR, | ||
616 | ad7150_show_powerdown_timer, | ||
617 | ad7150_store_powerdown_timer); | ||
618 | |||
619 | static struct attribute *ad7150_attributes[] = { | ||
620 | &iio_dev_attr_available_threshold_modes.dev_attr.attr, | ||
621 | &iio_dev_attr_threshold_mode.dev_attr.attr, | ||
622 | &iio_dev_attr_ch1_threshold.dev_attr.attr, | ||
623 | &iio_dev_attr_ch2_threshold.dev_attr.attr, | ||
624 | &iio_dev_attr_ch1_timeout.dev_attr.attr, | ||
625 | &iio_dev_attr_ch2_timeout.dev_attr.attr, | ||
626 | &iio_dev_attr_ch1_setup.dev_attr.attr, | ||
627 | &iio_dev_attr_ch2_setup.dev_attr.attr, | ||
628 | &iio_dev_attr_ch1_sensitivity.dev_attr.attr, | ||
629 | &iio_dev_attr_ch2_sensitivity.dev_attr.attr, | ||
630 | &iio_dev_attr_powerdown_timer.dev_attr.attr, | ||
631 | &iio_dev_attr_ch1_value.dev_attr.attr, | ||
632 | &iio_dev_attr_ch2_value.dev_attr.attr, | ||
633 | NULL, | ||
634 | }; | ||
635 | |||
636 | static const struct attribute_group ad7150_attribute_group = { | ||
637 | .attrs = ad7150_attributes, | ||
638 | }; | ||
639 | |||
640 | /* | ||
641 | * threshold events | ||
642 | */ | ||
643 | |||
644 | static irqreturn_t ad7150_event_handler(int irq, void *private) | ||
645 | { | ||
646 | struct iio_dev *indio_dev = private; | ||
647 | struct ad7150_chip_info *chip = iio_priv(indio_dev); | ||
648 | u8 int_status; | ||
649 | s64 timestamp = iio_get_time_ns(); | ||
650 | |||
651 | ad7150_i2c_read(chip, AD7150_STATUS, &int_status, 1); | ||
652 | |||
653 | if ((int_status & AD7150_STATUS_OUT1) && !(chip->old_state & AD7150_STATUS_OUT1)) | ||
654 | iio_push_event(indio_dev, 0, | ||
655 | IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_IN, | ||
656 | 0, | ||
657 | IIO_EV_TYPE_THRESH, | ||
658 | IIO_EV_DIR_RISING), | ||
659 | timestamp); | ||
660 | else if ((!(int_status & AD7150_STATUS_OUT1)) && (chip->old_state & AD7150_STATUS_OUT1)) | ||
661 | iio_push_event(indio_dev, 0, | ||
662 | IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_IN, | ||
663 | 0, | ||
664 | IIO_EV_TYPE_THRESH, | ||
665 | IIO_EV_DIR_FALLING), | ||
666 | timestamp); | ||
667 | |||
668 | if ((int_status & AD7150_STATUS_OUT2) && !(chip->old_state & AD7150_STATUS_OUT2)) | ||
669 | iio_push_event(indio_dev, 0, | ||
670 | IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_IN, | ||
671 | 1, | ||
672 | IIO_EV_TYPE_THRESH, | ||
673 | IIO_EV_DIR_RISING), | ||
674 | timestamp); | ||
675 | else if ((!(int_status & AD7150_STATUS_OUT2)) && (chip->old_state & AD7150_STATUS_OUT2)) | ||
676 | iio_push_event(indio_dev, 0, | ||
677 | IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_IN, | ||
678 | 1, | ||
679 | IIO_EV_TYPE_THRESH, | ||
680 | IIO_EV_DIR_FALLING), | ||
681 | timestamp); | ||
682 | return IRQ_HANDLED; | ||
683 | } | ||
684 | |||
685 | static IIO_CONST_ATTR(ch1_high_en, "1"); | ||
686 | static IIO_CONST_ATTR(ch2_high_en, "1"); | ||
687 | static IIO_CONST_ATTR(ch1_low_en, "1"); | ||
688 | static IIO_CONST_ATTR(ch2_low_en, "1"); | ||
689 | |||
690 | static struct attribute *ad7150_event_attributes[] = { | ||
691 | &iio_const_attr_ch1_high_en.dev_attr.attr, | ||
692 | &iio_const_attr_ch2_high_en.dev_attr.attr, | ||
693 | &iio_const_attr_ch1_low_en.dev_attr.attr, | ||
694 | &iio_const_attr_ch2_low_en.dev_attr.attr, | ||
695 | NULL, | ||
696 | }; | ||
697 | |||
698 | static struct attribute_group ad7150_event_attribute_group = { | ||
699 | .attrs = ad7150_event_attributes, | ||
700 | }; | ||
701 | |||
702 | static const struct iio_info ad7150_info = { | ||
703 | .attrs = &ad7150_attribute_group, | ||
704 | .num_interrupt_lines = 1, | ||
705 | .event_attrs = &ad7150_event_attribute_group, | ||
706 | .driver_module = THIS_MODULE, | ||
707 | }; | ||
708 | /* | ||
709 | * device probe and remove | ||
710 | */ | ||
711 | |||
712 | static int __devinit ad7150_probe(struct i2c_client *client, | ||
713 | const struct i2c_device_id *id) | ||
714 | { | ||
715 | int ret = 0, regdone = 0; | ||
716 | struct ad7150_chip_info *chip; | ||
717 | struct iio_dev *indio_dev; | ||
718 | |||
719 | indio_dev = iio_allocate_device(sizeof(*chip)); | ||
720 | if (indio_dev == NULL) { | ||
721 | ret = -ENOMEM; | ||
722 | goto error_ret; | ||
723 | } | ||
724 | chip = iio_priv(indio_dev); | ||
725 | /* this is only used for device removal purposes */ | ||
726 | i2c_set_clientdata(client, indio_dev); | ||
727 | |||
728 | chip->client = client; | ||
729 | |||
730 | /* Establish that the iio_dev is a child of the i2c device */ | ||
731 | indio_dev->name = id->name; | ||
732 | indio_dev->dev.parent = &client->dev; | ||
733 | |||
734 | indio_dev->info = &ad7150_info; | ||
735 | |||
736 | indio_dev->modes = INDIO_DIRECT_MODE; | ||
737 | |||
738 | ret = iio_device_register(indio_dev); | ||
739 | if (ret) | ||
740 | goto error_free_dev; | ||
741 | regdone = 1; | ||
742 | |||
743 | if (client->irq) { | ||
744 | ret = request_threaded_irq(client->irq, | ||
745 | NULL, | ||
746 | &ad7150_event_handler, | ||
747 | IRQF_TRIGGER_RISING | | ||
748 | IRQF_TRIGGER_FALLING, | ||
749 | "ad7150", | ||
750 | indio_dev); | ||
751 | if (ret) | ||
752 | goto error_free_dev; | ||
753 | } | ||
754 | |||
755 | dev_err(&client->dev, "%s capacitive sensor registered, irq: %d\n", id->name, client->irq); | ||
756 | |||
757 | return 0; | ||
758 | |||
759 | error_free_dev: | ||
760 | if (regdone) | ||
761 | iio_device_unregister(indio_dev); | ||
762 | else | ||
763 | iio_free_device(indio_dev); | ||
764 | error_ret: | ||
765 | return ret; | ||
766 | } | ||
767 | |||
768 | static int __devexit ad7150_remove(struct i2c_client *client) | ||
769 | { | ||
770 | struct iio_dev *indio_dev = i2c_get_clientdata(client); | ||
771 | |||
772 | if (client->irq) | ||
773 | free_irq(client->irq, indio_dev); | ||
774 | iio_device_unregister(indio_dev); | ||
775 | |||
776 | return 0; | ||
777 | } | ||
778 | |||
779 | static const struct i2c_device_id ad7150_id[] = { | ||
780 | { "ad7150", 0 }, | ||
781 | { "ad7151", 0 }, | ||
782 | { "ad7156", 0 }, | ||
783 | {} | ||
784 | }; | ||
785 | |||
786 | MODULE_DEVICE_TABLE(i2c, ad7150_id); | ||
787 | |||
788 | static struct i2c_driver ad7150_driver = { | ||
789 | .driver = { | ||
790 | .name = "ad7150", | ||
791 | }, | ||
792 | .probe = ad7150_probe, | ||
793 | .remove = __devexit_p(ad7150_remove), | ||
794 | .id_table = ad7150_id, | ||
795 | }; | ||
796 | |||
797 | static __init int ad7150_init(void) | ||
798 | { | ||
799 | return i2c_add_driver(&ad7150_driver); | ||
800 | } | ||
801 | |||
802 | static __exit void ad7150_exit(void) | ||
803 | { | ||
804 | i2c_del_driver(&ad7150_driver); | ||
805 | } | ||
806 | |||
807 | MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); | ||
808 | MODULE_DESCRIPTION("Analog Devices ad7150/1/6 capacitive sensor driver"); | ||
809 | MODULE_LICENSE("GPL v2"); | ||
810 | |||
811 | module_init(ad7150_init); | ||
812 | module_exit(ad7150_exit); | ||
diff --git a/drivers/staging/iio/adc/ad7152.c b/drivers/staging/iio/adc/ad7152.c new file mode 100644 index 00000000000..21f5f380fb5 --- /dev/null +++ b/drivers/staging/iio/adc/ad7152.c | |||
@@ -0,0 +1,586 @@ | |||
1 | /* | ||
2 | * AD7152 capacitive sensor driver supporting AD7152/3 | ||
3 | * | ||
4 | * Copyright 2010 Analog Devices Inc. | ||
5 | * | ||
6 | * Licensed under the GPL-2 or later. | ||
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/i2c.h> | ||
15 | |||
16 | #include "../iio.h" | ||
17 | #include "../sysfs.h" | ||
18 | |||
19 | /* | ||
20 | * AD7152 registers definition | ||
21 | */ | ||
22 | |||
23 | #define AD7152_STATUS 0 | ||
24 | #define AD7152_STATUS_RDY1 (1 << 0) | ||
25 | #define AD7152_STATUS_RDY2 (1 << 1) | ||
26 | #define AD7152_CH1_DATA_HIGH 1 | ||
27 | #define AD7152_CH1_DATA_LOW 2 | ||
28 | #define AD7152_CH2_DATA_HIGH 3 | ||
29 | #define AD7152_CH2_DATA_LOW 4 | ||
30 | #define AD7152_CH1_OFFS_HIGH 5 | ||
31 | #define AD7152_CH1_OFFS_LOW 6 | ||
32 | #define AD7152_CH2_OFFS_HIGH 7 | ||
33 | #define AD7152_CH2_OFFS_LOW 8 | ||
34 | #define AD7152_CH1_GAIN_HIGH 9 | ||
35 | #define AD7152_CH1_GAIN_LOW 10 | ||
36 | #define AD7152_CH1_SETUP 11 | ||
37 | #define AD7152_CH2_GAIN_HIGH 12 | ||
38 | #define AD7152_CH2_GAIN_LOW 13 | ||
39 | #define AD7152_CH2_SETUP 14 | ||
40 | #define AD7152_CFG 15 | ||
41 | #define AD7152_RESEVERD 16 | ||
42 | #define AD7152_CAPDAC_POS 17 | ||
43 | #define AD7152_CAPDAC_NEG 18 | ||
44 | #define AD7152_CFG2 26 | ||
45 | |||
46 | #define AD7152_MAX_CONV_MODE 6 | ||
47 | |||
48 | /* | ||
49 | * struct ad7152_chip_info - chip specifc information | ||
50 | */ | ||
51 | |||
52 | struct ad7152_chip_info { | ||
53 | struct i2c_client *client; | ||
54 | u16 ch1_offset; /* Channel 1 offset calibration coefficient */ | ||
55 | u16 ch1_gain; /* Channel 1 gain coefficient */ | ||
56 | u8 ch1_setup; | ||
57 | u16 ch2_offset; /* Channel 2 offset calibration coefficient */ | ||
58 | u16 ch2_gain; /* Channel 1 gain coefficient */ | ||
59 | u8 ch2_setup; | ||
60 | u8 filter_rate_setup; /* Capacitive channel digital filter setup; conversion time/update rate setup per channel */ | ||
61 | char *conversion_mode; | ||
62 | }; | ||
63 | |||
64 | struct ad7152_conversion_mode { | ||
65 | char *name; | ||
66 | u8 reg_cfg; | ||
67 | }; | ||
68 | |||
69 | static struct ad7152_conversion_mode | ||
70 | ad7152_conv_mode_table[AD7152_MAX_CONV_MODE] = { | ||
71 | { "idle", 0 }, | ||
72 | { "continuous-conversion", 1 }, | ||
73 | { "single-conversion", 2 }, | ||
74 | { "power-down", 3 }, | ||
75 | { "offset-calibration", 5 }, | ||
76 | { "gain-calibration", 6 }, | ||
77 | }; | ||
78 | |||
79 | /* | ||
80 | * ad7152 register access by I2C | ||
81 | */ | ||
82 | |||
83 | static int ad7152_i2c_read(struct ad7152_chip_info *chip, u8 reg, u8 *data, int len) | ||
84 | { | ||
85 | struct i2c_client *client = chip->client; | ||
86 | int ret; | ||
87 | |||
88 | ret = i2c_master_send(client, ®, 1); | ||
89 | if (ret < 0) { | ||
90 | dev_err(&client->dev, "I2C write error\n"); | ||
91 | return ret; | ||
92 | } | ||
93 | |||
94 | ret = i2c_master_recv(client, data, len); | ||
95 | if (ret < 0) { | ||
96 | dev_err(&client->dev, "I2C read error\n"); | ||
97 | } | ||
98 | |||
99 | return ret; | ||
100 | } | ||
101 | |||
102 | static int ad7152_i2c_write(struct ad7152_chip_info *chip, u8 reg, u8 data) | ||
103 | { | ||
104 | struct i2c_client *client = chip->client; | ||
105 | int ret; | ||
106 | |||
107 | u8 tx[2] = { | ||
108 | reg, | ||
109 | data, | ||
110 | }; | ||
111 | |||
112 | ret = i2c_master_send(client, tx, 2); | ||
113 | if (ret < 0) | ||
114 | dev_err(&client->dev, "I2C write error\n"); | ||
115 | |||
116 | return ret; | ||
117 | } | ||
118 | |||
119 | /* | ||
120 | * sysfs nodes | ||
121 | */ | ||
122 | |||
123 | #define IIO_DEV_ATTR_AVAIL_CONVERSION_MODES(_show) \ | ||
124 | IIO_DEVICE_ATTR(available_conversion_modes, S_IRUGO, _show, NULL, 0) | ||
125 | #define IIO_DEV_ATTR_CONVERSION_MODE(_mode, _show, _store) \ | ||
126 | IIO_DEVICE_ATTR(conversion_mode, _mode, _show, _store, 0) | ||
127 | #define IIO_DEV_ATTR_CH1_OFFSET(_mode, _show, _store) \ | ||
128 | IIO_DEVICE_ATTR(ch1_offset, _mode, _show, _store, 0) | ||
129 | #define IIO_DEV_ATTR_CH2_OFFSET(_mode, _show, _store) \ | ||
130 | IIO_DEVICE_ATTR(ch2_offset, _mode, _show, _store, 0) | ||
131 | #define IIO_DEV_ATTR_CH1_GAIN(_mode, _show, _store) \ | ||
132 | IIO_DEVICE_ATTR(ch1_gain, _mode, _show, _store, 0) | ||
133 | #define IIO_DEV_ATTR_CH2_GAIN(_mode, _show, _store) \ | ||
134 | IIO_DEVICE_ATTR(ch2_gain, _mode, _show, _store, 0) | ||
135 | #define IIO_DEV_ATTR_CH1_VALUE(_show) \ | ||
136 | IIO_DEVICE_ATTR(ch1_value, S_IRUGO, _show, NULL, 0) | ||
137 | #define IIO_DEV_ATTR_CH2_VALUE(_show) \ | ||
138 | IIO_DEVICE_ATTR(ch2_value, S_IRUGO, _show, NULL, 0) | ||
139 | #define IIO_DEV_ATTR_CH1_SETUP(_mode, _show, _store) \ | ||
140 | IIO_DEVICE_ATTR(ch1_setup, _mode, _show, _store, 0) | ||
141 | #define IIO_DEV_ATTR_CH2_SETUP(_mode, _show, _store) \ | ||
142 | IIO_DEVICE_ATTR(ch2_setup, _mode, _show, _store, 0) | ||
143 | #define IIO_DEV_ATTR_FILTER_RATE_SETUP(_mode, _show, _store) \ | ||
144 | IIO_DEVICE_ATTR(filter_rate_setup, _mode, _show, _store, 0) | ||
145 | |||
146 | static ssize_t ad7152_show_conversion_modes(struct device *dev, | ||
147 | struct device_attribute *attr, | ||
148 | char *buf) | ||
149 | { | ||
150 | int i; | ||
151 | int len = 0; | ||
152 | |||
153 | for (i = 0; i < AD7152_MAX_CONV_MODE; i++) | ||
154 | len += sprintf(buf + len, "%s ", ad7152_conv_mode_table[i].name); | ||
155 | |||
156 | len += sprintf(buf + len, "\n"); | ||
157 | |||
158 | return len; | ||
159 | } | ||
160 | |||
161 | static IIO_DEV_ATTR_AVAIL_CONVERSION_MODES(ad7152_show_conversion_modes); | ||
162 | |||
163 | static ssize_t ad7152_show_ch1_value(struct device *dev, | ||
164 | struct device_attribute *attr, | ||
165 | char *buf) | ||
166 | { | ||
167 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
168 | struct ad7152_chip_info *chip = iio_priv(dev_info); | ||
169 | u8 data[2]; | ||
170 | |||
171 | ad7152_i2c_read(chip, AD7152_CH1_DATA_HIGH, data, 2); | ||
172 | return sprintf(buf, "%d\n", ((int)data[0] << 8) | data[1]); | ||
173 | } | ||
174 | |||
175 | static IIO_DEV_ATTR_CH1_VALUE(ad7152_show_ch1_value); | ||
176 | |||
177 | static ssize_t ad7152_show_ch2_value(struct device *dev, | ||
178 | struct device_attribute *attr, | ||
179 | char *buf) | ||
180 | { | ||
181 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
182 | struct ad7152_chip_info *chip = iio_priv(dev_info); | ||
183 | u8 data[2]; | ||
184 | |||
185 | ad7152_i2c_read(chip, AD7152_CH2_DATA_HIGH, data, 2); | ||
186 | return sprintf(buf, "%d\n", ((int)data[0] << 8) | data[1]); | ||
187 | } | ||
188 | |||
189 | static IIO_DEV_ATTR_CH2_VALUE(ad7152_show_ch2_value); | ||
190 | |||
191 | static ssize_t ad7152_show_conversion_mode(struct device *dev, | ||
192 | struct device_attribute *attr, | ||
193 | char *buf) | ||
194 | { | ||
195 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
196 | struct ad7152_chip_info *chip = iio_priv(dev_info); | ||
197 | |||
198 | return sprintf(buf, "%s\n", chip->conversion_mode); | ||
199 | } | ||
200 | |||
201 | static ssize_t ad7152_store_conversion_mode(struct device *dev, | ||
202 | struct device_attribute *attr, | ||
203 | const char *buf, | ||
204 | size_t len) | ||
205 | { | ||
206 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
207 | struct ad7152_chip_info *chip = iio_priv(dev_info); | ||
208 | u8 cfg; | ||
209 | int i; | ||
210 | |||
211 | ad7152_i2c_read(chip, AD7152_CFG, &cfg, 1); | ||
212 | |||
213 | for (i = 0; i < AD7152_MAX_CONV_MODE; i++) | ||
214 | if (strncmp(buf, ad7152_conv_mode_table[i].name, | ||
215 | strlen(ad7152_conv_mode_table[i].name) - 1) == 0) { | ||
216 | chip->conversion_mode = ad7152_conv_mode_table[i].name; | ||
217 | cfg |= 0x18 | ad7152_conv_mode_table[i].reg_cfg; | ||
218 | ad7152_i2c_write(chip, AD7152_CFG, cfg); | ||
219 | return len; | ||
220 | } | ||
221 | |||
222 | dev_err(dev, "not supported conversion mode\n"); | ||
223 | |||
224 | return -EINVAL; | ||
225 | } | ||
226 | |||
227 | static IIO_DEV_ATTR_CONVERSION_MODE(S_IRUGO | S_IWUSR, | ||
228 | ad7152_show_conversion_mode, | ||
229 | ad7152_store_conversion_mode); | ||
230 | |||
231 | static ssize_t ad7152_show_ch1_offset(struct device *dev, | ||
232 | struct device_attribute *attr, | ||
233 | char *buf) | ||
234 | { | ||
235 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
236 | struct ad7152_chip_info *chip = iio_priv(dev_info); | ||
237 | |||
238 | return sprintf(buf, "%d\n", chip->ch1_offset); | ||
239 | } | ||
240 | |||
241 | static ssize_t ad7152_store_ch1_offset(struct device *dev, | ||
242 | struct device_attribute *attr, | ||
243 | const char *buf, | ||
244 | size_t len) | ||
245 | { | ||
246 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
247 | struct ad7152_chip_info *chip = iio_priv(dev_info); | ||
248 | unsigned long data; | ||
249 | int ret; | ||
250 | |||
251 | ret = strict_strtoul(buf, 10, &data); | ||
252 | |||
253 | if ((!ret) && (data < 0x10000)) { | ||
254 | ad7152_i2c_write(chip, AD7152_CH1_OFFS_HIGH, data >> 8); | ||
255 | ad7152_i2c_write(chip, AD7152_CH1_OFFS_LOW, data); | ||
256 | chip->ch1_offset = data; | ||
257 | return len; | ||
258 | } | ||
259 | |||
260 | return -EINVAL; | ||
261 | } | ||
262 | |||
263 | static IIO_DEV_ATTR_CH1_OFFSET(S_IRUGO | S_IWUSR, | ||
264 | ad7152_show_ch1_offset, | ||
265 | ad7152_store_ch1_offset); | ||
266 | |||
267 | static ssize_t ad7152_show_ch2_offset(struct device *dev, | ||
268 | struct device_attribute *attr, | ||
269 | char *buf) | ||
270 | { | ||
271 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
272 | struct ad7152_chip_info *chip = iio_priv(dev_info); | ||
273 | |||
274 | return sprintf(buf, "%d\n", chip->ch2_offset); | ||
275 | } | ||
276 | |||
277 | static ssize_t ad7152_store_ch2_offset(struct device *dev, | ||
278 | struct device_attribute *attr, | ||
279 | const char *buf, | ||
280 | size_t len) | ||
281 | { | ||
282 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
283 | struct ad7152_chip_info *chip = iio_priv(dev_info); | ||
284 | unsigned long data; | ||
285 | int ret; | ||
286 | |||
287 | ret = strict_strtoul(buf, 10, &data); | ||
288 | |||
289 | if ((!ret) && (data < 0x10000)) { | ||
290 | ad7152_i2c_write(chip, AD7152_CH2_OFFS_HIGH, data >> 8); | ||
291 | ad7152_i2c_write(chip, AD7152_CH2_OFFS_LOW, data); | ||
292 | chip->ch2_offset = data; | ||
293 | return len; | ||
294 | } | ||
295 | |||
296 | return -EINVAL; | ||
297 | } | ||
298 | |||
299 | static IIO_DEV_ATTR_CH2_OFFSET(S_IRUGO | S_IWUSR, | ||
300 | ad7152_show_ch2_offset, | ||
301 | ad7152_store_ch2_offset); | ||
302 | |||
303 | static ssize_t ad7152_show_ch1_gain(struct device *dev, | ||
304 | struct device_attribute *attr, | ||
305 | char *buf) | ||
306 | { | ||
307 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
308 | struct ad7152_chip_info *chip = iio_priv(dev_info); | ||
309 | |||
310 | return sprintf(buf, "%d\n", chip->ch1_gain); | ||
311 | } | ||
312 | |||
313 | static ssize_t ad7152_store_ch1_gain(struct device *dev, | ||
314 | struct device_attribute *attr, | ||
315 | const char *buf, | ||
316 | size_t len) | ||
317 | { | ||
318 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
319 | struct ad7152_chip_info *chip = iio_priv(dev_info); | ||
320 | unsigned long data; | ||
321 | int ret; | ||
322 | |||
323 | ret = strict_strtoul(buf, 10, &data); | ||
324 | |||
325 | if ((!ret) && (data < 0x10000)) { | ||
326 | ad7152_i2c_write(chip, AD7152_CH1_GAIN_HIGH, data >> 8); | ||
327 | ad7152_i2c_write(chip, AD7152_CH1_GAIN_LOW, data); | ||
328 | chip->ch1_gain = data; | ||
329 | return len; | ||
330 | } | ||
331 | |||
332 | return -EINVAL; | ||
333 | } | ||
334 | |||
335 | static IIO_DEV_ATTR_CH1_GAIN(S_IRUGO | S_IWUSR, | ||
336 | ad7152_show_ch1_gain, | ||
337 | ad7152_store_ch1_gain); | ||
338 | |||
339 | static ssize_t ad7152_show_ch2_gain(struct device *dev, | ||
340 | struct device_attribute *attr, | ||
341 | char *buf) | ||
342 | { | ||
343 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
344 | struct ad7152_chip_info *chip = iio_priv(dev_info); | ||
345 | |||
346 | return sprintf(buf, "%d\n", chip->ch2_gain); | ||
347 | } | ||
348 | |||
349 | static ssize_t ad7152_store_ch2_gain(struct device *dev, | ||
350 | struct device_attribute *attr, | ||
351 | const char *buf, | ||
352 | size_t len) | ||
353 | { | ||
354 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
355 | struct ad7152_chip_info *chip = iio_priv(dev_info); | ||
356 | unsigned long data; | ||
357 | int ret; | ||
358 | |||
359 | ret = strict_strtoul(buf, 10, &data); | ||
360 | |||
361 | if ((!ret) && (data < 0x10000)) { | ||
362 | ad7152_i2c_write(chip, AD7152_CH2_GAIN_HIGH, data >> 8); | ||
363 | ad7152_i2c_write(chip, AD7152_CH2_GAIN_LOW, data); | ||
364 | chip->ch2_gain = data; | ||
365 | return len; | ||
366 | } | ||
367 | |||
368 | return -EINVAL; | ||
369 | } | ||
370 | |||
371 | static IIO_DEV_ATTR_CH2_GAIN(S_IRUGO | S_IWUSR, | ||
372 | ad7152_show_ch2_gain, | ||
373 | ad7152_store_ch2_gain); | ||
374 | |||
375 | static ssize_t ad7152_show_ch1_setup(struct device *dev, | ||
376 | struct device_attribute *attr, | ||
377 | char *buf) | ||
378 | { | ||
379 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
380 | struct ad7152_chip_info *chip = iio_priv(dev_info); | ||
381 | |||
382 | return sprintf(buf, "0x%02x\n", chip->ch1_setup); | ||
383 | } | ||
384 | |||
385 | static ssize_t ad7152_store_ch1_setup(struct device *dev, | ||
386 | struct device_attribute *attr, | ||
387 | const char *buf, | ||
388 | size_t len) | ||
389 | { | ||
390 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
391 | struct ad7152_chip_info *chip = iio_priv(dev_info); | ||
392 | unsigned long data; | ||
393 | int ret; | ||
394 | |||
395 | ret = strict_strtoul(buf, 10, &data); | ||
396 | |||
397 | if ((!ret) && (data < 0x100)) { | ||
398 | ad7152_i2c_write(chip, AD7152_CH1_SETUP, data); | ||
399 | chip->ch1_setup = data; | ||
400 | return len; | ||
401 | } | ||
402 | |||
403 | return -EINVAL; | ||
404 | } | ||
405 | |||
406 | static IIO_DEV_ATTR_CH1_SETUP(S_IRUGO | S_IWUSR, | ||
407 | ad7152_show_ch1_setup, | ||
408 | ad7152_store_ch1_setup); | ||
409 | |||
410 | static ssize_t ad7152_show_ch2_setup(struct device *dev, | ||
411 | struct device_attribute *attr, | ||
412 | char *buf) | ||
413 | { | ||
414 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
415 | struct ad7152_chip_info *chip = iio_priv(dev_info); | ||
416 | |||
417 | return sprintf(buf, "0x%02x\n", chip->ch2_setup); | ||
418 | } | ||
419 | |||
420 | static ssize_t ad7152_store_ch2_setup(struct device *dev, | ||
421 | struct device_attribute *attr, | ||
422 | const char *buf, | ||
423 | size_t len) | ||
424 | { | ||
425 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
426 | struct ad7152_chip_info *chip = iio_priv(dev_info); | ||
427 | unsigned long data; | ||
428 | int ret; | ||
429 | |||
430 | ret = strict_strtoul(buf, 10, &data); | ||
431 | |||
432 | if ((!ret) && (data < 0x100)) { | ||
433 | ad7152_i2c_write(chip, AD7152_CH2_SETUP, data); | ||
434 | chip->ch2_setup = data; | ||
435 | return len; | ||
436 | } | ||
437 | |||
438 | return -EINVAL; | ||
439 | } | ||
440 | |||
441 | static IIO_DEV_ATTR_CH2_SETUP(S_IRUGO | S_IWUSR, | ||
442 | ad7152_show_ch2_setup, | ||
443 | ad7152_store_ch2_setup); | ||
444 | |||
445 | static ssize_t ad7152_show_filter_rate_setup(struct device *dev, | ||
446 | struct device_attribute *attr, | ||
447 | char *buf) | ||
448 | { | ||
449 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
450 | struct ad7152_chip_info *chip = iio_priv(dev_info); | ||
451 | |||
452 | return sprintf(buf, "0x%02x\n", chip->filter_rate_setup); | ||
453 | } | ||
454 | |||
455 | static ssize_t ad7152_store_filter_rate_setup(struct device *dev, | ||
456 | struct device_attribute *attr, | ||
457 | const char *buf, | ||
458 | size_t len) | ||
459 | { | ||
460 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
461 | struct ad7152_chip_info *chip = iio_priv(dev_info); | ||
462 | unsigned long data; | ||
463 | int ret; | ||
464 | |||
465 | ret = strict_strtoul(buf, 10, &data); | ||
466 | |||
467 | if ((!ret) && (data < 0x100)) { | ||
468 | ad7152_i2c_write(chip, AD7152_CFG2, data); | ||
469 | chip->filter_rate_setup = data; | ||
470 | return len; | ||
471 | } | ||
472 | |||
473 | return -EINVAL; | ||
474 | } | ||
475 | |||
476 | static IIO_DEV_ATTR_FILTER_RATE_SETUP(S_IRUGO | S_IWUSR, | ||
477 | ad7152_show_filter_rate_setup, | ||
478 | ad7152_store_filter_rate_setup); | ||
479 | |||
480 | static struct attribute *ad7152_attributes[] = { | ||
481 | &iio_dev_attr_available_conversion_modes.dev_attr.attr, | ||
482 | &iio_dev_attr_conversion_mode.dev_attr.attr, | ||
483 | &iio_dev_attr_ch1_gain.dev_attr.attr, | ||
484 | &iio_dev_attr_ch2_gain.dev_attr.attr, | ||
485 | &iio_dev_attr_ch1_offset.dev_attr.attr, | ||
486 | &iio_dev_attr_ch2_offset.dev_attr.attr, | ||
487 | &iio_dev_attr_ch1_value.dev_attr.attr, | ||
488 | &iio_dev_attr_ch2_value.dev_attr.attr, | ||
489 | &iio_dev_attr_ch1_setup.dev_attr.attr, | ||
490 | &iio_dev_attr_ch2_setup.dev_attr.attr, | ||
491 | &iio_dev_attr_filter_rate_setup.dev_attr.attr, | ||
492 | NULL, | ||
493 | }; | ||
494 | |||
495 | static const struct attribute_group ad7152_attribute_group = { | ||
496 | .attrs = ad7152_attributes, | ||
497 | }; | ||
498 | |||
499 | static const struct iio_info ad7152_info = { | ||
500 | .attrs = &ad7152_attribute_group, | ||
501 | .driver_module = THIS_MODULE, | ||
502 | }; | ||
503 | /* | ||
504 | * device probe and remove | ||
505 | */ | ||
506 | |||
507 | static int __devinit ad7152_probe(struct i2c_client *client, | ||
508 | const struct i2c_device_id *id) | ||
509 | { | ||
510 | int ret = 0; | ||
511 | struct ad7152_chip_info *chip; | ||
512 | struct iio_dev *indio_dev; | ||
513 | |||
514 | indio_dev = iio_allocate_device(sizeof(*chip)); | ||
515 | if (indio_dev == NULL) { | ||
516 | ret = -ENOMEM; | ||
517 | goto error_ret; | ||
518 | } | ||
519 | chip = iio_priv(indio_dev); | ||
520 | /* this is only used for device removal purposes */ | ||
521 | i2c_set_clientdata(client, indio_dev); | ||
522 | |||
523 | chip->client = client; | ||
524 | |||
525 | /* Echipabilish that the iio_dev is a child of the i2c device */ | ||
526 | indio_dev->name = id->name; | ||
527 | indio_dev->dev.parent = &client->dev; | ||
528 | indio_dev->info = &ad7152_info; | ||
529 | indio_dev->modes = INDIO_DIRECT_MODE; | ||
530 | |||
531 | ret = iio_device_register(indio_dev); | ||
532 | if (ret) | ||
533 | goto error_free_dev; | ||
534 | |||
535 | dev_err(&client->dev, "%s capacitive sensor registered\n", id->name); | ||
536 | |||
537 | return 0; | ||
538 | |||
539 | error_free_dev: | ||
540 | iio_free_device(indio_dev); | ||
541 | error_ret: | ||
542 | return ret; | ||
543 | } | ||
544 | |||
545 | static int __devexit ad7152_remove(struct i2c_client *client) | ||
546 | { | ||
547 | struct iio_dev *indio_dev = i2c_get_clientdata(client); | ||
548 | |||
549 | iio_device_unregister(indio_dev); | ||
550 | |||
551 | return 0; | ||
552 | } | ||
553 | |||
554 | static const struct i2c_device_id ad7152_id[] = { | ||
555 | { "ad7152", 0 }, | ||
556 | { "ad7153", 0 }, | ||
557 | {} | ||
558 | }; | ||
559 | |||
560 | MODULE_DEVICE_TABLE(i2c, ad7152_id); | ||
561 | |||
562 | static struct i2c_driver ad7152_driver = { | ||
563 | .driver = { | ||
564 | .name = "ad7152", | ||
565 | }, | ||
566 | .probe = ad7152_probe, | ||
567 | .remove = __devexit_p(ad7152_remove), | ||
568 | .id_table = ad7152_id, | ||
569 | }; | ||
570 | |||
571 | static __init int ad7152_init(void) | ||
572 | { | ||
573 | return i2c_add_driver(&ad7152_driver); | ||
574 | } | ||
575 | |||
576 | static __exit void ad7152_exit(void) | ||
577 | { | ||
578 | i2c_del_driver(&ad7152_driver); | ||
579 | } | ||
580 | |||
581 | MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); | ||
582 | MODULE_DESCRIPTION("Analog Devices ad7152/3 capacitive sensor driver"); | ||
583 | MODULE_LICENSE("GPL v2"); | ||
584 | |||
585 | module_init(ad7152_init); | ||
586 | module_exit(ad7152_exit); | ||
diff --git a/drivers/staging/iio/adc/ad7298.h b/drivers/staging/iio/adc/ad7298.h new file mode 100644 index 00000000000..628f5adcf0c --- /dev/null +++ b/drivers/staging/iio/adc/ad7298.h | |||
@@ -0,0 +1,76 @@ | |||
1 | /* | ||
2 | * AD7298 SPI ADC driver | ||
3 | * | ||
4 | * Copyright 2011 Analog Devices Inc. | ||
5 | * | ||
6 | * Licensed under the GPL-2. | ||
7 | */ | ||
8 | |||
9 | #ifndef IIO_ADC_AD7298_H_ | ||
10 | #define IIO_ADC_AD7298_H_ | ||
11 | |||
12 | #define AD7298_WRITE (1 << 15) /* write to the control register */ | ||
13 | #define AD7298_REPEAT (1 << 14) /* repeated conversion enable */ | ||
14 | #define AD7298_CH(x) (1 << (13 - (x))) /* channel select */ | ||
15 | #define AD7298_TSENSE (1 << 5) /* temperature conversion enable */ | ||
16 | #define AD7298_EXTREF (1 << 2) /* external reference enable */ | ||
17 | #define AD7298_TAVG (1 << 1) /* temperature sensor averaging enable */ | ||
18 | #define AD7298_PDD (1 << 0) /* partial power down enable */ | ||
19 | |||
20 | #define AD7298_MAX_CHAN 8 | ||
21 | #define AD7298_BITS 12 | ||
22 | #define AD7298_STORAGE_BITS 16 | ||
23 | #define AD7298_INTREF_mV 2500 | ||
24 | |||
25 | #define AD7298_CH_TEMP 9 | ||
26 | |||
27 | #define RES_MASK(bits) ((1 << (bits)) - 1) | ||
28 | |||
29 | /* | ||
30 | * TODO: struct ad7298_platform_data needs to go into include/linux/iio | ||
31 | */ | ||
32 | |||
33 | struct ad7298_platform_data { | ||
34 | /* External Vref voltage applied */ | ||
35 | u16 vref_mv; | ||
36 | }; | ||
37 | |||
38 | struct ad7298_state { | ||
39 | struct spi_device *spi; | ||
40 | struct regulator *reg; | ||
41 | size_t d_size; | ||
42 | u16 int_vref_mv; | ||
43 | unsigned ext_ref; | ||
44 | struct spi_transfer ring_xfer[10]; | ||
45 | struct spi_transfer scan_single_xfer[3]; | ||
46 | struct spi_message ring_msg; | ||
47 | struct spi_message scan_single_msg; | ||
48 | /* | ||
49 | * DMA (thus cache coherency maintenance) requires the | ||
50 | * transfer buffers to live in their own cache lines. | ||
51 | */ | ||
52 | unsigned short rx_buf[8] ____cacheline_aligned; | ||
53 | unsigned short tx_buf[2]; | ||
54 | }; | ||
55 | |||
56 | #ifdef CONFIG_IIO_RING_BUFFER | ||
57 | int ad7298_scan_from_ring(struct iio_dev *indio_dev, long ch); | ||
58 | int ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev); | ||
59 | void ad7298_ring_cleanup(struct iio_dev *indio_dev); | ||
60 | #else /* CONFIG_IIO_RING_BUFFER */ | ||
61 | static inline int ad7298_scan_from_ring(struct iio_dev *indio_dev, long ch) | ||
62 | { | ||
63 | return 0; | ||
64 | } | ||
65 | |||
66 | static inline int | ||
67 | ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev) | ||
68 | { | ||
69 | return 0; | ||
70 | } | ||
71 | |||
72 | static inline void ad7298_ring_cleanup(struct iio_dev *indio_dev) | ||
73 | { | ||
74 | } | ||
75 | #endif /* CONFIG_IIO_RING_BUFFER */ | ||
76 | #endif /* IIO_ADC_AD7298_H_ */ | ||
diff --git a/drivers/staging/iio/adc/ad7298_core.c b/drivers/staging/iio/adc/ad7298_core.c new file mode 100644 index 00000000000..b8e4ae29b0b --- /dev/null +++ b/drivers/staging/iio/adc/ad7298_core.c | |||
@@ -0,0 +1,299 @@ | |||
1 | /* | ||
2 | * AD7298 SPI ADC driver | ||
3 | * | ||
4 | * Copyright 2011 Analog Devices Inc. | ||
5 | * | ||
6 | * Licensed under the GPL-2. | ||
7 | */ | ||
8 | |||
9 | #include <linux/device.h> | ||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/slab.h> | ||
12 | #include <linux/sysfs.h> | ||
13 | #include <linux/spi/spi.h> | ||
14 | #include <linux/regulator/consumer.h> | ||
15 | #include <linux/err.h> | ||
16 | #include <linux/delay.h> | ||
17 | |||
18 | #include "../iio.h" | ||
19 | #include "../sysfs.h" | ||
20 | #include "../ring_generic.h" | ||
21 | #include "adc.h" | ||
22 | |||
23 | #include "ad7298.h" | ||
24 | |||
25 | static struct iio_chan_spec ad7298_channels[] = { | ||
26 | IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0, | ||
27 | (1 << IIO_CHAN_INFO_SCALE_SEPARATE), | ||
28 | 9, AD7298_CH_TEMP, IIO_ST('s', 32, 32, 0), 0), | ||
29 | IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0, | ||
30 | (1 << IIO_CHAN_INFO_SCALE_SHARED), | ||
31 | 0, 0, IIO_ST('u', 12, 16, 0), 0), | ||
32 | IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0, | ||
33 | (1 << IIO_CHAN_INFO_SCALE_SHARED), | ||
34 | 1, 1, IIO_ST('u', 12, 16, 0), 0), | ||
35 | IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 2, 0, | ||
36 | (1 << IIO_CHAN_INFO_SCALE_SHARED), | ||
37 | 2, 2, IIO_ST('u', 12, 16, 0), 0), | ||
38 | IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 3, 0, | ||
39 | (1 << IIO_CHAN_INFO_SCALE_SHARED), | ||
40 | 3, 3, IIO_ST('u', 12, 16, 0), 0), | ||
41 | IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 4, 0, | ||
42 | (1 << IIO_CHAN_INFO_SCALE_SHARED), | ||
43 | 4, 4, IIO_ST('u', 12, 16, 0), 0), | ||
44 | IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 5, 0, | ||
45 | (1 << IIO_CHAN_INFO_SCALE_SHARED), | ||
46 | 5, 5, IIO_ST('u', 12, 16, 0), 0), | ||
47 | IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 6, 0, | ||
48 | (1 << IIO_CHAN_INFO_SCALE_SHARED), | ||
49 | 6, 6, IIO_ST('u', 12, 16, 0), 0), | ||
50 | IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 7, 0, | ||
51 | (1 << IIO_CHAN_INFO_SCALE_SHARED), | ||
52 | 7, 7, IIO_ST('u', 12, 16, 0), 0), | ||
53 | IIO_CHAN_SOFT_TIMESTAMP(8), | ||
54 | }; | ||
55 | |||
56 | static int ad7298_scan_direct(struct ad7298_state *st, unsigned ch) | ||
57 | { | ||
58 | int ret; | ||
59 | st->tx_buf[0] = cpu_to_be16(AD7298_WRITE | st->ext_ref | | ||
60 | (AD7298_CH(0) >> ch)); | ||
61 | |||
62 | ret = spi_sync(st->spi, &st->scan_single_msg); | ||
63 | if (ret) | ||
64 | return ret; | ||
65 | |||
66 | return be16_to_cpu(st->rx_buf[0]); | ||
67 | } | ||
68 | |||
69 | static int ad7298_scan_temp(struct ad7298_state *st, int *val) | ||
70 | { | ||
71 | int tmp, ret; | ||
72 | |||
73 | tmp = cpu_to_be16(AD7298_WRITE | AD7298_TSENSE | | ||
74 | AD7298_TAVG | st->ext_ref); | ||
75 | |||
76 | ret = spi_write(st->spi, (u8 *)&tmp, 2); | ||
77 | if (ret) | ||
78 | return ret; | ||
79 | |||
80 | tmp = 0; | ||
81 | |||
82 | ret = spi_write(st->spi, (u8 *)&tmp, 2); | ||
83 | if (ret) | ||
84 | return ret; | ||
85 | |||
86 | usleep_range(101, 1000); /* sleep > 100us */ | ||
87 | |||
88 | ret = spi_read(st->spi, (u8 *)&tmp, 2); | ||
89 | if (ret) | ||
90 | return ret; | ||
91 | |||
92 | tmp = be16_to_cpu(tmp) & RES_MASK(AD7298_BITS); | ||
93 | |||
94 | /* | ||
95 | * One LSB of the ADC corresponds to 0.25 deg C. | ||
96 | * The temperature reading is in 12-bit twos complement format | ||
97 | */ | ||
98 | |||
99 | if (tmp & (1 << (AD7298_BITS - 1))) { | ||
100 | tmp = (4096 - tmp) * 250; | ||
101 | tmp -= (2 * tmp); | ||
102 | |||
103 | } else { | ||
104 | tmp *= 250; /* temperature in milli degrees Celsius */ | ||
105 | } | ||
106 | |||
107 | *val = tmp; | ||
108 | |||
109 | return 0; | ||
110 | } | ||
111 | |||
112 | static int ad7298_read_raw(struct iio_dev *dev_info, | ||
113 | struct iio_chan_spec const *chan, | ||
114 | int *val, | ||
115 | int *val2, | ||
116 | long m) | ||
117 | { | ||
118 | int ret; | ||
119 | struct ad7298_state *st = iio_priv(dev_info); | ||
120 | unsigned int scale_uv; | ||
121 | |||
122 | switch (m) { | ||
123 | case 0: | ||
124 | mutex_lock(&dev_info->mlock); | ||
125 | if (iio_ring_enabled(dev_info)) { | ||
126 | if (chan->address == AD7298_CH_TEMP) | ||
127 | ret = -ENODEV; | ||
128 | else | ||
129 | ret = ad7298_scan_from_ring(dev_info, | ||
130 | chan->address); | ||
131 | } else { | ||
132 | if (chan->address == AD7298_CH_TEMP) | ||
133 | ret = ad7298_scan_temp(st, val); | ||
134 | else | ||
135 | ret = ad7298_scan_direct(st, chan->address); | ||
136 | } | ||
137 | mutex_unlock(&dev_info->mlock); | ||
138 | |||
139 | if (ret < 0) | ||
140 | return ret; | ||
141 | |||
142 | if (chan->address != AD7298_CH_TEMP) | ||
143 | *val = ret & RES_MASK(AD7298_BITS); | ||
144 | |||
145 | return IIO_VAL_INT; | ||
146 | case (1 << IIO_CHAN_INFO_SCALE_SHARED): | ||
147 | scale_uv = (st->int_vref_mv * 1000) >> AD7298_BITS; | ||
148 | *val = scale_uv / 1000; | ||
149 | *val2 = (scale_uv % 1000) * 1000; | ||
150 | return IIO_VAL_INT_PLUS_MICRO; | ||
151 | case (1 << IIO_CHAN_INFO_SCALE_SEPARATE): | ||
152 | *val = 1; | ||
153 | *val2 = 0; | ||
154 | return IIO_VAL_INT_PLUS_MICRO; | ||
155 | } | ||
156 | return -EINVAL; | ||
157 | } | ||
158 | |||
159 | static const struct iio_info ad7298_info = { | ||
160 | .read_raw = &ad7298_read_raw, | ||
161 | .driver_module = THIS_MODULE, | ||
162 | }; | ||
163 | |||
164 | static int __devinit ad7298_probe(struct spi_device *spi) | ||
165 | { | ||
166 | struct ad7298_platform_data *pdata = spi->dev.platform_data; | ||
167 | struct ad7298_state *st; | ||
168 | int ret, regdone = 0; | ||
169 | struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st)); | ||
170 | |||
171 | if (indio_dev == NULL) | ||
172 | return -ENOMEM; | ||
173 | |||
174 | st = iio_priv(indio_dev); | ||
175 | |||
176 | st->reg = regulator_get(&spi->dev, "vcc"); | ||
177 | if (!IS_ERR(st->reg)) { | ||
178 | ret = regulator_enable(st->reg); | ||
179 | if (ret) | ||
180 | goto error_put_reg; | ||
181 | } | ||
182 | |||
183 | spi_set_drvdata(spi, indio_dev); | ||
184 | |||
185 | st->spi = spi; | ||
186 | |||
187 | indio_dev->name = spi_get_device_id(spi)->name; | ||
188 | indio_dev->dev.parent = &spi->dev; | ||
189 | indio_dev->modes = INDIO_DIRECT_MODE; | ||
190 | indio_dev->channels = ad7298_channels; | ||
191 | indio_dev->num_channels = ARRAY_SIZE(ad7298_channels); | ||
192 | indio_dev->info = &ad7298_info; | ||
193 | |||
194 | /* Setup default message */ | ||
195 | |||
196 | st->scan_single_xfer[0].tx_buf = &st->tx_buf[0]; | ||
197 | st->scan_single_xfer[0].len = 2; | ||
198 | st->scan_single_xfer[0].cs_change = 1; | ||
199 | st->scan_single_xfer[1].tx_buf = &st->tx_buf[1]; | ||
200 | st->scan_single_xfer[1].len = 2; | ||
201 | st->scan_single_xfer[1].cs_change = 1; | ||
202 | st->scan_single_xfer[2].rx_buf = &st->rx_buf[0]; | ||
203 | st->scan_single_xfer[2].len = 2; | ||
204 | |||
205 | spi_message_init(&st->scan_single_msg); | ||
206 | spi_message_add_tail(&st->scan_single_xfer[0], &st->scan_single_msg); | ||
207 | spi_message_add_tail(&st->scan_single_xfer[1], &st->scan_single_msg); | ||
208 | spi_message_add_tail(&st->scan_single_xfer[2], &st->scan_single_msg); | ||
209 | |||
210 | if (pdata && pdata->vref_mv) { | ||
211 | st->int_vref_mv = pdata->vref_mv; | ||
212 | st->ext_ref = AD7298_EXTREF; | ||
213 | } else { | ||
214 | st->int_vref_mv = AD7298_INTREF_mV; | ||
215 | } | ||
216 | |||
217 | ret = ad7298_register_ring_funcs_and_init(indio_dev); | ||
218 | if (ret) | ||
219 | goto error_disable_reg; | ||
220 | |||
221 | ret = iio_device_register(indio_dev); | ||
222 | if (ret) | ||
223 | goto error_disable_reg; | ||
224 | regdone = 1; | ||
225 | |||
226 | ret = iio_ring_buffer_register_ex(indio_dev->ring, 0, | ||
227 | &ad7298_channels[1], /* skip temp0 */ | ||
228 | ARRAY_SIZE(ad7298_channels) - 1); | ||
229 | if (ret) | ||
230 | goto error_cleanup_ring; | ||
231 | |||
232 | return 0; | ||
233 | |||
234 | error_cleanup_ring: | ||
235 | ad7298_ring_cleanup(indio_dev); | ||
236 | error_disable_reg: | ||
237 | if (!IS_ERR(st->reg)) | ||
238 | regulator_disable(st->reg); | ||
239 | error_put_reg: | ||
240 | if (!IS_ERR(st->reg)) | ||
241 | regulator_put(st->reg); | ||
242 | |||
243 | if (regdone) | ||
244 | iio_device_unregister(indio_dev); | ||
245 | else | ||
246 | iio_free_device(indio_dev); | ||
247 | |||
248 | return ret; | ||
249 | } | ||
250 | |||
251 | static int __devexit ad7298_remove(struct spi_device *spi) | ||
252 | { | ||
253 | struct iio_dev *indio_dev = spi_get_drvdata(spi); | ||
254 | struct ad7298_state *st = iio_priv(indio_dev); | ||
255 | |||
256 | iio_ring_buffer_unregister(indio_dev->ring); | ||
257 | ad7298_ring_cleanup(indio_dev); | ||
258 | iio_device_unregister(indio_dev); | ||
259 | if (!IS_ERR(st->reg)) { | ||
260 | regulator_disable(st->reg); | ||
261 | regulator_put(st->reg); | ||
262 | } | ||
263 | iio_device_unregister(indio_dev); | ||
264 | |||
265 | return 0; | ||
266 | } | ||
267 | |||
268 | static const struct spi_device_id ad7298_id[] = { | ||
269 | {"ad7298", 0}, | ||
270 | {} | ||
271 | }; | ||
272 | |||
273 | static struct spi_driver ad7298_driver = { | ||
274 | .driver = { | ||
275 | .name = "ad7298", | ||
276 | .bus = &spi_bus_type, | ||
277 | .owner = THIS_MODULE, | ||
278 | }, | ||
279 | .probe = ad7298_probe, | ||
280 | .remove = __devexit_p(ad7298_remove), | ||
281 | .id_table = ad7298_id, | ||
282 | }; | ||
283 | |||
284 | static int __init ad7298_init(void) | ||
285 | { | ||
286 | return spi_register_driver(&ad7298_driver); | ||
287 | } | ||
288 | module_init(ad7298_init); | ||
289 | |||
290 | static void __exit ad7298_exit(void) | ||
291 | { | ||
292 | spi_unregister_driver(&ad7298_driver); | ||
293 | } | ||
294 | module_exit(ad7298_exit); | ||
295 | |||
296 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | ||
297 | MODULE_DESCRIPTION("Analog Devices AD7298 ADC"); | ||
298 | MODULE_LICENSE("GPL v2"); | ||
299 | MODULE_ALIAS("spi:ad7298"); | ||
diff --git a/drivers/staging/iio/adc/ad7298_ring.c b/drivers/staging/iio/adc/ad7298_ring.c new file mode 100644 index 00000000000..a04c0335262 --- /dev/null +++ b/drivers/staging/iio/adc/ad7298_ring.c | |||
@@ -0,0 +1,202 @@ | |||
1 | /* | ||
2 | * AD7298 SPI ADC driver | ||
3 | * | ||
4 | * Copyright 2011 Analog Devices Inc. | ||
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 | |||
16 | #include "../iio.h" | ||
17 | #include "../ring_generic.h" | ||
18 | #include "../ring_sw.h" | ||
19 | #include "../trigger.h" | ||
20 | #include "../sysfs.h" | ||
21 | |||
22 | #include "ad7298.h" | ||
23 | |||
24 | int ad7298_scan_from_ring(struct iio_dev *dev_info, long ch) | ||
25 | { | ||
26 | struct iio_ring_buffer *ring = dev_info->ring; | ||
27 | int ret; | ||
28 | u16 *ring_data; | ||
29 | |||
30 | if (!(ring->scan_mask & (1 << ch))) { | ||
31 | ret = -EBUSY; | ||
32 | goto error_ret; | ||
33 | } | ||
34 | |||
35 | ring_data = kmalloc(ring->access->get_bytes_per_datum(ring), | ||
36 | GFP_KERNEL); | ||
37 | if (ring_data == NULL) { | ||
38 | ret = -ENOMEM; | ||
39 | goto error_ret; | ||
40 | } | ||
41 | ret = ring->access->read_last(ring, (u8 *) ring_data); | ||
42 | if (ret) | ||
43 | goto error_free_ring_data; | ||
44 | |||
45 | ret = be16_to_cpu(ring_data[ch]); | ||
46 | |||
47 | error_free_ring_data: | ||
48 | kfree(ring_data); | ||
49 | error_ret: | ||
50 | return ret; | ||
51 | } | ||
52 | |||
53 | /** | ||
54 | * ad7298_ring_preenable() setup the parameters of the ring before enabling | ||
55 | * | ||
56 | * The complex nature of the setting of the number of bytes per datum is due | ||
57 | * to this driver currently ensuring that the timestamp is stored at an 8 | ||
58 | * byte boundary. | ||
59 | **/ | ||
60 | static int ad7298_ring_preenable(struct iio_dev *indio_dev) | ||
61 | { | ||
62 | struct ad7298_state *st = iio_priv(indio_dev); | ||
63 | struct iio_ring_buffer *ring = indio_dev->ring; | ||
64 | size_t d_size; | ||
65 | int i, m; | ||
66 | unsigned short command; | ||
67 | |||
68 | d_size = ring->scan_count * (AD7298_STORAGE_BITS / 8); | ||
69 | |||
70 | if (ring->scan_timestamp) { | ||
71 | d_size += sizeof(s64); | ||
72 | |||
73 | if (d_size % sizeof(s64)) | ||
74 | d_size += sizeof(s64) - (d_size % sizeof(s64)); | ||
75 | } | ||
76 | |||
77 | if (ring->access->set_bytes_per_datum) | ||
78 | ring->access->set_bytes_per_datum(ring, d_size); | ||
79 | |||
80 | st->d_size = d_size; | ||
81 | |||
82 | command = AD7298_WRITE | st->ext_ref; | ||
83 | |||
84 | for (i = 0, m = AD7298_CH(0); i < AD7298_MAX_CHAN; i++, m >>= 1) | ||
85 | if (ring->scan_mask & (1 << i)) | ||
86 | command |= m; | ||
87 | |||
88 | st->tx_buf[0] = cpu_to_be16(command); | ||
89 | |||
90 | /* build spi ring message */ | ||
91 | st->ring_xfer[0].tx_buf = &st->tx_buf[0]; | ||
92 | st->ring_xfer[0].len = 2; | ||
93 | st->ring_xfer[0].cs_change = 1; | ||
94 | st->ring_xfer[1].tx_buf = &st->tx_buf[1]; | ||
95 | st->ring_xfer[1].len = 2; | ||
96 | st->ring_xfer[1].cs_change = 1; | ||
97 | |||
98 | spi_message_init(&st->ring_msg); | ||
99 | spi_message_add_tail(&st->ring_xfer[0], &st->ring_msg); | ||
100 | spi_message_add_tail(&st->ring_xfer[1], &st->ring_msg); | ||
101 | |||
102 | for (i = 0; i < ring->scan_count; i++) { | ||
103 | st->ring_xfer[i + 2].rx_buf = &st->rx_buf[i]; | ||
104 | st->ring_xfer[i + 2].len = 2; | ||
105 | st->ring_xfer[i + 2].cs_change = 1; | ||
106 | spi_message_add_tail(&st->ring_xfer[i + 2], &st->ring_msg); | ||
107 | } | ||
108 | /* make sure last transfer cs_change is not set */ | ||
109 | st->ring_xfer[i + 1].cs_change = 0; | ||
110 | |||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | /** | ||
115 | * ad7298_trigger_handler() bh of trigger launched polling to ring buffer | ||
116 | * | ||
117 | * Currently there is no option in this driver to disable the saving of | ||
118 | * timestamps within the ring. | ||
119 | **/ | ||
120 | static irqreturn_t ad7298_trigger_handler(int irq, void *p) | ||
121 | { | ||
122 | struct iio_poll_func *pf = p; | ||
123 | struct iio_dev *indio_dev = pf->private_data; | ||
124 | struct ad7298_state *st = iio_priv(indio_dev); | ||
125 | struct iio_ring_buffer *ring = indio_dev->ring; | ||
126 | s64 time_ns; | ||
127 | __u16 buf[16]; | ||
128 | int b_sent, i; | ||
129 | |||
130 | b_sent = spi_sync(st->spi, &st->ring_msg); | ||
131 | if (b_sent) | ||
132 | return b_sent; | ||
133 | |||
134 | if (ring->scan_timestamp) { | ||
135 | time_ns = iio_get_time_ns(); | ||
136 | memcpy((u8 *)buf + st->d_size - sizeof(s64), | ||
137 | &time_ns, sizeof(time_ns)); | ||
138 | } | ||
139 | |||
140 | for (i = 0; i < ring->scan_count; i++) | ||
141 | buf[i] = be16_to_cpu(st->rx_buf[i]); | ||
142 | |||
143 | indio_dev->ring->access->store_to(ring, (u8 *)buf, time_ns); | ||
144 | iio_trigger_notify_done(indio_dev->trig); | ||
145 | |||
146 | return IRQ_HANDLED; | ||
147 | } | ||
148 | |||
149 | static const struct iio_ring_setup_ops ad7298_ring_setup_ops = { | ||
150 | .preenable = &ad7298_ring_preenable, | ||
151 | .postenable = &iio_triggered_ring_postenable, | ||
152 | .predisable = &iio_triggered_ring_predisable, | ||
153 | }; | ||
154 | |||
155 | int ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev) | ||
156 | { | ||
157 | int ret; | ||
158 | |||
159 | indio_dev->ring = iio_sw_rb_allocate(indio_dev); | ||
160 | if (!indio_dev->ring) { | ||
161 | ret = -ENOMEM; | ||
162 | goto error_ret; | ||
163 | } | ||
164 | /* Effectively select the ring buffer implementation */ | ||
165 | indio_dev->ring->access = &ring_sw_access_funcs; | ||
166 | |||
167 | indio_dev->pollfunc = iio_alloc_pollfunc(NULL, | ||
168 | &ad7298_trigger_handler, | ||
169 | IRQF_ONESHOT, | ||
170 | indio_dev, | ||
171 | "ad7298_consumer%d", | ||
172 | indio_dev->id); | ||
173 | |||
174 | if (indio_dev->pollfunc == NULL) { | ||
175 | ret = -ENOMEM; | ||
176 | goto error_deallocate_sw_rb; | ||
177 | } | ||
178 | |||
179 | /* Ring buffer functions - here trigger setup related */ | ||
180 | indio_dev->ring->setup_ops = &ad7298_ring_setup_ops; | ||
181 | indio_dev->ring->scan_timestamp = true; | ||
182 | |||
183 | /* Flag that polled ring buffering is possible */ | ||
184 | indio_dev->modes |= INDIO_RING_TRIGGERED; | ||
185 | return 0; | ||
186 | |||
187 | error_deallocate_sw_rb: | ||
188 | iio_sw_rb_free(indio_dev->ring); | ||
189 | error_ret: | ||
190 | return ret; | ||
191 | } | ||
192 | |||
193 | void ad7298_ring_cleanup(struct iio_dev *indio_dev) | ||
194 | { | ||
195 | if (indio_dev->trig) { | ||
196 | iio_put_trigger(indio_dev->trig); | ||
197 | iio_trigger_dettach_poll_func(indio_dev->trig, | ||
198 | indio_dev->pollfunc); | ||
199 | } | ||
200 | iio_dealloc_pollfunc(indio_dev->pollfunc); | ||
201 | iio_sw_rb_free(indio_dev->ring); | ||
202 | } | ||
diff --git a/drivers/staging/iio/adc/ad7314.c b/drivers/staging/iio/adc/ad7314.c new file mode 100644 index 00000000000..9070d9cac72 --- /dev/null +++ b/drivers/staging/iio/adc/ad7314.c | |||
@@ -0,0 +1,281 @@ | |||
1 | /* | ||
2 | * AD7314 digital temperature sensor driver for AD7314, ADT7301 and ADT7302 | ||
3 | * | ||
4 | * Copyright 2010 Analog Devices Inc. | ||
5 | * | ||
6 | * Licensed under the GPL-2 or later. | ||
7 | */ | ||
8 | |||
9 | #include <linux/device.h> | ||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/slab.h> | ||
12 | #include <linux/sysfs.h> | ||
13 | #include <linux/spi/spi.h> | ||
14 | |||
15 | #include "../iio.h" | ||
16 | #include "../sysfs.h" | ||
17 | |||
18 | /* | ||
19 | * AD7314 power mode | ||
20 | */ | ||
21 | #define AD7314_PD 0x2000 | ||
22 | |||
23 | /* | ||
24 | * AD7314 temperature masks | ||
25 | */ | ||
26 | #define AD7314_TEMP_SIGN 0x200 | ||
27 | #define AD7314_TEMP_MASK 0x7FE0 | ||
28 | #define AD7314_TEMP_OFFSET 5 | ||
29 | #define AD7314_TEMP_FLOAT_OFFSET 2 | ||
30 | #define AD7314_TEMP_FLOAT_MASK 0x3 | ||
31 | |||
32 | /* | ||
33 | * ADT7301 and ADT7302 temperature masks | ||
34 | */ | ||
35 | #define ADT7301_TEMP_SIGN 0x2000 | ||
36 | #define ADT7301_TEMP_MASK 0x2FFF | ||
37 | #define ADT7301_TEMP_FLOAT_OFFSET 5 | ||
38 | #define ADT7301_TEMP_FLOAT_MASK 0x1F | ||
39 | |||
40 | /* | ||
41 | * struct ad7314_chip_info - chip specifc information | ||
42 | */ | ||
43 | |||
44 | struct ad7314_chip_info { | ||
45 | struct spi_device *spi_dev; | ||
46 | s64 last_timestamp; | ||
47 | u8 mode; | ||
48 | }; | ||
49 | |||
50 | /* | ||
51 | * ad7314 register access by SPI | ||
52 | */ | ||
53 | |||
54 | static int ad7314_spi_read(struct ad7314_chip_info *chip, u16 *data) | ||
55 | { | ||
56 | struct spi_device *spi_dev = chip->spi_dev; | ||
57 | int ret = 0; | ||
58 | u16 value; | ||
59 | |||
60 | ret = spi_read(spi_dev, (u8 *)&value, sizeof(value)); | ||
61 | if (ret < 0) { | ||
62 | dev_err(&spi_dev->dev, "SPI read error\n"); | ||
63 | return ret; | ||
64 | } | ||
65 | |||
66 | *data = be16_to_cpu((u16)value); | ||
67 | |||
68 | return ret; | ||
69 | } | ||
70 | |||
71 | static int ad7314_spi_write(struct ad7314_chip_info *chip, u16 data) | ||
72 | { | ||
73 | struct spi_device *spi_dev = chip->spi_dev; | ||
74 | int ret = 0; | ||
75 | u16 value = cpu_to_be16(data); | ||
76 | |||
77 | ret = spi_write(spi_dev, (u8 *)&value, sizeof(value)); | ||
78 | if (ret < 0) | ||
79 | dev_err(&spi_dev->dev, "SPI write error\n"); | ||
80 | |||
81 | return ret; | ||
82 | } | ||
83 | |||
84 | static ssize_t ad7314_show_mode(struct device *dev, | ||
85 | struct device_attribute *attr, | ||
86 | char *buf) | ||
87 | { | ||
88 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
89 | struct ad7314_chip_info *chip = iio_priv(dev_info); | ||
90 | |||
91 | if (chip->mode) | ||
92 | return sprintf(buf, "power-save\n"); | ||
93 | else | ||
94 | return sprintf(buf, "full\n"); | ||
95 | } | ||
96 | |||
97 | static ssize_t ad7314_store_mode(struct device *dev, | ||
98 | struct device_attribute *attr, | ||
99 | const char *buf, | ||
100 | size_t len) | ||
101 | { | ||
102 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
103 | struct ad7314_chip_info *chip = iio_priv(dev_info); | ||
104 | u16 mode = 0; | ||
105 | int ret; | ||
106 | |||
107 | if (!strcmp(buf, "full")) | ||
108 | mode = AD7314_PD; | ||
109 | |||
110 | ret = ad7314_spi_write(chip, mode); | ||
111 | if (ret) | ||
112 | return -EIO; | ||
113 | |||
114 | chip->mode = mode; | ||
115 | |||
116 | return len; | ||
117 | } | ||
118 | |||
119 | static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, | ||
120 | ad7314_show_mode, | ||
121 | ad7314_store_mode, | ||
122 | 0); | ||
123 | |||
124 | static ssize_t ad7314_show_available_modes(struct device *dev, | ||
125 | struct device_attribute *attr, | ||
126 | char *buf) | ||
127 | { | ||
128 | return sprintf(buf, "full\npower-save\n"); | ||
129 | } | ||
130 | |||
131 | static IIO_DEVICE_ATTR(available_modes, S_IRUGO, ad7314_show_available_modes, NULL, 0); | ||
132 | |||
133 | static ssize_t ad7314_show_temperature(struct device *dev, | ||
134 | struct device_attribute *attr, | ||
135 | char *buf) | ||
136 | { | ||
137 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
138 | struct ad7314_chip_info *chip = iio_priv(dev_info); | ||
139 | u16 data; | ||
140 | char sign = ' '; | ||
141 | int ret; | ||
142 | |||
143 | if (chip->mode) { | ||
144 | ret = ad7314_spi_write(chip, 0); | ||
145 | if (ret) | ||
146 | return -EIO; | ||
147 | } | ||
148 | |||
149 | ret = ad7314_spi_read(chip, &data); | ||
150 | if (ret) | ||
151 | return -EIO; | ||
152 | |||
153 | if (chip->mode) | ||
154 | ad7314_spi_write(chip, chip->mode); | ||
155 | |||
156 | if (strcmp(dev_info->name, "ad7314")) { | ||
157 | data = (data & AD7314_TEMP_MASK) >> | ||
158 | AD7314_TEMP_OFFSET; | ||
159 | if (data & AD7314_TEMP_SIGN) { | ||
160 | data = (AD7314_TEMP_SIGN << 1) - data; | ||
161 | sign = '-'; | ||
162 | } | ||
163 | |||
164 | return sprintf(buf, "%c%d.%.2d\n", sign, | ||
165 | data >> AD7314_TEMP_FLOAT_OFFSET, | ||
166 | (data & AD7314_TEMP_FLOAT_MASK) * 25); | ||
167 | } else { | ||
168 | data &= ADT7301_TEMP_MASK; | ||
169 | if (data & ADT7301_TEMP_SIGN) { | ||
170 | data = (ADT7301_TEMP_SIGN << 1) - data; | ||
171 | sign = '-'; | ||
172 | } | ||
173 | |||
174 | return sprintf(buf, "%c%d.%.5d\n", sign, | ||
175 | data >> ADT7301_TEMP_FLOAT_OFFSET, | ||
176 | (data & ADT7301_TEMP_FLOAT_MASK) * 3125); | ||
177 | } | ||
178 | } | ||
179 | |||
180 | static IIO_DEVICE_ATTR(temperature, S_IRUGO, ad7314_show_temperature, NULL, 0); | ||
181 | |||
182 | static struct attribute *ad7314_attributes[] = { | ||
183 | &iio_dev_attr_available_modes.dev_attr.attr, | ||
184 | &iio_dev_attr_mode.dev_attr.attr, | ||
185 | &iio_dev_attr_temperature.dev_attr.attr, | ||
186 | NULL, | ||
187 | }; | ||
188 | |||
189 | static const struct attribute_group ad7314_attribute_group = { | ||
190 | .attrs = ad7314_attributes, | ||
191 | }; | ||
192 | |||
193 | static const struct iio_info ad7314_info = { | ||
194 | .attrs = &ad7314_attribute_group, | ||
195 | .driver_module = THIS_MODULE, | ||
196 | }; | ||
197 | /* | ||
198 | * device probe and remove | ||
199 | */ | ||
200 | |||
201 | static int __devinit ad7314_probe(struct spi_device *spi_dev) | ||
202 | { | ||
203 | struct ad7314_chip_info *chip; | ||
204 | struct iio_dev *indio_dev; | ||
205 | int ret = 0; | ||
206 | |||
207 | indio_dev = iio_allocate_device(sizeof(*chip)); | ||
208 | if (indio_dev == NULL) { | ||
209 | ret = -ENOMEM; | ||
210 | goto error_ret; | ||
211 | } | ||
212 | chip = iio_priv(indio_dev); | ||
213 | /* this is only used for device removal purposes */ | ||
214 | dev_set_drvdata(&spi_dev->dev, chip); | ||
215 | |||
216 | chip->spi_dev = spi_dev; | ||
217 | |||
218 | indio_dev->name = spi_get_device_id(spi_dev)->name; | ||
219 | indio_dev->dev.parent = &spi_dev->dev; | ||
220 | indio_dev->info = &ad7314_info; | ||
221 | |||
222 | ret = iio_device_register(indio_dev); | ||
223 | if (ret) | ||
224 | goto error_free_dev; | ||
225 | |||
226 | dev_info(&spi_dev->dev, "%s temperature sensor registered.\n", | ||
227 | indio_dev->name); | ||
228 | |||
229 | return 0; | ||
230 | error_free_dev: | ||
231 | iio_free_device(indio_dev); | ||
232 | error_ret: | ||
233 | return ret; | ||
234 | } | ||
235 | |||
236 | static int __devexit ad7314_remove(struct spi_device *spi_dev) | ||
237 | { | ||
238 | struct iio_dev *indio_dev = dev_get_drvdata(&spi_dev->dev); | ||
239 | |||
240 | dev_set_drvdata(&spi_dev->dev, NULL); | ||
241 | iio_device_unregister(indio_dev); | ||
242 | iio_free_device(indio_dev); | ||
243 | |||
244 | return 0; | ||
245 | } | ||
246 | |||
247 | static const struct spi_device_id ad7314_id[] = { | ||
248 | { "adt7301", 0 }, | ||
249 | { "adt7302", 0 }, | ||
250 | { "ad7314", 0 }, | ||
251 | {} | ||
252 | }; | ||
253 | |||
254 | static struct spi_driver ad7314_driver = { | ||
255 | .driver = { | ||
256 | .name = "ad7314", | ||
257 | .bus = &spi_bus_type, | ||
258 | .owner = THIS_MODULE, | ||
259 | }, | ||
260 | .probe = ad7314_probe, | ||
261 | .remove = __devexit_p(ad7314_remove), | ||
262 | .id_table = ad7314_id, | ||
263 | }; | ||
264 | |||
265 | static __init int ad7314_init(void) | ||
266 | { | ||
267 | return spi_register_driver(&ad7314_driver); | ||
268 | } | ||
269 | |||
270 | static __exit void ad7314_exit(void) | ||
271 | { | ||
272 | spi_unregister_driver(&ad7314_driver); | ||
273 | } | ||
274 | |||
275 | MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>"); | ||
276 | MODULE_DESCRIPTION("Analog Devices AD7314, ADT7301 and ADT7302 digital" | ||
277 | " temperature sensor driver"); | ||
278 | MODULE_LICENSE("GPL v2"); | ||
279 | |||
280 | module_init(ad7314_init); | ||
281 | module_exit(ad7314_exit); | ||
diff --git a/drivers/staging/iio/adc/ad7476.h b/drivers/staging/iio/adc/ad7476.h new file mode 100644 index 00000000000..0d44976e846 --- /dev/null +++ b/drivers/staging/iio/adc/ad7476.h | |||
@@ -0,0 +1,72 @@ | |||
1 | /* | ||
2 | * AD7476/5/7/8 (A) SPI ADC driver | ||
3 | * | ||
4 | * Copyright 2010 Analog Devices Inc. | ||
5 | * | ||
6 | * Licensed under the GPL-2 or later. | ||
7 | */ | ||
8 | #ifndef IIO_ADC_AD7476_H_ | ||
9 | #define IIO_ADC_AD7476_H_ | ||
10 | |||
11 | #define RES_MASK(bits) ((1 << (bits)) - 1) | ||
12 | |||
13 | /* | ||
14 | * TODO: struct ad7476_platform_data needs to go into include/linux/iio | ||
15 | */ | ||
16 | |||
17 | struct ad7476_platform_data { | ||
18 | u16 vref_mv; | ||
19 | }; | ||
20 | |||
21 | struct ad7476_chip_info { | ||
22 | u16 int_vref_mv; | ||
23 | struct iio_chan_spec channel[2]; | ||
24 | }; | ||
25 | |||
26 | struct ad7476_state { | ||
27 | struct spi_device *spi; | ||
28 | const struct ad7476_chip_info *chip_info; | ||
29 | struct regulator *reg; | ||
30 | size_t d_size; | ||
31 | u16 int_vref_mv; | ||
32 | struct spi_transfer xfer; | ||
33 | struct spi_message msg; | ||
34 | /* | ||
35 | * DMA (thus cache coherency maintenance) requires the | ||
36 | * transfer buffers to live in their own cache lines. | ||
37 | */ | ||
38 | unsigned char data[2] ____cacheline_aligned; | ||
39 | }; | ||
40 | |||
41 | enum ad7476_supported_device_ids { | ||
42 | ID_AD7466, | ||
43 | ID_AD7467, | ||
44 | ID_AD7468, | ||
45 | ID_AD7475, | ||
46 | ID_AD7476, | ||
47 | ID_AD7477, | ||
48 | ID_AD7478, | ||
49 | ID_AD7495 | ||
50 | }; | ||
51 | |||
52 | #ifdef CONFIG_IIO_RING_BUFFER | ||
53 | int ad7476_scan_from_ring(struct iio_dev *indio_dev); | ||
54 | int ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev); | ||
55 | void ad7476_ring_cleanup(struct iio_dev *indio_dev); | ||
56 | #else /* CONFIG_IIO_RING_BUFFER */ | ||
57 | static inline int ad7476_scan_from_ring(struct iio_dev *indio_dev) | ||
58 | { | ||
59 | return 0; | ||
60 | } | ||
61 | |||
62 | static inline int | ||
63 | ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev) | ||
64 | { | ||
65 | return 0; | ||
66 | } | ||
67 | |||
68 | static inline void ad7476_ring_cleanup(struct iio_dev *indio_dev) | ||
69 | { | ||
70 | } | ||
71 | #endif /* CONFIG_IIO_RING_BUFFER */ | ||
72 | #endif /* IIO_ADC_AD7476_H_ */ | ||
diff --git a/drivers/staging/iio/adc/ad7476_core.c b/drivers/staging/iio/adc/ad7476_core.c new file mode 100644 index 00000000000..c21089894d2 --- /dev/null +++ b/drivers/staging/iio/adc/ad7476_core.c | |||
@@ -0,0 +1,270 @@ | |||
1 | /* | ||
2 | * AD7466/7/8 AD7476/5/7/8 (A) SPI ADC driver | ||
3 | * | ||
4 | * Copyright 2010 Analog Devices Inc. | ||
5 | * | ||
6 | * Licensed under the GPL-2 or later. | ||
7 | */ | ||
8 | |||
9 | #include <linux/device.h> | ||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/slab.h> | ||
12 | #include <linux/sysfs.h> | ||
13 | #include <linux/spi/spi.h> | ||
14 | #include <linux/regulator/consumer.h> | ||
15 | #include <linux/err.h> | ||
16 | |||
17 | #include "../iio.h" | ||
18 | #include "../sysfs.h" | ||
19 | #include "../ring_generic.h" | ||
20 | #include "adc.h" | ||
21 | |||
22 | #include "ad7476.h" | ||
23 | |||
24 | static int ad7476_scan_direct(struct ad7476_state *st) | ||
25 | { | ||
26 | int ret; | ||
27 | |||
28 | ret = spi_sync(st->spi, &st->msg); | ||
29 | if (ret) | ||
30 | return ret; | ||
31 | |||
32 | return (st->data[0] << 8) | st->data[1]; | ||
33 | } | ||
34 | |||
35 | static int ad7476_read_raw(struct iio_dev *dev_info, | ||
36 | struct iio_chan_spec const *chan, | ||
37 | int *val, | ||
38 | int *val2, | ||
39 | long m) | ||
40 | { | ||
41 | int ret; | ||
42 | struct ad7476_state *st = iio_priv(dev_info); | ||
43 | unsigned int scale_uv; | ||
44 | |||
45 | switch (m) { | ||
46 | case 0: | ||
47 | mutex_lock(&dev_info->mlock); | ||
48 | if (iio_ring_enabled(dev_info)) | ||
49 | ret = ad7476_scan_from_ring(dev_info); | ||
50 | else | ||
51 | ret = ad7476_scan_direct(st); | ||
52 | mutex_unlock(&dev_info->mlock); | ||
53 | |||
54 | if (ret < 0) | ||
55 | return ret; | ||
56 | *val = (ret >> st->chip_info->channel[0].scan_type.shift) & | ||
57 | RES_MASK(st->chip_info->channel[0].scan_type.realbits); | ||
58 | return IIO_VAL_INT; | ||
59 | case (1 << IIO_CHAN_INFO_SCALE_SHARED): | ||
60 | scale_uv = (st->int_vref_mv * 1000) | ||
61 | >> st->chip_info->channel[0].scan_type.realbits; | ||
62 | *val = scale_uv/1000; | ||
63 | *val2 = (scale_uv%1000)*1000; | ||
64 | return IIO_VAL_INT_PLUS_MICRO; | ||
65 | } | ||
66 | return -EINVAL; | ||
67 | } | ||
68 | |||
69 | static const struct ad7476_chip_info ad7476_chip_info_tbl[] = { | ||
70 | [ID_AD7466] = { | ||
71 | .channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0, | ||
72 | (1 << IIO_CHAN_INFO_SCALE_SHARED), | ||
73 | 0, 0, IIO_ST('u', 12, 16, 0), 0), | ||
74 | .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), | ||
75 | }, | ||
76 | [ID_AD7467] = { | ||
77 | .channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0, | ||
78 | (1 << IIO_CHAN_INFO_SCALE_SHARED), | ||
79 | 0, 0, IIO_ST('u', 10, 16, 2), 0), | ||
80 | .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), | ||
81 | }, | ||
82 | [ID_AD7468] = { | ||
83 | .channel[0] = IIO_CHAN(IIO_IN, 0, 1 , 0, NULL, 0, 0, | ||
84 | (1 << IIO_CHAN_INFO_SCALE_SHARED), | ||
85 | 0, 0, IIO_ST('u', 8, 16, 4), 0), | ||
86 | .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), | ||
87 | }, | ||
88 | [ID_AD7475] = { | ||
89 | .channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0, | ||
90 | (1 << IIO_CHAN_INFO_SCALE_SHARED), | ||
91 | 0, 0, IIO_ST('u', 12, 16, 0), 0), | ||
92 | .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), | ||
93 | }, | ||
94 | [ID_AD7476] = { | ||
95 | .channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0, | ||
96 | (1 << IIO_CHAN_INFO_SCALE_SHARED), | ||
97 | 0, 0, IIO_ST('u', 12, 16, 0), 0), | ||
98 | .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), | ||
99 | }, | ||
100 | [ID_AD7477] = { | ||
101 | .channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0, | ||
102 | (1 << IIO_CHAN_INFO_SCALE_SHARED), | ||
103 | 0, 0, IIO_ST('u', 10, 16, 2), 0), | ||
104 | .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), | ||
105 | }, | ||
106 | [ID_AD7478] = { | ||
107 | .channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0, | ||
108 | (1 << IIO_CHAN_INFO_SCALE_SHARED), | ||
109 | 0, 0, IIO_ST('u', 8, 16, 4), 0), | ||
110 | .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), | ||
111 | }, | ||
112 | [ID_AD7495] = { | ||
113 | .channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0, | ||
114 | (1 << IIO_CHAN_INFO_SCALE_SHARED), | ||
115 | 0, 0, IIO_ST('u', 12, 16, 0), 0), | ||
116 | .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), | ||
117 | .int_vref_mv = 2500, | ||
118 | }, | ||
119 | }; | ||
120 | |||
121 | static const struct iio_info ad7476_info = { | ||
122 | .driver_module = THIS_MODULE, | ||
123 | .read_raw = &ad7476_read_raw, | ||
124 | }; | ||
125 | |||
126 | static int __devinit ad7476_probe(struct spi_device *spi) | ||
127 | { | ||
128 | struct ad7476_platform_data *pdata = spi->dev.platform_data; | ||
129 | struct ad7476_state *st; | ||
130 | struct iio_dev *indio_dev; | ||
131 | int ret, voltage_uv = 0; | ||
132 | bool reg_done = false; | ||
133 | struct regulator *reg; | ||
134 | |||
135 | indio_dev = iio_allocate_device(sizeof(*st)); | ||
136 | if (indio_dev == NULL) { | ||
137 | ret = -ENOMEM; | ||
138 | goto error_ret; | ||
139 | } | ||
140 | st = iio_priv(indio_dev); | ||
141 | reg = regulator_get(&spi->dev, "vcc"); | ||
142 | if (!IS_ERR(reg)) { | ||
143 | ret = regulator_enable(reg); | ||
144 | if (ret) | ||
145 | goto error_put_reg; | ||
146 | |||
147 | voltage_uv = regulator_get_voltage(reg); | ||
148 | } | ||
149 | st->reg = reg; | ||
150 | st->chip_info = | ||
151 | &ad7476_chip_info_tbl[spi_get_device_id(spi)->driver_data]; | ||
152 | |||
153 | if (st->chip_info->int_vref_mv) | ||
154 | st->int_vref_mv = st->chip_info->int_vref_mv; | ||
155 | else if (pdata && pdata->vref_mv) | ||
156 | st->int_vref_mv = pdata->vref_mv; | ||
157 | else if (voltage_uv) | ||
158 | st->int_vref_mv = voltage_uv / 1000; | ||
159 | else | ||
160 | dev_warn(&spi->dev, "reference voltage unspecified\n"); | ||
161 | |||
162 | spi_set_drvdata(spi, indio_dev); | ||
163 | |||
164 | st->spi = spi; | ||
165 | |||
166 | /* Establish that the iio_dev is a child of the spi device */ | ||
167 | indio_dev->dev.parent = &spi->dev; | ||
168 | indio_dev->name = spi_get_device_id(spi)->name; | ||
169 | indio_dev->modes = INDIO_DIRECT_MODE; | ||
170 | indio_dev->channels = st->chip_info->channel; | ||
171 | indio_dev->num_channels = 2; | ||
172 | indio_dev->info = &ad7476_info; | ||
173 | /* Setup default message */ | ||
174 | |||
175 | st->xfer.rx_buf = &st->data; | ||
176 | st->xfer.len = st->chip_info->channel[0].scan_type.storagebits / 8; | ||
177 | |||
178 | spi_message_init(&st->msg); | ||
179 | spi_message_add_tail(&st->xfer, &st->msg); | ||
180 | |||
181 | ret = ad7476_register_ring_funcs_and_init(indio_dev); | ||
182 | if (ret) | ||
183 | goto error_disable_reg; | ||
184 | |||
185 | ret = iio_device_register(indio_dev); | ||
186 | if (ret) | ||
187 | goto error_disable_reg; | ||
188 | |||
189 | ret = iio_ring_buffer_register_ex(indio_dev->ring, 0, | ||
190 | st->chip_info->channel, | ||
191 | ARRAY_SIZE(st->chip_info->channel)); | ||
192 | if (ret) | ||
193 | goto error_cleanup_ring; | ||
194 | return 0; | ||
195 | |||
196 | error_cleanup_ring: | ||
197 | ad7476_ring_cleanup(indio_dev); | ||
198 | iio_device_unregister(indio_dev); | ||
199 | error_disable_reg: | ||
200 | if (!IS_ERR(reg)) | ||
201 | regulator_disable(st->reg); | ||
202 | error_put_reg: | ||
203 | if (!IS_ERR(reg)) | ||
204 | regulator_put(reg); | ||
205 | if (!reg_done) | ||
206 | iio_free_device(indio_dev); | ||
207 | error_ret: | ||
208 | return ret; | ||
209 | } | ||
210 | |||
211 | static int ad7476_remove(struct spi_device *spi) | ||
212 | { | ||
213 | struct iio_dev *indio_dev = spi_get_drvdata(spi); | ||
214 | struct ad7476_state *st = iio_priv(indio_dev); | ||
215 | /* copy needed as st will have been freed */ | ||
216 | struct regulator *reg = st->reg; | ||
217 | |||
218 | iio_ring_buffer_unregister(indio_dev->ring); | ||
219 | ad7476_ring_cleanup(indio_dev); | ||
220 | iio_device_unregister(indio_dev); | ||
221 | if (!IS_ERR(reg)) { | ||
222 | regulator_disable(reg); | ||
223 | regulator_put(reg); | ||
224 | } | ||
225 | |||
226 | return 0; | ||
227 | } | ||
228 | |||
229 | static const struct spi_device_id ad7476_id[] = { | ||
230 | {"ad7466", ID_AD7466}, | ||
231 | {"ad7467", ID_AD7467}, | ||
232 | {"ad7468", ID_AD7468}, | ||
233 | {"ad7475", ID_AD7475}, | ||
234 | {"ad7476", ID_AD7476}, | ||
235 | {"ad7476a", ID_AD7476}, | ||
236 | {"ad7477", ID_AD7477}, | ||
237 | {"ad7477a", ID_AD7477}, | ||
238 | {"ad7478", ID_AD7478}, | ||
239 | {"ad7478a", ID_AD7478}, | ||
240 | {"ad7495", ID_AD7495}, | ||
241 | {} | ||
242 | }; | ||
243 | |||
244 | static struct spi_driver ad7476_driver = { | ||
245 | .driver = { | ||
246 | .name = "ad7476", | ||
247 | .bus = &spi_bus_type, | ||
248 | .owner = THIS_MODULE, | ||
249 | }, | ||
250 | .probe = ad7476_probe, | ||
251 | .remove = __devexit_p(ad7476_remove), | ||
252 | .id_table = ad7476_id, | ||
253 | }; | ||
254 | |||
255 | static int __init ad7476_init(void) | ||
256 | { | ||
257 | return spi_register_driver(&ad7476_driver); | ||
258 | } | ||
259 | module_init(ad7476_init); | ||
260 | |||
261 | static void __exit ad7476_exit(void) | ||
262 | { | ||
263 | spi_unregister_driver(&ad7476_driver); | ||
264 | } | ||
265 | module_exit(ad7476_exit); | ||
266 | |||
267 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | ||
268 | MODULE_DESCRIPTION("Analog Devices AD7475/6/7/8(A) AD7466/7/8 ADC"); | ||
269 | MODULE_LICENSE("GPL v2"); | ||
270 | MODULE_ALIAS("spi:ad7476"); | ||
diff --git a/drivers/staging/iio/adc/ad7476_ring.c b/drivers/staging/iio/adc/ad7476_ring.c new file mode 100644 index 00000000000..a92fc5a1a60 --- /dev/null +++ b/drivers/staging/iio/adc/ad7476_ring.c | |||
@@ -0,0 +1,165 @@ | |||
1 | /* | ||
2 | * Copyright 2010 Analog Devices Inc. | ||
3 | * Copyright (C) 2008 Jonathan Cameron | ||
4 | * | ||
5 | * Licensed under the GPL-2 or later. | ||
6 | * | ||
7 | * ad7476_ring.c | ||
8 | */ | ||
9 | |||
10 | #include <linux/interrupt.h> | ||
11 | #include <linux/device.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/sysfs.h> | ||
15 | #include <linux/spi/spi.h> | ||
16 | |||
17 | #include "../iio.h" | ||
18 | #include "../ring_generic.h" | ||
19 | #include "../ring_sw.h" | ||
20 | #include "../trigger.h" | ||
21 | #include "../sysfs.h" | ||
22 | |||
23 | #include "ad7476.h" | ||
24 | |||
25 | int ad7476_scan_from_ring(struct iio_dev *indio_dev) | ||
26 | { | ||
27 | struct iio_ring_buffer *ring = indio_dev->ring; | ||
28 | int ret; | ||
29 | u8 *ring_data; | ||
30 | |||
31 | ring_data = kmalloc(ring->access->get_bytes_per_datum(ring), | ||
32 | GFP_KERNEL); | ||
33 | if (ring_data == NULL) { | ||
34 | ret = -ENOMEM; | ||
35 | goto error_ret; | ||
36 | } | ||
37 | ret = ring->access->read_last(ring, ring_data); | ||
38 | if (ret) | ||
39 | goto error_free_ring_data; | ||
40 | |||
41 | ret = (ring_data[0] << 8) | ring_data[1]; | ||
42 | |||
43 | error_free_ring_data: | ||
44 | kfree(ring_data); | ||
45 | error_ret: | ||
46 | return ret; | ||
47 | } | ||
48 | |||
49 | /** | ||
50 | * ad7476_ring_preenable() setup the parameters of the ring before enabling | ||
51 | * | ||
52 | * The complex nature of the setting of the nuber of bytes per datum is due | ||
53 | * to this driver currently ensuring that the timestamp is stored at an 8 | ||
54 | * byte boundary. | ||
55 | **/ | ||
56 | static int ad7476_ring_preenable(struct iio_dev *indio_dev) | ||
57 | { | ||
58 | struct ad7476_state *st = iio_priv(indio_dev); | ||
59 | struct iio_ring_buffer *ring = indio_dev->ring; | ||
60 | |||
61 | st->d_size = ring->scan_count * | ||
62 | st->chip_info->channel[0].scan_type.storagebits / 8; | ||
63 | |||
64 | if (ring->scan_timestamp) { | ||
65 | st->d_size += sizeof(s64); | ||
66 | |||
67 | if (st->d_size % sizeof(s64)) | ||
68 | st->d_size += sizeof(s64) - (st->d_size % sizeof(s64)); | ||
69 | } | ||
70 | |||
71 | if (indio_dev->ring->access->set_bytes_per_datum) | ||
72 | indio_dev->ring->access->set_bytes_per_datum(indio_dev->ring, | ||
73 | st->d_size); | ||
74 | |||
75 | return 0; | ||
76 | } | ||
77 | |||
78 | static irqreturn_t ad7476_trigger_handler(int irq, void *p) | ||
79 | { | ||
80 | struct iio_poll_func *pf = p; | ||
81 | struct iio_dev *indio_dev = pf->private_data; | ||
82 | struct ad7476_state *st = iio_priv(indio_dev); | ||
83 | s64 time_ns; | ||
84 | __u8 *rxbuf; | ||
85 | int b_sent; | ||
86 | |||
87 | rxbuf = kzalloc(st->d_size, GFP_KERNEL); | ||
88 | if (rxbuf == NULL) | ||
89 | return -ENOMEM; | ||
90 | |||
91 | b_sent = spi_read(st->spi, rxbuf, | ||
92 | st->chip_info->channel[0].scan_type.storagebits / 8); | ||
93 | if (b_sent < 0) | ||
94 | goto done; | ||
95 | |||
96 | time_ns = iio_get_time_ns(); | ||
97 | |||
98 | if (indio_dev->ring->scan_timestamp) | ||
99 | memcpy(rxbuf + st->d_size - sizeof(s64), | ||
100 | &time_ns, sizeof(time_ns)); | ||
101 | |||
102 | indio_dev->ring->access->store_to(indio_dev->ring, rxbuf, time_ns); | ||
103 | done: | ||
104 | iio_trigger_notify_done(indio_dev->trig); | ||
105 | kfree(rxbuf); | ||
106 | |||
107 | return IRQ_HANDLED; | ||
108 | } | ||
109 | |||
110 | static const struct iio_ring_setup_ops ad7476_ring_setup_ops = { | ||
111 | .preenable = &ad7476_ring_preenable, | ||
112 | .postenable = &iio_triggered_ring_postenable, | ||
113 | .predisable = &iio_triggered_ring_predisable, | ||
114 | }; | ||
115 | |||
116 | int ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev) | ||
117 | { | ||
118 | struct ad7476_state *st = iio_priv(indio_dev); | ||
119 | int ret = 0; | ||
120 | |||
121 | indio_dev->ring = iio_sw_rb_allocate(indio_dev); | ||
122 | if (!indio_dev->ring) { | ||
123 | ret = -ENOMEM; | ||
124 | goto error_ret; | ||
125 | } | ||
126 | /* Effectively select the ring buffer implementation */ | ||
127 | indio_dev->ring->access = &ring_sw_access_funcs; | ||
128 | indio_dev->pollfunc | ||
129 | = iio_alloc_pollfunc(NULL, | ||
130 | &ad7476_trigger_handler, | ||
131 | IRQF_ONESHOT, | ||
132 | indio_dev, | ||
133 | "%s_consumer%d", | ||
134 | spi_get_device_id(st->spi)->name, | ||
135 | indio_dev->id); | ||
136 | if (indio_dev->pollfunc == NULL) { | ||
137 | ret = -ENOMEM; | ||
138 | goto error_deallocate_sw_rb; | ||
139 | } | ||
140 | |||
141 | /* Ring buffer functions - here trigger setup related */ | ||
142 | indio_dev->ring->setup_ops = &ad7476_ring_setup_ops; | ||
143 | indio_dev->ring->scan_timestamp = true; | ||
144 | |||
145 | /* Flag that polled ring buffering is possible */ | ||
146 | indio_dev->modes |= INDIO_RING_TRIGGERED; | ||
147 | return 0; | ||
148 | |||
149 | error_deallocate_sw_rb: | ||
150 | iio_sw_rb_free(indio_dev->ring); | ||
151 | error_ret: | ||
152 | return ret; | ||
153 | } | ||
154 | |||
155 | void ad7476_ring_cleanup(struct iio_dev *indio_dev) | ||
156 | { | ||
157 | /* ensure that the trigger has been detached */ | ||
158 | if (indio_dev->trig) { | ||
159 | iio_put_trigger(indio_dev->trig); | ||
160 | iio_trigger_dettach_poll_func(indio_dev->trig, | ||
161 | indio_dev->pollfunc); | ||
162 | } | ||
163 | iio_dealloc_pollfunc(indio_dev->pollfunc); | ||
164 | iio_sw_rb_free(indio_dev->ring); | ||
165 | } | ||
diff --git a/drivers/staging/iio/adc/ad7745.c b/drivers/staging/iio/adc/ad7745.c new file mode 100644 index 00000000000..4c13f26aa9a --- /dev/null +++ b/drivers/staging/iio/adc/ad7745.c | |||
@@ -0,0 +1,674 @@ | |||
1 | /* | ||
2 | * AD774X capacitive sensor driver supporting AD7745/6/7 | ||
3 | * | ||
4 | * Copyright 2010 Analog Devices Inc. | ||
5 | * | ||
6 | * Licensed under the GPL-2 or later. | ||
7 | */ | ||
8 | |||
9 | #include <linux/interrupt.h> | ||
10 | #include <linux/gpio.h> | ||
11 | #include <linux/device.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/sysfs.h> | ||
15 | #include <linux/list.h> | ||
16 | #include <linux/i2c.h> | ||
17 | |||
18 | #include "../iio.h" | ||
19 | #include "../sysfs.h" | ||
20 | |||
21 | /* | ||
22 | * AD774X registers definition | ||
23 | */ | ||
24 | |||
25 | #define AD774X_STATUS 0 | ||
26 | #define AD774X_STATUS_RDY (1 << 2) | ||
27 | #define AD774X_STATUS_RDYVT (1 << 1) | ||
28 | #define AD774X_STATUS_RDYCAP (1 << 0) | ||
29 | #define AD774X_CAP_DATA_HIGH 1 | ||
30 | #define AD774X_CAP_DATA_MID 2 | ||
31 | #define AD774X_CAP_DATA_LOW 3 | ||
32 | #define AD774X_VT_DATA_HIGH 4 | ||
33 | #define AD774X_VT_DATA_MID 5 | ||
34 | #define AD774X_VT_DATA_LOW 6 | ||
35 | #define AD774X_CAP_SETUP 7 | ||
36 | #define AD774X_VT_SETUP 8 | ||
37 | #define AD774X_EXEC_SETUP 9 | ||
38 | #define AD774X_CFG 10 | ||
39 | #define AD774X_CAPDACA 11 | ||
40 | #define AD774X_CAPDACB 12 | ||
41 | #define AD774X_CAPDAC_EN (1 << 7) | ||
42 | #define AD774X_CAP_OFFH 13 | ||
43 | #define AD774X_CAP_OFFL 14 | ||
44 | #define AD774X_CAP_GAINH 15 | ||
45 | #define AD774X_CAP_GAINL 16 | ||
46 | #define AD774X_VOLT_GAINH 17 | ||
47 | #define AD774X_VOLT_GAINL 18 | ||
48 | |||
49 | #define AD774X_MAX_CONV_MODE 6 | ||
50 | |||
51 | /* | ||
52 | * struct ad774x_chip_info - chip specifc information | ||
53 | */ | ||
54 | |||
55 | struct ad774x_chip_info { | ||
56 | struct i2c_client *client; | ||
57 | bool inter; | ||
58 | u16 cap_offs; /* Capacitive offset */ | ||
59 | u16 cap_gain; /* Capacitive gain calibration */ | ||
60 | u16 volt_gain; /* Voltage gain calibration */ | ||
61 | u8 cap_setup; | ||
62 | u8 vt_setup; | ||
63 | u8 exec_setup; | ||
64 | |||
65 | char *conversion_mode; | ||
66 | }; | ||
67 | |||
68 | struct ad774x_conversion_mode { | ||
69 | char *name; | ||
70 | u8 reg_cfg; | ||
71 | }; | ||
72 | |||
73 | static struct ad774x_conversion_mode | ||
74 | ad774x_conv_mode_table[AD774X_MAX_CONV_MODE] = { | ||
75 | { "idle", 0 }, | ||
76 | { "continuous-conversion", 1 }, | ||
77 | { "single-conversion", 2 }, | ||
78 | { "power-down", 3 }, | ||
79 | { "offset-calibration", 5 }, | ||
80 | { "gain-calibration", 6 }, | ||
81 | }; | ||
82 | |||
83 | /* | ||
84 | * ad774x register access by I2C | ||
85 | */ | ||
86 | |||
87 | static int ad774x_i2c_read(struct ad774x_chip_info *chip, u8 reg, u8 *data, int len) | ||
88 | { | ||
89 | struct i2c_client *client = chip->client; | ||
90 | int ret; | ||
91 | |||
92 | ret = i2c_master_send(client, ®, 1); | ||
93 | if (ret < 0) { | ||
94 | dev_err(&client->dev, "I2C write error\n"); | ||
95 | return ret; | ||
96 | } | ||
97 | |||
98 | ret = i2c_master_recv(client, data, len); | ||
99 | if (ret < 0) { | ||
100 | dev_err(&client->dev, "I2C read error\n"); | ||
101 | return ret; | ||
102 | } | ||
103 | |||
104 | return ret; | ||
105 | } | ||
106 | |||
107 | static int ad774x_i2c_write(struct ad774x_chip_info *chip, u8 reg, u8 data) | ||
108 | { | ||
109 | struct i2c_client *client = chip->client; | ||
110 | int ret; | ||
111 | |||
112 | u8 tx[2] = { | ||
113 | reg, | ||
114 | data, | ||
115 | }; | ||
116 | |||
117 | ret = i2c_master_send(client, tx, 2); | ||
118 | if (ret < 0) | ||
119 | dev_err(&client->dev, "I2C write error\n"); | ||
120 | |||
121 | return ret; | ||
122 | } | ||
123 | |||
124 | /* | ||
125 | * sysfs nodes | ||
126 | */ | ||
127 | |||
128 | #define IIO_DEV_ATTR_AVAIL_CONVERSION_MODES(_show) \ | ||
129 | IIO_DEVICE_ATTR(available_conversion_modes, S_IRUGO, _show, NULL, 0) | ||
130 | #define IIO_DEV_ATTR_CONVERSION_MODE(_mode, _show, _store) \ | ||
131 | IIO_DEVICE_ATTR(conversion_mode, _mode, _show, _store, 0) | ||
132 | #define IIO_DEV_ATTR_CAP_SETUP(_mode, _show, _store) \ | ||
133 | IIO_DEVICE_ATTR(cap_setup, _mode, _show, _store, 0) | ||
134 | #define IIO_DEV_ATTR_VT_SETUP(_mode, _show, _store) \ | ||
135 | IIO_DEVICE_ATTR(in0_setup, _mode, _show, _store, 0) | ||
136 | #define IIO_DEV_ATTR_EXEC_SETUP(_mode, _show, _store) \ | ||
137 | IIO_DEVICE_ATTR(exec_setup, _mode, _show, _store, 0) | ||
138 | #define IIO_DEV_ATTR_VOLT_GAIN(_mode, _show, _store) \ | ||
139 | IIO_DEVICE_ATTR(in0_gain, _mode, _show, _store, 0) | ||
140 | #define IIO_DEV_ATTR_CAP_OFFS(_mode, _show, _store) \ | ||
141 | IIO_DEVICE_ATTR(cap_offs, _mode, _show, _store, 0) | ||
142 | #define IIO_DEV_ATTR_CAP_GAIN(_mode, _show, _store) \ | ||
143 | IIO_DEVICE_ATTR(cap_gain, _mode, _show, _store, 0) | ||
144 | #define IIO_DEV_ATTR_CAP_DATA(_show) \ | ||
145 | IIO_DEVICE_ATTR(cap0_raw, S_IRUGO, _show, NULL, 0) | ||
146 | #define IIO_DEV_ATTR_VT_DATA(_show) \ | ||
147 | IIO_DEVICE_ATTR(in0_raw, S_IRUGO, _show, NULL, 0) | ||
148 | |||
149 | static ssize_t ad774x_show_conversion_modes(struct device *dev, | ||
150 | struct device_attribute *attr, | ||
151 | char *buf) | ||
152 | { | ||
153 | int i; | ||
154 | int len = 0; | ||
155 | |||
156 | for (i = 0; i < AD774X_MAX_CONV_MODE; i++) | ||
157 | len += sprintf(buf + len, "%s ", ad774x_conv_mode_table[i].name); | ||
158 | |||
159 | len += sprintf(buf + len, "\n"); | ||
160 | |||
161 | return len; | ||
162 | } | ||
163 | |||
164 | static IIO_DEV_ATTR_AVAIL_CONVERSION_MODES(ad774x_show_conversion_modes); | ||
165 | |||
166 | static ssize_t ad774x_show_conversion_mode(struct device *dev, | ||
167 | struct device_attribute *attr, | ||
168 | char *buf) | ||
169 | { | ||
170 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
171 | struct ad774x_chip_info *chip = iio_priv(dev_info); | ||
172 | |||
173 | return sprintf(buf, "%s\n", chip->conversion_mode); | ||
174 | } | ||
175 | |||
176 | static ssize_t ad774x_store_conversion_mode(struct device *dev, | ||
177 | struct device_attribute *attr, | ||
178 | const char *buf, | ||
179 | size_t len) | ||
180 | { | ||
181 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
182 | struct ad774x_chip_info *chip = iio_priv(dev_info); | ||
183 | u8 cfg; | ||
184 | int i; | ||
185 | |||
186 | ad774x_i2c_read(chip, AD774X_CFG, &cfg, 1); | ||
187 | |||
188 | for (i = 0; i < AD774X_MAX_CONV_MODE; i++) { | ||
189 | if (strncmp(buf, ad774x_conv_mode_table[i].name, | ||
190 | strlen(ad774x_conv_mode_table[i].name) - 1) == 0) { | ||
191 | chip->conversion_mode = ad774x_conv_mode_table[i].name; | ||
192 | cfg |= 0x18 | ad774x_conv_mode_table[i].reg_cfg; | ||
193 | ad774x_i2c_write(chip, AD774X_CFG, cfg); | ||
194 | return len; | ||
195 | } | ||
196 | } | ||
197 | |||
198 | dev_err(dev, "not supported conversion mode\n"); | ||
199 | |||
200 | return -EINVAL; | ||
201 | } | ||
202 | |||
203 | static IIO_DEV_ATTR_CONVERSION_MODE(S_IRUGO | S_IWUSR, | ||
204 | ad774x_show_conversion_mode, | ||
205 | ad774x_store_conversion_mode); | ||
206 | |||
207 | static ssize_t ad774x_show_dac_value(struct device *dev, | ||
208 | struct device_attribute *attr, | ||
209 | char *buf) | ||
210 | { | ||
211 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
212 | struct ad774x_chip_info *chip = iio_priv(dev_info); | ||
213 | struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); | ||
214 | u8 data; | ||
215 | |||
216 | ad774x_i2c_read(chip, this_attr->address, &data, 1); | ||
217 | |||
218 | return sprintf(buf, "%02x\n", data & 0x7F); | ||
219 | } | ||
220 | |||
221 | static ssize_t ad774x_store_dac_value(struct device *dev, | ||
222 | struct device_attribute *attr, | ||
223 | const char *buf, | ||
224 | size_t len) | ||
225 | { | ||
226 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
227 | struct ad774x_chip_info *chip = iio_priv(dev_info); | ||
228 | struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); | ||
229 | unsigned long data; | ||
230 | int ret; | ||
231 | |||
232 | ret = strict_strtoul(buf, 10, &data); | ||
233 | |||
234 | if (!ret) { | ||
235 | ad774x_i2c_write(chip, this_attr->address, | ||
236 | (data ? AD774X_CAPDAC_EN : 0) | (data & 0x7F)); | ||
237 | return len; | ||
238 | } | ||
239 | |||
240 | return -EINVAL; | ||
241 | } | ||
242 | |||
243 | static IIO_DEVICE_ATTR(capdac0_raw, S_IRUGO | S_IWUSR, | ||
244 | ad774x_show_dac_value, | ||
245 | ad774x_store_dac_value, | ||
246 | AD774X_CAPDACA); | ||
247 | |||
248 | static IIO_DEVICE_ATTR(capdac1_raw, S_IRUGO | S_IWUSR, | ||
249 | ad774x_show_dac_value, | ||
250 | ad774x_store_dac_value, | ||
251 | AD774X_CAPDACB); | ||
252 | |||
253 | static ssize_t ad774x_show_cap_setup(struct device *dev, | ||
254 | struct device_attribute *attr, | ||
255 | char *buf) | ||
256 | { | ||
257 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
258 | struct ad774x_chip_info *chip = iio_priv(dev_info); | ||
259 | |||
260 | return sprintf(buf, "0x%02x\n", chip->cap_setup); | ||
261 | } | ||
262 | |||
263 | static ssize_t ad774x_store_cap_setup(struct device *dev, | ||
264 | struct device_attribute *attr, | ||
265 | const char *buf, | ||
266 | size_t len) | ||
267 | { | ||
268 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
269 | struct ad774x_chip_info *chip = iio_priv(dev_info); | ||
270 | unsigned long data; | ||
271 | int ret; | ||
272 | |||
273 | ret = strict_strtoul(buf, 10, &data); | ||
274 | |||
275 | if ((!ret) && (data < 0x100)) { | ||
276 | ad774x_i2c_write(chip, AD774X_CAP_SETUP, data); | ||
277 | chip->cap_setup = data; | ||
278 | return len; | ||
279 | } | ||
280 | |||
281 | return -EINVAL; | ||
282 | } | ||
283 | |||
284 | static IIO_DEV_ATTR_CAP_SETUP(S_IRUGO | S_IWUSR, | ||
285 | ad774x_show_cap_setup, | ||
286 | ad774x_store_cap_setup); | ||
287 | |||
288 | static ssize_t ad774x_show_vt_setup(struct device *dev, | ||
289 | struct device_attribute *attr, | ||
290 | char *buf) | ||
291 | { | ||
292 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
293 | struct ad774x_chip_info *chip = iio_priv(dev_info); | ||
294 | |||
295 | return sprintf(buf, "0x%02x\n", chip->vt_setup); | ||
296 | } | ||
297 | |||
298 | static ssize_t ad774x_store_vt_setup(struct device *dev, | ||
299 | struct device_attribute *attr, | ||
300 | const char *buf, | ||
301 | size_t len) | ||
302 | { | ||
303 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
304 | struct ad774x_chip_info *chip = iio_priv(dev_info); | ||
305 | unsigned long data; | ||
306 | int ret; | ||
307 | |||
308 | ret = strict_strtoul(buf, 10, &data); | ||
309 | |||
310 | if ((!ret) && (data < 0x100)) { | ||
311 | ad774x_i2c_write(chip, AD774X_VT_SETUP, data); | ||
312 | chip->vt_setup = data; | ||
313 | return len; | ||
314 | } | ||
315 | |||
316 | return -EINVAL; | ||
317 | } | ||
318 | |||
319 | static IIO_DEV_ATTR_VT_SETUP(S_IRUGO | S_IWUSR, | ||
320 | ad774x_show_vt_setup, | ||
321 | ad774x_store_vt_setup); | ||
322 | |||
323 | static ssize_t ad774x_show_exec_setup(struct device *dev, | ||
324 | struct device_attribute *attr, | ||
325 | char *buf) | ||
326 | { | ||
327 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
328 | struct ad774x_chip_info *chip = iio_priv(dev_info); | ||
329 | |||
330 | return sprintf(buf, "0x%02x\n", chip->exec_setup); | ||
331 | } | ||
332 | |||
333 | static ssize_t ad774x_store_exec_setup(struct device *dev, | ||
334 | struct device_attribute *attr, | ||
335 | const char *buf, | ||
336 | size_t len) | ||
337 | { | ||
338 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
339 | struct ad774x_chip_info *chip = iio_priv(dev_info); | ||
340 | unsigned long data; | ||
341 | int ret; | ||
342 | |||
343 | ret = strict_strtoul(buf, 10, &data); | ||
344 | |||
345 | if ((!ret) && (data < 0x100)) { | ||
346 | ad774x_i2c_write(chip, AD774X_EXEC_SETUP, data); | ||
347 | chip->exec_setup = data; | ||
348 | return len; | ||
349 | } | ||
350 | |||
351 | return -EINVAL; | ||
352 | } | ||
353 | |||
354 | static IIO_DEV_ATTR_EXEC_SETUP(S_IRUGO | S_IWUSR, | ||
355 | ad774x_show_exec_setup, | ||
356 | ad774x_store_exec_setup); | ||
357 | |||
358 | static ssize_t ad774x_show_volt_gain(struct device *dev, | ||
359 | struct device_attribute *attr, | ||
360 | char *buf) | ||
361 | { | ||
362 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
363 | struct ad774x_chip_info *chip = iio_priv(dev_info); | ||
364 | |||
365 | return sprintf(buf, "%d\n", chip->volt_gain); | ||
366 | } | ||
367 | |||
368 | static ssize_t ad774x_store_volt_gain(struct device *dev, | ||
369 | struct device_attribute *attr, | ||
370 | const char *buf, | ||
371 | size_t len) | ||
372 | { | ||
373 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
374 | struct ad774x_chip_info *chip = iio_priv(dev_info); | ||
375 | unsigned long data; | ||
376 | int ret; | ||
377 | |||
378 | ret = strict_strtoul(buf, 10, &data); | ||
379 | |||
380 | if ((!ret) && (data < 0x10000)) { | ||
381 | ad774x_i2c_write(chip, AD774X_VOLT_GAINH, data >> 8); | ||
382 | ad774x_i2c_write(chip, AD774X_VOLT_GAINL, data); | ||
383 | chip->volt_gain = data; | ||
384 | return len; | ||
385 | } | ||
386 | |||
387 | return -EINVAL; | ||
388 | } | ||
389 | |||
390 | static IIO_DEV_ATTR_VOLT_GAIN(S_IRUGO | S_IWUSR, | ||
391 | ad774x_show_volt_gain, | ||
392 | ad774x_store_volt_gain); | ||
393 | |||
394 | static ssize_t ad774x_show_cap_data(struct device *dev, | ||
395 | struct device_attribute *attr, | ||
396 | char *buf) | ||
397 | { | ||
398 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
399 | struct ad774x_chip_info *chip = iio_priv(dev_info); | ||
400 | unsigned long data; | ||
401 | char tmp[3]; | ||
402 | |||
403 | ad774x_i2c_read(chip, AD774X_CAP_DATA_HIGH, tmp, 3); | ||
404 | data = ((int)tmp[0] << 16) | ((int)tmp[1] << 8) | (int)tmp[2]; | ||
405 | |||
406 | return sprintf(buf, "%ld\n", data); | ||
407 | } | ||
408 | |||
409 | static IIO_DEV_ATTR_CAP_DATA(ad774x_show_cap_data); | ||
410 | |||
411 | static ssize_t ad774x_show_vt_data(struct device *dev, | ||
412 | struct device_attribute *attr, | ||
413 | char *buf) | ||
414 | { | ||
415 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
416 | struct ad774x_chip_info *chip = iio_priv(dev_info); | ||
417 | unsigned long data; | ||
418 | char tmp[3]; | ||
419 | |||
420 | ad774x_i2c_read(chip, AD774X_VT_DATA_HIGH, tmp, 3); | ||
421 | data = ((int)tmp[0] << 16) | ((int)tmp[1] << 8) | (int)tmp[2]; | ||
422 | |||
423 | return sprintf(buf, "%ld\n", data); | ||
424 | } | ||
425 | |||
426 | static IIO_DEV_ATTR_VT_DATA(ad774x_show_vt_data); | ||
427 | |||
428 | static ssize_t ad774x_show_cap_offs(struct device *dev, | ||
429 | struct device_attribute *attr, | ||
430 | char *buf) | ||
431 | { | ||
432 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
433 | struct ad774x_chip_info *chip = iio_priv(dev_info); | ||
434 | |||
435 | return sprintf(buf, "%d\n", chip->cap_offs); | ||
436 | } | ||
437 | |||
438 | static ssize_t ad774x_store_cap_offs(struct device *dev, | ||
439 | struct device_attribute *attr, | ||
440 | const char *buf, | ||
441 | size_t len) | ||
442 | { | ||
443 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
444 | struct ad774x_chip_info *chip = iio_priv(dev_info); | ||
445 | unsigned long data; | ||
446 | int ret; | ||
447 | |||
448 | ret = strict_strtoul(buf, 10, &data); | ||
449 | |||
450 | if ((!ret) && (data < 0x10000)) { | ||
451 | ad774x_i2c_write(chip, AD774X_CAP_OFFH, data >> 8); | ||
452 | ad774x_i2c_write(chip, AD774X_CAP_OFFL, data); | ||
453 | chip->cap_offs = data; | ||
454 | return len; | ||
455 | } | ||
456 | |||
457 | return -EINVAL; | ||
458 | } | ||
459 | |||
460 | static IIO_DEV_ATTR_CAP_OFFS(S_IRUGO | S_IWUSR, | ||
461 | ad774x_show_cap_offs, | ||
462 | ad774x_store_cap_offs); | ||
463 | |||
464 | static ssize_t ad774x_show_cap_gain(struct device *dev, | ||
465 | struct device_attribute *attr, | ||
466 | char *buf) | ||
467 | { | ||
468 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
469 | struct ad774x_chip_info *chip = iio_priv(dev_info); | ||
470 | |||
471 | return sprintf(buf, "%d\n", chip->cap_gain); | ||
472 | } | ||
473 | |||
474 | static ssize_t ad774x_store_cap_gain(struct device *dev, | ||
475 | struct device_attribute *attr, | ||
476 | const char *buf, | ||
477 | size_t len) | ||
478 | { | ||
479 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
480 | struct ad774x_chip_info *chip = iio_priv(dev_info); | ||
481 | unsigned long data; | ||
482 | int ret; | ||
483 | |||
484 | ret = strict_strtoul(buf, 10, &data); | ||
485 | |||
486 | if ((!ret) && (data < 0x10000)) { | ||
487 | ad774x_i2c_write(chip, AD774X_CAP_GAINH, data >> 8); | ||
488 | ad774x_i2c_write(chip, AD774X_CAP_GAINL, data); | ||
489 | chip->cap_gain = data; | ||
490 | return len; | ||
491 | } | ||
492 | |||
493 | return -EINVAL; | ||
494 | } | ||
495 | |||
496 | static IIO_DEV_ATTR_CAP_GAIN(S_IRUGO | S_IWUSR, | ||
497 | ad774x_show_cap_gain, | ||
498 | ad774x_store_cap_gain); | ||
499 | |||
500 | static struct attribute *ad774x_attributes[] = { | ||
501 | &iio_dev_attr_available_conversion_modes.dev_attr.attr, | ||
502 | &iio_dev_attr_conversion_mode.dev_attr.attr, | ||
503 | &iio_dev_attr_cap_setup.dev_attr.attr, | ||
504 | &iio_dev_attr_in0_setup.dev_attr.attr, | ||
505 | &iio_dev_attr_exec_setup.dev_attr.attr, | ||
506 | &iio_dev_attr_cap_offs.dev_attr.attr, | ||
507 | &iio_dev_attr_cap_gain.dev_attr.attr, | ||
508 | &iio_dev_attr_in0_gain.dev_attr.attr, | ||
509 | &iio_dev_attr_in0_raw.dev_attr.attr, | ||
510 | &iio_dev_attr_cap0_raw.dev_attr.attr, | ||
511 | &iio_dev_attr_capdac0_raw.dev_attr.attr, | ||
512 | &iio_dev_attr_capdac1_raw.dev_attr.attr, | ||
513 | NULL, | ||
514 | }; | ||
515 | |||
516 | static const struct attribute_group ad774x_attribute_group = { | ||
517 | .attrs = ad774x_attributes, | ||
518 | }; | ||
519 | |||
520 | /* | ||
521 | * data ready events | ||
522 | */ | ||
523 | |||
524 | #define IIO_EVENT_CODE_CAP_RDY 0 | ||
525 | #define IIO_EVENT_CODE_VT_RDY 1 | ||
526 | |||
527 | #define IIO_EVENT_ATTR_CAP_RDY_SH(_evlist, _show, _store, _mask) \ | ||
528 | IIO_EVENT_ATTR_SH(cap_rdy, _evlist, _show, _store, _mask) | ||
529 | |||
530 | #define IIO_EVENT_ATTR_VT_RDY_SH(_evlist, _show, _store, _mask) \ | ||
531 | IIO_EVENT_ATTR_SH(vt_rdy, _evlist, _show, _store, _mask) | ||
532 | |||
533 | static irqreturn_t ad774x_event_handler(int irq, void *private) | ||
534 | { | ||
535 | struct iio_dev *indio_dev = private; | ||
536 | struct ad774x_chip_info *chip = iio_priv(indio_dev); | ||
537 | u8 int_status; | ||
538 | |||
539 | ad774x_i2c_read(chip, AD774X_STATUS, &int_status, 1); | ||
540 | |||
541 | if (int_status & AD774X_STATUS_RDYCAP) | ||
542 | iio_push_event(indio_dev, 0, | ||
543 | IIO_EVENT_CODE_CAP_RDY, | ||
544 | iio_get_time_ns()); | ||
545 | |||
546 | if (int_status & AD774X_STATUS_RDYVT) | ||
547 | iio_push_event(indio_dev, 0, | ||
548 | IIO_EVENT_CODE_VT_RDY, | ||
549 | iio_get_time_ns()); | ||
550 | |||
551 | return IRQ_HANDLED; | ||
552 | } | ||
553 | |||
554 | static IIO_CONST_ATTR(cap_rdy_en, "1"); | ||
555 | static IIO_CONST_ATTR(vt_rdy_en, "1"); | ||
556 | |||
557 | static struct attribute *ad774x_event_attributes[] = { | ||
558 | &iio_const_attr_cap_rdy_en.dev_attr.attr, | ||
559 | &iio_const_attr_vt_rdy_en.dev_attr.attr, | ||
560 | NULL, | ||
561 | }; | ||
562 | |||
563 | static struct attribute_group ad774x_event_attribute_group = { | ||
564 | .attrs = ad774x_event_attributes, | ||
565 | }; | ||
566 | |||
567 | static const struct iio_info ad774x_info = { | ||
568 | .attrs = &ad774x_event_attribute_group, | ||
569 | .event_attrs = &ad774x_event_attribute_group, | ||
570 | .num_interrupt_lines = 1, | ||
571 | .driver_module = THIS_MODULE, | ||
572 | }; | ||
573 | /* | ||
574 | * device probe and remove | ||
575 | */ | ||
576 | |||
577 | static int __devinit ad774x_probe(struct i2c_client *client, | ||
578 | const struct i2c_device_id *id) | ||
579 | { | ||
580 | int ret = 0, regdone = 0; | ||
581 | struct ad774x_chip_info *chip; | ||
582 | struct iio_dev *indio_dev; | ||
583 | |||
584 | indio_dev = iio_allocate_device(sizeof(*chip)); | ||
585 | if (indio_dev == NULL) { | ||
586 | ret = -ENOMEM; | ||
587 | goto error_ret; | ||
588 | } | ||
589 | chip = iio_priv(indio_dev); | ||
590 | /* this is only used for device removal purposes */ | ||
591 | i2c_set_clientdata(client, indio_dev); | ||
592 | |||
593 | chip->client = client; | ||
594 | |||
595 | /* Establish that the iio_dev is a child of the i2c device */ | ||
596 | indio_dev->name = id->name; | ||
597 | indio_dev->dev.parent = &client->dev; | ||
598 | indio_dev->info = &ad774x_info; | ||
599 | indio_dev->modes = INDIO_DIRECT_MODE; | ||
600 | |||
601 | ret = iio_device_register(indio_dev); | ||
602 | if (ret) | ||
603 | goto error_free_dev; | ||
604 | regdone = 1; | ||
605 | |||
606 | if (client->irq) { | ||
607 | ret = request_threaded_irq(client->irq, | ||
608 | NULL, | ||
609 | &ad774x_event_handler, | ||
610 | IRQF_TRIGGER_FALLING, | ||
611 | "ad774x", | ||
612 | indio_dev); | ||
613 | if (ret) | ||
614 | goto error_free_dev; | ||
615 | } | ||
616 | |||
617 | dev_err(&client->dev, "%s capacitive sensor registered, irq: %d\n", id->name, client->irq); | ||
618 | |||
619 | return 0; | ||
620 | |||
621 | error_free_dev: | ||
622 | if (regdone) | ||
623 | free_irq(client->irq, indio_dev); | ||
624 | else | ||
625 | iio_free_device(indio_dev); | ||
626 | error_ret: | ||
627 | return ret; | ||
628 | } | ||
629 | |||
630 | static int __devexit ad774x_remove(struct i2c_client *client) | ||
631 | { | ||
632 | struct iio_dev *indio_dev = i2c_get_clientdata(client); | ||
633 | |||
634 | if (client->irq) | ||
635 | free_irq(client->irq, indio_dev); | ||
636 | iio_device_unregister(indio_dev); | ||
637 | |||
638 | return 0; | ||
639 | } | ||
640 | |||
641 | static const struct i2c_device_id ad774x_id[] = { | ||
642 | { "ad7745", 0 }, | ||
643 | { "ad7746", 0 }, | ||
644 | { "ad7747", 0 }, | ||
645 | {} | ||
646 | }; | ||
647 | |||
648 | MODULE_DEVICE_TABLE(i2c, ad774x_id); | ||
649 | |||
650 | static struct i2c_driver ad774x_driver = { | ||
651 | .driver = { | ||
652 | .name = "ad774x", | ||
653 | }, | ||
654 | .probe = ad774x_probe, | ||
655 | .remove = __devexit_p(ad774x_remove), | ||
656 | .id_table = ad774x_id, | ||
657 | }; | ||
658 | |||
659 | static __init int ad774x_init(void) | ||
660 | { | ||
661 | return i2c_add_driver(&ad774x_driver); | ||
662 | } | ||
663 | |||
664 | static __exit void ad774x_exit(void) | ||
665 | { | ||
666 | i2c_del_driver(&ad774x_driver); | ||
667 | } | ||
668 | |||
669 | MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); | ||
670 | MODULE_DESCRIPTION("Analog Devices ad7745/6/7 capacitive sensor driver"); | ||
671 | MODULE_LICENSE("GPL v2"); | ||
672 | |||
673 | module_init(ad774x_init); | ||
674 | module_exit(ad774x_exit); | ||
diff --git a/drivers/staging/iio/adc/ad7793.c b/drivers/staging/iio/adc/ad7793.c new file mode 100644 index 00000000000..90f6c039d6c --- /dev/null +++ b/drivers/staging/iio/adc/ad7793.c | |||
@@ -0,0 +1,987 @@ | |||
1 | /* | ||
2 | * AD7792/AD7793 SPI ADC driver | ||
3 | * | ||
4 | * Copyright 2011 Analog Devices Inc. | ||
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> | ||
19 | |||
20 | #include "../iio.h" | ||
21 | #include "../sysfs.h" | ||
22 | #include "../ring_generic.h" | ||
23 | #include "../ring_sw.h" | ||
24 | #include "../trigger.h" | ||
25 | #include "adc.h" | ||
26 | |||
27 | #include "ad7793.h" | ||
28 | |||
29 | /* NOTE: | ||
30 | * The AD7792/AD7793 features a dual use data out ready DOUT/RDY output. | ||
31 | * In order to avoid contentions on the SPI bus, it's therefore necessary | ||
32 | * to use spi bus locking. | ||
33 | * | ||
34 | * The DOUT/RDY output must also be wired to an interrupt capable GPIO. | ||
35 | */ | ||
36 | |||
37 | struct ad7793_chip_info { | ||
38 | struct iio_chan_spec channel[7]; | ||
39 | }; | ||
40 | |||
41 | struct ad7793_state { | ||
42 | struct spi_device *spi; | ||
43 | struct iio_trigger *trig; | ||
44 | const struct ad7793_chip_info *chip_info; | ||
45 | struct regulator *reg; | ||
46 | struct ad7793_platform_data *pdata; | ||
47 | wait_queue_head_t wq_data_avail; | ||
48 | bool done; | ||
49 | bool irq_dis; | ||
50 | u16 int_vref_mv; | ||
51 | u16 mode; | ||
52 | u16 conf; | ||
53 | u32 scale_avail[8][2]; | ||
54 | u32 available_scan_masks[7]; | ||
55 | /* | ||
56 | * DMA (thus cache coherency maintenance) requires the | ||
57 | * transfer buffers to live in their own cache lines. | ||
58 | */ | ||
59 | u8 data[4] ____cacheline_aligned; | ||
60 | }; | ||
61 | |||
62 | enum ad7793_supported_device_ids { | ||
63 | ID_AD7792, | ||
64 | ID_AD7793, | ||
65 | }; | ||
66 | |||
67 | static int __ad7793_write_reg(struct ad7793_state *st, bool locked, | ||
68 | bool cs_change, unsigned char reg, | ||
69 | unsigned size, unsigned val) | ||
70 | { | ||
71 | u8 *data = st->data; | ||
72 | struct spi_transfer t = { | ||
73 | .tx_buf = data, | ||
74 | .len = size + 1, | ||
75 | .cs_change = cs_change, | ||
76 | }; | ||
77 | struct spi_message m; | ||
78 | |||
79 | data[0] = AD7793_COMM_WRITE | AD7793_COMM_ADDR(reg); | ||
80 | |||
81 | switch (size) { | ||
82 | case 3: | ||
83 | data[1] = val >> 16; | ||
84 | data[2] = val >> 8; | ||
85 | data[3] = val; | ||
86 | break; | ||
87 | case 2: | ||
88 | data[1] = val >> 8; | ||
89 | data[2] = val; | ||
90 | break; | ||
91 | case 1: | ||
92 | data[1] = val; | ||
93 | break; | ||
94 | default: | ||
95 | return -EINVAL; | ||
96 | } | ||
97 | |||
98 | spi_message_init(&m); | ||
99 | spi_message_add_tail(&t, &m); | ||
100 | |||
101 | if (locked) | ||
102 | return spi_sync_locked(st->spi, &m); | ||
103 | else | ||
104 | return spi_sync(st->spi, &m); | ||
105 | } | ||
106 | |||
107 | static int ad7793_write_reg(struct ad7793_state *st, | ||
108 | unsigned reg, unsigned size, unsigned val) | ||
109 | { | ||
110 | return __ad7793_write_reg(st, false, false, reg, size, val); | ||
111 | } | ||
112 | |||
113 | static int __ad7793_read_reg(struct ad7793_state *st, bool locked, | ||
114 | bool cs_change, unsigned char reg, | ||
115 | int *val, unsigned size) | ||
116 | { | ||
117 | u8 *data = st->data; | ||
118 | int ret; | ||
119 | struct spi_transfer t[] = { | ||
120 | { | ||
121 | .tx_buf = data, | ||
122 | .len = 1, | ||
123 | }, { | ||
124 | .rx_buf = data, | ||
125 | .len = size, | ||
126 | .cs_change = cs_change, | ||
127 | }, | ||
128 | }; | ||
129 | struct spi_message m; | ||
130 | |||
131 | data[0] = AD7793_COMM_READ | AD7793_COMM_ADDR(reg); | ||
132 | |||
133 | spi_message_init(&m); | ||
134 | spi_message_add_tail(&t[0], &m); | ||
135 | spi_message_add_tail(&t[1], &m); | ||
136 | |||
137 | if (locked) | ||
138 | ret = spi_sync_locked(st->spi, &m); | ||
139 | else | ||
140 | ret = spi_sync(st->spi, &m); | ||
141 | |||
142 | if (ret < 0) | ||
143 | return ret; | ||
144 | |||
145 | switch (size) { | ||
146 | case 3: | ||
147 | *val = data[0] << 16 | data[1] << 8 | data[2]; | ||
148 | break; | ||
149 | case 2: | ||
150 | *val = data[0] << 8 | data[1]; | ||
151 | break; | ||
152 | case 1: | ||
153 | *val = data[0]; | ||
154 | break; | ||
155 | default: | ||
156 | return -EINVAL; | ||
157 | } | ||
158 | |||
159 | return 0; | ||
160 | } | ||
161 | |||
162 | static int ad7793_read_reg(struct ad7793_state *st, | ||
163 | unsigned reg, int *val, unsigned size) | ||
164 | { | ||
165 | return __ad7793_read_reg(st, 0, 0, reg, val, size); | ||
166 | } | ||
167 | |||
168 | static int ad7793_read(struct ad7793_state *st, unsigned ch, | ||
169 | unsigned len, int *val) | ||
170 | { | ||
171 | int ret; | ||
172 | st->conf = (st->conf & ~AD7793_CONF_CHAN(-1)) | AD7793_CONF_CHAN(ch); | ||
173 | st->mode = (st->mode & ~AD7793_MODE_SEL(-1)) | | ||
174 | AD7793_MODE_SEL(AD7793_MODE_SINGLE); | ||
175 | |||
176 | ad7793_write_reg(st, AD7793_REG_CONF, sizeof(st->conf), st->conf); | ||
177 | |||
178 | spi_bus_lock(st->spi->master); | ||
179 | st->done = false; | ||
180 | |||
181 | ret = __ad7793_write_reg(st, 1, 1, AD7793_REG_MODE, | ||
182 | sizeof(st->mode), st->mode); | ||
183 | if (ret < 0) | ||
184 | goto out; | ||
185 | |||
186 | st->irq_dis = false; | ||
187 | enable_irq(st->spi->irq); | ||
188 | wait_event_interruptible(st->wq_data_avail, st->done); | ||
189 | |||
190 | ret = __ad7793_read_reg(st, 1, 0, AD7793_REG_DATA, val, len); | ||
191 | out: | ||
192 | spi_bus_unlock(st->spi->master); | ||
193 | |||
194 | return ret; | ||
195 | } | ||
196 | |||
197 | static int ad7793_calibrate(struct ad7793_state *st, unsigned mode, unsigned ch) | ||
198 | { | ||
199 | int ret; | ||
200 | |||
201 | st->conf = (st->conf & ~AD7793_CONF_CHAN(-1)) | AD7793_CONF_CHAN(ch); | ||
202 | st->mode = (st->mode & ~AD7793_MODE_SEL(-1)) | AD7793_MODE_SEL(mode); | ||
203 | |||
204 | ad7793_write_reg(st, AD7793_REG_CONF, sizeof(st->conf), st->conf); | ||
205 | |||
206 | spi_bus_lock(st->spi->master); | ||
207 | st->done = false; | ||
208 | |||
209 | ret = __ad7793_write_reg(st, 1, 1, AD7793_REG_MODE, | ||
210 | sizeof(st->mode), st->mode); | ||
211 | if (ret < 0) | ||
212 | goto out; | ||
213 | |||
214 | st->irq_dis = false; | ||
215 | enable_irq(st->spi->irq); | ||
216 | wait_event_interruptible(st->wq_data_avail, st->done); | ||
217 | |||
218 | st->mode = (st->mode & ~AD7793_MODE_SEL(-1)) | | ||
219 | AD7793_MODE_SEL(AD7793_MODE_IDLE); | ||
220 | |||
221 | ret = __ad7793_write_reg(st, 1, 0, AD7793_REG_MODE, | ||
222 | sizeof(st->mode), st->mode); | ||
223 | out: | ||
224 | spi_bus_unlock(st->spi->master); | ||
225 | |||
226 | return ret; | ||
227 | } | ||
228 | |||
229 | static const u8 ad7793_calib_arr[6][2] = { | ||
230 | {AD7793_MODE_CAL_INT_ZERO, AD7793_CH_AIN1P_AIN1M}, | ||
231 | {AD7793_MODE_CAL_INT_FULL, AD7793_CH_AIN1P_AIN1M}, | ||
232 | {AD7793_MODE_CAL_INT_ZERO, AD7793_CH_AIN2P_AIN2M}, | ||
233 | {AD7793_MODE_CAL_INT_FULL, AD7793_CH_AIN2P_AIN2M}, | ||
234 | {AD7793_MODE_CAL_INT_ZERO, AD7793_CH_AIN3P_AIN3M}, | ||
235 | {AD7793_MODE_CAL_INT_FULL, AD7793_CH_AIN3P_AIN3M} | ||
236 | }; | ||
237 | |||
238 | static int ad7793_calibrate_all(struct ad7793_state *st) | ||
239 | { | ||
240 | int i, ret; | ||
241 | |||
242 | for (i = 0; i < ARRAY_SIZE(ad7793_calib_arr); i++) { | ||
243 | ret = ad7793_calibrate(st, ad7793_calib_arr[i][0], | ||
244 | ad7793_calib_arr[i][1]); | ||
245 | if (ret) | ||
246 | goto out; | ||
247 | } | ||
248 | |||
249 | return 0; | ||
250 | out: | ||
251 | dev_err(&st->spi->dev, "Calibration failed\n"); | ||
252 | return ret; | ||
253 | } | ||
254 | |||
255 | static int ad7793_setup(struct ad7793_state *st) | ||
256 | { | ||
257 | int i, ret = -1; | ||
258 | unsigned long long scale_uv; | ||
259 | u32 id; | ||
260 | |||
261 | /* reset the serial interface */ | ||
262 | ret = spi_write(st->spi, (u8 *)&ret, sizeof(ret)); | ||
263 | if (ret < 0) | ||
264 | goto out; | ||
265 | msleep(1); /* Wait for at least 500us */ | ||
266 | |||
267 | /* write/read test for device presence */ | ||
268 | ret = ad7793_read_reg(st, AD7793_REG_ID, &id, 1); | ||
269 | if (ret) | ||
270 | goto out; | ||
271 | |||
272 | id &= AD7793_ID_MASK; | ||
273 | |||
274 | if (!((id == AD7792_ID) || (id == AD7793_ID))) { | ||
275 | dev_err(&st->spi->dev, "device ID query failed\n"); | ||
276 | goto out; | ||
277 | } | ||
278 | |||
279 | st->mode = (st->pdata->mode & ~AD7793_MODE_SEL(-1)) | | ||
280 | AD7793_MODE_SEL(AD7793_MODE_IDLE); | ||
281 | st->conf = st->pdata->conf & ~AD7793_CONF_CHAN(-1); | ||
282 | |||
283 | ret = ad7793_write_reg(st, AD7793_REG_MODE, sizeof(st->mode), st->mode); | ||
284 | if (ret) | ||
285 | goto out; | ||
286 | |||
287 | ret = ad7793_write_reg(st, AD7793_REG_CONF, sizeof(st->conf), st->conf); | ||
288 | if (ret) | ||
289 | goto out; | ||
290 | |||
291 | ret = ad7793_write_reg(st, AD7793_REG_IO, | ||
292 | sizeof(st->pdata->io), st->pdata->io); | ||
293 | if (ret) | ||
294 | goto out; | ||
295 | |||
296 | ret = ad7793_calibrate_all(st); | ||
297 | if (ret) | ||
298 | goto out; | ||
299 | |||
300 | /* Populate available ADC input ranges */ | ||
301 | for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++) { | ||
302 | scale_uv = ((u64)st->int_vref_mv * 100000000) | ||
303 | >> (st->chip_info->channel[0].scan_type.realbits - | ||
304 | (!!(st->conf & AD7793_CONF_UNIPOLAR) ? 0 : 1)); | ||
305 | scale_uv >>= i; | ||
306 | |||
307 | st->scale_avail[i][1] = do_div(scale_uv, 100000000) * 10; | ||
308 | st->scale_avail[i][0] = scale_uv; | ||
309 | } | ||
310 | |||
311 | return 0; | ||
312 | out: | ||
313 | dev_err(&st->spi->dev, "setup failed\n"); | ||
314 | return ret; | ||
315 | } | ||
316 | |||
317 | static int ad7793_scan_from_ring(struct ad7793_state *st, unsigned ch, int *val) | ||
318 | { | ||
319 | struct iio_ring_buffer *ring = iio_priv_to_dev(st)->ring; | ||
320 | int ret; | ||
321 | s64 dat64[2]; | ||
322 | u32 *dat32 = (u32 *)dat64; | ||
323 | |||
324 | if (!(ring->scan_mask & (1 << ch))) | ||
325 | return -EBUSY; | ||
326 | |||
327 | ret = ring->access->read_last(ring, (u8 *) &dat64); | ||
328 | if (ret) | ||
329 | return ret; | ||
330 | |||
331 | *val = *dat32; | ||
332 | |||
333 | return 0; | ||
334 | } | ||
335 | |||
336 | static int ad7793_ring_preenable(struct iio_dev *indio_dev) | ||
337 | { | ||
338 | struct ad7793_state *st = iio_priv(indio_dev); | ||
339 | struct iio_ring_buffer *ring = indio_dev->ring; | ||
340 | size_t d_size; | ||
341 | unsigned channel; | ||
342 | |||
343 | if (!ring->scan_count) | ||
344 | return -EINVAL; | ||
345 | |||
346 | channel = __ffs(ring->scan_mask); | ||
347 | |||
348 | d_size = ring->scan_count * | ||
349 | indio_dev->channels[0].scan_type.storagebits / 8; | ||
350 | |||
351 | if (ring->scan_timestamp) { | ||
352 | d_size += sizeof(s64); | ||
353 | |||
354 | if (d_size % sizeof(s64)) | ||
355 | d_size += sizeof(s64) - (d_size % sizeof(s64)); | ||
356 | } | ||
357 | |||
358 | if (indio_dev->ring->access->set_bytes_per_datum) | ||
359 | indio_dev->ring->access->set_bytes_per_datum(indio_dev->ring, | ||
360 | d_size); | ||
361 | |||
362 | st->mode = (st->mode & ~AD7793_MODE_SEL(-1)) | | ||
363 | AD7793_MODE_SEL(AD7793_MODE_CONT); | ||
364 | st->conf = (st->conf & ~AD7793_CONF_CHAN(-1)) | | ||
365 | AD7793_CONF_CHAN(indio_dev->channels[channel].address); | ||
366 | |||
367 | ad7793_write_reg(st, AD7793_REG_CONF, sizeof(st->conf), st->conf); | ||
368 | |||
369 | spi_bus_lock(st->spi->master); | ||
370 | __ad7793_write_reg(st, 1, 1, AD7793_REG_MODE, | ||
371 | sizeof(st->mode), st->mode); | ||
372 | |||
373 | st->irq_dis = false; | ||
374 | enable_irq(st->spi->irq); | ||
375 | |||
376 | return 0; | ||
377 | } | ||
378 | |||
379 | static int ad7793_ring_postdisable(struct iio_dev *indio_dev) | ||
380 | { | ||
381 | struct ad7793_state *st = iio_priv(indio_dev); | ||
382 | |||
383 | st->mode = (st->mode & ~AD7793_MODE_SEL(-1)) | | ||
384 | AD7793_MODE_SEL(AD7793_MODE_IDLE); | ||
385 | |||
386 | st->done = false; | ||
387 | wait_event_interruptible(st->wq_data_avail, st->done); | ||
388 | |||
389 | if (!st->irq_dis) | ||
390 | disable_irq_nosync(st->spi->irq); | ||
391 | |||
392 | __ad7793_write_reg(st, 1, 0, AD7793_REG_MODE, | ||
393 | sizeof(st->mode), st->mode); | ||
394 | |||
395 | return spi_bus_unlock(st->spi->master); | ||
396 | } | ||
397 | |||
398 | /** | ||
399 | * ad7793_trigger_handler() bh of trigger launched polling to ring buffer | ||
400 | **/ | ||
401 | |||
402 | static irqreturn_t ad7793_trigger_handler(int irq, void *p) | ||
403 | { | ||
404 | struct iio_poll_func *pf = p; | ||
405 | struct iio_dev *indio_dev = pf->private_data; | ||
406 | struct iio_ring_buffer *ring = indio_dev->ring; | ||
407 | struct ad7793_state *st = iio_priv(indio_dev); | ||
408 | s64 dat64[2]; | ||
409 | s32 *dat32 = (s32 *)dat64; | ||
410 | |||
411 | if (ring->scan_count) | ||
412 | __ad7793_read_reg(st, 1, 1, AD7793_REG_DATA, | ||
413 | dat32, | ||
414 | indio_dev->channels[0].scan_type.realbits/8); | ||
415 | |||
416 | /* Guaranteed to be aligned with 8 byte boundary */ | ||
417 | if (ring->scan_timestamp) | ||
418 | dat64[1] = pf->timestamp; | ||
419 | |||
420 | ring->access->store_to(ring, (u8 *)dat64, pf->timestamp); | ||
421 | |||
422 | iio_trigger_notify_done(indio_dev->trig); | ||
423 | st->irq_dis = false; | ||
424 | enable_irq(st->spi->irq); | ||
425 | |||
426 | return IRQ_HANDLED; | ||
427 | } | ||
428 | |||
429 | static const struct iio_ring_setup_ops ad7793_ring_setup_ops = { | ||
430 | .preenable = &ad7793_ring_preenable, | ||
431 | .postenable = &iio_triggered_ring_postenable, | ||
432 | .predisable = &iio_triggered_ring_predisable, | ||
433 | .postdisable = &ad7793_ring_postdisable, | ||
434 | }; | ||
435 | |||
436 | static int ad7793_register_ring_funcs_and_init(struct iio_dev *indio_dev) | ||
437 | { | ||
438 | int ret; | ||
439 | |||
440 | indio_dev->ring = iio_sw_rb_allocate(indio_dev); | ||
441 | if (!indio_dev->ring) { | ||
442 | ret = -ENOMEM; | ||
443 | goto error_ret; | ||
444 | } | ||
445 | /* Effectively select the ring buffer implementation */ | ||
446 | indio_dev->ring->access = &ring_sw_access_funcs; | ||
447 | indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time, | ||
448 | &ad7793_trigger_handler, | ||
449 | IRQF_ONESHOT, | ||
450 | indio_dev, | ||
451 | "ad7793_consumer%d", | ||
452 | indio_dev->id); | ||
453 | if (indio_dev->pollfunc == NULL) { | ||
454 | ret = -ENOMEM; | ||
455 | goto error_deallocate_sw_rb; | ||
456 | } | ||
457 | |||
458 | /* Ring buffer functions - here trigger setup related */ | ||
459 | indio_dev->ring->setup_ops = &ad7793_ring_setup_ops; | ||
460 | |||
461 | /* Flag that polled ring buffering is possible */ | ||
462 | indio_dev->modes |= INDIO_RING_TRIGGERED; | ||
463 | return 0; | ||
464 | |||
465 | error_deallocate_sw_rb: | ||
466 | iio_sw_rb_free(indio_dev->ring); | ||
467 | error_ret: | ||
468 | return ret; | ||
469 | } | ||
470 | |||
471 | static void ad7793_ring_cleanup(struct iio_dev *indio_dev) | ||
472 | { | ||
473 | /* ensure that the trigger has been detached */ | ||
474 | if (indio_dev->trig) { | ||
475 | iio_put_trigger(indio_dev->trig); | ||
476 | iio_trigger_dettach_poll_func(indio_dev->trig, | ||
477 | indio_dev->pollfunc); | ||
478 | } | ||
479 | iio_dealloc_pollfunc(indio_dev->pollfunc); | ||
480 | iio_sw_rb_free(indio_dev->ring); | ||
481 | } | ||
482 | |||
483 | /** | ||
484 | * ad7793_data_rdy_trig_poll() the event handler for the data rdy trig | ||
485 | **/ | ||
486 | static irqreturn_t ad7793_data_rdy_trig_poll(int irq, void *private) | ||
487 | { | ||
488 | struct ad7793_state *st = iio_priv(private); | ||
489 | |||
490 | st->done = true; | ||
491 | wake_up_interruptible(&st->wq_data_avail); | ||
492 | disable_irq_nosync(irq); | ||
493 | st->irq_dis = true; | ||
494 | iio_trigger_poll(st->trig, iio_get_time_ns()); | ||
495 | |||
496 | return IRQ_HANDLED; | ||
497 | } | ||
498 | |||
499 | static int ad7793_probe_trigger(struct iio_dev *indio_dev) | ||
500 | { | ||
501 | struct ad7793_state *st = iio_priv(indio_dev); | ||
502 | int ret; | ||
503 | |||
504 | st->trig = iio_allocate_trigger("%s-dev%d", | ||
505 | spi_get_device_id(st->spi)->name, | ||
506 | indio_dev->id); | ||
507 | if (st->trig == NULL) { | ||
508 | ret = -ENOMEM; | ||
509 | goto error_ret; | ||
510 | } | ||
511 | |||
512 | ret = request_irq(st->spi->irq, | ||
513 | ad7793_data_rdy_trig_poll, | ||
514 | IRQF_TRIGGER_LOW, | ||
515 | spi_get_device_id(st->spi)->name, | ||
516 | indio_dev); | ||
517 | if (ret) | ||
518 | goto error_free_trig; | ||
519 | |||
520 | disable_irq_nosync(st->spi->irq); | ||
521 | st->irq_dis = true; | ||
522 | st->trig->dev.parent = &st->spi->dev; | ||
523 | st->trig->owner = THIS_MODULE; | ||
524 | st->trig->private_data = indio_dev; | ||
525 | |||
526 | ret = iio_trigger_register(st->trig); | ||
527 | |||
528 | /* select default trigger */ | ||
529 | indio_dev->trig = st->trig; | ||
530 | if (ret) | ||
531 | goto error_free_irq; | ||
532 | |||
533 | return 0; | ||
534 | |||
535 | error_free_irq: | ||
536 | free_irq(st->spi->irq, indio_dev); | ||
537 | error_free_trig: | ||
538 | iio_free_trigger(st->trig); | ||
539 | error_ret: | ||
540 | return ret; | ||
541 | } | ||
542 | |||
543 | static void ad7793_remove_trigger(struct iio_dev *indio_dev) | ||
544 | { | ||
545 | struct ad7793_state *st = iio_priv(indio_dev); | ||
546 | |||
547 | iio_trigger_unregister(st->trig); | ||
548 | free_irq(st->spi->irq, indio_dev); | ||
549 | iio_free_trigger(st->trig); | ||
550 | } | ||
551 | |||
552 | static const u16 sample_freq_avail[16] = {0, 470, 242, 123, 62, 50, 39, 33, 19, | ||
553 | 17, 16, 12, 10, 8, 6, 4}; | ||
554 | |||
555 | static ssize_t ad7793_read_frequency(struct device *dev, | ||
556 | struct device_attribute *attr, | ||
557 | char *buf) | ||
558 | { | ||
559 | struct iio_dev *indio_dev = dev_get_drvdata(dev); | ||
560 | struct ad7793_state *st = iio_priv(indio_dev); | ||
561 | |||
562 | return sprintf(buf, "%d\n", | ||
563 | sample_freq_avail[AD7793_MODE_RATE(st->mode)]); | ||
564 | } | ||
565 | |||
566 | static ssize_t ad7793_write_frequency(struct device *dev, | ||
567 | struct device_attribute *attr, | ||
568 | const char *buf, | ||
569 | size_t len) | ||
570 | { | ||
571 | struct iio_dev *indio_dev = dev_get_drvdata(dev); | ||
572 | struct ad7793_state *st = iio_priv(indio_dev); | ||
573 | long lval; | ||
574 | int i, ret; | ||
575 | |||
576 | mutex_lock(&indio_dev->mlock); | ||
577 | if (iio_ring_enabled(indio_dev)) { | ||
578 | mutex_unlock(&indio_dev->mlock); | ||
579 | return -EBUSY; | ||
580 | } | ||
581 | mutex_unlock(&indio_dev->mlock); | ||
582 | |||
583 | ret = strict_strtol(buf, 10, &lval); | ||
584 | if (ret) | ||
585 | return ret; | ||
586 | |||
587 | ret = -EINVAL; | ||
588 | |||
589 | for (i = 0; i < ARRAY_SIZE(sample_freq_avail); i++) | ||
590 | if (lval == sample_freq_avail[i]) { | ||
591 | mutex_lock(&indio_dev->mlock); | ||
592 | st->mode &= ~AD7793_MODE_RATE(-1); | ||
593 | st->mode |= AD7793_MODE_RATE(i); | ||
594 | ad7793_write_reg(st, AD7793_REG_MODE, | ||
595 | sizeof(st->mode), st->mode); | ||
596 | mutex_unlock(&indio_dev->mlock); | ||
597 | ret = 0; | ||
598 | } | ||
599 | |||
600 | return ret ? ret : len; | ||
601 | } | ||
602 | |||
603 | static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, | ||
604 | ad7793_read_frequency, | ||
605 | ad7793_write_frequency); | ||
606 | |||
607 | static IIO_CONST_ATTR_SAMP_FREQ_AVAIL( | ||
608 | "470 242 123 62 50 39 33 19 17 16 12 10 8 6 4"); | ||
609 | |||
610 | static ssize_t ad7793_show_scale_available(struct device *dev, | ||
611 | struct device_attribute *attr, char *buf) | ||
612 | { | ||
613 | struct iio_dev *indio_dev = dev_get_drvdata(dev); | ||
614 | struct ad7793_state *st = iio_priv(indio_dev); | ||
615 | int i, len = 0; | ||
616 | |||
617 | for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++) | ||
618 | len += sprintf(buf + len, "%d.%09u ", st->scale_avail[i][0], | ||
619 | st->scale_avail[i][1]); | ||
620 | |||
621 | len += sprintf(buf + len, "\n"); | ||
622 | |||
623 | return len; | ||
624 | } | ||
625 | |||
626 | static IIO_DEVICE_ATTR_NAMED(in_m_in_scale_available, in-in_scale_available, | ||
627 | S_IRUGO, ad7793_show_scale_available, NULL, 0); | ||
628 | |||
629 | static struct attribute *ad7793_attributes[] = { | ||
630 | &iio_dev_attr_sampling_frequency.dev_attr.attr, | ||
631 | &iio_const_attr_sampling_frequency_available.dev_attr.attr, | ||
632 | &iio_dev_attr_in_m_in_scale_available.dev_attr.attr, | ||
633 | NULL | ||
634 | }; | ||
635 | |||
636 | static const struct attribute_group ad7793_attribute_group = { | ||
637 | .attrs = ad7793_attributes, | ||
638 | }; | ||
639 | |||
640 | static int ad7793_read_raw(struct iio_dev *indio_dev, | ||
641 | struct iio_chan_spec const *chan, | ||
642 | int *val, | ||
643 | int *val2, | ||
644 | long m) | ||
645 | { | ||
646 | struct ad7793_state *st = iio_priv(indio_dev); | ||
647 | int ret, smpl = 0; | ||
648 | unsigned long long scale_uv; | ||
649 | bool unipolar = !!(st->conf & AD7793_CONF_UNIPOLAR); | ||
650 | |||
651 | switch (m) { | ||
652 | case 0: | ||
653 | mutex_lock(&indio_dev->mlock); | ||
654 | if (iio_ring_enabled(indio_dev)) | ||
655 | ret = ad7793_scan_from_ring(st, | ||
656 | chan->scan_index, &smpl); | ||
657 | else | ||
658 | ret = ad7793_read(st, chan->address, | ||
659 | chan->scan_type.realbits / 8, &smpl); | ||
660 | mutex_unlock(&indio_dev->mlock); | ||
661 | |||
662 | if (ret < 0) | ||
663 | return ret; | ||
664 | |||
665 | *val = (smpl >> chan->scan_type.shift) & | ||
666 | ((1 << (chan->scan_type.realbits)) - 1); | ||
667 | |||
668 | if (!unipolar) | ||
669 | *val -= (1 << (chan->scan_type.realbits - 1)); | ||
670 | |||
671 | return IIO_VAL_INT; | ||
672 | |||
673 | case (1 << IIO_CHAN_INFO_SCALE_SHARED): | ||
674 | *val = st->scale_avail[(st->conf >> 8) & 0x7][0]; | ||
675 | *val2 = st->scale_avail[(st->conf >> 8) & 0x7][1]; | ||
676 | |||
677 | return IIO_VAL_INT_PLUS_NANO; | ||
678 | |||
679 | case (1 << IIO_CHAN_INFO_SCALE_SEPARATE): | ||
680 | switch (chan->type) { | ||
681 | case IIO_IN: | ||
682 | /* 1170mV / 2^23 * 6 */ | ||
683 | scale_uv = (1170ULL * 100000000ULL * 6ULL) | ||
684 | >> (chan->scan_type.realbits - | ||
685 | (unipolar ? 0 : 1)); | ||
686 | break; | ||
687 | case IIO_TEMP: | ||
688 | /* Always uses unity gain and internal ref */ | ||
689 | scale_uv = (2500ULL * 100000000ULL) | ||
690 | >> (chan->scan_type.realbits - | ||
691 | (unipolar ? 0 : 1)); | ||
692 | break; | ||
693 | default: | ||
694 | return -EINVAL; | ||
695 | } | ||
696 | |||
697 | *val2 = do_div(scale_uv, 100000000) * 10; | ||
698 | *val = scale_uv; | ||
699 | |||
700 | return IIO_VAL_INT_PLUS_NANO; | ||
701 | } | ||
702 | return -EINVAL; | ||
703 | } | ||
704 | |||
705 | static int ad7793_write_raw(struct iio_dev *indio_dev, | ||
706 | struct iio_chan_spec const *chan, | ||
707 | int val, | ||
708 | int val2, | ||
709 | long mask) | ||
710 | { | ||
711 | struct ad7793_state *st = iio_priv(indio_dev); | ||
712 | int ret, i; | ||
713 | unsigned int tmp; | ||
714 | |||
715 | mutex_lock(&indio_dev->mlock); | ||
716 | if (iio_ring_enabled(indio_dev)) { | ||
717 | mutex_unlock(&indio_dev->mlock); | ||
718 | return -EBUSY; | ||
719 | } | ||
720 | |||
721 | switch (mask) { | ||
722 | case (1 << IIO_CHAN_INFO_SCALE_SHARED): | ||
723 | ret = -EINVAL; | ||
724 | for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++) | ||
725 | if (val2 == st->scale_avail[i][1]) { | ||
726 | tmp = st->conf; | ||
727 | st->conf &= ~AD7793_CONF_GAIN(-1); | ||
728 | st->conf |= AD7793_CONF_GAIN(i); | ||
729 | |||
730 | if (tmp != st->conf) { | ||
731 | ad7793_write_reg(st, AD7793_REG_CONF, | ||
732 | sizeof(st->conf), | ||
733 | st->conf); | ||
734 | ad7793_calibrate_all(st); | ||
735 | } | ||
736 | ret = 0; | ||
737 | } | ||
738 | |||
739 | default: | ||
740 | ret = -EINVAL; | ||
741 | } | ||
742 | |||
743 | mutex_unlock(&indio_dev->mlock); | ||
744 | return ret; | ||
745 | } | ||
746 | |||
747 | static int ad7793_validate_trigger(struct iio_dev *indio_dev, | ||
748 | struct iio_trigger *trig) | ||
749 | { | ||
750 | if (indio_dev->trig != trig) | ||
751 | return -EINVAL; | ||
752 | |||
753 | return 0; | ||
754 | } | ||
755 | |||
756 | static int ad7793_write_raw_get_fmt(struct iio_dev *indio_dev, | ||
757 | struct iio_chan_spec const *chan, | ||
758 | long mask) | ||
759 | { | ||
760 | return IIO_VAL_INT_PLUS_NANO; | ||
761 | } | ||
762 | |||
763 | static const struct iio_info ad7793_info = { | ||
764 | .read_raw = &ad7793_read_raw, | ||
765 | .write_raw = &ad7793_write_raw, | ||
766 | .write_raw_get_fmt = &ad7793_write_raw_get_fmt, | ||
767 | .attrs = &ad7793_attribute_group, | ||
768 | .validate_trigger = ad7793_validate_trigger, | ||
769 | .driver_module = THIS_MODULE, | ||
770 | }; | ||
771 | |||
772 | static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { | ||
773 | [ID_AD7793] = { | ||
774 | .channel[0] = IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 0, 0, | ||
775 | (1 << IIO_CHAN_INFO_SCALE_SHARED), | ||
776 | AD7793_CH_AIN1P_AIN1M, | ||
777 | 0, IIO_ST('s', 24, 32, 0), 0), | ||
778 | .channel[1] = IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 1, 1, | ||
779 | (1 << IIO_CHAN_INFO_SCALE_SHARED), | ||
780 | AD7793_CH_AIN2P_AIN2M, | ||
781 | 1, IIO_ST('s', 24, 32, 0), 0), | ||
782 | .channel[2] = IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 2, 2, | ||
783 | (1 << IIO_CHAN_INFO_SCALE_SHARED), | ||
784 | AD7793_CH_AIN3P_AIN3M, | ||
785 | 2, IIO_ST('s', 24, 32, 0), 0), | ||
786 | .channel[3] = IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, "shorted", 0, 0, | ||
787 | (1 << IIO_CHAN_INFO_SCALE_SHARED), | ||
788 | AD7793_CH_AIN1M_AIN1M, | ||
789 | 3, IIO_ST('s', 24, 32, 0), 0), | ||
790 | .channel[4] = IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0, | ||
791 | (1 << IIO_CHAN_INFO_SCALE_SEPARATE), | ||
792 | AD7793_CH_TEMP, | ||
793 | 4, IIO_ST('s', 24, 32, 0), 0), | ||
794 | .channel[5] = IIO_CHAN(IIO_IN, 0, 1, 0, "supply", 4, 0, | ||
795 | (1 << IIO_CHAN_INFO_SCALE_SEPARATE), | ||
796 | AD7793_CH_AVDD_MONITOR, | ||
797 | 5, IIO_ST('s', 24, 32, 0), 0), | ||
798 | .channel[6] = IIO_CHAN_SOFT_TIMESTAMP(6), | ||
799 | }, | ||
800 | [ID_AD7792] = { | ||
801 | .channel[0] = IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 0, 0, | ||
802 | (1 << IIO_CHAN_INFO_SCALE_SHARED), | ||
803 | AD7793_CH_AIN1P_AIN1M, | ||
804 | 0, IIO_ST('s', 16, 32, 0), 0), | ||
805 | .channel[1] = IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 1, 1, | ||
806 | (1 << IIO_CHAN_INFO_SCALE_SHARED), | ||
807 | AD7793_CH_AIN2P_AIN2M, | ||
808 | 1, IIO_ST('s', 16, 32, 0), 0), | ||
809 | .channel[2] = IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 2, 2, | ||
810 | (1 << IIO_CHAN_INFO_SCALE_SHARED), | ||
811 | AD7793_CH_AIN3P_AIN3M, | ||
812 | 2, IIO_ST('s', 16, 32, 0), 0), | ||
813 | .channel[3] = IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, "shorted", 0, 0, | ||
814 | (1 << IIO_CHAN_INFO_SCALE_SHARED), | ||
815 | AD7793_CH_AIN1M_AIN1M, | ||
816 | 3, IIO_ST('s', 16, 32, 0), 0), | ||
817 | .channel[4] = IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0, | ||
818 | (1 << IIO_CHAN_INFO_SCALE_SEPARATE), | ||
819 | AD7793_CH_TEMP, | ||
820 | 4, IIO_ST('s', 16, 32, 0), 0), | ||
821 | .channel[5] = IIO_CHAN(IIO_IN, 0, 1, 0, "supply", 4, 0, | ||
822 | (1 << IIO_CHAN_INFO_SCALE_SEPARATE), | ||
823 | AD7793_CH_AVDD_MONITOR, | ||
824 | 5, IIO_ST('s', 16, 32, 0), 0), | ||
825 | .channel[6] = IIO_CHAN_SOFT_TIMESTAMP(6), | ||
826 | }, | ||
827 | }; | ||
828 | |||
829 | static int __devinit ad7793_probe(struct spi_device *spi) | ||
830 | { | ||
831 | struct ad7793_platform_data *pdata = spi->dev.platform_data; | ||
832 | struct ad7793_state *st; | ||
833 | struct iio_dev *indio_dev; | ||
834 | int ret, i, voltage_uv = 0, regdone = 0; | ||
835 | |||
836 | if (!pdata) { | ||
837 | dev_err(&spi->dev, "no platform data?\n"); | ||
838 | return -ENODEV; | ||
839 | } | ||
840 | |||
841 | if (!spi->irq) { | ||
842 | dev_err(&spi->dev, "no IRQ?\n"); | ||
843 | return -ENODEV; | ||
844 | } | ||
845 | |||
846 | indio_dev = iio_allocate_device(sizeof(*st)); | ||
847 | if (indio_dev == NULL) | ||
848 | return -ENOMEM; | ||
849 | |||
850 | st = iio_priv(indio_dev); | ||
851 | |||
852 | st->reg = regulator_get(&spi->dev, "vcc"); | ||
853 | if (!IS_ERR(st->reg)) { | ||
854 | ret = regulator_enable(st->reg); | ||
855 | if (ret) | ||
856 | goto error_put_reg; | ||
857 | |||
858 | voltage_uv = regulator_get_voltage(st->reg); | ||
859 | } | ||
860 | |||
861 | st->chip_info = | ||
862 | &ad7793_chip_info_tbl[spi_get_device_id(spi)->driver_data]; | ||
863 | |||
864 | st->pdata = pdata; | ||
865 | |||
866 | if (pdata && pdata->vref_mv) | ||
867 | st->int_vref_mv = pdata->vref_mv; | ||
868 | else if (voltage_uv) | ||
869 | st->int_vref_mv = voltage_uv / 1000; | ||
870 | else | ||
871 | st->int_vref_mv = 2500; /* Build-in ref */ | ||
872 | |||
873 | spi_set_drvdata(spi, indio_dev); | ||
874 | st->spi = spi; | ||
875 | |||
876 | indio_dev->dev.parent = &spi->dev; | ||
877 | indio_dev->name = spi_get_device_id(spi)->name; | ||
878 | indio_dev->modes = INDIO_DIRECT_MODE; | ||
879 | indio_dev->channels = st->chip_info->channel; | ||
880 | indio_dev->available_scan_masks = st->available_scan_masks; | ||
881 | indio_dev->num_channels = 7; | ||
882 | indio_dev->info = &ad7793_info; | ||
883 | |||
884 | for (i = 0; i < indio_dev->num_channels; i++) | ||
885 | st->available_scan_masks[i] = (1 << i) | (1 << | ||
886 | indio_dev->channels[indio_dev->num_channels - 1]. | ||
887 | scan_index); | ||
888 | |||
889 | init_waitqueue_head(&st->wq_data_avail); | ||
890 | |||
891 | ret = ad7793_register_ring_funcs_and_init(indio_dev); | ||
892 | if (ret) | ||
893 | goto error_disable_reg; | ||
894 | |||
895 | ret = iio_device_register(indio_dev); | ||
896 | if (ret) | ||
897 | goto error_unreg_ring; | ||
898 | regdone = 1; | ||
899 | |||
900 | ret = ad7793_probe_trigger(indio_dev); | ||
901 | if (ret) | ||
902 | goto error_unreg_ring; | ||
903 | |||
904 | ret = iio_ring_buffer_register_ex(indio_dev->ring, 0, | ||
905 | indio_dev->channels, | ||
906 | indio_dev->num_channels); | ||
907 | if (ret) | ||
908 | goto error_remove_trigger; | ||
909 | |||
910 | ret = ad7793_setup(st); | ||
911 | if (ret) | ||
912 | goto error_uninitialize_ring; | ||
913 | |||
914 | return 0; | ||
915 | |||
916 | error_uninitialize_ring: | ||
917 | iio_ring_buffer_unregister(indio_dev->ring); | ||
918 | error_remove_trigger: | ||
919 | ad7793_remove_trigger(indio_dev); | ||
920 | error_unreg_ring: | ||
921 | ad7793_ring_cleanup(indio_dev); | ||
922 | error_disable_reg: | ||
923 | if (!IS_ERR(st->reg)) | ||
924 | regulator_disable(st->reg); | ||
925 | error_put_reg: | ||
926 | if (!IS_ERR(st->reg)) | ||
927 | regulator_put(st->reg); | ||
928 | |||
929 | if (regdone) | ||
930 | iio_device_unregister(indio_dev); | ||
931 | else | ||
932 | iio_free_device(indio_dev); | ||
933 | |||
934 | return ret; | ||
935 | } | ||
936 | |||
937 | static int ad7793_remove(struct spi_device *spi) | ||
938 | { | ||
939 | struct iio_dev *indio_dev = spi_get_drvdata(spi); | ||
940 | struct ad7793_state *st = iio_priv(indio_dev); | ||
941 | |||
942 | iio_ring_buffer_unregister(indio_dev->ring); | ||
943 | ad7793_remove_trigger(indio_dev); | ||
944 | ad7793_ring_cleanup(indio_dev); | ||
945 | |||
946 | if (!IS_ERR(st->reg)) { | ||
947 | regulator_disable(st->reg); | ||
948 | regulator_put(st->reg); | ||
949 | } | ||
950 | |||
951 | iio_device_unregister(indio_dev); | ||
952 | |||
953 | return 0; | ||
954 | } | ||
955 | |||
956 | static const struct spi_device_id ad7793_id[] = { | ||
957 | {"ad7792", ID_AD7792}, | ||
958 | {"ad7793", ID_AD7793}, | ||
959 | {} | ||
960 | }; | ||
961 | |||
962 | static struct spi_driver ad7793_driver = { | ||
963 | .driver = { | ||
964 | .name = "ad7793", | ||
965 | .bus = &spi_bus_type, | ||
966 | .owner = THIS_MODULE, | ||
967 | }, | ||
968 | .probe = ad7793_probe, | ||
969 | .remove = __devexit_p(ad7793_remove), | ||
970 | .id_table = ad7793_id, | ||
971 | }; | ||
972 | |||
973 | static int __init ad7793_init(void) | ||
974 | { | ||
975 | return spi_register_driver(&ad7793_driver); | ||
976 | } | ||
977 | module_init(ad7793_init); | ||
978 | |||
979 | static void __exit ad7793_exit(void) | ||
980 | { | ||
981 | spi_unregister_driver(&ad7793_driver); | ||
982 | } | ||
983 | module_exit(ad7793_exit); | ||
984 | |||
985 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | ||
986 | MODULE_DESCRIPTION("Analog Devices AD7792/3 ADC"); | ||
987 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/staging/iio/adc/ad7793.h b/drivers/staging/iio/adc/ad7793.h new file mode 100644 index 00000000000..64f7d41dc45 --- /dev/null +++ b/drivers/staging/iio/adc/ad7793.h | |||
@@ -0,0 +1,107 @@ | |||
1 | /* | ||
2 | * AD7792/AD7793 SPI ADC driver | ||
3 | * | ||
4 | * Copyright 2011 Analog Devices Inc. | ||
5 | * | ||
6 | * Licensed under the GPL-2. | ||
7 | */ | ||
8 | #ifndef IIO_ADC_AD7793_H_ | ||
9 | #define IIO_ADC_AD7793_H_ | ||
10 | |||
11 | /* | ||
12 | * TODO: struct ad7793_platform_data needs to go into include/linux/iio | ||
13 | */ | ||
14 | |||
15 | /* Registers */ | ||
16 | #define AD7793_REG_COMM 0 /* Communications Register (WO, 8-bit) */ | ||
17 | #define AD7793_REG_STAT 0 /* Status Register (RO, 8-bit) */ | ||
18 | #define AD7793_REG_MODE 1 /* Mode Register (RW, 16-bit */ | ||
19 | #define AD7793_REG_CONF 2 /* Configuration Register (RW, 16-bit) */ | ||
20 | #define AD7793_REG_DATA 3 /* Data Register (RO, 16-/24-bit) */ | ||
21 | #define AD7793_REG_ID 4 /* ID Register (RO, 8-bit) */ | ||
22 | #define AD7793_REG_IO 5 /* IO Register (RO, 8-bit) */ | ||
23 | #define AD7793_REG_OFFSET 6 /* Offset Register (RW, 16-bit | ||
24 | * (AD7792)/24-bit (AD7793)) */ | ||
25 | #define AD7793_REG_FULLSALE 7 /* Full-Scale Register | ||
26 | * (RW, 16-bit (AD7792)/24-bit (AD7793)) */ | ||
27 | |||
28 | /* Communications Register Bit Designations (AD7793_REG_COMM) */ | ||
29 | #define AD7793_COMM_WEN (1 << 7) /* Write Enable */ | ||
30 | #define AD7793_COMM_WRITE (0 << 6) /* Write Operation */ | ||
31 | #define AD7793_COMM_READ (1 << 6) /* Read Operation */ | ||
32 | #define AD7793_COMM_ADDR(x) (((x) & 0x7) << 3) /* Register Address */ | ||
33 | #define AD7793_COMM_CREAD (1 << 2) /* Continuous Read of Data Register */ | ||
34 | |||
35 | /* Status Register Bit Designations (AD7793_REG_STAT) */ | ||
36 | #define AD7793_STAT_RDY (1 << 7) /* Ready */ | ||
37 | #define AD7793_STAT_ERR (1 << 6) /* Error (Overrange, Underrange) */ | ||
38 | #define AD7793_STAT_CH3 (1 << 2) /* Channel 3 */ | ||
39 | #define AD7793_STAT_CH2 (1 << 1) /* Channel 2 */ | ||
40 | #define AD7793_STAT_CH1 (1 << 0) /* Channel 1 */ | ||
41 | |||
42 | /* Mode Register Bit Designations (AD7793_REG_MODE) */ | ||
43 | #define AD7793_MODE_SEL(x) (((x) & 0x7) << 13) /* Operation Mode Select */ | ||
44 | #define AD7793_MODE_CLKSRC(x) (((x) & 0x3) << 6) /* ADC Clock Source Select */ | ||
45 | #define AD7793_MODE_RATE(x) ((x) & 0xF) /* Filter Update Rate Select */ | ||
46 | |||
47 | #define AD7793_MODE_CONT 0 /* Continuous Conversion Mode */ | ||
48 | #define AD7793_MODE_SINGLE 1 /* Single Conversion Mode */ | ||
49 | #define AD7793_MODE_IDLE 2 /* Idle Mode */ | ||
50 | #define AD7793_MODE_PWRDN 3 /* Power-Down Mode */ | ||
51 | #define AD7793_MODE_CAL_INT_ZERO 4 /* Internal Zero-Scale Calibration */ | ||
52 | #define AD7793_MODE_CAL_INT_FULL 5 /* Internal Full-Scale Calibration */ | ||
53 | #define AD7793_MODE_CAL_SYS_ZERO 6 /* System Zero-Scale Calibration */ | ||
54 | #define AD7793_MODE_CAL_SYS_FULL 7 /* System Full-Scale Calibration */ | ||
55 | |||
56 | #define AD7793_CLK_INT 0 /* Internal 64 kHz Clock not | ||
57 | * available at the CLK pin */ | ||
58 | #define AD7793_CLK_INT_CO 1 /* Internal 64 kHz Clock available | ||
59 | * at the CLK pin */ | ||
60 | #define AD7793_CLK_EXT 2 /* External 64 kHz Clock */ | ||
61 | #define AD7793_CLK_EXT_DIV2 3 /* External Clock divided by 2 */ | ||
62 | |||
63 | /* Configuration Register Bit Designations (AD7793_REG_CONF) */ | ||
64 | #define AD7793_CONF_VBIAS(x) (((x) & 0x3) << 14) /* Bias Voltage | ||
65 | * Generator Enable */ | ||
66 | #define AD7793_CONF_BO_EN (1 << 13) /* Burnout Current Enable */ | ||
67 | #define AD7793_CONF_UNIPOLAR (1 << 12) /* Unipolar/Bipolar Enable */ | ||
68 | #define AD7793_CONF_BOOST (1 << 11) /* Boost Enable */ | ||
69 | #define AD7793_CONF_GAIN(x) (((x) & 0x7) << 8) /* Gain Select */ | ||
70 | #define AD7793_CONF_REFSEL (1 << 7) /* INT/EXT Reference Select */ | ||
71 | #define AD7793_CONF_BUF (1 << 4) /* Buffered Mode Enable */ | ||
72 | #define AD7793_CONF_CHAN(x) ((x) & 0x7) /* Channel select */ | ||
73 | |||
74 | #define AD7793_CH_AIN1P_AIN1M 0 /* AIN1(+) - AIN1(-) */ | ||
75 | #define AD7793_CH_AIN2P_AIN2M 1 /* AIN2(+) - AIN2(-) */ | ||
76 | #define AD7793_CH_AIN3P_AIN3M 2 /* AIN3(+) - AIN3(-) */ | ||
77 | #define AD7793_CH_AIN1M_AIN1M 3 /* AIN1(-) - AIN1(-) */ | ||
78 | #define AD7793_CH_TEMP 6 /* Temp Sensor */ | ||
79 | #define AD7793_CH_AVDD_MONITOR 7 /* AVDD Monitor */ | ||
80 | |||
81 | /* ID Register Bit Designations (AD7793_REG_ID) */ | ||
82 | #define AD7792_ID 0xA | ||
83 | #define AD7793_ID 0xB | ||
84 | #define AD7793_ID_MASK 0xF | ||
85 | |||
86 | /* IO (Excitation Current Sources) Register Bit Designations (AD7793_REG_IO) */ | ||
87 | #define AD7793_IO_IEXC1_IOUT1_IEXC2_IOUT2 0 /* IEXC1 connect to IOUT1, | ||
88 | * IEXC2 connect to IOUT2 */ | ||
89 | #define AD7793_IO_IEXC1_IOUT2_IEXC2_IOUT1 1 /* IEXC1 connect to IOUT2, | ||
90 | * IEXC2 connect to IOUT1 */ | ||
91 | #define AD7793_IO_IEXC1_IEXC2_IOUT1 2 /* Both current sources | ||
92 | * IEXC1,2 connect to IOUT1 */ | ||
93 | #define AD7793_IO_IEXC1_IEXC2_IOUT2 3 /* Both current sources | ||
94 | * IEXC1,2 connect to IOUT2 */ | ||
95 | |||
96 | #define AD7793_IO_IXCEN_10uA (1 << 0) /* Excitation Current 10uA */ | ||
97 | #define AD7793_IO_IXCEN_210uA (2 << 0) /* Excitation Current 210uA */ | ||
98 | #define AD7793_IO_IXCEN_1mA (3 << 0) /* Excitation Current 1mA */ | ||
99 | |||
100 | struct ad7793_platform_data { | ||
101 | u16 vref_mv; | ||
102 | u16 mode; | ||
103 | u16 conf; | ||
104 | u8 io; | ||
105 | }; | ||
106 | |||
107 | #endif /* IIO_ADC_AD7793_H_ */ | ||
diff --git a/drivers/staging/iio/adc/ad7887.h b/drivers/staging/iio/adc/ad7887.h new file mode 100644 index 00000000000..837046c7b89 --- /dev/null +++ b/drivers/staging/iio/adc/ad7887.h | |||
@@ -0,0 +1,105 @@ | |||
1 | /* | ||
2 | * AD7887 SPI ADC driver | ||
3 | * | ||
4 | * Copyright 2010 Analog Devices Inc. | ||
5 | * | ||
6 | * Licensed under the GPL-2 or later. | ||
7 | */ | ||
8 | #ifndef IIO_ADC_AD7887_H_ | ||
9 | #define IIO_ADC_AD7887_H_ | ||
10 | |||
11 | #define AD7887_REF_DIS (1 << 5) /* on-chip reference disable */ | ||
12 | #define AD7887_DUAL (1 << 4) /* dual-channel mode */ | ||
13 | #define AD7887_CH_AIN1 (1 << 3) /* convert on channel 1, DUAL=1 */ | ||
14 | #define AD7887_CH_AIN0 (0 << 3) /* convert on channel 0, DUAL=0,1 */ | ||
15 | #define AD7887_PM_MODE1 (0) /* CS based shutdown */ | ||
16 | #define AD7887_PM_MODE2 (1) /* full on */ | ||
17 | #define AD7887_PM_MODE3 (2) /* auto shutdown after conversion */ | ||
18 | #define AD7887_PM_MODE4 (3) /* standby mode */ | ||
19 | |||
20 | enum ad7887_channels { | ||
21 | AD7887_CH0, | ||
22 | AD7887_CH0_CH1, | ||
23 | AD7887_CH1, | ||
24 | }; | ||
25 | |||
26 | #define RES_MASK(bits) ((1 << (bits)) - 1) /* TODO: move this into a common header */ | ||
27 | |||
28 | /* | ||
29 | * TODO: struct ad7887_platform_data needs to go into include/linux/iio | ||
30 | */ | ||
31 | |||
32 | struct ad7887_platform_data { | ||
33 | /* External Vref voltage applied */ | ||
34 | u16 vref_mv; | ||
35 | /* | ||
36 | * AD7887: | ||
37 | * In single channel mode en_dual = flase, AIN1/Vref pins assumes its | ||
38 | * Vref function. In dual channel mode en_dual = true, AIN1 becomes the | ||
39 | * second input channel, and Vref is internally connected to Vdd. | ||
40 | */ | ||
41 | bool en_dual; | ||
42 | /* | ||
43 | * AD7887: | ||
44 | * use_onchip_ref = true, the Vref is internally connected to the 2.500V | ||
45 | * Voltage reference. If use_onchip_ref = false, the reference voltage | ||
46 | * is supplied by AIN1/Vref | ||
47 | */ | ||
48 | bool use_onchip_ref; | ||
49 | }; | ||
50 | |||
51 | /** | ||
52 | * struct ad7887_chip_info - chip specifc information | ||
53 | * @int_vref_mv: the internal reference voltage | ||
54 | * @channel: channel specification | ||
55 | */ | ||
56 | |||
57 | struct ad7887_chip_info { | ||
58 | u16 int_vref_mv; | ||
59 | struct iio_chan_spec channel[3]; | ||
60 | }; | ||
61 | |||
62 | struct ad7887_state { | ||
63 | struct spi_device *spi; | ||
64 | const struct ad7887_chip_info *chip_info; | ||
65 | struct regulator *reg; | ||
66 | size_t d_size; | ||
67 | u16 int_vref_mv; | ||
68 | struct spi_transfer xfer[4]; | ||
69 | struct spi_message msg[3]; | ||
70 | struct spi_message *ring_msg; | ||
71 | unsigned char tx_cmd_buf[8]; | ||
72 | |||
73 | /* | ||
74 | * DMA (thus cache coherency maintenance) requires the | ||
75 | * transfer buffers to live in their own cache lines. | ||
76 | */ | ||
77 | |||
78 | unsigned char data[4] ____cacheline_aligned; | ||
79 | }; | ||
80 | |||
81 | enum ad7887_supported_device_ids { | ||
82 | ID_AD7887 | ||
83 | }; | ||
84 | |||
85 | #ifdef CONFIG_IIO_RING_BUFFER | ||
86 | int ad7887_scan_from_ring(struct ad7887_state *st, long mask); | ||
87 | int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev); | ||
88 | void ad7887_ring_cleanup(struct iio_dev *indio_dev); | ||
89 | #else /* CONFIG_IIO_RING_BUFFER */ | ||
90 | static inline int ad7887_scan_from_ring(struct ad7887_state *st, long mask) | ||
91 | { | ||
92 | return 0; | ||
93 | } | ||
94 | |||
95 | static inline int | ||
96 | ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev) | ||
97 | { | ||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | static inline void ad7887_ring_cleanup(struct iio_dev *indio_dev) | ||
102 | { | ||
103 | } | ||
104 | #endif /* CONFIG_IIO_RING_BUFFER */ | ||
105 | #endif /* IIO_ADC_AD7887_H_ */ | ||
diff --git a/drivers/staging/iio/adc/ad7887_core.c b/drivers/staging/iio/adc/ad7887_core.c new file mode 100644 index 00000000000..3d9121e5c37 --- /dev/null +++ b/drivers/staging/iio/adc/ad7887_core.c | |||
@@ -0,0 +1,266 @@ | |||
1 | /* | ||
2 | * AD7887 SPI ADC driver | ||
3 | * | ||
4 | * Copyright 2010-2011 Analog Devices Inc. | ||
5 | * | ||
6 | * Licensed under the GPL-2. | ||
7 | */ | ||
8 | |||
9 | #include <linux/device.h> | ||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/slab.h> | ||
12 | #include <linux/sysfs.h> | ||
13 | #include <linux/spi/spi.h> | ||
14 | #include <linux/regulator/consumer.h> | ||
15 | #include <linux/err.h> | ||
16 | |||
17 | #include "../iio.h" | ||
18 | #include "../sysfs.h" | ||
19 | #include "../ring_generic.h" | ||
20 | #include "adc.h" | ||
21 | |||
22 | #include "ad7887.h" | ||
23 | |||
24 | static int ad7887_scan_direct(struct ad7887_state *st, unsigned ch) | ||
25 | { | ||
26 | int ret = spi_sync(st->spi, &st->msg[ch]); | ||
27 | if (ret) | ||
28 | return ret; | ||
29 | |||
30 | return (st->data[(ch * 2)] << 8) | st->data[(ch * 2) + 1]; | ||
31 | } | ||
32 | |||
33 | static int ad7887_read_raw(struct iio_dev *dev_info, | ||
34 | struct iio_chan_spec const *chan, | ||
35 | int *val, | ||
36 | int *val2, | ||
37 | long m) | ||
38 | { | ||
39 | int ret; | ||
40 | struct ad7887_state *st = iio_priv(dev_info); | ||
41 | unsigned int scale_uv; | ||
42 | |||
43 | switch (m) { | ||
44 | case 0: | ||
45 | mutex_lock(&dev_info->mlock); | ||
46 | if (iio_ring_enabled(dev_info)) | ||
47 | ret = ad7887_scan_from_ring(st, 1 << chan->address); | ||
48 | else | ||
49 | ret = ad7887_scan_direct(st, chan->address); | ||
50 | mutex_unlock(&dev_info->mlock); | ||
51 | |||
52 | if (ret < 0) | ||
53 | return ret; | ||
54 | *val = (ret >> st->chip_info->channel[0].scan_type.shift) & | ||
55 | RES_MASK(st->chip_info->channel[0].scan_type.realbits); | ||
56 | return IIO_VAL_INT; | ||
57 | case (1 << IIO_CHAN_INFO_SCALE_SHARED): | ||
58 | scale_uv = (st->int_vref_mv * 1000) | ||
59 | >> st->chip_info->channel[0].scan_type.realbits; | ||
60 | *val = scale_uv/1000; | ||
61 | *val2 = (scale_uv%1000)*1000; | ||
62 | return IIO_VAL_INT_PLUS_MICRO; | ||
63 | } | ||
64 | return -EINVAL; | ||
65 | } | ||
66 | |||
67 | |||
68 | static const struct ad7887_chip_info ad7887_chip_info_tbl[] = { | ||
69 | /* | ||
70 | * More devices added in future | ||
71 | */ | ||
72 | [ID_AD7887] = { | ||
73 | .channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0, | ||
74 | (1 << IIO_CHAN_INFO_SCALE_SHARED), | ||
75 | 1, 1, IIO_ST('u', 12, 16, 0), 0), | ||
76 | |||
77 | .channel[1] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0, | ||
78 | (1 << IIO_CHAN_INFO_SCALE_SHARED), | ||
79 | 0, 0, IIO_ST('u', 12, 16, 0), 0), | ||
80 | |||
81 | .channel[2] = IIO_CHAN_SOFT_TIMESTAMP(2), | ||
82 | .int_vref_mv = 2500, | ||
83 | }, | ||
84 | }; | ||
85 | |||
86 | static const struct iio_info ad7887_info = { | ||
87 | .read_raw = &ad7887_read_raw, | ||
88 | .driver_module = THIS_MODULE, | ||
89 | }; | ||
90 | |||
91 | static int __devinit ad7887_probe(struct spi_device *spi) | ||
92 | { | ||
93 | struct ad7887_platform_data *pdata = spi->dev.platform_data; | ||
94 | struct ad7887_state *st; | ||
95 | int ret, voltage_uv = 0, regdone = 0; | ||
96 | struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st)); | ||
97 | |||
98 | if (indio_dev == NULL) | ||
99 | return -ENOMEM; | ||
100 | |||
101 | st = iio_priv(indio_dev); | ||
102 | |||
103 | st->reg = regulator_get(&spi->dev, "vcc"); | ||
104 | if (!IS_ERR(st->reg)) { | ||
105 | ret = regulator_enable(st->reg); | ||
106 | if (ret) | ||
107 | goto error_put_reg; | ||
108 | |||
109 | voltage_uv = regulator_get_voltage(st->reg); | ||
110 | } | ||
111 | |||
112 | st->chip_info = | ||
113 | &ad7887_chip_info_tbl[spi_get_device_id(spi)->driver_data]; | ||
114 | |||
115 | spi_set_drvdata(spi, indio_dev); | ||
116 | st->spi = spi; | ||
117 | |||
118 | /* Estabilish that the iio_dev is a child of the spi device */ | ||
119 | indio_dev->dev.parent = &spi->dev; | ||
120 | indio_dev->name = spi_get_device_id(spi)->name; | ||
121 | indio_dev->info = &ad7887_info; | ||
122 | indio_dev->modes = INDIO_DIRECT_MODE; | ||
123 | |||
124 | /* Setup default message */ | ||
125 | |||
126 | st->tx_cmd_buf[0] = AD7887_CH_AIN0 | AD7887_PM_MODE4 | | ||
127 | ((pdata && pdata->use_onchip_ref) ? | ||
128 | 0 : AD7887_REF_DIS); | ||
129 | |||
130 | st->xfer[0].rx_buf = &st->data[0]; | ||
131 | st->xfer[0].tx_buf = &st->tx_cmd_buf[0]; | ||
132 | st->xfer[0].len = 2; | ||
133 | |||
134 | spi_message_init(&st->msg[AD7887_CH0]); | ||
135 | spi_message_add_tail(&st->xfer[0], &st->msg[AD7887_CH0]); | ||
136 | |||
137 | if (pdata && pdata->en_dual) { | ||
138 | st->tx_cmd_buf[0] |= AD7887_DUAL | AD7887_REF_DIS; | ||
139 | |||
140 | st->tx_cmd_buf[2] = AD7887_CH_AIN1 | AD7887_DUAL | | ||
141 | AD7887_REF_DIS | AD7887_PM_MODE4; | ||
142 | st->tx_cmd_buf[4] = AD7887_CH_AIN0 | AD7887_DUAL | | ||
143 | AD7887_REF_DIS | AD7887_PM_MODE4; | ||
144 | st->tx_cmd_buf[6] = AD7887_CH_AIN1 | AD7887_DUAL | | ||
145 | AD7887_REF_DIS | AD7887_PM_MODE4; | ||
146 | |||
147 | st->xfer[1].rx_buf = &st->data[0]; | ||
148 | st->xfer[1].tx_buf = &st->tx_cmd_buf[2]; | ||
149 | st->xfer[1].len = 2; | ||
150 | |||
151 | st->xfer[2].rx_buf = &st->data[2]; | ||
152 | st->xfer[2].tx_buf = &st->tx_cmd_buf[4]; | ||
153 | st->xfer[2].len = 2; | ||
154 | |||
155 | spi_message_init(&st->msg[AD7887_CH0_CH1]); | ||
156 | spi_message_add_tail(&st->xfer[1], &st->msg[AD7887_CH0_CH1]); | ||
157 | spi_message_add_tail(&st->xfer[2], &st->msg[AD7887_CH0_CH1]); | ||
158 | |||
159 | st->xfer[3].rx_buf = &st->data[0]; | ||
160 | st->xfer[3].tx_buf = &st->tx_cmd_buf[6]; | ||
161 | st->xfer[3].len = 2; | ||
162 | |||
163 | spi_message_init(&st->msg[AD7887_CH1]); | ||
164 | spi_message_add_tail(&st->xfer[3], &st->msg[AD7887_CH1]); | ||
165 | |||
166 | if (pdata && pdata->vref_mv) | ||
167 | st->int_vref_mv = pdata->vref_mv; | ||
168 | else if (voltage_uv) | ||
169 | st->int_vref_mv = voltage_uv / 1000; | ||
170 | else | ||
171 | dev_warn(&spi->dev, "reference voltage unspecified\n"); | ||
172 | |||
173 | indio_dev->channels = st->chip_info->channel; | ||
174 | indio_dev->num_channels = 3; | ||
175 | } else { | ||
176 | if (pdata && pdata->vref_mv) | ||
177 | st->int_vref_mv = pdata->vref_mv; | ||
178 | else if (pdata && pdata->use_onchip_ref) | ||
179 | st->int_vref_mv = st->chip_info->int_vref_mv; | ||
180 | else | ||
181 | dev_warn(&spi->dev, "reference voltage unspecified\n"); | ||
182 | |||
183 | indio_dev->channels = &st->chip_info->channel[1]; | ||
184 | indio_dev->num_channels = 2; | ||
185 | } | ||
186 | |||
187 | ret = ad7887_register_ring_funcs_and_init(indio_dev); | ||
188 | if (ret) | ||
189 | goto error_disable_reg; | ||
190 | |||
191 | ret = iio_device_register(indio_dev); | ||
192 | if (ret) | ||
193 | goto error_disable_reg; | ||
194 | regdone = 1; | ||
195 | |||
196 | ret = iio_ring_buffer_register_ex(indio_dev->ring, 0, | ||
197 | indio_dev->channels, | ||
198 | indio_dev->num_channels); | ||
199 | if (ret) | ||
200 | goto error_cleanup_ring; | ||
201 | return 0; | ||
202 | |||
203 | error_cleanup_ring: | ||
204 | ad7887_ring_cleanup(indio_dev); | ||
205 | error_disable_reg: | ||
206 | if (!IS_ERR(st->reg)) | ||
207 | regulator_disable(st->reg); | ||
208 | error_put_reg: | ||
209 | if (!IS_ERR(st->reg)) | ||
210 | regulator_put(st->reg); | ||
211 | if (regdone) | ||
212 | iio_device_unregister(indio_dev); | ||
213 | else | ||
214 | iio_free_device(indio_dev); | ||
215 | |||
216 | return ret; | ||
217 | } | ||
218 | |||
219 | static int ad7887_remove(struct spi_device *spi) | ||
220 | { | ||
221 | struct iio_dev *indio_dev = spi_get_drvdata(spi); | ||
222 | struct ad7887_state *st = iio_priv(indio_dev); | ||
223 | |||
224 | iio_ring_buffer_unregister(indio_dev->ring); | ||
225 | ad7887_ring_cleanup(indio_dev); | ||
226 | if (!IS_ERR(st->reg)) { | ||
227 | regulator_disable(st->reg); | ||
228 | regulator_put(st->reg); | ||
229 | } | ||
230 | iio_device_unregister(indio_dev); | ||
231 | |||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | static const struct spi_device_id ad7887_id[] = { | ||
236 | {"ad7887", ID_AD7887}, | ||
237 | {} | ||
238 | }; | ||
239 | |||
240 | static struct spi_driver ad7887_driver = { | ||
241 | .driver = { | ||
242 | .name = "ad7887", | ||
243 | .bus = &spi_bus_type, | ||
244 | .owner = THIS_MODULE, | ||
245 | }, | ||
246 | .probe = ad7887_probe, | ||
247 | .remove = __devexit_p(ad7887_remove), | ||
248 | .id_table = ad7887_id, | ||
249 | }; | ||
250 | |||
251 | static int __init ad7887_init(void) | ||
252 | { | ||
253 | return spi_register_driver(&ad7887_driver); | ||
254 | } | ||
255 | module_init(ad7887_init); | ||
256 | |||
257 | static void __exit ad7887_exit(void) | ||
258 | { | ||
259 | spi_unregister_driver(&ad7887_driver); | ||
260 | } | ||
261 | module_exit(ad7887_exit); | ||
262 | |||
263 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | ||
264 | MODULE_DESCRIPTION("Analog Devices AD7887 ADC"); | ||
265 | MODULE_LICENSE("GPL v2"); | ||
266 | MODULE_ALIAS("spi:ad7887"); | ||
diff --git a/drivers/staging/iio/adc/ad7887_ring.c b/drivers/staging/iio/adc/ad7887_ring.c new file mode 100644 index 00000000000..0ac7c0b9d71 --- /dev/null +++ b/drivers/staging/iio/adc/ad7887_ring.c | |||
@@ -0,0 +1,202 @@ | |||
1 | /* | ||
2 | * Copyright 2010-2011 Analog Devices Inc. | ||
3 | * Copyright (C) 2008 Jonathan Cameron | ||
4 | * | ||
5 | * Licensed under the GPL-2. | ||
6 | * | ||
7 | * ad7887_ring.c | ||
8 | */ | ||
9 | |||
10 | #include <linux/interrupt.h> | ||
11 | #include <linux/device.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/sysfs.h> | ||
15 | #include <linux/spi/spi.h> | ||
16 | |||
17 | #include "../iio.h" | ||
18 | #include "../ring_generic.h" | ||
19 | #include "../ring_sw.h" | ||
20 | #include "../trigger.h" | ||
21 | #include "../sysfs.h" | ||
22 | |||
23 | #include "ad7887.h" | ||
24 | |||
25 | int ad7887_scan_from_ring(struct ad7887_state *st, long mask) | ||
26 | { | ||
27 | struct iio_ring_buffer *ring = iio_priv_to_dev(st)->ring; | ||
28 | int count = 0, ret; | ||
29 | u16 *ring_data; | ||
30 | |||
31 | if (!(ring->scan_mask & mask)) { | ||
32 | ret = -EBUSY; | ||
33 | goto error_ret; | ||
34 | } | ||
35 | |||
36 | ring_data = kmalloc(ring->access->get_bytes_per_datum(ring), | ||
37 | GFP_KERNEL); | ||
38 | if (ring_data == NULL) { | ||
39 | ret = -ENOMEM; | ||
40 | goto error_ret; | ||
41 | } | ||
42 | ret = ring->access->read_last(ring, (u8 *) ring_data); | ||
43 | if (ret) | ||
44 | goto error_free_ring_data; | ||
45 | |||
46 | /* for single channel scan the result is stored with zero offset */ | ||
47 | if ((ring->scan_mask == ((1 << 1) | (1 << 0))) && (mask == (1 << 1))) | ||
48 | count = 1; | ||
49 | |||
50 | ret = be16_to_cpu(ring_data[count]); | ||
51 | |||
52 | error_free_ring_data: | ||
53 | kfree(ring_data); | ||
54 | error_ret: | ||
55 | return ret; | ||
56 | } | ||
57 | |||
58 | /** | ||
59 | * ad7887_ring_preenable() setup the parameters of the ring before enabling | ||
60 | * | ||
61 | * The complex nature of the setting of the nuber of bytes per datum is due | ||
62 | * to this driver currently ensuring that the timestamp is stored at an 8 | ||
63 | * byte boundary. | ||
64 | **/ | ||
65 | static int ad7887_ring_preenable(struct iio_dev *indio_dev) | ||
66 | { | ||
67 | struct ad7887_state *st = iio_priv(indio_dev); | ||
68 | struct iio_ring_buffer *ring = indio_dev->ring; | ||
69 | |||
70 | st->d_size = ring->scan_count * | ||
71 | st->chip_info->channel[0].scan_type.storagebits / 8; | ||
72 | |||
73 | if (ring->scan_timestamp) { | ||
74 | st->d_size += sizeof(s64); | ||
75 | |||
76 | if (st->d_size % sizeof(s64)) | ||
77 | st->d_size += sizeof(s64) - (st->d_size % sizeof(s64)); | ||
78 | } | ||
79 | |||
80 | if (indio_dev->ring->access->set_bytes_per_datum) | ||
81 | indio_dev->ring->access->set_bytes_per_datum(indio_dev->ring, | ||
82 | st->d_size); | ||
83 | |||
84 | switch (ring->scan_mask) { | ||
85 | case (1 << 0): | ||
86 | st->ring_msg = &st->msg[AD7887_CH0]; | ||
87 | break; | ||
88 | case (1 << 1): | ||
89 | st->ring_msg = &st->msg[AD7887_CH1]; | ||
90 | /* Dummy read: push CH1 setting down to hardware */ | ||
91 | spi_sync(st->spi, st->ring_msg); | ||
92 | break; | ||
93 | case ((1 << 1) | (1 << 0)): | ||
94 | st->ring_msg = &st->msg[AD7887_CH0_CH1]; | ||
95 | break; | ||
96 | } | ||
97 | |||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | static int ad7887_ring_postdisable(struct iio_dev *indio_dev) | ||
102 | { | ||
103 | struct ad7887_state *st = iio_priv(indio_dev); | ||
104 | |||
105 | /* dummy read: restore default CH0 settin */ | ||
106 | return spi_sync(st->spi, &st->msg[AD7887_CH0]); | ||
107 | } | ||
108 | |||
109 | /** | ||
110 | * ad7887_trigger_handler() bh of trigger launched polling to ring buffer | ||
111 | * | ||
112 | * Currently there is no option in this driver to disable the saving of | ||
113 | * timestamps within the ring. | ||
114 | **/ | ||
115 | static irqreturn_t ad7887_trigger_handler(int irq, void *p) | ||
116 | { | ||
117 | struct iio_poll_func *pf = p; | ||
118 | struct iio_dev *indio_dev = pf->private_data; | ||
119 | struct ad7887_state *st = iio_priv(indio_dev); | ||
120 | struct iio_ring_buffer *ring = indio_dev->ring; | ||
121 | s64 time_ns; | ||
122 | __u8 *buf; | ||
123 | int b_sent; | ||
124 | |||
125 | unsigned int bytes = ring->scan_count * | ||
126 | st->chip_info->channel[0].scan_type.storagebits / 8; | ||
127 | |||
128 | buf = kzalloc(st->d_size, GFP_KERNEL); | ||
129 | if (buf == NULL) | ||
130 | return -ENOMEM; | ||
131 | |||
132 | b_sent = spi_sync(st->spi, st->ring_msg); | ||
133 | if (b_sent) | ||
134 | goto done; | ||
135 | |||
136 | time_ns = iio_get_time_ns(); | ||
137 | |||
138 | memcpy(buf, st->data, bytes); | ||
139 | if (ring->scan_timestamp) | ||
140 | memcpy(buf + st->d_size - sizeof(s64), | ||
141 | &time_ns, sizeof(time_ns)); | ||
142 | |||
143 | indio_dev->ring->access->store_to(indio_dev->ring, buf, time_ns); | ||
144 | done: | ||
145 | kfree(buf); | ||
146 | iio_trigger_notify_done(indio_dev->trig); | ||
147 | |||
148 | return IRQ_HANDLED; | ||
149 | } | ||
150 | |||
151 | static const struct iio_ring_setup_ops ad7887_ring_setup_ops = { | ||
152 | .preenable = &ad7887_ring_preenable, | ||
153 | .postenable = &iio_triggered_ring_postenable, | ||
154 | .predisable = &iio_triggered_ring_predisable, | ||
155 | .postdisable = &ad7887_ring_postdisable, | ||
156 | }; | ||
157 | |||
158 | int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev) | ||
159 | { | ||
160 | int ret; | ||
161 | |||
162 | indio_dev->ring = iio_sw_rb_allocate(indio_dev); | ||
163 | if (!indio_dev->ring) { | ||
164 | ret = -ENOMEM; | ||
165 | goto error_ret; | ||
166 | } | ||
167 | /* Effectively select the ring buffer implementation */ | ||
168 | indio_dev->ring->access = &ring_sw_access_funcs; | ||
169 | indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time, | ||
170 | &ad7887_trigger_handler, | ||
171 | IRQF_ONESHOT, | ||
172 | indio_dev, | ||
173 | "ad7887_consumer%d", | ||
174 | indio_dev->id); | ||
175 | if (indio_dev->pollfunc == NULL) { | ||
176 | ret = -ENOMEM; | ||
177 | goto error_deallocate_sw_rb; | ||
178 | } | ||
179 | /* Ring buffer functions - here trigger setup related */ | ||
180 | indio_dev->ring->setup_ops = &ad7887_ring_setup_ops; | ||
181 | |||
182 | /* Flag that polled ring buffering is possible */ | ||
183 | indio_dev->modes |= INDIO_RING_TRIGGERED; | ||
184 | return 0; | ||
185 | |||
186 | error_deallocate_sw_rb: | ||
187 | iio_sw_rb_free(indio_dev->ring); | ||
188 | error_ret: | ||
189 | return ret; | ||
190 | } | ||
191 | |||
192 | void ad7887_ring_cleanup(struct iio_dev *indio_dev) | ||
193 | { | ||
194 | /* ensure that the trigger has been detached */ | ||
195 | if (indio_dev->trig) { | ||
196 | iio_put_trigger(indio_dev->trig); | ||
197 | iio_trigger_dettach_poll_func(indio_dev->trig, | ||
198 | indio_dev->pollfunc); | ||
199 | } | ||
200 | iio_dealloc_pollfunc(indio_dev->pollfunc); | ||
201 | iio_sw_rb_free(indio_dev->ring); | ||
202 | } | ||
diff --git a/drivers/staging/iio/adc/adc.h b/drivers/staging/iio/adc/adc.h new file mode 100644 index 00000000000..40c5949880b --- /dev/null +++ b/drivers/staging/iio/adc/adc.h | |||
@@ -0,0 +1,42 @@ | |||
1 | /* | ||
2 | * adc.h - sysfs attributes associated with ADCs | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms of the GNU General Public License version 2 as published by | ||
6 | * the Free Software Foundation. | ||
7 | * | ||
8 | * Copyright (c) 2008 Jonathan Cameron <jic23@cam.ac.uk> | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | /* Deprecated */ | ||
13 | #define IIO_DEV_ATTR_ADC(_num, _show, _addr) \ | ||
14 | IIO_DEVICE_ATTR(adc_##_num, S_IRUGO, _show, NULL, _addr) | ||
15 | |||
16 | #define IIO_DEV_ATTR_IN_RAW(_num, _show, _addr) \ | ||
17 | IIO_DEVICE_ATTR(in##_num##_raw, S_IRUGO, _show, NULL, _addr) | ||
18 | |||
19 | #define IIO_DEV_ATTR_IN_NAMED_RAW(_num, _name, _show, _addr) \ | ||
20 | IIO_DEVICE_ATTR(in##_num##_##_name##_raw, S_IRUGO, _show, NULL, _addr) | ||
21 | |||
22 | #define IIO_DEV_ATTR_IN_DIFF_RAW(_nump, _numn, _show, _addr) \ | ||
23 | IIO_DEVICE_ATTR_NAMED(in##_nump##min##_numn##_raw, \ | ||
24 | in##_nump-in##_numn##_raw, \ | ||
25 | S_IRUGO, \ | ||
26 | _show, \ | ||
27 | NULL, \ | ||
28 | _addr) | ||
29 | |||
30 | |||
31 | #define IIO_CONST_ATTR_IN_NAMED_OFFSET(_num, _name, _string) \ | ||
32 | IIO_CONST_ATTR(in##_num##_##_name##_offset, _string) | ||
33 | |||
34 | #define IIO_CONST_ATTR_IN_NAMED_SCALE(_num, _name, _string) \ | ||
35 | IIO_CONST_ATTR(in##_num##_##_name##_scale, _string) | ||
36 | |||
37 | #define IIO_EVENT_CODE_IN_HIGH_THRESH(a) \ | ||
38 | IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_IN, a, IIO_EV_TYPE_THRESH, \ | ||
39 | IIO_EV_DIR_RISING) | ||
40 | #define IIO_EVENT_CODE_IN_LOW_THRESH(a) \ | ||
41 | IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_IN, a, IIO_EV_TYPE_THRESH, \ | ||
42 | IIO_EV_DIR_FALLING) | ||
diff --git a/drivers/staging/iio/adc/adt7310.c b/drivers/staging/iio/adc/adt7310.c new file mode 100644 index 00000000000..1a41b803440 --- /dev/null +++ b/drivers/staging/iio/adc/adt7310.c | |||
@@ -0,0 +1,904 @@ | |||
1 | /* | ||
2 | * ADT7310 digital temperature sensor driver supporting ADT7310 | ||
3 | * | ||
4 | * Copyright 2010 Analog Devices Inc. | ||
5 | * | ||
6 | * Licensed under the GPL-2 or later. | ||
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/list.h> | ||
15 | #include <linux/spi/spi.h> | ||
16 | |||
17 | #include "../iio.h" | ||
18 | #include "../sysfs.h" | ||
19 | |||
20 | /* | ||
21 | * ADT7310 registers definition | ||
22 | */ | ||
23 | |||
24 | #define ADT7310_STATUS 0 | ||
25 | #define ADT7310_CONFIG 1 | ||
26 | #define ADT7310_TEMPERATURE 2 | ||
27 | #define ADT7310_ID 3 | ||
28 | #define ADT7310_T_CRIT 4 | ||
29 | #define ADT7310_T_HYST 5 | ||
30 | #define ADT7310_T_ALARM_HIGH 6 | ||
31 | #define ADT7310_T_ALARM_LOW 7 | ||
32 | |||
33 | /* | ||
34 | * ADT7310 status | ||
35 | */ | ||
36 | #define ADT7310_STAT_T_LOW 0x10 | ||
37 | #define ADT7310_STAT_T_HIGH 0x20 | ||
38 | #define ADT7310_STAT_T_CRIT 0x40 | ||
39 | #define ADT7310_STAT_NOT_RDY 0x80 | ||
40 | |||
41 | /* | ||
42 | * ADT7310 config | ||
43 | */ | ||
44 | #define ADT7310_FAULT_QUEUE_MASK 0x3 | ||
45 | #define ADT7310_CT_POLARITY 0x4 | ||
46 | #define ADT7310_INT_POLARITY 0x8 | ||
47 | #define ADT7310_EVENT_MODE 0x10 | ||
48 | #define ADT7310_MODE_MASK 0x60 | ||
49 | #define ADT7310_ONESHOT 0x20 | ||
50 | #define ADT7310_SPS 0x40 | ||
51 | #define ADT7310_PD 0x60 | ||
52 | #define ADT7310_RESOLUTION 0x80 | ||
53 | |||
54 | /* | ||
55 | * ADT7310 masks | ||
56 | */ | ||
57 | #define ADT7310_T16_VALUE_SIGN 0x8000 | ||
58 | #define ADT7310_T16_VALUE_FLOAT_OFFSET 7 | ||
59 | #define ADT7310_T16_VALUE_FLOAT_MASK 0x7F | ||
60 | #define ADT7310_T13_VALUE_SIGN 0x1000 | ||
61 | #define ADT7310_T13_VALUE_OFFSET 3 | ||
62 | #define ADT7310_T13_VALUE_FLOAT_OFFSET 4 | ||
63 | #define ADT7310_T13_VALUE_FLOAT_MASK 0xF | ||
64 | #define ADT7310_T_HYST_MASK 0xF | ||
65 | #define ADT7310_DEVICE_ID_MASK 0x7 | ||
66 | #define ADT7310_MANUFACTORY_ID_MASK 0xF8 | ||
67 | #define ADT7310_MANUFACTORY_ID_OFFSET 3 | ||
68 | |||
69 | |||
70 | #define ADT7310_CMD_REG_MASK 0x28 | ||
71 | #define ADT7310_CMD_REG_OFFSET 3 | ||
72 | #define ADT7310_CMD_READ 0x40 | ||
73 | #define ADT7310_CMD_CON_READ 0x4 | ||
74 | |||
75 | #define ADT7310_IRQS 2 | ||
76 | |||
77 | /* | ||
78 | * struct adt7310_chip_info - chip specifc information | ||
79 | */ | ||
80 | |||
81 | struct adt7310_chip_info { | ||
82 | struct spi_device *spi_dev; | ||
83 | u8 config; | ||
84 | }; | ||
85 | |||
86 | /* | ||
87 | * adt7310 register access by SPI | ||
88 | */ | ||
89 | |||
90 | static int adt7310_spi_read_word(struct adt7310_chip_info *chip, u8 reg, u16 *data) | ||
91 | { | ||
92 | struct spi_device *spi_dev = chip->spi_dev; | ||
93 | u8 command = (reg << ADT7310_CMD_REG_OFFSET) & ADT7310_CMD_REG_MASK; | ||
94 | int ret = 0; | ||
95 | |||
96 | command |= ADT7310_CMD_READ; | ||
97 | ret = spi_write(spi_dev, &command, sizeof(command)); | ||
98 | if (ret < 0) { | ||
99 | dev_err(&spi_dev->dev, "SPI write command error\n"); | ||
100 | return ret; | ||
101 | } | ||
102 | |||
103 | ret = spi_read(spi_dev, (u8 *)data, sizeof(*data)); | ||
104 | if (ret < 0) { | ||
105 | dev_err(&spi_dev->dev, "SPI read word error\n"); | ||
106 | return ret; | ||
107 | } | ||
108 | |||
109 | *data = be16_to_cpu(*data); | ||
110 | |||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | static int adt7310_spi_write_word(struct adt7310_chip_info *chip, u8 reg, u16 data) | ||
115 | { | ||
116 | struct spi_device *spi_dev = chip->spi_dev; | ||
117 | u8 buf[3]; | ||
118 | int ret = 0; | ||
119 | |||
120 | buf[0] = (reg << ADT7310_CMD_REG_OFFSET) & ADT7310_CMD_REG_MASK; | ||
121 | buf[1] = (u8)(data >> 8); | ||
122 | buf[2] = (u8)(data & 0xFF); | ||
123 | |||
124 | ret = spi_write(spi_dev, buf, 3); | ||
125 | if (ret < 0) { | ||
126 | dev_err(&spi_dev->dev, "SPI write word error\n"); | ||
127 | return ret; | ||
128 | } | ||
129 | |||
130 | return ret; | ||
131 | } | ||
132 | |||
133 | static int adt7310_spi_read_byte(struct adt7310_chip_info *chip, u8 reg, u8 *data) | ||
134 | { | ||
135 | struct spi_device *spi_dev = chip->spi_dev; | ||
136 | u8 command = (reg << ADT7310_CMD_REG_OFFSET) & ADT7310_CMD_REG_MASK; | ||
137 | int ret = 0; | ||
138 | |||
139 | command |= ADT7310_CMD_READ; | ||
140 | ret = spi_write(spi_dev, &command, sizeof(command)); | ||
141 | if (ret < 0) { | ||
142 | dev_err(&spi_dev->dev, "SPI write command error\n"); | ||
143 | return ret; | ||
144 | } | ||
145 | |||
146 | ret = spi_read(spi_dev, data, sizeof(*data)); | ||
147 | if (ret < 0) { | ||
148 | dev_err(&spi_dev->dev, "SPI read byte error\n"); | ||
149 | return ret; | ||
150 | } | ||
151 | |||
152 | return 0; | ||
153 | } | ||
154 | |||
155 | static int adt7310_spi_write_byte(struct adt7310_chip_info *chip, u8 reg, u8 data) | ||
156 | { | ||
157 | struct spi_device *spi_dev = chip->spi_dev; | ||
158 | u8 buf[2]; | ||
159 | int ret = 0; | ||
160 | |||
161 | buf[0] = (reg << ADT7310_CMD_REG_OFFSET) & ADT7310_CMD_REG_MASK; | ||
162 | buf[1] = data; | ||
163 | |||
164 | ret = spi_write(spi_dev, buf, 2); | ||
165 | if (ret < 0) { | ||
166 | dev_err(&spi_dev->dev, "SPI write byte error\n"); | ||
167 | return ret; | ||
168 | } | ||
169 | |||
170 | return ret; | ||
171 | } | ||
172 | |||
173 | static ssize_t adt7310_show_mode(struct device *dev, | ||
174 | struct device_attribute *attr, | ||
175 | char *buf) | ||
176 | { | ||
177 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
178 | struct adt7310_chip_info *chip = iio_priv(dev_info); | ||
179 | u8 config; | ||
180 | |||
181 | config = chip->config & ADT7310_MODE_MASK; | ||
182 | |||
183 | switch (config) { | ||
184 | case ADT7310_PD: | ||
185 | return sprintf(buf, "power-down\n"); | ||
186 | case ADT7310_ONESHOT: | ||
187 | return sprintf(buf, "one-shot\n"); | ||
188 | case ADT7310_SPS: | ||
189 | return sprintf(buf, "sps\n"); | ||
190 | default: | ||
191 | return sprintf(buf, "full\n"); | ||
192 | } | ||
193 | } | ||
194 | |||
195 | static ssize_t adt7310_store_mode(struct device *dev, | ||
196 | struct device_attribute *attr, | ||
197 | const char *buf, | ||
198 | size_t len) | ||
199 | { | ||
200 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
201 | struct adt7310_chip_info *chip = iio_priv(dev_info); | ||
202 | u16 config; | ||
203 | int ret; | ||
204 | |||
205 | ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config); | ||
206 | if (ret) | ||
207 | return -EIO; | ||
208 | |||
209 | config = chip->config & (~ADT7310_MODE_MASK); | ||
210 | if (strcmp(buf, "power-down")) | ||
211 | config |= ADT7310_PD; | ||
212 | else if (strcmp(buf, "one-shot")) | ||
213 | config |= ADT7310_ONESHOT; | ||
214 | else if (strcmp(buf, "sps")) | ||
215 | config |= ADT7310_SPS; | ||
216 | |||
217 | ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, config); | ||
218 | if (ret) | ||
219 | return -EIO; | ||
220 | |||
221 | chip->config = config; | ||
222 | |||
223 | return len; | ||
224 | } | ||
225 | |||
226 | static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, | ||
227 | adt7310_show_mode, | ||
228 | adt7310_store_mode, | ||
229 | 0); | ||
230 | |||
231 | static ssize_t adt7310_show_available_modes(struct device *dev, | ||
232 | struct device_attribute *attr, | ||
233 | char *buf) | ||
234 | { | ||
235 | return sprintf(buf, "full\none-shot\nsps\npower-down\n"); | ||
236 | } | ||
237 | |||
238 | static IIO_DEVICE_ATTR(available_modes, S_IRUGO, adt7310_show_available_modes, NULL, 0); | ||
239 | |||
240 | static ssize_t adt7310_show_resolution(struct device *dev, | ||
241 | struct device_attribute *attr, | ||
242 | char *buf) | ||
243 | { | ||
244 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
245 | struct adt7310_chip_info *chip = iio_priv(dev_info); | ||
246 | int ret; | ||
247 | int bits; | ||
248 | |||
249 | ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config); | ||
250 | if (ret) | ||
251 | return -EIO; | ||
252 | |||
253 | if (chip->config & ADT7310_RESOLUTION) | ||
254 | bits = 16; | ||
255 | else | ||
256 | bits = 13; | ||
257 | |||
258 | return sprintf(buf, "%d bits\n", bits); | ||
259 | } | ||
260 | |||
261 | static ssize_t adt7310_store_resolution(struct device *dev, | ||
262 | struct device_attribute *attr, | ||
263 | const char *buf, | ||
264 | size_t len) | ||
265 | { | ||
266 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
267 | struct adt7310_chip_info *chip = iio_priv(dev_info); | ||
268 | unsigned long data; | ||
269 | u16 config; | ||
270 | int ret; | ||
271 | |||
272 | ret = strict_strtoul(buf, 10, &data); | ||
273 | if (ret) | ||
274 | return -EINVAL; | ||
275 | |||
276 | ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config); | ||
277 | if (ret) | ||
278 | return -EIO; | ||
279 | |||
280 | config = chip->config & (~ADT7310_RESOLUTION); | ||
281 | if (data) | ||
282 | config |= ADT7310_RESOLUTION; | ||
283 | |||
284 | ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, config); | ||
285 | if (ret) | ||
286 | return -EIO; | ||
287 | |||
288 | chip->config = config; | ||
289 | |||
290 | return len; | ||
291 | } | ||
292 | |||
293 | static IIO_DEVICE_ATTR(resolution, S_IRUGO | S_IWUSR, | ||
294 | adt7310_show_resolution, | ||
295 | adt7310_store_resolution, | ||
296 | 0); | ||
297 | |||
298 | static ssize_t adt7310_show_id(struct device *dev, | ||
299 | struct device_attribute *attr, | ||
300 | char *buf) | ||
301 | { | ||
302 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
303 | struct adt7310_chip_info *chip = iio_priv(dev_info); | ||
304 | u8 id; | ||
305 | int ret; | ||
306 | |||
307 | ret = adt7310_spi_read_byte(chip, ADT7310_ID, &id); | ||
308 | if (ret) | ||
309 | return -EIO; | ||
310 | |||
311 | return sprintf(buf, "device id: 0x%x\nmanufactory id: 0x%x\n", | ||
312 | id & ADT7310_DEVICE_ID_MASK, | ||
313 | (id & ADT7310_MANUFACTORY_ID_MASK) >> ADT7310_MANUFACTORY_ID_OFFSET); | ||
314 | } | ||
315 | |||
316 | static IIO_DEVICE_ATTR(id, S_IRUGO | S_IWUSR, | ||
317 | adt7310_show_id, | ||
318 | NULL, | ||
319 | 0); | ||
320 | |||
321 | static ssize_t adt7310_convert_temperature(struct adt7310_chip_info *chip, | ||
322 | u16 data, char *buf) | ||
323 | { | ||
324 | char sign = ' '; | ||
325 | |||
326 | if (chip->config & ADT7310_RESOLUTION) { | ||
327 | if (data & ADT7310_T16_VALUE_SIGN) { | ||
328 | /* convert supplement to positive value */ | ||
329 | data = (u16)((ADT7310_T16_VALUE_SIGN << 1) - (u32)data); | ||
330 | sign = '-'; | ||
331 | } | ||
332 | return sprintf(buf, "%c%d.%.7d\n", sign, | ||
333 | (data >> ADT7310_T16_VALUE_FLOAT_OFFSET), | ||
334 | (data & ADT7310_T16_VALUE_FLOAT_MASK) * 78125); | ||
335 | } else { | ||
336 | if (data & ADT7310_T13_VALUE_SIGN) { | ||
337 | /* convert supplement to positive value */ | ||
338 | data >>= ADT7310_T13_VALUE_OFFSET; | ||
339 | data = (ADT7310_T13_VALUE_SIGN << 1) - data; | ||
340 | sign = '-'; | ||
341 | } | ||
342 | return sprintf(buf, "%c%d.%.4d\n", sign, | ||
343 | (data >> ADT7310_T13_VALUE_FLOAT_OFFSET), | ||
344 | (data & ADT7310_T13_VALUE_FLOAT_MASK) * 625); | ||
345 | } | ||
346 | } | ||
347 | |||
348 | static ssize_t adt7310_show_value(struct device *dev, | ||
349 | struct device_attribute *attr, | ||
350 | char *buf) | ||
351 | { | ||
352 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
353 | struct adt7310_chip_info *chip = iio_priv(dev_info); | ||
354 | u8 status; | ||
355 | u16 data; | ||
356 | int ret, i = 0; | ||
357 | |||
358 | do { | ||
359 | ret = adt7310_spi_read_byte(chip, ADT7310_STATUS, &status); | ||
360 | if (ret) | ||
361 | return -EIO; | ||
362 | i++; | ||
363 | if (i == 10000) | ||
364 | return -EIO; | ||
365 | } while (status & ADT7310_STAT_NOT_RDY); | ||
366 | |||
367 | ret = adt7310_spi_read_word(chip, ADT7310_TEMPERATURE, &data); | ||
368 | if (ret) | ||
369 | return -EIO; | ||
370 | |||
371 | return adt7310_convert_temperature(chip, data, buf); | ||
372 | } | ||
373 | |||
374 | static IIO_DEVICE_ATTR(value, S_IRUGO, adt7310_show_value, NULL, 0); | ||
375 | |||
376 | static struct attribute *adt7310_attributes[] = { | ||
377 | &iio_dev_attr_available_modes.dev_attr.attr, | ||
378 | &iio_dev_attr_mode.dev_attr.attr, | ||
379 | &iio_dev_attr_resolution.dev_attr.attr, | ||
380 | &iio_dev_attr_id.dev_attr.attr, | ||
381 | &iio_dev_attr_value.dev_attr.attr, | ||
382 | NULL, | ||
383 | }; | ||
384 | |||
385 | static const struct attribute_group adt7310_attribute_group = { | ||
386 | .attrs = adt7310_attributes, | ||
387 | }; | ||
388 | |||
389 | static irqreturn_t adt7310_event_handler(int irq, void *private) | ||
390 | { | ||
391 | struct iio_dev *indio_dev = private; | ||
392 | struct adt7310_chip_info *chip = iio_priv(indio_dev); | ||
393 | s64 timestamp = iio_get_time_ns(); | ||
394 | u8 status; | ||
395 | int ret; | ||
396 | |||
397 | ret = adt7310_spi_read_byte(chip, ADT7310_STATUS, &status); | ||
398 | if (ret) | ||
399 | return ret; | ||
400 | |||
401 | if (status & ADT7310_STAT_T_HIGH) | ||
402 | iio_push_event(indio_dev, 0, | ||
403 | IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0, | ||
404 | IIO_EV_TYPE_THRESH, | ||
405 | IIO_EV_DIR_RISING), | ||
406 | timestamp); | ||
407 | if (status & ADT7310_STAT_T_LOW) | ||
408 | iio_push_event(indio_dev, 0, | ||
409 | IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0, | ||
410 | IIO_EV_TYPE_THRESH, | ||
411 | IIO_EV_DIR_FALLING), | ||
412 | timestamp); | ||
413 | if (status & ADT7310_STAT_T_CRIT) | ||
414 | iio_push_event(indio_dev, 0, | ||
415 | IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0, | ||
416 | IIO_EV_TYPE_THRESH, | ||
417 | IIO_EV_DIR_RISING), | ||
418 | timestamp); | ||
419 | return IRQ_HANDLED; | ||
420 | } | ||
421 | |||
422 | static ssize_t adt7310_show_event_mode(struct device *dev, | ||
423 | struct device_attribute *attr, | ||
424 | char *buf) | ||
425 | { | ||
426 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
427 | struct adt7310_chip_info *chip = iio_priv(dev_info); | ||
428 | int ret; | ||
429 | |||
430 | ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config); | ||
431 | if (ret) | ||
432 | return -EIO; | ||
433 | |||
434 | if (chip->config & ADT7310_EVENT_MODE) | ||
435 | return sprintf(buf, "interrupt\n"); | ||
436 | else | ||
437 | return sprintf(buf, "comparator\n"); | ||
438 | } | ||
439 | |||
440 | static ssize_t adt7310_set_event_mode(struct device *dev, | ||
441 | struct device_attribute *attr, | ||
442 | const char *buf, | ||
443 | size_t len) | ||
444 | { | ||
445 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
446 | struct adt7310_chip_info *chip = iio_priv(dev_info); | ||
447 | u16 config; | ||
448 | int ret; | ||
449 | |||
450 | ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config); | ||
451 | if (ret) | ||
452 | return -EIO; | ||
453 | |||
454 | config = chip->config &= ~ADT7310_EVENT_MODE; | ||
455 | if (strcmp(buf, "comparator") != 0) | ||
456 | config |= ADT7310_EVENT_MODE; | ||
457 | |||
458 | ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, config); | ||
459 | if (ret) | ||
460 | return -EIO; | ||
461 | |||
462 | chip->config = config; | ||
463 | |||
464 | return len; | ||
465 | } | ||
466 | |||
467 | static ssize_t adt7310_show_available_event_modes(struct device *dev, | ||
468 | struct device_attribute *attr, | ||
469 | char *buf) | ||
470 | { | ||
471 | return sprintf(buf, "comparator\ninterrupt\n"); | ||
472 | } | ||
473 | |||
474 | static ssize_t adt7310_show_fault_queue(struct device *dev, | ||
475 | struct device_attribute *attr, | ||
476 | char *buf) | ||
477 | { | ||
478 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
479 | struct adt7310_chip_info *chip = iio_priv(dev_info); | ||
480 | int ret; | ||
481 | |||
482 | ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config); | ||
483 | if (ret) | ||
484 | return -EIO; | ||
485 | |||
486 | return sprintf(buf, "%d\n", chip->config & ADT7310_FAULT_QUEUE_MASK); | ||
487 | } | ||
488 | |||
489 | static ssize_t adt7310_set_fault_queue(struct device *dev, | ||
490 | struct device_attribute *attr, | ||
491 | const char *buf, | ||
492 | size_t len) | ||
493 | { | ||
494 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
495 | struct adt7310_chip_info *chip = iio_priv(dev_info); | ||
496 | unsigned long data; | ||
497 | int ret; | ||
498 | u8 config; | ||
499 | |||
500 | ret = strict_strtoul(buf, 10, &data); | ||
501 | if (ret || data > 3) | ||
502 | return -EINVAL; | ||
503 | |||
504 | ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config); | ||
505 | if (ret) | ||
506 | return -EIO; | ||
507 | |||
508 | config = chip->config & ~ADT7310_FAULT_QUEUE_MASK; | ||
509 | config |= data; | ||
510 | ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, config); | ||
511 | if (ret) | ||
512 | return -EIO; | ||
513 | |||
514 | chip->config = config; | ||
515 | |||
516 | return len; | ||
517 | } | ||
518 | |||
519 | static inline ssize_t adt7310_show_t_bound(struct device *dev, | ||
520 | struct device_attribute *attr, | ||
521 | u8 bound_reg, | ||
522 | char *buf) | ||
523 | { | ||
524 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
525 | struct adt7310_chip_info *chip = iio_priv(dev_info); | ||
526 | u16 data; | ||
527 | int ret; | ||
528 | |||
529 | ret = adt7310_spi_read_word(chip, bound_reg, &data); | ||
530 | if (ret) | ||
531 | return -EIO; | ||
532 | |||
533 | return adt7310_convert_temperature(chip, data, buf); | ||
534 | } | ||
535 | |||
536 | static inline ssize_t adt7310_set_t_bound(struct device *dev, | ||
537 | struct device_attribute *attr, | ||
538 | u8 bound_reg, | ||
539 | const char *buf, | ||
540 | size_t len) | ||
541 | { | ||
542 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
543 | struct adt7310_chip_info *chip = iio_priv(dev_info); | ||
544 | long tmp1, tmp2; | ||
545 | u16 data; | ||
546 | char *pos; | ||
547 | int ret; | ||
548 | |||
549 | pos = strchr(buf, '.'); | ||
550 | |||
551 | ret = strict_strtol(buf, 10, &tmp1); | ||
552 | |||
553 | if (ret || tmp1 > 127 || tmp1 < -128) | ||
554 | return -EINVAL; | ||
555 | |||
556 | if (pos) { | ||
557 | len = strlen(pos); | ||
558 | |||
559 | if (chip->config & ADT7310_RESOLUTION) { | ||
560 | if (len > ADT7310_T16_VALUE_FLOAT_OFFSET) | ||
561 | len = ADT7310_T16_VALUE_FLOAT_OFFSET; | ||
562 | pos[len] = 0; | ||
563 | ret = strict_strtol(pos, 10, &tmp2); | ||
564 | |||
565 | if (!ret) | ||
566 | tmp2 = (tmp2 / 78125) * 78125; | ||
567 | } else { | ||
568 | if (len > ADT7310_T13_VALUE_FLOAT_OFFSET) | ||
569 | len = ADT7310_T13_VALUE_FLOAT_OFFSET; | ||
570 | pos[len] = 0; | ||
571 | ret = strict_strtol(pos, 10, &tmp2); | ||
572 | |||
573 | if (!ret) | ||
574 | tmp2 = (tmp2 / 625) * 625; | ||
575 | } | ||
576 | } | ||
577 | |||
578 | if (tmp1 < 0) | ||
579 | data = (u16)(-tmp1); | ||
580 | else | ||
581 | data = (u16)tmp1; | ||
582 | |||
583 | if (chip->config & ADT7310_RESOLUTION) { | ||
584 | data = (data << ADT7310_T16_VALUE_FLOAT_OFFSET) | | ||
585 | (tmp2 & ADT7310_T16_VALUE_FLOAT_MASK); | ||
586 | |||
587 | if (tmp1 < 0) | ||
588 | /* convert positive value to supplyment */ | ||
589 | data = (u16)((ADT7310_T16_VALUE_SIGN << 1) - (u32)data); | ||
590 | } else { | ||
591 | data = (data << ADT7310_T13_VALUE_FLOAT_OFFSET) | | ||
592 | (tmp2 & ADT7310_T13_VALUE_FLOAT_MASK); | ||
593 | |||
594 | if (tmp1 < 0) | ||
595 | /* convert positive value to supplyment */ | ||
596 | data = (ADT7310_T13_VALUE_SIGN << 1) - data; | ||
597 | data <<= ADT7310_T13_VALUE_OFFSET; | ||
598 | } | ||
599 | |||
600 | ret = adt7310_spi_write_word(chip, bound_reg, data); | ||
601 | if (ret) | ||
602 | return -EIO; | ||
603 | |||
604 | return len; | ||
605 | } | ||
606 | |||
607 | static ssize_t adt7310_show_t_alarm_high(struct device *dev, | ||
608 | struct device_attribute *attr, | ||
609 | char *buf) | ||
610 | { | ||
611 | return adt7310_show_t_bound(dev, attr, | ||
612 | ADT7310_T_ALARM_HIGH, buf); | ||
613 | } | ||
614 | |||
615 | static inline ssize_t adt7310_set_t_alarm_high(struct device *dev, | ||
616 | struct device_attribute *attr, | ||
617 | const char *buf, | ||
618 | size_t len) | ||
619 | { | ||
620 | return adt7310_set_t_bound(dev, attr, | ||
621 | ADT7310_T_ALARM_HIGH, buf, len); | ||
622 | } | ||
623 | |||
624 | static ssize_t adt7310_show_t_alarm_low(struct device *dev, | ||
625 | struct device_attribute *attr, | ||
626 | char *buf) | ||
627 | { | ||
628 | return adt7310_show_t_bound(dev, attr, | ||
629 | ADT7310_T_ALARM_LOW, buf); | ||
630 | } | ||
631 | |||
632 | static inline ssize_t adt7310_set_t_alarm_low(struct device *dev, | ||
633 | struct device_attribute *attr, | ||
634 | const char *buf, | ||
635 | size_t len) | ||
636 | { | ||
637 | return adt7310_set_t_bound(dev, attr, | ||
638 | ADT7310_T_ALARM_LOW, buf, len); | ||
639 | } | ||
640 | |||
641 | static ssize_t adt7310_show_t_crit(struct device *dev, | ||
642 | struct device_attribute *attr, | ||
643 | char *buf) | ||
644 | { | ||
645 | return adt7310_show_t_bound(dev, attr, | ||
646 | ADT7310_T_CRIT, buf); | ||
647 | } | ||
648 | |||
649 | static inline ssize_t adt7310_set_t_crit(struct device *dev, | ||
650 | struct device_attribute *attr, | ||
651 | const char *buf, | ||
652 | size_t len) | ||
653 | { | ||
654 | return adt7310_set_t_bound(dev, attr, | ||
655 | ADT7310_T_CRIT, buf, len); | ||
656 | } | ||
657 | |||
658 | static ssize_t adt7310_show_t_hyst(struct device *dev, | ||
659 | struct device_attribute *attr, | ||
660 | char *buf) | ||
661 | { | ||
662 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
663 | struct adt7310_chip_info *chip = iio_priv(dev_info); | ||
664 | int ret; | ||
665 | u8 t_hyst; | ||
666 | |||
667 | ret = adt7310_spi_read_byte(chip, ADT7310_T_HYST, &t_hyst); | ||
668 | if (ret) | ||
669 | return -EIO; | ||
670 | |||
671 | return sprintf(buf, "%d\n", t_hyst & ADT7310_T_HYST_MASK); | ||
672 | } | ||
673 | |||
674 | static inline ssize_t adt7310_set_t_hyst(struct device *dev, | ||
675 | struct device_attribute *attr, | ||
676 | const char *buf, | ||
677 | size_t len) | ||
678 | { | ||
679 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
680 | struct adt7310_chip_info *chip = iio_priv(dev_info); | ||
681 | int ret; | ||
682 | unsigned long data; | ||
683 | u8 t_hyst; | ||
684 | |||
685 | ret = strict_strtol(buf, 10, &data); | ||
686 | |||
687 | if (ret || data > ADT7310_T_HYST_MASK) | ||
688 | return -EINVAL; | ||
689 | |||
690 | t_hyst = (u8)data; | ||
691 | |||
692 | ret = adt7310_spi_write_byte(chip, ADT7310_T_HYST, t_hyst); | ||
693 | if (ret) | ||
694 | return -EIO; | ||
695 | |||
696 | return len; | ||
697 | } | ||
698 | |||
699 | static IIO_DEVICE_ATTR(event_mode, | ||
700 | S_IRUGO | S_IWUSR, | ||
701 | adt7310_show_event_mode, adt7310_set_event_mode, 0); | ||
702 | static IIO_DEVICE_ATTR(available_event_modes, | ||
703 | S_IRUGO | S_IWUSR, | ||
704 | adt7310_show_available_event_modes, NULL, 0); | ||
705 | static IIO_DEVICE_ATTR(fault_queue, | ||
706 | S_IRUGO | S_IWUSR, | ||
707 | adt7310_show_fault_queue, adt7310_set_fault_queue, 0); | ||
708 | static IIO_DEVICE_ATTR(t_alarm_high, | ||
709 | S_IRUGO | S_IWUSR, | ||
710 | adt7310_show_t_alarm_high, adt7310_set_t_alarm_high, 0); | ||
711 | static IIO_DEVICE_ATTR(t_alarm_low, | ||
712 | S_IRUGO | S_IWUSR, | ||
713 | adt7310_show_t_alarm_low, adt7310_set_t_alarm_low, 0); | ||
714 | static IIO_DEVICE_ATTR(t_crit, | ||
715 | S_IRUGO | S_IWUSR, | ||
716 | adt7310_show_t_crit, adt7310_set_t_crit, 0); | ||
717 | static IIO_DEVICE_ATTR(t_hyst, | ||
718 | S_IRUGO | S_IWUSR, | ||
719 | adt7310_show_t_hyst, adt7310_set_t_hyst, 0); | ||
720 | |||
721 | static struct attribute *adt7310_event_int_attributes[] = { | ||
722 | &iio_dev_attr_event_mode.dev_attr.attr, | ||
723 | &iio_dev_attr_available_event_modes.dev_attr.attr, | ||
724 | &iio_dev_attr_fault_queue.dev_attr.attr, | ||
725 | &iio_dev_attr_t_alarm_high.dev_attr.attr, | ||
726 | &iio_dev_attr_t_alarm_low.dev_attr.attr, | ||
727 | &iio_dev_attr_t_hyst.dev_attr.attr, | ||
728 | NULL, | ||
729 | }; | ||
730 | |||
731 | static struct attribute *adt7310_event_ct_attributes[] = { | ||
732 | &iio_dev_attr_event_mode.dev_attr.attr, | ||
733 | &iio_dev_attr_available_event_modes.dev_attr.attr, | ||
734 | &iio_dev_attr_fault_queue.dev_attr.attr, | ||
735 | &iio_dev_attr_t_crit.dev_attr.attr, | ||
736 | &iio_dev_attr_t_hyst.dev_attr.attr, | ||
737 | NULL, | ||
738 | }; | ||
739 | |||
740 | static struct attribute_group adt7310_event_attribute_group[ADT7310_IRQS] = { | ||
741 | { | ||
742 | .attrs = adt7310_event_int_attributes, | ||
743 | }, { | ||
744 | .attrs = adt7310_event_ct_attributes, | ||
745 | } | ||
746 | }; | ||
747 | |||
748 | static const struct iio_info adt7310_info = { | ||
749 | .attrs = &adt7310_attribute_group, | ||
750 | .num_interrupt_lines = ADT7310_IRQS, | ||
751 | .event_attrs = adt7310_event_attribute_group, | ||
752 | .driver_module = THIS_MODULE, | ||
753 | }; | ||
754 | |||
755 | /* | ||
756 | * device probe and remove | ||
757 | */ | ||
758 | |||
759 | static int __devinit adt7310_probe(struct spi_device *spi_dev) | ||
760 | { | ||
761 | struct adt7310_chip_info *chip; | ||
762 | struct iio_dev *indio_dev; | ||
763 | int ret = 0; | ||
764 | unsigned long *adt7310_platform_data = spi_dev->dev.platform_data; | ||
765 | unsigned long irq_flags; | ||
766 | |||
767 | indio_dev = iio_allocate_device(sizeof(*chip)); | ||
768 | if (indio_dev == NULL) { | ||
769 | ret = -ENOMEM; | ||
770 | goto error_ret; | ||
771 | } | ||
772 | chip = iio_priv(indio_dev); | ||
773 | /* this is only used for device removal purposes */ | ||
774 | dev_set_drvdata(&spi_dev->dev, indio_dev); | ||
775 | |||
776 | chip->spi_dev = spi_dev; | ||
777 | |||
778 | indio_dev->dev.parent = &spi_dev->dev; | ||
779 | indio_dev->name = spi_get_device_id(spi_dev)->name; | ||
780 | indio_dev->info = &adt7310_info; | ||
781 | indio_dev->modes = INDIO_DIRECT_MODE; | ||
782 | |||
783 | ret = iio_device_register(indio_dev); | ||
784 | if (ret) | ||
785 | goto error_free_dev; | ||
786 | |||
787 | /* CT critcal temperature event. line 0 */ | ||
788 | if (spi_dev->irq) { | ||
789 | if (adt7310_platform_data[2]) | ||
790 | irq_flags = adt7310_platform_data[2]; | ||
791 | else | ||
792 | irq_flags = IRQF_TRIGGER_LOW; | ||
793 | ret = request_threaded_irq(spi_dev->irq, | ||
794 | NULL, | ||
795 | &adt7310_event_handler, | ||
796 | irq_flags, | ||
797 | indio_dev->name, | ||
798 | indio_dev); | ||
799 | if (ret) | ||
800 | goto error_unreg_dev; | ||
801 | } | ||
802 | |||
803 | /* INT bound temperature alarm event. line 1 */ | ||
804 | if (adt7310_platform_data[0]) { | ||
805 | ret = request_threaded_irq(adt7310_platform_data[0], | ||
806 | NULL, | ||
807 | &adt7310_event_handler, | ||
808 | adt7310_platform_data[1], | ||
809 | indio_dev->name, | ||
810 | indio_dev); | ||
811 | if (ret) | ||
812 | goto error_unreg_ct_irq; | ||
813 | } | ||
814 | |||
815 | if (spi_dev->irq && adt7310_platform_data[0]) { | ||
816 | ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config); | ||
817 | if (ret) { | ||
818 | ret = -EIO; | ||
819 | goto error_unreg_int_irq; | ||
820 | } | ||
821 | |||
822 | /* set irq polarity low level */ | ||
823 | chip->config &= ~ADT7310_CT_POLARITY; | ||
824 | |||
825 | if (adt7310_platform_data[1] & IRQF_TRIGGER_HIGH) | ||
826 | chip->config |= ADT7310_INT_POLARITY; | ||
827 | else | ||
828 | chip->config &= ~ADT7310_INT_POLARITY; | ||
829 | |||
830 | ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, chip->config); | ||
831 | if (ret) { | ||
832 | ret = -EIO; | ||
833 | goto error_unreg_int_irq; | ||
834 | } | ||
835 | } | ||
836 | |||
837 | dev_info(&spi_dev->dev, "%s temperature sensor registered.\n", | ||
838 | indio_dev->name); | ||
839 | |||
840 | return 0; | ||
841 | |||
842 | error_unreg_int_irq: | ||
843 | free_irq(adt7310_platform_data[0], indio_dev); | ||
844 | error_unreg_ct_irq: | ||
845 | free_irq(spi_dev->irq, indio_dev); | ||
846 | error_unreg_dev: | ||
847 | iio_device_unregister(indio_dev); | ||
848 | error_free_dev: | ||
849 | iio_free_device(indio_dev); | ||
850 | error_ret: | ||
851 | return ret; | ||
852 | } | ||
853 | |||
854 | static int __devexit adt7310_remove(struct spi_device *spi_dev) | ||
855 | { | ||
856 | struct iio_dev *indio_dev = dev_get_drvdata(&spi_dev->dev); | ||
857 | unsigned long *adt7310_platform_data = spi_dev->dev.platform_data; | ||
858 | |||
859 | dev_set_drvdata(&spi_dev->dev, NULL); | ||
860 | if (adt7310_platform_data[0]) | ||
861 | free_irq(adt7310_platform_data[0], indio_dev); | ||
862 | if (spi_dev->irq) | ||
863 | free_irq(spi_dev->irq, indio_dev); | ||
864 | iio_device_unregister(indio_dev); | ||
865 | iio_free_device(indio_dev); | ||
866 | |||
867 | return 0; | ||
868 | } | ||
869 | |||
870 | static const struct spi_device_id adt7310_id[] = { | ||
871 | { "adt7310", 0 }, | ||
872 | {} | ||
873 | }; | ||
874 | |||
875 | MODULE_DEVICE_TABLE(spi, adt7310_id); | ||
876 | |||
877 | static struct spi_driver adt7310_driver = { | ||
878 | .driver = { | ||
879 | .name = "adt7310", | ||
880 | .bus = &spi_bus_type, | ||
881 | .owner = THIS_MODULE, | ||
882 | }, | ||
883 | .probe = adt7310_probe, | ||
884 | .remove = __devexit_p(adt7310_remove), | ||
885 | .id_table = adt7310_id, | ||
886 | }; | ||
887 | |||
888 | static __init int adt7310_init(void) | ||
889 | { | ||
890 | return spi_register_driver(&adt7310_driver); | ||
891 | } | ||
892 | |||
893 | static __exit void adt7310_exit(void) | ||
894 | { | ||
895 | spi_unregister_driver(&adt7310_driver); | ||
896 | } | ||
897 | |||
898 | MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>"); | ||
899 | MODULE_DESCRIPTION("Analog Devices ADT7310 digital" | ||
900 | " temperature sensor driver"); | ||
901 | MODULE_LICENSE("GPL v2"); | ||
902 | |||
903 | module_init(adt7310_init); | ||
904 | module_exit(adt7310_exit); | ||
diff --git a/drivers/staging/iio/adc/adt75.c b/drivers/staging/iio/adc/adt75.c new file mode 100644 index 00000000000..38f141de6a4 --- /dev/null +++ b/drivers/staging/iio/adc/adt75.c | |||
@@ -0,0 +1,657 @@ | |||
1 | /* | ||
2 | * ADT75 digital temperature sensor driver supporting ADT75 | ||
3 | * | ||
4 | * Copyright 2010 Analog Devices Inc. | ||
5 | * | ||
6 | * Licensed under the GPL-2 or later. | ||
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/i2c.h> | ||
15 | |||
16 | #include "../iio.h" | ||
17 | #include "../sysfs.h" | ||
18 | |||
19 | /* | ||
20 | * ADT75 registers definition | ||
21 | */ | ||
22 | |||
23 | #define ADT75_TEMPERATURE 0 | ||
24 | #define ADT75_CONFIG 1 | ||
25 | #define ADT75_T_HYST 2 | ||
26 | #define ADT75_T_OS 3 | ||
27 | #define ADT75_ONESHOT 4 | ||
28 | |||
29 | /* | ||
30 | * ADT75 config | ||
31 | */ | ||
32 | #define ADT75_PD 0x1 | ||
33 | #define ADT75_OS_INT 0x2 | ||
34 | #define ADT75_OS_POLARITY 0x4 | ||
35 | #define ADT75_FAULT_QUEUE_MASK 0x18 | ||
36 | #define ADT75_FAULT_QUEUE_OFFSET 3 | ||
37 | #define ADT75_SMBUS_ALART 0x8 | ||
38 | |||
39 | /* | ||
40 | * ADT75 masks | ||
41 | */ | ||
42 | #define ADT75_VALUE_SIGN 0x800 | ||
43 | #define ADT75_VALUE_OFFSET 4 | ||
44 | #define ADT75_VALUE_FLOAT_OFFSET 4 | ||
45 | #define ADT75_VALUE_FLOAT_MASK 0xF | ||
46 | |||
47 | |||
48 | /* | ||
49 | * struct adt75_chip_info - chip specifc information | ||
50 | */ | ||
51 | |||
52 | struct adt75_chip_info { | ||
53 | struct i2c_client *client; | ||
54 | u8 config; | ||
55 | }; | ||
56 | |||
57 | /* | ||
58 | * adt75 register access by I2C | ||
59 | */ | ||
60 | |||
61 | static int adt75_i2c_read(struct iio_dev *dev_info, u8 reg, u8 *data) | ||
62 | { | ||
63 | struct adt75_chip_info *chip = iio_priv(dev_info); | ||
64 | struct i2c_client *client = chip->client; | ||
65 | int ret = 0, len; | ||
66 | |||
67 | ret = i2c_smbus_write_byte(client, reg); | ||
68 | if (ret < 0) { | ||
69 | dev_err(&client->dev, "I2C read register address error\n"); | ||
70 | return ret; | ||
71 | } | ||
72 | |||
73 | if (reg == ADT75_CONFIG || reg == ADT75_ONESHOT) | ||
74 | len = 1; | ||
75 | else | ||
76 | len = 2; | ||
77 | |||
78 | ret = i2c_master_recv(client, data, len); | ||
79 | if (ret < 0) { | ||
80 | dev_err(&client->dev, "I2C read error\n"); | ||
81 | return ret; | ||
82 | } | ||
83 | |||
84 | return ret; | ||
85 | } | ||
86 | |||
87 | static int adt75_i2c_write(struct iio_dev *dev_info, u8 reg, u8 data) | ||
88 | { | ||
89 | struct adt75_chip_info *chip = iio_priv(dev_info); | ||
90 | struct i2c_client *client = chip->client; | ||
91 | int ret = 0; | ||
92 | |||
93 | if (reg == ADT75_CONFIG || reg == ADT75_ONESHOT) | ||
94 | ret = i2c_smbus_write_byte_data(client, reg, data); | ||
95 | else | ||
96 | ret = i2c_smbus_write_word_data(client, reg, data); | ||
97 | |||
98 | if (ret < 0) | ||
99 | dev_err(&client->dev, "I2C write error\n"); | ||
100 | |||
101 | return ret; | ||
102 | } | ||
103 | |||
104 | static ssize_t adt75_show_mode(struct device *dev, | ||
105 | struct device_attribute *attr, | ||
106 | char *buf) | ||
107 | { | ||
108 | struct adt75_chip_info *chip = iio_priv(dev_get_drvdata(dev)); | ||
109 | |||
110 | if (chip->config & ADT75_PD) | ||
111 | return sprintf(buf, "power-save\n"); | ||
112 | else | ||
113 | return sprintf(buf, "full\n"); | ||
114 | } | ||
115 | |||
116 | static ssize_t adt75_store_mode(struct device *dev, | ||
117 | struct device_attribute *attr, | ||
118 | const char *buf, | ||
119 | size_t len) | ||
120 | { | ||
121 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
122 | struct adt75_chip_info *chip = iio_priv(dev_info); | ||
123 | int ret; | ||
124 | u8 config; | ||
125 | |||
126 | ret = adt75_i2c_read(dev_info, ADT75_CONFIG, &chip->config); | ||
127 | if (ret) | ||
128 | return -EIO; | ||
129 | |||
130 | config = chip->config & ~ADT75_PD; | ||
131 | if (!strcmp(buf, "full")) | ||
132 | config |= ADT75_PD; | ||
133 | |||
134 | ret = adt75_i2c_write(dev_info, ADT75_CONFIG, config); | ||
135 | if (ret) | ||
136 | return -EIO; | ||
137 | |||
138 | chip->config = config; | ||
139 | |||
140 | return ret; | ||
141 | } | ||
142 | |||
143 | static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, | ||
144 | adt75_show_mode, | ||
145 | adt75_store_mode, | ||
146 | 0); | ||
147 | |||
148 | static ssize_t adt75_show_available_modes(struct device *dev, | ||
149 | struct device_attribute *attr, | ||
150 | char *buf) | ||
151 | { | ||
152 | return sprintf(buf, "full\npower-down\n"); | ||
153 | } | ||
154 | |||
155 | static IIO_DEVICE_ATTR(available_modes, S_IRUGO, adt75_show_available_modes, NULL, 0); | ||
156 | |||
157 | static ssize_t adt75_show_oneshot(struct device *dev, | ||
158 | struct device_attribute *attr, | ||
159 | char *buf) | ||
160 | { | ||
161 | struct adt75_chip_info *chip = iio_priv(dev_get_drvdata(dev)); | ||
162 | |||
163 | return sprintf(buf, "%d\n", !!(chip->config & ADT75_ONESHOT)); | ||
164 | } | ||
165 | |||
166 | static ssize_t adt75_store_oneshot(struct device *dev, | ||
167 | struct device_attribute *attr, | ||
168 | const char *buf, | ||
169 | size_t len) | ||
170 | { | ||
171 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
172 | struct adt75_chip_info *chip = iio_priv(dev_info); | ||
173 | unsigned long data = 0; | ||
174 | int ret; | ||
175 | u8 config; | ||
176 | |||
177 | ret = strict_strtoul(buf, 10, &data); | ||
178 | if (ret) | ||
179 | return -EINVAL; | ||
180 | |||
181 | |||
182 | ret = adt75_i2c_read(dev_info, ADT75_CONFIG, &chip->config); | ||
183 | if (ret) | ||
184 | return -EIO; | ||
185 | |||
186 | config = chip->config & ~ADT75_ONESHOT; | ||
187 | if (data) | ||
188 | config |= ADT75_ONESHOT; | ||
189 | |||
190 | ret = adt75_i2c_write(dev_info, ADT75_CONFIG, config); | ||
191 | if (ret) | ||
192 | return -EIO; | ||
193 | |||
194 | chip->config = config; | ||
195 | |||
196 | return ret; | ||
197 | } | ||
198 | |||
199 | static IIO_DEVICE_ATTR(oneshot, S_IRUGO | S_IWUSR, | ||
200 | adt75_show_oneshot, | ||
201 | adt75_store_oneshot, | ||
202 | 0); | ||
203 | |||
204 | static ssize_t adt75_show_value(struct device *dev, | ||
205 | struct device_attribute *attr, | ||
206 | char *buf) | ||
207 | { | ||
208 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
209 | struct adt75_chip_info *chip = iio_priv(dev_info); | ||
210 | u16 data; | ||
211 | char sign = ' '; | ||
212 | int ret; | ||
213 | |||
214 | if (chip->config & ADT75_PD) { | ||
215 | dev_err(dev, "Can't read value in power-down mode.\n"); | ||
216 | return -EIO; | ||
217 | } | ||
218 | |||
219 | if (chip->config & ADT75_ONESHOT) { | ||
220 | /* write to active converter */ | ||
221 | ret = i2c_smbus_write_byte(chip->client, ADT75_ONESHOT); | ||
222 | if (ret) | ||
223 | return -EIO; | ||
224 | } | ||
225 | |||
226 | ret = adt75_i2c_read(dev_info, ADT75_TEMPERATURE, (u8 *)&data); | ||
227 | if (ret) | ||
228 | return -EIO; | ||
229 | |||
230 | data = swab16(data) >> ADT75_VALUE_OFFSET; | ||
231 | if (data & ADT75_VALUE_SIGN) { | ||
232 | /* convert supplement to positive value */ | ||
233 | data = (ADT75_VALUE_SIGN << 1) - data; | ||
234 | sign = '-'; | ||
235 | } | ||
236 | |||
237 | return sprintf(buf, "%c%d.%.4d\n", sign, | ||
238 | (data >> ADT75_VALUE_FLOAT_OFFSET), | ||
239 | (data & ADT75_VALUE_FLOAT_MASK) * 625); | ||
240 | } | ||
241 | |||
242 | static IIO_DEVICE_ATTR(value, S_IRUGO, adt75_show_value, NULL, 0); | ||
243 | |||
244 | static struct attribute *adt75_attributes[] = { | ||
245 | &iio_dev_attr_available_modes.dev_attr.attr, | ||
246 | &iio_dev_attr_mode.dev_attr.attr, | ||
247 | &iio_dev_attr_oneshot.dev_attr.attr, | ||
248 | &iio_dev_attr_value.dev_attr.attr, | ||
249 | NULL, | ||
250 | }; | ||
251 | |||
252 | static const struct attribute_group adt75_attribute_group = { | ||
253 | .attrs = adt75_attributes, | ||
254 | }; | ||
255 | |||
256 | /* | ||
257 | * temperature bound events | ||
258 | */ | ||
259 | |||
260 | #define IIO_EVENT_CODE_ADT75_OTI IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_TEMP, \ | ||
261 | 0, \ | ||
262 | IIO_EV_TYPE_THRESH, \ | ||
263 | IIO_EV_DIR_FALLING) | ||
264 | |||
265 | static irqreturn_t adt75_event_handler(int irq, void *private) | ||
266 | { | ||
267 | iio_push_event(private, 0, | ||
268 | IIO_EVENT_CODE_ADT75_OTI, | ||
269 | iio_get_time_ns()); | ||
270 | |||
271 | return IRQ_HANDLED; | ||
272 | } | ||
273 | |||
274 | static ssize_t adt75_show_oti_mode(struct device *dev, | ||
275 | struct device_attribute *attr, | ||
276 | char *buf) | ||
277 | { | ||
278 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
279 | struct adt75_chip_info *chip = iio_priv(dev_info); | ||
280 | int ret; | ||
281 | |||
282 | /* retrive ALART status */ | ||
283 | ret = adt75_i2c_read(dev_info, ADT75_CONFIG, &chip->config); | ||
284 | if (ret) | ||
285 | return -EIO; | ||
286 | |||
287 | if (chip->config & ADT75_OS_INT) | ||
288 | return sprintf(buf, "interrupt\n"); | ||
289 | else | ||
290 | return sprintf(buf, "comparator\n"); | ||
291 | } | ||
292 | |||
293 | static ssize_t adt75_set_oti_mode(struct device *dev, | ||
294 | struct device_attribute *attr, | ||
295 | const char *buf, | ||
296 | size_t len) | ||
297 | { | ||
298 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
299 | struct adt75_chip_info *chip = iio_priv(dev_info); | ||
300 | int ret; | ||
301 | u8 config; | ||
302 | |||
303 | /* retrive ALART status */ | ||
304 | ret = adt75_i2c_read(dev_info, ADT75_CONFIG, &chip->config); | ||
305 | if (ret) | ||
306 | return -EIO; | ||
307 | |||
308 | config = chip->config & ~ADT75_OS_INT; | ||
309 | if (strcmp(buf, "comparator") != 0) | ||
310 | config |= ADT75_OS_INT; | ||
311 | |||
312 | ret = adt75_i2c_write(dev_info, ADT75_CONFIG, config); | ||
313 | if (ret) | ||
314 | return -EIO; | ||
315 | |||
316 | chip->config = config; | ||
317 | |||
318 | return ret; | ||
319 | } | ||
320 | |||
321 | static ssize_t adt75_show_available_oti_modes(struct device *dev, | ||
322 | struct device_attribute *attr, | ||
323 | char *buf) | ||
324 | { | ||
325 | return sprintf(buf, "comparator\ninterrupt\n"); | ||
326 | } | ||
327 | |||
328 | static ssize_t adt75_show_smbus_alart(struct device *dev, | ||
329 | struct device_attribute *attr, | ||
330 | char *buf) | ||
331 | { | ||
332 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
333 | struct adt75_chip_info *chip = iio_priv(dev_info); | ||
334 | int ret; | ||
335 | |||
336 | /* retrive ALART status */ | ||
337 | ret = adt75_i2c_read(dev_info, ADT75_CONFIG, &chip->config); | ||
338 | if (ret) | ||
339 | return -EIO; | ||
340 | |||
341 | return sprintf(buf, "%d\n", !!(chip->config & ADT75_SMBUS_ALART)); | ||
342 | } | ||
343 | |||
344 | static ssize_t adt75_set_smbus_alart(struct device *dev, | ||
345 | struct device_attribute *attr, | ||
346 | const char *buf, | ||
347 | size_t len) | ||
348 | { | ||
349 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
350 | struct adt75_chip_info *chip = iio_priv(dev_info); | ||
351 | unsigned long data = 0; | ||
352 | int ret; | ||
353 | u8 config; | ||
354 | |||
355 | ret = strict_strtoul(buf, 10, &data); | ||
356 | if (ret) | ||
357 | return -EINVAL; | ||
358 | |||
359 | /* retrive ALART status */ | ||
360 | ret = adt75_i2c_read(dev_info, ADT75_CONFIG, &chip->config); | ||
361 | if (ret) | ||
362 | return -EIO; | ||
363 | |||
364 | config = chip->config & ~ADT75_SMBUS_ALART; | ||
365 | if (data) | ||
366 | config |= ADT75_SMBUS_ALART; | ||
367 | |||
368 | ret = adt75_i2c_write(dev_info, ADT75_CONFIG, config); | ||
369 | if (ret) | ||
370 | return -EIO; | ||
371 | |||
372 | chip->config = config; | ||
373 | |||
374 | return ret; | ||
375 | } | ||
376 | |||
377 | static ssize_t adt75_show_fault_queue(struct device *dev, | ||
378 | struct device_attribute *attr, | ||
379 | char *buf) | ||
380 | { | ||
381 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
382 | struct adt75_chip_info *chip = iio_priv(dev_info); | ||
383 | int ret; | ||
384 | |||
385 | /* retrive ALART status */ | ||
386 | ret = adt75_i2c_read(dev_info, ADT75_CONFIG, &chip->config); | ||
387 | if (ret) | ||
388 | return -EIO; | ||
389 | |||
390 | return sprintf(buf, "%d\n", (chip->config & ADT75_FAULT_QUEUE_MASK) >> | ||
391 | ADT75_FAULT_QUEUE_OFFSET); | ||
392 | } | ||
393 | |||
394 | static ssize_t adt75_set_fault_queue(struct device *dev, | ||
395 | struct device_attribute *attr, | ||
396 | const char *buf, | ||
397 | size_t len) | ||
398 | { | ||
399 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
400 | struct adt75_chip_info *chip = iio_priv(dev_info); | ||
401 | unsigned long data; | ||
402 | int ret; | ||
403 | u8 config; | ||
404 | |||
405 | ret = strict_strtoul(buf, 10, &data); | ||
406 | if (ret || data > 3) | ||
407 | return -EINVAL; | ||
408 | |||
409 | /* retrive ALART status */ | ||
410 | ret = adt75_i2c_read(dev_info, ADT75_CONFIG, &chip->config); | ||
411 | if (ret) | ||
412 | return -EIO; | ||
413 | |||
414 | config = chip->config & ~ADT75_FAULT_QUEUE_MASK; | ||
415 | config |= (data << ADT75_FAULT_QUEUE_OFFSET); | ||
416 | ret = adt75_i2c_write(dev_info, ADT75_CONFIG, config); | ||
417 | if (ret) | ||
418 | return -EIO; | ||
419 | |||
420 | chip->config = config; | ||
421 | |||
422 | return ret; | ||
423 | } | ||
424 | static inline ssize_t adt75_show_t_bound(struct device *dev, | ||
425 | struct device_attribute *attr, | ||
426 | char *buf) | ||
427 | { | ||
428 | struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); | ||
429 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
430 | u16 data; | ||
431 | char sign = ' '; | ||
432 | int ret; | ||
433 | |||
434 | ret = adt75_i2c_read(dev_info, this_attr->address, (u8 *)&data); | ||
435 | if (ret) | ||
436 | return -EIO; | ||
437 | |||
438 | data = swab16(data) >> ADT75_VALUE_OFFSET; | ||
439 | if (data & ADT75_VALUE_SIGN) { | ||
440 | /* convert supplement to positive value */ | ||
441 | data = (ADT75_VALUE_SIGN << 1) - data; | ||
442 | sign = '-'; | ||
443 | } | ||
444 | |||
445 | return sprintf(buf, "%c%d.%.4d\n", sign, | ||
446 | (data >> ADT75_VALUE_FLOAT_OFFSET), | ||
447 | (data & ADT75_VALUE_FLOAT_MASK) * 625); | ||
448 | } | ||
449 | |||
450 | static inline ssize_t adt75_set_t_bound(struct device *dev, | ||
451 | struct device_attribute *attr, | ||
452 | const char *buf, | ||
453 | size_t len) | ||
454 | { | ||
455 | struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); | ||
456 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
457 | long tmp1, tmp2; | ||
458 | u16 data; | ||
459 | char *pos; | ||
460 | int ret; | ||
461 | |||
462 | pos = strchr(buf, '.'); | ||
463 | |||
464 | ret = strict_strtol(buf, 10, &tmp1); | ||
465 | |||
466 | if (ret || tmp1 > 127 || tmp1 < -128) | ||
467 | return -EINVAL; | ||
468 | |||
469 | if (pos) { | ||
470 | len = strlen(pos); | ||
471 | if (len > ADT75_VALUE_FLOAT_OFFSET) | ||
472 | len = ADT75_VALUE_FLOAT_OFFSET; | ||
473 | pos[len] = 0; | ||
474 | ret = strict_strtol(pos, 10, &tmp2); | ||
475 | |||
476 | if (!ret) | ||
477 | tmp2 = (tmp2 / 625) * 625; | ||
478 | } | ||
479 | |||
480 | if (tmp1 < 0) | ||
481 | data = (u16)(-tmp1); | ||
482 | else | ||
483 | data = (u16)tmp1; | ||
484 | data = (data << ADT75_VALUE_FLOAT_OFFSET) | (tmp2 & ADT75_VALUE_FLOAT_MASK); | ||
485 | if (tmp1 < 0) | ||
486 | /* convert positive value to supplyment */ | ||
487 | data = (ADT75_VALUE_SIGN << 1) - data; | ||
488 | data <<= ADT75_VALUE_OFFSET; | ||
489 | data = swab16(data); | ||
490 | |||
491 | ret = adt75_i2c_write(dev_info, this_attr->address, (u8)data); | ||
492 | if (ret) | ||
493 | return -EIO; | ||
494 | |||
495 | return ret; | ||
496 | } | ||
497 | |||
498 | |||
499 | static IIO_DEVICE_ATTR(oti_mode, | ||
500 | S_IRUGO | S_IWUSR, | ||
501 | adt75_show_oti_mode, adt75_set_oti_mode, 0); | ||
502 | static IIO_DEVICE_ATTR(available_oti_modes, | ||
503 | S_IRUGO, | ||
504 | adt75_show_available_oti_modes, NULL, 0); | ||
505 | static IIO_DEVICE_ATTR(smbus_alart, | ||
506 | S_IRUGO | S_IWUSR, | ||
507 | adt75_show_smbus_alart, adt75_set_smbus_alart, 0); | ||
508 | static IIO_DEVICE_ATTR(fault_queue, | ||
509 | S_IRUGO | S_IWUSR, | ||
510 | adt75_show_fault_queue, adt75_set_fault_queue, 0); | ||
511 | static IIO_DEVICE_ATTR(t_os_value, | ||
512 | S_IRUGO | S_IWUSR, | ||
513 | adt75_show_t_bound, adt75_set_t_bound, | ||
514 | ADT75_T_OS); | ||
515 | static IIO_DEVICE_ATTR(t_hyst_value, | ||
516 | S_IRUGO | S_IWUSR, | ||
517 | adt75_show_t_bound, adt75_set_t_bound, | ||
518 | ADT75_T_HYST); | ||
519 | |||
520 | static struct attribute *adt75_event_attributes[] = { | ||
521 | &iio_dev_attr_oti_mode.dev_attr.attr, | ||
522 | &iio_dev_attr_available_oti_modes.dev_attr.attr, | ||
523 | &iio_dev_attr_smbus_alart.dev_attr.attr, | ||
524 | &iio_dev_attr_fault_queue.dev_attr.attr, | ||
525 | &iio_dev_attr_t_os_value.dev_attr.attr, | ||
526 | &iio_dev_attr_t_hyst_value.dev_attr.attr, | ||
527 | NULL, | ||
528 | }; | ||
529 | |||
530 | static struct attribute_group adt75_event_attribute_group = { | ||
531 | .attrs = adt75_event_attributes, | ||
532 | }; | ||
533 | |||
534 | static const struct iio_info adt75_info = { | ||
535 | .attrs = &adt75_attribute_group, | ||
536 | .num_interrupt_lines = 1, | ||
537 | .event_attrs = &adt75_event_attribute_group, | ||
538 | .driver_module = THIS_MODULE, | ||
539 | }; | ||
540 | |||
541 | /* | ||
542 | * device probe and remove | ||
543 | */ | ||
544 | |||
545 | static int __devinit adt75_probe(struct i2c_client *client, | ||
546 | const struct i2c_device_id *id) | ||
547 | { | ||
548 | struct adt75_chip_info *chip; | ||
549 | struct iio_dev *indio_dev; | ||
550 | int ret = 0; | ||
551 | |||
552 | indio_dev = iio_allocate_device(sizeof(*chip)); | ||
553 | if (indio_dev == NULL) { | ||
554 | ret = -ENOMEM; | ||
555 | goto error_ret; | ||
556 | } | ||
557 | chip = iio_priv(indio_dev); | ||
558 | |||
559 | /* this is only used for device removal purposes */ | ||
560 | i2c_set_clientdata(client, indio_dev); | ||
561 | |||
562 | chip->client = client; | ||
563 | |||
564 | indio_dev->name = id->name; | ||
565 | indio_dev->dev.parent = &client->dev; | ||
566 | indio_dev->info = &adt75_info; | ||
567 | indio_dev->modes = INDIO_DIRECT_MODE; | ||
568 | |||
569 | ret = iio_device_register(indio_dev); | ||
570 | if (ret) | ||
571 | goto error_free_dev; | ||
572 | |||
573 | if (client->irq > 0) { | ||
574 | ret = request_threaded_irq(client->irq, | ||
575 | NULL, | ||
576 | &adt75_event_handler, | ||
577 | IRQF_TRIGGER_LOW, | ||
578 | indio_dev->name, | ||
579 | indio_dev); | ||
580 | if (ret) | ||
581 | goto error_unreg_dev; | ||
582 | |||
583 | ret = adt75_i2c_read(indio_dev, ADT75_CONFIG, &chip->config); | ||
584 | if (ret) { | ||
585 | ret = -EIO; | ||
586 | goto error_unreg_irq; | ||
587 | } | ||
588 | |||
589 | /* set irq polarity low level */ | ||
590 | chip->config &= ~ADT75_OS_POLARITY; | ||
591 | |||
592 | ret = adt75_i2c_write(indio_dev, ADT75_CONFIG, chip->config); | ||
593 | if (ret) { | ||
594 | ret = -EIO; | ||
595 | goto error_unreg_irq; | ||
596 | } | ||
597 | } | ||
598 | |||
599 | dev_info(&client->dev, "%s temperature sensor registered.\n", | ||
600 | indio_dev->name); | ||
601 | |||
602 | return 0; | ||
603 | error_unreg_irq: | ||
604 | free_irq(client->irq, indio_dev); | ||
605 | error_unreg_dev: | ||
606 | iio_device_unregister(indio_dev); | ||
607 | error_free_dev: | ||
608 | iio_free_device(indio_dev); | ||
609 | error_ret: | ||
610 | return ret; | ||
611 | } | ||
612 | |||
613 | static int __devexit adt75_remove(struct i2c_client *client) | ||
614 | { | ||
615 | struct iio_dev *indio_dev = i2c_get_clientdata(client); | ||
616 | |||
617 | if (client->irq) | ||
618 | free_irq(client->irq, indio_dev); | ||
619 | iio_device_unregister(indio_dev); | ||
620 | iio_free_device(indio_dev); | ||
621 | |||
622 | return 0; | ||
623 | } | ||
624 | |||
625 | static const struct i2c_device_id adt75_id[] = { | ||
626 | { "adt75", 0 }, | ||
627 | {} | ||
628 | }; | ||
629 | |||
630 | MODULE_DEVICE_TABLE(i2c, adt75_id); | ||
631 | |||
632 | static struct i2c_driver adt75_driver = { | ||
633 | .driver = { | ||
634 | .name = "adt75", | ||
635 | }, | ||
636 | .probe = adt75_probe, | ||
637 | .remove = __devexit_p(adt75_remove), | ||
638 | .id_table = adt75_id, | ||
639 | }; | ||
640 | |||
641 | static __init int adt75_init(void) | ||
642 | { | ||
643 | return i2c_add_driver(&adt75_driver); | ||
644 | } | ||
645 | |||
646 | static __exit void adt75_exit(void) | ||
647 | { | ||
648 | i2c_del_driver(&adt75_driver); | ||
649 | } | ||
650 | |||
651 | MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>"); | ||
652 | MODULE_DESCRIPTION("Analog Devices ADT75 digital" | ||
653 | " temperature sensor driver"); | ||
654 | MODULE_LICENSE("GPL v2"); | ||
655 | |||
656 | module_init(adt75_init); | ||
657 | module_exit(adt75_exit); | ||
diff --git a/drivers/staging/iio/adc/max1363.h b/drivers/staging/iio/adc/max1363.h new file mode 100644 index 00000000000..360bfc5398f --- /dev/null +++ b/drivers/staging/iio/adc/max1363.h | |||
@@ -0,0 +1,175 @@ | |||
1 | #ifndef _MAX1363_H_ | ||
2 | #define _MAX1363_H_ | ||
3 | |||
4 | #define MAX1363_SETUP_BYTE(a) ((a) | 0x80) | ||
5 | |||
6 | /* There is a fair bit more defined here than currently | ||
7 | * used, but the intention is to support everything these | ||
8 | * chips do in the long run */ | ||
9 | |||
10 | /* see data sheets */ | ||
11 | /* max1363 and max1236, max1237, max1238, max1239 */ | ||
12 | #define MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_VDD 0x00 | ||
13 | #define MAX1363_SETUP_AIN3_IS_REF_EXT_TO_REF 0x20 | ||
14 | #define MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_INT 0x40 | ||
15 | #define MAX1363_SETUP_AIN3_IS_REF_REF_IS_INT 0x60 | ||
16 | #define MAX1363_SETUP_POWER_UP_INT_REF 0x10 | ||
17 | #define MAX1363_SETUP_POWER_DOWN_INT_REF 0x00 | ||
18 | |||
19 | /* think about includeing max11600 etc - more settings */ | ||
20 | #define MAX1363_SETUP_EXT_CLOCK 0x08 | ||
21 | #define MAX1363_SETUP_INT_CLOCK 0x00 | ||
22 | #define MAX1363_SETUP_UNIPOLAR 0x00 | ||
23 | #define MAX1363_SETUP_BIPOLAR 0x04 | ||
24 | #define MAX1363_SETUP_RESET 0x00 | ||
25 | #define MAX1363_SETUP_NORESET 0x02 | ||
26 | /* max1363 only - though don't care on others. | ||
27 | * For now monitor modes are not implemented as the relevant | ||
28 | * line is not connected on my test board. | ||
29 | * The definitions are here as I intend to add this soon. | ||
30 | */ | ||
31 | #define MAX1363_SETUP_MONITOR_SETUP 0x01 | ||
32 | |||
33 | /* Specific to the max1363 */ | ||
34 | #define MAX1363_MON_RESET_CHAN(a) (1 << ((a) + 4)) | ||
35 | #define MAX1363_MON_INT_ENABLE 0x01 | ||
36 | |||
37 | /* defined for readability reasons */ | ||
38 | /* All chips */ | ||
39 | #define MAX1363_CONFIG_BYTE(a) ((a)) | ||
40 | |||
41 | #define MAX1363_CONFIG_SE 0x01 | ||
42 | #define MAX1363_CONFIG_DE 0x00 | ||
43 | #define MAX1363_CONFIG_SCAN_TO_CS 0x00 | ||
44 | #define MAX1363_CONFIG_SCAN_SINGLE_8 0x20 | ||
45 | #define MAX1363_CONFIG_SCAN_MONITOR_MODE 0x40 | ||
46 | #define MAX1363_CONFIG_SCAN_SINGLE_1 0x60 | ||
47 | /* max123{6-9} only */ | ||
48 | #define MAX1236_SCAN_MID_TO_CHANNEL 0x40 | ||
49 | |||
50 | /* max1363 only - merely part of channel selects or don't care for others*/ | ||
51 | #define MAX1363_CONFIG_EN_MON_MODE_READ 0x18 | ||
52 | |||
53 | #define MAX1363_CHANNEL_SEL(a) ((a) << 1) | ||
54 | |||
55 | /* max1363 strictly 0x06 - but doesn't matter */ | ||
56 | #define MAX1363_CHANNEL_SEL_MASK 0x1E | ||
57 | #define MAX1363_SCAN_MASK 0x60 | ||
58 | #define MAX1363_SE_DE_MASK 0x01 | ||
59 | |||
60 | /** | ||
61 | * struct max1363_mode - scan mode information | ||
62 | * @conf: The corresponding value of the configuration register | ||
63 | * @modemask: Bit mask corresponding to channels enabled in this mode | ||
64 | */ | ||
65 | struct max1363_mode { | ||
66 | int8_t conf; | ||
67 | long modemask; | ||
68 | }; | ||
69 | |||
70 | /* This must be maintained along side the max1363_mode_table in max1363_core */ | ||
71 | enum max1363_modes { | ||
72 | /* Single read of a single channel */ | ||
73 | _s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s9, _s10, _s11, | ||
74 | /* Differential single read */ | ||
75 | d0m1, d2m3, d4m5, d6m7, d8m9, d10m11, | ||
76 | d1m0, d3m2, d5m4, d7m6, d9m8, d11m10, | ||
77 | /* Scan to channel and mid to channel where overlapping */ | ||
78 | s0to1, s0to2, s2to3, s0to3, s0to4, s0to5, s0to6, | ||
79 | s6to7, s0to7, s6to8, s0to8, s6to9, | ||
80 | s0to9, s6to10, s0to10, s6to11, s0to11, | ||
81 | /* Differential scan to channel and mid to channel where overlapping */ | ||
82 | d0m1to2m3, d0m1to4m5, d0m1to6m7, d6m7to8m9, | ||
83 | d0m1to8m9, d6m7to10m11, d0m1to10m11, d1m0to3m2, | ||
84 | d1m0to5m4, d1m0to7m6, d7m6to9m8, d1m0to9m8, | ||
85 | d7m6to11m10, d1m0to11m10, | ||
86 | }; | ||
87 | |||
88 | /** | ||
89 | * struct max1363_chip_info - chip specifc information | ||
90 | * @name: indentification string for chip | ||
91 | * @bits: accuracy of the adc in bits | ||
92 | * @int_vref_mv: the internal reference voltage | ||
93 | * @info: iio core function callbacks structure | ||
94 | * @mode_list: array of available scan modes | ||
95 | * @num_modes: the number of scan modes available | ||
96 | * @default_mode: the scan mode in which the chip starts up | ||
97 | * @channel: channel specification | ||
98 | * @num_channels: number of channels | ||
99 | */ | ||
100 | struct max1363_chip_info { | ||
101 | const struct iio_info *info; | ||
102 | struct iio_chan_spec *channels; | ||
103 | int num_channels; | ||
104 | const enum max1363_modes *mode_list; | ||
105 | enum max1363_modes default_mode; | ||
106 | u16 int_vref_mv; | ||
107 | u8 num_modes; | ||
108 | u8 bits; | ||
109 | }; | ||
110 | |||
111 | /** | ||
112 | * struct max1363_state - driver instance specific data | ||
113 | * @client: i2c_client | ||
114 | * @setupbyte: cache of current device setup byte | ||
115 | * @configbyte: cache of current device config byte | ||
116 | * @chip_info: chip model specific constants, available modes etc | ||
117 | * @current_mode: the scan mode of this chip | ||
118 | * @requestedmask: a valid requested set of channels | ||
119 | * @reg: supply regulator | ||
120 | * @monitor_on: whether monitor mode is enabled | ||
121 | * @monitor_speed: parameter corresponding to device monitor speed setting | ||
122 | * @mask_high: bitmask for enabled high thresholds | ||
123 | * @mask_low: bitmask for enabled low thresholds | ||
124 | * @thresh_high: high threshold values | ||
125 | * @thresh_low: low threshold values | ||
126 | */ | ||
127 | struct max1363_state { | ||
128 | struct i2c_client *client; | ||
129 | u8 setupbyte; | ||
130 | u8 configbyte; | ||
131 | const struct max1363_chip_info *chip_info; | ||
132 | const struct max1363_mode *current_mode; | ||
133 | u32 requestedmask; | ||
134 | struct regulator *reg; | ||
135 | |||
136 | /* Using monitor modes and buffer at the same time is | ||
137 | currently not supported */ | ||
138 | bool monitor_on; | ||
139 | unsigned int monitor_speed:3; | ||
140 | u8 mask_high; | ||
141 | u8 mask_low; | ||
142 | /* 4x unipolar first then the fours bipolar ones */ | ||
143 | s16 thresh_high[8]; | ||
144 | s16 thresh_low[8]; | ||
145 | }; | ||
146 | |||
147 | const struct max1363_mode | ||
148 | *max1363_match_mode(u32 mask, const struct max1363_chip_info *ci); | ||
149 | |||
150 | int max1363_set_scan_mode(struct max1363_state *st); | ||
151 | |||
152 | #ifdef CONFIG_MAX1363_RING_BUFFER | ||
153 | |||
154 | int max1363_single_channel_from_ring(long mask, struct max1363_state *st); | ||
155 | int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev); | ||
156 | void max1363_ring_cleanup(struct iio_dev *indio_dev); | ||
157 | |||
158 | #else /* CONFIG_MAX1363_RING_BUFFER */ | ||
159 | |||
160 | int max1363_single_channel_from_ring(long mask, struct max1363_state *st) | ||
161 | { | ||
162 | return -EINVAL; | ||
163 | } | ||
164 | |||
165 | static inline int | ||
166 | max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev) | ||
167 | { | ||
168 | return 0; | ||
169 | } | ||
170 | |||
171 | static inline void max1363_ring_cleanup(struct iio_dev *indio_dev) | ||
172 | { | ||
173 | } | ||
174 | #endif /* CONFIG_MAX1363_RING_BUFFER */ | ||
175 | #endif /* _MAX1363_H_ */ | ||
diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c new file mode 100644 index 00000000000..72b0917412e --- /dev/null +++ b/drivers/staging/iio/adc/max1363_core.c | |||
@@ -0,0 +1,1433 @@ | |||
1 | /* | ||
2 | * iio/adc/max1363.c | ||
3 | * Copyright (C) 2008-2010 Jonathan Cameron | ||
4 | * | ||
5 | * based on linux/drivers/i2c/chips/max123x | ||
6 | * Copyright (C) 2002-2004 Stefan Eletzhofer | ||
7 | * | ||
8 | * based on linux/drivers/acron/char/pcf8583.c | ||
9 | * Copyright (C) 2000 Russell King | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License version 2 as | ||
13 | * published by the Free Software Foundation. | ||
14 | * | ||
15 | * max1363.c | ||
16 | * | ||
17 | * Partial support for max1363 and similar chips. | ||
18 | * | ||
19 | * Not currently implemented. | ||
20 | * | ||
21 | * - Control of internal reference. | ||
22 | */ | ||
23 | |||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/device.h> | ||
26 | #include <linux/kernel.h> | ||
27 | #include <linux/sysfs.h> | ||
28 | #include <linux/list.h> | ||
29 | #include <linux/i2c.h> | ||
30 | #include <linux/regulator/consumer.h> | ||
31 | #include <linux/slab.h> | ||
32 | #include <linux/err.h> | ||
33 | |||
34 | #include "../iio.h" | ||
35 | #include "../sysfs.h" | ||
36 | |||
37 | #include "../ring_generic.h" | ||
38 | #include "adc.h" | ||
39 | #include "max1363.h" | ||
40 | |||
41 | #define MAX1363_MODE_SINGLE(_num, _mask) { \ | ||
42 | .conf = MAX1363_CHANNEL_SEL(_num) \ | ||
43 | | MAX1363_CONFIG_SCAN_SINGLE_1 \ | ||
44 | | MAX1363_CONFIG_SE, \ | ||
45 | .modemask = _mask, \ | ||
46 | } | ||
47 | |||
48 | #define MAX1363_MODE_SCAN_TO_CHANNEL(_num, _mask) { \ | ||
49 | .conf = MAX1363_CHANNEL_SEL(_num) \ | ||
50 | | MAX1363_CONFIG_SCAN_TO_CS \ | ||
51 | | MAX1363_CONFIG_SE, \ | ||
52 | .modemask = _mask, \ | ||
53 | } | ||
54 | |||
55 | /* note not available for max1363 hence naming */ | ||
56 | #define MAX1236_MODE_SCAN_MID_TO_CHANNEL(_mid, _num, _mask) { \ | ||
57 | .conf = MAX1363_CHANNEL_SEL(_num) \ | ||
58 | | MAX1236_SCAN_MID_TO_CHANNEL \ | ||
59 | | MAX1363_CONFIG_SE, \ | ||
60 | .modemask = _mask \ | ||
61 | } | ||
62 | |||
63 | #define MAX1363_MODE_DIFF_SINGLE(_nump, _numm, _mask) { \ | ||
64 | .conf = MAX1363_CHANNEL_SEL(_nump) \ | ||
65 | | MAX1363_CONFIG_SCAN_SINGLE_1 \ | ||
66 | | MAX1363_CONFIG_DE, \ | ||
67 | .modemask = _mask \ | ||
68 | } | ||
69 | |||
70 | /* Can't think how to automate naming so specify for now */ | ||
71 | #define MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(_num, _numvals, _mask) { \ | ||
72 | .conf = MAX1363_CHANNEL_SEL(_num) \ | ||
73 | | MAX1363_CONFIG_SCAN_TO_CS \ | ||
74 | | MAX1363_CONFIG_DE, \ | ||
75 | .modemask = _mask \ | ||
76 | } | ||
77 | |||
78 | /* note only available for max1363 hence naming */ | ||
79 | #define MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(_num, _numvals, _mask) { \ | ||
80 | .conf = MAX1363_CHANNEL_SEL(_num) \ | ||
81 | | MAX1236_SCAN_MID_TO_CHANNEL \ | ||
82 | | MAX1363_CONFIG_SE, \ | ||
83 | .modemask = _mask \ | ||
84 | } | ||
85 | |||
86 | static const struct max1363_mode max1363_mode_table[] = { | ||
87 | /* All of the single channel options first */ | ||
88 | MAX1363_MODE_SINGLE(0, 1 << 0), | ||
89 | MAX1363_MODE_SINGLE(1, 1 << 1), | ||
90 | MAX1363_MODE_SINGLE(2, 1 << 2), | ||
91 | MAX1363_MODE_SINGLE(3, 1 << 3), | ||
92 | MAX1363_MODE_SINGLE(4, 1 << 4), | ||
93 | MAX1363_MODE_SINGLE(5, 1 << 5), | ||
94 | MAX1363_MODE_SINGLE(6, 1 << 6), | ||
95 | MAX1363_MODE_SINGLE(7, 1 << 7), | ||
96 | MAX1363_MODE_SINGLE(8, 1 << 8), | ||
97 | MAX1363_MODE_SINGLE(9, 1 << 9), | ||
98 | MAX1363_MODE_SINGLE(10, 1 << 10), | ||
99 | MAX1363_MODE_SINGLE(11, 1 << 11), | ||
100 | |||
101 | MAX1363_MODE_DIFF_SINGLE(0, 1, 1 << 12), | ||
102 | MAX1363_MODE_DIFF_SINGLE(2, 3, 1 << 13), | ||
103 | MAX1363_MODE_DIFF_SINGLE(4, 5, 1 << 14), | ||
104 | MAX1363_MODE_DIFF_SINGLE(6, 7, 1 << 15), | ||
105 | MAX1363_MODE_DIFF_SINGLE(8, 9, 1 << 16), | ||
106 | MAX1363_MODE_DIFF_SINGLE(10, 11, 1 << 17), | ||
107 | MAX1363_MODE_DIFF_SINGLE(1, 0, 1 << 18), | ||
108 | MAX1363_MODE_DIFF_SINGLE(3, 2, 1 << 19), | ||
109 | MAX1363_MODE_DIFF_SINGLE(5, 4, 1 << 20), | ||
110 | MAX1363_MODE_DIFF_SINGLE(7, 6, 1 << 21), | ||
111 | MAX1363_MODE_DIFF_SINGLE(9, 8, 1 << 22), | ||
112 | MAX1363_MODE_DIFF_SINGLE(11, 10, 1 << 23), | ||
113 | |||
114 | /* The multichannel scans next */ | ||
115 | MAX1363_MODE_SCAN_TO_CHANNEL(1, 0x003), | ||
116 | MAX1363_MODE_SCAN_TO_CHANNEL(2, 0x007), | ||
117 | MAX1236_MODE_SCAN_MID_TO_CHANNEL(2, 3, 0x00C), | ||
118 | MAX1363_MODE_SCAN_TO_CHANNEL(3, 0x00F), | ||
119 | MAX1363_MODE_SCAN_TO_CHANNEL(4, 0x01F), | ||
120 | MAX1363_MODE_SCAN_TO_CHANNEL(5, 0x03F), | ||
121 | MAX1363_MODE_SCAN_TO_CHANNEL(6, 0x07F), | ||
122 | MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 7, 0x0C0), | ||
123 | MAX1363_MODE_SCAN_TO_CHANNEL(7, 0x0FF), | ||
124 | MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 8, 0x1C0), | ||
125 | MAX1363_MODE_SCAN_TO_CHANNEL(8, 0x1FF), | ||
126 | MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 9, 0x3C0), | ||
127 | MAX1363_MODE_SCAN_TO_CHANNEL(9, 0x3FF), | ||
128 | MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 10, 0x7C0), | ||
129 | MAX1363_MODE_SCAN_TO_CHANNEL(10, 0x7FF), | ||
130 | MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 11, 0xFC0), | ||
131 | MAX1363_MODE_SCAN_TO_CHANNEL(11, 0xFFF), | ||
132 | |||
133 | MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(2, 2, 0x003000), | ||
134 | MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(4, 3, 0x007000), | ||
135 | MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(6, 4, 0x00F000), | ||
136 | MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(8, 2, 0x018000), | ||
137 | MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(8, 5, 0x01F000), | ||
138 | MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(10, 3, 0x038000), | ||
139 | MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(10, 6, 0x3F000), | ||
140 | MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(3, 2, 0x0C0000), | ||
141 | MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(5, 3, 0x1C0000), | ||
142 | MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(7, 4, 0x3C0000), | ||
143 | MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(9, 2, 0x600000), | ||
144 | MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(9, 5, 0x7C0000), | ||
145 | MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(11, 3, 0xE00000), | ||
146 | MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(11, 6, 0xFC0000), | ||
147 | }; | ||
148 | |||
149 | const struct max1363_mode | ||
150 | *max1363_match_mode(u32 mask, const struct max1363_chip_info *ci) | ||
151 | { | ||
152 | int i; | ||
153 | if (mask) | ||
154 | for (i = 0; i < ci->num_modes; i++) | ||
155 | if (!((~max1363_mode_table[ci->mode_list[i]].modemask) & | ||
156 | mask)) | ||
157 | return &max1363_mode_table[ci->mode_list[i]]; | ||
158 | return NULL; | ||
159 | } | ||
160 | |||
161 | static int max1363_write_basic_config(struct i2c_client *client, | ||
162 | unsigned char d1, | ||
163 | unsigned char d2) | ||
164 | { | ||
165 | u8 tx_buf[2] = {d1, d2}; | ||
166 | |||
167 | return i2c_master_send(client, tx_buf, 2); | ||
168 | } | ||
169 | |||
170 | int max1363_set_scan_mode(struct max1363_state *st) | ||
171 | { | ||
172 | st->configbyte &= ~(MAX1363_CHANNEL_SEL_MASK | ||
173 | | MAX1363_SCAN_MASK | ||
174 | | MAX1363_SE_DE_MASK); | ||
175 | st->configbyte |= st->current_mode->conf; | ||
176 | |||
177 | return max1363_write_basic_config(st->client, | ||
178 | st->setupbyte, | ||
179 | st->configbyte); | ||
180 | } | ||
181 | |||
182 | static int max1363_read_single_chan(struct iio_dev *indio_dev, | ||
183 | struct iio_chan_spec const *chan, | ||
184 | int *val, | ||
185 | long m) | ||
186 | { | ||
187 | int ret = 0; | ||
188 | s32 data; | ||
189 | char rxbuf[2]; | ||
190 | long mask; | ||
191 | struct max1363_state *st = iio_priv(indio_dev); | ||
192 | struct i2c_client *client = st->client; | ||
193 | |||
194 | mutex_lock(&indio_dev->mlock); | ||
195 | /* | ||
196 | * If monitor mode is enabled, the method for reading a single | ||
197 | * channel will have to be rather different and has not yet | ||
198 | * been implemented. | ||
199 | */ | ||
200 | if (st->monitor_on) { | ||
201 | ret = -EBUSY; | ||
202 | goto error_ret; | ||
203 | } | ||
204 | |||
205 | /* If ring buffer capture is occurring, query the buffer */ | ||
206 | if (iio_ring_enabled(indio_dev)) { | ||
207 | mask = max1363_mode_table[chan->address].modemask; | ||
208 | data = max1363_single_channel_from_ring(mask, st); | ||
209 | if (data < 0) { | ||
210 | ret = data; | ||
211 | goto error_ret; | ||
212 | } | ||
213 | } else { | ||
214 | /* Check to see if current scan mode is correct */ | ||
215 | if (st->current_mode != &max1363_mode_table[chan->address]) { | ||
216 | /* Update scan mode if needed */ | ||
217 | st->current_mode = &max1363_mode_table[chan->address]; | ||
218 | ret = max1363_set_scan_mode(st); | ||
219 | if (ret < 0) | ||
220 | goto error_ret; | ||
221 | } | ||
222 | if (st->chip_info->bits != 8) { | ||
223 | /* Get reading */ | ||
224 | data = i2c_master_recv(client, rxbuf, 2); | ||
225 | if (data < 0) { | ||
226 | ret = data; | ||
227 | goto error_ret; | ||
228 | } | ||
229 | data = (s32)(rxbuf[1]) | ((s32)(rxbuf[0] & 0x0F)) << 8; | ||
230 | } else { | ||
231 | /* Get reading */ | ||
232 | data = i2c_master_recv(client, rxbuf, 1); | ||
233 | if (data < 0) { | ||
234 | ret = data; | ||
235 | goto error_ret; | ||
236 | } | ||
237 | data = rxbuf[0]; | ||
238 | } | ||
239 | } | ||
240 | *val = data; | ||
241 | error_ret: | ||
242 | mutex_unlock(&indio_dev->mlock); | ||
243 | return ret; | ||
244 | |||
245 | } | ||
246 | |||
247 | static int max1363_read_raw(struct iio_dev *indio_dev, | ||
248 | struct iio_chan_spec const *chan, | ||
249 | int *val, | ||
250 | int *val2, | ||
251 | long m) | ||
252 | { | ||
253 | struct max1363_state *st = iio_priv(indio_dev); | ||
254 | int ret; | ||
255 | switch (m) { | ||
256 | case 0: | ||
257 | ret = max1363_read_single_chan(indio_dev, chan, val, m); | ||
258 | if (ret) | ||
259 | return ret; | ||
260 | return IIO_VAL_INT; | ||
261 | case (1 << IIO_CHAN_INFO_SCALE_SHARED): | ||
262 | if ((1 << (st->chip_info->bits + 1)) > | ||
263 | st->chip_info->int_vref_mv) { | ||
264 | *val = 0; | ||
265 | *val2 = 500000; | ||
266 | return IIO_VAL_INT_PLUS_MICRO; | ||
267 | } else { | ||
268 | *val = (st->chip_info->int_vref_mv) | ||
269 | >> st->chip_info->bits; | ||
270 | return IIO_VAL_INT; | ||
271 | } | ||
272 | default: | ||
273 | return -EINVAL; | ||
274 | } | ||
275 | return 0; | ||
276 | } | ||
277 | |||
278 | /* Applies to max1363 */ | ||
279 | static const enum max1363_modes max1363_mode_list[] = { | ||
280 | _s0, _s1, _s2, _s3, | ||
281 | s0to1, s0to2, s0to3, | ||
282 | d0m1, d2m3, d1m0, d3m2, | ||
283 | d0m1to2m3, d1m0to3m2, | ||
284 | }; | ||
285 | |||
286 | #define MAX1363_EV_M \ | ||
287 | (IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) \ | ||
288 | | IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING)) | ||
289 | #define MAX1363_INFO_MASK (1 << IIO_CHAN_INFO_SCALE_SHARED) | ||
290 | |||
291 | static struct iio_chan_spec max1363_channels[] = { | ||
292 | IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0, MAX1363_INFO_MASK, | ||
293 | _s0, 0, IIO_ST('u', 12, 16, 0), MAX1363_EV_M), | ||
294 | IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0, MAX1363_INFO_MASK, | ||
295 | _s1, 1, IIO_ST('u', 12, 16, 0), MAX1363_EV_M), | ||
296 | IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 2, 0, MAX1363_INFO_MASK, | ||
297 | _s2, 2, IIO_ST('u', 12, 16, 0), MAX1363_EV_M), | ||
298 | IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 3, 0, MAX1363_INFO_MASK, | ||
299 | _s3, 3, IIO_ST('u', 12, 16, 0), MAX1363_EV_M), | ||
300 | IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 0, 1, MAX1363_INFO_MASK, | ||
301 | d0m1, 4, IIO_ST('s', 12, 16, 0), MAX1363_EV_M), | ||
302 | IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 2, 3, MAX1363_INFO_MASK, | ||
303 | d2m3, 5, IIO_ST('s', 12, 16, 0), MAX1363_EV_M), | ||
304 | IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 1, 0, MAX1363_INFO_MASK, | ||
305 | d1m0, 6, IIO_ST('s', 12, 16, 0), MAX1363_EV_M), | ||
306 | IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 3, 2, MAX1363_INFO_MASK, | ||
307 | d3m2, 7, IIO_ST('s', 12, 16, 0), MAX1363_EV_M), | ||
308 | IIO_CHAN_SOFT_TIMESTAMP(8) | ||
309 | }; | ||
310 | |||
311 | static struct iio_chan_spec max1361_channels[] = { | ||
312 | IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0, MAX1363_INFO_MASK, | ||
313 | _s0, 0, IIO_ST('u', 10, 16, 0), MAX1363_EV_M), | ||
314 | IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0, MAX1363_INFO_MASK, | ||
315 | _s1, 1, IIO_ST('u', 10, 16, 0), MAX1363_EV_M), | ||
316 | IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 2, 0, MAX1363_INFO_MASK, | ||
317 | _s2, 2, IIO_ST('u', 10, 16, 0), MAX1363_EV_M), | ||
318 | IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 3, 0, MAX1363_INFO_MASK, | ||
319 | _s3, 3, IIO_ST('u', 10, 16, 0), MAX1363_EV_M), | ||
320 | IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 0, 1, MAX1363_INFO_MASK, | ||
321 | d0m1, 4, IIO_ST('s', 10, 16, 0), MAX1363_EV_M), | ||
322 | IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 2, 3, MAX1363_INFO_MASK, | ||
323 | d2m3, 5, IIO_ST('s', 10, 16, 0), MAX1363_EV_M), | ||
324 | IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 1, 0, MAX1363_INFO_MASK, | ||
325 | d1m0, 6, IIO_ST('s', 10, 16, 0), MAX1363_EV_M), | ||
326 | IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 3, 2, MAX1363_INFO_MASK, | ||
327 | d3m2, 7, IIO_ST('s', 10, 16, 0), MAX1363_EV_M), | ||
328 | IIO_CHAN_SOFT_TIMESTAMP(8) | ||
329 | }; | ||
330 | |||
331 | #define MAX1363_CHAN_U(num, address, scan_index, bits) \ | ||
332 | IIO_CHAN(IIO_IN, 0, 1, 0, NULL, num, 0, MAX1363_INFO_MASK, \ | ||
333 | address, scan_index, IIO_ST('u', bits, \ | ||
334 | (bits == 8) ? 8 : 16, 0), 0) | ||
335 | /* bipolar channel */ | ||
336 | #define MAX1363_CHAN_B(num, num2, address, scan_index, bits) \ | ||
337 | IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, num, num2, MAX1363_INFO_MASK,\ | ||
338 | address, scan_index, IIO_ST('s', bits, \ | ||
339 | (bits == 8) ? 8 : 16, 0), 0) | ||
340 | |||
341 | #define MAX1363_4X_CHANS(bits) { \ | ||
342 | MAX1363_CHAN_U(0, _s0, 0, bits), \ | ||
343 | MAX1363_CHAN_U(1, _s1, 1, bits), \ | ||
344 | MAX1363_CHAN_U(2, _s2, 2, bits), \ | ||
345 | MAX1363_CHAN_U(3, _s3, 3, bits), \ | ||
346 | MAX1363_CHAN_B(0, 1, d0m1, 4, bits), \ | ||
347 | MAX1363_CHAN_B(2, 3, d2m3, 5, bits), \ | ||
348 | MAX1363_CHAN_B(1, 0, d1m0, 6, bits), \ | ||
349 | MAX1363_CHAN_B(3, 2, d3m2, 7, bits), \ | ||
350 | IIO_CHAN_SOFT_TIMESTAMP(8) \ | ||
351 | } | ||
352 | |||
353 | static struct iio_chan_spec max1036_channels[] = MAX1363_4X_CHANS(8); | ||
354 | static struct iio_chan_spec max1136_channels[] = MAX1363_4X_CHANS(10); | ||
355 | static struct iio_chan_spec max1236_channels[] = MAX1363_4X_CHANS(12); | ||
356 | |||
357 | /* Appies to max1236, max1237 */ | ||
358 | static const enum max1363_modes max1236_mode_list[] = { | ||
359 | _s0, _s1, _s2, _s3, | ||
360 | s0to1, s0to2, s0to3, | ||
361 | d0m1, d2m3, d1m0, d3m2, | ||
362 | d0m1to2m3, d1m0to3m2, | ||
363 | s2to3, | ||
364 | }; | ||
365 | |||
366 | /* Applies to max1238, max1239 */ | ||
367 | static const enum max1363_modes max1238_mode_list[] = { | ||
368 | _s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s9, _s10, _s11, | ||
369 | s0to1, s0to2, s0to3, s0to4, s0to5, s0to6, | ||
370 | s0to7, s0to8, s0to9, s0to10, s0to11, | ||
371 | d0m1, d2m3, d4m5, d6m7, d8m9, d10m11, | ||
372 | d1m0, d3m2, d5m4, d7m6, d9m8, d11m10, | ||
373 | d0m1to2m3, d0m1to4m5, d0m1to6m7, d0m1to8m9, d0m1to10m11, | ||
374 | d1m0to3m2, d1m0to5m4, d1m0to7m6, d1m0to9m8, d1m0to11m10, | ||
375 | s6to7, s6to8, s6to9, s6to10, s6to11, | ||
376 | d6m7to8m9, d6m7to10m11, d7m6to9m8, d7m6to11m10, | ||
377 | }; | ||
378 | |||
379 | #define MAX1363_12X_CHANS(bits) { \ | ||
380 | MAX1363_CHAN_U(0, _s0, 0, bits), \ | ||
381 | MAX1363_CHAN_U(1, _s1, 1, bits), \ | ||
382 | MAX1363_CHAN_U(2, _s2, 2, bits), \ | ||
383 | MAX1363_CHAN_U(3, _s3, 3, bits), \ | ||
384 | MAX1363_CHAN_U(4, _s4, 4, bits), \ | ||
385 | MAX1363_CHAN_U(5, _s5, 5, bits), \ | ||
386 | MAX1363_CHAN_U(6, _s6, 6, bits), \ | ||
387 | MAX1363_CHAN_U(7, _s7, 7, bits), \ | ||
388 | MAX1363_CHAN_U(8, _s8, 8, bits), \ | ||
389 | MAX1363_CHAN_U(9, _s9, 9, bits), \ | ||
390 | MAX1363_CHAN_U(10, _s10, 10, bits), \ | ||
391 | MAX1363_CHAN_U(11, _s11, 11, bits), \ | ||
392 | MAX1363_CHAN_B(0, 1, d0m1, 12, bits), \ | ||
393 | MAX1363_CHAN_B(2, 3, d2m3, 13, bits), \ | ||
394 | MAX1363_CHAN_B(4, 5, d4m5, 14, bits), \ | ||
395 | MAX1363_CHAN_B(6, 7, d6m7, 15, bits), \ | ||
396 | MAX1363_CHAN_B(8, 9, d8m9, 16, bits), \ | ||
397 | MAX1363_CHAN_B(10, 11, d10m11, 17, bits), \ | ||
398 | MAX1363_CHAN_B(1, 0, d1m0, 18, bits), \ | ||
399 | MAX1363_CHAN_B(3, 2, d3m2, 19, bits), \ | ||
400 | MAX1363_CHAN_B(5, 4, d5m4, 20, bits), \ | ||
401 | MAX1363_CHAN_B(7, 6, d7m6, 21, bits), \ | ||
402 | MAX1363_CHAN_B(9, 8, d9m8, 22, bits), \ | ||
403 | MAX1363_CHAN_B(11, 10, d11m10, 23, bits), \ | ||
404 | IIO_CHAN_SOFT_TIMESTAMP(24) \ | ||
405 | } | ||
406 | static struct iio_chan_spec max1038_channels[] = MAX1363_12X_CHANS(8); | ||
407 | static struct iio_chan_spec max1138_channels[] = MAX1363_12X_CHANS(10); | ||
408 | static struct iio_chan_spec max1238_channels[] = MAX1363_12X_CHANS(12); | ||
409 | |||
410 | static const enum max1363_modes max11607_mode_list[] = { | ||
411 | _s0, _s1, _s2, _s3, | ||
412 | s0to1, s0to2, s0to3, | ||
413 | s2to3, | ||
414 | d0m1, d2m3, d1m0, d3m2, | ||
415 | d0m1to2m3, d1m0to3m2, | ||
416 | }; | ||
417 | |||
418 | static const enum max1363_modes max11608_mode_list[] = { | ||
419 | _s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, | ||
420 | s0to1, s0to2, s0to3, s0to4, s0to5, s0to6, s0to7, | ||
421 | s6to7, | ||
422 | d0m1, d2m3, d4m5, d6m7, | ||
423 | d1m0, d3m2, d5m4, d7m6, | ||
424 | d0m1to2m3, d0m1to4m5, d0m1to6m7, | ||
425 | d1m0to3m2, d1m0to5m4, d1m0to7m6, | ||
426 | }; | ||
427 | |||
428 | #define MAX1363_8X_CHANS(bits) { \ | ||
429 | MAX1363_CHAN_U(0, _s0, 0, bits), \ | ||
430 | MAX1363_CHAN_U(1, _s1, 1, bits), \ | ||
431 | MAX1363_CHAN_U(2, _s2, 2, bits), \ | ||
432 | MAX1363_CHAN_U(3, _s3, 3, bits), \ | ||
433 | MAX1363_CHAN_U(4, _s4, 4, bits), \ | ||
434 | MAX1363_CHAN_U(5, _s5, 5, bits), \ | ||
435 | MAX1363_CHAN_U(6, _s6, 6, bits), \ | ||
436 | MAX1363_CHAN_U(7, _s7, 7, bits), \ | ||
437 | MAX1363_CHAN_B(0, 1, d0m1, 8, bits), \ | ||
438 | MAX1363_CHAN_B(2, 3, d2m3, 9, bits), \ | ||
439 | MAX1363_CHAN_B(4, 5, d4m5, 10, bits), \ | ||
440 | MAX1363_CHAN_B(6, 7, d6m7, 11, bits), \ | ||
441 | MAX1363_CHAN_B(1, 0, d1m0, 12, bits), \ | ||
442 | MAX1363_CHAN_B(3, 2, d3m2, 13, bits), \ | ||
443 | MAX1363_CHAN_B(5, 4, d5m4, 14, bits), \ | ||
444 | MAX1363_CHAN_B(7, 6, d7m6, 15, bits), \ | ||
445 | IIO_CHAN_SOFT_TIMESTAMP(16) \ | ||
446 | } | ||
447 | static struct iio_chan_spec max11602_channels[] = MAX1363_8X_CHANS(8); | ||
448 | static struct iio_chan_spec max11608_channels[] = MAX1363_8X_CHANS(10); | ||
449 | static struct iio_chan_spec max11614_channels[] = MAX1363_8X_CHANS(12); | ||
450 | |||
451 | static const enum max1363_modes max11644_mode_list[] = { | ||
452 | _s0, _s1, s0to1, d0m1, d1m0, | ||
453 | }; | ||
454 | |||
455 | #define MAX1363_2X_CHANS(bits) { \ | ||
456 | MAX1363_CHAN_U(0, _s0, 0, bits), \ | ||
457 | MAX1363_CHAN_U(1, _s1, 1, bits), \ | ||
458 | MAX1363_CHAN_B(0, 1, d0m1, 2, bits), \ | ||
459 | MAX1363_CHAN_B(1, 0, d1m0, 3, bits), \ | ||
460 | IIO_CHAN_SOFT_TIMESTAMP(4) \ | ||
461 | } | ||
462 | |||
463 | static struct iio_chan_spec max11646_channels[] = MAX1363_2X_CHANS(10); | ||
464 | static struct iio_chan_spec max11644_channels[] = MAX1363_2X_CHANS(12); | ||
465 | |||
466 | enum { max1361, | ||
467 | max1362, | ||
468 | max1363, | ||
469 | max1364, | ||
470 | max1036, | ||
471 | max1037, | ||
472 | max1038, | ||
473 | max1039, | ||
474 | max1136, | ||
475 | max1137, | ||
476 | max1138, | ||
477 | max1139, | ||
478 | max1236, | ||
479 | max1237, | ||
480 | max1238, | ||
481 | max1239, | ||
482 | max11600, | ||
483 | max11601, | ||
484 | max11602, | ||
485 | max11603, | ||
486 | max11604, | ||
487 | max11605, | ||
488 | max11606, | ||
489 | max11607, | ||
490 | max11608, | ||
491 | max11609, | ||
492 | max11610, | ||
493 | max11611, | ||
494 | max11612, | ||
495 | max11613, | ||
496 | max11614, | ||
497 | max11615, | ||
498 | max11616, | ||
499 | max11617, | ||
500 | max11644, | ||
501 | max11645, | ||
502 | max11646, | ||
503 | max11647 | ||
504 | }; | ||
505 | |||
506 | static const int max1363_monitor_speeds[] = { 133000, 665000, 33300, 16600, | ||
507 | 8300, 4200, 2000, 1000 }; | ||
508 | |||
509 | static ssize_t max1363_monitor_show_freq(struct device *dev, | ||
510 | struct device_attribute *attr, | ||
511 | char *buf) | ||
512 | { | ||
513 | struct max1363_state *st = iio_priv(dev_get_drvdata(dev)); | ||
514 | return sprintf(buf, "%d\n", max1363_monitor_speeds[st->monitor_speed]); | ||
515 | } | ||
516 | |||
517 | static ssize_t max1363_monitor_store_freq(struct device *dev, | ||
518 | struct device_attribute *attr, | ||
519 | const char *buf, | ||
520 | size_t len) | ||
521 | { | ||
522 | struct iio_dev *indio_dev = dev_get_drvdata(dev); | ||
523 | struct max1363_state *st = iio_priv(indio_dev); | ||
524 | int i, ret; | ||
525 | unsigned long val; | ||
526 | bool found = false; | ||
527 | |||
528 | ret = strict_strtoul(buf, 10, &val); | ||
529 | if (ret) | ||
530 | return -EINVAL; | ||
531 | for (i = 0; i < ARRAY_SIZE(max1363_monitor_speeds); i++) | ||
532 | if (val == max1363_monitor_speeds[i]) { | ||
533 | found = true; | ||
534 | break; | ||
535 | } | ||
536 | if (!found) | ||
537 | return -EINVAL; | ||
538 | |||
539 | mutex_lock(&indio_dev->mlock); | ||
540 | st->monitor_speed = i; | ||
541 | mutex_unlock(&indio_dev->mlock); | ||
542 | |||
543 | return 0; | ||
544 | } | ||
545 | |||
546 | static IIO_DEV_ATTR_SAMP_FREQ(S_IRUGO | S_IWUSR, | ||
547 | max1363_monitor_show_freq, | ||
548 | max1363_monitor_store_freq); | ||
549 | |||
550 | static IIO_CONST_ATTR(sampling_frequency_available, | ||
551 | "133000 665000 33300 16600 8300 4200 2000 1000"); | ||
552 | |||
553 | static int max1363_read_thresh(struct iio_dev *indio_dev, | ||
554 | int event_code, | ||
555 | int *val) | ||
556 | { | ||
557 | struct max1363_state *st = iio_priv(indio_dev); | ||
558 | if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_FALLING) | ||
559 | *val = st->thresh_low[IIO_EVENT_CODE_EXTRACT_NUM(event_code)]; | ||
560 | else | ||
561 | *val = st->thresh_high[IIO_EVENT_CODE_EXTRACT_NUM(event_code)]; | ||
562 | return 0; | ||
563 | } | ||
564 | |||
565 | static int max1363_write_thresh(struct iio_dev *indio_dev, | ||
566 | int event_code, | ||
567 | int val) | ||
568 | { | ||
569 | struct max1363_state *st = iio_priv(indio_dev); | ||
570 | /* make it handle signed correctly as well */ | ||
571 | switch (st->chip_info->bits) { | ||
572 | case 10: | ||
573 | if (val > 0x3FF) | ||
574 | return -EINVAL; | ||
575 | break; | ||
576 | case 12: | ||
577 | if (val > 0xFFF) | ||
578 | return -EINVAL; | ||
579 | break; | ||
580 | } | ||
581 | |||
582 | switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) { | ||
583 | case IIO_EV_DIR_FALLING: | ||
584 | st->thresh_low[IIO_EVENT_CODE_EXTRACT_NUM(event_code)] = val; | ||
585 | break; | ||
586 | case IIO_EV_DIR_RISING: | ||
587 | st->thresh_high[IIO_EVENT_CODE_EXTRACT_NUM(event_code)] = val; | ||
588 | break; | ||
589 | } | ||
590 | |||
591 | return 0; | ||
592 | } | ||
593 | |||
594 | static const int max1363_event_codes[] = { | ||
595 | IIO_EVENT_CODE_IN_LOW_THRESH(3), IIO_EVENT_CODE_IN_HIGH_THRESH(3), | ||
596 | IIO_EVENT_CODE_IN_LOW_THRESH(2), IIO_EVENT_CODE_IN_HIGH_THRESH(2), | ||
597 | IIO_EVENT_CODE_IN_LOW_THRESH(1), IIO_EVENT_CODE_IN_HIGH_THRESH(1), | ||
598 | IIO_EVENT_CODE_IN_LOW_THRESH(0), IIO_EVENT_CODE_IN_HIGH_THRESH(0) | ||
599 | }; | ||
600 | |||
601 | static irqreturn_t max1363_event_handler(int irq, void *private) | ||
602 | { | ||
603 | struct iio_dev *indio_dev = private; | ||
604 | struct max1363_state *st = iio_priv(indio_dev); | ||
605 | s64 timestamp = iio_get_time_ns(); | ||
606 | unsigned long mask, loc; | ||
607 | u8 rx; | ||
608 | u8 tx[2] = { st->setupbyte, | ||
609 | MAX1363_MON_INT_ENABLE | (st->monitor_speed << 1) | 0xF0 }; | ||
610 | |||
611 | i2c_master_recv(st->client, &rx, 1); | ||
612 | mask = rx; | ||
613 | for_each_set_bit(loc, &mask, 8) | ||
614 | iio_push_event(indio_dev, 0, max1363_event_codes[loc], | ||
615 | timestamp); | ||
616 | i2c_master_send(st->client, tx, 2); | ||
617 | |||
618 | return IRQ_HANDLED; | ||
619 | } | ||
620 | |||
621 | static int max1363_read_event_config(struct iio_dev *indio_dev, | ||
622 | int event_code) | ||
623 | { | ||
624 | struct max1363_state *st = iio_priv(indio_dev); | ||
625 | |||
626 | int val; | ||
627 | int number = IIO_EVENT_CODE_EXTRACT_NUM(event_code); | ||
628 | mutex_lock(&indio_dev->mlock); | ||
629 | if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_FALLING) | ||
630 | val = (1 << number) & st->mask_low; | ||
631 | else | ||
632 | val = (1 << number) & st->mask_high; | ||
633 | mutex_unlock(&indio_dev->mlock); | ||
634 | |||
635 | return val; | ||
636 | } | ||
637 | |||
638 | static int max1363_monitor_mode_update(struct max1363_state *st, int enabled) | ||
639 | { | ||
640 | u8 *tx_buf; | ||
641 | int ret, i = 3, j; | ||
642 | unsigned long numelements; | ||
643 | int len; | ||
644 | long modemask; | ||
645 | |||
646 | if (!enabled) { | ||
647 | /* transition to ring capture is not currently supported */ | ||
648 | st->setupbyte &= ~MAX1363_SETUP_MONITOR_SETUP; | ||
649 | st->configbyte &= ~MAX1363_SCAN_MASK; | ||
650 | st->monitor_on = false; | ||
651 | return max1363_write_basic_config(st->client, | ||
652 | st->setupbyte, | ||
653 | st->configbyte); | ||
654 | } | ||
655 | |||
656 | /* Ensure we are in the relevant mode */ | ||
657 | st->setupbyte |= MAX1363_SETUP_MONITOR_SETUP; | ||
658 | st->configbyte &= ~(MAX1363_CHANNEL_SEL_MASK | ||
659 | | MAX1363_SCAN_MASK | ||
660 | | MAX1363_SE_DE_MASK); | ||
661 | st->configbyte |= MAX1363_CONFIG_SCAN_MONITOR_MODE; | ||
662 | if ((st->mask_low | st->mask_high) & 0x0F) { | ||
663 | st->configbyte |= max1363_mode_table[s0to3].conf; | ||
664 | modemask = max1363_mode_table[s0to3].modemask; | ||
665 | } else if ((st->mask_low | st->mask_high) & 0x30) { | ||
666 | st->configbyte |= max1363_mode_table[d0m1to2m3].conf; | ||
667 | modemask = max1363_mode_table[d0m1to2m3].modemask; | ||
668 | } else { | ||
669 | st->configbyte |= max1363_mode_table[d1m0to3m2].conf; | ||
670 | modemask = max1363_mode_table[d1m0to3m2].modemask; | ||
671 | } | ||
672 | numelements = hweight_long(modemask); | ||
673 | len = 3 * numelements + 3; | ||
674 | tx_buf = kmalloc(len, GFP_KERNEL); | ||
675 | if (!tx_buf) { | ||
676 | ret = -ENOMEM; | ||
677 | goto error_ret; | ||
678 | } | ||
679 | tx_buf[0] = st->configbyte; | ||
680 | tx_buf[1] = st->setupbyte; | ||
681 | tx_buf[2] = (st->monitor_speed << 1); | ||
682 | |||
683 | /* | ||
684 | * So we need to do yet another bit of nefarious scan mode | ||
685 | * setup to match what we need. | ||
686 | */ | ||
687 | for (j = 0; j < 8; j++) | ||
688 | if (modemask & (1 << j)) { | ||
689 | /* Establish the mode is in the scan */ | ||
690 | if (st->mask_low & (1 << j)) { | ||
691 | tx_buf[i] = (st->thresh_low[j] >> 4) & 0xFF; | ||
692 | tx_buf[i + 1] = (st->thresh_low[j] << 4) & 0xF0; | ||
693 | } else if (j < 4) { | ||
694 | tx_buf[i] = 0; | ||
695 | tx_buf[i + 1] = 0; | ||
696 | } else { | ||
697 | tx_buf[i] = 0x80; | ||
698 | tx_buf[i + 1] = 0; | ||
699 | } | ||
700 | if (st->mask_high & (1 << j)) { | ||
701 | tx_buf[i + 1] |= | ||
702 | (st->thresh_high[j] >> 8) & 0x0F; | ||
703 | tx_buf[i + 2] = st->thresh_high[j] & 0xFF; | ||
704 | } else if (j < 4) { | ||
705 | tx_buf[i + 1] |= 0x0F; | ||
706 | tx_buf[i + 2] = 0xFF; | ||
707 | } else { | ||
708 | tx_buf[i + 1] |= 0x07; | ||
709 | tx_buf[i + 2] = 0xFF; | ||
710 | } | ||
711 | i += 3; | ||
712 | } | ||
713 | |||
714 | |||
715 | ret = i2c_master_send(st->client, tx_buf, len); | ||
716 | if (ret < 0) | ||
717 | goto error_ret; | ||
718 | if (ret != len) { | ||
719 | ret = -EIO; | ||
720 | goto error_ret; | ||
721 | } | ||
722 | |||
723 | /* | ||
724 | * Now that we hopefully have sensible thresholds in place it is | ||
725 | * time to turn the interrupts on. | ||
726 | * It is unclear from the data sheet if this should be necessary | ||
727 | * (i.e. whether monitor mode setup is atomic) but it appears to | ||
728 | * be in practice. | ||
729 | */ | ||
730 | tx_buf[0] = st->setupbyte; | ||
731 | tx_buf[1] = MAX1363_MON_INT_ENABLE | (st->monitor_speed << 1) | 0xF0; | ||
732 | ret = i2c_master_send(st->client, tx_buf, 2); | ||
733 | if (ret < 0) | ||
734 | goto error_ret; | ||
735 | if (ret != 2) { | ||
736 | ret = -EIO; | ||
737 | goto error_ret; | ||
738 | } | ||
739 | ret = 0; | ||
740 | st->monitor_on = true; | ||
741 | error_ret: | ||
742 | |||
743 | kfree(tx_buf); | ||
744 | |||
745 | return ret; | ||
746 | } | ||
747 | |||
748 | /* | ||
749 | * To keep this manageable we always use one of 3 scan modes. | ||
750 | * Scan 0...3, 0-1,2-3 and 1-0,3-2 | ||
751 | */ | ||
752 | |||
753 | static inline int __max1363_check_event_mask(int thismask, int checkmask) | ||
754 | { | ||
755 | int ret = 0; | ||
756 | /* Is it unipolar */ | ||
757 | if (thismask < 4) { | ||
758 | if (checkmask & ~0x0F) { | ||
759 | ret = -EBUSY; | ||
760 | goto error_ret; | ||
761 | } | ||
762 | } else if (thismask < 6) { | ||
763 | if (checkmask & ~0x30) { | ||
764 | ret = -EBUSY; | ||
765 | goto error_ret; | ||
766 | } | ||
767 | } else if (checkmask & ~0xC0) | ||
768 | ret = -EBUSY; | ||
769 | error_ret: | ||
770 | return ret; | ||
771 | } | ||
772 | |||
773 | static int max1363_write_event_config(struct iio_dev *indio_dev, | ||
774 | int event_code, | ||
775 | int state) | ||
776 | { | ||
777 | int ret = 0; | ||
778 | struct max1363_state *st = iio_priv(indio_dev); | ||
779 | u16 unifiedmask; | ||
780 | int number = IIO_EVENT_CODE_EXTRACT_NUM(event_code); | ||
781 | |||
782 | mutex_lock(&indio_dev->mlock); | ||
783 | unifiedmask = st->mask_low | st->mask_high; | ||
784 | if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_FALLING) { | ||
785 | |||
786 | if (state == 0) | ||
787 | st->mask_low &= ~(1 << number); | ||
788 | else { | ||
789 | ret = __max1363_check_event_mask((1 << number), | ||
790 | unifiedmask); | ||
791 | if (ret) | ||
792 | goto error_ret; | ||
793 | st->mask_low |= (1 << number); | ||
794 | } | ||
795 | } else { | ||
796 | if (state == 0) | ||
797 | st->mask_high &= ~(1 << number); | ||
798 | else { | ||
799 | ret = __max1363_check_event_mask((1 << number), | ||
800 | unifiedmask); | ||
801 | if (ret) | ||
802 | goto error_ret; | ||
803 | st->mask_high |= (1 << number); | ||
804 | } | ||
805 | } | ||
806 | |||
807 | max1363_monitor_mode_update(st, !!(st->mask_high | st->mask_low)); | ||
808 | error_ret: | ||
809 | mutex_unlock(&indio_dev->mlock); | ||
810 | |||
811 | return ret; | ||
812 | } | ||
813 | |||
814 | /* | ||
815 | * As with scan_elements, only certain sets of these can | ||
816 | * be combined. | ||
817 | */ | ||
818 | static struct attribute *max1363_event_attributes[] = { | ||
819 | &iio_dev_attr_sampling_frequency.dev_attr.attr, | ||
820 | &iio_const_attr_sampling_frequency_available.dev_attr.attr, | ||
821 | NULL, | ||
822 | }; | ||
823 | |||
824 | static struct attribute_group max1363_event_attribute_group = { | ||
825 | .attrs = max1363_event_attributes, | ||
826 | }; | ||
827 | |||
828 | #define MAX1363_EVENT_FUNCS \ | ||
829 | |||
830 | |||
831 | static const struct iio_info max1238_info = { | ||
832 | .read_raw = &max1363_read_raw, | ||
833 | .driver_module = THIS_MODULE, | ||
834 | }; | ||
835 | |||
836 | static const struct iio_info max1363_info = { | ||
837 | .read_event_value = &max1363_read_thresh, | ||
838 | .write_event_value = &max1363_write_thresh, | ||
839 | .read_event_config = &max1363_read_event_config, | ||
840 | .write_event_config = &max1363_write_event_config, | ||
841 | .read_raw = &max1363_read_raw, | ||
842 | .driver_module = THIS_MODULE, | ||
843 | .num_interrupt_lines = 1, | ||
844 | .event_attrs = &max1363_event_attribute_group, | ||
845 | }; | ||
846 | |||
847 | /* max1363 and max1368 tested - rest from data sheet */ | ||
848 | static const struct max1363_chip_info max1363_chip_info_tbl[] = { | ||
849 | [max1361] = { | ||
850 | .bits = 10, | ||
851 | .int_vref_mv = 2048, | ||
852 | .mode_list = max1363_mode_list, | ||
853 | .num_modes = ARRAY_SIZE(max1363_mode_list), | ||
854 | .default_mode = s0to3, | ||
855 | .channels = max1361_channels, | ||
856 | .num_channels = ARRAY_SIZE(max1361_channels), | ||
857 | .info = &max1363_info, | ||
858 | }, | ||
859 | [max1362] = { | ||
860 | .bits = 10, | ||
861 | .int_vref_mv = 4096, | ||
862 | .mode_list = max1363_mode_list, | ||
863 | .num_modes = ARRAY_SIZE(max1363_mode_list), | ||
864 | .default_mode = s0to3, | ||
865 | .channels = max1361_channels, | ||
866 | .num_channels = ARRAY_SIZE(max1361_channels), | ||
867 | .info = &max1363_info, | ||
868 | }, | ||
869 | [max1363] = { | ||
870 | .bits = 12, | ||
871 | .int_vref_mv = 2048, | ||
872 | .mode_list = max1363_mode_list, | ||
873 | .num_modes = ARRAY_SIZE(max1363_mode_list), | ||
874 | .default_mode = s0to3, | ||
875 | .channels = max1363_channels, | ||
876 | .num_channels = ARRAY_SIZE(max1363_channels), | ||
877 | .info = &max1363_info, | ||
878 | }, | ||
879 | [max1364] = { | ||
880 | .bits = 12, | ||
881 | .int_vref_mv = 4096, | ||
882 | .mode_list = max1363_mode_list, | ||
883 | .num_modes = ARRAY_SIZE(max1363_mode_list), | ||
884 | .default_mode = s0to3, | ||
885 | .channels = max1363_channels, | ||
886 | .num_channels = ARRAY_SIZE(max1363_channels), | ||
887 | .info = &max1363_info, | ||
888 | }, | ||
889 | [max1036] = { | ||
890 | .bits = 8, | ||
891 | .int_vref_mv = 4096, | ||
892 | .mode_list = max1236_mode_list, | ||
893 | .num_modes = ARRAY_SIZE(max1236_mode_list), | ||
894 | .default_mode = s0to3, | ||
895 | .info = &max1238_info, | ||
896 | .channels = max1036_channels, | ||
897 | .num_channels = ARRAY_SIZE(max1036_channels), | ||
898 | }, | ||
899 | [max1037] = { | ||
900 | .bits = 8, | ||
901 | .int_vref_mv = 2048, | ||
902 | .mode_list = max1236_mode_list, | ||
903 | .num_modes = ARRAY_SIZE(max1236_mode_list), | ||
904 | .default_mode = s0to3, | ||
905 | .info = &max1238_info, | ||
906 | .channels = max1036_channels, | ||
907 | .num_channels = ARRAY_SIZE(max1036_channels), | ||
908 | }, | ||
909 | [max1038] = { | ||
910 | .bits = 8, | ||
911 | .int_vref_mv = 4096, | ||
912 | .mode_list = max1238_mode_list, | ||
913 | .num_modes = ARRAY_SIZE(max1238_mode_list), | ||
914 | .default_mode = s0to11, | ||
915 | .info = &max1238_info, | ||
916 | .channels = max1038_channels, | ||
917 | .num_channels = ARRAY_SIZE(max1038_channels), | ||
918 | }, | ||
919 | [max1039] = { | ||
920 | .bits = 8, | ||
921 | .int_vref_mv = 2048, | ||
922 | .mode_list = max1238_mode_list, | ||
923 | .num_modes = ARRAY_SIZE(max1238_mode_list), | ||
924 | .default_mode = s0to11, | ||
925 | .info = &max1238_info, | ||
926 | .channels = max1038_channels, | ||
927 | .num_channels = ARRAY_SIZE(max1038_channels), | ||
928 | }, | ||
929 | [max1136] = { | ||
930 | .bits = 10, | ||
931 | .int_vref_mv = 4096, | ||
932 | .mode_list = max1236_mode_list, | ||
933 | .num_modes = ARRAY_SIZE(max1236_mode_list), | ||
934 | .default_mode = s0to3, | ||
935 | .info = &max1238_info, | ||
936 | .channels = max1136_channels, | ||
937 | .num_channels = ARRAY_SIZE(max1136_channels), | ||
938 | }, | ||
939 | [max1137] = { | ||
940 | .bits = 10, | ||
941 | .int_vref_mv = 2048, | ||
942 | .mode_list = max1236_mode_list, | ||
943 | .num_modes = ARRAY_SIZE(max1236_mode_list), | ||
944 | .default_mode = s0to3, | ||
945 | .info = &max1238_info, | ||
946 | .channels = max1136_channels, | ||
947 | .num_channels = ARRAY_SIZE(max1136_channels), | ||
948 | }, | ||
949 | [max1138] = { | ||
950 | .bits = 10, | ||
951 | .int_vref_mv = 4096, | ||
952 | .mode_list = max1238_mode_list, | ||
953 | .num_modes = ARRAY_SIZE(max1238_mode_list), | ||
954 | .default_mode = s0to11, | ||
955 | .info = &max1238_info, | ||
956 | .channels = max1138_channels, | ||
957 | .num_channels = ARRAY_SIZE(max1138_channels), | ||
958 | }, | ||
959 | [max1139] = { | ||
960 | .bits = 10, | ||
961 | .int_vref_mv = 2048, | ||
962 | .mode_list = max1238_mode_list, | ||
963 | .num_modes = ARRAY_SIZE(max1238_mode_list), | ||
964 | .default_mode = s0to11, | ||
965 | .info = &max1238_info, | ||
966 | .channels = max1138_channels, | ||
967 | .num_channels = ARRAY_SIZE(max1138_channels), | ||
968 | }, | ||
969 | [max1236] = { | ||
970 | .bits = 12, | ||
971 | .int_vref_mv = 4096, | ||
972 | .mode_list = max1236_mode_list, | ||
973 | .num_modes = ARRAY_SIZE(max1236_mode_list), | ||
974 | .default_mode = s0to3, | ||
975 | .info = &max1238_info, | ||
976 | .channels = max1236_channels, | ||
977 | .num_channels = ARRAY_SIZE(max1236_channels), | ||
978 | }, | ||
979 | [max1237] = { | ||
980 | .bits = 12, | ||
981 | .int_vref_mv = 2048, | ||
982 | .mode_list = max1236_mode_list, | ||
983 | .num_modes = ARRAY_SIZE(max1236_mode_list), | ||
984 | .default_mode = s0to3, | ||
985 | .info = &max1238_info, | ||
986 | .channels = max1236_channels, | ||
987 | .num_channels = ARRAY_SIZE(max1236_channels), | ||
988 | }, | ||
989 | [max1238] = { | ||
990 | .bits = 12, | ||
991 | .int_vref_mv = 4096, | ||
992 | .mode_list = max1238_mode_list, | ||
993 | .num_modes = ARRAY_SIZE(max1238_mode_list), | ||
994 | .default_mode = s0to11, | ||
995 | .info = &max1238_info, | ||
996 | .channels = max1238_channels, | ||
997 | .num_channels = ARRAY_SIZE(max1238_channels), | ||
998 | }, | ||
999 | [max1239] = { | ||
1000 | .bits = 12, | ||
1001 | .int_vref_mv = 2048, | ||
1002 | .mode_list = max1238_mode_list, | ||
1003 | .num_modes = ARRAY_SIZE(max1238_mode_list), | ||
1004 | .default_mode = s0to11, | ||
1005 | .info = &max1238_info, | ||
1006 | .channels = max1238_channels, | ||
1007 | .num_channels = ARRAY_SIZE(max1238_channels), | ||
1008 | }, | ||
1009 | [max11600] = { | ||
1010 | .bits = 8, | ||
1011 | .int_vref_mv = 4096, | ||
1012 | .mode_list = max11607_mode_list, | ||
1013 | .num_modes = ARRAY_SIZE(max11607_mode_list), | ||
1014 | .default_mode = s0to3, | ||
1015 | .info = &max1238_info, | ||
1016 | .channels = max1036_channels, | ||
1017 | .num_channels = ARRAY_SIZE(max1036_channels), | ||
1018 | }, | ||
1019 | [max11601] = { | ||
1020 | .bits = 8, | ||
1021 | .int_vref_mv = 2048, | ||
1022 | .mode_list = max11607_mode_list, | ||
1023 | .num_modes = ARRAY_SIZE(max11607_mode_list), | ||
1024 | .default_mode = s0to3, | ||
1025 | .info = &max1238_info, | ||
1026 | .channels = max1036_channels, | ||
1027 | .num_channels = ARRAY_SIZE(max1036_channels), | ||
1028 | }, | ||
1029 | [max11602] = { | ||
1030 | .bits = 8, | ||
1031 | .int_vref_mv = 4096, | ||
1032 | .mode_list = max11608_mode_list, | ||
1033 | .num_modes = ARRAY_SIZE(max11608_mode_list), | ||
1034 | .default_mode = s0to7, | ||
1035 | .info = &max1238_info, | ||
1036 | .channels = max11602_channels, | ||
1037 | .num_channels = ARRAY_SIZE(max11602_channels), | ||
1038 | }, | ||
1039 | [max11603] = { | ||
1040 | .bits = 8, | ||
1041 | .int_vref_mv = 2048, | ||
1042 | .mode_list = max11608_mode_list, | ||
1043 | .num_modes = ARRAY_SIZE(max11608_mode_list), | ||
1044 | .default_mode = s0to7, | ||
1045 | .info = &max1238_info, | ||
1046 | .channels = max11602_channels, | ||
1047 | .num_channels = ARRAY_SIZE(max11602_channels), | ||
1048 | }, | ||
1049 | [max11604] = { | ||
1050 | .bits = 8, | ||
1051 | .int_vref_mv = 4098, | ||
1052 | .mode_list = max1238_mode_list, | ||
1053 | .num_modes = ARRAY_SIZE(max1238_mode_list), | ||
1054 | .default_mode = s0to11, | ||
1055 | .info = &max1238_info, | ||
1056 | .channels = max1238_channels, | ||
1057 | .num_channels = ARRAY_SIZE(max1238_channels), | ||
1058 | }, | ||
1059 | [max11605] = { | ||
1060 | .bits = 8, | ||
1061 | .int_vref_mv = 2048, | ||
1062 | .mode_list = max1238_mode_list, | ||
1063 | .num_modes = ARRAY_SIZE(max1238_mode_list), | ||
1064 | .default_mode = s0to11, | ||
1065 | .info = &max1238_info, | ||
1066 | .channels = max1238_channels, | ||
1067 | .num_channels = ARRAY_SIZE(max1238_channels), | ||
1068 | }, | ||
1069 | [max11606] = { | ||
1070 | .bits = 10, | ||
1071 | .int_vref_mv = 4096, | ||
1072 | .mode_list = max11607_mode_list, | ||
1073 | .num_modes = ARRAY_SIZE(max11607_mode_list), | ||
1074 | .default_mode = s0to3, | ||
1075 | .info = &max1238_info, | ||
1076 | .channels = max1136_channels, | ||
1077 | .num_channels = ARRAY_SIZE(max1136_channels), | ||
1078 | }, | ||
1079 | [max11607] = { | ||
1080 | .bits = 10, | ||
1081 | .int_vref_mv = 2048, | ||
1082 | .mode_list = max11607_mode_list, | ||
1083 | .num_modes = ARRAY_SIZE(max11607_mode_list), | ||
1084 | .default_mode = s0to3, | ||
1085 | .info = &max1238_info, | ||
1086 | .channels = max1136_channels, | ||
1087 | .num_channels = ARRAY_SIZE(max1136_channels), | ||
1088 | }, | ||
1089 | [max11608] = { | ||
1090 | .bits = 10, | ||
1091 | .int_vref_mv = 4096, | ||
1092 | .mode_list = max11608_mode_list, | ||
1093 | .num_modes = ARRAY_SIZE(max11608_mode_list), | ||
1094 | .default_mode = s0to7, | ||
1095 | .info = &max1238_info, | ||
1096 | .channels = max11608_channels, | ||
1097 | .num_channels = ARRAY_SIZE(max11608_channels), | ||
1098 | }, | ||
1099 | [max11609] = { | ||
1100 | .bits = 10, | ||
1101 | .int_vref_mv = 2048, | ||
1102 | .mode_list = max11608_mode_list, | ||
1103 | .num_modes = ARRAY_SIZE(max11608_mode_list), | ||
1104 | .default_mode = s0to7, | ||
1105 | .info = &max1238_info, | ||
1106 | .channels = max11608_channels, | ||
1107 | .num_channels = ARRAY_SIZE(max11608_channels), | ||
1108 | }, | ||
1109 | [max11610] = { | ||
1110 | .bits = 10, | ||
1111 | .int_vref_mv = 4098, | ||
1112 | .mode_list = max1238_mode_list, | ||
1113 | .num_modes = ARRAY_SIZE(max1238_mode_list), | ||
1114 | .default_mode = s0to11, | ||
1115 | .info = &max1238_info, | ||
1116 | .channels = max1238_channels, | ||
1117 | .num_channels = ARRAY_SIZE(max1238_channels), | ||
1118 | }, | ||
1119 | [max11611] = { | ||
1120 | .bits = 10, | ||
1121 | .int_vref_mv = 2048, | ||
1122 | .mode_list = max1238_mode_list, | ||
1123 | .num_modes = ARRAY_SIZE(max1238_mode_list), | ||
1124 | .default_mode = s0to11, | ||
1125 | .info = &max1238_info, | ||
1126 | .channels = max1238_channels, | ||
1127 | .num_channels = ARRAY_SIZE(max1238_channels), | ||
1128 | }, | ||
1129 | [max11612] = { | ||
1130 | .bits = 12, | ||
1131 | .int_vref_mv = 4096, | ||
1132 | .mode_list = max11607_mode_list, | ||
1133 | .num_modes = ARRAY_SIZE(max11607_mode_list), | ||
1134 | .default_mode = s0to3, | ||
1135 | .info = &max1238_info, | ||
1136 | .channels = max1363_channels, | ||
1137 | .num_channels = ARRAY_SIZE(max1363_channels), | ||
1138 | }, | ||
1139 | [max11613] = { | ||
1140 | .bits = 12, | ||
1141 | .int_vref_mv = 2048, | ||
1142 | .mode_list = max11607_mode_list, | ||
1143 | .num_modes = ARRAY_SIZE(max11607_mode_list), | ||
1144 | .default_mode = s0to3, | ||
1145 | .info = &max1238_info, | ||
1146 | .channels = max1363_channels, | ||
1147 | .num_channels = ARRAY_SIZE(max1363_channels), | ||
1148 | }, | ||
1149 | [max11614] = { | ||
1150 | .bits = 12, | ||
1151 | .int_vref_mv = 4096, | ||
1152 | .mode_list = max11608_mode_list, | ||
1153 | .num_modes = ARRAY_SIZE(max11608_mode_list), | ||
1154 | .default_mode = s0to7, | ||
1155 | .info = &max1238_info, | ||
1156 | .channels = max11614_channels, | ||
1157 | .num_channels = ARRAY_SIZE(max11614_channels), | ||
1158 | }, | ||
1159 | [max11615] = { | ||
1160 | .bits = 12, | ||
1161 | .int_vref_mv = 2048, | ||
1162 | .mode_list = max11608_mode_list, | ||
1163 | .num_modes = ARRAY_SIZE(max11608_mode_list), | ||
1164 | .default_mode = s0to7, | ||
1165 | .info = &max1238_info, | ||
1166 | .channels = max11614_channels, | ||
1167 | .num_channels = ARRAY_SIZE(max11614_channels), | ||
1168 | }, | ||
1169 | [max11616] = { | ||
1170 | .bits = 12, | ||
1171 | .int_vref_mv = 4098, | ||
1172 | .mode_list = max1238_mode_list, | ||
1173 | .num_modes = ARRAY_SIZE(max1238_mode_list), | ||
1174 | .default_mode = s0to11, | ||
1175 | .info = &max1238_info, | ||
1176 | .channels = max1238_channels, | ||
1177 | .num_channels = ARRAY_SIZE(max1238_channels), | ||
1178 | }, | ||
1179 | [max11617] = { | ||
1180 | .bits = 12, | ||
1181 | .int_vref_mv = 2048, | ||
1182 | .mode_list = max1238_mode_list, | ||
1183 | .num_modes = ARRAY_SIZE(max1238_mode_list), | ||
1184 | .default_mode = s0to11, | ||
1185 | .info = &max1238_info, | ||
1186 | .channels = max1238_channels, | ||
1187 | .num_channels = ARRAY_SIZE(max1238_channels), | ||
1188 | }, | ||
1189 | [max11644] = { | ||
1190 | .bits = 12, | ||
1191 | .int_vref_mv = 2048, | ||
1192 | .mode_list = max11644_mode_list, | ||
1193 | .num_modes = ARRAY_SIZE(max11644_mode_list), | ||
1194 | .default_mode = s0to1, | ||
1195 | .info = &max1238_info, | ||
1196 | .channels = max11644_channels, | ||
1197 | .num_channels = ARRAY_SIZE(max11644_channels), | ||
1198 | }, | ||
1199 | [max11645] = { | ||
1200 | .bits = 12, | ||
1201 | .int_vref_mv = 4096, | ||
1202 | .mode_list = max11644_mode_list, | ||
1203 | .num_modes = ARRAY_SIZE(max11644_mode_list), | ||
1204 | .default_mode = s0to1, | ||
1205 | .info = &max1238_info, | ||
1206 | .channels = max11644_channels, | ||
1207 | .num_channels = ARRAY_SIZE(max11644_channels), | ||
1208 | }, | ||
1209 | [max11646] = { | ||
1210 | .bits = 10, | ||
1211 | .int_vref_mv = 2048, | ||
1212 | .mode_list = max11644_mode_list, | ||
1213 | .num_modes = ARRAY_SIZE(max11644_mode_list), | ||
1214 | .default_mode = s0to1, | ||
1215 | .info = &max1238_info, | ||
1216 | .channels = max11646_channels, | ||
1217 | .num_channels = ARRAY_SIZE(max11646_channels), | ||
1218 | }, | ||
1219 | [max11647] = { | ||
1220 | .bits = 10, | ||
1221 | .int_vref_mv = 4096, | ||
1222 | .mode_list = max11644_mode_list, | ||
1223 | .num_modes = ARRAY_SIZE(max11644_mode_list), | ||
1224 | .default_mode = s0to1, | ||
1225 | .info = &max1238_info, | ||
1226 | .channels = max11646_channels, | ||
1227 | .num_channels = ARRAY_SIZE(max11646_channels), | ||
1228 | }, | ||
1229 | }; | ||
1230 | |||
1231 | |||
1232 | |||
1233 | static int max1363_initial_setup(struct max1363_state *st) | ||
1234 | { | ||
1235 | st->setupbyte = MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_VDD | ||
1236 | | MAX1363_SETUP_POWER_UP_INT_REF | ||
1237 | | MAX1363_SETUP_INT_CLOCK | ||
1238 | | MAX1363_SETUP_UNIPOLAR | ||
1239 | | MAX1363_SETUP_NORESET; | ||
1240 | |||
1241 | /* Set scan mode writes the config anyway so wait until then*/ | ||
1242 | st->setupbyte = MAX1363_SETUP_BYTE(st->setupbyte); | ||
1243 | st->current_mode = &max1363_mode_table[st->chip_info->default_mode]; | ||
1244 | st->configbyte = MAX1363_CONFIG_BYTE(st->configbyte); | ||
1245 | |||
1246 | return max1363_set_scan_mode(st); | ||
1247 | } | ||
1248 | |||
1249 | static int __devinit max1363_probe(struct i2c_client *client, | ||
1250 | const struct i2c_device_id *id) | ||
1251 | { | ||
1252 | int ret, i, regdone = 0; | ||
1253 | struct max1363_state *st; | ||
1254 | struct iio_dev *indio_dev; | ||
1255 | struct regulator *reg; | ||
1256 | |||
1257 | reg = regulator_get(&client->dev, "vcc"); | ||
1258 | if (IS_ERR(reg)) { | ||
1259 | ret = PTR_ERR(reg); | ||
1260 | goto error_out; | ||
1261 | } | ||
1262 | |||
1263 | ret = regulator_enable(reg); | ||
1264 | if (ret) | ||
1265 | goto error_put_reg; | ||
1266 | |||
1267 | indio_dev = iio_allocate_device(sizeof(struct max1363_state)); | ||
1268 | if (indio_dev == NULL) { | ||
1269 | ret = -ENOMEM; | ||
1270 | goto error_disable_reg; | ||
1271 | } | ||
1272 | st = iio_priv(indio_dev); | ||
1273 | st->reg = reg; | ||
1274 | /* this is only used for device removal purposes */ | ||
1275 | i2c_set_clientdata(client, indio_dev); | ||
1276 | |||
1277 | st->chip_info = &max1363_chip_info_tbl[id->driver_data]; | ||
1278 | st->client = client; | ||
1279 | |||
1280 | indio_dev->available_scan_masks | ||
1281 | = kzalloc(sizeof(*indio_dev->available_scan_masks)* | ||
1282 | (st->chip_info->num_modes + 1), GFP_KERNEL); | ||
1283 | if (!indio_dev->available_scan_masks) { | ||
1284 | ret = -ENOMEM; | ||
1285 | goto error_free_device; | ||
1286 | } | ||
1287 | |||
1288 | for (i = 0; i < st->chip_info->num_modes; i++) | ||
1289 | indio_dev->available_scan_masks[i] = | ||
1290 | max1363_mode_table[st->chip_info->mode_list[i]] | ||
1291 | .modemask; | ||
1292 | /* Estabilish that the iio_dev is a child of the i2c device */ | ||
1293 | indio_dev->dev.parent = &client->dev; | ||
1294 | indio_dev->name = id->name; | ||
1295 | |||
1296 | indio_dev->info = st->chip_info->info; | ||
1297 | indio_dev->modes = INDIO_DIRECT_MODE; | ||
1298 | ret = max1363_initial_setup(st); | ||
1299 | if (ret < 0) | ||
1300 | goto error_free_available_scan_masks; | ||
1301 | |||
1302 | ret = max1363_register_ring_funcs_and_init(indio_dev); | ||
1303 | if (ret) | ||
1304 | goto error_free_available_scan_masks; | ||
1305 | |||
1306 | ret = iio_device_register(indio_dev); | ||
1307 | if (ret) | ||
1308 | goto error_cleanup_ring; | ||
1309 | regdone = 1; | ||
1310 | ret = iio_ring_buffer_register_ex(indio_dev->ring, 0, | ||
1311 | st->chip_info->channels, | ||
1312 | st->chip_info->num_channels); | ||
1313 | if (ret) | ||
1314 | goto error_cleanup_ring; | ||
1315 | |||
1316 | if (client->irq) { | ||
1317 | ret = request_threaded_irq(st->client->irq, | ||
1318 | NULL, | ||
1319 | &max1363_event_handler, | ||
1320 | IRQF_TRIGGER_RISING | IRQF_ONESHOT, | ||
1321 | "max1363_event", | ||
1322 | indio_dev); | ||
1323 | |||
1324 | if (ret) | ||
1325 | goto error_uninit_ring; | ||
1326 | } | ||
1327 | |||
1328 | return 0; | ||
1329 | |||
1330 | error_uninit_ring: | ||
1331 | iio_ring_buffer_unregister(indio_dev->ring); | ||
1332 | error_cleanup_ring: | ||
1333 | max1363_ring_cleanup(indio_dev); | ||
1334 | error_free_available_scan_masks: | ||
1335 | kfree(indio_dev->available_scan_masks); | ||
1336 | error_free_device: | ||
1337 | if (!regdone) | ||
1338 | iio_free_device(indio_dev); | ||
1339 | else | ||
1340 | iio_device_unregister(indio_dev); | ||
1341 | error_disable_reg: | ||
1342 | regulator_disable(reg); | ||
1343 | error_put_reg: | ||
1344 | regulator_put(reg); | ||
1345 | error_out: | ||
1346 | return ret; | ||
1347 | } | ||
1348 | |||
1349 | static int max1363_remove(struct i2c_client *client) | ||
1350 | { | ||
1351 | struct iio_dev *indio_dev = i2c_get_clientdata(client); | ||
1352 | struct max1363_state *st = iio_priv(indio_dev); | ||
1353 | struct regulator *reg = st->reg; | ||
1354 | |||
1355 | if (client->irq) | ||
1356 | free_irq(st->client->irq, indio_dev); | ||
1357 | iio_ring_buffer_unregister(indio_dev->ring); | ||
1358 | max1363_ring_cleanup(indio_dev); | ||
1359 | kfree(indio_dev->available_scan_masks); | ||
1360 | if (!IS_ERR(reg)) { | ||
1361 | regulator_disable(reg); | ||
1362 | regulator_put(reg); | ||
1363 | } | ||
1364 | iio_device_unregister(indio_dev); | ||
1365 | |||
1366 | return 0; | ||
1367 | } | ||
1368 | |||
1369 | static const struct i2c_device_id max1363_id[] = { | ||
1370 | { "max1361", max1361 }, | ||
1371 | { "max1362", max1362 }, | ||
1372 | { "max1363", max1363 }, | ||
1373 | { "max1364", max1364 }, | ||
1374 | { "max1036", max1036 }, | ||
1375 | { "max1037", max1037 }, | ||
1376 | { "max1038", max1038 }, | ||
1377 | { "max1039", max1039 }, | ||
1378 | { "max1136", max1136 }, | ||
1379 | { "max1137", max1137 }, | ||
1380 | { "max1138", max1138 }, | ||
1381 | { "max1139", max1139 }, | ||
1382 | { "max1236", max1236 }, | ||
1383 | { "max1237", max1237 }, | ||
1384 | { "max1238", max1238 }, | ||
1385 | { "max1239", max1239 }, | ||
1386 | { "max11600", max11600 }, | ||
1387 | { "max11601", max11601 }, | ||
1388 | { "max11602", max11602 }, | ||
1389 | { "max11603", max11603 }, | ||
1390 | { "max11604", max11604 }, | ||
1391 | { "max11605", max11605 }, | ||
1392 | { "max11606", max11606 }, | ||
1393 | { "max11607", max11607 }, | ||
1394 | { "max11608", max11608 }, | ||
1395 | { "max11609", max11609 }, | ||
1396 | { "max11610", max11610 }, | ||
1397 | { "max11611", max11611 }, | ||
1398 | { "max11612", max11612 }, | ||
1399 | { "max11613", max11613 }, | ||
1400 | { "max11614", max11614 }, | ||
1401 | { "max11615", max11615 }, | ||
1402 | { "max11616", max11616 }, | ||
1403 | { "max11617", max11617 }, | ||
1404 | {} | ||
1405 | }; | ||
1406 | |||
1407 | MODULE_DEVICE_TABLE(i2c, max1363_id); | ||
1408 | |||
1409 | static struct i2c_driver max1363_driver = { | ||
1410 | .driver = { | ||
1411 | .name = "max1363", | ||
1412 | }, | ||
1413 | .probe = max1363_probe, | ||
1414 | .remove = max1363_remove, | ||
1415 | .id_table = max1363_id, | ||
1416 | }; | ||
1417 | |||
1418 | static __init int max1363_init(void) | ||
1419 | { | ||
1420 | return i2c_add_driver(&max1363_driver); | ||
1421 | } | ||
1422 | |||
1423 | static __exit void max1363_exit(void) | ||
1424 | { | ||
1425 | i2c_del_driver(&max1363_driver); | ||
1426 | } | ||
1427 | |||
1428 | MODULE_AUTHOR("Jonathan Cameron <jic23@cam.ac.uk>"); | ||
1429 | MODULE_DESCRIPTION("Maxim 1363 ADC"); | ||
1430 | MODULE_LICENSE("GPL v2"); | ||
1431 | |||
1432 | module_init(max1363_init); | ||
1433 | module_exit(max1363_exit); | ||
diff --git a/drivers/staging/iio/adc/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c new file mode 100644 index 00000000000..f43befd1f77 --- /dev/null +++ b/drivers/staging/iio/adc/max1363_ring.c | |||
@@ -0,0 +1,209 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008 Jonathan Cameron | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | * max1363_ring.c | ||
9 | */ | ||
10 | |||
11 | #include <linux/interrupt.h> | ||
12 | #include <linux/device.h> | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/sysfs.h> | ||
16 | #include <linux/list.h> | ||
17 | #include <linux/i2c.h> | ||
18 | #include <linux/bitops.h> | ||
19 | |||
20 | #include "../iio.h" | ||
21 | #include "../ring_generic.h" | ||
22 | #include "../ring_sw.h" | ||
23 | #include "../trigger.h" | ||
24 | #include "../sysfs.h" | ||
25 | |||
26 | #include "max1363.h" | ||
27 | |||
28 | int max1363_single_channel_from_ring(long mask, struct max1363_state *st) | ||
29 | { | ||
30 | struct iio_ring_buffer *ring = iio_priv_to_dev(st)->ring; | ||
31 | int count = 0, ret; | ||
32 | u8 *ring_data; | ||
33 | if (!(st->current_mode->modemask & mask)) { | ||
34 | ret = -EBUSY; | ||
35 | goto error_ret; | ||
36 | } | ||
37 | |||
38 | ring_data = kmalloc(ring->access->get_bytes_per_datum(ring), | ||
39 | GFP_KERNEL); | ||
40 | if (ring_data == NULL) { | ||
41 | ret = -ENOMEM; | ||
42 | goto error_ret; | ||
43 | } | ||
44 | ret = ring->access->read_last(ring, ring_data); | ||
45 | if (ret) | ||
46 | goto error_free_ring_data; | ||
47 | /* Need a count of channels prior to this one */ | ||
48 | mask >>= 1; | ||
49 | while (mask) { | ||
50 | if (mask & st->current_mode->modemask) | ||
51 | count++; | ||
52 | mask >>= 1; | ||
53 | } | ||
54 | if (st->chip_info->bits != 8) | ||
55 | ret = ((int)(ring_data[count*2 + 0] & 0x0F) << 8) | ||
56 | + (int)(ring_data[count*2 + 1]); | ||
57 | else | ||
58 | ret = ring_data[count]; | ||
59 | |||
60 | error_free_ring_data: | ||
61 | kfree(ring_data); | ||
62 | error_ret: | ||
63 | return ret; | ||
64 | } | ||
65 | |||
66 | |||
67 | /** | ||
68 | * max1363_ring_preenable() - setup the parameters of the ring before enabling | ||
69 | * | ||
70 | * The complex nature of the setting of the nuber of bytes per datum is due | ||
71 | * to this driver currently ensuring that the timestamp is stored at an 8 | ||
72 | * byte boundary. | ||
73 | **/ | ||
74 | static int max1363_ring_preenable(struct iio_dev *indio_dev) | ||
75 | { | ||
76 | struct max1363_state *st = iio_priv(indio_dev); | ||
77 | struct iio_ring_buffer *ring = indio_dev->ring; | ||
78 | size_t d_size = 0; | ||
79 | unsigned long numvals; | ||
80 | |||
81 | /* | ||
82 | * Need to figure out the current mode based upon the requested | ||
83 | * scan mask in iio_dev | ||
84 | */ | ||
85 | st->current_mode = max1363_match_mode(ring->scan_mask, | ||
86 | st->chip_info); | ||
87 | if (!st->current_mode) | ||
88 | return -EINVAL; | ||
89 | |||
90 | max1363_set_scan_mode(st); | ||
91 | |||
92 | numvals = hweight_long(st->current_mode->modemask); | ||
93 | if (ring->access->set_bytes_per_datum) { | ||
94 | if (ring->scan_timestamp) | ||
95 | d_size += sizeof(s64); | ||
96 | if (st->chip_info->bits != 8) | ||
97 | d_size += numvals*2; | ||
98 | else | ||
99 | d_size += numvals; | ||
100 | if (ring->scan_timestamp && (d_size % 8)) | ||
101 | d_size += 8 - (d_size % 8); | ||
102 | ring->access->set_bytes_per_datum(ring, d_size); | ||
103 | } | ||
104 | |||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | static irqreturn_t max1363_trigger_handler(int irq, void *p) | ||
109 | { | ||
110 | struct iio_poll_func *pf = p; | ||
111 | struct iio_dev *indio_dev = pf->private_data; | ||
112 | struct max1363_state *st = iio_priv(indio_dev); | ||
113 | s64 time_ns; | ||
114 | __u8 *rxbuf; | ||
115 | int b_sent; | ||
116 | size_t d_size; | ||
117 | unsigned long numvals = hweight_long(st->current_mode->modemask); | ||
118 | |||
119 | /* Ensure the timestamp is 8 byte aligned */ | ||
120 | if (st->chip_info->bits != 8) | ||
121 | d_size = numvals*2 + sizeof(s64); | ||
122 | else | ||
123 | d_size = numvals + sizeof(s64); | ||
124 | if (d_size % sizeof(s64)) | ||
125 | d_size += sizeof(s64) - (d_size % sizeof(s64)); | ||
126 | |||
127 | /* Monitor mode prevents reading. Whilst not currently implemented | ||
128 | * might as well have this test in here in the meantime as it does | ||
129 | * no harm. | ||
130 | */ | ||
131 | if (numvals == 0) | ||
132 | return IRQ_HANDLED; | ||
133 | |||
134 | rxbuf = kmalloc(d_size, GFP_KERNEL); | ||
135 | if (rxbuf == NULL) | ||
136 | return -ENOMEM; | ||
137 | if (st->chip_info->bits != 8) | ||
138 | b_sent = i2c_master_recv(st->client, rxbuf, numvals*2); | ||
139 | else | ||
140 | b_sent = i2c_master_recv(st->client, rxbuf, numvals); | ||
141 | if (b_sent < 0) | ||
142 | goto done; | ||
143 | |||
144 | time_ns = iio_get_time_ns(); | ||
145 | |||
146 | memcpy(rxbuf + d_size - sizeof(s64), &time_ns, sizeof(time_ns)); | ||
147 | |||
148 | indio_dev->ring->access->store_to(indio_dev->ring, rxbuf, time_ns); | ||
149 | done: | ||
150 | iio_trigger_notify_done(indio_dev->trig); | ||
151 | kfree(rxbuf); | ||
152 | |||
153 | return IRQ_HANDLED; | ||
154 | } | ||
155 | |||
156 | static const struct iio_ring_setup_ops max1363_ring_setup_ops = { | ||
157 | .postenable = &iio_triggered_ring_postenable, | ||
158 | .preenable = &max1363_ring_preenable, | ||
159 | .predisable = &iio_triggered_ring_predisable, | ||
160 | }; | ||
161 | |||
162 | int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev) | ||
163 | { | ||
164 | struct max1363_state *st = iio_priv(indio_dev); | ||
165 | int ret = 0; | ||
166 | |||
167 | indio_dev->ring = iio_sw_rb_allocate(indio_dev); | ||
168 | if (!indio_dev->ring) { | ||
169 | ret = -ENOMEM; | ||
170 | goto error_ret; | ||
171 | } | ||
172 | indio_dev->pollfunc = iio_alloc_pollfunc(NULL, | ||
173 | &max1363_trigger_handler, | ||
174 | IRQF_ONESHOT, | ||
175 | indio_dev, | ||
176 | "%s_consumer%d", | ||
177 | st->client->name, | ||
178 | indio_dev->id); | ||
179 | if (indio_dev->pollfunc == NULL) { | ||
180 | ret = -ENOMEM; | ||
181 | goto error_deallocate_sw_rb; | ||
182 | } | ||
183 | /* Effectively select the ring buffer implementation */ | ||
184 | indio_dev->ring->access = &ring_sw_access_funcs; | ||
185 | /* Ring buffer functions - here trigger setup related */ | ||
186 | indio_dev->ring->setup_ops = &max1363_ring_setup_ops; | ||
187 | |||
188 | /* Flag that polled ring buffering is possible */ | ||
189 | indio_dev->modes |= INDIO_RING_TRIGGERED; | ||
190 | |||
191 | return 0; | ||
192 | |||
193 | error_deallocate_sw_rb: | ||
194 | iio_sw_rb_free(indio_dev->ring); | ||
195 | error_ret: | ||
196 | return ret; | ||
197 | } | ||
198 | |||
199 | void max1363_ring_cleanup(struct iio_dev *indio_dev) | ||
200 | { | ||
201 | /* ensure that the trigger has been detached */ | ||
202 | if (indio_dev->trig) { | ||
203 | iio_put_trigger(indio_dev->trig); | ||
204 | iio_trigger_dettach_poll_func(indio_dev->trig, | ||
205 | indio_dev->pollfunc); | ||
206 | } | ||
207 | iio_dealloc_pollfunc(indio_dev->pollfunc); | ||
208 | iio_sw_rb_free(indio_dev->ring); | ||
209 | } | ||