Title: [8676] trunk/drivers/staging/iio/addac: Task[#6015] Add adt7516/7/8 support to adt7316 driver.

Diff

Modified: trunk/drivers/staging/iio/addac/Kconfig (8675 => 8676)


--- trunk/drivers/staging/iio/addac/Kconfig	2010-04-28 09:28:37 UTC (rev 8675)
+++ trunk/drivers/staging/iio/addac/Kconfig	2010-04-29 06:08:54 UTC (rev 8676)
@@ -4,21 +4,23 @@
 comment "Analog digital bi-direction convertors"
 
 config ADT7316
-	tristate "Analog Devices ADT7316/7/8 temperature sensor, ADC and DAC driver"
+	tristate "Analog Devices ADT7316/7/8 ADT7516/7/8 temperature sensor, ADC and DAC driver"
 	depends on SPI
 	help
 	  Say yes here to build support for Analog Devices ADT7316/7/8
-	  temperature sensors, ADC and DAC.
+	  and ADT7516/7/8 temperature sensors, ADC and DAC.
 
 config ADT7316_SPI
-	tristate "Analog Devices ADT7316/7/8 SPI bus driver"
+	tristate "Analog Devices ADT7316/7/8 ADT7516/7/8 SPI bus driver"
 	depends on SPI && ADT7316
 	default y
 	help
-	  Say yes here to build SPI bus support for Analog Devices ADT7316/7/8.
+	  Say yes here to build SPI bus support for Analog Devices ADT7316/7/8
+	  and ADT7516/7/8.
 
 config ADT7316_I2C
-	tristate "Analog Devices ADT7316/7/8 I2C bus driver"
+	tristate "Analog Devices ADT7316/7/8 ADT7516/7/8 I2C bus driver"
 	depends on I2C && ADT7316
 	help
-	  Say yes here to build I2C bus support for Analog Devices ADT7316/7/8.
+	  Say yes here to build I2C bus support for Analog Devices ADT7316/7/8
+	  and ADT7516/7/8.

Modified: trunk/drivers/staging/iio/addac/adt7316-i2c.c (8675 => 8676)


--- trunk/drivers/staging/iio/addac/adt7316-i2c.c	2010-04-28 09:28:37 UTC (rev 8675)
+++ trunk/drivers/staging/iio/addac/adt7316-i2c.c	2010-04-29 06:08:54 UTC (rev 8676)
@@ -1,5 +1,6 @@
 /*
- * I2C bus driver for ADT7316/7/8 digital temperature sensor, ADC and DAC
+ * I2C bus driver for ADT7316/7/8 ADT7516/7/8 digital temperature
+ * sensor, ADC and DAC
  *
  * Copyright 2010 Analog Devices Inc.
  *
@@ -114,6 +115,9 @@
 	{ "adt7316", 0 },
 	{ "adt7317", 0 },
 	{ "adt7318", 0 },
+	{ "adt7516", 0 },
+	{ "adt7517", 0 },
+	{ "adt7518", 0 },
 	{ }
 };
 
@@ -157,8 +161,8 @@
 }
 
 MODULE_AUTHOR("Sonic Zhang <[email protected]>");
-MODULE_DESCRIPTION("I2C bus driver for Analog Devices ADT7316/7/8 digital"
-			" temperature sensor, ADC and DAC");
+MODULE_DESCRIPTION("I2C bus driver for Analog Devices ADT7316/7/8 and"
+			"ADT7516/7/8 digital temperature sensor, ADC and DAC");
 MODULE_LICENSE("GPL v2");
 
 module_init(adt7316_i2c_init);

Modified: trunk/drivers/staging/iio/addac/adt7316-spi.c (8675 => 8676)


--- trunk/drivers/staging/iio/addac/adt7316-spi.c	2010-04-28 09:28:37 UTC (rev 8675)
+++ trunk/drivers/staging/iio/addac/adt7316-spi.c	2010-04-29 06:08:54 UTC (rev 8676)
@@ -1,5 +1,6 @@
 /*
- * API bus driver for ADT7316/7/8 digital temperature sensor, ADC and DAC
+ * API bus driver for ADT7316/7/8 ADT7516/7/8 digital temperature
+ * sensor, ADC and DAC
  *
  * Copyright 2010 Analog Devices Inc.
  *
@@ -123,6 +124,9 @@
 	{ "adt7316", 0 },
 	{ "adt7317", 0 },
 	{ "adt7318", 0 },
+	{ "adt7516", 0 },
+	{ "adt7517", 0 },
+	{ "adt7518", 0 },
 	{ }
 };
 
@@ -167,8 +171,8 @@
 }
 
 MODULE_AUTHOR("Sonic Zhang <[email protected]>");
-MODULE_DESCRIPTION("SPI bus driver for Analog Devices ADT7316/7/8 digital"
-			" temperature sensor, ADC and DAC");
+MODULE_DESCRIPTION("SPI bus driver for Analog Devices ADT7316/7/8 and"
+			"ADT7516/7/8 digital temperature sensor, ADC and DAC");
 MODULE_LICENSE("GPL v2");
 
 module_init(adt7316_spi_init);

Modified: trunk/drivers/staging/iio/addac/adt7316.c (8675 => 8676)


--- trunk/drivers/staging/iio/addac/adt7316.c	2010-04-28 09:28:37 UTC (rev 8675)
+++ trunk/drivers/staging/iio/addac/adt7316.c	2010-04-29 06:08:54 UTC (rev 8676)
@@ -1,6 +1,7 @@
 /*
- * ADT7316 digital temperature sensor driver supporting ADT7316/7/8
+ * ADT7316 digital temperature sensor driver supporting ADT7316/7/8 ADT7516/7/8
  *
+ *
  * Copyright 2010 Analog Devices Inc.
  *
  * Licensed under the GPL-2 or later.
@@ -23,19 +24,25 @@
 /*
  * ADT7316 registers definition
  */
-#define ADT7316_INT_STAT1               0x0
-#define ADT7316_INT_STAT2               0x1
-#define ADT7316_LSB_IN_TEMP_VDD         0x3
+#define ADT7316_INT_STAT1		0x0
+#define ADT7316_INT_STAT2		0x1
+#define ADT7316_LSB_IN_TEMP_VDD		0x3
 #define ADT7316_LSB_IN_TEMP_MASK	0x3
 #define ADT7316_LSB_VDD_MASK		0xC
 #define ADT7316_LSB_VDD_OFFSET		2
-#define ADT7316_LSB_EX_TEMP             0x4
+#define ADT7316_LSB_EX_TEMP_AIN		0x4
 #define ADT7316_LSB_EX_TEMP_MASK	0x3
+#define ADT7516_LSB_AIN_SHIFT		2
 #define ADT7316_AD_MSB_DATA_BASE        0x6
 #define ADT7316_AD_MSB_DATA_REGS        3
-#define ADT7316_MSB_VDD                 0x6
-#define ADT7316_MSB_IN_TEMP             0x7
-#define ADT7316_MSB_EX_TEMP             0x8
+#define ADT7516_AD_MSB_DATA_REGS        6
+#define ADT7316_MSB_VDD			0x6
+#define ADT7316_MSB_IN_TEMP		0x7
+#define ADT7316_MSB_EX_TEMP		0x8
+#define ADT7516_MSB_AIN1		0x8
+#define ADT7516_MSB_AIN2		0x9
+#define ADT7516_MSB_AIN3		0xA
+#define ADT7516_MSB_AIN4		0xB
 #define ADT7316_DA_DATA_BASE		0x10
 #define ADT7316_DA_MSB_DATA_REGS	4
 #define ADT7316_LSB_DAC_A		0x10
@@ -63,6 +70,12 @@
 #define ADT7316_IN_TEMP_LOW		0x26
 #define ADT7316_EX_TEMP_HIGH		0x27
 #define ADT7316_EX_TEMP_LOW		0x28
+#define ADT7516_AIN2_HIGH		0x2B
+#define ADT7516_AIN2_LOW		0x2C
+#define ADT7516_AIN3_HIGH		0x2D
+#define ADT7516_AIN3_LOW		0x2E
+#define ADT7516_AIN4_HIGH		0x2F
+#define ADT7516_AIN4_LOW		0x30
 #define ADT7316_DEVICE_ID		0x4D
 #define ADT7316_MANUFACTURE_ID		0x4E
 #define ADT7316_DEVICE_REV		0x4F
@@ -72,6 +85,9 @@
  * ADT7316 config1
  */
 #define ADT7316_EN			0x1
+#define ADT7516_SEL_EX_TEMP		0x4
+#define ADT7516_SEL_AIN1_2_EX_TEMP_MASK	0x6
+#define ADT7516_SEL_AIN3		0x8
 #define ADT7316_INT_EN			0x20
 #define ADT7316_INT_POLARITY		0x40
 #define ADT7316_PD			0x80
@@ -80,9 +96,14 @@
  * ADT7316 config2
  */
 #define ADT7316_AD_SINGLE_CH_MASK	0x3
+#define ADT7516_AD_SINGLE_CH_MASK	0x7
 #define ADT7316_AD_SINGLE_CH_VDD	0
 #define ADT7316_AD_SINGLE_CH_IN		1
 #define ADT7316_AD_SINGLE_CH_EX		2
+#define ADT7516_AD_SINGLE_CH_AIN1	2
+#define ADT7516_AD_SINGLE_CH_AIN2	3
+#define ADT7516_AD_SINGLE_CH_AIN3	4
+#define ADT7516_AD_SINGLE_CH_AIN4	5
 #define ADT7316_AD_SINGLE_CH_MODE	0x10
 #define ADT7316_DISABLE_AVERAGING	0x20
 #define ADT7316_EN_SMBUS_TIMEOUT	0x40
@@ -94,6 +115,7 @@
 #define ADT7316_ADCLK_22_5		0x1
 #define ADT7316_DA_HIGH_RESOLUTION	0x2
 #define ADT7316_DA_EN_VIA_DAC_LDCA	0x4
+#define ADT7516_AIN_IN_VREF		0x10
 #define ADT7316_EN_IN_TEMP_PROP_DACA	0x20
 #define ADT7316_EN_EX_TEMP_PROP_DACB	0x40
 
@@ -113,7 +135,11 @@
  * ADT7316 LDAC config
  */
 #define ADT7316_LDAC_EN_DA_MASK		0xF
-#define ADT7316_IN_VREF			0x10
+#define ADT7316_DAC_IN_VREF		0x10
+#define ADT7516_DAC_AB_IN_VREF		0x10
+#define ADT7516_DAC_CD_IN_VREF		0x20
+#define ADT7516_DAC_IN_VREF_OFFSET	4
+#define ADT7516_DAC_IN_VREF_MASK	0x30
 
 /*
  * ADT7316 INT_MASK2
@@ -129,6 +155,20 @@
 #define ADT7316_T_VALUE_FLOAT_MASK	0x2
 
 /*
+ * Chip ID
+ */
+#define ID_ADT7316		0x1
+#define ID_ADT7317		0x2
+#define ID_ADT7318		0x3
+#define ID_ADT7516		0x11
+#define ID_ADT7517		0x12
+#define ID_ADT7518		0x13
+
+#define ID_FAMILY_MASK		0xF0
+#define ID_ADT73XX		0x0
+#define ID_ADT75XX		0x10
+
+/*
  * struct adt7316_chip_info - chip specifc information
  */
 
@@ -139,13 +179,14 @@
 	s64			last_timestamp;
 	struct adt7316_bus	bus;
 	u16			ldac_pin;
+	u16			int_mask;	/* 0x2f */
 	u8			config1;
 	u8			config2;
 	u8			config3;
 	u8			dac_config;	/* DAC config */
 	u8			ldac_config;	/* LDAC config */
-	u8			dac_bits;
-	u8			int_mask;
+	u8			dac_bits;	/* 8, 10, 12 */
+	u8			id;		/* chip id */
 };
 
 /*
@@ -157,8 +198,15 @@
 #define ADT7316_EX_TEMP_HIGH_INT_MASK	0x4
 #define ADT7316_EX_TEMP_LOW_INT_MASK	0x8
 #define ADT7316_EX_TEMP_FAULT_INT_MASK	0x10
-#define ADT7316_VDD_INT_MASK		0x20
+#define ADT7516_AIN1_INT_MASK		0x4
+#define ADT7516_AIN2_INT_MASK		0x20
+#define ADT7516_AIN3_INT_MASK		0x40
+#define ADT7516_AIN4_INT_MASK		0x80
+#define ADT7316_VDD_INT_MASK		0x100
 #define ADT7316_TEMP_INT_MASK		0x1F
+#define ADT7516_AIN_INT_MASK		0xE0
+#define ADT7316_TEMP_AIN_INT_MASK	\
+	(ADT7316_TEMP_INT_MASK | ADT7316_TEMP_INT_MASK)
 
 /*
  * struct adt7316_chip_info - chip specifc information
@@ -225,6 +273,50 @@
 		adt7316_store_enabled,
 		0);
 
+static ssize_t adt7316_show_select_ex_temp(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	if ((chip->id & ID_FAMILY_MASK) != ID_ADT75XX)
+		return -EPERM;
+
+	return sprintf(buf, "%d\n", !!(chip->config1 & ADT7516_SEL_EX_TEMP));
+}
+
+static ssize_t adt7316_store_select_ex_temp(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+	u8 config1;
+	int ret;
+
+	if ((chip->id & ID_FAMILY_MASK) != ID_ADT75XX)
+		return -EPERM;
+
+	config1 = chip->config1 & (~ADT7516_SEL_EX_TEMP);
+	if (!memcmp(buf, "1", 1))
+		config1 |= ADT7516_SEL_EX_TEMP;
+
+	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG1, config1);
+	if (ret)
+		return -EIO;
+
+	chip->config1 = config1;
+
+	return len;
+}
+
+static IIO_DEVICE_ATTR(select_ex_temp, S_IRUGO | S_IWUSR,
+		adt7316_show_select_ex_temp,
+		adt7316_store_select_ex_temp,
+		0);
+
 static ssize_t adt7316_show_mode(struct device *dev,
 		struct device_attribute *attr,
 		char *buf)
@@ -285,13 +377,29 @@
 	if (!(chip->config2 & ADT7316_AD_SINGLE_CH_MODE))
 		return -EPERM;
 
-	switch (chip->config2 & ADT7316_AD_SINGLE_CH_MASK) {
+	switch (chip->config2 & ADT7516_AD_SINGLE_CH_MASK) {
 	case ADT7316_AD_SINGLE_CH_VDD:
 		return sprintf(buf, "0 - VDD\n");
 	case ADT7316_AD_SINGLE_CH_IN:
 		return sprintf(buf, "1 - Internal Temperature\n");
 	case ADT7316_AD_SINGLE_CH_EX:
-		return sprintf(buf, "2 - External Temperature\n");
+		if (((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) &&
+			(chip->config1 & ADT7516_SEL_AIN1_2_EX_TEMP_MASK) == 0)
+			return sprintf(buf, "2 - AIN1\n");
+		else
+			return sprintf(buf, "2 - External Temperature\n");
+	case ADT7516_AD_SINGLE_CH_AIN2:
+		if ((chip->config1 & ADT7516_SEL_AIN1_2_EX_TEMP_MASK) == 0)
+			return sprintf(buf, "3 - AIN2\n");
+		else
+			return sprintf(buf, "N/A\n");
+	case ADT7516_AD_SINGLE_CH_AIN3:
+		if (chip->config1 & ADT7516_SEL_AIN3)
+			return sprintf(buf, "4 - AIN3\n");
+		else
+			return sprintf(buf, "N/A\n");
+	case ADT7516_AD_SINGLE_CH_AIN4:
+		return sprintf(buf, "5 - AIN4\n");
 	default:
 		return sprintf(buf, "N/A\n");
 	};
@@ -312,11 +420,22 @@
 		return -EPERM;
 
 	ret = strict_strtoul(buf, 10, &data);
-	if (ret || data > 2)
+	if (ret)
 		return -EINVAL;
 
-	config2 = chip->config2 & (~ADT7316_AD_SINGLE_CH_MASK);
+	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) {
+		if (data > 5)
+			return -EINVAL;
 
+		config2 = chip->config2 & (~ADT7516_AD_SINGLE_CH_MASK);
+	} else {
+		if (data > 2)
+			return -EINVAL;
+
+		config2 = chip->config2 & (~ADT7316_AD_SINGLE_CH_MASK);
+	}
+
+
 	config2 |= data;
 
 	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG2, config2);
@@ -343,7 +462,12 @@
 	if (!(chip->config2 & ADT7316_AD_SINGLE_CH_MODE))
 		return -EPERM;
 
-	return sprintf(buf, "0 - VDD\n1 - Internal Temperature\n"
+	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
+		return sprintf(buf, "0 - VDD\n1 - Internal Temperature\n"
+				"2 - External Temperature or AIN2\n"
+				"3 - AIN2\n4 - AIN3\n5 - AIN4\n");
+	else
+		return sprintf(buf, "0 - VDD\n1 - Internal Temperature\n"
 				"2 - External Temperature\n");
 }
 
@@ -537,9 +661,9 @@
 	struct adt7316_chip_info *chip = dev_info->dev_data;
 
 	if (chip->config3 & ADT7316_DA_HIGH_RESOLUTION) {
-		if (!strcmp(chip->name, "adt7316"))
+		if (chip->id == ID_ADT7316)
 			return sprintf(buf, "1 (12 bits)\n");
-		else if (!strcmp(chip->name, "adt7317"))
+		else if (chip->id == ID_ADT7317)
 			return sprintf(buf, "1 (10 bits)\n");
 	}
 
@@ -560,9 +684,9 @@
 
 	if (!memcmp(buf, "1", 1)) {
 		config3 = chip->config3 | ADT7316_DA_HIGH_RESOLUTION;
-		if (!strcmp(chip->name, "adt7316"))
+		if (chip->id == ID_ADT7316)
 			chip->dac_bits = 12;
-		else if (!strcmp(chip->name, "adt7317"))
+		else if (chip->id == ID_ADT7317)
 			chip->dac_bits = 10;
 	} else
 		config3 = chip->config3 & (~ADT7316_DA_HIGH_RESOLUTION);
@@ -581,6 +705,53 @@
 		adt7316_store_da_high_resolution,
 		0);
 
+static ssize_t adt7316_show_AIN_internal_Vref(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	if ((chip->id & ID_FAMILY_MASK) != ID_ADT75XX)
+		return -EPERM;
+
+	return sprintf(buf, "%d\n",
+		!!(chip->config3 & ADT7516_AIN_IN_VREF));
+}
+
+static ssize_t adt7316_store_AIN_internal_Vref(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+	u8 config3;
+	int ret;
+
+	if ((chip->id & ID_FAMILY_MASK) != ID_ADT75XX)
+		return -EPERM;
+
+	if (memcmp(buf, "1", 1))
+		config3 = chip->config3 & (~ADT7516_AIN_IN_VREF);
+	else
+		config3 = chip->config3 | ADT7516_AIN_IN_VREF;
+
+	ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG3, config3);
+	if (ret)
+		return -EIO;
+
+	chip->config3 = config3;
+
+	return len;
+}
+
+static IIO_DEVICE_ATTR(AIN_internal_Vref, S_IRUGO | S_IWUSR,
+		adt7316_show_AIN_internal_Vref,
+		adt7316_store_AIN_internal_Vref,
+		0);
+
+
 static ssize_t adt7316_show_enable_prop_DACA(struct device *dev,
 		struct device_attribute *attr,
 		char *buf)
@@ -827,6 +998,9 @@
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct adt7316_chip_info *chip = dev_info->dev_data;
 
+	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
+		return -EPERM;
+
 	return sprintf(buf, "%d\n",
 		!!(chip->dac_config & ADT7316_VREF_BYPASS_DAC_AB));
 }
@@ -841,6 +1015,9 @@
 	u8 dac_config;
 	int ret;
 
+	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
+		return -EPERM;
+
 	dac_config = chip->dac_config & (~ADT7316_VREF_BYPASS_DAC_AB);
 	if (!memcmp(buf, "1", 1))
 		dac_config |= ADT7316_VREF_BYPASS_DAC_AB;
@@ -866,6 +1043,9 @@
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct adt7316_chip_info *chip = dev_info->dev_data;
 
+	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
+		return -EPERM;
+
 	return sprintf(buf, "%d\n",
 		!!(chip->dac_config & ADT7316_VREF_BYPASS_DAC_CD));
 }
@@ -880,6 +1060,9 @@
 	u8 dac_config;
 	int ret;
 
+	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
+		return -EPERM;
+
 	dac_config = chip->dac_config & (~ADT7316_VREF_BYPASS_DAC_CD);
 	if (!memcmp(buf, "1", 1))
 		dac_config |= ADT7316_VREF_BYPASS_DAC_CD;
@@ -898,18 +1081,23 @@
 		adt7316_store_DA_CD_Vref_bypass,
 		0);
 
-static ssize_t adt7316_show_internal_Vref(struct device *dev,
+static ssize_t adt7316_show_DAC_internal_Vref(struct device *dev,
 		struct device_attribute *attr,
 		char *buf)
 {
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct adt7316_chip_info *chip = dev_info->dev_data;
 
-	return sprintf(buf, "%d\n",
-		!!(chip->dac_config & ADT7316_IN_VREF));
+	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
+		return sprintf(buf, "0x%x\n",
+			(chip->dac_config & ADT7516_DAC_IN_VREF_MASK) >>
+			ADT7516_DAC_IN_VREF_OFFSET);
+	else
+		return sprintf(buf, "%d\n",
+			!!(chip->dac_config & ADT7316_DAC_IN_VREF));
 }
 
-static ssize_t adt7316_store_internal_Vref(struct device *dev,
+static ssize_t adt7316_store_DAC_internal_Vref(struct device *dev,
 		struct device_attribute *attr,
 		const char *buf,
 		size_t len)
@@ -917,12 +1105,29 @@
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct adt7316_chip_info *chip = dev_info->dev_data;
 	u8 ldac_config;
+	unsigned long data;
 	int ret;
 
-	ldac_config = chip->ldac_config & (~ADT7316_IN_VREF);
-	if (!memcmp(buf, "1", 1))
-		ldac_config |= ADT7316_IN_VREF;
+	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) {
+		ret = strict_strtoul(buf, 16, &data);
+		if (ret || data > 3)
+			return -EINVAL;
 
+		ldac_config = chip->ldac_config & (~ADT7516_DAC_IN_VREF_MASK);
+		if (data & 0x1)
+			ldac_config |= ADT7516_DAC_AB_IN_VREF;
+		else if (data & 0x2)
+			ldac_config |= ADT7516_DAC_CD_IN_VREF;
+	} else {
+		ret = strict_strtoul(buf, 16, &data);
+		if (ret)
+			return -EINVAL;
+
+		ldac_config = chip->ldac_config & (~ADT7316_DAC_IN_VREF);
+		if (data)
+			ldac_config = chip->ldac_config | ADT7316_DAC_IN_VREF;
+	}
+
 	ret = chip->bus.write(chip->bus.client, ADT7316_LDAC_CONFIG, ldac_config);
 	if (ret)
 		return -EIO;
@@ -932,12 +1137,12 @@
 	return len;
 }
 
-static IIO_DEVICE_ATTR(internal_Vref, S_IRUGO | S_IWUSR,
-		adt7316_show_internal_Vref,
-		adt7316_store_internal_Vref,
+static IIO_DEVICE_ATTR(DAC_internal_Vref, S_IRUGO | S_IWUSR,
+		adt7316_show_DAC_internal_Vref,
+		adt7316_store_DAC_internal_Vref,
 		0);
 
-static ssize_t adt7316_show_temp(struct adt7316_chip_info *chip,
+static ssize_t adt7316_show_ad(struct adt7316_chip_info *chip,
 		int channel, char *buf)
 {
 	u16 data;
@@ -946,7 +1151,7 @@
 	int ret;
 
 	if ((chip->config2 & ADT7316_AD_SINGLE_CH_MODE) &&
-		channel != (chip->config2 & ADT7316_AD_SINGLE_CH_MASK))
+		channel != (chip->config2 & ADT7516_AD_SINGLE_CH_MASK))
 		return -EPERM;
 
 	switch (channel) {
@@ -964,35 +1169,41 @@
 		data = "" << ADT7316_T_VALUE_FLOAT_OFFSET;
 		data |= lsb & ADT7316_LSB_IN_TEMP_MASK;
 		break;
-	case ADT7316_AD_SINGLE_CH_EX:
+	case ADT7316_AD_SINGLE_CH_VDD:
 		ret = chip->bus.read(chip->bus.client,
-			ADT7316_LSB_EX_TEMP, &lsb);
+			ADT7316_LSB_IN_TEMP_VDD, &lsb);
 		if (ret)
 			return -EIO;
 
 		ret = chip->bus.read(chip->bus.client,
+
 			ADT7316_AD_MSB_DATA_BASE + channel, &msb);
 		if (ret)
 			return -EIO;
 
 		data = "" << ADT7316_T_VALUE_FLOAT_OFFSET;
-		data |= lsb & ADT7316_LSB_EX_TEMP_MASK;
-		break;
-	default: /* ADT7316_AD_SINGLE_CH_VDD */
+		data |= (lsb & ADT7316_LSB_VDD_MASK) >> ADT7316_LSB_VDD_OFFSET;
+		return sprintf(buf, "%d\n", data);
+	default: /* ex_temp and ain */
 		ret = chip->bus.read(chip->bus.client,
-			ADT7316_LSB_IN_TEMP_VDD, &lsb);
+			ADT7316_LSB_EX_TEMP_AIN, &lsb);
 		if (ret)
 			return -EIO;
 
 		ret = chip->bus.read(chip->bus.client,
-
 			ADT7316_AD_MSB_DATA_BASE + channel, &msb);
 		if (ret)
 			return -EIO;
 
 		data = "" << ADT7316_T_VALUE_FLOAT_OFFSET;
