ad525x_dpot.c (5f400cf40fc703673aa791966ffb1c628c1ff45a) ad525x_dpot.c (a4bd394956f20d0bfc0ca6ecfac2af4150da274a)
1/*
2 * ad525x_dpot: Driver for the Analog Devices digital potentiometers
3 * Copyright (c) 2009-2010 Analog Devices, Inc.
4 * Author: Michael Hennerich <hennerich@blackfin.uclinux.org>
5 *
6 * DEVID #Wipers #Positions Resistor Options (kOhm)
7 * AD5258 1 64 1, 10, 50, 100
8 * AD5259 1 256 5, 10, 50, 100

--- 15 unchanged lines hidden (view full) ---

24 * AD5231 1 1024 10, 50, 100
25 * AD5232 2 256 10, 50, 100
26 * AD5233 4 64 10, 50, 100
27 * AD5235 2 1024 25, 250
28 * AD5260 1 256 20, 50, 200
29 * AD5262 2 256 20, 50, 200
30 * AD5263 4 256 20, 50, 200
31 * AD5290 1 256 10, 50, 100
1/*
2 * ad525x_dpot: Driver for the Analog Devices digital potentiometers
3 * Copyright (c) 2009-2010 Analog Devices, Inc.
4 * Author: Michael Hennerich <hennerich@blackfin.uclinux.org>
5 *
6 * DEVID #Wipers #Positions Resistor Options (kOhm)
7 * AD5258 1 64 1, 10, 50, 100
8 * AD5259 1 256 5, 10, 50, 100

--- 15 unchanged lines hidden (view full) ---

24 * AD5231 1 1024 10, 50, 100
25 * AD5232 2 256 10, 50, 100
26 * AD5233 4 64 10, 50, 100
27 * AD5235 2 1024 25, 250
28 * AD5260 1 256 20, 50, 200
29 * AD5262 2 256 20, 50, 200
30 * AD5263 4 256 20, 50, 200
31 * AD5290 1 256 10, 50, 100
32 * AD5291 1 256 20
33 * AD5292 1 1024 20
34 * AD5293 1 1024 20
32 * AD5291 1 256 20, 50, 100 (20-TP)
33 * AD5292 1 1024 20, 50, 100 (20-TP)
34 * AD5293 1 1024 20, 50, 100
35 * AD7376 1 128 10, 50, 100, 1M
36 * AD8400 1 256 1, 10, 50, 100
37 * AD8402 2 256 1, 10, 50, 100
38 * AD8403 4 256 1, 10, 50, 100
39 * ADN2850 3 512 25, 250
40 * AD5241 1 256 10, 100, 1M
41 * AD5246 1 128 5, 10, 50, 100
42 * AD5247 1 128 5, 10, 50, 100

--- 4 unchanged lines hidden (view full) ---

47 * AD5280 1 256 20, 50, 200
48 * AD5282 2 256 20, 50, 200
49 * ADN2860 3 512 25, 250
50 * AD5273 1 64 1, 10, 50, 100 (OTP)
51 * AD5171 1 64 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)
54 * AD5173 2 256 2.5, 10, 50, 100 (OTP)
35 * AD7376 1 128 10, 50, 100, 1M
36 * AD8400 1 256 1, 10, 50, 100
37 * AD8402 2 256 1, 10, 50, 100
38 * AD8403 4 256 1, 10, 50, 100
39 * ADN2850 3 512 25, 250
40 * AD5241 1 256 10, 100, 1M
41 * AD5246 1 128 5, 10, 50, 100
42 * AD5247 1 128 5, 10, 50, 100

--- 4 unchanged lines hidden (view full) ---

47 * AD5280 1 256 20, 50, 200
48 * AD5282 2 256 20, 50, 200
49 * ADN2860 3 512 25, 250
50 * AD5273 1 64 1, 10, 50, 100 (OTP)
51 * AD5171 1 64 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)
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 *
56 * See Documentation/misc-devices/ad525x_dpot.txt for more info.
57 *
58 * derived from ad5258.c
59 * Copyright (c) 2009 Cyber Switching, Inc.
60 * Author: Chris Verges <chrisv@cyberswitching.com>
61 *
62 * derived from ad5252.c

--- 58 unchanged lines hidden (view full) ---

121static inline int dpot_write_r8d16(struct dpot_data *dpot, u8 reg, u16 val)
122{
123 return dpot->bdata.bops->write_r8d16(dpot->bdata.client, reg, val);
124}
125
126static s32 dpot_read_spi(struct dpot_data *dpot, u8 reg)
127{
128 unsigned ctrl = 0;
59 *
60 * See Documentation/misc-devices/ad525x_dpot.txt for more info.
61 *
62 * derived from ad5258.c
63 * Copyright (c) 2009 Cyber Switching, Inc.
64 * Author: Chris Verges <chrisv@cyberswitching.com>
65 *
66 * derived from ad5252.c

--- 58 unchanged lines hidden (view full) ---

125static inline int dpot_write_r8d16(struct dpot_data *dpot, u8 reg, u16 val)
126{
127 return dpot->bdata.bops->write_r8d16(dpot->bdata.client, reg, val);
128}
129
130static s32 dpot_read_spi(struct dpot_data *dpot, u8 reg)
131{
132 unsigned ctrl = 0;
133 int value;
129
130 if (!(reg & (DPOT_ADDR_EEPROM | DPOT_ADDR_CMD))) {
131
132 if (dpot->feat & F_RDACS_WONLY)
133 return dpot->rdac_cache[reg & DPOT_RDAC_MASK];
134
135 if (!(reg & (DPOT_ADDR_EEPROM | DPOT_ADDR_CMD))) {
136
137 if (dpot->feat & F_RDACS_WONLY)
138 return dpot->rdac_cache[reg & DPOT_RDAC_MASK];
134
135 if (dpot->uid == DPOT_UID(AD5291_ID) ||
136 dpot->uid == DPOT_UID(AD5292_ID) ||
139 if (dpot->uid == DPOT_UID(AD5291_ID) ||
140 dpot->uid == DPOT_UID(AD5292_ID) ||
137 dpot->uid == DPOT_UID(AD5293_ID))
138 return dpot_read_r8d8(dpot,
141 dpot->uid == DPOT_UID(AD5293_ID)) {
142
143 value = dpot_read_r8d8(dpot,
139 DPOT_AD5291_READ_RDAC << 2);
140
144 DPOT_AD5291_READ_RDAC << 2);
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;
142 } else if (reg & DPOT_ADDR_EEPROM) {
143 ctrl = DPOT_SPI_READ_EEPROM;
144 }
145
146 if (dpot->feat & F_SPI_16BIT)
147 return dpot_read_r8d8(dpot, ctrl);
148 else if (dpot->feat & F_SPI_24BIT)
149 return dpot_read_r8d16(dpot, ctrl);
150
151 return -EFAULT;
152}
153
154static s32 dpot_read_i2c(struct dpot_data *dpot, u8 reg)
155{
165 ctrl = DPOT_SPI_READ_RDAC;
166 } else if (reg & DPOT_ADDR_EEPROM) {
167 ctrl = DPOT_SPI_READ_EEPROM;
168 }
169
170 if (dpot->feat & F_SPI_16BIT)
171 return dpot_read_r8d8(dpot, ctrl);
172 else if (dpot->feat & F_SPI_24BIT)
173 return dpot_read_r8d16(dpot, ctrl);
174
175 return -EFAULT;
176}
177
178static s32 dpot_read_i2c(struct dpot_data *dpot, u8 reg)
179{
180 int value;
156 unsigned ctrl = 0;
157 switch (dpot->uid) {
158 case DPOT_UID(AD5246_ID):
159 case DPOT_UID(AD5247_ID):
160 return dpot_read_d8(dpot);
161 case DPOT_UID(AD5245_ID):
162 case DPOT_UID(AD5241_ID):
163 case DPOT_UID(AD5242_ID):

--- 8 unchanged lines hidden (view full) ---

172 case DPOT_UID(AD5171_ID):
173 case DPOT_UID(AD5273_ID):
174 return dpot_read_d8(dpot);
175 case DPOT_UID(AD5172_ID):
176 case DPOT_UID(AD5173_ID):
177 ctrl = ((reg & DPOT_RDAC_MASK) == DPOT_RDAC0) ?
178 0 : DPOT_AD5172_3_A0;
179 return dpot_read_r8d8(dpot, ctrl);
181 unsigned ctrl = 0;
182 switch (dpot->uid) {
183 case DPOT_UID(AD5246_ID):
184 case DPOT_UID(AD5247_ID):
185 return dpot_read_d8(dpot);
186 case DPOT_UID(AD5245_ID):
187 case DPOT_UID(AD5241_ID):
188 case DPOT_UID(AD5242_ID):

--- 8 unchanged lines hidden (view full) ---

197 case DPOT_UID(AD5171_ID):
198 case DPOT_UID(AD5273_ID):
199 return dpot_read_d8(dpot);
200 case DPOT_UID(AD5172_ID):
201 case DPOT_UID(AD5173_ID):
202 ctrl = ((reg & DPOT_RDAC_MASK) == DPOT_RDAC0) ?
203 0 : DPOT_AD5172_3_A0;
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:
181 if ((reg & DPOT_REG_TOL) || (dpot->max_pos > 256))
182 return dpot_read_r8d16(dpot, (reg & 0xF8) |
183 ((reg & 0x7) << 1));
184 else
185 return dpot_read_r8d8(dpot, reg);
186 }
187}

--- 5 unchanged lines hidden (view full) ---

193 else
194 return dpot_read_i2c(dpot, reg);
195}
196
197static s32 dpot_write_spi(struct dpot_data *dpot, u8 reg, u16 value)
198{
199 unsigned val = 0;
200
224 default:
225 if ((reg & DPOT_REG_TOL) || (dpot->max_pos > 256))
226 return dpot_read_r8d16(dpot, (reg & 0xF8) |
227 ((reg & 0x7) << 1));
228 else
229 return dpot_read_r8d8(dpot, reg);
230 }
231}

--- 5 unchanged lines hidden (view full) ---

237 else
238 return dpot_read_i2c(dpot, reg);
239}
240
241static s32 dpot_write_spi(struct dpot_data *dpot, u8 reg, u16 value)
242{
243 unsigned val = 0;
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)
203 dpot->rdac_cache[reg & DPOT_RDAC_MASK] = value;
204
205 if (dpot->feat & F_AD_APPDATA) {
206 if (dpot->feat & F_SPI_8BIT) {
207 val = ((reg & DPOT_RDAC_MASK) <<
208 DPOT_MAX_POS(dpot->devid)) |
209 value;

--- 4 unchanged lines hidden (view full) ---

214 value;
215 return dpot_write_r8d8(dpot, val >> 8,
216 val & 0xFF);
217 } else
218 BUG();
219 } else {
220 if (dpot->uid == DPOT_UID(AD5291_ID) ||
221 dpot->uid == DPOT_UID(AD5292_ID) ||
246 if (dpot->feat & F_RDACS_WONLY)
247 dpot->rdac_cache[reg & DPOT_RDAC_MASK] = value;
248
249 if (dpot->feat & F_AD_APPDATA) {
250 if (dpot->feat & F_SPI_8BIT) {
251 val = ((reg & DPOT_RDAC_MASK) <<
252 DPOT_MAX_POS(dpot->devid)) |
253 value;

--- 4 unchanged lines hidden (view full) ---

258 value;
259 return dpot_write_r8d8(dpot, val >> 8,
260 val & 0xFF);
261 } else
262 BUG();
263 } else {
264 if (dpot->uid == DPOT_UID(AD5291_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,
224 (DPOT_AD5291_RDAC << 2) |
225 (value >> 8), value & 0xFF);
274 return dpot_write_r8d8(dpot,
275 (DPOT_AD5291_RDAC << 2) |
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);
226
282
283 if (dpot->uid == DPOT_UID(AD5271_ID))
284 value = value << 2;
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);
228 }
229 } else if (reg & DPOT_ADDR_EEPROM) {
230 val = DPOT_SPI_EEPROM | (reg & DPOT_RDAC_MASK);
231 } else if (reg & DPOT_ADDR_CMD) {
232 switch (reg) {
233 case DPOT_DEC_ALL_6DB:
234 val = DPOT_SPI_DEC_ALL_6DB;
235 break;
236 case DPOT_INC_ALL_6DB:
237 val = DPOT_SPI_INC_ALL_6DB;
238 break;
239 case DPOT_DEC_ALL:
240 val = DPOT_SPI_DEC_ALL;
241 break;
242 case DPOT_INC_ALL:
243 val = DPOT_SPI_INC_ALL;
244 break;
245 }
290 val = DPOT_SPI_RDAC | (reg & DPOT_RDAC_MASK);
291 }
292 } else if (reg & DPOT_ADDR_EEPROM) {
293 val = DPOT_SPI_EEPROM | (reg & DPOT_RDAC_MASK);
294 } else if (reg & DPOT_ADDR_CMD) {
295 switch (reg) {
296 case DPOT_DEC_ALL_6DB:
297 val = DPOT_SPI_DEC_ALL_6DB;
298 break;
299 case DPOT_INC_ALL_6DB:
300 val = DPOT_SPI_INC_ALL_6DB;
301 break;
302 case DPOT_DEC_ALL:
303 val = DPOT_SPI_DEC_ALL;
304 break;
305 case DPOT_INC_ALL:
306 val = DPOT_SPI_INC_ALL;
307 break;
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
247 BUG();
248
249 if (dpot->feat & F_SPI_16BIT)
250 return dpot_write_r8d8(dpot, val, value);
251 else if (dpot->feat & F_SPI_24BIT)
252 return dpot_write_r8d16(dpot, val, value);
253

--- 44 unchanged lines hidden (view full) ---

298 }
299 return dpot_write_r8d8(dpot, ctrl, value);
300 break;
301 case DPOT_UID(AD5170_ID):
302 if (reg & DPOT_ADDR_OTP) {
303 tmp = dpot_read_r8d16(dpot, tmp);
304 if (tmp >> 14) /* Ready to Program? */
305 return -EFAULT;
319 } else
320 BUG();
321
322 if (dpot->feat & F_SPI_16BIT)
323 return dpot_write_r8d8(dpot, val, value);
324 else if (dpot->feat & F_SPI_24BIT)
325 return dpot_write_r8d16(dpot, val, value);
326

