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>
6 * DEVID #Wipers #Positions Resistor Options (kOhm)
7 * AD5258 1 64 1, 10, 50, 100
8 * AD5259 1 256 5, 10, 50, 100
9 * AD5251 2 64 1, 10, 50, 100
10 * AD5252 2 256 1, 10, 50, 100
11 * AD5255 3 512 25, 250
12 * AD5253 4 64 1, 10, 50, 100
13 * AD5254 4 256 1, 10, 50, 100
14 * AD5160 1 256 5, 10, 50, 100
15 * AD5161 1 256 5, 10, 50, 100
16 * AD5162 2 256 2.5, 10, 50, 100
21 * AD5204 4 256 10, 50, 100
22 * AD5206 6 256 10, 50, 100
23 * AD5207 2 256 10, 50, 100
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, 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
43 * AD5245 1 256 5, 10, 50, 100
44 * AD5243 2 256 2.5, 10, 50, 100
45 * AD5248 2 256 2.5, 10, 50, 100
46 * AD5242 2 256 20, 50, 200
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)
60 * See Documentation/misc-devices/ad525x_dpot.txt for more info.
62 * derived from ad5258.c
63 * Copyright (c) 2009 Cyber Switching, Inc.
64 * Author: Chris Verges <chrisv@cyberswitching.com>
66 * derived from ad5252.c
67 * Copyright (c) 2006-2011 Michael Hennerich <hennerich@blackfin.uclinux.org>
69 * Licensed under the GPL-2 or later.
72 #include <linux/module.h>
73 #include <linux/device.h>
74 #include <linux/kernel.h>
75 #include <linux/init.h>
76 #include <linux/delay.h>
77 #include <linux/slab.h>
79 #include "ad525x_dpot.h"
82 * Client data (each client gets its own)
86 struct ad_dpot_bus_data bdata
;
87 struct mutex update_lock
;
94 u16 rdac_cache
[MAX_RDACS
];
95 DECLARE_BITMAP(otp_en_mask
, MAX_RDACS
);
98 static inline int dpot_read_d8(struct dpot_data
*dpot
)
100 return dpot
->bdata
.bops
->read_d8(dpot
->bdata
.client
);
103 static inline int dpot_read_r8d8(struct dpot_data
*dpot
, u8 reg
)
105 return dpot
->bdata
.bops
->read_r8d8(dpot
->bdata
.client
, reg
);
108 static inline int dpot_read_r8d16(struct dpot_data
*dpot
, u8 reg
)
110 return dpot
->bdata
.bops
->read_r8d16(dpot
->bdata
.client
, reg
);
113 static inline int dpot_write_d8(struct dpot_data
*dpot
, u8 val
)
115 return dpot
->bdata
.bops
->write_d8(dpot
->bdata
.client
, val
);
118 static inline int dpot_write_r8d8(struct dpot_data
*dpot
, u8 reg
, u16 val
)
120 return dpot
->bdata
.bops
->write_r8d8(dpot
->bdata
.client
, reg
, val
);
123 static inline int dpot_write_r8d16(struct dpot_data
*dpot
, u8 reg
, u16 val
)
125 return dpot
->bdata
.bops
->write_r8d16(dpot
->bdata
.client
, reg
, val
);
128 static s32
dpot_read_spi(struct dpot_data
*dpot
, u8 reg
)
133 if (!(reg
& (DPOT_ADDR_EEPROM
| DPOT_ADDR_CMD
))) {
135 if (dpot
->feat
& F_RDACS_WONLY
)
136 return dpot
->rdac_cache
[reg
& DPOT_RDAC_MASK
];
137 if (dpot
->uid
== DPOT_UID(AD5291_ID
) ||
138 dpot
->uid
== DPOT_UID(AD5292_ID
) ||
139 dpot
->uid
== DPOT_UID(AD5293_ID
)) {
141 value
= dpot_read_r8d8(dpot
,
142 DPOT_AD5291_READ_RDAC
<< 2);
144 if (dpot
->uid
== DPOT_UID(AD5291_ID
))
148 } else if (dpot
->uid
== DPOT_UID(AD5270_ID
) ||
149 dpot
->uid
== DPOT_UID(AD5271_ID
)) {
151 value
= dpot_read_r8d8(dpot
,
152 DPOT_AD5270_1_2_4_READ_RDAC
<< 2);
157 if (dpot
->uid
== DPOT_UID(AD5271_ID
))
163 ctrl
= DPOT_SPI_READ_RDAC
;
164 } else if (reg
& DPOT_ADDR_EEPROM
) {
165 ctrl
= DPOT_SPI_READ_EEPROM
;
168 if (dpot
->feat
& F_SPI_16BIT
)
169 return dpot_read_r8d8(dpot
, ctrl
);
170 else if (dpot
->feat
& F_SPI_24BIT
)
171 return dpot_read_r8d16(dpot
, ctrl
);
176 static s32
dpot_read_i2c(struct dpot_data
*dpot
, u8 reg
)
181 case DPOT_UID(AD5246_ID
):
182 case DPOT_UID(AD5247_ID
):
183 return dpot_read_d8(dpot
);
184 case DPOT_UID(AD5245_ID
):
185 case DPOT_UID(AD5241_ID
):
186 case DPOT_UID(AD5242_ID
):
187 case DPOT_UID(AD5243_ID
):
188 case DPOT_UID(AD5248_ID
):
189 case DPOT_UID(AD5280_ID
):
190 case DPOT_UID(AD5282_ID
):
191 ctrl
= ((reg
& DPOT_RDAC_MASK
) == DPOT_RDAC0
) ?
192 0 : DPOT_AD5282_RDAC_AB
;
193 return dpot_read_r8d8(dpot
, ctrl
);
194 case DPOT_UID(AD5170_ID
):
195 case DPOT_UID(AD5171_ID
):
196 case DPOT_UID(AD5273_ID
):
197 return dpot_read_d8(dpot
);
198 case DPOT_UID(AD5172_ID
):
199 case DPOT_UID(AD5173_ID
):
200 ctrl
= ((reg
& DPOT_RDAC_MASK
) == DPOT_RDAC0
) ?
201 0 : DPOT_AD5172_3_A0
;
202 return dpot_read_r8d8(dpot
, ctrl
);
203 case DPOT_UID(AD5272_ID
):
204 case DPOT_UID(AD5274_ID
):
205 dpot_write_r8d8(dpot
,
206 (DPOT_AD5270_1_2_4_READ_RDAC
<< 2), 0);
208 value
= dpot_read_r8d16(dpot
,
209 DPOT_AD5270_1_2_4_RDAC
<< 2);
214 * AD5272/AD5274 returns high byte first, however
215 * underling smbus expects low byte first.
217 value
= swab16(value
);
219 if (dpot
->uid
== DPOT_UID(AD5271_ID
))
223 if ((reg
& DPOT_REG_TOL
) || (dpot
->max_pos
> 256))
224 return dpot_read_r8d16(dpot
, (reg
& 0xF8) |
227 return dpot_read_r8d8(dpot
, reg
);
231 static s32
dpot_read(struct dpot_data
*dpot
, u8 reg
)
233 if (dpot
->feat
& F_SPI
)
234 return dpot_read_spi(dpot
, reg
);
236 return dpot_read_i2c(dpot
, reg
);
239 static s32
dpot_write_spi(struct dpot_data
*dpot
, u8 reg
, u16 value
)
243 if (!(reg
& (DPOT_ADDR_EEPROM
| DPOT_ADDR_CMD
| DPOT_ADDR_OTP
))) {
244 if (dpot
->feat
& F_RDACS_WONLY
)
245 dpot
->rdac_cache
[reg
& DPOT_RDAC_MASK
] = value
;
247 if (dpot
->feat
& F_AD_APPDATA
) {
248 if (dpot
->feat
& F_SPI_8BIT
) {
249 val
= ((reg
& DPOT_RDAC_MASK
) <<
250 DPOT_MAX_POS(dpot
->devid
)) |
252 return dpot_write_d8(dpot
, val
);
253 } else if (dpot
->feat
& F_SPI_16BIT
) {
254 val
= ((reg
& DPOT_RDAC_MASK
) <<
255 DPOT_MAX_POS(dpot
->devid
)) |
257 return dpot_write_r8d8(dpot
, val
>> 8,
262 if (dpot
->uid
== DPOT_UID(AD5291_ID
) ||
263 dpot
->uid
== DPOT_UID(AD5292_ID
) ||
264 dpot
->uid
== DPOT_UID(AD5293_ID
)) {
266 dpot_write_r8d8(dpot
, DPOT_AD5291_CTRLREG
<< 2,
267 DPOT_AD5291_UNLOCK_CMD
);
269 if (dpot
->uid
== DPOT_UID(AD5291_ID
))
272 return dpot_write_r8d8(dpot
,
273 (DPOT_AD5291_RDAC
<< 2) |
274 (value
>> 8), value
& 0xFF);
275 } else if (dpot
->uid
== DPOT_UID(AD5270_ID
) ||
276 dpot
->uid
== DPOT_UID(AD5271_ID
)) {
277 dpot_write_r8d8(dpot
,
278 DPOT_AD5270_1_2_4_CTRLREG
<< 2,
279 DPOT_AD5270_1_2_4_UNLOCK_CMD
);
281 if (dpot
->uid
== DPOT_UID(AD5271_ID
))
284 return dpot_write_r8d8(dpot
,
285 (DPOT_AD5270_1_2_4_RDAC
<< 2) |
286 (value
>> 8), value
& 0xFF);
288 val
= DPOT_SPI_RDAC
| (reg
& DPOT_RDAC_MASK
);
290 } else if (reg
& DPOT_ADDR_EEPROM
) {
291 val
= DPOT_SPI_EEPROM
| (reg
& DPOT_RDAC_MASK
);
292 } else if (reg
& DPOT_ADDR_CMD
) {
294 case DPOT_DEC_ALL_6DB
:
295 val
= DPOT_SPI_DEC_ALL_6DB
;
297 case DPOT_INC_ALL_6DB
:
298 val
= DPOT_SPI_INC_ALL_6DB
;
301 val
= DPOT_SPI_DEC_ALL
;
304 val
= DPOT_SPI_INC_ALL
;
307 } else if (reg
& DPOT_ADDR_OTP
) {
308 if (dpot
->uid
== DPOT_UID(AD5291_ID
) ||
309 dpot
->uid
== DPOT_UID(AD5292_ID
)) {
310 return dpot_write_r8d8(dpot
,
311 DPOT_AD5291_STORE_XTPM
<< 2, 0);
312 } else if (dpot
->uid
== DPOT_UID(AD5270_ID
) ||
313 dpot
->uid
== DPOT_UID(AD5271_ID
)) {
314 return dpot_write_r8d8(dpot
,
315 DPOT_AD5270_1_2_4_STORE_XTPM
<< 2, 0);
320 if (dpot
->feat
& F_SPI_16BIT
)
321 return dpot_write_r8d8(dpot
, val
, value
);
322 else if (dpot
->feat
& F_SPI_24BIT
)
323 return dpot_write_r8d16(dpot
, val
, value
);
328 static s32
dpot_write_i2c(struct dpot_data
*dpot
, u8 reg
, u16 value
)
330 /* Only write the instruction byte for certain commands */
331 unsigned tmp
= 0, ctrl
= 0;
334 case DPOT_UID(AD5246_ID
):
335 case DPOT_UID(AD5247_ID
):
336 return dpot_write_d8(dpot
, value
);
339 case DPOT_UID(AD5245_ID
):
340 case DPOT_UID(AD5241_ID
):
341 case DPOT_UID(AD5242_ID
):
342 case DPOT_UID(AD5243_ID
):
343 case DPOT_UID(AD5248_ID
):
344 case DPOT_UID(AD5280_ID
):
345 case DPOT_UID(AD5282_ID
):
346 ctrl
= ((reg
& DPOT_RDAC_MASK
) == DPOT_RDAC0
) ?
347 0 : DPOT_AD5282_RDAC_AB
;
348 return dpot_write_r8d8(dpot
, ctrl
, value
);
350 case DPOT_UID(AD5171_ID
):
351 case DPOT_UID(AD5273_ID
):
352 if (reg
& DPOT_ADDR_OTP
) {
353 tmp
= dpot_read_d8(dpot
);
354 if (tmp
>> 6) /* Ready to Program? */
356 ctrl
= DPOT_AD5273_FUSE
;
358 return dpot_write_r8d8(dpot
, ctrl
, value
);
360 case DPOT_UID(AD5172_ID
):
361 case DPOT_UID(AD5173_ID
):
362 ctrl
= ((reg
& DPOT_RDAC_MASK
) == DPOT_RDAC0
) ?
363 0 : DPOT_AD5172_3_A0
;
364 if (reg
& DPOT_ADDR_OTP
) {
365 tmp
= dpot_read_r8d16(dpot
, ctrl
);
366 if (tmp
>> 14) /* Ready to Program? */
368 ctrl
|= DPOT_AD5170_2_3_FUSE
;
370 return dpot_write_r8d8(dpot
, ctrl
, value
);
372 case DPOT_UID(AD5170_ID
):
373 if (reg
& DPOT_ADDR_OTP
) {
374 tmp
= dpot_read_r8d16(dpot
, tmp
);
375 if (tmp
>> 14) /* Ready to Program? */
377 ctrl
= DPOT_AD5170_2_3_FUSE
;
379 return dpot_write_r8d8(dpot
, ctrl
, value
);
381 case DPOT_UID(AD5272_ID
):
382 case DPOT_UID(AD5274_ID
):
383 dpot_write_r8d8(dpot
, DPOT_AD5270_1_2_4_CTRLREG
<< 2,
384 DPOT_AD5270_1_2_4_UNLOCK_CMD
);
386 if (reg
& DPOT_ADDR_OTP
)
387 return dpot_write_r8d8(dpot
,
388 DPOT_AD5270_1_2_4_STORE_XTPM
<< 2, 0);
390 if (dpot
->uid
== DPOT_UID(AD5274_ID
))
393 return dpot_write_r8d8(dpot
, (DPOT_AD5270_1_2_4_RDAC
<< 2) |
394 (value
>> 8), value
& 0xFF);
397 if (reg
& DPOT_ADDR_CMD
)
398 return dpot_write_d8(dpot
, reg
);
400 if (dpot
->max_pos
> 256)
401 return dpot_write_r8d16(dpot
, (reg
& 0xF8) |
402 ((reg
& 0x7) << 1), value
);
404 /* All other registers require instruction + data bytes */
405 return dpot_write_r8d8(dpot
, reg
, value
);
409 static s32
dpot_write(struct dpot_data
*dpot
, u8 reg
, u16 value
)
411 if (dpot
->feat
& F_SPI
)
412 return dpot_write_spi(dpot
, reg
, value
);
414 return dpot_write_i2c(dpot
, reg
, value
);
417 /* sysfs functions */
419 static ssize_t
sysfs_show_reg(struct device
*dev
,
420 struct device_attribute
*attr
,
423 struct dpot_data
*data
= dev_get_drvdata(dev
);
426 if (reg
& DPOT_ADDR_OTP_EN
)
427 return sprintf(buf
, "%s\n",
428 test_bit(DPOT_RDAC_MASK
& reg
, data
->otp_en_mask
) ?
429 "enabled" : "disabled");
432 mutex_lock(&data
->update_lock
);
433 value
= dpot_read(data
, reg
);
434 mutex_unlock(&data
->update_lock
);
439 * Let someone else deal with converting this ...
440 * the tolerance is a two-byte value where the MSB
441 * is a sign + integer value, and the LSB is a
442 * decimal value. See page 18 of the AD5258
443 * datasheet (Rev. A) for more details.
446 if (reg
& DPOT_REG_TOL
)
447 return sprintf(buf
, "0x%04x\n", value
& 0xFFFF);
449 return sprintf(buf
, "%u\n", value
& data
->rdac_mask
);
452 static ssize_t
sysfs_set_reg(struct device
*dev
,
453 struct device_attribute
*attr
,
454 const char *buf
, size_t count
, u32 reg
)
456 struct dpot_data
*data
= dev_get_drvdata(dev
);
460 if (reg
& DPOT_ADDR_OTP_EN
) {
461 if (!strncmp(buf
, "enabled", sizeof("enabled")))
462 set_bit(DPOT_RDAC_MASK
& reg
, data
->otp_en_mask
);
464 clear_bit(DPOT_RDAC_MASK
& reg
, data
->otp_en_mask
);
469 if ((reg
& DPOT_ADDR_OTP
) &&
470 !test_bit(DPOT_RDAC_MASK
& reg
, data
->otp_en_mask
))
473 err
= strict_strtoul(buf
, 10, &value
);
477 if (value
> data
->rdac_mask
)
478 value
= data
->rdac_mask
;
480 mutex_lock(&data
->update_lock
);
481 dpot_write(data
, reg
, value
);
482 if (reg
& DPOT_ADDR_EEPROM
)
483 msleep(26); /* Sleep while the EEPROM updates */
484 else if (reg
& DPOT_ADDR_OTP
)
485 msleep(400); /* Sleep while the OTP updates */
486 mutex_unlock(&data
->update_lock
);
491 static ssize_t
sysfs_do_cmd(struct device
*dev
,
492 struct device_attribute
*attr
,
493 const char *buf
, size_t count
, u32 reg
)
495 struct dpot_data
*data
= dev_get_drvdata(dev
);
497 mutex_lock(&data
->update_lock
);
498 dpot_write(data
, reg
, 0);
499 mutex_unlock(&data
->update_lock
);
504 /* ------------------------------------------------------------------------- */
506 #define DPOT_DEVICE_SHOW(_name, _reg) static ssize_t \
507 show_##_name(struct device *dev, \
508 struct device_attribute *attr, char *buf) \
510 return sysfs_show_reg(dev, attr, buf, _reg); \
513 #define DPOT_DEVICE_SET(_name, _reg) static ssize_t \
514 set_##_name(struct device *dev, \
515 struct device_attribute *attr, \
516 const char *buf, size_t count) \
518 return sysfs_set_reg(dev, attr, buf, count, _reg); \
521 #define DPOT_DEVICE_SHOW_SET(name, reg) \
522 DPOT_DEVICE_SHOW(name, reg) \
523 DPOT_DEVICE_SET(name, reg) \
524 static DEVICE_ATTR(name, S_IWUSR | S_IRUGO, show_##name, set_##name);
526 #define DPOT_DEVICE_SHOW_ONLY(name, reg) \
527 DPOT_DEVICE_SHOW(name, reg) \
528 static DEVICE_ATTR(name, S_IWUSR | S_IRUGO, show_##name, NULL);
530 DPOT_DEVICE_SHOW_SET(rdac0
, DPOT_ADDR_RDAC
| DPOT_RDAC0
);
531 DPOT_DEVICE_SHOW_SET(eeprom0
, DPOT_ADDR_EEPROM
| DPOT_RDAC0
);
532 DPOT_DEVICE_SHOW_ONLY(tolerance0
, DPOT_ADDR_EEPROM
| DPOT_TOL_RDAC0
);
533 DPOT_DEVICE_SHOW_SET(otp0
, DPOT_ADDR_OTP
| DPOT_RDAC0
);
534 DPOT_DEVICE_SHOW_SET(otp0en
, DPOT_ADDR_OTP_EN
| DPOT_RDAC0
);
536 DPOT_DEVICE_SHOW_SET(rdac1
, DPOT_ADDR_RDAC
| DPOT_RDAC1
);
537 DPOT_DEVICE_SHOW_SET(eeprom1
, DPOT_ADDR_EEPROM
| DPOT_RDAC1
);
538 DPOT_DEVICE_SHOW_ONLY(tolerance1
, DPOT_ADDR_EEPROM
| DPOT_TOL_RDAC1
);
539 DPOT_DEVICE_SHOW_SET(otp1
, DPOT_ADDR_OTP
| DPOT_RDAC1
);
540 DPOT_DEVICE_SHOW_SET(otp1en
, DPOT_ADDR_OTP_EN
| DPOT_RDAC1
);
542 DPOT_DEVICE_SHOW_SET(rdac2
, DPOT_ADDR_RDAC
| DPOT_RDAC2
);
543 DPOT_DEVICE_SHOW_SET(eeprom2
, DPOT_ADDR_EEPROM
| DPOT_RDAC2
);
544 DPOT_DEVICE_SHOW_ONLY(tolerance2
, DPOT_ADDR_EEPROM
| DPOT_TOL_RDAC2
);
545 DPOT_DEVICE_SHOW_SET(otp2
, DPOT_ADDR_OTP
| DPOT_RDAC2
);
546 DPOT_DEVICE_SHOW_SET(otp2en
, DPOT_ADDR_OTP_EN
| DPOT_RDAC2
);
548 DPOT_DEVICE_SHOW_SET(rdac3
, DPOT_ADDR_RDAC
| DPOT_RDAC3
);
549 DPOT_DEVICE_SHOW_SET(eeprom3
, DPOT_ADDR_EEPROM
| DPOT_RDAC3
);
550 DPOT_DEVICE_SHOW_ONLY(tolerance3
, DPOT_ADDR_EEPROM
| DPOT_TOL_RDAC3
);
551 DPOT_DEVICE_SHOW_SET(otp3
, DPOT_ADDR_OTP
| DPOT_RDAC3
);
552 DPOT_DEVICE_SHOW_SET(otp3en
, DPOT_ADDR_OTP_EN
| DPOT_RDAC3
);
554 DPOT_DEVICE_SHOW_SET(rdac4
, DPOT_ADDR_RDAC
| DPOT_RDAC4
);
555 DPOT_DEVICE_SHOW_SET(eeprom4
, DPOT_ADDR_EEPROM
| DPOT_RDAC4
);
556 DPOT_DEVICE_SHOW_ONLY(tolerance4
, DPOT_ADDR_EEPROM
| DPOT_TOL_RDAC4
);
557 DPOT_DEVICE_SHOW_SET(otp4
, DPOT_ADDR_OTP
| DPOT_RDAC4
);
558 DPOT_DEVICE_SHOW_SET(otp4en
, DPOT_ADDR_OTP_EN
| DPOT_RDAC4
);
560 DPOT_DEVICE_SHOW_SET(rdac5
, DPOT_ADDR_RDAC
| DPOT_RDAC5
);
561 DPOT_DEVICE_SHOW_SET(eeprom5
, DPOT_ADDR_EEPROM
| DPOT_RDAC5
);
562 DPOT_DEVICE_SHOW_ONLY(tolerance5
, DPOT_ADDR_EEPROM
| DPOT_TOL_RDAC5
);
563 DPOT_DEVICE_SHOW_SET(otp5
, DPOT_ADDR_OTP
| DPOT_RDAC5
);
564 DPOT_DEVICE_SHOW_SET(otp5en
, DPOT_ADDR_OTP_EN
| DPOT_RDAC5
);
566 static const struct attribute
*dpot_attrib_wipers
[] = {
567 &dev_attr_rdac0
.attr
,
568 &dev_attr_rdac1
.attr
,
569 &dev_attr_rdac2
.attr
,
570 &dev_attr_rdac3
.attr
,
571 &dev_attr_rdac4
.attr
,
572 &dev_attr_rdac5
.attr
,
576 static const struct attribute
*dpot_attrib_eeprom
[] = {
577 &dev_attr_eeprom0
.attr
,
578 &dev_attr_eeprom1
.attr
,
579 &dev_attr_eeprom2
.attr
,
580 &dev_attr_eeprom3
.attr
,
581 &dev_attr_eeprom4
.attr
,
582 &dev_attr_eeprom5
.attr
,
586 static const struct attribute
*dpot_attrib_otp
[] = {
596 static const struct attribute
*dpot_attrib_otp_en
[] = {
597 &dev_attr_otp0en
.attr
,
598 &dev_attr_otp1en
.attr
,
599 &dev_attr_otp2en
.attr
,
600 &dev_attr_otp3en
.attr
,
601 &dev_attr_otp4en
.attr
,
602 &dev_attr_otp5en
.attr
,
606 static const struct attribute
*dpot_attrib_tolerance
[] = {
607 &dev_attr_tolerance0
.attr
,
608 &dev_attr_tolerance1
.attr
,
609 &dev_attr_tolerance2
.attr
,
610 &dev_attr_tolerance3
.attr
,
611 &dev_attr_tolerance4
.attr
,
612 &dev_attr_tolerance5
.attr
,
616 /* ------------------------------------------------------------------------- */
618 #define DPOT_DEVICE_DO_CMD(_name, _cmd) static ssize_t \
619 set_##_name(struct device *dev, \
620 struct device_attribute *attr, \
621 const char *buf, size_t count) \
623 return sysfs_do_cmd(dev, attr, buf, count, _cmd); \
625 static DEVICE_ATTR(_name, S_IWUSR | S_IRUGO, NULL, set_##_name);
627 DPOT_DEVICE_DO_CMD(inc_all
, DPOT_INC_ALL
);
628 DPOT_DEVICE_DO_CMD(dec_all
, DPOT_DEC_ALL
);
629 DPOT_DEVICE_DO_CMD(inc_all_6db
, DPOT_INC_ALL_6DB
);
630 DPOT_DEVICE_DO_CMD(dec_all_6db
, DPOT_DEC_ALL_6DB
);
632 static struct attribute
*ad525x_attributes_commands
[] = {
633 &dev_attr_inc_all
.attr
,
634 &dev_attr_dec_all
.attr
,
635 &dev_attr_inc_all_6db
.attr
,
636 &dev_attr_dec_all_6db
.attr
,
640 static const struct attribute_group ad525x_group_commands
= {
641 .attrs
= ad525x_attributes_commands
,
644 int ad_dpot_add_files(struct device
*dev
,
645 unsigned features
, unsigned rdac
)
647 int err
= sysfs_create_file(&dev
->kobj
,
648 dpot_attrib_wipers
[rdac
]);
649 if (features
& F_CMD_EEP
)
650 err
|= sysfs_create_file(&dev
->kobj
,
651 dpot_attrib_eeprom
[rdac
]);
652 if (features
& F_CMD_TOL
)
653 err
|= sysfs_create_file(&dev
->kobj
,
654 dpot_attrib_tolerance
[rdac
]);
655 if (features
& F_CMD_OTP
) {
656 err
|= sysfs_create_file(&dev
->kobj
,
657 dpot_attrib_otp_en
[rdac
]);
658 err
|= sysfs_create_file(&dev
->kobj
,
659 dpot_attrib_otp
[rdac
]);
663 dev_err(dev
, "failed to register sysfs hooks for RDAC%d\n",
669 inline void ad_dpot_remove_files(struct device
*dev
,
670 unsigned features
, unsigned rdac
)
672 sysfs_remove_file(&dev
->kobj
,
673 dpot_attrib_wipers
[rdac
]);
674 if (features
& F_CMD_EEP
)
675 sysfs_remove_file(&dev
->kobj
,
676 dpot_attrib_eeprom
[rdac
]);
677 if (features
& F_CMD_TOL
)
678 sysfs_remove_file(&dev
->kobj
,
679 dpot_attrib_tolerance
[rdac
]);
680 if (features
& F_CMD_OTP
) {
681 sysfs_remove_file(&dev
->kobj
,
682 dpot_attrib_otp_en
[rdac
]);
683 sysfs_remove_file(&dev
->kobj
,
684 dpot_attrib_otp
[rdac
]);
688 int ad_dpot_probe(struct device
*dev
,
689 struct ad_dpot_bus_data
*bdata
, unsigned long devid
,
693 struct dpot_data
*data
;
696 data
= kzalloc(sizeof(struct dpot_data
), GFP_KERNEL
);
702 dev_set_drvdata(dev
, data
);
703 mutex_init(&data
->update_lock
);
705 data
->bdata
= *bdata
;
708 data
->max_pos
= 1 << DPOT_MAX_POS(devid
);
709 data
->rdac_mask
= data
->max_pos
- 1;
710 data
->feat
= DPOT_FEAT(devid
);
711 data
->uid
= DPOT_UID(devid
);
712 data
->wipers
= DPOT_WIPERS(devid
);
714 for (i
= DPOT_RDAC0
; i
< MAX_RDACS
; i
++)
715 if (data
->wipers
& (1 << i
)) {
716 err
= ad_dpot_add_files(dev
, data
->feat
, i
);
718 goto exit_remove_files
;
719 /* power-up midscale */
720 if (data
->feat
& F_RDACS_WONLY
)
721 data
->rdac_cache
[i
] = data
->max_pos
/ 2;
724 if (data
->feat
& F_CMD_INC
)
725 err
= sysfs_create_group(&dev
->kobj
, &ad525x_group_commands
);
728 dev_err(dev
, "failed to register sysfs hooks\n");
732 dev_info(dev
, "%s %d-Position Digital Potentiometer registered\n",
733 name
, data
->max_pos
);
738 for (i
= DPOT_RDAC0
; i
< MAX_RDACS
; i
++)
739 if (data
->wipers
& (1 << i
))
740 ad_dpot_remove_files(dev
, data
->feat
, i
);
744 dev_set_drvdata(dev
, NULL
);
746 dev_err(dev
, "failed to create client for %s ID 0x%lX\n",
750 EXPORT_SYMBOL(ad_dpot_probe
);
752 int ad_dpot_remove(struct device
*dev
)
754 struct dpot_data
*data
= dev_get_drvdata(dev
);
757 for (i
= DPOT_RDAC0
; i
< MAX_RDACS
; i
++)
758 if (data
->wipers
& (1 << i
))
759 ad_dpot_remove_files(dev
, data
->feat
, i
);
765 EXPORT_SYMBOL(ad_dpot_remove
);
768 MODULE_AUTHOR("Chris Verges <chrisv@cyberswitching.com>, "
769 "Michael Hennerich <hennerich@blackfin.uclinux.org>");
770 MODULE_DESCRIPTION("Digital potentiometer driver");
771 MODULE_LICENSE("GPL");