diff options
-rw-r--r-- | drivers/misc/Kconfig | 3 | ||||
-rw-r--r-- | drivers/misc/ad525x_dpot-i2c.c | 2 | ||||
-rw-r--r-- | drivers/misc/ad525x_dpot-spi.c | 2 | ||||
-rw-r--r-- | drivers/misc/ad525x_dpot.c | 107 | ||||
-rw-r--r-- | drivers/misc/ad525x_dpot.h | 23 |
5 files changed, 123 insertions, 14 deletions
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 1f69743b12ec..3d57adfc8703 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig | |||
@@ -24,7 +24,8 @@ config AD525X_DPOT | |||
24 | AD5260, AD5262, AD5263, AD5290, AD5291, AD5292, AD5293, | 24 | AD5260, AD5262, AD5263, AD5290, AD5291, AD5292, AD5293, |
25 | AD7376, AD8400, AD8402, AD8403, ADN2850, AD5241, AD5242, | 25 | AD7376, AD8400, AD8402, AD8403, ADN2850, AD5241, AD5242, |
26 | AD5243, AD5245, AD5246, AD5247, AD5248, AD5280, AD5282, | 26 | AD5243, AD5245, AD5246, AD5247, AD5248, AD5280, AD5282, |
27 | ADN2860, AD5273, AD5171, AD5170, AD5172, AD5173 | 27 | ADN2860, AD5273, AD5171, AD5170, AD5172, AD5173, AD5270, |
28 | AD5271, AD5272, AD5274 | ||
28 | digital potentiometer chips. | 29 | digital potentiometer chips. |
29 | 30 | ||
30 | See Documentation/misc-devices/ad525x_dpot.txt for the | 31 | See Documentation/misc-devices/ad525x_dpot.txt for the |
diff --git a/drivers/misc/ad525x_dpot-i2c.c b/drivers/misc/ad525x_dpot-i2c.c index 374352af7979..4ff73c215746 100644 --- a/drivers/misc/ad525x_dpot-i2c.c +++ b/drivers/misc/ad525x_dpot-i2c.c | |||
@@ -102,6 +102,8 @@ static const struct i2c_device_id ad_dpot_id[] = { | |||
102 | {"ad5170", AD5170_ID}, | 102 | {"ad5170", AD5170_ID}, |
103 | {"ad5172", AD5172_ID}, | 103 | {"ad5172", AD5172_ID}, |
104 | {"ad5173", AD5173_ID}, | 104 | {"ad5173", AD5173_ID}, |
105 | {"ad5272", AD5272_ID}, | ||
106 | {"ad5274", AD5274_ID}, | ||
105 | {} | 107 | {} |
106 | }; | 108 | }; |
107 | MODULE_DEVICE_TABLE(i2c, ad_dpot_id); | 109 | MODULE_DEVICE_TABLE(i2c, ad_dpot_id); |
diff --git a/drivers/misc/ad525x_dpot-spi.c b/drivers/misc/ad525x_dpot-spi.c index 6cfcb636577a..7f9a55afe05d 100644 --- a/drivers/misc/ad525x_dpot-spi.c +++ b/drivers/misc/ad525x_dpot-spi.c | |||
@@ -38,6 +38,8 @@ static const struct ad_dpot_id ad_dpot_spi_devlist[] = { | |||
38 | {.name = "ad8402", .devid = AD8402_ID}, | 38 | {.name = "ad8402", .devid = AD8402_ID}, |
39 | {.name = "ad8403", .devid = AD8403_ID}, | 39 | {.name = "ad8403", .devid = AD8403_ID}, |
40 | {.name = "adn2850", .devid = ADN2850_ID}, | 40 | {.name = "adn2850", .devid = ADN2850_ID}, |
41 | {.name = "ad5270", .devid = AD5270_ID}, | ||
42 | {.name = "ad5271", .devid = AD5271_ID}, | ||
41 | {} | 43 | {} |
42 | }; | 44 | }; |
43 | 45 | ||
diff --git a/drivers/misc/ad525x_dpot.c b/drivers/misc/ad525x_dpot.c index 9698c7546911..7cb911028d09 100644 --- a/drivers/misc/ad525x_dpot.c +++ b/drivers/misc/ad525x_dpot.c | |||
@@ -29,9 +29,9 @@ | |||
29 | * AD5262 2 256 20, 50, 200 | 29 | * AD5262 2 256 20, 50, 200 |
30 | * AD5263 4 256 20, 50, 200 | 30 | * AD5263 4 256 20, 50, 200 |
31 | * AD5290 1 256 10, 50, 100 | 31 | * AD5290 1 256 10, 50, 100 |
32 | * AD5291 1 256 20 | 32 | * AD5291 1 256 20, 50, 100 (20-TP) |
33 | * AD5292 1 1024 20 | 33 | * AD5292 1 1024 20, 50, 100 (20-TP) |
34 | * AD5293 1 1024 20 | 34 | * AD5293 1 1024 20, 50, 100 |
35 | * AD7376 1 128 10, 50, 100, 1M | 35 | * AD7376 1 128 10, 50, 100, 1M |
36 | * AD8400 1 256 1, 10, 50, 100 | 36 | * AD8400 1 256 1, 10, 50, 100 |
37 | * AD8402 2 256 1, 10, 50, 100 | 37 | * AD8402 2 256 1, 10, 50, 100 |
@@ -52,6 +52,10 @@ | |||
52 | * AD5170 1 256 2.5, 10, 50, 100 (OTP) | 52 | * AD5170 1 256 2.5, 10, 50, 100 (OTP) |
53 | * AD5172 2 256 2.5, 10, 50, 100 (OTP) | 53 | * AD5172 2 256 2.5, 10, 50, 100 (OTP) |
54 | * AD5173 2 256 2.5, 10, 50, 100 (OTP) | 54 | * AD5173 2 256 2.5, 10, 50, 100 (OTP) |
55 | * AD5270 1 1024 20, 50, 100 (50-TP) | ||
56 | * AD5271 1 256 20, 50, 100 (50-TP) | ||
57 | * AD5272 1 1024 20, 50, 100 (50-TP) | ||
58 | * AD5274 1 256 20, 50, 100 (50-TP) | ||
55 | * | 59 | * |
56 | * See Documentation/misc-devices/ad525x_dpot.txt for more info. | 60 | * See Documentation/misc-devices/ad525x_dpot.txt for more info. |
57 | * | 61 | * |
@@ -126,18 +130,38 @@ static inline int dpot_write_r8d16(struct dpot_data *dpot, u8 reg, u16 val) | |||
126 | static s32 dpot_read_spi(struct dpot_data *dpot, u8 reg) | 130 | static s32 dpot_read_spi(struct dpot_data *dpot, u8 reg) |
127 | { | 131 | { |
128 | unsigned ctrl = 0; | 132 | unsigned ctrl = 0; |
133 | int value; | ||
129 | 134 | ||
130 | if (!(reg & (DPOT_ADDR_EEPROM | DPOT_ADDR_CMD))) { | 135 | if (!(reg & (DPOT_ADDR_EEPROM | DPOT_ADDR_CMD))) { |
131 | 136 | ||
132 | if (dpot->feat & F_RDACS_WONLY) | 137 | if (dpot->feat & F_RDACS_WONLY) |
133 | return dpot->rdac_cache[reg & DPOT_RDAC_MASK]; | 138 | return dpot->rdac_cache[reg & DPOT_RDAC_MASK]; |
134 | |||
135 | if (dpot->uid == DPOT_UID(AD5291_ID) || | 139 | if (dpot->uid == DPOT_UID(AD5291_ID) || |
136 | dpot->uid == DPOT_UID(AD5292_ID) || | 140 | dpot->uid == DPOT_UID(AD5292_ID) || |
137 | dpot->uid == DPOT_UID(AD5293_ID)) | 141 | dpot->uid == DPOT_UID(AD5293_ID)) { |
138 | return dpot_read_r8d8(dpot, | 142 | |
143 | value = dpot_read_r8d8(dpot, | ||
139 | DPOT_AD5291_READ_RDAC << 2); | 144 | DPOT_AD5291_READ_RDAC << 2); |
140 | 145 | ||
146 | if (dpot->uid == DPOT_UID(AD5291_ID)) | ||
147 | value = value >> 2; | ||
148 | |||
149 | return value; | ||
150 | } else if (dpot->uid == DPOT_UID(AD5270_ID) || | ||
151 | dpot->uid == DPOT_UID(AD5271_ID)) { | ||
152 | |||
153 | value = dpot_read_r8d8(dpot, | ||
154 | DPOT_AD5270_1_2_4_READ_RDAC << 2); | ||
155 | |||
156 | if (value < 0) | ||
157 | return value; | ||
158 | |||
159 | if (dpot->uid == DPOT_UID(AD5271_ID)) | ||
160 | value = value >> 2; | ||
161 | |||
162 | return value; | ||
163 | } | ||
164 | |||
141 | ctrl = DPOT_SPI_READ_RDAC; | 165 | ctrl = DPOT_SPI_READ_RDAC; |
142 | } else if (reg & DPOT_ADDR_EEPROM) { | 166 | } else if (reg & DPOT_ADDR_EEPROM) { |
143 | ctrl = DPOT_SPI_READ_EEPROM; | 167 | ctrl = DPOT_SPI_READ_EEPROM; |
@@ -153,6 +177,7 @@ static s32 dpot_read_spi(struct dpot_data *dpot, u8 reg) | |||
153 | 177 | ||
154 | static s32 dpot_read_i2c(struct dpot_data *dpot, u8 reg) | 178 | static s32 dpot_read_i2c(struct dpot_data *dpot, u8 reg) |
155 | { | 179 | { |
180 | int value; | ||
156 | unsigned ctrl = 0; | 181 | unsigned ctrl = 0; |
157 | switch (dpot->uid) { | 182 | switch (dpot->uid) { |
158 | case DPOT_UID(AD5246_ID): | 183 | case DPOT_UID(AD5246_ID): |
@@ -177,6 +202,25 @@ static s32 dpot_read_i2c(struct dpot_data *dpot, u8 reg) | |||
177 | ctrl = ((reg & DPOT_RDAC_MASK) == DPOT_RDAC0) ? | 202 | ctrl = ((reg & DPOT_RDAC_MASK) == DPOT_RDAC0) ? |
178 | 0 : DPOT_AD5172_3_A0; | 203 | 0 : DPOT_AD5172_3_A0; |
179 | return dpot_read_r8d8(dpot, ctrl); | 204 | return dpot_read_r8d8(dpot, ctrl); |
205 | case DPOT_UID(AD5272_ID): | ||
206 | case DPOT_UID(AD5274_ID): | ||
207 | dpot_write_r8d8(dpot, | ||
208 | (DPOT_AD5270_1_2_4_READ_RDAC << 2), 0); | ||
209 | |||
210 | value = dpot_read_r8d16(dpot, | ||
211 | DPOT_AD5270_1_2_4_RDAC << 2); | ||
212 | |||
213 | if (value < 0) | ||
214 | return value; | ||
215 | /* | ||
216 | * AD5272/AD5274 returns high byte first, however | ||
217 | * underling smbus expects low byte first. | ||
218 | */ | ||
219 | value = swab16(value); | ||
220 | |||
221 | if (dpot->uid == DPOT_UID(AD5271_ID)) | ||
222 | value = value >> 2; | ||
223 | return value; | ||
180 | default: | 224 | default: |
181 | if ((reg & DPOT_REG_TOL) || (dpot->max_pos > 256)) | 225 | if ((reg & DPOT_REG_TOL) || (dpot->max_pos > 256)) |
182 | return dpot_read_r8d16(dpot, (reg & 0xF8) | | 226 | return dpot_read_r8d16(dpot, (reg & 0xF8) | |
@@ -198,7 +242,7 @@ static s32 dpot_write_spi(struct dpot_data *dpot, u8 reg, u16 value) | |||
198 | { | 242 | { |
199 | unsigned val = 0; | 243 | unsigned val = 0; |
200 | 244 | ||
201 | if (!(reg & (DPOT_ADDR_EEPROM | DPOT_ADDR_CMD))) { | 245 | if (!(reg & (DPOT_ADDR_EEPROM | DPOT_ADDR_CMD | DPOT_ADDR_OTP))) { |
202 | if (dpot->feat & F_RDACS_WONLY) | 246 | if (dpot->feat & F_RDACS_WONLY) |
203 | dpot->rdac_cache[reg & DPOT_RDAC_MASK] = value; | 247 | dpot->rdac_cache[reg & DPOT_RDAC_MASK] = value; |
204 | 248 | ||
@@ -219,11 +263,30 @@ static s32 dpot_write_spi(struct dpot_data *dpot, u8 reg, u16 value) | |||
219 | } else { | 263 | } else { |
220 | if (dpot->uid == DPOT_UID(AD5291_ID) || | 264 | if (dpot->uid == DPOT_UID(AD5291_ID) || |
221 | dpot->uid == DPOT_UID(AD5292_ID) || | 265 | dpot->uid == DPOT_UID(AD5292_ID) || |
222 | dpot->uid == DPOT_UID(AD5293_ID)) | 266 | dpot->uid == DPOT_UID(AD5293_ID)) { |
267 | |||
268 | dpot_write_r8d8(dpot, DPOT_AD5291_CTRLREG << 2, | ||
269 | DPOT_AD5291_UNLOCK_CMD); | ||
270 | |||
271 | if (dpot->uid == DPOT_UID(AD5291_ID)) | ||
272 | value = value << 2; | ||
273 | |||
223 | return dpot_write_r8d8(dpot, | 274 | return dpot_write_r8d8(dpot, |
224 | (DPOT_AD5291_RDAC << 2) | | 275 | (DPOT_AD5291_RDAC << 2) | |
225 | (value >> 8), value & 0xFF); | 276 | (value >> 8), value & 0xFF); |
277 | } else if (dpot->uid == DPOT_UID(AD5270_ID) || | ||
278 | dpot->uid == DPOT_UID(AD5271_ID)) { | ||
279 | dpot_write_r8d8(dpot, | ||
280 | DPOT_AD5270_1_2_4_CTRLREG << 2, | ||
281 | DPOT_AD5270_1_2_4_UNLOCK_CMD); | ||
282 | |||
283 | if (dpot->uid == DPOT_UID(AD5271_ID)) | ||
284 | value = value << 2; | ||
226 | 285 | ||
286 | return dpot_write_r8d8(dpot, | ||
287 | (DPOT_AD5270_1_2_4_RDAC << 2) | | ||
288 | (value >> 8), value & 0xFF); | ||
289 | } | ||
227 | val = DPOT_SPI_RDAC | (reg & DPOT_RDAC_MASK); | 290 | val = DPOT_SPI_RDAC | (reg & DPOT_RDAC_MASK); |
228 | } | 291 | } |
229 | } else if (reg & DPOT_ADDR_EEPROM) { | 292 | } else if (reg & DPOT_ADDR_EEPROM) { |
@@ -243,6 +306,16 @@ static s32 dpot_write_spi(struct dpot_data *dpot, u8 reg, u16 value) | |||
243 | val = DPOT_SPI_INC_ALL; | 306 | val = DPOT_SPI_INC_ALL; |
244 | break; | 307 | break; |
245 | } | 308 | } |
309 | } else if (reg & DPOT_ADDR_OTP) { | ||
310 | if (dpot->uid == DPOT_UID(AD5291_ID) || | ||
311 | dpot->uid == DPOT_UID(AD5292_ID)) { | ||
312 | return dpot_write_r8d8(dpot, | ||
313 | DPOT_AD5291_STORE_XTPM << 2, 0); | ||
314 | } else if (dpot->uid == DPOT_UID(AD5270_ID) || | ||
315 | dpot->uid == DPOT_UID(AD5271_ID)) { | ||
316 | return dpot_write_r8d8(dpot, | ||
317 | DPOT_AD5270_1_2_4_STORE_XTPM << 2, 0); | ||
318 | } | ||
246 | } else | 319 | } else |
247 | BUG(); | 320 | BUG(); |
248 | 321 | ||
@@ -303,10 +376,25 @@ static s32 dpot_write_i2c(struct dpot_data *dpot, u8 reg, u16 value) | |||
303 | tmp = dpot_read_r8d16(dpot, tmp); | 376 | tmp = dpot_read_r8d16(dpot, tmp); |
304 | if (tmp >> 14) /* Ready to Program? */ | 377 | if (tmp >> 14) /* Ready to Program? */ |
305 | return -EFAULT; | 378 | return -EFAULT; |
306 | ctrl = DPOT_AD5270_2_3_FUSE; | 379 | ctrl = DPOT_AD5170_2_3_FUSE; |
307 | } | 380 | } |
308 | return dpot_write_r8d8(dpot, ctrl, value); | 381 | return dpot_write_r8d8(dpot, ctrl, value); |
309 | break; | 382 | break; |
383 | case DPOT_UID(AD5272_ID): | ||
384 | case DPOT_UID(AD5274_ID): | ||
385 | dpot_write_r8d8(dpot, DPOT_AD5270_1_2_4_CTRLREG << 2, | ||
386 | DPOT_AD5270_1_2_4_UNLOCK_CMD); | ||
387 | |||
388 | if (reg & DPOT_ADDR_OTP) | ||
389 | return dpot_write_r8d8(dpot, | ||
390 | DPOT_AD5270_1_2_4_STORE_XTPM << 2, 0); | ||
391 | |||
392 | if (dpot->uid == DPOT_UID(AD5274_ID)) | ||
393 | value = value << 2; | ||
394 | |||
395 | return dpot_write_r8d8(dpot, (DPOT_AD5270_1_2_4_RDAC << 2) | | ||
396 | (value >> 8), value & 0xFF); | ||
397 | break; | ||
310 | default: | 398 | default: |
311 | if (reg & DPOT_ADDR_CMD) | 399 | if (reg & DPOT_ADDR_CMD) |
312 | return dpot_write_d8(dpot, reg); | 400 | return dpot_write_d8(dpot, reg); |
@@ -320,7 +408,6 @@ static s32 dpot_write_i2c(struct dpot_data *dpot, u8 reg, u16 value) | |||
320 | } | 408 | } |
321 | } | 409 | } |
322 | 410 | ||
323 | |||
324 | static s32 dpot_write(struct dpot_data *dpot, u8 reg, u16 value) | 411 | static s32 dpot_write(struct dpot_data *dpot, u8 reg, u16 value) |
325 | { | 412 | { |
326 | if (dpot->feat & F_SPI) | 413 | if (dpot->feat & F_SPI) |
diff --git a/drivers/misc/ad525x_dpot.h b/drivers/misc/ad525x_dpot.h index 7609d49efd31..3b9e355489ae 100644 --- a/drivers/misc/ad525x_dpot.h +++ b/drivers/misc/ad525x_dpot.h | |||
@@ -93,8 +93,10 @@ enum dpot_devid { | |||
93 | BRDAC0 | BRDAC1 | BRDAC2 | BRDAC3, 8, 23), | 93 | BRDAC0 | BRDAC1 | BRDAC2 | BRDAC3, 8, 23), |
94 | AD5290_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_8BIT, | 94 | AD5290_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_8BIT, |
95 | BRDAC0, 8, 24), | 95 | BRDAC0, 8, 24), |
96 | AD5291_ID = DPOT_CONF(F_RDACS_RW | F_SPI_16BIT, BRDAC0, 8, 25), | 96 | AD5291_ID = DPOT_CONF(F_RDACS_RW | F_SPI_16BIT | F_CMD_OTP, |
97 | AD5292_ID = DPOT_CONF(F_RDACS_RW | F_SPI_16BIT, BRDAC0, 10, 26), | 97 | BRDAC0, 8, 25), |
98 | AD5292_ID = DPOT_CONF(F_RDACS_RW | F_SPI_16BIT | F_CMD_OTP, | ||
99 | BRDAC0, 10, 26), | ||
98 | AD5293_ID = DPOT_CONF(F_RDACS_RW | F_SPI_16BIT, BRDAC0, 10, 27), | 100 | AD5293_ID = DPOT_CONF(F_RDACS_RW | F_SPI_16BIT, BRDAC0, 10, 27), |
99 | AD7376_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_8BIT, | 101 | AD7376_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_8BIT, |
100 | BRDAC0, 7, 28), | 102 | BRDAC0, 7, 28), |
@@ -122,6 +124,12 @@ enum dpot_devid { | |||
122 | AD5170_ID = DPOT_CONF(F_RDACS_RW | F_CMD_OTP, BRDAC0, 8, 45), | 124 | AD5170_ID = DPOT_CONF(F_RDACS_RW | F_CMD_OTP, BRDAC0, 8, 45), |
123 | AD5172_ID = DPOT_CONF(F_RDACS_RW | F_CMD_OTP, BRDAC0 | BRDAC1, 8, 46), | 125 | AD5172_ID = DPOT_CONF(F_RDACS_RW | F_CMD_OTP, BRDAC0 | BRDAC1, 8, 46), |
124 | AD5173_ID = DPOT_CONF(F_RDACS_RW | F_CMD_OTP, BRDAC0 | BRDAC1, 8, 47), | 126 | AD5173_ID = DPOT_CONF(F_RDACS_RW | F_CMD_OTP, BRDAC0 | BRDAC1, 8, 47), |
127 | AD5270_ID = DPOT_CONF(F_RDACS_RW | F_CMD_OTP | F_SPI_16BIT, | ||
128 | BRDAC0, 10, 48), | ||
129 | AD5271_ID = DPOT_CONF(F_RDACS_RW | F_CMD_OTP | F_SPI_16BIT, | ||
130 | BRDAC0, 8, 49), | ||
131 | AD5272_ID = DPOT_CONF(F_RDACS_RW | F_CMD_OTP, BRDAC0, 10, 50), | ||
132 | AD5274_ID = DPOT_CONF(F_RDACS_RW | F_CMD_OTP, BRDAC0, 8, 51), | ||
125 | }; | 133 | }; |
126 | 134 | ||
127 | #define DPOT_RDAC0 0 | 135 | #define DPOT_RDAC0 0 |
@@ -165,10 +173,19 @@ enum dpot_devid { | |||
165 | /* AD5291/2/3 use special commands */ | 173 | /* AD5291/2/3 use special commands */ |
166 | #define DPOT_AD5291_RDAC 0x01 | 174 | #define DPOT_AD5291_RDAC 0x01 |
167 | #define DPOT_AD5291_READ_RDAC 0x02 | 175 | #define DPOT_AD5291_READ_RDAC 0x02 |
176 | #define DPOT_AD5291_STORE_XTPM 0x03 | ||
177 | #define DPOT_AD5291_CTRLREG 0x06 | ||
178 | #define DPOT_AD5291_UNLOCK_CMD 0x03 | ||
168 | 179 | ||
169 | #define DPOT_AD5291_RDAC_AB 0x80 | 180 | /* AD5270/1/2/4 use special commands */ |
181 | #define DPOT_AD5270_1_2_4_RDAC 0x01 | ||
182 | #define DPOT_AD5270_1_2_4_READ_RDAC 0x02 | ||
183 | #define DPOT_AD5270_1_2_4_STORE_XTPM 0x03 | ||
184 | #define DPOT_AD5270_1_2_4_CTRLREG 0x07 | ||
185 | #define DPOT_AD5270_1_2_4_UNLOCK_CMD 0x03 | ||
170 | 186 | ||
171 | #define DPOT_AD5282_RDAC_AB 0x80 | 187 | #define DPOT_AD5282_RDAC_AB 0x80 |
188 | |||
172 | #define DPOT_AD5273_FUSE 0x80 | 189 | #define DPOT_AD5273_FUSE 0x80 |
173 | #define DPOT_AD5170_2_3_FUSE 0x20 | 190 | #define DPOT_AD5170_2_3_FUSE 0x20 |
174 | #define DPOT_AD5170_2_3_OW 0x08 | 191 | #define DPOT_AD5170_2_3_OW 0x08 |