浏览代码

ad525x_dpot: add support for one time programmable pots

New parts supported:
	AD5170, AD5171, AD5172, AD5173, AD5273

Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Michael Hennerich 15 年之前
父节点
当前提交
59592d0ccc
共有 4 个文件被更改,包括 150 次插入20 次删除
  1. 1 1
      drivers/misc/Kconfig
  2. 5 0
      drivers/misc/ad525x_dpot-i2c.c
  3. 116 5
      drivers/misc/ad525x_dpot.c
  4. 28 14
      drivers/misc/ad525x_dpot.h

+ 1 - 1
drivers/misc/Kconfig

@@ -24,7 +24,7 @@ config AD525X_DPOT
 	  AD5260, AD5262, AD5263, AD5290, AD5291, AD5292, AD5293,
 	  AD5260, AD5262, AD5263, AD5290, AD5291, AD5292, AD5293,
 	  AD7376, AD8400, AD8402, AD8403, ADN2850, AD5241, AD5242,
 	  AD7376, AD8400, AD8402, AD8403, ADN2850, AD5241, AD5242,
 	  AD5243, AD5245, AD5246, AD5247, AD5248, AD5280, AD5282,
 	  AD5243, AD5245, AD5246, AD5247, AD5248, AD5280, AD5282,
-	  ADN2860
+	  ADN2860, AD5273, AD5171, AD5170, AD5172, AD5173
 	  digital potentiometer chips.
 	  digital potentiometer chips.
 
 
 	  See Documentation/misc-devices/ad525x_dpot.txt for the
 	  See Documentation/misc-devices/ad525x_dpot.txt for the

+ 5 - 0
drivers/misc/ad525x_dpot-i2c.c

@@ -97,6 +97,11 @@ static const struct i2c_device_id ad_dpot_id[] = {
 	{"ad5280", AD5280_ID},
 	{"ad5280", AD5280_ID},
 	{"ad5282", AD5282_ID},
 	{"ad5282", AD5282_ID},
 	{"adn2860", ADN2860_ID},
 	{"adn2860", ADN2860_ID},
+	{"ad5273", AD5273_ID},
+	{"ad5171", AD5171_ID},
+	{"ad5170", AD5170_ID},
+	{"ad5172", AD5172_ID},
+	{"ad5173", AD5173_ID},
 	{}
 	{}
 };
 };
 MODULE_DEVICE_TABLE(i2c, ad_dpot_id);
 MODULE_DEVICE_TABLE(i2c, ad_dpot_id);

+ 116 - 5
drivers/misc/ad525x_dpot.c

@@ -47,6 +47,11 @@
  * AD5280		1		256		20, 50, 200
  * AD5280		1		256		20, 50, 200
  * AD5282		2		256		20, 50, 200
  * AD5282		2		256		20, 50, 200
  * ADN2860		3		512		25, 250
  * ADN2860		3		512		25, 250
+ * AD5273		1		64		1, 10, 50, 100 (OTP)
+ * AD5171		1		64		5, 10, 50, 100 (OTP)
+ * AD5170		1		256		2.5, 10, 50, 100 (OTP)
+ * AD5172		2		256		2.5, 10, 50, 100 (OTP)
+ * AD5173		2		256		2.5, 10, 50, 100 (OTP)
  *
  *
  * See Documentation/misc-devices/ad525x_dpot.txt for more info.
  * See Documentation/misc-devices/ad525x_dpot.txt for more info.
  *
  *
@@ -84,7 +89,8 @@ struct dpot_data {
 	unsigned uid;
 	unsigned uid;
 	unsigned feat;
 	unsigned feat;
 	unsigned wipers;
 	unsigned wipers;
-	u16 rdac_cache[8];
+	u16 rdac_cache[MAX_RDACS];
+	DECLARE_BITMAP(otp_en_mask, MAX_RDACS);
 };
 };
 
 
 static inline int dpot_read_d8(struct dpot_data *dpot)
 static inline int dpot_read_d8(struct dpot_data *dpot)
