aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/ad525x_dpot.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/ad525x_dpot.c')
-rw-r--r--drivers/misc/ad525x_dpot.c107
1 files changed, 97 insertions, 10 deletions
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)
126static s32 dpot_read_spi(struct dpot_data *dpot, u8 reg) 130static 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
154static s32 dpot_read_i2c(struct dpot_data *dpot, u8 reg) 178static 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
324static s32 dpot_write(struct dpot_data *dpot, u8 reg, u16 value) 411static 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)