-		data |= (lsb & ADT7316_LSB_VDD_MASK) >> ADT7316_LSB_VDD_OFFSET;
-		return sprintf(buf, "%d\n", data);
+		data |= lsb & (ADT7316_LSB_EX_TEMP_MASK <<
+			(ADT7516_LSB_AIN_SHIFT * (channel -
+			(ADT7316_MSB_EX_TEMP - ADT7316_AD_MSB_DATA_BASE))));
+
+		if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
+			return sprintf(buf, "%d\n", data);
+		else
+			break;
 	};
 
 	if (data & ADT7316_T_VALUE_SIGN) {
@@ -1013,9 +1224,9 @@
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct adt7316_chip_info *chip = dev_info->dev_data;
 
-	return adt7316_show_temp(chip, ADT7316_AD_SINGLE_CH_VDD, buf);
+	return adt7316_show_ad(chip, ADT7316_AD_SINGLE_CH_VDD, buf);
 }
-static IIO_DEVICE_ATTR(vdd, S_IRUGO, adt7316_show_VDD, NULL, 0);
+static IIO_DEVICE_ATTR(VDD, S_IRUGO, adt7316_show_VDD, NULL, 0);
 
 static ssize_t adt7316_show_in_temp(struct device *dev,
 		struct device_attribute *attr,
@@ -1024,23 +1235,57 @@
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct adt7316_chip_info *chip = dev_info->dev_data;
 
-	return adt7316_show_temp(chip, ADT7316_AD_SINGLE_CH_IN, buf);
+	return adt7316_show_ad(chip, ADT7316_AD_SINGLE_CH_IN, buf);
 }
 
 static IIO_DEVICE_ATTR(in_temp, S_IRUGO, adt7316_show_in_temp, NULL, 0);
 
