aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/iio/adc/ad7298.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/iio/adc/ad7298.c')
-rw-r--r--drivers/staging/iio/adc/ad7298.c501
1 files changed, 501 insertions, 0 deletions
diff --git a/drivers/staging/iio/adc/ad7298.c b/drivers/staging/iio/adc/ad7298.c
new file mode 100644
index 00000000000..1a080c97763
--- /dev/null
+++ b/drivers/staging/iio/adc/ad7298.c
@@ -0,0 +1,501 @@
1/*
2 * AD7298 digital temperature sensor driver supporting AD7298
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/workqueue.h>
12#include <linux/device.h>
13#include <linux/kernel.h>
14#include <linux/slab.h>
15#include <linux/sysfs.h>
16#include <linux/list.h>
17#include <linux/spi/spi.h>
18#include <linux/rtc.h>
19
20#include "../iio.h"
21#include "../sysfs.h"
22
23/*
24 * AD7298 command
25 */
26#define AD7298_PD 0x1
27#define AD7298_T_AVG_MASK 0x2
28#define AD7298_EXT_REF 0x4
29#define AD7298_T_SENSE_MASK 0x20
30#define AD7298_VOLTAGE_MASK 0x3fc0
31#define AD7298_VOLTAGE_OFFSET 0x6
32#define AD7298_VOLTAGE_LIMIT_COUNT 8
33#define AD7298_REPEAT 0x40
34#define AD7298_WRITE 0x80
35
36/*
37 * AD7298 value masks
38 */
39#define AD7298_CHANNEL_MASK 0xf000
40#define AD7298_VALUE_MASK 0xfff
41#define AD7298_T_VALUE_SIGN 0x400
42#define AD7298_T_VALUE_FLOAT_OFFSET 2
43#define AD7298_T_VALUE_FLOAT_MASK 0x2
44
45/*
46 * struct ad7298_chip_info - chip specifc information
47 */
48
49struct ad7298_chip_info {
50 const char *name;
51 struct spi_device *spi_dev;
52 struct iio_dev *indio_dev;
53 u16 command;
54 u16 busy_pin;
55 u8 channels; /* Active voltage channels */
56};
57
58/*
59 * ad7298 register access by SPI
60 */
61static int ad7298_spi_write(struct ad7298_chip_info *chip, u16 data)
62{
63 struct spi_device *spi_dev = chip->spi_dev;
64 int ret = 0;
65
66 data |= AD7298_WRITE;
67 data = cpu_to_be16(data);
68 ret = spi_write(spi_dev, (u8 *)&data, sizeof(data));
69 if (ret < 0)
70 dev_err(&spi_dev->dev, "SPI write error\n");
71
72 return ret;
73}
74
75static int ad7298_spi_read(struct ad7298_chip_info *chip, u16 mask, u16 *data)
76{
77 struct spi_device *spi_dev = chip->spi_dev;
78 int ret = 0;
79 u8 count = chip->channels;
80 u16 command;
81 int i;
82
83 if (mask & AD7298_T_SENSE_MASK) {
84 command = chip->command & ~(AD7298_T_AVG_MASK | AD7298_VOLTAGE_MASK);
85 command |= AD7298_T_SENSE_MASK;
86 count = 1;
87 } else if (mask & AD7298_T_AVG_MASK) {
88 command = chip->command & ~AD7298_VOLTAGE_MASK;
89 command |= AD7298_T_SENSE_MASK | AD7298_T_AVG_MASK;
90 count = 2;
91 } else if (mask & AD7298_VOLTAGE_MASK) {
92 command = chip->command & ~(AD7298_T_AVG_MASK | AD7298_T_SENSE_MASK);
93 count = chip->channels;
94 }
95
96 ret = ad7298_spi_write(chip, chip->command);
97 if (ret < 0) {
98 dev_err(&spi_dev->dev, "SPI write command error\n");
99 return ret;
100 }
101
102 ret = spi_read(spi_dev, (u8 *)&command, sizeof(command));
103 if (ret < 0) {
104 dev_err(&spi_dev->dev, "SPI read error\n");
105 return ret;
106 }
107
108 i = 10000;
109 while (i && gpio_get_value(chip->busy_pin)) {
110 cpu_relax();
111 i--;
112 }
113 if (!i) {
114 dev_err(&spi_dev->dev, "Always in busy convertion.\n");
115 return -EBUSY;
116 }
117
118 for (i = 0; i < count; i++) {
119 ret = spi_read(spi_dev, (u8 *)&data[i], sizeof(data[i]));
120 if (ret < 0) {
121 dev_err(&spi_dev->dev, "SPI read error\n");
122 return ret;
123 }
124 *data = be16_to_cpu(data[i]);
125 }
126
127 return 0;
128}
129
130static ssize_t ad7298_show_mode(struct device *dev,
131 struct device_attribute *attr,
132 char *buf)
133{
134 struct iio_dev *dev_info = dev_get_drvdata(dev);
135 struct ad7298_chip_info *chip = dev_info->dev_data;
136
137 if (chip->command & AD7298_REPEAT)
138 return sprintf(buf, "repeat\n");
139 else
140 return sprintf(buf, "normal\n");
141}
142
143static ssize_t ad7298_store_mode(struct device *dev,
144 struct device_attribute *attr,
145 const char *buf,
146 size_t len)
147{
148 struct iio_dev *dev_info = dev_get_drvdata(dev);
149 struct ad7298_chip_info *chip = dev_info->dev_data;
150
151 if (strcmp(buf, "repeat"))
152 chip->command |= AD7298_REPEAT;
153 else
154 chip->command &= (~AD7298_REPEAT);
155
156 return 1;
157}
158
159static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
160 ad7298_show_mode,
161 ad7298_store_mode,
162 0);
163
164static ssize_t ad7298_show_available_modes(struct device *dev,
165 struct device_attribute *attr,
166 char *buf)
167{
168 return sprintf(buf, "normal\nrepeat\n");
169}
170
171static IIO_DEVICE_ATTR(available_modes, S_IRUGO, ad7298_show_available_modes, NULL, 0);
172
173static ssize_t ad7298_store_reset(struct device *dev,
174 struct device_attribute *attr,
175 const char *buf,
176 size_t len)
177{
178 struct iio_dev *dev_info = dev_get_drvdata(dev);
179 struct ad7298_chip_info *chip = dev_info->dev_data;
180 u16 command;
181 int ret;
182
183 command = chip->command & ~AD7298_PD;
184
185 ret = ad7298_spi_write(chip, command);
186 if (ret)
187 return -EIO;
188
189 command = chip->command | AD7298_PD;
190
191 ret = ad7298_spi_write(chip, command);
192 if (ret)
193 return -EIO;
194
195 return len;
196}
197
198static IIO_DEVICE_ATTR(reset, S_IWUSR,
199 NULL,
200 ad7298_store_reset,
201 0);
202
203static ssize_t ad7298_show_ext_ref(struct device *dev,
204 struct device_attribute *attr,
205 char *buf)
206{
207 struct iio_dev *dev_info = dev_get_drvdata(dev);
208 struct ad7298_chip_info *chip = dev_info->dev_data;
209
210 return sprintf(buf, "%d\n", !!(chip->command & AD7298_EXT_REF));
211}
212
213static ssize_t ad7298_store_ext_ref(struct device *dev,
214 struct device_attribute *attr,
215 const char *buf,
216 size_t len)
217{
218 struct iio_dev *dev_info = dev_get_drvdata(dev);
219 struct ad7298_chip_info *chip = dev_info->dev_data;
220 u16 command;
221 int ret;
222
223 command = chip->command & (~AD7298_EXT_REF);
224 if (strcmp(buf, "1"))
225 command |= AD7298_EXT_REF;
226
227 ret = ad7298_spi_write(chip, command);
228 if (ret)
229 return -EIO;
230
231 chip->command = command;
232
233 return len;
234}
235
236static IIO_DEVICE_ATTR(ext_ref, S_IRUGO | S_IWUSR,
237 ad7298_show_ext_ref,
238 ad7298_store_ext_ref,
239 0);
240
241static ssize_t ad7298_show_t_sense(struct device *dev,
242 struct device_attribute *attr,
243 char *buf)
244{
245 struct iio_dev *dev_info = dev_get_drvdata(dev);
246 struct ad7298_chip_info *chip = dev_info->dev_data;
247 u16 data;
248 char sign = ' ';
249 int ret;
250
251 ret = ad7298_spi_read(chip, AD7298_T_SENSE_MASK, &data);
252 if (ret)
253 return -EIO;
254
255 if (data & AD7298_T_VALUE_SIGN) {
256 /* convert supplement to positive value */
257 data = (AD7298_T_VALUE_SIGN << 1) - data;
258 sign = '-';
259 }
260
261 return sprintf(buf, "%c%d.%.2d\n", sign,
262 (data >> AD7298_T_VALUE_FLOAT_OFFSET),
263 (data & AD7298_T_VALUE_FLOAT_MASK) * 25);
264}
265
266static IIO_DEVICE_ATTR(t_sense, S_IRUGO, ad7298_show_t_sense, NULL, 0);
267
268static ssize_t ad7298_show_t_average(struct device *dev,
269 struct device_attribute *attr,
270 char *buf)
271{
272 struct iio_dev *dev_info = dev_get_drvdata(dev);
273 struct ad7298_chip_info *chip = dev_info->dev_data;
274 u16 data[2];
275 char sign = ' ';
276 int ret;
277
278 ret = ad7298_spi_read(chip, AD7298_T_AVG_MASK, data);
279 if (ret)
280 return -EIO;
281
282 if (data[1] & AD7298_T_VALUE_SIGN) {
283 /* convert supplement to positive value */
284 data[1] = (AD7298_T_VALUE_SIGN << 1) - data[1];
285 sign = '-';
286 }
287
288 return sprintf(buf, "%c%d.%.2d\n", sign,
289 (data[1] >> AD7298_T_VALUE_FLOAT_OFFSET),
290 (data[1] & AD7298_T_VALUE_FLOAT_MASK) * 25);
291}
292
293static IIO_DEVICE_ATTR(t_average, S_IRUGO, ad7298_show_t_average, NULL, 0);
294
295static ssize_t ad7298_show_voltage(struct device *dev,
296 struct device_attribute *attr,
297 char *buf)
298{
299 struct iio_dev *dev_info = dev_get_drvdata(dev);
300 struct ad7298_chip_info *chip = dev_info->dev_data;
301 u16 data[AD7298_VOLTAGE_LIMIT_COUNT];
302 int i, size, ret;
303
304 ret = ad7298_spi_read(chip, AD7298_VOLTAGE_MASK, data);
305 if (ret)
306 return -EIO;
307
308 for (i = 0; i < AD7298_VOLTAGE_LIMIT_COUNT; i++) {
309 if (chip->command & (AD7298_T_SENSE_MASK << i)) {
310 ret = sprintf(buf, "channel[%d]=%d\n", i,
311 data[i] & AD7298_VALUE_MASK);
312 if (ret < 0)
313 break;
314 buf += ret;
315 size += ret;
316 }
317 }
318
319 return size;
320}
321
322static IIO_DEVICE_ATTR(voltage, S_IRUGO, ad7298_show_voltage, NULL, 0);
323
324static ssize_t ad7298_show_channel_mask(struct device *dev,
325 struct device_attribute *attr,
326 char *buf)
327{
328 struct iio_dev *dev_info = dev_get_drvdata(dev);
329 struct ad7298_chip_info *chip = dev_info->dev_data;
330
331 return sprintf(buf, "0x%x\n", (chip->command & AD7298_VOLTAGE_MASK) >>
332 AD7298_VOLTAGE_OFFSET);
333}
334
335static ssize_t ad7298_store_channel_mask(struct device *dev,
336 struct device_attribute *attr,
337 const char *buf,
338 size_t len)
339{
340 struct iio_dev *dev_info = dev_get_drvdata(dev);
341 struct ad7298_chip_info *chip = dev_info->dev_data;
342 unsigned long data;
343 int i, ret;
344
345 ret = strict_strtoul(buf, 16, &data);
346 if (ret || data > 0xff)
347 return -EINVAL;
348
349 chip->command &= (~AD7298_VOLTAGE_MASK);
350 chip->command |= data << AD7298_VOLTAGE_OFFSET;
351
352 for (i = 0, chip->channels = 0; i < AD7298_VOLTAGE_LIMIT_COUNT; i++) {
353 if (chip->command & (AD7298_T_SENSE_MASK << i))
354 chip->channels++;
355 }
356
357 return ret;
358}
359
360static IIO_DEVICE_ATTR(channel_mask, S_IRUGO | S_IWUSR,
361 ad7298_show_channel_mask,
362 ad7298_store_channel_mask,
363 0);
364
365static ssize_t ad7298_show_name(struct device *dev,
366 struct device_attribute *attr,
367 char *buf)
368{
369 struct iio_dev *dev_info = dev_get_drvdata(dev);
370 struct ad7298_chip_info *chip = dev_info->dev_data;
371 return sprintf(buf, "%s\n", chip->name);
372}
373
374static IIO_DEVICE_ATTR(name, S_IRUGO, ad7298_show_name, NULL, 0);
375
376static struct attribute *ad7298_attributes[] = {
377 &iio_dev_attr_available_modes.dev_attr.attr,
378 &iio_dev_attr_mode.dev_attr.attr,
379 &iio_dev_attr_reset.dev_attr.attr,
380 &iio_dev_attr_ext_ref.dev_attr.attr,
381 &iio_dev_attr_t_sense.dev_attr.attr,
382 &iio_dev_attr_t_average.dev_attr.attr,
383 &iio_dev_attr_voltage.dev_attr.attr,
384 &iio_dev_attr_channel_mask.dev_attr.attr,
385 &iio_dev_attr_name.dev_attr.attr,
386 NULL,
387};
388
389static const struct attribute_group ad7298_attribute_group = {
390 .attrs = ad7298_attributes,
391};
392
393/*
394 * device probe and remove
395 */
396static int __devinit ad7298_probe(struct spi_device *spi_dev)
397{
398 struct ad7298_chip_info *chip;
399 unsigned short *pins = spi_dev->dev.platform_data;
400 int ret = 0;
401
402 chip = kzalloc(sizeof(struct ad7298_chip_info), GFP_KERNEL);
403
404 if (chip == NULL)
405 return -ENOMEM;
406
407 /* this is only used for device removal purposes */
408 dev_set_drvdata(&spi_dev->dev, chip);
409
410 chip->spi_dev = spi_dev;
411 chip->name = spi_dev->modalias;
412 chip->busy_pin = pins[0];
413
414 ret = gpio_request(chip->busy_pin, chip->name);
415 if (ret) {
416 dev_err(&spi_dev->dev, "Fail to request busy gpio PIN %d.\n",
417 chip->busy_pin);
418 goto error_free_chip;
419 }
420 gpio_direction_input(chip->busy_pin);
421
422 chip->indio_dev = iio_allocate_device();
423 if (chip->indio_dev == NULL) {
424 ret = -ENOMEM;
425 goto error_free_gpio;
426 }
427
428 chip->indio_dev->dev.parent = &spi_dev->dev;
429 chip->indio_dev->attrs = &ad7298_attribute_group;
430 chip->indio_dev->dev_data = (void *)chip;
431 chip->indio_dev->driver_module = THIS_MODULE;
432 chip->indio_dev->modes = INDIO_DIRECT_MODE;
433
434 ret = iio_device_register(chip->indio_dev);
435 if (ret)
436 goto error_free_dev;
437
438 dev_info(&spi_dev->dev, "%s temperature sensor and ADC registered.\n",
439 chip->name);
440
441 return 0;
442
443error_free_dev:
444 iio_free_device(chip->indio_dev);
445error_free_gpio:
446 gpio_free(chip->busy_pin);
447error_free_chip:
448 kfree(chip);
449
450 return ret;
451}
452
453static int __devexit ad7298_remove(struct spi_device *spi_dev)
454{
455 struct ad7298_chip_info *chip = dev_get_drvdata(&spi_dev->dev);
456 struct iio_dev *indio_dev = chip->indio_dev;
457
458 dev_set_drvdata(&spi_dev->dev, NULL);
459 iio_device_unregister(indio_dev);
460 iio_free_device(chip->indio_dev);
461 gpio_free(chip->busy_pin);
462 kfree(chip);
463
464 return 0;
465}
466
467static const struct spi_device_id ad7298_id[] = {
468 { "ad7298", 0 },
469 {}
470};
471
472MODULE_DEVICE_TABLE(spi, ad7298_id);
473
474static struct spi_driver ad7298_driver = {
475 .driver = {
476 .name = "ad7298",
477 .bus = &spi_bus_type,
478 .owner = THIS_MODULE,
479 },
480 .probe = ad7298_probe,
481 .remove = __devexit_p(ad7298_remove),
482 .id_table = ad7298_id,
483};
484
485static __init int ad7298_init(void)
486{
487 return spi_register_driver(&ad7298_driver);
488}
489
490static __exit void ad7298_exit(void)
491{
492 spi_unregister_driver(&ad7298_driver);
493}
494
495MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
496MODULE_DESCRIPTION("Analog Devices AD7298 digital"
497 " temperature sensor and ADC driver");
498MODULE_LICENSE("GPL v2");
499
500module_init(ad7298_init);
501module_exit(ad7298_exit);