staging:iio: implement an iio_info structure to take some of the constant elements...
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / iio / adc / adt75.c
CommitLineData
d7713b6c
SZ
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>
d7713b6c
SZ
10#include <linux/device.h>
11#include <linux/kernel.h>
12#include <linux/slab.h>
13#include <linux/sysfs.h>
d7713b6c 14#include <linux/i2c.h>
d7713b6c
SZ
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
52struct adt75_chip_info {
d7713b6c
SZ
53 struct i2c_client *client;
54 struct iio_dev *indio_dev;
d7713b6c
SZ
55 u8 config;
56};
57
58/*
59 * adt75 register access by I2C
60 */
61
62static int adt75_i2c_read(struct adt75_chip_info *chip, u8 reg, u8 *data)
63{
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
87static int adt75_i2c_write(struct adt75_chip_info *chip, u8 reg, u8 data)
88{
89 struct i2c_client *client = chip->client;
90 int ret = 0;
91
92 if (reg == ADT75_CONFIG || reg == ADT75_ONESHOT)
93 ret = i2c_smbus_write_byte_data(client, reg, data);
94 else
95 ret = i2c_smbus_write_word_data(client, reg, data);
96
97 if (ret < 0)
98 dev_err(&client->dev, "I2C write error\n");
99
100 return ret;
101}
102
103static ssize_t adt75_show_mode(struct device *dev,
104 struct device_attribute *attr,
105 char *buf)
106{
107 struct iio_dev *dev_info = dev_get_drvdata(dev);
108 struct adt75_chip_info *chip = dev_info->dev_data;
109
110 if (chip->config & ADT75_PD)
111 return sprintf(buf, "power-save\n");
112 else
113 return sprintf(buf, "full\n");
114}
115
116static 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 = dev_info->dev_data;
123 int ret;
124 u8 config;
125
126 ret = adt75_i2c_read(chip, 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(chip, ADT75_CONFIG, config);
135 if (ret)
136 return -EIO;
137
138 chip->config = config;
139
140 return ret;
141}
142
143static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
144 adt75_show_mode,
145 adt75_store_mode,
146 0);
147
148static 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
155static IIO_DEVICE_ATTR(available_modes, S_IRUGO, adt75_show_available_modes, NULL, 0);
156
157static ssize_t adt75_show_oneshot(struct device *dev,
158 struct device_attribute *attr,
159 char *buf)
160{
161 struct iio_dev *dev_info = dev_get_drvdata(dev);
162 struct adt75_chip_info *chip = dev_info->dev_data;
163
164 return sprintf(buf, "%d\n", !!(chip->config & ADT75_ONESHOT));
165}
166
167static ssize_t adt75_store_oneshot(struct device *dev,
168 struct device_attribute *attr,
169 const char *buf,
170 size_t len)
171{
172 struct iio_dev *dev_info = dev_get_drvdata(dev);
173 struct adt75_chip_info *chip = dev_info->dev_data;
174 unsigned long data = 0;
175 int ret;
176 u8 config;
177
178 ret = strict_strtoul(buf, 10, &data);
179 if (ret)
180 return -EINVAL;
181
182
183 ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config);
184 if (ret)
185 return -EIO;
186
187 config = chip->config & ~ADT75_ONESHOT;
188 if (data)
189 config |= ADT75_ONESHOT;
190
191 ret = adt75_i2c_write(chip, ADT75_CONFIG, config);
192 if (ret)
193 return -EIO;
194
195 chip->config = config;
196
197 return ret;
198}
199
200static IIO_DEVICE_ATTR(oneshot, S_IRUGO | S_IWUSR,
201 adt75_show_oneshot,
202 adt75_store_oneshot,
203 0);
204
205static ssize_t adt75_show_value(struct device *dev,
206 struct device_attribute *attr,
207 char *buf)
208{
209 struct iio_dev *dev_info = dev_get_drvdata(dev);
210 struct adt75_chip_info *chip = dev_info->dev_data;
211 u16 data;
212 char sign = ' ';
213 int ret;
214
215 if (chip->config & ADT75_PD) {
216 dev_err(dev, "Can't read value in power-down mode.\n");
217 return -EIO;
218 }
219
220 if (chip->config & ADT75_ONESHOT) {
221 /* write to active converter */
222 ret = i2c_smbus_write_byte(chip->client, ADT75_ONESHOT);
223 if (ret)
224 return -EIO;
225 }
226
227 ret = adt75_i2c_read(chip, ADT75_TEMPERATURE, (u8 *)&data);
228 if (ret)
229 return -EIO;
230
231 data = swab16(data) >> ADT75_VALUE_OFFSET;
232 if (data & ADT75_VALUE_SIGN) {
233 /* convert supplement to positive value */
234 data = (ADT75_VALUE_SIGN << 1) - data;
235 sign = '-';
236 }
237
238 return sprintf(buf, "%c%d.%.4d\n", sign,
239 (data >> ADT75_VALUE_FLOAT_OFFSET),
240 (data & ADT75_VALUE_FLOAT_MASK) * 625);
241}
242
243static IIO_DEVICE_ATTR(value, S_IRUGO, adt75_show_value, NULL, 0);
244
d7713b6c
SZ
245static struct attribute *adt75_attributes[] = {
246 &iio_dev_attr_available_modes.dev_attr.attr,
247 &iio_dev_attr_mode.dev_attr.attr,
248 &iio_dev_attr_oneshot.dev_attr.attr,
249 &iio_dev_attr_value.dev_attr.attr,
d7713b6c
SZ
250 NULL,
251};
252
253static const struct attribute_group adt75_attribute_group = {
254 .attrs = adt75_attributes,
255};
256
257/*
258 * temperature bound events
259 */
260
0bb8be64
JC
261#define IIO_EVENT_CODE_ADT75_OTI IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_TEMP, \
262 0, \
263 IIO_EV_TYPE_THRESH, \
264 IIO_EV_DIR_FALLING)
d7713b6c 265
1142f709 266static irqreturn_t adt75_event_handler(int irq, void *private)
d7713b6c 267{
1142f709
JC
268 iio_push_event(private, 0,
269 IIO_EVENT_CODE_ADT75_OTI,
270 iio_get_time_ns());
d7713b6c 271
1142f709 272 return IRQ_HANDLED;
d7713b6c
SZ
273}
274
d7713b6c
SZ
275static ssize_t adt75_show_oti_mode(struct device *dev,
276 struct device_attribute *attr,
277 char *buf)
278{
279 struct iio_dev *dev_info = dev_get_drvdata(dev);
280 struct adt75_chip_info *chip = dev_info->dev_data;
281 int ret;
282
283 /* retrive ALART status */
284 ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config);
285 if (ret)
286 return -EIO;
287
288 if (chip->config & ADT75_OS_INT)
289 return sprintf(buf, "interrupt\n");
290 else
291 return sprintf(buf, "comparator\n");
292}
293
294static ssize_t adt75_set_oti_mode(struct device *dev,
295 struct device_attribute *attr,
296 const char *buf,
297 size_t len)
298{
299 struct iio_dev *dev_info = dev_get_drvdata(dev);
300 struct adt75_chip_info *chip = dev_info->dev_data;
301 int ret;
302 u8 config;
303
304 /* retrive ALART status */
305 ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config);
306 if (ret)
307 return -EIO;
308
309 config = chip->config & ~ADT75_OS_INT;
310 if (strcmp(buf, "comparator") != 0)
311 config |= ADT75_OS_INT;
312
313 ret = adt75_i2c_write(chip, ADT75_CONFIG, config);
314 if (ret)
315 return -EIO;
316
317 chip->config = config;
318
319 return ret;
320}
321
322static ssize_t adt75_show_available_oti_modes(struct device *dev,
323 struct device_attribute *attr,
324 char *buf)
325{
326 return sprintf(buf, "comparator\ninterrupt\n");
327}
328
329static ssize_t adt75_show_smbus_alart(struct device *dev,
330 struct device_attribute *attr,
331 char *buf)
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
337 /* retrive ALART status */
338 ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config);
339 if (ret)
340 return -EIO;
341
342 return sprintf(buf, "%d\n", !!(chip->config & ADT75_SMBUS_ALART));
343}
344
345static ssize_t adt75_set_smbus_alart(struct device *dev,
346 struct device_attribute *attr,
347 const char *buf,
348 size_t len)
349{
350 struct iio_dev *dev_info = dev_get_drvdata(dev);
351 struct adt75_chip_info *chip = dev_info->dev_data;
352 unsigned long data = 0;
353 int ret;
354 u8 config;
355
356 ret = strict_strtoul(buf, 10, &data);
357 if (ret)
358 return -EINVAL;
359
360 /* retrive ALART status */
361 ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config);
362 if (ret)
363 return -EIO;
364
365 config = chip->config & ~ADT75_SMBUS_ALART;
366 if (data)
367 config |= ADT75_SMBUS_ALART;
368
369 ret = adt75_i2c_write(chip, ADT75_CONFIG, config);
370 if (ret)
371 return -EIO;
372
373 chip->config = config;
374
375 return ret;
376}
377
378static ssize_t adt75_show_fault_queue(struct device *dev,
379 struct device_attribute *attr,
380 char *buf)
381{
382 struct iio_dev *dev_info = dev_get_drvdata(dev);
383 struct adt75_chip_info *chip = dev_info->dev_data;
384 int ret;
385
386 /* retrive ALART status */
387 ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config);
388 if (ret)
389 return -EIO;
390
391 return sprintf(buf, "%d\n", (chip->config & ADT75_FAULT_QUEUE_MASK) >>
392 ADT75_FAULT_QUEUE_OFFSET);
393}
394
395static ssize_t adt75_set_fault_queue(struct device *dev,
396 struct device_attribute *attr,
397 const char *buf,
398 size_t len)
399{
400 struct iio_dev *dev_info = dev_get_drvdata(dev);
401 struct adt75_chip_info *chip = dev_info->dev_data;
402 unsigned long data;
403 int ret;
404 u8 config;
405
406 ret = strict_strtoul(buf, 10, &data);
407 if (ret || data > 3)
408 return -EINVAL;
409
410 /* retrive ALART status */
411 ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config);
412 if (ret)
413 return -EIO;
414
415 config = chip->config & ~ADT75_FAULT_QUEUE_MASK;
416 config |= (data << ADT75_FAULT_QUEUE_OFFSET);
417 ret = adt75_i2c_write(chip, ADT75_CONFIG, config);
418 if (ret)
419 return -EIO;
420
421 chip->config = config;
422
423 return ret;
424}
425static inline ssize_t adt75_show_t_bound(struct device *dev,
426 struct device_attribute *attr,
d7713b6c
SZ
427 char *buf)
428{
1142f709 429 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
d7713b6c
SZ
430 struct iio_dev *dev_info = dev_get_drvdata(dev);
431 struct adt75_chip_info *chip = dev_info->dev_data;
432 u16 data;
433 char sign = ' ';
434 int ret;
435
1142f709 436 ret = adt75_i2c_read(chip, this_attr->address, (u8 *)&data);
d7713b6c
SZ
437 if (ret)
438 return -EIO;
439
440 data = swab16(data) >> ADT75_VALUE_OFFSET;
441 if (data & ADT75_VALUE_SIGN) {
442 /* convert supplement to positive value */
443 data = (ADT75_VALUE_SIGN << 1) - data;
444 sign = '-';
445 }
446
447 return sprintf(buf, "%c%d.%.4d\n", sign,
448 (data >> ADT75_VALUE_FLOAT_OFFSET),
449 (data & ADT75_VALUE_FLOAT_MASK) * 625);
450}
451
452static inline ssize_t adt75_set_t_bound(struct device *dev,
453 struct device_attribute *attr,
d7713b6c
SZ
454 const char *buf,
455 size_t len)
456{
1142f709 457 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
d7713b6c
SZ
458 struct iio_dev *dev_info = dev_get_drvdata(dev);
459 struct adt75_chip_info *chip = dev_info->dev_data;
460 long tmp1, tmp2;
461 u16 data;
462 char *pos;
463 int ret;
464
465 pos = strchr(buf, '.');
466
467 ret = strict_strtol(buf, 10, &tmp1);
468
469 if (ret || tmp1 > 127 || tmp1 < -128)
470 return -EINVAL;
471
472 if (pos) {
473 len = strlen(pos);
474 if (len > ADT75_VALUE_FLOAT_OFFSET)
475 len = ADT75_VALUE_FLOAT_OFFSET;
476 pos[len] = 0;
477 ret = strict_strtol(pos, 10, &tmp2);
478
479 if (!ret)
480 tmp2 = (tmp2 / 625) * 625;
481 }
482
483 if (tmp1 < 0)
484 data = (u16)(-tmp1);
485 else
486 data = (u16)tmp1;
487 data = (data << ADT75_VALUE_FLOAT_OFFSET) | (tmp2 & ADT75_VALUE_FLOAT_MASK);
488 if (tmp1 < 0)
489 /* convert positive value to supplyment */
490 data = (ADT75_VALUE_SIGN << 1) - data;
491 data <<= ADT75_VALUE_OFFSET;
492 data = swab16(data);
493
1142f709 494 ret = adt75_i2c_write(chip, this_attr->address, (u8)data);
d7713b6c
SZ
495 if (ret)
496 return -EIO;
497
498 return ret;
499}
500
d7713b6c 501
1142f709
JC
502static IIO_DEVICE_ATTR(oti_mode,
503 S_IRUGO | S_IWUSR,
504 adt75_show_oti_mode, adt75_set_oti_mode, 0);
505static IIO_DEVICE_ATTR(available_oti_modes,
506 S_IRUGO,
507 adt75_show_available_oti_modes, NULL, 0);
508static IIO_DEVICE_ATTR(smbus_alart,
509 S_IRUGO | S_IWUSR,
510 adt75_show_smbus_alart, adt75_set_smbus_alart, 0);
511static IIO_DEVICE_ATTR(fault_queue,
512 S_IRUGO | S_IWUSR,
513 adt75_show_fault_queue, adt75_set_fault_queue, 0);
514static IIO_DEVICE_ATTR(t_os_value,
515 S_IRUGO | S_IWUSR,
516 adt75_show_t_bound, adt75_set_t_bound,
517 ADT75_T_OS);
518static IIO_DEVICE_ATTR(t_hyst_value,
519 S_IRUGO | S_IWUSR,
520 adt75_show_t_bound, adt75_set_t_bound,
521 ADT75_T_HYST);
d7713b6c
SZ
522
523static struct attribute *adt75_event_attributes[] = {
1142f709
JC
524 &iio_dev_attr_oti_mode.dev_attr.attr,
525 &iio_dev_attr_available_oti_modes.dev_attr.attr,
526 &iio_dev_attr_smbus_alart.dev_attr.attr,
527 &iio_dev_attr_fault_queue.dev_attr.attr,
528 &iio_dev_attr_t_os_value.dev_attr.attr,
529 &iio_dev_attr_t_hyst_value.dev_attr.attr,
d7713b6c
SZ
530 NULL,
531};
532
533static struct attribute_group adt75_event_attribute_group = {
534 .attrs = adt75_event_attributes,
535};
536
6fe8135f
JC
537static const struct iio_info adt75_info = {
538 .attrs = &adt75_attribute_group,
539 .num_interrupt_lines = 1,
540 .event_attrs = &adt75_event_attribute_group,
541 .driver_module = THIS_MODULE,
542};
543
d7713b6c
SZ
544/*
545 * device probe and remove
546 */
547
548static int __devinit adt75_probe(struct i2c_client *client,
549 const struct i2c_device_id *id)
550{
551 struct adt75_chip_info *chip;
552 int ret = 0;
553
554 chip = kzalloc(sizeof(struct adt75_chip_info), GFP_KERNEL);
555
556 if (chip == NULL)
557 return -ENOMEM;
558
559 /* this is only used for device removal purposes */
560 i2c_set_clientdata(client, chip);
561
562 chip->client = client;
d7713b6c 563
6f7c8ee5 564 chip->indio_dev = iio_allocate_device(0);
d7713b6c
SZ
565 if (chip->indio_dev == NULL) {
566 ret = -ENOMEM;
567 goto error_free_chip;
568 }
569
845bd12a 570 chip->indio_dev->name = id->name;
d7713b6c 571 chip->indio_dev->dev.parent = &client->dev;
6fe8135f 572 chip->indio_dev->info = &adt75_info;
d7713b6c 573 chip->indio_dev->dev_data = (void *)chip;
d7713b6c
SZ
574 chip->indio_dev->modes = INDIO_DIRECT_MODE;
575
576 ret = iio_device_register(chip->indio_dev);
577 if (ret)
578 goto error_free_dev;
579
580 if (client->irq > 0) {
1142f709
JC
581 ret = request_threaded_irq(client->irq,
582 NULL,
583 &adt75_event_handler,
584 IRQF_TRIGGER_LOW,
845bd12a 585 chip->indio_dev->name,
1142f709 586 chip->indio_dev);
d7713b6c
SZ
587 if (ret)
588 goto error_unreg_dev;
589
d7713b6c
SZ
590 ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config);
591 if (ret) {
592 ret = -EIO;
593 goto error_unreg_irq;
594 }
595
596 /* set irq polarity low level */
597 chip->config &= ~ADT75_OS_POLARITY;
598
599 ret = adt75_i2c_write(chip, ADT75_CONFIG, chip->config);
600 if (ret) {
601 ret = -EIO;
602 goto error_unreg_irq;
603 }
604 }
605
606 dev_info(&client->dev, "%s temperature sensor registered.\n",
845bd12a 607 chip->indio_dev->name);
d7713b6c
SZ
608
609 return 0;
610error_unreg_irq:
1142f709 611 free_irq(client->irq, chip->indio_dev);
d7713b6c
SZ
612error_unreg_dev:
613 iio_device_unregister(chip->indio_dev);
614error_free_dev:
615 iio_free_device(chip->indio_dev);
616error_free_chip:
617 kfree(chip);
618
619 return ret;
620}
621
622static int __devexit adt75_remove(struct i2c_client *client)
623{
624 struct adt75_chip_info *chip = i2c_get_clientdata(client);
625 struct iio_dev *indio_dev = chip->indio_dev;
626
627 if (client->irq)
1142f709 628 free_irq(client->irq, chip->indio_dev);
d7713b6c
SZ
629 iio_device_unregister(indio_dev);
630 iio_free_device(chip->indio_dev);
631 kfree(chip);
632
633 return 0;
634}
635
636static const struct i2c_device_id adt75_id[] = {
637 { "adt75", 0 },
638 {}
639};
640
641MODULE_DEVICE_TABLE(i2c, adt75_id);
642
643static struct i2c_driver adt75_driver = {
644 .driver = {
645 .name = "adt75",
646 },
647 .probe = adt75_probe,
648 .remove = __devexit_p(adt75_remove),
649 .id_table = adt75_id,
650};
651
652static __init int adt75_init(void)
653{
654 return i2c_add_driver(&adt75_driver);
655}
656
657static __exit void adt75_exit(void)
658{
659 i2c_del_driver(&adt75_driver);
660}
661
662MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
663MODULE_DESCRIPTION("Analog Devices ADT75 digital"
664 " temperature sensor driver");
665MODULE_LICENSE("GPL v2");
666
667module_init(adt75_init);
668module_exit(adt75_exit);