--- 44 unchanged lines hidden (view full) ---

371 }
372 return dpot_write_r8d8(dpot, ctrl, value);
373 break;
374 case DPOT_UID(AD5170_ID):
375 if (reg & DPOT_ADDR_OTP) {
376 tmp = dpot_read_r8d16(dpot, tmp);
377 if (tmp >> 14) /* Ready to Program? */
378 return -EFAULT;
306 ctrl = DPOT_AD5270_2_3_FUSE;
379 ctrl = DPOT_AD5170_2_3_FUSE;
307 }
308 return dpot_write_r8d8(dpot, ctrl, value);
309 break;
380 }
381 return dpot_write_r8d8(dpot, ctrl, value);
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:
311 if (reg & DPOT_ADDR_CMD)
312 return dpot_write_d8(dpot, reg);
313
314 if (dpot->max_pos > 256)
315 return dpot_write_r8d16(dpot, (reg & 0xF8) |
316 ((reg & 0x7) << 1), value);
317 else
318 /* All other registers require instruction + data bytes */
319 return dpot_write_r8d8(dpot, reg, value);
320 }
321}
322
398 default:
399 if (reg & DPOT_ADDR_CMD)
400 return dpot_write_d8(dpot, reg);
401
402 if (dpot->max_pos > 256)
403 return dpot_write_r8d16(dpot, (reg & 0xF8) |
404 ((reg & 0x7) << 1), value);
405 else
406 /* All other registers require instruction + data bytes */
407 return dpot_write_r8d8(dpot, reg, value);
408 }
409}
410
323
324static s32 dpot_write(struct dpot_data *dpot, u8 reg, u16 value)
325{
326 if (dpot->feat & F_SPI)
327 return dpot_write_spi(dpot, reg, value);
328 else
329 return dpot_write_i2c(dpot, reg, value);
330}
331

--- 355 unchanged lines hidden ---
411static s32 dpot_write(struct dpot_data *dpot, u8 reg, u16 value)
412{
413 if (dpot->feat & F_SPI)
414 return dpot_write_spi(dpot, reg, value);
415 else
416 return dpot_write_i2c(dpot, reg, value);
417}
418

--- 355 unchanged lines hidden ---