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