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