]> Git Repo - linux.git/blob - drivers/staging/iio/adc/adt7310.c
tracing: Replace syscall_meta_data struct array with pointer array
[linux.git] / drivers / staging / iio / adc / adt7310.c
1 /*
2  * ADT7310 digital temperature sensor driver supporting ADT7310
3  *
4  * Copyright 2010 Analog Devices Inc.
5  *
6  * Licensed under the GPL-2 or later.
7  */
8
9 #include <linux/interrupt.h>
10 #include <linux/gpio.h>
11 #include <linux/workqueue.h>
12 #include <linux/device.h>
13 #include <linux/kernel.h>
14 #include <linux/slab.h>
15 #include <linux/sysfs.h>
16 #include <linux/list.h>
17 #include <linux/spi/spi.h>
18 #include <linux/rtc.h>
19
20 #include "../iio.h"
21 #include "../sysfs.h"
22
23 /*
24  * ADT7310 registers definition
25  */
26
27 #define ADT7310_STATUS                  0
28 #define ADT7310_CONFIG                  1
29 #define ADT7310_TEMPERATURE             2
30 #define ADT7310_ID                      3
31 #define ADT7310_T_CRIT                  4
32 #define ADT7310_T_HYST                  5
33 #define ADT7310_T_ALARM_HIGH            6
34 #define ADT7310_T_ALARM_LOW             7
35
36 /*
37  * ADT7310 status
38  */
39 #define ADT7310_STAT_T_LOW              0x10
40 #define ADT7310_STAT_T_HIGH             0x20
41 #define ADT7310_STAT_T_CRIT             0x40
42 #define ADT7310_STAT_NOT_RDY            0x80
43
44 /*
45  * ADT7310 config
46  */
47 #define ADT7310_FAULT_QUEUE_MASK        0x3
48 #define ADT7310_CT_POLARITY             0x4
49 #define ADT7310_INT_POLARITY            0x8
50 #define ADT7310_EVENT_MODE              0x10
51 #define ADT7310_MODE_MASK               0x60
52 #define ADT7310_ONESHOT                 0x20
53 #define ADT7310_SPS                     0x40
54 #define ADT7310_PD                      0x60
55 #define ADT7310_RESOLUTION              0x80
56
57 /*
58  * ADT7310 masks
59  */
60 #define ADT7310_T16_VALUE_SIGN                  0x8000
61 #define ADT7310_T16_VALUE_FLOAT_OFFSET          7
62 #define ADT7310_T16_VALUE_FLOAT_MASK            0x7F
63 #define ADT7310_T13_VALUE_SIGN                  0x1000
64 #define ADT7310_T13_VALUE_OFFSET                3
65 #define ADT7310_T13_VALUE_FLOAT_OFFSET          4
66 #define ADT7310_T13_VALUE_FLOAT_MASK            0xF
67 #define ADT7310_T_HYST_MASK                     0xF
68 #define ADT7310_DEVICE_ID_MASK                  0x7
69 #define ADT7310_MANUFACTORY_ID_MASK             0xF8
70 #define ADT7310_MANUFACTORY_ID_OFFSET           3
71
72
73 #define ADT7310_CMD_REG_MASK                    0x28
74 #define ADT7310_CMD_REG_OFFSET                  3
75 #define ADT7310_CMD_READ                        0x40
76 #define ADT7310_CMD_CON_READ                    0x4
77
78 #define ADT7310_IRQS                            2
79
80 /*
81  * struct adt7310_chip_info - chip specifc information
82  */
83
84 struct adt7310_chip_info {
85         const char *name;
86         struct spi_device *spi_dev;
87         struct iio_dev *indio_dev;
88         struct work_struct thresh_work;
89         s64 last_timestamp;
90         u8  config;
91 };
92
93 /*
94  * adt7310 register access by SPI
95  */
96
97 static int adt7310_spi_read_word(struct adt7310_chip_info *chip, u8 reg, u16 *data)
98 {
99         struct spi_device *spi_dev = chip->spi_dev;
100         u8 command = (reg << ADT7310_CMD_REG_OFFSET) & ADT7310_CMD_REG_MASK;
101         int ret = 0;
102
103         command |= ADT7310_CMD_READ;
104         ret = spi_write(spi_dev, &command, sizeof(command));
105         if (ret < 0) {
106                 dev_err(&spi_dev->dev, "SPI write command error\n");
107                 return ret;
108         }
109
110         ret = spi_read(spi_dev, (u8 *)data, sizeof(*data));
111         if (ret < 0) {
112                 dev_err(&spi_dev->dev, "SPI read word error\n");
113                 return ret;
114         }
115
116         *data = be16_to_cpu(*data);
117
118         return 0;
119 }
120
121 static int adt7310_spi_write_word(struct adt7310_chip_info *chip, u8 reg, u16 data)
122 {
123         struct spi_device *spi_dev = chip->spi_dev;
124         u8 buf[3];
125         int ret = 0;
126
127         buf[0] = (reg << ADT7310_CMD_REG_OFFSET) & ADT7310_CMD_REG_MASK;
128         buf[1] = (u8)(data >> 8);
129         buf[2] = (u8)(data & 0xFF);
130
131         ret = spi_write(spi_dev, buf, 3);
132         if (ret < 0) {
133                 dev_err(&spi_dev->dev, "SPI write word error\n");
134                 return ret;
135         }
136
137         return ret;
138 }
139
140 static int adt7310_spi_read_byte(struct adt7310_chip_info *chip, u8 reg, u8 *data)
141 {
142         struct spi_device *spi_dev = chip->spi_dev;
143         u8 command = (reg << ADT7310_CMD_REG_OFFSET) & ADT7310_CMD_REG_MASK;
144         int ret = 0;
145
146         command |= ADT7310_CMD_READ;
147         ret = spi_write(spi_dev, &command, sizeof(command));
148         if (ret < 0) {
149                 dev_err(&spi_dev->dev, "SPI write command error\n");
150                 return ret;
151         }
152
153         ret = spi_read(spi_dev, data, sizeof(*data));
154         if (ret < 0) {
155                 dev_err(&spi_dev->dev, "SPI read byte error\n");
156                 return ret;
157         }
158
159         return 0;
160 }
161
162 static int adt7310_spi_write_byte(struct adt7310_chip_info *chip, u8 reg, u8 data)
163 {
164         struct spi_device *spi_dev = chip->spi_dev;
165         u8 buf[2];
166         int ret = 0;
167
168         buf[0] = (reg << ADT7310_CMD_REG_OFFSET) & ADT7310_CMD_REG_MASK;
169         buf[1] = data;
170
171         ret = spi_write(spi_dev, buf, 2);
172         if (ret < 0) {
173                 dev_err(&spi_dev->dev, "SPI write byte error\n");
174                 return ret;
175         }
176
177         return ret;
178 }
179
180 static ssize_t adt7310_show_mode(struct device *dev,
181                 struct device_attribute *attr,
182                 char *buf)
183 {
184         struct iio_dev *dev_info = dev_get_drvdata(dev);
185         struct adt7310_chip_info *chip = dev_info->dev_data;
186         u8 config;
187
188         config = chip->config & ADT7310_MODE_MASK;
189
190         switch (config) {
191         case ADT7310_PD:
192                 return sprintf(buf, "power-down\n");
193         case ADT7310_ONESHOT:
194                 return sprintf(buf, "one-shot\n");
195         case ADT7310_SPS:
196                 return sprintf(buf, "sps\n");
197         default:
198                 return sprintf(buf, "full\n");
199         }
200 }
201
202 static ssize_t adt7310_store_mode(struct device *dev,
203                 struct device_attribute *attr,
204                 const char *buf,
205                 size_t len)
206 {
207         struct iio_dev *dev_info = dev_get_drvdata(dev);
208         struct adt7310_chip_info *chip = dev_info->dev_data;
209         u16 config;
210         int ret;
211
212         ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config);
213         if (ret)
214                 return -EIO;
215
216         config = chip->config & (~ADT7310_MODE_MASK);
217         if (strcmp(buf, "power-down"))
218                 config |= ADT7310_PD;
219         else if (strcmp(buf, "one-shot"))
220                 config |= ADT7310_ONESHOT;
221         else if (strcmp(buf, "sps"))
222                 config |= ADT7310_SPS;
223
224         ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, config);
225         if (ret)
226                 return -EIO;
227
228         chip->config = config;
229
230         return len;
231 }
232
233 static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
234                 adt7310_show_mode,
235                 adt7310_store_mode,
236                 0);
237
238 static ssize_t adt7310_show_available_modes(struct device *dev,
239                 struct device_attribute *attr,
240                 char *buf)
241 {
242         return sprintf(buf, "full\none-shot\nsps\npower-down\n");
243 }
244
245 static IIO_DEVICE_ATTR(available_modes, S_IRUGO, adt7310_show_available_modes, NULL, 0);
246
247 static ssize_t adt7310_show_resolution(struct device *dev,
248                 struct device_attribute *attr,
249                 char *buf)
250 {
251         struct iio_dev *dev_info = dev_get_drvdata(dev);
252         struct adt7310_chip_info *chip = dev_info->dev_data;
253         int ret;
254         int bits;
255
256         ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config);
257         if (ret)
258                 return -EIO;
259
260         if (chip->config & ADT7310_RESOLUTION)
261                 bits = 16;
262         else
263                 bits = 13;
264
265         return sprintf(buf, "%d bits\n", bits);
266 }
267
268 static ssize_t adt7310_store_resolution(struct device *dev,
269                 struct device_attribute *attr,
270                 const char *buf,
271                 size_t len)
272 {
273         struct iio_dev *dev_info = dev_get_drvdata(dev);
274         struct adt7310_chip_info *chip = dev_info->dev_data;
275         unsigned long data;
276         u16 config;
277         int ret;
278
279         ret = strict_strtoul(buf, 10, &data);
280         if (ret)
281                 return -EINVAL;
282
283         ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config);
284         if (ret)
285                 return -EIO;
286
287         config = chip->config & (~ADT7310_RESOLUTION);
288         if (data)
289                 config |= ADT7310_RESOLUTION;
290
291         ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, config);
292         if (ret)
293                 return -EIO;
294
295         chip->config = config;
296
297         return len;
298 }
299
300 static IIO_DEVICE_ATTR(resolution, S_IRUGO | S_IWUSR,
301                 adt7310_show_resolution,
302                 adt7310_store_resolution,
303                 0);
304
305 static ssize_t adt7310_show_id(struct device *dev,
306                 struct device_attribute *attr,
307                 char *buf)
308 {
309         struct iio_dev *dev_info = dev_get_drvdata(dev);
310         struct adt7310_chip_info *chip = dev_info->dev_data;
311         u8 id;
312         int ret;
313
314         ret = adt7310_spi_read_byte(chip, ADT7310_ID, &id);
315         if (ret)
316                 return -EIO;
317
318         return sprintf(buf, "device id: 0x%x\nmanufactory id: 0x%x\n",
319                         id & ADT7310_DEVICE_ID_MASK,
320                         (id & ADT7310_MANUFACTORY_ID_MASK) >> ADT7310_MANUFACTORY_ID_OFFSET);
321 }
322
323 static IIO_DEVICE_ATTR(id, S_IRUGO | S_IWUSR,
324                 adt7310_show_id,
325                 NULL,
326                 0);
327
328 static ssize_t adt7310_convert_temperature(struct adt7310_chip_info *chip,
329                 u16 data, char *buf)
330 {
331         char sign = ' ';
332
333         if (chip->config & ADT7310_RESOLUTION) {
334                 if (data & ADT7310_T16_VALUE_SIGN) {
335                         /* convert supplement to positive value */
336                         data = (u16)((ADT7310_T16_VALUE_SIGN << 1) - (u32)data);
337                         sign = '-';
338                 }
339                 return sprintf(buf, "%c%d.%.7d\n", sign,
340                                 (data >> ADT7310_T16_VALUE_FLOAT_OFFSET),
341                                 (data & ADT7310_T16_VALUE_FLOAT_MASK) * 78125);
342         } else {
343                 if (data & ADT7310_T13_VALUE_SIGN) {
344                         /* convert supplement to positive value */
345                         data >>= ADT7310_T13_VALUE_OFFSET;
346                         data = (ADT7310_T13_VALUE_SIGN << 1) - data;
347                         sign = '-';
348                 }
349                 return sprintf(buf, "%c%d.%.4d\n", sign,
350                                 (data >> ADT7310_T13_VALUE_FLOAT_OFFSET),
351                                 (data & ADT7310_T13_VALUE_FLOAT_MASK) * 625);
352         }
353 }
354
355 static ssize_t adt7310_show_value(struct device *dev,
356                 struct device_attribute *attr,
357                 char *buf)
358 {
359         struct iio_dev *dev_info = dev_get_drvdata(dev);
360         struct adt7310_chip_info *chip = dev_info->dev_data;
361         u8 status;
362         u16 data;
363         int ret, i = 0;
364
365         do {
366                 ret = adt7310_spi_read_byte(chip, ADT7310_STATUS, &status);
367                 if (ret)
368                         return -EIO;
369                 i++;
370                 if (i == 10000)
371                         return -EIO;
372         } while (status & ADT7310_STAT_NOT_RDY);
373
374         ret = adt7310_spi_read_word(chip, ADT7310_TEMPERATURE, &data);
375         if (ret)
376                 return -EIO;
377
378         return adt7310_convert_temperature(chip, data, buf);
379 }
380
381 static IIO_DEVICE_ATTR(value, S_IRUGO, adt7310_show_value, NULL, 0);
382
383 static ssize_t adt7310_show_name(struct device *dev,
384                 struct device_attribute *attr,
385                 char *buf)
386 {
387         struct iio_dev *dev_info = dev_get_drvdata(dev);
388         struct adt7310_chip_info *chip = dev_info->dev_data;
389         return sprintf(buf, "%s\n", chip->name);
390 }
391
392 static IIO_DEVICE_ATTR(name, S_IRUGO, adt7310_show_name, NULL, 0);
393
394 static struct attribute *adt7310_attributes[] = {
395         &iio_dev_attr_available_modes.dev_attr.attr,
396         &iio_dev_attr_mode.dev_attr.attr,
397         &iio_dev_attr_resolution.dev_attr.attr,
398         &iio_dev_attr_id.dev_attr.attr,
399         &iio_dev_attr_value.dev_attr.attr,
400         &iio_dev_attr_name.dev_attr.attr,
401         NULL,
402 };
403
404 static const struct attribute_group adt7310_attribute_group = {
405         .attrs = adt7310_attributes,
406 };
407
408 /*
409  * temperature bound events
410  */
411
412 #define IIO_EVENT_CODE_ADT7310_ABOVE_ALARM    IIO_BUFFER_EVENT_CODE(0)
413 #define IIO_EVENT_CODE_ADT7310_BELLOW_ALARM   IIO_BUFFER_EVENT_CODE(1)
414 #define IIO_EVENT_CODE_ADT7310_ABOVE_CRIT     IIO_BUFFER_EVENT_CODE(2)
415
416 static void adt7310_interrupt_bh(struct work_struct *work_s)
417 {
418         struct adt7310_chip_info *chip =
419                 container_of(work_s, struct adt7310_chip_info, thresh_work);
420         u8 status;
421
422         if (adt7310_spi_read_byte(chip, ADT7310_STATUS, &status))
423                 return;
424
425         if (status & ADT7310_STAT_T_HIGH)
426                 iio_push_event(chip->indio_dev, 0,
427                         IIO_EVENT_CODE_ADT7310_ABOVE_ALARM,
428                         chip->last_timestamp);
429         if (status & ADT7310_STAT_T_LOW)
430                 iio_push_event(chip->indio_dev, 0,
431                         IIO_EVENT_CODE_ADT7310_BELLOW_ALARM,
432                         chip->last_timestamp);
433         if (status & ADT7310_STAT_T_CRIT)
434                 iio_push_event(chip->indio_dev, 0,
435                         IIO_EVENT_CODE_ADT7310_ABOVE_CRIT,
436                         chip->last_timestamp);
437 }
438
439 static int adt7310_interrupt(struct iio_dev *dev_info,
440                 int index,
441                 s64 timestamp,
442                 int no_test)
443 {
444         struct adt7310_chip_info *chip = dev_info->dev_data;
445
446         chip->last_timestamp = timestamp;
447         schedule_work(&chip->thresh_work);
448
449         return 0;
450 }
451
452 IIO_EVENT_SH(adt7310, &adt7310_interrupt);
453 IIO_EVENT_SH(adt7310_ct, &adt7310_interrupt);
454
455 static ssize_t adt7310_show_event_mode(struct device *dev,
456                 struct device_attribute *attr,
457                 char *buf)
458 {
459         struct iio_dev *dev_info = dev_get_drvdata(dev);
460         struct adt7310_chip_info *chip = dev_info->dev_data;
461         int ret;
462
463         ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config);
464         if (ret)
465                 return -EIO;
466
467         if (chip->config & ADT7310_EVENT_MODE)
468                 return sprintf(buf, "interrupt\n");
469         else
470                 return sprintf(buf, "comparator\n");
471 }
472
473 static ssize_t adt7310_set_event_mode(struct device *dev,
474                 struct device_attribute *attr,
475                 const char *buf,
476                 size_t len)
477 {
478         struct iio_dev *dev_info = dev_get_drvdata(dev);
479         struct adt7310_chip_info *chip = dev_info->dev_data;
480         u16 config;
481         int ret;
482
483         ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config);
484         if (ret)
485                 return -EIO;
486
487         config = chip->config &= ~ADT7310_EVENT_MODE;
488         if (strcmp(buf, "comparator") != 0)
489                 config |= ADT7310_EVENT_MODE;
490
491         ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, config);
492         if (ret)
493                 return -EIO;
494
495         chip->config = config;
496
497         return len;
498 }
499
500 static ssize_t adt7310_show_available_event_modes(struct device *dev,
501                 struct device_attribute *attr,
502                 char *buf)
503 {
504         return sprintf(buf, "comparator\ninterrupt\n");
505 }
506
507 static ssize_t adt7310_show_fault_queue(struct device *dev,
508                 struct device_attribute *attr,
509                 char *buf)
510 {
511         struct iio_dev *dev_info = dev_get_drvdata(dev);
512         struct adt7310_chip_info *chip = dev_info->dev_data;
513         int ret;
514
515         ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config);
516         if (ret)
517                 return -EIO;
518
519         return sprintf(buf, "%d\n", chip->config & ADT7310_FAULT_QUEUE_MASK);
520 }
521
522 static ssize_t adt7310_set_fault_queue(struct device *dev,
523                 struct device_attribute *attr,
524                 const char *buf,
525                 size_t len)
526 {
527         struct iio_dev *dev_info = dev_get_drvdata(dev);
528         struct adt7310_chip_info *chip = dev_info->dev_data;
529         unsigned long data;
530         int ret;
531         u8 config;
532
533         ret = strict_strtoul(buf, 10, &data);
534         if (ret || data > 3)
535                 return -EINVAL;
536
537         ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config);
538         if (ret)
539                 return -EIO;
540
541         config = chip->config & ~ADT7310_FAULT_QUEUE_MASK;
542         config |= data;
543         ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, config);
544         if (ret)
545                 return -EIO;
546
547         chip->config = config;
548
549         return len;
550 }
551
552 static inline ssize_t adt7310_show_t_bound(struct device *dev,
553                 struct device_attribute *attr,
554                 u8 bound_reg,
555                 char *buf)
556 {
557         struct iio_dev *dev_info = dev_get_drvdata(dev);
558         struct adt7310_chip_info *chip = dev_info->dev_data;
559         u16 data;
560         int ret;
561
562         ret = adt7310_spi_read_word(chip, bound_reg, &data);
563         if (ret)
564                 return -EIO;
565
566         return adt7310_convert_temperature(chip, data, buf);
567 }
568
569 static inline ssize_t adt7310_set_t_bound(struct device *dev,
570                 struct device_attribute *attr,
571                 u8 bound_reg,
572                 const char *buf,
573                 size_t len)
574 {
575         struct iio_dev *dev_info = dev_get_drvdata(dev);
576         struct adt7310_chip_info *chip = dev_info->dev_data;
577         long tmp1, tmp2;
578         u16 data;
579         char *pos;
580         int ret;
581
582         pos = strchr(buf, '.');
583
584         ret = strict_strtol(buf, 10, &tmp1);
585
586         if (ret || tmp1 > 127 || tmp1 < -128)
587                 return -EINVAL;
588
589         if (pos) {
590                 len = strlen(pos);
591
592                 if (chip->config & ADT7310_RESOLUTION) {
593                         if (len > ADT7310_T16_VALUE_FLOAT_OFFSET)
594                                 len = ADT7310_T16_VALUE_FLOAT_OFFSET;
595                         pos[len] = 0;
596                         ret = strict_strtol(pos, 10, &tmp2);
597
598                         if (!ret)
599                                 tmp2 = (tmp2 / 78125) * 78125;
600                 } else {
601                         if (len > ADT7310_T13_VALUE_FLOAT_OFFSET)
602                                 len = ADT7310_T13_VALUE_FLOAT_OFFSET;
603                         pos[len] = 0;
604                         ret = strict_strtol(pos, 10, &tmp2);
605
606                         if (!ret)
607                                 tmp2 = (tmp2 / 625) * 625;
608                 }
609         }
610
611         if (tmp1 < 0)
612                 data = (u16)(-tmp1);
613         else
614                 data = (u16)tmp1;
615
616         if (chip->config & ADT7310_RESOLUTION) {
617                 data = (data << ADT7310_T16_VALUE_FLOAT_OFFSET) |
618                         (tmp2 & ADT7310_T16_VALUE_FLOAT_MASK);
619
620                 if (tmp1 < 0)
621                         /* convert positive value to supplyment */
622                         data = (u16)((ADT7310_T16_VALUE_SIGN << 1) - (u32)data);
623         } else {
624                 data = (data << ADT7310_T13_VALUE_FLOAT_OFFSET) |
625                         (tmp2 & ADT7310_T13_VALUE_FLOAT_MASK);
626
627                 if (tmp1 < 0)
628                         /* convert positive value to supplyment */
629                         data = (ADT7310_T13_VALUE_SIGN << 1) - data;
630                 data <<= ADT7310_T13_VALUE_OFFSET;
631         }
632
633         ret = adt7310_spi_write_word(chip, bound_reg, data);
634         if (ret)
635                 return -EIO;
636
637         return len;
638 }
639
640 static ssize_t adt7310_show_t_alarm_high(struct device *dev,
641                 struct device_attribute *attr,
642                 char *buf)
643 {
644         return adt7310_show_t_bound(dev, attr,
645                         ADT7310_T_ALARM_HIGH, buf);
646 }
647
648 static inline ssize_t adt7310_set_t_alarm_high(struct device *dev,
649                 struct device_attribute *attr,
650                 const char *buf,
651                 size_t len)
652 {
653         return adt7310_set_t_bound(dev, attr,
654                         ADT7310_T_ALARM_HIGH, buf, len);
655 }
656
657 static ssize_t adt7310_show_t_alarm_low(struct device *dev,
658                 struct device_attribute *attr,
659                 char *buf)
660 {
661         return adt7310_show_t_bound(dev, attr,
662                         ADT7310_T_ALARM_LOW, buf);
663 }
664
665 static inline ssize_t adt7310_set_t_alarm_low(struct device *dev,
666                 struct device_attribute *attr,
667                 const char *buf,
668                 size_t len)
669 {
670         return adt7310_set_t_bound(dev, attr,
671                         ADT7310_T_ALARM_LOW, buf, len);
672 }
673
674 static ssize_t adt7310_show_t_crit(struct device *dev,
675                 struct device_attribute *attr,
676                 char *buf)
677 {
678         return adt7310_show_t_bound(dev, attr,
679                         ADT7310_T_CRIT, buf);
680 }
681
682 static inline ssize_t adt7310_set_t_crit(struct device *dev,
683                 struct device_attribute *attr,
684                 const char *buf,
685                 size_t len)
686 {
687         return adt7310_set_t_bound(dev, attr,
688                         ADT7310_T_CRIT, buf, len);
689 }
690
691 static ssize_t adt7310_show_t_hyst(struct device *dev,
692                 struct device_attribute *attr,
693                 char *buf)
694 {
695         struct iio_dev *dev_info = dev_get_drvdata(dev);
696         struct adt7310_chip_info *chip = dev_info->dev_data;
697         int ret;
698         u8 t_hyst;
699
700         ret = adt7310_spi_read_byte(chip, ADT7310_T_HYST, &t_hyst);
701         if (ret)
702                 return -EIO;
703
704         return sprintf(buf, "%d\n", t_hyst & ADT7310_T_HYST_MASK);
705 }
706
707 static inline ssize_t adt7310_set_t_hyst(struct device *dev,
708                 struct device_attribute *attr,
709                 const char *buf,
710                 size_t len)
711 {
712         struct iio_dev *dev_info = dev_get_drvdata(dev);
713         struct adt7310_chip_info *chip = dev_info->dev_data;
714         int ret;
715         unsigned long data;
716         u8 t_hyst;
717
718         ret = strict_strtol(buf, 10, &data);
719
720         if (ret || data > ADT7310_T_HYST_MASK)
721                 return -EINVAL;
722
723         t_hyst = (u8)data;
724
725         ret = adt7310_spi_write_byte(chip, ADT7310_T_HYST, t_hyst);
726         if (ret)
727                 return -EIO;
728
729         return len;
730 }
731
732 IIO_EVENT_ATTR_SH(event_mode, iio_event_adt7310,
733                 adt7310_show_event_mode, adt7310_set_event_mode, 0);
734 IIO_EVENT_ATTR_SH(available_event_modes, iio_event_adt7310,
735                 adt7310_show_available_event_modes, NULL, 0);
736 IIO_EVENT_ATTR_SH(fault_queue, iio_event_adt7310,
737                 adt7310_show_fault_queue, adt7310_set_fault_queue, 0);
738 IIO_EVENT_ATTR_SH(t_alarm_high, iio_event_adt7310,
739                 adt7310_show_t_alarm_high, adt7310_set_t_alarm_high, 0);
740 IIO_EVENT_ATTR_SH(t_alarm_low, iio_event_adt7310,
741                 adt7310_show_t_alarm_low, adt7310_set_t_alarm_low, 0);
742 IIO_EVENT_ATTR_SH(t_crit, iio_event_adt7310_ct,
743                 adt7310_show_t_crit, adt7310_set_t_crit, 0);
744 IIO_EVENT_ATTR_SH(t_hyst, iio_event_adt7310,
745                 adt7310_show_t_hyst, adt7310_set_t_hyst, 0);
746
747 static struct attribute *adt7310_event_int_attributes[] = {
748         &iio_event_attr_event_mode.dev_attr.attr,
749         &iio_event_attr_available_event_modes.dev_attr.attr,
750         &iio_event_attr_fault_queue.dev_attr.attr,
751         &iio_event_attr_t_alarm_high.dev_attr.attr,
752         &iio_event_attr_t_alarm_low.dev_attr.attr,
753         &iio_event_attr_t_hyst.dev_attr.attr,
754         NULL,
755 };
756
757 static struct attribute *adt7310_event_ct_attributes[] = {
758         &iio_event_attr_event_mode.dev_attr.attr,
759         &iio_event_attr_available_event_modes.dev_attr.attr,
760         &iio_event_attr_fault_queue.dev_attr.attr,
761         &iio_event_attr_t_crit.dev_attr.attr,
762         &iio_event_attr_t_hyst.dev_attr.attr,
763         NULL,
764 };
765
766 static struct attribute_group adt7310_event_attribute_group[ADT7310_IRQS] = {
767         {
768                 .attrs = adt7310_event_int_attributes,
769         },
770         {
771                 .attrs = adt7310_event_ct_attributes,
772         }
773 };
774
775 /*
776  * device probe and remove
777  */
778
779 static int __devinit adt7310_probe(struct spi_device *spi_dev)
780 {
781         struct adt7310_chip_info *chip;
782         int ret = 0;
783         unsigned long *adt7310_platform_data = spi_dev->dev.platform_data;
784         unsigned long irq_flags;
785
786         chip = kzalloc(sizeof(struct adt7310_chip_info), GFP_KERNEL);
787
788         if (chip == NULL)
789                 return -ENOMEM;
790
791         /* this is only used for device removal purposes */
792         dev_set_drvdata(&spi_dev->dev, chip);
793
794         chip->spi_dev = spi_dev;
795         chip->name = spi_dev->modalias;
796
797         chip->indio_dev = iio_allocate_device();
798         if (chip->indio_dev == NULL) {
799                 ret = -ENOMEM;
800                 goto error_free_chip;
801         }
802
803         chip->indio_dev->dev.parent = &spi_dev->dev;
804         chip->indio_dev->attrs = &adt7310_attribute_group;
805         chip->indio_dev->event_attrs = adt7310_event_attribute_group;
806         chip->indio_dev->dev_data = (void *)chip;
807         chip->indio_dev->driver_module = THIS_MODULE;
808         chip->indio_dev->num_interrupt_lines = ADT7310_IRQS;
809         chip->indio_dev->modes = INDIO_DIRECT_MODE;
810
811         ret = iio_device_register(chip->indio_dev);
812         if (ret)
813                 goto error_free_dev;
814
815         /* CT critcal temperature event. line 0 */
816         if (spi_dev->irq) {
817                 if (adt7310_platform_data[2])
818                         irq_flags = adt7310_platform_data[2];
819                 else
820                         irq_flags = IRQF_TRIGGER_LOW;
821                 ret = iio_register_interrupt_line(spi_dev->irq,
822                                 chip->indio_dev,
823                                 0,
824                                 irq_flags,
825                                 chip->name);
826                 if (ret)
827                         goto error_unreg_dev;
828
829                 /*
830                  * The event handler list element refer to iio_event_adt7310.
831                  * All event attributes bind to the same event handler.
832                  * One event handler can only be added to one event list.
833                  */
834                 iio_add_event_to_list(&iio_event_adt7310,
835                                 &chip->indio_dev->interrupts[0]->ev_list);
836         }
837
838         /* INT bound temperature alarm event. line 1 */
839         if (adt7310_platform_data[0]) {
840                 ret = iio_register_interrupt_line(adt7310_platform_data[0],
841                                 chip->indio_dev,
842                                 1,
843                                 adt7310_platform_data[1],
844                                 chip->name);
845                 if (ret)
846                         goto error_unreg_ct_irq;
847
848                 /*
849                  * The event handler list element refer to iio_event_adt7310.
850                  * All event attributes bind to the same event handler.
851                  * One event handler can only be added to one event list.
852                  */
853                 iio_add_event_to_list(&iio_event_adt7310_ct,
854                                 &chip->indio_dev->interrupts[1]->ev_list);
855         }
856
857         if (spi_dev->irq && adt7310_platform_data[0]) {
858                 INIT_WORK(&chip->thresh_work, adt7310_interrupt_bh);
859
860                 ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config);
861                 if (ret) {
862                         ret = -EIO;
863                         goto error_unreg_int_irq;
864                 }
865
866                 /* set irq polarity low level */
867                 chip->config &= ~ADT7310_CT_POLARITY;
868
869                 if (adt7310_platform_data[1] & IRQF_TRIGGER_HIGH)
870                         chip->config |= ADT7310_INT_POLARITY;
871                 else
872                         chip->config &= ~ADT7310_INT_POLARITY;
873
874                 ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, chip->config);
875                 if (ret) {
876                         ret = -EIO;
877                         goto error_unreg_int_irq;
878                 }
879         }
880
881         dev_info(&spi_dev->dev, "%s temperature sensor registered.\n",
882                         chip->name);
883
884         return 0;
885
886 error_unreg_int_irq:
887         iio_unregister_interrupt_line(chip->indio_dev, 1);
888 error_unreg_ct_irq:
889         iio_unregister_interrupt_line(chip->indio_dev, 0);
890 error_unreg_dev:
891         iio_device_unregister(chip->indio_dev);
892 error_free_dev:
893         iio_free_device(chip->indio_dev);
894 error_free_chip:
895         kfree(chip);
896
897         return ret;
898 }
899
900 static int __devexit adt7310_remove(struct spi_device *spi_dev)
901 {
902         struct adt7310_chip_info *chip = dev_get_drvdata(&spi_dev->dev);
903         struct iio_dev *indio_dev = chip->indio_dev;
904         unsigned long *adt7310_platform_data = spi_dev->dev.platform_data;
905
906         dev_set_drvdata(&spi_dev->dev, NULL);
907         if (adt7310_platform_data[0])
908                 iio_unregister_interrupt_line(indio_dev, 1);
909         if (spi_dev->irq)
910                 iio_unregister_interrupt_line(indio_dev, 0);
911         iio_device_unregister(indio_dev);
912         iio_free_device(chip->indio_dev);
913         kfree(chip);
914
915         return 0;
916 }
917
918 static const struct spi_device_id adt7310_id[] = {
919         { "adt7310", 0 },
920         {}
921 };
922
923 MODULE_DEVICE_TABLE(spi, adt7310_id);
924
925 static struct spi_driver adt7310_driver = {
926         .driver = {
927                 .name = "adt7310",
928                 .bus = &spi_bus_type,
929                 .owner = THIS_MODULE,
930         },
931         .probe = adt7310_probe,
932         .remove = __devexit_p(adt7310_remove),
933         .id_table = adt7310_id,
934 };
935
936 static __init int adt7310_init(void)
937 {
938         return spi_register_driver(&adt7310_driver);
939 }
940
941 static __exit void adt7310_exit(void)
942 {
943         spi_unregister_driver(&adt7310_driver);
944 }
945
946 MODULE_AUTHOR("Sonic Zhang <[email protected]>");
947 MODULE_DESCRIPTION("Analog Devices ADT7310 digital"
948                         " temperature sensor driver");
949 MODULE_LICENSE("GPL v2");
950
951 module_init(adt7310_init);
952 module_exit(adt7310_exit);
This page took 0.09041 seconds and 4 git commands to generate.