Linux Audio

Check our new training course

Loading...
  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
 78struct adt7410_chip_info {
 79	struct i2c_client *client;
 80	u8  config;
 81};
 82
 83/*
 84 * adt7410 register access by I2C
 85 */
 86
 87static 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
103static 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
115static 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
131static 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
143static 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
165static 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
196static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
197		adt7410_show_mode,
198		adt7410_store_mode,
199		0);
200
201static 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
208static IIO_DEVICE_ATTR(available_modes, S_IRUGO, adt7410_show_available_modes, NULL, 0);
209
210static 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
231static 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
263static IIO_DEVICE_ATTR(resolution, S_IRUGO | S_IWUSR,
264		adt7410_show_resolution,
265		adt7410_store_resolution,
266		0);
267
268static 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
286static IIO_DEVICE_ATTR(id, S_IRUGO | S_IWUSR,
287		adt7410_show_id,
288		NULL,
289		0);
290
291static 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
318static 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
344static IIO_DEVICE_ATTR(value, S_IRUGO, adt7410_show_value, NULL, 0);
345
346static 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
355static const struct attribute_group adt7410_attribute_group = {
356	.attrs = adt7410_attributes,
357};
358
359static 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
391static 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
409static 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
436static 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
443static 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
458static 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
488static 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
505static 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
576static 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
584static 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
593static 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
601static 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
610static 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
618static 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
627static 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
643static 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
668static IIO_DEVICE_ATTR(event_mode,
669		       S_IRUGO | S_IWUSR,
670		       adt7410_show_event_mode, adt7410_set_event_mode, 0);
671static IIO_DEVICE_ATTR(available_event_modes,
672		       S_IRUGO,
673		       adt7410_show_available_event_modes, NULL, 0);
674static IIO_DEVICE_ATTR(fault_queue,
675		       S_IRUGO | S_IWUSR,
676		       adt7410_show_fault_queue, adt7410_set_fault_queue, 0);
677static IIO_DEVICE_ATTR(t_alarm_high,
678		       S_IRUGO | S_IWUSR,
679		       adt7410_show_t_alarm_high, adt7410_set_t_alarm_high, 0);
680static IIO_DEVICE_ATTR(t_alarm_low,
681		       S_IRUGO | S_IWUSR,
682		       adt7410_show_t_alarm_low, adt7410_set_t_alarm_low, 0);
683static IIO_DEVICE_ATTR(t_crit,
684		       S_IRUGO | S_IWUSR,
685		       adt7410_show_t_crit, adt7410_set_t_crit, 0);
686static IIO_DEVICE_ATTR(t_hyst,
687		       S_IRUGO | S_IWUSR,
688		       adt7410_show_t_hyst, adt7410_set_t_hyst, 0);
689
690static 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
701static struct attribute_group adt7410_event_attribute_group = {
702	.attrs = adt7410_event_int_attributes,
703	.name = "events",
704};
705
706static 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
716static 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,
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					   id->name,
759					   indio_dev);
760		if (ret)
761			goto error_unreg_ct_irq;
762	}
763
764	if (client->irq && adt7410_platform_data[0]) {
765
766		ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config);
767		if (ret) {
768			ret = -EIO;
769			goto error_unreg_int_irq;
770		}
771
772		/* set irq polarity low level */
773		chip->config &= ~ADT7410_CT_POLARITY;
774
775		if (adt7410_platform_data[1] & IRQF_TRIGGER_HIGH)
776			chip->config |= ADT7410_INT_POLARITY;
777		else
778			chip->config &= ~ADT7410_INT_POLARITY;
779
780		ret = adt7410_i2c_write_byte(chip, ADT7410_CONFIG, chip->config);
781		if (ret) {
782			ret = -EIO;
783			goto error_unreg_int_irq;
784		}
785	}
786	ret = iio_device_register(indio_dev);
787	if (ret)
788		goto error_unreg_int_irq;
789
790	dev_info(&client->dev, "%s temperature sensor registered.\n",
791			 id->name);
792
793	return 0;
794
795error_unreg_int_irq:
796	free_irq(adt7410_platform_data[0], indio_dev);
797error_unreg_ct_irq:
798	free_irq(client->irq, indio_dev);
799error_free_dev:
800	iio_device_free(indio_dev);
801error_ret:
802	return ret;
803}
804
805static int __devexit adt7410_remove(struct i2c_client *client)
806{
807	struct iio_dev *indio_dev = i2c_get_clientdata(client);
808	unsigned long *adt7410_platform_data = client->dev.platform_data;
809
810	iio_device_unregister(indio_dev);
811	if (adt7410_platform_data[0])
812		free_irq(adt7410_platform_data[0], indio_dev);
813	if (client->irq)
814		free_irq(client->irq, indio_dev);
815	iio_device_free(indio_dev);
816
817	return 0;
818}
819
820static const struct i2c_device_id adt7410_id[] = {
821	{ "adt7410", 0 },
822	{}
823};
824
825MODULE_DEVICE_TABLE(i2c, adt7410_id);
826
827static struct i2c_driver adt7410_driver = {
828	.driver = {
829		.name = "adt7410",
830	},
831	.probe = adt7410_probe,
832	.remove = __devexit_p(adt7410_remove),
833	.id_table = adt7410_id,
834};
835module_i2c_driver(adt7410_driver);
836
837MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
838MODULE_DESCRIPTION("Analog Devices ADT7410 digital"
839			" temperature sensor driver");
840MODULE_LICENSE("GPL v2");