@@ -162,6 +168,15 @@ static s32 dpot_read_i2c(struct dpot_data *dpot, u8 reg)
 		ctrl = ((reg & DPOT_RDAC_MASK) == DPOT_RDAC0) ?
 		ctrl = ((reg & DPOT_RDAC_MASK) == DPOT_RDAC0) ?
 			0 : DPOT_AD5291_RDAC_AB;
 			0 : DPOT_AD5291_RDAC_AB;
 		return dpot_read_r8d8(dpot, ctrl);
 		return dpot_read_r8d8(dpot, ctrl);
+	case DPOT_UID(AD5170_ID):
+	case DPOT_UID(AD5171_ID):
+	case DPOT_UID(AD5273_ID):
+			return dpot_read_d8(dpot);
+	case DPOT_UID(AD5172_ID):
+	case DPOT_UID(AD5173_ID):
+		ctrl = ((reg & DPOT_RDAC_MASK) == DPOT_RDAC0) ?
+			0 : DPOT_AD5272_3_A0;
+		return dpot_read_r8d8(dpot, ctrl);
 	default:
 	default:
 		if ((reg & DPOT_REG_TOL) || (dpot->max_pos > 256))
 		if ((reg & DPOT_REG_TOL) || (dpot->max_pos > 256))
 			return dpot_read_r8d16(dpot, (reg & 0xF8) |
 			return dpot_read_r8d16(dpot, (reg & 0xF8) |
@@ -242,7 +257,7 @@ static s32 dpot_write_spi(struct dpot_data *dpot, u8 reg, u16 value)
 static s32 dpot_write_i2c(struct dpot_data *dpot, u8 reg, u16 value)
 static s32 dpot_write_i2c(struct dpot_data *dpot, u8 reg, u16 value)
 {
 {
 	/* Only write the instruction byte for certain commands */
 	/* Only write the instruction byte for certain commands */
-	unsigned ctrl = 0;
+	unsigned tmp = 0, ctrl = 0;
 
 
 	switch (dpot->uid) {
 	switch (dpot->uid) {
 	case DPOT_UID(AD5246_ID):
 	case DPOT_UID(AD5246_ID):
@@ -261,6 +276,37 @@ static s32 dpot_write_i2c(struct dpot_data *dpot, u8 reg, u16 value)
 			0 : DPOT_AD5291_RDAC_AB;
 			0 : DPOT_AD5291_RDAC_AB;
 		return dpot_write_r8d8(dpot, ctrl, value);
 		return dpot_write_r8d8(dpot, ctrl, value);
 		break;
 		break;
+	case DPOT_UID(AD5171_ID):
+	case DPOT_UID(AD5273_ID):
+		if (reg & DPOT_ADDR_OTP) {
+			tmp = dpot_read_d8(dpot);
+			if (tmp >> 6) /* Ready to Program? */
+				return -EFAULT;
+			ctrl = DPOT_AD5273_FUSE;
+		}
+		return dpot_write_r8d8(dpot, ctrl, value);
+		break;
+	case DPOT_UID(AD5172_ID):
+	case DPOT_UID(AD5173_ID):
+		ctrl = ((reg & DPOT_RDAC_MASK) == DPOT_RDAC0) ?
+			0 : DPOT_AD5272_3_A0;
+		if (reg & DPOT_ADDR_OTP) {
+			tmp = dpot_read_r8d16(dpot, ctrl);
+			if (tmp >> 14) /* Ready to Program? */
+				return -EFAULT;
+			ctrl |= DPOT_AD5270_2_3_FUSE;
+		}
+		return dpot_write_r8d8(dpot, ctrl, value);
+		break;
+	case DPOT_UID(AD5170_ID):
+		if (reg & DPOT_ADDR_OTP) {
+			tmp = dpot_read_r8d16(dpot, tmp);
+			if (tmp >> 14) /* Ready to Program? */
+				return -EFAULT;
+			ctrl = DPOT_AD5270_2_3_FUSE;
+		}
+		return dpot_write_r8d8(dpot, ctrl, value);
+		break;
 	default:
 	default:
 		if (reg & DPOT_ADDR_CMD)
 		if (reg & DPOT_ADDR_CMD)
 			return dpot_write_d8(dpot, reg);
 			return dpot_write_d8(dpot, reg);
@@ -292,6 +338,12 @@ static ssize_t sysfs_show_reg(struct device *dev,
 	struct dpot_data *data = dev_get_drvdata(dev);
 	struct dpot_data *data = dev_get_drvdata(dev);
 	s32 value;
 	s32 value;
 
 
+	if (reg & DPOT_ADDR_OTP_EN)
+		return sprintf(buf, "%s\n",
+			test_bit(DPOT_RDAC_MASK & reg, data->otp_en_mask) ?
+			"enabled" : "disabled");
+
+
 	mutex_lock(&data->update_lock);
 	mutex_lock(&data->update_lock);
 	value = dpot_read(data, reg);
 	value = dpot_read(data, reg);
 	mutex_unlock(&data->update_lock);
 	mutex_unlock(&data->update_lock);
@@ -320,6 +372,19 @@ static ssize_t sysfs_set_reg(struct device *dev,
 	unsigned long value;
 	unsigned long value;
 	int err;
 	int err;
 
 
+	if (reg & DPOT_ADDR_OTP_EN) {
+		if (!strncmp(buf, "enabled", sizeof("enabled")))
+			set_bit(DPOT_RDAC_MASK & reg, data->otp_en_mask);
+		else
+			clear_bit(DPOT_RDAC_MASK & reg, data->otp_en_mask);
+
+		return count;
+	}
+
+	if ((reg & DPOT_ADDR_OTP) &&
+		!test_bit(DPOT_RDAC_MASK & reg, data->otp_en_mask))
+		return -EPERM;
+
 	err = strict_strtoul(buf, 10, &value);
 	err = strict_strtoul(buf, 10, &value);
 	if (err)
 	if (err)
 		return err;
 		return err;
@@ -331,6 +396,8 @@ static ssize_t sysfs_set_reg(struct device *dev,
 	dpot_write(data, reg, value);
 	dpot_write(data, reg, value);
 	if (reg & DPOT_ADDR_EEPROM)
 	if (reg & DPOT_ADDR_EEPROM)
 		msleep(26);	/* Sleep while the EEPROM updates */
 		msleep(26);	/* Sleep while the EEPROM updates */
+	else if (reg & DPOT_ADDR_OTP)
+		msleep(400);	/* Sleep while the OTP updates */
 	mutex_unlock(&data->update_lock);
 	mutex_unlock(&data->update_lock);
 
 
 	return count;
 	return count;
@@ -378,26 +445,38 @@ static DEVICE_ATTR(name, S_IWUSR | S_IRUGO, show_##name, NULL);
 DPOT_DEVICE_SHOW_SET(rdac0, DPOT_ADDR_RDAC | DPOT_RDAC0);
 DPOT_DEVICE_SHOW_SET(rdac0, DPOT_ADDR_RDAC | DPOT_RDAC0);
 DPOT_DEVICE_SHOW_SET(eeprom0, DPOT_ADDR_EEPROM | DPOT_RDAC0);
 DPOT_DEVICE_SHOW_SET(eeprom0, DPOT_ADDR_EEPROM | DPOT_RDAC0);
 DPOT_DEVICE_SHOW_ONLY(tolerance0, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC0);
 DPOT_DEVICE_SHOW_ONLY(tolerance0, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC0);
+DPOT_DEVICE_SHOW_SET(otp0, DPOT_ADDR_OTP | DPOT_RDAC0);
+DPOT_DEVICE_SHOW_SET(otp0en, DPOT_ADDR_OTP_EN | DPOT_RDAC0);
 
 
 DPOT_DEVICE_SHOW_SET(rdac1, DPOT_ADDR_RDAC | DPOT_RDAC1);
 DPOT_DEVICE_SHOW_SET(rdac1, DPOT_ADDR_RDAC | DPOT_RDAC1);
 DPOT_DEVICE_SHOW_SET(eeprom1, DPOT_ADDR_EEPROM | DPOT_RDAC1);
 DPOT_DEVICE_SHOW_SET(eeprom1, DPOT_ADDR_EEPROM | DPOT_RDAC1);
 DPOT_DEVICE_SHOW_ONLY(tolerance1, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC1);
 DPOT_DEVICE_SHOW_ONLY(tolerance1, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC1);
+DPOT_DEVICE_SHOW_SET(otp1, DPOT_ADDR_OTP | DPOT_RDAC1);
+DPOT_DEVICE_SHOW_SET(otp1en, DPOT_ADDR_OTP_EN | DPOT_RDAC1);
 
 
 DPOT_DEVICE_SHOW_SET(rdac2, DPOT_ADDR_RDAC | DPOT_RDAC2);
 DPOT_DEVICE_SHOW_SET(rdac2, DPOT_ADDR_RDAC | DPOT_RDAC2);
 DPOT_DEVICE_SHOW_SET(eeprom2, DPOT_ADDR_EEPROM | DPOT_RDAC2);
 DPOT_DEVICE_SHOW_SET(eeprom2, DPOT_ADDR_EEPROM | DPOT_RDAC2);
 DPOT_DEVICE_SHOW_ONLY(tolerance2, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC2);
 DPOT_DEVICE_SHOW_ONLY(tolerance2, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC2);
+DPOT_DEVICE_SHOW_SET(otp2, DPOT_ADDR_OTP | DPOT_RDAC2);
+DPOT_DEVICE_SHOW_SET(otp2en, DPOT_ADDR_OTP_EN | DPOT_RDAC2);
 
 
 DPOT_DEVICE_SHOW_SET(rdac3, DPOT_ADDR_RDAC | DPOT_RDAC3);
 DPOT_DEVICE_SHOW_SET(rdac3, DPOT_ADDR_RDAC | DPOT_RDAC3);
 DPOT_DEVICE_SHOW_SET(eeprom3, DPOT_ADDR_EEPROM | DPOT_RDAC3);
 DPOT_DEVICE_SHOW_SET(eeprom3, DPOT_ADDR_EEPROM | DPOT_RDAC3);
 DPOT_DEVICE_SHOW_ONLY(tolerance3, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC3);
 DPOT_DEVICE_SHOW_ONLY(tolerance3, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC3);
+DPOT_DEVICE_SHOW_SET(otp3, DPOT_ADDR_OTP | DPOT_RDAC3);
+DPOT_DEVICE_SHOW_SET(otp3en, DPOT_ADDR_OTP_EN | DPOT_RDAC3);
 
 
 DPOT_DEVICE_SHOW_SET(rdac4, DPOT_ADDR_RDAC | DPOT_RDAC4);
 DPOT_DEVICE_SHOW_SET(rdac4, DPOT_ADDR_RDAC | DPOT_RDAC4);
 DPOT_DEVICE_SHOW_SET(eeprom4, DPOT_ADDR_EEPROM | DPOT_RDAC4);
 DPOT_DEVICE_SHOW_SET(eeprom4, DPOT_ADDR_EEPROM | DPOT_RDAC4);
 DPOT_DEVICE_SHOW_ONLY(tolerance4, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC4);
 DPOT_DEVICE_SHOW_ONLY(tolerance4, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC4);
+DPOT_DEVICE_SHOW_SET(otp4, DPOT_ADDR_OTP | DPOT_RDAC4);
+DPOT_DEVICE_SHOW_SET(otp4en, DPOT_ADDR_OTP_EN | DPOT_RDAC4);
 
 
 DPOT_DEVICE_SHOW_SET(rdac5, DPOT_ADDR_RDAC | DPOT_RDAC5);
 DPOT_DEVICE_SHOW_SET(rdac5, DPOT_ADDR_RDAC | DPOT_RDAC5);
 DPOT_DEVICE_SHOW_SET(eeprom5, DPOT_ADDR_EEPROM | DPOT_RDAC5);
 DPOT_DEVICE_SHOW_SET(eeprom5, DPOT_ADDR_EEPROM | DPOT_RDAC5);
 DPOT_DEVICE_SHOW_ONLY(tolerance5, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC5);
 DPOT_DEVICE_SHOW_ONLY(tolerance5, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC5);
+DPOT_DEVICE_SHOW_SET(otp5, DPOT_ADDR_OTP | DPOT_RDAC5);
+DPOT_DEVICE_SHOW_SET(otp5en, DPOT_ADDR_OTP_EN | DPOT_RDAC5);
 
 
 static const struct attribute *dpot_attrib_wipers[] = {
 static const struct attribute *dpot_attrib_wipers[] = {
 	&dev_attr_rdac0.attr,
 	&dev_attr_rdac0.attr,
@@ -419,6 +498,26 @@ static const struct attribute *dpot_attrib_eeprom[] = {
 	NULL
 	NULL
 };
 };
 
 
+static const struct attribute *dpot_attrib_otp[] = {
+	&dev_attr_otp0.attr,
+	&dev_attr_otp1.attr,
+	&dev_attr_otp2.attr,
+	&dev_attr_otp3.attr,
+	&dev_attr_otp4.attr,
+	&dev_attr_otp5.attr,
+	NULL
+};
+
+static const struct attribute *dpot_attrib_otp_en[] = {
+	&dev_attr_otp0en.attr,
+	&dev_attr_otp1en.attr,
+	&dev_attr_otp2en.attr,
+	&dev_attr_otp3en.attr,
+	&dev_attr_otp4en.attr,
+	&dev_attr_otp5en.attr,
+	NULL
+};
+
 static const struct attribute *dpot_attrib_tolerance[] = {
 static const struct attribute *dpot_attrib_tolerance[] = {
 	&dev_attr_tolerance0.attr,
 	&dev_attr_tolerance0.attr,
 	&dev_attr_tolerance1.attr,
 	&dev_attr_tolerance1.attr,
@@ -468,6 +567,12 @@ __devinit int ad_dpot_add_files(struct device *dev,
 	if (features & F_CMD_TOL)
 	if (features & F_CMD_TOL)
 		err |= sysfs_create_file(&dev->kobj,
 		err |= sysfs_create_file(&dev->kobj,
 			dpot_attrib_tolerance[rdac]);
 			dpot_attrib_tolerance[rdac]);
+	if (features & F_CMD_OTP) {
+		err |= sysfs_create_file(&dev->kobj,
+			dpot_attrib_otp_en[rdac]);
+		err |= sysfs_create_file(&dev->kobj,
+			dpot_attrib_otp[rdac]);
+	}
 
 
 	if (err)
 	if (err)
 		dev_err(dev, "failed to register sysfs hooks for RDAC%d\n",
 		dev_err(dev, "failed to register sysfs hooks for RDAC%d\n",
@@ -487,6 +592,12 @@ inline void ad_dpot_remove_files(struct device *dev,
 	if (features & F_CMD_TOL)
 	if (features & F_CMD_TOL)
 		sysfs_remove_file(&dev->kobj,
 		sysfs_remove_file(&dev->kobj,
 			dpot_attrib_tolerance[rdac]);
 			dpot_attrib_tolerance[rdac]);
+	if (features & F_CMD_OTP) {
+		sysfs_remove_file(&dev->kobj,
+			dpot_attrib_otp_en[rdac]);
+		sysfs_remove_file(&dev->kobj,
+			dpot_attrib_otp[rdac]);
+	}
 }
 }
 
 
 __devinit int ad_dpot_probe(struct device *dev,
 __devinit int ad_dpot_probe(struct device *dev,
@@ -514,7 +625,7 @@ __devinit int ad_dpot_probe(struct device *dev,
 	data->uid = DPOT_UID(data->devid);
 	data->uid = DPOT_UID(data->devid);
 	data->wipers = DPOT_WIPERS(data->devid);
 	data->wipers = DPOT_WIPERS(data->devid);
 
 
-	for (i = DPOT_RDAC0; i <= DPOT_RDAC5; i++)
+	for (i = DPOT_RDAC0; i < MAX_RDACS; i++)
 		if (data->wipers & (1 << i)) {
 		if (data->wipers & (1 << i)) {
 			err = ad_dpot_add_files(dev, data->feat, i);
 			err = ad_dpot_add_files(dev, data->feat, i);
 			if (err)
 			if (err)
@@ -538,7 +649,7 @@ __devinit int ad_dpot_probe(struct device *dev,
 	return 0;
 	return 0;
 
 
 exit_remove_files:
 exit_remove_files:
-	for (i = DPOT_RDAC0; i <= DPOT_RDAC5; i++)
+	for (i = DPOT_RDAC0; i < MAX_RDACS; i++)
 		if (data->wipers & (1 << i))
 		if (data->wipers & (1 << i))
 			ad_dpot_remove_files(dev, data->feat, i);
 			ad_dpot_remove_files(dev, data->feat, i);
 
 
@@ -557,7 +668,7 @@ __devexit int ad_dpot_remove(struct device *dev)
 	struct dpot_data *data = dev_get_drvdata(dev);
 	struct dpot_data *data = dev_get_drvdata(dev);
 	int i;
 	int i;
 
 
-	for (i = DPOT_RDAC0; i <= DPOT_RDAC5; i++)
+	for (i = DPOT_RDAC0; i < MAX_RDACS; i++)
 		if (data->wipers & (1 << i))
 		if (data->wipers & (1 << i))
 			ad_dpot_remove_files(dev, data->feat, i);
 			ad_dpot_remove_files(dev, data->feat, i);
 
 

+ 28 - 14
drivers/misc/ad525x_dpot.h

@@ -15,17 +15,18 @@
 		(((features) << 18) | (((wipers) & 0xFF) << 10) | \
 		(((features) << 18) | (((wipers) & 0xFF) << 10) | \
 		((max_pos & 0xF) << 6) | (uid & 0x3F))
 		((max_pos & 0xF) << 6) | (uid & 0x3F))
 
 
-#define DPOT_UID(conf) (conf & 0x3F)
-#define DPOT_MAX_POS(conf) ((conf >> 6) & 0xF)
-#define DPOT_WIPERS(conf) ((conf >> 10) & 0xFF)
-#define DPOT_FEAT(conf) (conf >> 18)
-
-#define BRDAC0	(1 << 0)
-#define BRDAC1	(1 << 1)
-#define BRDAC2	(1 << 2)
-#define BRDAC3	(1 << 3)
-#define BRDAC4	(1 << 4)
-#define BRDAC5	(1 << 5)
+#define DPOT_UID(conf)		(conf & 0x3F)
+#define DPOT_MAX_POS(conf)	((conf >> 6) & 0xF)
+#define DPOT_WIPERS(conf)	((conf >> 10) & 0xFF)
+#define DPOT_FEAT(conf)		(conf >> 18)
+
+#define BRDAC0			(1 << 0)
+#define BRDAC1			(1 << 1)
+#define BRDAC2			(1 << 2)
+#define BRDAC3			(1 << 3)
+#define BRDAC4			(1 << 4)
+#define BRDAC5			(1 << 5)
+#define MAX_RDACS		6
 
 
 #define F_CMD_INC		(1 << 0)	/* Features INC/DEC ALL, 6dB */
 #define F_CMD_INC		(1 << 0)	/* Features INC/DEC ALL, 6dB */
 #define F_CMD_EEP		(1 << 1)	/* Features EEPROM */
 #define F_CMD_EEP		(1 << 1)	/* Features EEPROM */
@@ -116,6 +117,11 @@ enum dpot_devid {
 	AD5282_ID = DPOT_CONF(F_RDACS_RW, BRDAC0 | BRDAC1, 8, 41),
 	AD5282_ID = DPOT_CONF(F_RDACS_RW, BRDAC0 | BRDAC1, 8, 41),
 	ADN2860_ID = DPOT_CONF(F_RDACS_RW_TOL | F_CMD_INC,
 	ADN2860_ID = DPOT_CONF(F_RDACS_RW_TOL | F_CMD_INC,
 			BRDAC0 | BRDAC1 | BRDAC2, 9, 42),
 			BRDAC0 | BRDAC1 | BRDAC2, 9, 42),
+	AD5273_ID = DPOT_CONF(F_RDACS_RW | F_CMD_OTP, BRDAC0, 6, 43),
+	AD5171_ID = DPOT_CONF(F_RDACS_RW | F_CMD_OTP, BRDAC0, 6, 44),
+	AD5170_ID = DPOT_CONF(F_RDACS_RW | F_CMD_OTP, BRDAC0, 8, 45),
+	AD5172_ID = DPOT_CONF(F_RDACS_RW | F_CMD_OTP, BRDAC0 | BRDAC1, 8, 46),
+	AD5173_ID = DPOT_CONF(F_RDACS_RW | F_CMD_OTP, BRDAC0 | BRDAC1, 8, 47),
 };
 };
 
 
 #define DPOT_RDAC0		0
 #define DPOT_RDAC0		0
@@ -136,9 +142,11 @@ enum dpot_devid {
 #define DPOT_TOL_RDAC5		(DPOT_REG_TOL | DPOT_RDAC5)
 #define DPOT_TOL_RDAC5		(DPOT_REG_TOL | DPOT_RDAC5)
 
 
 /* RDAC-to-EEPROM Interface Commands */
 /* RDAC-to-EEPROM Interface Commands */
-#define DPOT_ADDR_RDAC		(0x00 << 5)
-#define DPOT_ADDR_EEPROM	(0x01 << 5)
-#define DPOT_ADDR_CMD		(0x80)
+#define DPOT_ADDR_RDAC		(0x0 << 5)
+#define DPOT_ADDR_EEPROM	(0x1 << 5)
+#define DPOT_ADDR_OTP		(0x1 << 6)
+#define DPOT_ADDR_CMD		(0x1 << 7)
+#define DPOT_ADDR_OTP_EN	(0x1 << 9)
 
 
 #define DPOT_DEC_ALL_6DB	(DPOT_ADDR_CMD | (0x4 << 3))
 #define DPOT_DEC_ALL_6DB	(DPOT_ADDR_CMD | (0x4 << 3))
 #define DPOT_INC_ALL_6DB	(DPOT_ADDR_CMD | (0x9 << 3))
 #define DPOT_INC_ALL_6DB	(DPOT_ADDR_CMD | (0x9 << 3))
@@ -161,6 +169,12 @@ enum dpot_devid {
 /* AD524x use special commands */
 /* AD524x use special commands */
 #define DPOT_AD5291_RDAC_AB	0x80
 #define DPOT_AD5291_RDAC_AB	0x80
 
 
+#define DPOT_AD5273_FUSE	0x80
+#define DPOT_AD5270_2_3_FUSE	0x20
+#define DPOT_AD5270_2_3_OW	0x08
+#define DPOT_AD5272_3_A0	0x08
+#define DPOT_AD5270_2FUSE	0x80
+
 struct dpot_data;
 struct dpot_data;
 
 
 struct ad_dpot_bus_ops {
 struct ad_dpot_bus_ops {