pandora: defconfig: update
[pandora-kernel.git] / drivers / staging / iio / adc / adt7410.c
1 /*
2  * ADT7410 digital temperature sensor driver supporting ADT7410
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/i2c.h>
16 #include <linux/module.h>
17
18 #include "../iio.h"
19 #include "../sysfs.h"
20
21 /*
22  * ADT7410 registers definition
23  */
24
25 #define ADT7410_TEMPERATURE             0
26 #define ADT7410_STATUS                  2
27 #define ADT7410_CONFIG                  3
28 #define ADT7410_T_ALARM_HIGH            4
29 #define ADT7410_T_ALARM_LOW             6
30 #define ADT7410_T_CRIT                  8
31 #define ADT7410_T_HYST                  0xA
32 #define ADT7410_ID                      0xB
33 #define ADT7410_RESET                   0x2F
34
35 /*
36  * ADT7410 status
37  */
38 #define ADT7410_STAT_T_LOW              0x10
39 #define ADT7410_STAT_T_HIGH             0x20
40 #define ADT7410_STAT_T_CRIT             0x40
41 #define ADT7410_STAT_NOT_RDY            0x80
42
43 /*
44  * ADT7410 config
45  */
46 #define ADT7410_FAULT_QUEUE_MASK        0x3
47 #define ADT7410_CT_POLARITY             0x4
48 #define ADT7410_INT_POLARITY            0x8
49 #define ADT7410_EVENT_MODE              0x10
50 #define ADT7410_MODE_MASK               0x60
51 #define ADT7410_ONESHOT                 0x20
52 #define ADT7410_SPS                     0x40
53 #define ADT7410_PD                      0x60
54 #define ADT7410_RESOLUTION              0x80
55
56 /*
57  * ADT7410 masks
58  */
59 #define ADT7410_T16_VALUE_SIGN                  0x8000
60 #define ADT7410_T16_VALUE_FLOAT_OFFSET          7
61 #define ADT7410_T16_VALUE_FLOAT_MASK            0x7F
62 #define ADT7410_T13_VALUE_SIGN                  0x1000
63 #define ADT7410_T13_VALUE_OFFSET                3
64 #define ADT7410_T13_VALUE_FLOAT_OFFSET          4
65 #define ADT7410_T13_VALUE_FLOAT_MASK            0xF
66 #define ADT7410_T_HYST_MASK                     0xF
67 #define ADT7410_DEVICE_ID_MASK                  0xF
68 #define ADT7410_MANUFACTORY_ID_MASK             0xF0
69 #define ADT7410_MANUFACTORY_ID_OFFSET           4
70
71 #define ADT7410_IRQS                            2
72
73 /*
74  * struct adt7410_chip_info - chip specifc information
75  */
76
77 struct adt7410_chip_info {
78         struct i2c_client *client;
79         u8  config;
80 };
81
82 /*
83  * adt7410 register access by I2C
84  */
85
86 static int adt7410_i2c_read_word(struct adt7410_chip_info *chip, u8 reg, u16 *data)
87 {
88         struct i2c_client *client = chip->client;
89         int ret = 0;
90
91         ret = i2c_smbus_read_word_data(client, reg);
92         if (ret < 0) {
93                 dev_err(&client->dev, "I2C read error\n");
94                 return ret;
95         }
96
97         *data = swab16((u16)ret);
98
99         return 0;
100 }
101
102 static int adt7410_i2c_write_word(struct adt7410_chip_info *chip, u8 reg, u16 data)
103 {
104         struct i2c_client *client = chip->client;
105         int ret = 0;
106
107         ret = i2c_smbus_write_word_data(client, reg, swab16(data));
108         if (ret < 0)
109                 dev_err(&client->dev, "I2C write error\n");
110
111         return ret;
112 }
113
114 static int adt7410_i2c_read_byte(struct adt7410_chip_info *chip, u8 reg, u8 *data)
115 {
116         struct i2c_client *client = chip->client;
117         int ret = 0;
118
119         ret = i2c_smbus_read_byte_data(client, reg);
120         if (ret < 0) {
121                 dev_err(&client->dev, "I2C read error\n");
122                 return ret;
123         }
124
125         *data = (u8)ret;
126
127         return 0;
128 }
129
130 static int adt7410_i2c_write_byte(struct adt7410_chip_info *chip, u8 reg, u8 data)
131 {
132         struct i2c_client *client = chip->client;
133         int ret = 0;
134
135         ret = i2c_smbus_write_byte_data(client, reg, data);
136         if (ret < 0)
137                 dev_err(&client->dev, "I2C write error\n");
138
139         return ret;
140 }
141
142 static ssize_t adt7410_show_mode(struct device *dev,
143                 struct device_attribute *attr,
144                 char *buf)
145 {
146         struct iio_dev *dev_info = dev_get_drvdata(dev);
147         struct adt7410_chip_info *chip = iio_priv(dev_info);
148         u8 config;
149
150         config = chip->config & ADT7410_MODE_MASK;
151
152         switch (config) {
153         case ADT7410_PD:
154                 return sprintf(buf, "power-down\n");
155         case ADT7410_ONESHOT:
156                 return sprintf(buf, "one-shot\n");
157         case ADT7410_SPS:
158                 return sprintf(buf, "sps\n");
159         default:
160                 return sprintf(buf, "full\n");
161         }
162 }
163
164 static ssize_t adt7410_store_mode(struct device *dev,
165                 struct device_attribute *attr,
166                 const char *buf,
167                 size_t len)
168 {
169         struct iio_dev *dev_info = dev_get_drvdata(dev);
170         struct adt7410_chip_info *chip = iio_priv(dev_info);
171         u16 config;
172         int ret;
173
174         ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config);
175         if (ret)
176                 return -EIO;
177
178         config = chip->config & (~ADT7410_MODE_MASK);
179         if (strcmp(buf, "power-down"))
180                 config |= ADT7410_PD;
181         else if (strcmp(buf, "one-shot"))
182                 config |= ADT7410_ONESHOT;
183         else if (strcmp(buf, "sps"))
184                 config |= ADT7410_SPS;
185
186         ret = adt7410_i2c_write_byte(chip, ADT7410_CONFIG, config);
187         if (ret)
188                 return -EIO;
189
190         chip->config = config;
191
192         return ret;
193 }
194
195 static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
196                 adt7410_show_mode,
197                 adt7410_store_mode,
198                 0);
199
200 static ssize_t adt7410_show_available_modes(struct device *dev,
201                 struct device_attribute *attr,
202                 char *buf)
203 {
204         return sprintf(buf, "full\none-shot\nsps\npower-down\n");
205 }
206
207 static IIO_DEVICE_ATTR(available_modes, S_IRUGO, adt7410_show_available_modes, NULL, 0);
208
209 static ssize_t adt7410_show_resolution(struct device *dev,
210                 struct device_attribute *attr,
211                 char *buf)
212 {
213         struct iio_dev *dev_info = dev_get_drvdata(dev);
214         struct adt7410_chip_info *chip = iio_priv(dev_info);
215         int ret;
216         int bits;
217
218         ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config);
219         if (ret)
220                 return -EIO;
221
222         if (chip->config & ADT7410_RESOLUTION)
223                 bits = 16;
224         else
225                 bits = 13;
226
227         return sprintf(buf, "%d bits\n", bits);
228 }
229
230 static ssize_t adt7410_store_resolution(struct device *dev,
231                 struct device_attribute *attr,
232                 const char *buf,
233                 size_t len)
234 {
235         struct iio_dev *dev_info = dev_get_drvdata(dev);
236         struct adt7410_chip_info *chip = iio_priv(dev_info);
237         unsigned long data;
238         u16 config;
239         int ret;
240
241         ret = strict_strtoul(buf, 10, &data);
242         if (ret)
243                 return -EINVAL;
244
245         ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config);
246         if (ret)
247                 return -EIO;
248
249         config = chip->config & (~ADT7410_RESOLUTION);
250         if (data)
251                 config |= ADT7410_RESOLUTION;
252
253         ret = adt7410_i2c_write_byte(chip, ADT7410_CONFIG, config);
254         if (ret)
255                 return -EIO;
256
257         chip->config = config;
258
259         return ret;
260 }
261
262 static IIO_DEVICE_ATTR(resolution, S_IRUGO | S_IWUSR,
263                 adt7410_show_resolution,
264                 adt7410_store_resolution,
265                 0);
266
267 static ssize_t adt7410_show_id(struct device *dev,
268                 struct device_attribute *attr,
269                 char *buf)
270 {
271         struct iio_dev *dev_info = dev_get_drvdata(dev);
272         struct adt7410_chip_info *chip = iio_priv(dev_info);
273         u8 id;
274         int ret;
275
276         ret = adt7410_i2c_read_byte(chip, ADT7410_ID, &id);
277         if (ret)
278                 return -EIO;
279
280         return sprintf(buf, "device id: 0x%x\nmanufactory id: 0x%x\n",
281                         id & ADT7410_DEVICE_ID_MASK,
282                         (id & ADT7410_MANUFACTORY_ID_MASK) >> ADT7410_MANUFACTORY_ID_OFFSET);
283 }
284
285 static IIO_DEVICE_ATTR(id, S_IRUGO | S_IWUSR,
286                 adt7410_show_id,
287                 NULL,
288                 0);
289
290 static ssize_t adt7410_convert_temperature(struct adt7410_chip_info *chip,
291                 u16 data, char *buf)
292 {
293         char sign = ' ';
294
295         if (chip->config & ADT7410_RESOLUTION) {
296                 if (data & ADT7410_T16_VALUE_SIGN) {
297                         /* convert supplement to positive value */
298                         data = (u16)((ADT7410_T16_VALUE_SIGN << 1) - (u32)data);
299                         sign = '-';
300                 }
301                 return sprintf(buf, "%c%d.%.7d\n", sign,
302                                 (data >> ADT7410_T16_VALUE_FLOAT_OFFSET),
303                                 (data & ADT7410_T16_VALUE_FLOAT_MASK) * 78125);
304         } else {
305                 if (data & ADT7410_T13_VALUE_SIGN) {
306                         /* convert supplement to positive value */
307                         data >>= ADT7410_T13_VALUE_OFFSET;
308                         data = (ADT7410_T13_VALUE_SIGN << 1) - data;
309                         sign = '-';
310                 }
311                 return sprintf(buf, "%c%d.%.4d\n", sign,
312                                 (data >> ADT7410_T13_VALUE_FLOAT_OFFSET),
313                                 (data & ADT7410_T13_VALUE_FLOAT_MASK) * 625);
314         }
315 }
316
317 static ssize_t adt7410_show_value(struct device *dev,
318                 struct device_attribute *attr,
319                 char *buf)
320 {
321         struct iio_dev *dev_info = dev_get_drvdata(dev);
322         struct adt7410_chip_info *chip = iio_priv(dev_info);
323         u8 status;
324         u16 data;
325         int ret, i = 0;
326
327         do {
328                 ret = adt7410_i2c_read_byte(chip, ADT7410_STATUS, &status);
329                 if (ret)
330                         return -EIO;
331                 i++;
332                 if (i == 10000)
333                         return -EIO;
334         } while (status & ADT7410_STAT_NOT_RDY);
335
336         ret = adt7410_i2c_read_word(chip, ADT7410_TEMPERATURE, &data);
337         if (ret)
338                 return -EIO;
339
340         return adt7410_convert_temperature(chip, data, buf);
341 }
342
343 static IIO_DEVICE_ATTR(value, S_IRUGO, adt7410_show_value, NULL, 0);
344
345 static struct attribute *adt7410_attributes[] = {
346         &iio_dev_attr_available_modes.dev_attr.attr,
347         &iio_dev_attr_mode.dev_attr.attr,
348         &iio_dev_attr_resolution.dev_attr.attr,
349         &iio_dev_attr_id.dev_attr.attr,
350         &iio_dev_attr_value.dev_attr.attr,
351         NULL,
352 };
353
354 static const struct attribute_group adt7410_attribute_group = {
355         .attrs = adt7410_attributes,
356 };
357
358 static irqreturn_t adt7410_event_handler(int irq, void *private)
359 {
360         struct iio_dev *indio_dev = private;
361         struct adt7410_chip_info *chip = iio_priv(indio_dev);
362         s64 timestamp = iio_get_time_ns();
363         u8 status;
364
365         if (adt7410_i2c_read_byte(chip, ADT7410_STATUS, &status))
366                 return IRQ_HANDLED;
367
368         if (status & ADT7410_STAT_T_HIGH)
369                 iio_push_event(indio_dev,
370                                IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0,
371                                                     IIO_EV_TYPE_THRESH,
372                                                     IIO_EV_DIR_RISING),
373                                timestamp);
374         if (status & ADT7410_STAT_T_LOW)
375                 iio_push_event(indio_dev,
376                                IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0,
377                                                     IIO_EV_TYPE_THRESH,
378                                                     IIO_EV_DIR_FALLING),
379                                timestamp);
380         if (status & ADT7410_STAT_T_CRIT)
381                 iio_push_event(indio_dev,
382                                IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0,
383                                                     IIO_EV_TYPE_THRESH,
384                                                     IIO_EV_DIR_RISING),
385                                timestamp);
386
387         return IRQ_HANDLED;
388 }
389
390 static ssize_t adt7410_show_event_mode(struct device *dev,
391                 struct device_attribute *attr,
392                 char *buf)
393 {
394         struct iio_dev *dev_info = dev_get_drvdata(dev);
395         struct adt7410_chip_info *chip = iio_priv(dev_info);
396         int ret;
397
398         ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config);
399         if (ret)
400                 return -EIO;
401
402         if (chip->config & ADT7410_EVENT_MODE)
403                 return sprintf(buf, "interrupt\n");
404         else
405                 return sprintf(buf, "comparator\n");
406 }
407
408 static ssize_t adt7410_set_event_mode(struct device *dev,
409                 struct device_attribute *attr,
410                 const char *buf,
411                 size_t len)
412 {
413         struct iio_dev *dev_info = dev_get_drvdata(dev);
414         struct adt7410_chip_info *chip = iio_priv(dev_info);
415         u16 config;
416         int ret;
417
418         ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config);
419         if (ret)
420                 return -EIO;
421
422         config = chip->config &= ~ADT7410_EVENT_MODE;
423         if (strcmp(buf, "comparator") != 0)
424                 config |= ADT7410_EVENT_MODE;
425
426         ret = adt7410_i2c_write_byte(chip, ADT7410_CONFIG, config);
427         if (ret)
428                 return -EIO;
429
430         chip->config = config;
431
432         return ret;
433 }
434
435 static ssize_t adt7410_show_available_event_modes(struct device *dev,
436                 struct device_attribute *attr,
437                 char *buf)
438 {
439         return sprintf(buf, "comparator\ninterrupt\n");
440 }
441
442 static ssize_t adt7410_show_fault_queue(struct device *dev,
443                 struct device_attribute *attr,
444                 char *buf)
445 {
446         struct iio_dev *dev_info = dev_get_drvdata(dev);
447         struct adt7410_chip_info *chip = iio_priv(dev_info);
448         int ret;
449
450         ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config);
451         if (ret)
452                 return -EIO;
453
454         return sprintf(buf, "%d\n", chip->config & ADT7410_FAULT_QUEUE_MASK);
455 }
456
457 static ssize_t adt7410_set_fault_queue(struct device *dev,
458                 struct device_attribute *attr,
459                 const char *buf,
460                 size_t len)
461 {
462         struct iio_dev *dev_info = dev_get_drvdata(dev);
463         struct adt7410_chip_info *chip = iio_priv(dev_info);
464         unsigned long data;
465         int ret;
466         u8 config;
467
468         ret = strict_strtoul(buf, 10, &data);
469         if (ret || data > 3)
470                 return -EINVAL;
471
472         ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config);
473         if (ret)
474                 return -EIO;
475
476         config = chip->config & ~ADT7410_FAULT_QUEUE_MASK;
477         config |= data;
478         ret = adt7410_i2c_write_byte(chip, ADT7410_CONFIG, config);
479         if (ret)
480                 return -EIO;
481
482         chip->config = config;
483
484         return ret;
485 }
486
487 static inline ssize_t adt7410_show_t_bound(struct device *dev,
488                 struct device_attribute *attr,
489                 u8 bound_reg,
490                 char *buf)
491 {
492         struct iio_dev *dev_info = dev_get_drvdata(dev);
493         struct adt7410_chip_info *chip = iio_priv(dev_info);
494         u16 data;
495         int ret;
496
497         ret = adt7410_i2c_read_word(chip, bound_reg, &data);
498         if (ret)
499                 return -EIO;
500
501         return adt7410_convert_temperature(chip, data, buf);
502 }
503
504 static inline ssize_t adt7410_set_t_bound(struct device *dev,
505                 struct device_attribute *attr,
506                 u8 bound_reg,
507                 const char *buf,
508                 size_t len)
509 {
510         struct iio_dev *dev_info = dev_get_drvdata(dev);
511         struct adt7410_chip_info *chip = iio_priv(dev_info);
512         long tmp1, tmp2;
513         u16 data;
514         char *pos;
515         int ret;
516
517         pos = strchr(buf, '.');
518
519         ret = strict_strtol(buf, 10, &tmp1);
520
521         if (ret || tmp1 > 127 || tmp1 < -128)
522                 return -EINVAL;
523
524         if (pos) {
525                 len = strlen(pos);
526
527                 if (chip->config & ADT7410_RESOLUTION) {
528                         if (len > ADT7410_T16_VALUE_FLOAT_OFFSET)
529                                 len = ADT7410_T16_VALUE_FLOAT_OFFSET;
530                         pos[len] = 0;
531                         ret = strict_strtol(pos, 10, &tmp2);
532
533                         if (!ret)
534                                 tmp2 = (tmp2 / 78125) * 78125;
535                 } else {
536                         if (len > ADT7410_T13_VALUE_FLOAT_OFFSET)
537                                 len = ADT7410_T13_VALUE_FLOAT_OFFSET;
538                         pos[len] = 0;
539                         ret = strict_strtol(pos, 10, &tmp2);
540
541                         if (!ret)
542                                 tmp2 = (tmp2 / 625) * 625;
543                 }
544         }
545
546         if (tmp1 < 0)
547                 data = (u16)(-tmp1);
548         else
549                 data = (u16)tmp1;
550
551         if (chip->config & ADT7410_RESOLUTION) {
552                 data = (data << ADT7410_T16_VALUE_FLOAT_OFFSET) |
553                         (tmp2 & ADT7410_T16_VALUE_FLOAT_MASK);
554
555                 if (tmp1 < 0)
556                         /* convert positive value to supplyment */
557                         data = (u16)((ADT7410_T16_VALUE_SIGN << 1) - (u32)data);
558         } else {
559                 data = (data << ADT7410_T13_VALUE_FLOAT_OFFSET) |
560                         (tmp2 & ADT7410_T13_VALUE_FLOAT_MASK);
561
562                 if (tmp1 < 0)
563                         /* convert positive value to supplyment */
564                         data = (ADT7410_T13_VALUE_SIGN << 1) - data;
565                 data <<= ADT7410_T13_VALUE_OFFSET;
566         }
567
568         ret = adt7410_i2c_write_word(chip, bound_reg, data);
569         if (ret)
570                 return -EIO;
571
572         return ret;
573 }
574
575 static ssize_t adt7410_show_t_alarm_high(struct device *dev,
576                 struct device_attribute *attr,
577                 char *buf)
578 {
579         return adt7410_show_t_bound(dev, attr,
580                         ADT7410_T_ALARM_HIGH, buf);
581 }
582
583 static inline ssize_t adt7410_set_t_alarm_high(struct device *dev,
584                 struct device_attribute *attr,
585                 const char *buf,
586                 size_t len)
587 {
588         return adt7410_set_t_bound(dev, attr,
589                         ADT7410_T_ALARM_HIGH, buf, len);
590 }
591
592 static ssize_t adt7410_show_t_alarm_low(struct device *dev,
593                 struct device_attribute *attr,
594                 char *buf)
595 {
596         return adt7410_show_t_bound(dev, attr,
597                         ADT7410_T_ALARM_LOW, buf);
598 }
599
600 static inline ssize_t adt7410_set_t_alarm_low(struct device *dev,
601                 struct device_attribute *attr,
602                 const char *buf,
603                 size_t len)
604 {
605         return adt7410_set_t_bound(dev, attr,
606                         ADT7410_T_ALARM_LOW, buf, len);
607 }
608
609 static ssize_t adt7410_show_t_crit(struct device *dev,
610                 struct device_attribute *attr,
611                 char *buf)
612 {
613         return adt7410_show_t_bound(dev, attr,
614                         ADT7410_T_CRIT, buf);
615 }
616
617 static inline ssize_t adt7410_set_t_crit(struct device *dev,
618                 struct device_attribute *attr,
619                 const char *buf,
620                 size_t len)
621 {
622         return adt7410_set_t_bound(dev, attr,
623                         ADT7410_T_CRIT, buf, len);
624 }
625
626 static ssize_t adt7410_show_t_hyst(struct device *dev,
627                 struct device_attribute *attr,
628                 char *buf)
629 {
630         struct iio_dev *dev_info = dev_get_drvdata(dev);
631         struct adt7410_chip_info *chip = iio_priv(dev_info);
632         int ret;
633         u8 t_hyst;
634
635         ret = adt7410_i2c_read_byte(chip, ADT7410_T_HYST, &t_hyst);
636         if (ret)
637                 return -EIO;
638
639         return sprintf(buf, "%d\n", t_hyst & ADT7410_T_HYST_MASK);
640 }
641
642 static inline ssize_t adt7410_set_t_hyst(struct device *dev,
643                 struct device_attribute *attr,
644                 const char *buf,
645                 size_t len)
646 {
647         struct iio_dev *dev_info = dev_get_drvdata(dev);
648         struct adt7410_chip_info *chip = iio_priv(dev_info);
649         int ret;
650         unsigned long data;
651         u8 t_hyst;
652
653         ret = strict_strtol(buf, 10, &data);
654
655         if (ret || data > ADT7410_T_HYST_MASK)
656                 return -EINVAL;
657
658         t_hyst = (u8)data;
659
660         ret = adt7410_i2c_write_byte(chip, ADT7410_T_HYST, t_hyst);
661         if (ret)
662                 return -EIO;
663
664         return ret;
665 }
666
667 static IIO_DEVICE_ATTR(event_mode,
668                        S_IRUGO | S_IWUSR,
669                        adt7410_show_event_mode, adt7410_set_event_mode, 0);
670 static IIO_DEVICE_ATTR(available_event_modes,
671                        S_IRUGO,
672                        adt7410_show_available_event_modes, NULL, 0);
673 static IIO_DEVICE_ATTR(fault_queue,
674                        S_IRUGO | S_IWUSR,
675                        adt7410_show_fault_queue, adt7410_set_fault_queue, 0);
676 static IIO_DEVICE_ATTR(t_alarm_high,
677                        S_IRUGO | S_IWUSR,
678                        adt7410_show_t_alarm_high, adt7410_set_t_alarm_high, 0);
679 static IIO_DEVICE_ATTR(t_alarm_low,
680                        S_IRUGO | S_IWUSR,
681                        adt7410_show_t_alarm_low, adt7410_set_t_alarm_low, 0);
682 static IIO_DEVICE_ATTR(t_crit,
683                        S_IRUGO | S_IWUSR,
684                        adt7410_show_t_crit, adt7410_set_t_crit, 0);
685 static IIO_DEVICE_ATTR(t_hyst,
686                        S_IRUGO | S_IWUSR,
687                        adt7410_show_t_hyst, adt7410_set_t_hyst, 0);
688
689 static struct attribute *adt7410_event_int_attributes[] = {
690         &iio_dev_attr_event_mode.dev_attr.attr,
691         &iio_dev_attr_available_event_modes.dev_attr.attr,
692         &iio_dev_attr_fault_queue.dev_attr.attr,
693         &iio_dev_attr_t_alarm_high.dev_attr.attr,
694         &iio_dev_attr_t_alarm_low.dev_attr.attr,
695         &iio_dev_attr_t_hyst.dev_attr.attr,
696         NULL,
697 };
698
699 static struct attribute *adt7410_event_ct_attributes[] = {
700         &iio_dev_attr_event_mode.dev_attr.attr,
701         &iio_dev_attr_available_event_modes.dev_attr.attr,
702         &iio_dev_attr_fault_queue.dev_attr.attr,
703         &iio_dev_attr_t_crit.dev_attr.attr,
704         &iio_dev_attr_t_hyst.dev_attr.attr,
705         NULL,
706 };
707
708 static struct attribute_group adt7410_event_attribute_group[ADT7410_IRQS] = {
709         {
710                 .attrs = adt7410_event_int_attributes,
711                 .name = "events",
712         }, {
713                 .attrs = adt7410_event_ct_attributes,
714                 .name = "events",
715         }
716 };
717
718 static const struct iio_info adt7410_info = {
719         .attrs = &adt7410_attribute_group,
720         .event_attrs = adt7410_event_attribute_group,
721         .driver_module = THIS_MODULE,
722 };
723
724 /*
725  * device probe and remove
726  */
727
728 static int __devinit adt7410_probe(struct i2c_client *client,
729                 const struct i2c_device_id *id)
730 {
731         struct adt7410_chip_info *chip;
732         struct iio_dev *indio_dev;
733         int ret = 0;
734         unsigned long *adt7410_platform_data = client->dev.platform_data;
735
736         indio_dev = iio_allocate_device(sizeof(*chip));
737         if (indio_dev == NULL) {
738                 ret = -ENOMEM;
739                 goto error_ret;
740         }
741         chip = iio_priv(indio_dev);
742         /* this is only used for device removal purposes */
743         i2c_set_clientdata(client, indio_dev);
744
745         chip->client = client;
746
747         indio_dev->name = id->name;
748         indio_dev->dev.parent = &client->dev;
749         indio_dev->info = &adt7410_info;
750         indio_dev->modes = INDIO_DIRECT_MODE;
751
752         /* CT critcal temperature event. line 0 */
753         if (client->irq) {
754                 ret = request_threaded_irq(client->irq,
755                                            NULL,
756                                            &adt7410_event_handler,
757                                            IRQF_TRIGGER_LOW,
758                                            id->name,
759                                            indio_dev);
760                 if (ret)
761                         goto error_free_dev;
762         }
763
764         /* INT bound temperature alarm event. line 1 */
765         if (adt7410_platform_data[0]) {
766                 ret = request_threaded_irq(adt7410_platform_data[0],
767                                            NULL,
768                                            &adt7410_event_handler,
769                                            adt7410_platform_data[1],
770                                            id->name,
771                                            indio_dev);
772                 if (ret)
773                         goto error_unreg_ct_irq;
774         }
775
776         if (client->irq && adt7410_platform_data[0]) {
777
778                 ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config);
779                 if (ret) {
780                         ret = -EIO;
781                         goto error_unreg_int_irq;
782                 }
783
784                 /* set irq polarity low level */
785                 chip->config &= ~ADT7410_CT_POLARITY;
786
787                 if (adt7410_platform_data[1] & IRQF_TRIGGER_HIGH)
788                         chip->config |= ADT7410_INT_POLARITY;
789                 else
790                         chip->config &= ~ADT7410_INT_POLARITY;
791
792                 ret = adt7410_i2c_write_byte(chip, ADT7410_CONFIG, chip->config);
793                 if (ret) {
794                         ret = -EIO;
795                         goto error_unreg_int_irq;
796                 }
797         }
798         ret = iio_device_register(indio_dev);
799         if (ret)
800                 goto error_unreg_int_irq;
801
802         dev_info(&client->dev, "%s temperature sensor registered.\n",
803                          id->name);
804
805         return 0;
806
807 error_unreg_int_irq:
808         free_irq(adt7410_platform_data[0], indio_dev);
809 error_unreg_ct_irq:
810         free_irq(client->irq, indio_dev);
811 error_free_dev:
812         iio_free_device(indio_dev);
813 error_ret:
814         return ret;
815 }
816
817 static int __devexit adt7410_remove(struct i2c_client *client)
818 {
819         struct iio_dev *indio_dev = i2c_get_clientdata(client);
820         unsigned long *adt7410_platform_data = client->dev.platform_data;
821
822         iio_device_unregister(indio_dev);
823         if (adt7410_platform_data[0])
824                 free_irq(adt7410_platform_data[0], indio_dev);
825         if (client->irq)
826                 free_irq(client->irq, indio_dev);
827         iio_free_device(indio_dev);
828
829         return 0;
830 }
831
832 static const struct i2c_device_id adt7410_id[] = {
833         { "adt7410", 0 },
834         {}
835 };
836
837 MODULE_DEVICE_TABLE(i2c, adt7410_id);
838
839 static struct i2c_driver adt7410_driver = {
840         .driver = {
841                 .name = "adt7410",
842         },
843         .probe = adt7410_probe,
844         .remove = __devexit_p(adt7410_remove),
845         .id_table = adt7410_id,
846 };
847
848 static __init int adt7410_init(void)
849 {
850         return i2c_add_driver(&adt7410_driver);
851 }
852
853 static __exit void adt7410_exit(void)
854 {
855         i2c_del_driver(&adt7410_driver);
856 }
857
858 MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
859 MODULE_DESCRIPTION("Analog Devices ADT7410 digital"
860                         " temperature sensor driver");
861 MODULE_LICENSE("GPL v2");
862
863 module_init(adt7410_init);
864 module_exit(adt7410_exit);