-static ssize_t adt7316_show_ex_temp(struct device *dev,
+static ssize_t adt7316_show_ex_temp_AIN1(struct device *dev,
 		struct device_attribute *attr,
 		char *buf)
 {
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct adt7316_chip_info *chip = dev_info->dev_data;
 
-	return adt7316_show_temp(chip, ADT7316_AD_SINGLE_CH_EX, buf);
+	return adt7316_show_ad(chip, ADT7316_AD_SINGLE_CH_EX, buf);
 }
 
-static IIO_DEVICE_ATTR(ex_temp, S_IRUGO, adt7316_show_ex_temp, NULL, 0);
+static IIO_DEVICE_ATTR(ex_temp_AIN1, S_IRUGO, adt7316_show_ex_temp_AIN1, NULL, 0);
+static IIO_DEVICE_ATTR(ex_temp, S_IRUGO, adt7316_show_ex_temp_AIN1, NULL, 0);
 
+static ssize_t adt7316_show_AIN2(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	return adt7316_show_ad(chip, ADT7516_AD_SINGLE_CH_AIN2, buf);
+}
+static IIO_DEVICE_ATTR(AIN2, S_IRUGO, adt7316_show_AIN2, NULL, 0);
+
+static ssize_t adt7316_show_AIN3(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	return adt7316_show_ad(chip, ADT7516_AD_SINGLE_CH_AIN3, buf);
+}
+static IIO_DEVICE_ATTR(AIN3, S_IRUGO, adt7316_show_AIN3, NULL, 0);
+
+static ssize_t adt7316_show_AIN4(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct adt7316_chip_info *chip = dev_info->dev_data;
+
+	return adt7316_show_ad(chip, ADT7516_AD_SINGLE_CH_AIN4, buf);
+}
+static IIO_DEVICE_ATTR(AIN4, S_IRUGO, adt7316_show_AIN4, NULL, 0);
+
 static ssize_t adt7316_show_temp_offset(struct adt7316_chip_info *chip,
 		int offset_addr, char *buf)
 {
@@ -1460,8 +1705,8 @@
 	&iio_dev_attr_update_DAC.dev_attr.attr,
 	&iio_dev_attr_DA_AB_Vref_bypass.dev_attr.attr,
 	&iio_dev_attr_DA_CD_Vref_bypass.dev_attr.attr,
-	&iio_dev_attr_internal_Vref.dev_attr.attr,
-	&iio_dev_attr_vdd.dev_attr.attr,
+	&iio_dev_attr_DAC_internal_Vref.dev_attr.attr,
+	&iio_dev_attr_VDD.dev_attr.attr,
 	&iio_dev_attr_in_temp.dev_attr.attr,
 	&iio_dev_attr_ex_temp.dev_attr.attr,
 	&iio_dev_attr_in_temp_offset.dev_attr.attr,
@@ -1484,27 +1729,86 @@
 	.attrs = adt7316_attributes,
 };
 
+static struct attribute *adt7516_attributes[] = {
+	&iio_dev_attr_all_modes.dev_attr.attr,
+	&iio_dev_attr_mode.dev_attr.attr,
+	&iio_dev_attr_select_ex_temp.dev_attr.attr,
+	&iio_dev_attr_reset.dev_attr.attr,
+	&iio_dev_attr_enabled.dev_attr.attr,
+	&iio_dev_attr_ad_channel.dev_attr.attr,
+	&iio_dev_attr_all_ad_channels.dev_attr.attr,
+	&iio_dev_attr_disable_averaging.dev_attr.attr,
+	&iio_dev_attr_enable_smbus_timeout.dev_attr.attr,
+	&iio_dev_attr_powerdown.dev_attr.attr,
+	&iio_dev_attr_fast_ad_clock.dev_attr.attr,
+	&iio_dev_attr_AIN_internal_Vref.dev_attr.attr,
+	&iio_dev_attr_da_high_resolution.dev_attr.attr,
+	&iio_dev_attr_enable_proportion_DACA.dev_attr.attr,
+	&iio_dev_attr_enable_proportion_DACB.dev_attr.attr,
+	&iio_dev_attr_DAC_2Vref_channels_mask.dev_attr.attr,
+	&iio_dev_attr_DAC_update_mode.dev_attr.attr,
+	&iio_dev_attr_all_DAC_update_modes.dev_attr.attr,
+	&iio_dev_attr_update_DAC.dev_attr.attr,
+	&iio_dev_attr_DA_AB_Vref_bypass.dev_attr.attr,
+	&iio_dev_attr_DA_CD_Vref_bypass.dev_attr.attr,
+	&iio_dev_attr_DAC_internal_Vref.dev_attr.attr,
+	&iio_dev_attr_VDD.dev_attr.attr,
+	&iio_dev_attr_in_temp.dev_attr.attr,
+	&iio_dev_attr_ex_temp_AIN1.dev_attr.attr,
+	&iio_dev_attr_AIN2.dev_attr.attr,
+	&iio_dev_attr_AIN3.dev_attr.attr,
+	&iio_dev_attr_AIN4.dev_attr.attr,
+	&iio_dev_attr_in_temp_offset.dev_attr.attr,
+	&iio_dev_attr_ex_temp_offset.dev_attr.attr,
+	&iio_dev_attr_in_analog_temp_offset.dev_attr.attr,
+	&iio_dev_attr_ex_analog_temp_offset.dev_attr.attr,
+	&iio_dev_attr_DAC_A.dev_attr.attr,
+	&iio_dev_attr_DAC_B.dev_attr.attr,
+	&iio_dev_attr_DAC_C.dev_attr.attr,
+	&iio_dev_attr_DAC_D.dev_attr.attr,
+	&iio_dev_attr_device_id.dev_attr.attr,
+	&iio_dev_attr_manufactorer_id.dev_attr.attr,
+	&iio_dev_attr_device_rev.dev_attr.attr,
+	&iio_dev_attr_bus_type.dev_attr.attr,
+	&iio_dev_attr_name.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group adt7516_attribute_group = {
+	.attrs = adt7516_attributes,
+};
+
+
 /*
  * temperature bound events
  */
 
-#define IIO_EVENT_CODE_ADT7316_IN_TEMP_HIGH    (IIO_EVENT_CODE_DEVICE_SPECIFIC + 1)
+#define IIO_EVENT_CODE_ADT7316_IN_TEMP_HIGH   (IIO_EVENT_CODE_DEVICE_SPECIFIC + 1)
 #define IIO_EVENT_CODE_ADT7316_IN_TEMP_LOW    (IIO_EVENT_CODE_DEVICE_SPECIFIC + 2)
-#define IIO_EVENT_CODE_ADT7316_EX_TEMP_HIGH    (IIO_EVENT_CODE_DEVICE_SPECIFIC + 3)
+#define IIO_EVENT_CODE_ADT7316_EX_TEMP_HIGH   (IIO_EVENT_CODE_DEVICE_SPECIFIC + 3)
 #define IIO_EVENT_CODE_ADT7316_EX_TEMP_LOW    (IIO_EVENT_CODE_DEVICE_SPECIFIC + 4)
-#define IIO_EVENT_CODE_ADT7316_EX_TEMP_FAULT   (IIO_EVENT_CODE_DEVICE_SPECIFIC + 5)
-#define IIO_EVENT_CODE_ADT7316_VDD	      (IIO_EVENT_CODE_DEVICE_SPECIFIC + 6)
+#define IIO_EVENT_CODE_ADT7316_EX_TEMP_FAULT  (IIO_EVENT_CODE_DEVICE_SPECIFIC + 5)
+#define IIO_EVENT_CODE_ADT7516_AIN1           (IIO_EVENT_CODE_DEVICE_SPECIFIC + 3)
+#define IIO_EVENT_CODE_ADT7516_AIN2           (IIO_EVENT_CODE_DEVICE_SPECIFIC + 6)
+#define IIO_EVENT_CODE_ADT7516_AIN3           (IIO_EVENT_CODE_DEVICE_SPECIFIC + 7)
+#define IIO_EVENT_CODE_ADT7516_AIN4           (IIO_EVENT_CODE_DEVICE_SPECIFIC + 8)
+#define IIO_EVENT_CODE_ADT7316_VDD	      (IIO_EVENT_CODE_DEVICE_SPECIFIC + 9)
 
 static void adt7316_interrupt_bh(struct work_struct *work_s)
 {
 	struct iio_work_cont *wc = to_iio_work_cont_no_check(work_s);
 	struct adt7316_chip_info *chip = wc->st;
 	u8 stat1, stat2;
-	int i, ret;
+	int i, ret, count;
 
 	ret = chip->bus.read(chip->bus.client, ADT7316_INT_STAT1, &stat1);
 	if (!ret) {
-		for (i = 0; i < 5; i++) {
+		if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
+			count = 8;
+		else
+			count = 5;
+
+		for (i = 0; i < count; i++) {
 			if (stat1 & (1 << i))
 				iio_push_event(chip->indio_dev, 0,
 					IIO_EVENT_CODE_ADT7316_IN_TEMP_HIGH + i,
@@ -1580,18 +1884,21 @@
 		chip->int_mask |= data & ADT7316_VDD_INT_MASK;
 	}
 
-	if (data & ADT7316_TEMP_INT_MASK)
-		/* mask in reg is opposite, set 1 to disable */
-		mask = (~data) & ADT7316_TEMP_INT_MASK;
+	if (data & ADT7316_TEMP_AIN_INT_MASK) {
+		if ((chip->id & ID_FAMILY_MASK) == ID_ADT73XX)
+			/* mask in reg is opposite, set 1 to disable */
+			mask = (~data) & ADT7316_TEMP_INT_MASK;
+		else
+			/* mask in reg is opposite, set 1 to disable */
+			mask = (~data) & ADT7316_TEMP_AIN_INT_MASK;
+	}
 	ret = chip->bus.write(chip->bus.client, ADT7316_INT_MASK1, mask);
-	if (!ret) {
-		chip->int_mask &= ~ADT7316_TEMP_INT_MASK;
-		chip->int_mask |= data & ADT7316_TEMP_INT_MASK;
-	}
 
+	chip->int_mask = mask;
+
 	return len;
 }
-static inline ssize_t adt7316_show_temp_bound(struct device *dev,
+static inline ssize_t adt7316_show_ad_bound(struct device *dev,
 		struct device_attribute *attr,
 		u8 bound_reg,
 		char *buf)
@@ -1602,19 +1909,26 @@
 	int data;
 	int ret;
 
+	if ((chip->id & ID_FAMILY_MASK) == ID_ADT73XX &&
+		bound_reg > ADT7316_EX_TEMP_LOW)
+		return -EPERM;
+
 	ret = chip->bus.read(chip->bus.client, bound_reg, &val);
 	if (ret)
 		return -EIO;
 
 	data = ""
 
-	if (data & 0x80)
-		data -= 256;
+	if (!((chip->id & ID_FAMILY_MASK) == ID_ADT75XX &&
+		(chip->config1 & ADT7516_SEL_AIN1_2_EX_TEMP_MASK) == 0)) {
+		if (data & 0x80)
+			data -= 256;
+	}
 
 	return sprintf(buf, "%d\n", data);
 }
 
-static inline ssize_t adt7316_set_temp_bound(struct device *dev,
+static inline ssize_t adt7316_set_ad_bound(struct device *dev,
 		struct device_attribute *attr,
 		u8 bound_reg,
 		const char *buf,
@@ -1626,14 +1940,26 @@
 	u8 val;
 	int ret;
 
+	if ((chip->id & ID_FAMILY_MASK) == ID_ADT73XX &&
+		bound_reg > ADT7316_EX_TEMP_LOW)
+		return -EPERM;
+
 	ret = strict_strtol(buf, 10, &data);
-
-	if (ret || data > 127 || data < -128)
+	if (ret)
 		return -EINVAL;
 
-	if (data < 0)
-		data += 256;
+	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX &&
+		(chip->config1 & ADT7516_SEL_AIN1_2_EX_TEMP_MASK) == 0) {
+		if (data > 255 || data < 0)
+			return -EINVAL;
+	} else {
+		if (data > 127 || data < -128)
+			return -EINVAL;
 
+		if (data < 0)
+			data += 256;
+	}
+
 	val = (u8)data;
 
 	ret = chip->bus.write(chip->bus.client, bound_reg, val);
@@ -1647,7 +1973,7 @@
 		struct device_attribute *attr,
 		char *buf)
 {
-	return adt7316_show_temp_bound(dev, attr,
+	return adt7316_show_ad_bound(dev, attr,
 			ADT7316_IN_TEMP_HIGH, buf);
 }
 
@@ -1656,7 +1982,7 @@
 		const char *buf,
 		size_t len)
 {
-	return adt7316_set_temp_bound(dev, attr,
+	return adt7316_set_ad_bound(dev, attr,
 			ADT7316_IN_TEMP_HIGH, buf, len);
 }
 
@@ -1664,7 +1990,7 @@
 		struct device_attribute *attr,
 		char *buf)
 {
-	return adt7316_show_temp_bound(dev, attr,
+	return adt7316_show_ad_bound(dev, attr,
 			ADT7316_IN_TEMP_LOW, buf);
 }
 
@@ -1673,44 +1999,146 @@
 		const char *buf,
 		size_t len)
 {
-	return adt7316_set_temp_bound(dev, attr,
+	return adt7316_set_ad_bound(dev, attr,
 			ADT7316_IN_TEMP_LOW, buf, len);
 }
 
-static ssize_t adt7316_show_ex_temp_high(struct device *dev,
+static ssize_t adt7316_show_ex_temp_ain1_high(struct device *dev,
 		struct device_attribute *attr,
 		char *buf)
 {
-	return adt7316_show_temp_bound(dev, attr,
+	return adt7316_show_ad_bound(dev, attr,
 			ADT7316_EX_TEMP_HIGH, buf);
 }
 
-static inline ssize_t adt7316_set_ex_temp_high(struct device *dev,
+static inline ssize_t adt7316_set_ex_temp_ain1_high(struct device *dev,
 		struct device_attribute *attr,
 		const char *buf,
 		size_t len)
 {
-	return adt7316_set_temp_bound(dev, attr,
+	return adt7316_set_ad_bound(dev, attr,
 			ADT7316_EX_TEMP_HIGH, buf, len);
 }
 
-static ssize_t adt7316_show_ex_temp_low(struct device *dev,
+static ssize_t adt7316_show_ex_temp_ain1_low(struct device *dev,
 		struct device_attribute *attr,
 		char *buf)
 {
-	return adt7316_show_temp_bound(dev, attr,
+	return adt7316_show_ad_bound(dev, attr,
 			ADT7316_EX_TEMP_LOW, buf);
 }
 
-static inline ssize_t adt7316_set_ex_temp_low(struct device *dev,
+static inline ssize_t adt7316_set_ex_temp_ain1_low(struct device *dev,
 		struct device_attribute *attr,
 		const char *buf,
 		size_t len)
 {
-	return adt7316_set_temp_bound(dev, attr,
+	return adt7316_set_ad_bound(dev, attr,
 			ADT7316_EX_TEMP_LOW, buf, len);
 }
 
+static ssize_t adt7316_show_ain2_high(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return adt7316_show_ad_bound(dev, attr,
+			ADT7516_AIN2_HIGH, buf);
+}
+
+static inline ssize_t adt7316_set_ain2_high(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	return adt7316_set_ad_bound(dev, attr,
+			ADT7516_AIN2_HIGH, buf, len);
+}
+
+static ssize_t adt7316_show_ain2_low(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return adt7316_show_ad_bound(dev, attr,
+			ADT7516_AIN2_LOW, buf);
+}
+
+static inline ssize_t adt7316_set_ain2_low(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	return adt7316_set_ad_bound(dev, attr,
+			ADT7516_AIN2_LOW, buf, len);
+}
+
+static ssize_t adt7316_show_ain3_high(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return adt7316_show_ad_bound(dev, attr,
+			ADT7516_AIN3_HIGH, buf);
+}
+
+static inline ssize_t adt7316_set_ain3_high(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	return adt7316_set_ad_bound(dev, attr,
+			ADT7516_AIN3_HIGH, buf, len);
+}
+
+static ssize_t adt7316_show_ain3_low(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return adt7316_show_ad_bound(dev, attr,
+			ADT7516_AIN3_LOW, buf);
+}
+
+static inline ssize_t adt7316_set_ain3_low(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	return adt7316_set_ad_bound(dev, attr,
+			ADT7516_AIN3_LOW, buf, len);
+}
+
+static ssize_t adt7316_show_ain4_high(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return adt7316_show_ad_bound(dev, attr,
+			ADT7516_AIN4_HIGH, buf);
+}
+
+static inline ssize_t adt7316_set_ain4_high(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	return adt7316_set_ad_bound(dev, attr,
+			ADT7516_AIN4_HIGH, buf, len);
+}
+
+static ssize_t adt7316_show_ain4_low(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return adt7316_show_ad_bound(dev, attr,
+			ADT7516_AIN4_LOW, buf);
+}
+
+static inline ssize_t adt7316_set_ain4_low(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	return adt7316_set_ad_bound(dev, attr,
+			ADT7516_AIN4_LOW, buf, len);
+}
+
 static ssize_t adt7316_show_int_enabled(struct device *dev,
 		struct device_attribute *attr,
 		char *buf)
@@ -1752,9 +2180,29 @@
 IIO_EVENT_ATTR_SH(in_temp_low, iio_event_adt7316,
 		adt7316_show_in_temp_low, adt7316_set_in_temp_low, 0);
 IIO_EVENT_ATTR_SH(ex_temp_high, iio_event_adt7316,
-		adt7316_show_ex_temp_high, adt7316_set_ex_temp_high, 0);
+		adt7316_show_ex_temp_ain1_high,
+		adt7316_set_ex_temp_ain1_high, 0);
 IIO_EVENT_ATTR_SH(ex_temp_low, iio_event_adt7316,
-		adt7316_show_ex_temp_low, adt7316_set_ex_temp_low, 0);
+		adt7316_show_ex_temp_ain1_low,
+		adt7316_set_ex_temp_ain1_low, 0);
+IIO_EVENT_ATTR_SH(ex_temp_ain1_high, iio_event_adt7316,
+		adt7316_show_ex_temp_ain1_high,
+		adt7316_set_ex_temp_ain1_high, 0);
+IIO_EVENT_ATTR_SH(ex_temp_ain1_low, iio_event_adt7316,
+		adt7316_show_ex_temp_ain1_low,
+		adt7316_set_ex_temp_ain1_low, 0);
+IIO_EVENT_ATTR_SH(ain2_high, iio_event_adt7316,
+		adt7316_show_ain2_high, adt7316_set_ain2_high, 0);
+IIO_EVENT_ATTR_SH(ain2_low, iio_event_adt7316,
+		adt7316_show_ain2_low, adt7316_set_ain2_low, 0);
+IIO_EVENT_ATTR_SH(ain3_high, iio_event_adt7316,
+		adt7316_show_ain3_high, adt7316_set_ain3_high, 0);
+IIO_EVENT_ATTR_SH(ain3_low, iio_event_adt7316,
+		adt7316_show_ain3_low, adt7316_set_ain3_low, 0);
+IIO_EVENT_ATTR_SH(ain4_high, iio_event_adt7316,
+		adt7316_show_ain4_high, adt7316_set_ain4_high, 0);
+IIO_EVENT_ATTR_SH(ain4_low, iio_event_adt7316,
+		adt7316_show_ain4_low, adt7316_set_ain4_low, 0);
 IIO_EVENT_ATTR_SH(int_enabled, iio_event_adt7316,
 		adt7316_show_int_enabled, adt7316_set_int_enabled, 0);
 
@@ -1772,6 +2220,26 @@
 	.attrs = adt7316_event_attributes,
 };
 
+static struct attribute *adt7516_event_attributes[] = {
+	&iio_event_attr_int_mask.dev_attr.attr,
+	&iio_event_attr_in_temp_high.dev_attr.attr,
+	&iio_event_attr_in_temp_low.dev_attr.attr,
+	&iio_event_attr_ex_temp_ain1_high.dev_attr.attr,
+	&iio_event_attr_ex_temp_ain1_low.dev_attr.attr,
+	&iio_event_attr_ain2_high.dev_attr.attr,
+	&iio_event_attr_ain2_low.dev_attr.attr,
+	&iio_event_attr_ain3_high.dev_attr.attr,
+	&iio_event_attr_ain3_low.dev_attr.attr,
+	&iio_event_attr_ain4_high.dev_attr.attr,
+	&iio_event_attr_ain4_low.dev_attr.attr,
+	&iio_event_attr_int_enabled.dev_attr.attr,
+	NULL,
+};
+
+static struct attribute_group adt7516_event_attribute_group = {
+	.attrs = adt7516_event_attributes,
+};
+
 #ifdef CONFIG_PM
 int adt7316_disable(struct device *dev)
 {
@@ -1812,9 +2280,23 @@
 
 	chip->bus = *bus;
 	chip->name = name;
+
+	if (name[4] == '3')
+		chip->id = ID_ADT7316 + (name[6] - '6');
+	else if (name[4] == '5')
+		chip->id = ID_ADT7516 + (name[6] - '6');
+	else
+		return -ENODEV;
+
 	chip->ldac_pin = adt7316_platform_data[1];
-	chip->config3 = ADT7316_DA_EN_VIA_DAC_LDCA;
+	if (chip->ldac_pin) {
+		chip->config3 |= ADT7316_DA_EN_VIA_DAC_LDCA;
+		if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
+			chip->config1 |= ADT7516_SEL_AIN3;
+	}
 	chip->int_mask = ADT7316_TEMP_INT_MASK | ADT7316_VDD_INT_MASK;
+	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
+		chip->int_mask |= ADT7516_AIN_INT_MASK;
 
 	chip->indio_dev = iio_allocate_device();
 	if (chip->indio_dev == NULL) {
@@ -1823,8 +2305,13 @@
 	}
 
 	chip->indio_dev->dev.parent = dev;
-	chip->indio_dev->attrs = &adt7316_attribute_group;
-	chip->indio_dev->event_attrs = &adt7316_event_attribute_group;
+	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) {
+		chip->indio_dev->attrs = &adt7516_attribute_group;
+		chip->indio_dev->event_attrs = &adt7516_event_attribute_group;
+	} else {
+		chip->indio_dev->attrs = &adt7316_attribute_group;
+		chip->indio_dev->event_attrs = &adt7316_event_attribute_group;
+	}
 	chip->indio_dev->dev_data = (void *)chip;
 	chip->indio_dev->driver_module = THIS_MODULE;
 	chip->indio_dev->num_interrupt_lines = 1;
@@ -1914,6 +2401,6 @@
 EXPORT_SYMBOL(adt7316_remove);
 
 MODULE_AUTHOR("Sonic Zhang <[email protected]>");
-MODULE_DESCRIPTION("Analog Devices ADT7316/7/8 digital"
+MODULE_DESCRIPTION("Analog Devices ADT7316/7/8 and ADT7516/7/8 digital"
 			" temperature sensor, ADC and DAC driver");
 MODULE_LICENSE("GPL v2");

Modified: trunk/drivers/staging/iio/addac/adt7316.h (8675 => 8676)


--- trunk/drivers/staging/iio/addac/adt7316.h	2010-04-28 09:28:37 UTC (rev 8675)
+++ trunk/drivers/staging/iio/addac/adt7316.h	2010-04-29 06:08:54 UTC (rev 8676)
@@ -1,5 +1,5 @@
 /*
- * ADT7316 digital temperature sensor driver supporting ADT7316/7/8
+ * ADT7316 digital temperature sensor driver supporting ADT7316/7/8 ADT7516/7/8
  *
  * Copyright 2010 Analog Devices Inc.
  *
_______________________________________________
Linux-kernel-commits mailing list
[email protected]
https://blackfin.uclinux.org/mailman/listinfo/linux-kernel-commits

Reply via email to