Linux 3.9-rc5
[deliverable/linux.git] / drivers / staging / iio / adc / adt7410.c
CommitLineData
06b86a75 1/*
2b0c856a 2 * ADT7410 digital temperature sensor driver supporting ADT7310/ADT7410
06b86a75
SZ
3 *
4 * Copyright 2010 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
7 */
8
9#include <linux/interrupt.h>
06b86a75
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/i2c.h>
2b0c856a 16#include <linux/spi/spi.h>
99c97852 17#include <linux/module.h>
06b86a75 18
06458e27
JC
19#include <linux/iio/iio.h>
20#include <linux/iio/sysfs.h>
21#include <linux/iio/events.h>
06b86a75
SZ
22
23/*
24 * ADT7410 registers definition
25 */
26
27#define ADT7410_TEMPERATURE 0
28#define ADT7410_STATUS 2
29#define ADT7410_CONFIG 3
30#define ADT7410_T_ALARM_HIGH 4
31#define ADT7410_T_ALARM_LOW 6
32#define ADT7410_T_CRIT 8
33#define ADT7410_T_HYST 0xA
34#define ADT7410_ID 0xB
35#define ADT7410_RESET 0x2F
36
2b0c856a
LPC
37/*
38 * ADT7310 registers definition
39 */
40
41#define ADT7310_STATUS 0
42#define ADT7310_CONFIG 1
43#define ADT7310_TEMPERATURE 2
44#define ADT7310_ID 3
45#define ADT7310_T_CRIT 4
46#define ADT7310_T_HYST 5
47#define ADT7310_T_ALARM_HIGH 6
48#define ADT7310_T_ALARM_LOW 7
49
06b86a75
SZ
50/*
51 * ADT7410 status
52 */
53#define ADT7410_STAT_T_LOW 0x10
54#define ADT7410_STAT_T_HIGH 0x20
55#define ADT7410_STAT_T_CRIT 0x40
56#define ADT7410_STAT_NOT_RDY 0x80
57
58/*
59 * ADT7410 config
60 */
61#define ADT7410_FAULT_QUEUE_MASK 0x3
62#define ADT7410_CT_POLARITY 0x4
63#define ADT7410_INT_POLARITY 0x8
64#define ADT7410_EVENT_MODE 0x10
65#define ADT7410_MODE_MASK 0x60
66#define ADT7410_ONESHOT 0x20
67#define ADT7410_SPS 0x40
68#define ADT7410_PD 0x60
69#define ADT7410_RESOLUTION 0x80
70
71/*
72 * ADT7410 masks
73 */
74#define ADT7410_T16_VALUE_SIGN 0x8000
75#define ADT7410_T16_VALUE_FLOAT_OFFSET 7
76#define ADT7410_T16_VALUE_FLOAT_MASK 0x7F
77#define ADT7410_T13_VALUE_SIGN 0x1000
78#define ADT7410_T13_VALUE_OFFSET 3
79#define ADT7410_T13_VALUE_FLOAT_OFFSET 4
80#define ADT7410_T13_VALUE_FLOAT_MASK 0xF
81#define ADT7410_T_HYST_MASK 0xF
82#define ADT7410_DEVICE_ID_MASK 0xF
83#define ADT7410_MANUFACTORY_ID_MASK 0xF0
84#define ADT7410_MANUFACTORY_ID_OFFSET 4
85
2b0c856a
LPC
86
87#define ADT7310_CMD_REG_MASK 0x28
88#define ADT7310_CMD_REG_OFFSET 3
89#define ADT7310_CMD_READ 0x40
90#define ADT7310_CMD_CON_READ 0x4
91
06b86a75
SZ
92#define ADT7410_IRQS 2
93
94/*
95 * struct adt7410_chip_info - chip specifc information
96 */
97
2b0c856a
LPC
98struct adt7410_chip_info;
99
100struct adt7410_ops {
101 int (*read_word)(struct adt7410_chip_info *, u8 reg, u16 *data);
102 int (*write_word)(struct adt7410_chip_info *, u8 reg, u16 data);
103 int (*read_byte)(struct adt7410_chip_info *, u8 reg, u8 *data);
104 int (*write_byte)(struct adt7410_chip_info *, u8 reg, u8 data);
105};
106
06b86a75 107struct adt7410_chip_info {
2b0c856a 108 struct device *dev;
06b86a75 109 u8 config;
06b86a75 110
2b0c856a
LPC
111 const struct adt7410_ops *ops;
112};
06b86a75 113
2b0c856a 114static int adt7410_read_word(struct adt7410_chip_info *chip, u8 reg, u16 *data)
06b86a75 115{
2b0c856a 116 return chip->ops->read_word(chip, reg, data);
06b86a75
SZ
117}
118
2b0c856a 119static int adt7410_write_word(struct adt7410_chip_info *chip, u8 reg, u16 data)
06b86a75 120{
2b0c856a 121 return chip->ops->write_word(chip, reg, data);
06b86a75
SZ
122}
123
2b0c856a 124static int adt7410_read_byte(struct adt7410_chip_info *chip, u8 reg, u8 *data)
06b86a75 125{
2b0c856a 126 return chip->ops->read_byte(chip, reg, data);
06b86a75
SZ
127}
128
2b0c856a 129static int adt7410_write_byte(struct adt7410_chip_info *chip, u8 reg, u8 data)
06b86a75 130{
2b0c856a 131 return chip->ops->write_byte(chip, reg, data);
06b86a75
SZ
132}
133
134static ssize_t adt7410_show_mode(struct device *dev,
135 struct device_attribute *attr,
136 char *buf)
137{
62c51839 138 struct iio_dev *dev_info = dev_to_iio_dev(dev);
d3de2935 139 struct adt7410_chip_info *chip = iio_priv(dev_info);
06b86a75
SZ
140 u8 config;
141
142 config = chip->config & ADT7410_MODE_MASK;
143
144 switch (config) {
145 case ADT7410_PD:
146 return sprintf(buf, "power-down\n");
147 case ADT7410_ONESHOT:
148 return sprintf(buf, "one-shot\n");
149 case ADT7410_SPS:
150 return sprintf(buf, "sps\n");
151 default:
152 return sprintf(buf, "full\n");
153 }
154}
155
156static ssize_t adt7410_store_mode(struct device *dev,
157 struct device_attribute *attr,
158 const char *buf,
159 size_t len)
160{
62c51839 161 struct iio_dev *dev_info = dev_to_iio_dev(dev);
d3de2935 162 struct adt7410_chip_info *chip = iio_priv(dev_info);
06b86a75
SZ
163 u16 config;
164 int ret;
165
2b0c856a 166 ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config);
06b86a75
SZ
167 if (ret)
168 return -EIO;
169
170 config = chip->config & (~ADT7410_MODE_MASK);
171 if (strcmp(buf, "power-down"))
172 config |= ADT7410_PD;
173 else if (strcmp(buf, "one-shot"))
174 config |= ADT7410_ONESHOT;
175 else if (strcmp(buf, "sps"))
176 config |= ADT7410_SPS;
177
2b0c856a 178 ret = adt7410_write_byte(chip, ADT7410_CONFIG, config);
06b86a75
SZ
179 if (ret)
180 return -EIO;
181
182 chip->config = config;
183
e8f45e33 184 return len;
06b86a75
SZ
185}
186
187static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
188 adt7410_show_mode,
189 adt7410_store_mode,
190 0);
191
192static ssize_t adt7410_show_available_modes(struct device *dev,
193 struct device_attribute *attr,
194 char *buf)
195{
196 return sprintf(buf, "full\none-shot\nsps\npower-down\n");
197}
198
199static IIO_DEVICE_ATTR(available_modes, S_IRUGO, adt7410_show_available_modes, NULL, 0);
200
201static ssize_t adt7410_show_resolution(struct device *dev,
202 struct device_attribute *attr,
203 char *buf)
204{
62c51839 205 struct iio_dev *dev_info = dev_to_iio_dev(dev);
d3de2935 206 struct adt7410_chip_info *chip = iio_priv(dev_info);
06b86a75
SZ
207 int ret;
208 int bits;
209
2b0c856a 210 ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config);
06b86a75
SZ
211 if (ret)
212 return -EIO;
213
214 if (chip->config & ADT7410_RESOLUTION)
215 bits = 16;
216 else
217 bits = 13;
218
219 return sprintf(buf, "%d bits\n", bits);
220}
221
222static ssize_t adt7410_store_resolution(struct device *dev,
223 struct device_attribute *attr,
224 const char *buf,
225 size_t len)
226{
62c51839 227 struct iio_dev *dev_info = dev_to_iio_dev(dev);
d3de2935 228 struct adt7410_chip_info *chip = iio_priv(dev_info);
06b86a75
SZ
229 unsigned long data;
230 u16 config;
231 int ret;
232
233 ret = strict_strtoul(buf, 10, &data);
234 if (ret)
235 return -EINVAL;
236
2b0c856a 237 ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config);
06b86a75
SZ
238 if (ret)
239 return -EIO;
240
241 config = chip->config & (~ADT7410_RESOLUTION);
242 if (data)
243 config |= ADT7410_RESOLUTION;
244
2b0c856a 245 ret = adt7410_write_byte(chip, ADT7410_CONFIG, config);
06b86a75
SZ
246 if (ret)
247 return -EIO;
248
249 chip->config = config;
250
3a427d18 251 return len;
06b86a75
SZ
252}
253
254static IIO_DEVICE_ATTR(resolution, S_IRUGO | S_IWUSR,
255 adt7410_show_resolution,
256 adt7410_store_resolution,
257 0);
258
259static ssize_t adt7410_show_id(struct device *dev,
260 struct device_attribute *attr,
261 char *buf)
262{
62c51839 263 struct iio_dev *dev_info = dev_to_iio_dev(dev);
d3de2935 264 struct adt7410_chip_info *chip = iio_priv(dev_info);
06b86a75
SZ
265 u8 id;
266 int ret;
267
2b0c856a 268 ret = adt7410_read_byte(chip, ADT7410_ID, &id);
06b86a75
SZ
269 if (ret)
270 return -EIO;
271
272 return sprintf(buf, "device id: 0x%x\nmanufactory id: 0x%x\n",
273 id & ADT7410_DEVICE_ID_MASK,
274 (id & ADT7410_MANUFACTORY_ID_MASK) >> ADT7410_MANUFACTORY_ID_OFFSET);
275}
276
277static IIO_DEVICE_ATTR(id, S_IRUGO | S_IWUSR,
278 adt7410_show_id,
279 NULL,
280 0);
281
282static ssize_t adt7410_convert_temperature(struct adt7410_chip_info *chip,
283 u16 data, char *buf)
284{
285 char sign = ' ';
286
1764eff7
SH
287 if (!(chip->config & ADT7410_RESOLUTION))
288 data &= ~0x7;
289
290 if (data & ADT7410_T16_VALUE_SIGN) {
291 /* convert supplement to positive value */
292 data = (u16)((ADT7410_T16_VALUE_SIGN << 1) - (u32)data);
293 sign = '-';
06b86a75 294 }
1764eff7
SH
295 return sprintf(buf, "%c%d.%.7d\n", sign,
296 (data >> ADT7410_T16_VALUE_FLOAT_OFFSET),
297 (data & ADT7410_T16_VALUE_FLOAT_MASK) * 78125);
06b86a75
SZ
298}
299
300static ssize_t adt7410_show_value(struct device *dev,
301 struct device_attribute *attr,
302 char *buf)
303{
62c51839 304 struct iio_dev *dev_info = dev_to_iio_dev(dev);
d3de2935 305 struct adt7410_chip_info *chip = iio_priv(dev_info);
06b86a75
SZ
306 u8 status;
307 u16 data;
308 int ret, i = 0;
309
310 do {
2b0c856a 311 ret = adt7410_read_byte(chip, ADT7410_STATUS, &status);
06b86a75
SZ
312 if (ret)
313 return -EIO;
314 i++;
315 if (i == 10000)
316 return -EIO;
317 } while (status & ADT7410_STAT_NOT_RDY);
318
2b0c856a 319 ret = adt7410_read_word(chip, ADT7410_TEMPERATURE, &data);
06b86a75
SZ
320 if (ret)
321 return -EIO;
322
323 return adt7410_convert_temperature(chip, data, buf);
324}
325
326static IIO_DEVICE_ATTR(value, S_IRUGO, adt7410_show_value, NULL, 0);
327
06b86a75
SZ
328static struct attribute *adt7410_attributes[] = {
329 &iio_dev_attr_available_modes.dev_attr.attr,
330 &iio_dev_attr_mode.dev_attr.attr,
331 &iio_dev_attr_resolution.dev_attr.attr,
332 &iio_dev_attr_id.dev_attr.attr,
333 &iio_dev_attr_value.dev_attr.attr,
06b86a75
SZ
334 NULL,
335};
336
337static const struct attribute_group adt7410_attribute_group = {
338 .attrs = adt7410_attributes,
339};
340
9c6b6ba8 341static irqreturn_t adt7410_event_handler(int irq, void *private)
06b86a75 342{
9c6b6ba8 343 struct iio_dev *indio_dev = private;
d3de2935 344 struct adt7410_chip_info *chip = iio_priv(indio_dev);
9c6b6ba8 345 s64 timestamp = iio_get_time_ns();
06b86a75
SZ
346 u8 status;
347
2b0c856a 348 if (adt7410_read_byte(chip, ADT7410_STATUS, &status))
9c6b6ba8 349 return IRQ_HANDLED;
06b86a75
SZ
350
351 if (status & ADT7410_STAT_T_HIGH)
5aa96188 352 iio_push_event(indio_dev,
d1ab8552
JC
353 IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0,
354 IIO_EV_TYPE_THRESH,
355 IIO_EV_DIR_RISING),
356 timestamp);
06b86a75 357 if (status & ADT7410_STAT_T_LOW)
5aa96188 358 iio_push_event(indio_dev,
d1ab8552
JC
359 IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0,
360 IIO_EV_TYPE_THRESH,
361 IIO_EV_DIR_FALLING),
362 timestamp);
06b86a75 363 if (status & ADT7410_STAT_T_CRIT)
5aa96188 364 iio_push_event(indio_dev,
d1ab8552
JC
365 IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0,
366 IIO_EV_TYPE_THRESH,
367 IIO_EV_DIR_RISING),
368 timestamp);
06b86a75 369
9c6b6ba8 370 return IRQ_HANDLED;
06b86a75
SZ
371}
372
06b86a75
SZ
373static ssize_t adt7410_show_event_mode(struct device *dev,
374 struct device_attribute *attr,
375 char *buf)
376{
62c51839 377 struct iio_dev *dev_info = dev_to_iio_dev(dev);
d3de2935 378 struct adt7410_chip_info *chip = iio_priv(dev_info);
06b86a75
SZ
379 int ret;
380
2b0c856a 381 ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config);
06b86a75
SZ
382 if (ret)
383 return -EIO;
384
385 if (chip->config & ADT7410_EVENT_MODE)
386 return sprintf(buf, "interrupt\n");
387 else
388 return sprintf(buf, "comparator\n");
389}
390
391static ssize_t adt7410_set_event_mode(struct device *dev,
392 struct device_attribute *attr,
393 const char *buf,
394 size_t len)
395{
62c51839 396 struct iio_dev *dev_info = dev_to_iio_dev(dev);
d3de2935 397 struct adt7410_chip_info *chip = iio_priv(dev_info);
06b86a75
SZ
398 u16 config;
399 int ret;
400
2b0c856a 401 ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config);
06b86a75
SZ
402 if (ret)
403 return -EIO;
404
405 config = chip->config &= ~ADT7410_EVENT_MODE;
406 if (strcmp(buf, "comparator") != 0)
407 config |= ADT7410_EVENT_MODE;
408
2b0c856a 409 ret = adt7410_write_byte(chip, ADT7410_CONFIG, config);
06b86a75
SZ
410 if (ret)
411 return -EIO;
412
413 chip->config = config;
414
415 return ret;
416}
417
418static ssize_t adt7410_show_available_event_modes(struct device *dev,
419 struct device_attribute *attr,
420 char *buf)
421{
422 return sprintf(buf, "comparator\ninterrupt\n");
423}
424
425static ssize_t adt7410_show_fault_queue(struct device *dev,
426 struct device_attribute *attr,
427 char *buf)
428{
62c51839 429 struct iio_dev *dev_info = dev_to_iio_dev(dev);
d3de2935 430 struct adt7410_chip_info *chip = iio_priv(dev_info);
06b86a75
SZ
431 int ret;
432
2b0c856a 433 ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config);
06b86a75
SZ
434 if (ret)
435 return -EIO;
436
437 return sprintf(buf, "%d\n", chip->config & ADT7410_FAULT_QUEUE_MASK);
438}
439
440static ssize_t adt7410_set_fault_queue(struct device *dev,
441 struct device_attribute *attr,
442 const char *buf,
443 size_t len)
444{
62c51839 445 struct iio_dev *dev_info = dev_to_iio_dev(dev);
d3de2935 446 struct adt7410_chip_info *chip = iio_priv(dev_info);
06b86a75
SZ
447 unsigned long data;
448 int ret;
449 u8 config;
450
451 ret = strict_strtoul(buf, 10, &data);
452 if (ret || data > 3)
453 return -EINVAL;
454
2b0c856a 455 ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config);
06b86a75
SZ
456 if (ret)
457 return -EIO;
458
459 config = chip->config & ~ADT7410_FAULT_QUEUE_MASK;
460 config |= data;
2b0c856a 461 ret = adt7410_write_byte(chip, ADT7410_CONFIG, config);
06b86a75
SZ
462 if (ret)
463 return -EIO;
464
465 chip->config = config;
466
467 return ret;
468}
469
470static inline ssize_t adt7410_show_t_bound(struct device *dev,
471 struct device_attribute *attr,
472 u8 bound_reg,
473 char *buf)
474{
62c51839 475 struct iio_dev *dev_info = dev_to_iio_dev(dev);
d3de2935 476 struct adt7410_chip_info *chip = iio_priv(dev_info);
06b86a75
SZ
477 u16 data;
478 int ret;
479
2b0c856a 480 ret = adt7410_read_word(chip, bound_reg, &data);
06b86a75
SZ
481 if (ret)
482 return -EIO;
483
484 return adt7410_convert_temperature(chip, data, buf);
485}
486
487static inline ssize_t adt7410_set_t_bound(struct device *dev,
488 struct device_attribute *attr,
489 u8 bound_reg,
490 const char *buf,
491 size_t len)
492{
62c51839 493 struct iio_dev *dev_info = dev_to_iio_dev(dev);
d3de2935 494 struct adt7410_chip_info *chip = iio_priv(dev_info);
06b86a75
SZ
495 long tmp1, tmp2;
496 u16 data;
497 char *pos;
498 int ret;
499
500 pos = strchr(buf, '.');
501
502 ret = strict_strtol(buf, 10, &tmp1);
503
504 if (ret || tmp1 > 127 || tmp1 < -128)
505 return -EINVAL;
506
507 if (pos) {
508 len = strlen(pos);
509
510 if (chip->config & ADT7410_RESOLUTION) {
511 if (len > ADT7410_T16_VALUE_FLOAT_OFFSET)
512 len = ADT7410_T16_VALUE_FLOAT_OFFSET;
513 pos[len] = 0;
514 ret = strict_strtol(pos, 10, &tmp2);
515
516 if (!ret)
517 tmp2 = (tmp2 / 78125) * 78125;
518 } else {
519 if (len > ADT7410_T13_VALUE_FLOAT_OFFSET)
520 len = ADT7410_T13_VALUE_FLOAT_OFFSET;
521 pos[len] = 0;
522 ret = strict_strtol(pos, 10, &tmp2);
523
524 if (!ret)
525 tmp2 = (tmp2 / 625) * 625;
526 }
527 }
528
529 if (tmp1 < 0)
530 data = (u16)(-tmp1);
531 else
532 data = (u16)tmp1;
533
534 if (chip->config & ADT7410_RESOLUTION) {
535 data = (data << ADT7410_T16_VALUE_FLOAT_OFFSET) |
536 (tmp2 & ADT7410_T16_VALUE_FLOAT_MASK);
537
538 if (tmp1 < 0)
539 /* convert positive value to supplyment */
540 data = (u16)((ADT7410_T16_VALUE_SIGN << 1) - (u32)data);
541 } else {
542 data = (data << ADT7410_T13_VALUE_FLOAT_OFFSET) |
543 (tmp2 & ADT7410_T13_VALUE_FLOAT_MASK);
544
545 if (tmp1 < 0)
546 /* convert positive value to supplyment */
547 data = (ADT7410_T13_VALUE_SIGN << 1) - data;
548 data <<= ADT7410_T13_VALUE_OFFSET;
549 }
550
2b0c856a 551 ret = adt7410_write_word(chip, bound_reg, data);
06b86a75
SZ
552 if (ret)
553 return -EIO;
554
555 return ret;
556}
557
558static ssize_t adt7410_show_t_alarm_high(struct device *dev,
559 struct device_attribute *attr,
560 char *buf)
561{
562 return adt7410_show_t_bound(dev, attr,
563 ADT7410_T_ALARM_HIGH, buf);
564}
565
566static inline ssize_t adt7410_set_t_alarm_high(struct device *dev,
567 struct device_attribute *attr,
568 const char *buf,
569 size_t len)
570{
571 return adt7410_set_t_bound(dev, attr,
572 ADT7410_T_ALARM_HIGH, buf, len);
573}
574
575static ssize_t adt7410_show_t_alarm_low(struct device *dev,
576 struct device_attribute *attr,
577 char *buf)
578{
579 return adt7410_show_t_bound(dev, attr,
580 ADT7410_T_ALARM_LOW, buf);
581}
582
583static inline ssize_t adt7410_set_t_alarm_low(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_LOW, buf, len);
590}
591
592static ssize_t adt7410_show_t_crit(struct device *dev,
593 struct device_attribute *attr,
594 char *buf)
595{
596 return adt7410_show_t_bound(dev, attr,
597 ADT7410_T_CRIT, buf);
598}
599
600static inline ssize_t adt7410_set_t_crit(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_CRIT, buf, len);
607}
608
609static ssize_t adt7410_show_t_hyst(struct device *dev,
610 struct device_attribute *attr,
611 char *buf)
612{
62c51839 613 struct iio_dev *dev_info = dev_to_iio_dev(dev);
d3de2935 614 struct adt7410_chip_info *chip = iio_priv(dev_info);
06b86a75
SZ
615 int ret;
616 u8 t_hyst;
617
2b0c856a 618 ret = adt7410_read_byte(chip, ADT7410_T_HYST, &t_hyst);
06b86a75
SZ
619 if (ret)
620 return -EIO;
621
622 return sprintf(buf, "%d\n", t_hyst & ADT7410_T_HYST_MASK);
623}
624
625static inline ssize_t adt7410_set_t_hyst(struct device *dev,
626 struct device_attribute *attr,
627 const char *buf,
628 size_t len)
629{
62c51839 630 struct iio_dev *dev_info = dev_to_iio_dev(dev);
d3de2935 631 struct adt7410_chip_info *chip = iio_priv(dev_info);
06b86a75
SZ
632 int ret;
633 unsigned long data;
634 u8 t_hyst;
635
636 ret = strict_strtol(buf, 10, &data);
637
638 if (ret || data > ADT7410_T_HYST_MASK)
639 return -EINVAL;
640
641 t_hyst = (u8)data;
642
2b0c856a 643 ret = adt7410_write_byte(chip, ADT7410_T_HYST, t_hyst);
06b86a75
SZ
644 if (ret)
645 return -EIO;
646
647 return ret;
648}
649
9c6b6ba8
JC
650static IIO_DEVICE_ATTR(event_mode,
651 S_IRUGO | S_IWUSR,
652 adt7410_show_event_mode, adt7410_set_event_mode, 0);
653static IIO_DEVICE_ATTR(available_event_modes,
654 S_IRUGO,
655 adt7410_show_available_event_modes, NULL, 0);
656static IIO_DEVICE_ATTR(fault_queue,
657 S_IRUGO | S_IWUSR,
658 adt7410_show_fault_queue, adt7410_set_fault_queue, 0);
659static IIO_DEVICE_ATTR(t_alarm_high,
660 S_IRUGO | S_IWUSR,
661 adt7410_show_t_alarm_high, adt7410_set_t_alarm_high, 0);
662static IIO_DEVICE_ATTR(t_alarm_low,
663 S_IRUGO | S_IWUSR,
664 adt7410_show_t_alarm_low, adt7410_set_t_alarm_low, 0);
665static IIO_DEVICE_ATTR(t_crit,
666 S_IRUGO | S_IWUSR,
667 adt7410_show_t_crit, adt7410_set_t_crit, 0);
668static IIO_DEVICE_ATTR(t_hyst,
669 S_IRUGO | S_IWUSR,
670 adt7410_show_t_hyst, adt7410_set_t_hyst, 0);
06b86a75
SZ
671
672static struct attribute *adt7410_event_int_attributes[] = {
9c6b6ba8
JC
673 &iio_dev_attr_event_mode.dev_attr.attr,
674 &iio_dev_attr_available_event_modes.dev_attr.attr,
675 &iio_dev_attr_fault_queue.dev_attr.attr,
676 &iio_dev_attr_t_alarm_high.dev_attr.attr,
677 &iio_dev_attr_t_alarm_low.dev_attr.attr,
9c6b6ba8
JC
678 &iio_dev_attr_t_crit.dev_attr.attr,
679 &iio_dev_attr_t_hyst.dev_attr.attr,
06b86a75
SZ
680 NULL,
681};
682
8f9cde23
JC
683static struct attribute_group adt7410_event_attribute_group = {
684 .attrs = adt7410_event_int_attributes,
685 .name = "events",
06b86a75
SZ
686};
687
6fe8135f
JC
688static const struct iio_info adt7410_info = {
689 .attrs = &adt7410_attribute_group,
8f9cde23 690 .event_attrs = &adt7410_event_attribute_group,
6fe8135f
JC
691 .driver_module = THIS_MODULE,
692};
693
06b86a75
SZ
694/*
695 * device probe and remove
696 */
697
4ae1c61f 698static int adt7410_probe(struct device *dev, int irq,
2b0c856a 699 const char *name, const struct adt7410_ops *ops)
06b86a75 700{
2b0c856a
LPC
701 unsigned long *adt7410_platform_data = dev->platform_data;
702 unsigned long local_pdata[] = {0, 0};
06b86a75 703 struct adt7410_chip_info *chip;
d3de2935 704 struct iio_dev *indio_dev;
06b86a75 705 int ret = 0;
06b86a75 706
7cbb7537 707 indio_dev = iio_device_alloc(sizeof(*chip));
d3de2935
JC
708 if (indio_dev == NULL) {
709 ret = -ENOMEM;
710 goto error_ret;
711 }
712 chip = iio_priv(indio_dev);
06b86a75 713 /* this is only used for device removal purposes */
2b0c856a 714 dev_set_drvdata(dev, indio_dev);
06b86a75 715
2b0c856a
LPC
716 chip->dev = dev;
717 chip->ops = ops;
06b86a75 718
2b0c856a
LPC
719 indio_dev->name = name;
720 indio_dev->dev.parent = dev;
d3de2935
JC
721 indio_dev->info = &adt7410_info;
722 indio_dev->modes = INDIO_DIRECT_MODE;
06b86a75 723
c732a24c
SH
724 if (!adt7410_platform_data)
725 adt7410_platform_data = local_pdata;
726
06b86a75 727 /* CT critcal temperature event. line 0 */
2b0c856a
LPC
728 if (irq) {
729 ret = request_threaded_irq(irq,
9c6b6ba8
JC
730 NULL,
731 &adt7410_event_handler,
a91aff1c 732 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
2b0c856a 733 name,
d3de2935 734 indio_dev);
06b86a75 735 if (ret)
26d25ae3 736 goto error_free_dev;
06b86a75
SZ
737 }
738
739 /* INT bound temperature alarm event. line 1 */
740 if (adt7410_platform_data[0]) {
9c6b6ba8
JC
741 ret = request_threaded_irq(adt7410_platform_data[0],
742 NULL,
743 &adt7410_event_handler,
a91aff1c
LPC
744 adt7410_platform_data[1] |
745 IRQF_ONESHOT,
2b0c856a 746 name,
d3de2935 747 indio_dev);
06b86a75
SZ
748 if (ret)
749 goto error_unreg_ct_irq;
06b86a75
SZ
750 }
751
2b0c856a 752 ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config);
d297b9bd
SH
753 if (ret) {
754 ret = -EIO;
755 goto error_unreg_int_irq;
756 }
06b86a75 757
d297b9bd
SH
758 chip->config |= ADT7410_RESOLUTION;
759
2b0c856a 760 if (irq && adt7410_platform_data[0]) {
06b86a75
SZ
761
762 /* set irq polarity low level */
763 chip->config &= ~ADT7410_CT_POLARITY;
764
765 if (adt7410_platform_data[1] & IRQF_TRIGGER_HIGH)
766 chip->config |= ADT7410_INT_POLARITY;
767 else
768 chip->config &= ~ADT7410_INT_POLARITY;
d297b9bd 769 }
06b86a75 770
2b0c856a 771 ret = adt7410_write_byte(chip, ADT7410_CONFIG, chip->config);
d297b9bd
SH
772 if (ret) {
773 ret = -EIO;
774 goto error_unreg_int_irq;
06b86a75 775 }
26d25ae3
JC
776 ret = iio_device_register(indio_dev);
777 if (ret)
778 goto error_unreg_int_irq;
06b86a75 779
2b0c856a
LPC
780 dev_info(dev, "%s temperature sensor registered.\n",
781 name);
06b86a75
SZ
782
783 return 0;
784
785error_unreg_int_irq:
d3de2935 786 free_irq(adt7410_platform_data[0], indio_dev);
06b86a75 787error_unreg_ct_irq:
2b0c856a 788 free_irq(irq, indio_dev);
06b86a75 789error_free_dev:
7cbb7537 790 iio_device_free(indio_dev);
d3de2935 791error_ret:
06b86a75
SZ
792 return ret;
793}
794
447d4f29 795static int adt7410_remove(struct device *dev, int irq)
06b86a75 796{
2b0c856a
LPC
797 struct iio_dev *indio_dev = dev_get_drvdata(dev);
798 unsigned long *adt7410_platform_data = dev->platform_data;
06b86a75 799
d2fffd6c 800 iio_device_unregister(indio_dev);
06b86a75 801 if (adt7410_platform_data[0])
d3de2935 802 free_irq(adt7410_platform_data[0], indio_dev);
2b0c856a
LPC
803 if (irq)
804 free_irq(irq, indio_dev);
7cbb7537 805 iio_device_free(indio_dev);
06b86a75
SZ
806
807 return 0;
808}
809
2b0c856a
LPC
810#if IS_ENABLED(CONFIG_I2C)
811
812static int adt7410_i2c_read_word(struct adt7410_chip_info *chip, u8 reg,
813 u16 *data)
814{
815 struct i2c_client *client = to_i2c_client(chip->dev);
816 int ret = 0;
817
818 ret = i2c_smbus_read_word_data(client, reg);
819 if (ret < 0) {
820 dev_err(&client->dev, "I2C read error\n");
821 return ret;
822 }
823
824 *data = swab16((u16)ret);
825
826 return 0;
827}
828
829static int adt7410_i2c_write_word(struct adt7410_chip_info *chip, u8 reg,
830 u16 data)
831{
832 struct i2c_client *client = to_i2c_client(chip->dev);
833 int ret = 0;
834
835 ret = i2c_smbus_write_word_data(client, reg, swab16(data));
836 if (ret < 0)
837 dev_err(&client->dev, "I2C write error\n");
838
839 return ret;
840}
841
842static int adt7410_i2c_read_byte(struct adt7410_chip_info *chip, u8 reg,
843 u8 *data)
844{
845 struct i2c_client *client = to_i2c_client(chip->dev);
846 int ret = 0;
847
848 ret = i2c_smbus_read_byte_data(client, reg);
849 if (ret < 0) {
850 dev_err(&client->dev, "I2C read error\n");
851 return ret;
852 }
853
854 *data = (u8)ret;
855
856 return 0;
857}
858
859static int adt7410_i2c_write_byte(struct adt7410_chip_info *chip, u8 reg,
860 u8 data)
861{
862 struct i2c_client *client = to_i2c_client(chip->dev);
863 int ret = 0;
864
865 ret = i2c_smbus_write_byte_data(client, reg, data);
866 if (ret < 0)
867 dev_err(&client->dev, "I2C write error\n");
868
869 return ret;
870}
871
872static const struct adt7410_ops adt7410_i2c_ops = {
873 .read_word = adt7410_i2c_read_word,
874 .write_word = adt7410_i2c_write_word,
875 .read_byte = adt7410_i2c_read_byte,
876 .write_byte = adt7410_i2c_write_byte,
877};
878
4ae1c61f 879static int adt7410_i2c_probe(struct i2c_client *client,
2b0c856a
LPC
880 const struct i2c_device_id *id)
881{
882 return adt7410_probe(&client->dev, client->irq, id->name,
883 &adt7410_i2c_ops);
884}
885
447d4f29 886static int adt7410_i2c_remove(struct i2c_client *client)
2b0c856a
LPC
887{
888 return adt7410_remove(&client->dev, client->irq);
889}
890
06b86a75
SZ
891static const struct i2c_device_id adt7410_id[] = {
892 { "adt7410", 0 },
893 {}
894};
895
896MODULE_DEVICE_TABLE(i2c, adt7410_id);
897
898static struct i2c_driver adt7410_driver = {
899 .driver = {
900 .name = "adt7410",
901 },
2b0c856a 902 .probe = adt7410_i2c_probe,
e543acf0 903 .remove = adt7410_i2c_remove,
06b86a75
SZ
904 .id_table = adt7410_id,
905};
2b0c856a
LPC
906
907static int __init adt7410_i2c_init(void)
908{
909 return i2c_add_driver(&adt7410_driver);
910}
911
912static void __exit adt7410_i2c_exit(void)
913{
914 i2c_del_driver(&adt7410_driver);
915}
916
917#else
918
919static int __init adt7410_i2c_init(void) { return 0; };
920static void __exit adt7410_i2c_exit(void) {};
921
922#endif
923
924#if IS_ENABLED(CONFIG_SPI_MASTER)
925
926static const u8 adt7371_reg_table[] = {
927 [ADT7410_TEMPERATURE] = ADT7310_TEMPERATURE,
928 [ADT7410_STATUS] = ADT7310_STATUS,
929 [ADT7410_CONFIG] = ADT7310_CONFIG,
930 [ADT7410_T_ALARM_HIGH] = ADT7310_T_ALARM_HIGH,
931 [ADT7410_T_ALARM_LOW] = ADT7310_T_ALARM_LOW,
932 [ADT7410_T_CRIT] = ADT7310_T_CRIT,
933 [ADT7410_T_HYST] = ADT7310_T_HYST,
934 [ADT7410_ID] = ADT7310_ID,
935};
936
937#define AD7310_COMMAND(reg) (adt7371_reg_table[(reg)] << ADT7310_CMD_REG_OFFSET)
938
939static int adt7310_spi_read_word(struct adt7410_chip_info *chip,
940 u8 reg, u16 *data)
941{
942 struct spi_device *spi = to_spi_device(chip->dev);
943 u8 command = AD7310_COMMAND(reg);
944 int ret = 0;
945
946 command |= ADT7310_CMD_READ;
947 ret = spi_write(spi, &command, sizeof(command));
948 if (ret < 0) {
949 dev_err(&spi->dev, "SPI write command error\n");
950 return ret;
951 }
952
953 ret = spi_read(spi, (u8 *)data, sizeof(*data));
954 if (ret < 0) {
955 dev_err(&spi->dev, "SPI read word error\n");
956 return ret;
957 }
958
959 *data = be16_to_cpu(*data);
960
961 return 0;
962}
963
964static int adt7310_spi_write_word(struct adt7410_chip_info *chip, u8 reg,
965 u16 data)
966{
967 struct spi_device *spi = to_spi_device(chip->dev);
968 u8 buf[3];
969 int ret = 0;
970
971 buf[0] = AD7310_COMMAND(reg);
972 buf[1] = (u8)(data >> 8);
973 buf[2] = (u8)(data & 0xFF);
974
975 ret = spi_write(spi, buf, 3);
976 if (ret < 0) {
977 dev_err(&spi->dev, "SPI write word error\n");
978 return ret;
979 }
980
981 return ret;
982}
983
984static int adt7310_spi_read_byte(struct adt7410_chip_info *chip, u8 reg,
985 u8 *data)
986{
987 struct spi_device *spi = to_spi_device(chip->dev);
988 u8 command = AD7310_COMMAND(reg);
989 int ret = 0;
990
991 command |= ADT7310_CMD_READ;
992 ret = spi_write(spi, &command, sizeof(command));
993 if (ret < 0) {
994 dev_err(&spi->dev, "SPI write command error\n");
995 return ret;
996 }
997
998 ret = spi_read(spi, data, sizeof(*data));
999 if (ret < 0) {
1000 dev_err(&spi->dev, "SPI read byte error\n");
1001 return ret;
1002 }
1003
1004 return 0;
1005}
1006
1007static int adt7310_spi_write_byte(struct adt7410_chip_info *chip, u8 reg,
1008 u8 data)
1009{
1010 struct spi_device *spi = to_spi_device(chip->dev);
1011 u8 buf[2];
1012 int ret = 0;
1013
1014 buf[0] = AD7310_COMMAND(reg);
1015 buf[1] = data;
1016
1017 ret = spi_write(spi, buf, 2);
1018 if (ret < 0) {
1019 dev_err(&spi->dev, "SPI write byte error\n");
1020 return ret;
1021 }
1022
1023 return ret;
1024}
1025
1026static const struct adt7410_ops adt7310_spi_ops = {
1027 .read_word = adt7310_spi_read_word,
1028 .write_word = adt7310_spi_write_word,
1029 .read_byte = adt7310_spi_read_byte,
1030 .write_byte = adt7310_spi_write_byte,
1031};
1032
4ae1c61f 1033static int adt7310_spi_probe(struct spi_device *spi)
2b0c856a
LPC
1034{
1035 return adt7410_probe(&spi->dev, spi->irq,
1036 spi_get_device_id(spi)->name, &adt7310_spi_ops);
1037}
1038
447d4f29 1039static int adt7310_spi_remove(struct spi_device *spi)
2b0c856a
LPC
1040{
1041 return adt7410_remove(&spi->dev, spi->irq);
1042}
1043
1044static const struct spi_device_id adt7310_id[] = {
1045 { "adt7310", 0 },
1046 {}
1047};
1048MODULE_DEVICE_TABLE(spi, adt7310_id);
1049
1050static struct spi_driver adt7310_driver = {
1051 .driver = {
1052 .name = "adt7310",
1053 .owner = THIS_MODULE,
1054 },
1055 .probe = adt7310_spi_probe,
e543acf0 1056 .remove = adt7310_spi_remove,
2b0c856a
LPC
1057 .id_table = adt7310_id,
1058};
1059
1060static int __init adt7310_spi_init(void)
1061{
1062 return spi_register_driver(&adt7310_driver);
1063}
1064
1065static void adt7310_spi_exit(void)
1066{
1067 spi_unregister_driver(&adt7310_driver);
1068}
1069
1070#else
1071
1072static int __init adt7310_spi_init(void) { return 0; };
1073static void adt7310_spi_exit(void) {};
1074
1075#endif
1076
1077static int __init adt7410_init(void)
1078{
1079 int ret;
1080
1081 ret = adt7310_spi_init();
1082 if (ret)
1083 return ret;
1084
1085 ret = adt7410_i2c_init();
1086 if (ret)
1087 adt7310_spi_exit();
1088
1089 return ret;
1090}
1091module_init(adt7410_init);
1092
1093static void __exit adt7410_exit(void)
1094{
1095 adt7410_i2c_exit();
1096 adt7310_spi_exit();
1097}
1098module_exit(adt7410_exit);
06b86a75
SZ
1099
1100MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
2b0c856a 1101MODULE_DESCRIPTION("Analog Devices ADT7310/ADT7410 digital temperature sensor driver");
06b86a75 1102MODULE_LICENSE("GPL v2");
This page took 0.302262 seconds and 5 git commands to generate.