|
@@ -29,9 +29,9 @@
|
|
|
* AD5262 2 256 20, 50, 200
|
|
|
* AD5263 4 256 20, 50, 200
|
|
|
* AD5290 1 256 10, 50, 100
|
|
|
- * AD5291 1 256 20
|
|
|
- * AD5292 1 1024 20
|
|
|
- * AD5293 1 1024 20
|
|
|
+ * AD5291 1 256 20, 50, 100 (20-TP)
|
|
|
+ * AD5292 1 1024 20, 50, 100 (20-TP)
|
|
|
+ * AD5293 1 1024 20, 50, 100
|
|
|
* AD7376 1 128 10, 50, 100, 1M
|
|
|
* AD8400 1 256 1, 10, 50, 100
|
|
|
* AD8402 2 256 1, 10, 50, 100
|
|
@@ -52,6 +52,10 @@
|
|
|
* 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)
|
|
|
+ * AD5270 1 1024 20, 50, 100 (50-TP)
|
|
|
+ * AD5271 1 256 20, 50, 100 (50-TP)
|
|
|
+ * AD5272 1 1024 20, 50, 100 (50-TP)
|
|
|
+ * AD5274 1 256 20, 50, 100 (50-TP)
|
|
|
*
|
|
|
* See Documentation/misc-devices/ad525x_dpot.txt for more info.
|
|
|
*
|
|
@@ -126,18 +130,38 @@ static inline int dpot_write_r8d16(struct dpot_data *dpot, u8 reg, u16 val)
|
|
|
static s32 dpot_read_spi(struct dpot_data *dpot, u8 reg)
|
|
|
{
|
|
|
unsigned ctrl = 0;
|
|
|
+ int value;
|
|
|
|
|
|
if (!(reg & (DPOT_ADDR_EEPROM | DPOT_ADDR_CMD))) {
|
|
|
|
|
|
if (dpot->feat & F_RDACS_WONLY)
|
|
|
return dpot->rdac_cache[reg & DPOT_RDAC_MASK];
|
|
|
-
|
|
|
if (dpot->uid == DPOT_UID(AD5291_ID) ||
|
|
|
dpot->uid == DPOT_UID(AD5292_ID) ||
|
|
|
- dpot->uid == DPOT_UID(AD5293_ID))
|
|
|
- return dpot_read_r8d8(dpot,
|
|
|
+ dpot->uid == DPOT_UID(AD5293_ID)) {
|
|
|
+
|
|
|
+ value = dpot_read_r8d8(dpot,
|
|
|
DPOT_AD5291_READ_RDAC << 2);
|
|
|
|
|
|
+ if (dpot->uid == DPOT_UID(AD5291_ID))
|
|
|
+ value = value >> 2;
|
|
|
+
|
|
|
+ return value;
|
|
|
+ } else if (dpot->uid == DPOT_UID(AD5270_ID) ||
|
|
|
+ dpot->uid == DPOT_UID(AD5271_ID)) {
|
|
|
+
|
|
|
+ value = dpot_read_r8d8(dpot,
|
|
|
+ DPOT_AD5270_1_2_4_READ_RDAC << 2);
|
|
|
+
|
|
|
+ if (value < 0)
|
|
|
+ return value;
|
|
|
+
|
|
|
+ if (dpot->uid == DPOT_UID(AD5271_ID))
|
|
|
+ value = value >> 2;
|
|
|
+
|
|
|
+ return value;
|
|
|
+ }
|
|
|
+
|
|
|
ctrl = DPOT_SPI_READ_RDAC;
|
|
|
} else if (reg & DPOT_ADDR_EEPROM) {
|
|
|
ctrl = DPOT_SPI_READ_EEPROM;
|
|
@@ -153,6 +177,7 @@ static s32 dpot_read_spi(struct dpot_data *dpot, u8 reg)
|
|
|
|
|
|
static s32 dpot_read_i2c(struct dpot_data *dpot, u8 reg)
|
|
|
{
|
|
|
+ int value;
|
|
|
unsigned ctrl = 0;
|
|
|
switch (dpot->uid) {
|
|
|
case DPOT_UID(AD5246_ID):
|
|
@@ -177,6 +202,25 @@ static s32 dpot_read_i2c(struct dpot_data *dpot, u8 reg)
|
|
|
ctrl = ((reg & DPOT_RDAC_MASK) == DPOT_RDAC0) ?
|
|
|
0 : DPOT_AD5172_3_A0;
|
|
|
return dpot_read_r8d8(dpot, ctrl);
|
|
|
+ case DPOT_UID(AD5272_ID):
|
|
|
+ case DPOT_UID(AD5274_ID):
|
|
|
+ dpot_write_r8d8(dpot,
|
|
|
+ (DPOT_AD5270_1_2_4_READ_RDAC << 2), 0);
|
|
|
+
|
|
|
+ value = dpot_read_r8d16(dpot,
|
|
|
+ DPOT_AD5270_1_2_4_RDAC << 2);
|
|
|
+
|
|
|
+ if (value < 0)
|
|
|
+ return value;
|
|
|
+ /*
|
|
|
+ * AD5272/AD5274 returns high byte first, however
|
|
|
+ * underling smbus expects low byte first.
|
|
|
+ */
|
|
|
+ value = swab16(value);
|
|
|
+
|
|
|
+ if (dpot->uid == DPOT_UID(AD5271_ID))
|
|
|
+ value = value >> 2;
|
|
|
+ return value;
|
|
|
default:
|
|
|
if ((reg & DPOT_REG_TOL) || (dpot->max_pos > 256))
|
|
|
return dpot_read_r8d16(dpot, (reg & 0xF8) |
|
|
@@ -198,7 +242,7 @@ static s32 dpot_write_spi(struct dpot_data *dpot, u8 reg, u16 value)
|
|
|
{
|
|
|
unsigned val = 0;
|
|
|
|
|
|
- if (!(reg & (DPOT_ADDR_EEPROM | DPOT_ADDR_CMD))) {
|
|
|
+ if (!(reg & (DPOT_ADDR_EEPROM | DPOT_ADDR_CMD | DPOT_ADDR_OTP))) {
|
|
|
if (dpot->feat & F_RDACS_WONLY)
|
|
|
dpot->rdac_cache[reg & DPOT_RDAC_MASK] = value;
|
|
|
|
|
@@ -219,11 +263,30 @@ static s32 dpot_write_spi(struct dpot_data *dpot, u8 reg, u16 value)
|
|
|
} else {
|
|
|
if (dpot->uid == DPOT_UID(AD5291_ID) ||
|
|
|
dpot->uid == DPOT_UID(AD5292_ID) ||
|
|
|
- dpot->uid == DPOT_UID(AD5293_ID))
|
|
|
+ dpot->uid == DPOT_UID(AD5293_ID)) {
|
|
|
+
|
|
|
+ dpot_write_r8d8(dpot, DPOT_AD5291_CTRLREG << 2,
|
|
|
+ DPOT_AD5291_UNLOCK_CMD);
|
|
|
+
|
|
|
+ if (dpot->uid == DPOT_UID(AD5291_ID))
|
|
|
+ value = value << 2;
|
|
|
+
|
|
|
return dpot_write_r8d8(dpot,
|
|
|
(DPOT_AD5291_RDAC << 2) |
|
|
|
(value >> 8), value & 0xFF);
|
|
|
+ } else if (dpot->uid == DPOT_UID(AD5270_ID) ||
|
|
|
+ dpot->uid == DPOT_UID(AD5271_ID)) {
|
|
|
+ dpot_write_r8d8(dpot,
|
|
|
+ DPOT_AD5270_1_2_4_CTRLREG << 2,
|
|
|
+ DPOT_AD5270_1_2_4_UNLOCK_CMD);
|
|
|
+
|
|
|
+ if (dpot->uid == DPOT_UID(AD5271_ID))
|
|
|
+ value = value << 2;
|
|
|
|
|
|
+ return dpot_write_r8d8(dpot,
|
|
|
+ (DPOT_AD5270_1_2_4_RDAC << 2) |
|
|
|
+ (value >> 8), value & 0xFF);
|
|
|
+ }
|
|
|
val = DPOT_SPI_RDAC | (reg & DPOT_RDAC_MASK);
|
|
|
}
|
|
|
} else if (reg & DPOT_ADDR_EEPROM) {
|
|
@@ -243,6 +306,16 @@ static s32 dpot_write_spi(struct dpot_data *dpot, u8 reg, u16 value)
|
|
|
val = DPOT_SPI_INC_ALL;
|
|
|
break;
|
|
|
}
|
|
|
+ } else if (reg & DPOT_ADDR_OTP) {
|
|
|
+ if (dpot->uid == DPOT_UID(AD5291_ID) ||
|
|
|
+ dpot->uid == DPOT_UID(AD5292_ID)) {
|
|
|
+ return dpot_write_r8d8(dpot,
|
|
|
+ DPOT_AD5291_STORE_XTPM << 2, 0);
|
|
|
+ } else if (dpot->uid == DPOT_UID(AD5270_ID) ||
|
|
|
+ dpot->uid == DPOT_UID(AD5271_ID)) {
|
|
|
+ return dpot_write_r8d8(dpot,
|
|
|
+ DPOT_AD5270_1_2_4_STORE_XTPM << 2, 0);
|
|
|
+ }
|
|
|
} else
|
|
|
BUG();
|
|
|
|
|
@@ -303,10 +376,25 @@ static s32 dpot_write_i2c(struct dpot_data *dpot, u8 reg, u16 value)
|
|
|
tmp = dpot_read_r8d16(dpot, tmp);
|
|
|
if (tmp >> 14) /* Ready to Program? */
|
|
|
return -EFAULT;
|
|
|
- ctrl = DPOT_AD5270_2_3_FUSE;
|
|
|
+ ctrl = DPOT_AD5170_2_3_FUSE;
|
|
|
}
|
|
|
return dpot_write_r8d8(dpot, ctrl, value);
|
|
|
break;
|
|
|
+ case DPOT_UID(AD5272_ID):
|
|
|
+ case DPOT_UID(AD5274_ID):
|
|
|
+ dpot_write_r8d8(dpot, DPOT_AD5270_1_2_4_CTRLREG << 2,
|
|
|
+ DPOT_AD5270_1_2_4_UNLOCK_CMD);
|
|
|
+
|
|
|
+ if (reg & DPOT_ADDR_OTP)
|
|
|
+ return dpot_write_r8d8(dpot,
|
|
|
+ DPOT_AD5270_1_2_4_STORE_XTPM << 2, 0);
|
|
|
+
|
|
|
+ if (dpot->uid == DPOT_UID(AD5274_ID))
|
|
|
+ value = value << 2;
|
|
|
+
|
|
|
+ return dpot_write_r8d8(dpot, (DPOT_AD5270_1_2_4_RDAC << 2) |
|
|
|
+ (value >> 8), value & 0xFF);
|
|
|
+ break;
|
|
|
default:
|
|
|
if (reg & DPOT_ADDR_CMD)
|
|
|
return dpot_write_d8(dpot, reg);
|
|
@@ -320,7 +408,6 @@ static s32 dpot_write_i2c(struct dpot_data *dpot, u8 reg, u16 value)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
static s32 dpot_write(struct dpot_data *dpot, u8 reg, u16 value)
|
|
|
{
|
|
|
if (dpot->feat & F_SPI)
|