aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/iio/adc/adt75.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/iio/adc/adt75.c')
-rw-r--r--drivers/staging/iio/adc/adt75.c732
1 files changed, 732 insertions, 0 deletions
diff --git a/drivers/staging/iio/adc/adt75.c b/drivers/staging/iio/adc/adt75.c
new file mode 100644
index 00000000000..aff4d31eb89
--- /dev/null
+++ b/drivers/staging/iio/adc/adt75.c
@@ -0,0 +1,732 @@
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/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/i2c.h>
18#include <linux/rtc.h>
19
20#include "../iio.h"
21#include "../sysfs.h"
22
23/*
24 * ADT75 registers definition
25 */
26
27#define ADT75_TEMPERATURE 0
28#define ADT75_CONFIG 1
29#define ADT75_T_HYST 2
30#define ADT75_T_OS 3
31#define ADT75_ONESHOT 4
32
33/*
34 * ADT75 config
35 */
36#define ADT75_PD 0x1
37#define ADT75_OS_INT 0x2
38#define ADT75_OS_POLARITY 0x4
39#define ADT75_FAULT_QUEUE_MASK 0x18
40#define ADT75_FAULT_QUEUE_OFFSET 3
41#define ADT75_SMBUS_ALART 0x8
42
43/*
44 * ADT75 masks
45 */
46#define ADT75_VALUE_SIGN 0x800
47#define ADT75_VALUE_OFFSET 4
48#define ADT75_VALUE_FLOAT_OFFSET 4
49#define ADT75_VALUE_FLOAT_MASK 0xF
50
51
52/*
53 * struct adt75_chip_info - chip specifc information
54 */
55
56struct adt75_chip_info {
57 const char *name;
58 struct i2c_client *client;
59 struct iio_dev *indio_dev;
60 struct work_struct thresh_work;
61 s64 last_timestamp;
62 u8 config;
63};
64
65/*
66 * adt75 register access by I2C
67 */
68
69static int adt75_i2c_read(struct adt75_chip_info *chip, u8 reg, u8 *data)
70{
71 struct i2c_client *client = chip->client;
72 int ret = 0, len;
73
74 ret = i2c_smbus_write_byte(client, reg);
75 if (ret < 0) {
76 dev_err(&client->dev, "I2C read register address error\n");
77 return ret;
78 }
79
80 if (reg == ADT75_CONFIG || reg == ADT75_ONESHOT)
81 len = 1;
82 else
83 len = 2;
84
85 ret = i2c_master_recv(client, data, len);
86 if (ret < 0) {
87 dev_err(&client->dev, "I2C read error\n");
88 return ret;
89 }
90
91 return ret;
92}
93
94static int adt75_i2c_write(struct adt75_chip_info *chip, u8 reg, u8 data)
95{
96 struct i2c_client *client = chip->client;
97 int ret = 0;
98
99 if (reg == ADT75_CONFIG || reg == ADT75_ONESHOT)
100 ret = i2c_smbus_write_byte_data(client, reg, data);
101 else
102 ret = i2c_smbus_write_word_data(client, reg, data);
103
104 if (ret < 0)
105 dev_err(&client->dev, "I2C write error\n");
106
107 return ret;
108}
109
110static ssize_t adt75_show_mode(struct device *dev,
111 struct device_attribute *attr,
112 char *buf)
113{
114 struct iio_dev *dev_info = dev_get_drvdata(dev);
115 struct adt75_chip_info *chip = dev_info->dev_data;
116
117 if (chip->config & ADT75_PD)
118 return sprintf(buf, "power-save\n");
119 else
120 return sprintf(buf, "full\n");
121}
122
123static ssize_t adt75_store_mode(struct device *dev,
124 struct device_attribute *attr,
125 const char *buf,
126 size_t len)
127{
128 struct iio_dev *dev_info = dev_get_drvdata(dev);
129 struct adt75_chip_info *chip = dev_info->dev_data;
130 int ret;
131 u8 config;
132
133 ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config);
134 if (ret)
135 return -EIO;
136
137 config = chip->config & ~ADT75_PD;
138 if (!strcmp(buf, "full"))
139 config |= ADT75_PD;
140
141 ret = adt75_i2c_write(chip, ADT75_CONFIG, config);
142 if (ret)
143 return -EIO;
144
145 chip->config = config;
146
147 return ret;
148}
149
150static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
151 adt75_show_mode,
152 adt75_store_mode,
153 0);
154
155static ssize_t adt75_show_available_modes(struct device *dev,
156 struct device_attribute *attr,
157 char *buf)
158{
159 return sprintf(buf, "full\npower-down\n");
160}
161
162static IIO_DEVICE_ATTR(available_modes, S_IRUGO, adt75_show_available_modes, NULL, 0);
163
164static ssize_t adt75_show_oneshot(struct device *dev,
165 struct device_attribute *attr,
166 char *buf)
167{
168 struct iio_dev *dev_info = dev_get_drvdata(dev);
169 struct adt75_chip_info *chip = dev_info->dev_data;
170
171 return sprintf(buf, "%d\n", !!(chip->config & ADT75_ONESHOT));
172}
173
174static ssize_t adt75_store_oneshot(struct device *dev,
175 struct device_attribute *attr,
176 const char *buf,
177 size_t len)
178{
179 struct iio_dev *dev_info = dev_get_drvdata(dev);
180 struct adt75_chip_info *chip = dev_info->dev_data;
181 unsigned long data = 0;
182 int ret;
183 u8 config;
184
185 ret = strict_strtoul(buf, 10, &data);
186 if (ret)
187 return -EINVAL;
188
189
190 ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config);
191 if (ret)
192 return -EIO;
193
194 config = chip->config & ~ADT75_ONESHOT;
195 if (data)
196 config |= ADT75_ONESHOT;
197
198 ret = adt75_i2c_write(chip, ADT75_CONFIG, config);
199 if (ret)
200 return -EIO;
201
202 chip->config = config;
203
204 return ret;
205}
206
207static IIO_DEVICE_ATTR(oneshot, S_IRUGO | S_IWUSR,
208 adt75_show_oneshot,
209 adt75_store_oneshot,
210 0);
211
212static ssize_t adt75_show_value(struct device *dev,
213 struct device_attribute *attr,
214 char *buf)
215{
216 struct iio_dev *dev_info = dev_get_drvdata(dev);
217 struct adt75_chip_info *chip = dev_info->dev_data;
218 u16 data;
219 char sign = ' ';
220 int ret;
221
222 if (chip->config & ADT75_PD) {
223 dev_err(dev, "Can't read value in power-down mode.\n");
224 return -EIO;
225 }
226
227 if (chip->config & ADT75_ONESHOT) {
228 /* write to active converter */
229 ret = i2c_smbus_write_byte(chip->client, ADT75_ONESHOT);
230 if (ret)
231 return -EIO;
232 }
233
234 ret = adt75_i2c_read(chip, ADT75_TEMPERATURE, (u8 *)&data);
235 if (ret)
236 return -EIO;
237
238 data = swab16(data) >> ADT75_VALUE_OFFSET;
239 if (data & ADT75_VALUE_SIGN) {
240 /* convert supplement to positive value */
241 data = (ADT75_VALUE_SIGN << 1) - data;
242 sign = '-';
243 }
244
245 return sprintf(buf, "%c%d.%.4d\n", sign,
246 (data >> ADT75_VALUE_FLOAT_OFFSET),
247 (data & ADT75_VALUE_FLOAT_MASK) * 625);
248}
249
250static IIO_DEVICE_ATTR(value, S_IRUGO, adt75_show_value, NULL, 0);
251
252static ssize_t adt75_show_name(struct device *dev,
253 struct device_attribute *attr,
254 char *buf)
255{
256 struct iio_dev *dev_info = dev_get_drvdata(dev);
257 struct adt75_chip_info *chip = dev_info->dev_data;
258 return sprintf(buf, "%s\n", chip->name);
259}
260
261static IIO_DEVICE_ATTR(name, S_IRUGO, adt75_show_name, NULL, 0);
262
263static struct attribute *adt75_attributes[] = {
264 &iio_dev_attr_available_modes.dev_attr.attr,
265 &iio_dev_attr_mode.dev_attr.attr,
266 &iio_dev_attr_oneshot.dev_attr.attr,
267 &iio_dev_attr_value.dev_attr.attr,
268 &iio_dev_attr_name.dev_attr.attr,
269 NULL,
270};
271
272static const struct attribute_group adt75_attribute_group = {
273 .attrs = adt75_attributes,
274};
275
276/*
277 * temperature bound events
278 */
279
280#define IIO_EVENT_CODE_ADT75_OTI IIO_BUFFER_EVENT_CODE(0)
281
282static void adt75_interrupt_bh(struct work_struct *work_s)
283{
284 struct adt75_chip_info *chip =
285 container_of(work_s, struct adt75_chip_info, thresh_work);
286
287 enable_irq(chip->client->irq);
288
289 iio_push_event(chip->indio_dev, 0,
290 IIO_EVENT_CODE_ADT75_OTI,
291 chip->last_timestamp);
292}
293
294static int adt75_interrupt(struct iio_dev *dev_info,
295 int index,
296 s64 timestamp,
297 int no_test)
298{
299 struct adt75_chip_info *chip = dev_info->dev_data;
300
301 chip->last_timestamp = timestamp;
302 schedule_work(&chip->thresh_work);
303
304 return 0;
305}
306
307IIO_EVENT_SH(adt75, &adt75_interrupt);
308
309static ssize_t adt75_show_oti_mode(struct device *dev,
310 struct device_attribute *attr,
311 char *buf)
312{
313 struct iio_dev *dev_info = dev_get_drvdata(dev);
314 struct adt75_chip_info *chip = dev_info->dev_data;
315 int ret;
316
317 /* retrive ALART status */
318 ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config);
319 if (ret)
320 return -EIO;
321
322 if (chip->config & ADT75_OS_INT)
323 return sprintf(buf, "interrupt\n");
324 else
325 return sprintf(buf, "comparator\n");
326}
327
328static ssize_t adt75_set_oti_mode(struct device *dev,
329 struct device_attribute *attr,
330 const char *buf,
331 size_t len)
332{
333 struct iio_dev *dev_info = dev_get_drvdata(dev);
334 struct adt75_chip_info *chip = dev_info->dev_data;
335 int ret;
336 u8 config;
337
338 /* retrive ALART status */
339 ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config);
340 if (ret)
341 return -EIO;
342
343 config = chip->config & ~ADT75_OS_INT;
344 if (strcmp(buf, "comparator") != 0)
345 config |= ADT75_OS_INT;
346
347 ret = adt75_i2c_write(chip, ADT75_CONFIG, config);
348 if (ret)
349 return -EIO;
350
351 chip->config = config;
352
353 return ret;
354}
355
356static ssize_t adt75_show_available_oti_modes(struct device *dev,
357 struct device_attribute *attr,
358 char *buf)
359{
360 return sprintf(buf, "comparator\ninterrupt\n");
361}
362
363static ssize_t adt75_show_smbus_alart(struct device *dev,
364 struct device_attribute *attr,
365 char *buf)
366{
367 struct iio_dev *dev_info = dev_get_drvdata(dev);
368 struct adt75_chip_info *chip = dev_info->dev_data;
369 int ret;
370
371 /* retrive ALART status */
372 ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config);
373 if (ret)
374 return -EIO;
375
376 return sprintf(buf, "%d\n", !!(chip->config & ADT75_SMBUS_ALART));
377}
378
379static ssize_t adt75_set_smbus_alart(struct device *dev,
380 struct device_attribute *attr,
381 const char *buf,
382 size_t len)
383{
384 struct iio_dev *dev_info = dev_get_drvdata(dev);
385 struct adt75_chip_info *chip = dev_info->dev_data;
386 unsigned long data = 0;
387 int ret;
388 u8 config;
389
390 ret = strict_strtoul(buf, 10, &data);
391 if (ret)
392 return -EINVAL;
393
394 /* retrive ALART status */
395 ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config);
396 if (ret)
397 return -EIO;
398
399 config = chip->config & ~ADT75_SMBUS_ALART;
400 if (data)
401 config |= ADT75_SMBUS_ALART;
402
403 ret = adt75_i2c_write(chip, ADT75_CONFIG, config);
404 if (ret)
405 return -EIO;
406
407 chip->config = config;
408
409 return ret;
410}
411
412static ssize_t adt75_show_fault_queue(struct device *dev,
413 struct device_attribute *attr,
414 char *buf)
415{
416 struct iio_dev *dev_info = dev_get_drvdata(dev);
417 struct adt75_chip_info *chip = dev_info->dev_data;
418 int ret;
419
420 /* retrive ALART status */
421 ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config);
422 if (ret)
423 return -EIO;
424
425 return sprintf(buf, "%d\n", (chip->config & ADT75_FAULT_QUEUE_MASK) >>
426 ADT75_FAULT_QUEUE_OFFSET);
427}
428
429static ssize_t adt75_set_fault_queue(struct device *dev,
430 struct device_attribute *attr,
431 const char *buf,
432 size_t len)
433{
434 struct iio_dev *dev_info = dev_get_drvdata(dev);
435 struct adt75_chip_info *chip = dev_info->dev_data;
436 unsigned long data;
437 int ret;
438 u8 config;
439
440 ret = strict_strtoul(buf, 10, &data);
441 if (ret || data > 3)
442 return -EINVAL;
443
444 /* retrive ALART status */
445 ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config);
446 if (ret)
447 return -EIO;
448
449 config = chip->config & ~ADT75_FAULT_QUEUE_MASK;
450 config |= (data << ADT75_FAULT_QUEUE_OFFSET);
451 ret = adt75_i2c_write(chip, ADT75_CONFIG, config);
452 if (ret)
453 return -EIO;
454
455 chip->config = config;
456
457 return ret;
458}
459static inline ssize_t adt75_show_t_bound(struct device *dev,
460 struct device_attribute *attr,
461 u8 bound_reg,
462 char *buf)
463{
464 struct iio_dev *dev_info = dev_get_drvdata(dev);
465 struct adt75_chip_info *chip = dev_info->dev_data;
466 u16 data;
467 char sign = ' ';
468 int ret;
469
470 ret = adt75_i2c_read(chip, bound_reg, (u8 *)&data);
471 if (ret)
472 return -EIO;
473
474 data = swab16(data) >> ADT75_VALUE_OFFSET;
475 if (data & ADT75_VALUE_SIGN) {
476 /* convert supplement to positive value */
477 data = (ADT75_VALUE_SIGN << 1) - data;
478 sign = '-';
479 }
480
481 return sprintf(buf, "%c%d.%.4d\n", sign,
482 (data >> ADT75_VALUE_FLOAT_OFFSET),
483 (data & ADT75_VALUE_FLOAT_MASK) * 625);
484}
485
486static inline ssize_t adt75_set_t_bound(struct device *dev,
487 struct device_attribute *attr,
488 u8 bound_reg,
489 const char *buf,
490 size_t len)
491{
492 struct iio_dev *dev_info = dev_get_drvdata(dev);
493 struct adt75_chip_info *chip = dev_info->dev_data;
494 long tmp1, tmp2;
495 u16 data;
496 char *pos;
497 int ret;
498
499 pos = strchr(buf, '.');
500
501 ret = strict_strtol(buf, 10, &tmp1);
502
503 if (ret || tmp1 > 127 || tmp1 < -128)
504 return -EINVAL;
505
506 if (pos) {
507 len = strlen(pos);
508 if (len > ADT75_VALUE_FLOAT_OFFSET)
509 len = ADT75_VALUE_FLOAT_OFFSET;
510 pos[len] = 0;
511 ret = strict_strtol(pos, 10, &tmp2);
512
513 if (!ret)
514 tmp2 = (tmp2 / 625) * 625;
515 }
516
517 if (tmp1 < 0)
518 data = (u16)(-tmp1);
519 else
520 data = (u16)tmp1;
521 data = (data << ADT75_VALUE_FLOAT_OFFSET) | (tmp2 & ADT75_VALUE_FLOAT_MASK);
522 if (tmp1 < 0)
523 /* convert positive value to supplyment */
524 data = (ADT75_VALUE_SIGN << 1) - data;
525 data <<= ADT75_VALUE_OFFSET;
526 data = swab16(data);
527
528 ret = adt75_i2c_write(chip, bound_reg, (u8)data);
529 if (ret)
530 return -EIO;
531
532 return ret;
533}
534
535static ssize_t adt75_show_t_os(struct device *dev,
536 struct device_attribute *attr,
537 char *buf)
538{
539 return adt75_show_t_bound(dev, attr,
540 ADT75_T_OS, buf);
541}
542
543static inline ssize_t adt75_set_t_os(struct device *dev,
544 struct device_attribute *attr,
545 const char *buf,
546 size_t len)
547{
548 return adt75_set_t_bound(dev, attr,
549 ADT75_T_OS, buf, len);
550}
551
552static ssize_t adt75_show_t_hyst(struct device *dev,
553 struct device_attribute *attr,
554 char *buf)
555{
556 return adt75_show_t_bound(dev, attr,
557 ADT75_T_HYST, buf);
558}
559
560static inline ssize_t adt75_set_t_hyst(struct device *dev,
561 struct device_attribute *attr,
562 const char *buf,
563 size_t len)
564{
565 return adt75_set_t_bound(dev, attr,
566 ADT75_T_HYST, buf, len);
567}
568
569IIO_EVENT_ATTR_SH(oti_mode, iio_event_adt75,
570 adt75_show_oti_mode, adt75_set_oti_mode, 0);
571IIO_EVENT_ATTR_SH(available_oti_modes, iio_event_adt75,
572 adt75_show_available_oti_modes, NULL, 0);
573IIO_EVENT_ATTR_SH(smbus_alart, iio_event_adt75,
574 adt75_show_smbus_alart, adt75_set_smbus_alart, 0);
575IIO_EVENT_ATTR_SH(fault_queue, iio_event_adt75,
576 adt75_show_fault_queue, adt75_set_fault_queue, 0);
577IIO_EVENT_ATTR_SH(t_os, iio_event_adt75,
578 adt75_show_t_os, adt75_set_t_os, 0);
579IIO_EVENT_ATTR_SH(t_hyst, iio_event_adt75,
580 adt75_show_t_hyst, adt75_set_t_hyst, 0);
581
582static struct attribute *adt75_event_attributes[] = {
583 &iio_event_attr_oti_mode.dev_attr.attr,
584 &iio_event_attr_available_oti_modes.dev_attr.attr,
585 &iio_event_attr_smbus_alart.dev_attr.attr,
586 &iio_event_attr_fault_queue.dev_attr.attr,
587 &iio_event_attr_t_os.dev_attr.attr,
588 &iio_event_attr_t_hyst.dev_attr.attr,
589 NULL,
590};
591
592static struct attribute_group adt75_event_attribute_group = {
593 .attrs = adt75_event_attributes,
594};
595
596/*
597 * device probe and remove
598 */
599
600static int __devinit adt75_probe(struct i2c_client *client,
601 const struct i2c_device_id *id)
602{
603 struct adt75_chip_info *chip;
604 int ret = 0;
605
606 chip = kzalloc(sizeof(struct adt75_chip_info), GFP_KERNEL);
607
608 if (chip == NULL)
609 return -ENOMEM;
610
611 /* this is only used for device removal purposes */
612 i2c_set_clientdata(client, chip);
613
614 chip->client = client;
615 chip->name = id->name;
616
617 chip->indio_dev = iio_allocate_device();
618 if (chip->indio_dev == NULL) {
619 ret = -ENOMEM;
620 goto error_free_chip;
621 }
622
623 chip->indio_dev->dev.parent = &client->dev;
624 chip->indio_dev->attrs = &adt75_attribute_group;
625 chip->indio_dev->event_attrs = &adt75_event_attribute_group;
626 chip->indio_dev->dev_data = (void *)chip;
627 chip->indio_dev->driver_module = THIS_MODULE;
628 chip->indio_dev->num_interrupt_lines = 1;
629 chip->indio_dev->modes = INDIO_DIRECT_MODE;
630
631 ret = iio_device_register(chip->indio_dev);
632 if (ret)
633 goto error_free_dev;
634
635 if (client->irq > 0) {
636 ret = iio_register_interrupt_line(client->irq,
637 chip->indio_dev,
638 0,
639 IRQF_TRIGGER_LOW,
640 chip->name);
641 if (ret)
642 goto error_unreg_dev;
643
644 /*
645 * The event handler list element refer to iio_event_adt75.
646 * All event attributes bind to the same event handler.
647 * So, only register event handler once.
648 */
649 iio_add_event_to_list(&iio_event_adt75,
650 &chip->indio_dev->interrupts[0]->ev_list);
651
652 INIT_WORK(&chip->thresh_work, adt75_interrupt_bh);
653
654 ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config);
655 if (ret) {
656 ret = -EIO;
657 goto error_unreg_irq;
658 }
659
660 /* set irq polarity low level */
661 chip->config &= ~ADT75_OS_POLARITY;
662
663 ret = adt75_i2c_write(chip, ADT75_CONFIG, chip->config);
664 if (ret) {
665 ret = -EIO;
666 goto error_unreg_irq;
667 }
668 }
669
670 dev_info(&client->dev, "%s temperature sensor registered.\n",
671 id->name);
672
673 return 0;
674error_unreg_irq:
675 iio_unregister_interrupt_line(chip->indio_dev, 0);
676error_unreg_dev:
677 iio_device_unregister(chip->indio_dev);
678error_free_dev:
679 iio_free_device(chip->indio_dev);
680error_free_chip:
681 kfree(chip);
682
683 return ret;
684}
685
686static int __devexit adt75_remove(struct i2c_client *client)
687{
688 struct adt75_chip_info *chip = i2c_get_clientdata(client);
689 struct iio_dev *indio_dev = chip->indio_dev;
690
691 if (client->irq)
692 iio_unregister_interrupt_line(indio_dev, 0);
693 iio_device_unregister(indio_dev);
694 iio_free_device(chip->indio_dev);
695 kfree(chip);
696
697 return 0;
698}
699
700static const struct i2c_device_id adt75_id[] = {
701 { "adt75", 0 },
702 {}
703};
704
705MODULE_DEVICE_TABLE(i2c, adt75_id);
706
707static struct i2c_driver adt75_driver = {
708 .driver = {
709 .name = "adt75",
710 },
711 .probe = adt75_probe,
712 .remove = __devexit_p(adt75_remove),
713 .id_table = adt75_id,
714};
715
716static __init int adt75_init(void)
717{
718 return i2c_add_driver(&adt75_driver);
719}
720
721static __exit void adt75_exit(void)
722{
723 i2c_del_driver(&adt75_driver);
724}
725
726MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
727MODULE_DESCRIPTION("Analog Devices ADT75 digital"
728 " temperature sensor driver");
729MODULE_LICENSE("GPL v2");
730
731module_init(adt75_init);
732module_exit(adt75_exit);