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 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 #define DRIVER_VERSION "0.2"
81 #include "ad525x_dpot.h"
84 * Client data (each client gets its own)
88 struct ad_dpot_bus_data bdata
;
89 struct mutex update_lock
;
96 u16 rdac_cache
[MAX_RDACS
];
97 DECLARE_BITMAP(otp_en_mask
, MAX_RDACS
);
100 static inline int dpot_read_d8(struct dpot_data
*dpot
)
102 return dpot
->bdata
.bops
->read_d8(dpot
->bdata
.client
);
105 static inline int dpot_read_r8d8(struct dpot_data
*dpot
, u8 reg
)
107 return dpot
->bdata
.bops
->read_r8d8(dpot
->bdata
.client
, reg
);
110 static inline int dpot_read_r8d16(struct dpot_data
*dpot
, u8 reg
)
112 return dpot
->bdata
.bops
->read_r8d16(dpot
->bdata
.client
, reg
);
115 static inline int dpot_write_d8(struct dpot_data
*dpot
, u8 val
)
117 return dpot
->bdata
.bops
->write_d8(dpot
->bdata
.client
, val
);
120 static inline int dpot_write_r8d8(struct dpot_data
*dpot
, u8 reg
, u16 val
)
122 return dpot
->bdata
.bops
->write_r8d8(dpot
->bdata
.client
, reg
, val
);
125 static inline int dpot_write_r8d16(struct dpot_data
*dpot
, u8 reg
, u16 val
)
127 return dpot
->bdata
.bops
->write_r8d16(dpot
->bdata
.client
, reg
, val
);
130 static s32
dpot_read_spi(struct dpot_data
*dpot
, u8 reg
)
135 if (!(reg
& (DPOT_ADDR_EEPROM
| DPOT_ADDR_CMD
))) {
137 if (dpot
->feat
& F_RDACS_WONLY
)
138 return dpot
->rdac_cache
[reg
& DPOT_RDAC_MASK
];
139 if (dpot
->uid
== DPOT_UID(AD5291_ID
) ||
140 dpot
->uid
== DPOT_UID(AD5292_ID
) ||
141 dpot
->uid
== DPOT_UID(AD5293_ID
)) {
143 value
= dpot_read_r8d8(dpot
,
144 DPOT_AD5291_READ_RDAC
<< 2);
146 if (dpot
->uid
== DPOT_UID(AD5291_ID
))
150 } else if (dpot
->uid
== DPOT_UID(AD5270_ID
) ||
151 dpot
->uid
== DPOT_UID(AD5271_ID
)) {
153 value
= dpot_read_r8d8(dpot
,
154 DPOT_AD5270_1_2_4_READ_RDAC
<< 2);
159 if (dpot
->uid
== DPOT_UID(AD5271_ID
))
165 ctrl
= DPOT_SPI_READ_RDAC
;
166 } else if (reg
& DPOT_ADDR_EEPROM
) {
167 ctrl
= DPOT_SPI_READ_EEPROM
;
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
);
178 static s32
dpot_read_i2c(struct dpot_data
*dpot
, u8 reg
)
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
):
189 case DPOT_UID(AD5243_ID
):
190 case DPOT_UID(AD5248_ID
):
191 case DPOT_UID(AD5280_ID
):
192 case DPOT_UID(AD5282_ID
):
193 ctrl
= ((reg
& DPOT_RDAC_MASK
) == DPOT_RDAC0
) ?
194 0 : DPOT_AD5282_RDAC_AB
;
195 return dpot_read_r8d8(dpot
, ctrl
);
196 case DPOT_UID(AD5170_ID
):
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);
210 value
= dpot_read_r8d16(dpot
,
211 DPOT_AD5270_1_2_4_RDAC
<< 2);
216 * AD5272/AD5274 returns high byte first, however
217 * underling smbus expects low byte first.
219 value
= swab16(value
);
221 if (dpot
->uid
== DPOT_UID(AD5271_ID
))
225 if ((reg
& DPOT_REG_TOL
) || (dpot
->max_pos
> 256))
226 return dpot_read_r8d16(dpot
, (reg
& 0xF8) |
229 return dpot_read_r8d8(dpot
, reg
);
233 static s32
dpot_read(struct dpot_data
*dpot
, u8 reg
)
235 if (dpot
->feat
& F_SPI
)
236 return dpot_read_spi(dpot
, reg
);
238 return dpot_read_i2c(dpot
, reg
);
241 static s32
dpot_write_spi(struct dpot_data
*dpot
, u8 reg
, u16 value
)
245 if (!(reg
& (DPOT_ADDR_EEPROM
| DPOT_ADDR_CMD
| DPOT_ADDR_OTP
))) {
246 if (dpot
->feat
& F_RDACS_WONLY
)
247 dpot
->rdac_cache
[reg
& DPOT_RDAC_MASK
] = value
;
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
)) |
254 return dpot_write_d8(dpot
, val
);
255 } else if (dpot
->feat
& F_SPI_16BIT
) {
256 val
= ((reg
& DPOT_RDAC_MASK
) <<
257 DPOT_MAX_POS(dpot
->devid
)) |
259 return dpot_write_r8d8(dpot
, val
>> 8,
264 if (dpot
->uid
== DPOT_UID(AD5291_ID
) ||
265 dpot
->uid
== DPOT_UID(AD5292_ID
) ||
266 dpot
->uid
== DPOT_UID(AD5293_ID
)) {
268 dpot_write_r8d8(dpot
, DPOT_AD5291_CTRLREG
<< 2,
269 DPOT_AD5291_UNLOCK_CMD
);
271 if (dpot
->uid
== DPOT_UID(AD5291_ID
))
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
);
283 if (dpot
->uid
== DPOT_UID(AD5271_ID
))
286 return dpot_write_r8d8(dpot
,
287 (DPOT_AD5270_1_2_4_RDAC
<< 2) |
288 (value
>> 8), value
& 0xFF);
290 val
= DPOT_SPI_RDAC
| (reg
& DPOT_RDAC_MASK
);
292 } else if (reg
& DPOT_ADDR_EEPROM
) {
293 val
= DPOT_SPI_EEPROM
| (reg
& DPOT_RDAC_MASK
);
294 } else if (reg
& DPOT_ADDR_CMD
) {
296 case DPOT_DEC_ALL_6DB
:
297 val
= DPOT_SPI_DEC_ALL_6DB
;
299 case DPOT_INC_ALL_6DB
:
300 val
= DPOT_SPI_INC_ALL_6DB
;
303 val
= DPOT_SPI_DEC_ALL
;
306 val
= DPOT_SPI_INC_ALL
;
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);
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
);
330 static s32
dpot_write_i2c(struct dpot_data
*dpot
, u8 reg
, u16 value
)
332 /* Only write the instruction byte for certain commands */
333 unsigned tmp
= 0, ctrl
= 0;
336 case DPOT_UID(AD5246_ID
):
337 case DPOT_UID(AD5247_ID
):
338 return dpot_write_d8(dpot
, value
);
341 case DPOT_UID(AD5245_ID
):
342 case DPOT_UID(AD5241_ID
):
343 case DPOT_UID(AD5242_ID
):
344 case DPOT_UID(AD5243_ID
):
345 case DPOT_UID(AD5248_ID
):
346 case DPOT_UID(AD5280_ID
):
347 case DPOT_UID(AD5282_ID
):
348 ctrl
= ((reg
& DPOT_RDAC_MASK
) == DPOT_RDAC0
) ?
349 0 : DPOT_AD5282_RDAC_AB
;
350 return dpot_write_r8d8(dpot
, ctrl
, value
);
352 case DPOT_UID(AD5171_ID
):
353 case DPOT_UID(AD5273_ID
):
354 if (reg
& DPOT_ADDR_OTP
) {
355 tmp
= dpot_read_d8(dpot
);
356 if (tmp
>> 6) /* Ready to Program? */
358 ctrl
= DPOT_AD5273_FUSE
;
360 return dpot_write_r8d8(dpot
, ctrl
, value
);
362 case DPOT_UID(AD5172_ID
):
363 case DPOT_UID(AD5173_ID
):
364 ctrl
= ((reg
& DPOT_RDAC_MASK
) == DPOT_RDAC0
) ?
365 0 : DPOT_AD5172_3_A0
;
366 if (reg
& DPOT_ADDR_OTP
) {
367 tmp
= dpot_read_r8d16(dpot
, ctrl
);
368 if (tmp
>> 14) /* Ready to Program? */
370 ctrl
|= DPOT_AD5170_2_3_FUSE
;
372 return dpot_write_r8d8(dpot
, ctrl
, value
);
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? */
379 ctrl
= DPOT_AD5170_2_3_FUSE
;
381 return dpot_write_r8d8(dpot
, ctrl
, value
);
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
);
388 if (reg
& DPOT_ADDR_OTP
)
389 return dpot_write_r8d8(dpot
,
390 DPOT_AD5270_1_2_4_STORE_XTPM
<< 2, 0);
392 if (dpot
->uid
== DPOT_UID(AD5274_ID
))
395 return dpot_write_r8d8(dpot
, (DPOT_AD5270_1_2_4_RDAC
<< 2) |
396 (value
>> 8), value
& 0xFF);
399 if (reg
& DPOT_ADDR_CMD
)
400 return dpot_write_d8(dpot
, reg
);
402 if (dpot
->max_pos
> 256)
403 return dpot_write_r8d16(dpot
, (reg
& 0xF8) |
404 ((reg
& 0x7) << 1), value
);
406 /* All other registers require instruction + data bytes */
407 return dpot_write_r8d8(dpot
, reg
, value
);
411 static s32
dpot_write(struct dpot_data
*dpot
, u8 reg
, u16 value
)
413 if (dpot
->feat
& F_SPI
)
414 return dpot_write_spi(dpot
, reg
, value
);
416 return dpot_write_i2c(dpot
, reg
, value
);
419 /* sysfs functions */
421 static ssize_t
sysfs_show_reg(struct device
*dev
,
422 struct device_attribute
*attr
,
425 struct dpot_data
*data
= dev_get_drvdata(dev
);
428 if (reg
& DPOT_ADDR_OTP_EN
)
429 return sprintf(buf
, "%s\n",
430 test_bit(DPOT_RDAC_MASK
& reg
, data
->otp_en_mask
) ?
431 "enabled" : "disabled");
434 mutex_lock(&data
->update_lock
);
435 value
= dpot_read(data
, reg
);
436 mutex_unlock(&data
->update_lock
);
441 * Let someone else deal with converting this ...
442 * the tolerance is a two-byte value where the MSB
443 * is a sign + integer value, and the LSB is a
444 * decimal value. See page 18 of the AD5258
445 * datasheet (Rev. A) for more details.
448 if (reg
& DPOT_REG_TOL
)
449 return sprintf(buf
, "0x%04x\n", value
& 0xFFFF);
451 return sprintf(buf
, "%u\n", value
& data
->rdac_mask
);
454 static ssize_t
sysfs_set_reg(struct device
*dev
,
455 struct device_attribute
*attr
,
456 const char *buf
, size_t count
, u32 reg
)
458 struct dpot_data
*data
= dev_get_drvdata(dev
);
462 if (reg
& DPOT_ADDR_OTP_EN
) {
463 if (!strncmp(buf
, "enabled", sizeof("enabled")))
464 set_bit(DPOT_RDAC_MASK
& reg
, data
->otp_en_mask
);
466 clear_bit(DPOT_RDAC_MASK
& reg
, data
->otp_en_mask
);
471 if ((reg
& DPOT_ADDR_OTP
) &&
472 !test_bit(DPOT_RDAC_MASK
& reg
, data
->otp_en_mask
))
475 err
= strict_strtoul(buf
, 10, &value
);
479 if (value
> data
->rdac_mask
)
480 value
= data
->rdac_mask
;
482 mutex_lock(&data
->update_lock
);
483 dpot_write(data
, reg
, value
);
484 if (reg
& DPOT_ADDR_EEPROM
)
485 msleep(26); /* Sleep while the EEPROM updates */
486 else if (reg
& DPOT_ADDR_OTP
)
487 msleep(400); /* Sleep while the OTP updates */
488 mutex_unlock(&data
->update_lock
);
493 static ssize_t
sysfs_do_cmd(struct device
*dev
,
494 struct device_attribute
*attr
,
495 const char *buf
, size_t count
, u32 reg
)
497 struct dpot_data
*data
= dev_get_drvdata(dev
);
499 mutex_lock(&data
->update_lock
);
500 dpot_write(data
, reg
, 0);
501 mutex_unlock(&data
->update_lock
);
506 /* ------------------------------------------------------------------------- */
508 #define DPOT_DEVICE_SHOW(_name, _reg) static ssize_t \
509 show_##_name(struct device *dev, \
510 struct device_attribute *attr, char *buf) \
512 return sysfs_show_reg(dev, attr, buf, _reg); \
515 #define DPOT_DEVICE_SET(_name, _reg) static ssize_t \
516 set_##_name(struct device *dev, \
517 struct device_attribute *attr, \
518 const char *buf, size_t count) \
520 return sysfs_set_reg(dev, attr, buf, count, _reg); \
523 #define DPOT_DEVICE_SHOW_SET(name, reg) \
524 DPOT_DEVICE_SHOW(name, reg) \
525 DPOT_DEVICE_SET(name, reg) \
526 static DEVICE_ATTR(name, S_IWUSR | S_IRUGO, show_##name, set_##name);
528 #define DPOT_DEVICE_SHOW_ONLY(name, reg) \
529 DPOT_DEVICE_SHOW(name, reg) \
530 static DEVICE_ATTR(name, S_IWUSR | S_IRUGO, show_##name, NULL);
532 DPOT_DEVICE_SHOW_SET(rdac0
, DPOT_ADDR_RDAC
| DPOT_RDAC0
);
533 DPOT_DEVICE_SHOW_SET(eeprom0
, DPOT_ADDR_EEPROM
| DPOT_RDAC0
);
534 DPOT_DEVICE_SHOW_ONLY(tolerance0
, DPOT_ADDR_EEPROM
| DPOT_TOL_RDAC0
);
535 DPOT_DEVICE_SHOW_SET(otp0
, DPOT_ADDR_OTP
| DPOT_RDAC0
);
536 DPOT_DEVICE_SHOW_SET(otp0en
, DPOT_ADDR_OTP_EN
| DPOT_RDAC0
);
538 DPOT_DEVICE_SHOW_SET(rdac1
, DPOT_ADDR_RDAC
| DPOT_RDAC1
);
539 DPOT_DEVICE_SHOW_SET(eeprom1
, DPOT_ADDR_EEPROM
| DPOT_RDAC1
);
540 DPOT_DEVICE_SHOW_ONLY(tolerance1
, DPOT_ADDR_EEPROM
| DPOT_TOL_RDAC1
);
541 DPOT_DEVICE_SHOW_SET(otp1
, DPOT_ADDR_OTP
| DPOT_RDAC1
);
542 DPOT_DEVICE_SHOW_SET(otp1en
, DPOT_ADDR_OTP_EN
| DPOT_RDAC1
);
544 DPOT_DEVICE_SHOW_SET(rdac2
, DPOT_ADDR_RDAC
| DPOT_RDAC2
);
545 DPOT_DEVICE_SHOW_SET(eeprom2
, DPOT_ADDR_EEPROM
| DPOT_RDAC2
);
546 DPOT_DEVICE_SHOW_ONLY(tolerance2
, DPOT_ADDR_EEPROM
| DPOT_TOL_RDAC2
);
547 DPOT_DEVICE_SHOW_SET(otp2
, DPOT_ADDR_OTP
| DPOT_RDAC2
);
548 DPOT_DEVICE_SHOW_SET(otp2en
, DPOT_ADDR_OTP_EN
| DPOT_RDAC2
);
550 DPOT_DEVICE_SHOW_SET(rdac3
, DPOT_ADDR_RDAC
| DPOT_RDAC3
);
551 DPOT_DEVICE_SHOW_SET(eeprom3
, DPOT_ADDR_EEPROM
| DPOT_RDAC3
);
552 DPOT_DEVICE_SHOW_ONLY(tolerance3
, DPOT_ADDR_EEPROM
| DPOT_TOL_RDAC3
);
553 DPOT_DEVICE_SHOW_SET(otp3
, DPOT_ADDR_OTP
| DPOT_RDAC3
);
554 DPOT_DEVICE_SHOW_SET(otp3en
, DPOT_ADDR_OTP_EN
| DPOT_RDAC3
);
556 DPOT_DEVICE_SHOW_SET(rdac4
, DPOT_ADDR_RDAC
| DPOT_RDAC4
);
557 DPOT_DEVICE_SHOW_SET(eeprom4
, DPOT_ADDR_EEPROM
| DPOT_RDAC4
);
558 DPOT_DEVICE_SHOW_ONLY(tolerance4
, DPOT_ADDR_EEPROM
| DPOT_TOL_RDAC4
);
559 DPOT_DEVICE_SHOW_SET(otp4
, DPOT_ADDR_OTP
| DPOT_RDAC4
);
560 DPOT_DEVICE_SHOW_SET(otp4en
, DPOT_ADDR_OTP_EN
| DPOT_RDAC4
);
562 DPOT_DEVICE_SHOW_SET(rdac5
, DPOT_ADDR_RDAC
| DPOT_RDAC5
);
563 DPOT_DEVICE_SHOW_SET(eeprom5
, DPOT_ADDR_EEPROM
| DPOT_RDAC5
);
564 DPOT_DEVICE_SHOW_ONLY(tolerance5
, DPOT_ADDR_EEPROM
| DPOT_TOL_RDAC5
);
565 DPOT_DEVICE_SHOW_SET(otp5
, DPOT_ADDR_OTP
| DPOT_RDAC5
);
566 DPOT_DEVICE_SHOW_SET(otp5en
, DPOT_ADDR_OTP_EN
| DPOT_RDAC5
);
568 static const struct attribute
*dpot_attrib_wipers
[] = {
569 &dev_attr_rdac0
.attr
,
570 &dev_attr_rdac1
.attr
,
571 &dev_attr_rdac2
.attr
,
572 &dev_attr_rdac3
.attr
,
573 &dev_attr_rdac4
.attr
,
574 &dev_attr_rdac5
.attr
,
578 static const struct attribute
*dpot_attrib_eeprom
[] = {
579 &dev_attr_eeprom0
.attr
,
580 &dev_attr_eeprom1
.attr
,
581 &dev_attr_eeprom2
.attr
,
582 &dev_attr_eeprom3
.attr
,
583 &dev_attr_eeprom4
.attr
,
584 &dev_attr_eeprom5
.attr
,
588 static const struct attribute
*dpot_attrib_otp
[] = {
598 static const struct attribute
*dpot_attrib_otp_en
[] = {
599 &dev_attr_otp0en
.attr
,
600 &dev_attr_otp1en
.attr
,
601 &dev_attr_otp2en
.attr
,
602 &dev_attr_otp3en
.attr
,
603 &dev_attr_otp4en
.attr
,
604 &dev_attr_otp5en
.attr
,
608 static const struct attribute
*dpot_attrib_tolerance
[] = {
609 &dev_attr_tolerance0
.attr
,
610 &dev_attr_tolerance1
.attr
,
611 &dev_attr_tolerance2
.attr
,
612 &dev_attr_tolerance3
.attr
,
613 &dev_attr_tolerance4
.attr
,
614 &dev_attr_tolerance5
.attr
,
618 /* ------------------------------------------------------------------------- */
620 #define DPOT_DEVICE_DO_CMD(_name, _cmd) static ssize_t \
621 set_##_name(struct device *dev, \
622 struct device_attribute *attr, \
623 const char *buf, size_t count) \
625 return sysfs_do_cmd(dev, attr, buf, count, _cmd); \
627 static DEVICE_ATTR(_name, S_IWUSR | S_IRUGO, NULL, set_##_name);
629 DPOT_DEVICE_DO_CMD(inc_all
, DPOT_INC_ALL
);
630 DPOT_DEVICE_DO_CMD(dec_all
, DPOT_DEC_ALL
);
631 DPOT_DEVICE_DO_CMD(inc_all_6db
, DPOT_INC_ALL_6DB
);
632 DPOT_DEVICE_DO_CMD(dec_all_6db
, DPOT_DEC_ALL_6DB
);
634 static struct attribute
*ad525x_attributes_commands
[] = {
635 &dev_attr_inc_all
.attr
,
636 &dev_attr_dec_all
.attr
,
637 &dev_attr_inc_all_6db
.attr
,
638 &dev_attr_dec_all_6db
.attr
,
642 static const struct attribute_group ad525x_group_commands
= {
643 .attrs
= ad525x_attributes_commands
,
646 __devinit
int ad_dpot_add_files(struct device
*dev
,
647 unsigned features
, unsigned rdac
)
649 int err
= sysfs_create_file(&dev
->kobj
,
650 dpot_attrib_wipers
[rdac
]);
651 if (features
& F_CMD_EEP
)
652 err
|= sysfs_create_file(&dev
->kobj
,
653 dpot_attrib_eeprom
[rdac
]);
654 if (features
& F_CMD_TOL
)
655 err
|= sysfs_create_file(&dev
->kobj
,
656 dpot_attrib_tolerance
[rdac
]);
657 if (features
& F_CMD_OTP
) {
658 err
|= sysfs_create_file(&dev
->kobj
,
659 dpot_attrib_otp_en
[rdac
]);
660 err
|= sysfs_create_file(&dev
->kobj
,
661 dpot_attrib_otp
[rdac
]);
665 dev_err(dev
, "failed to register sysfs hooks for RDAC%d\n",
671 inline void ad_dpot_remove_files(struct device
*dev
,
672 unsigned features
, unsigned rdac
)
674 sysfs_remove_file(&dev
->kobj
,
675 dpot_attrib_wipers
[rdac
]);
676 if (features
& F_CMD_EEP
)
677 sysfs_remove_file(&dev
->kobj
,
678 dpot_attrib_eeprom
[rdac
]);
679 if (features
& F_CMD_TOL
)
680 sysfs_remove_file(&dev
->kobj
,
681 dpot_attrib_tolerance
[rdac
]);
682 if (features
& F_CMD_OTP
) {
683 sysfs_remove_file(&dev
->kobj
,
684 dpot_attrib_otp_en
[rdac
]);
685 sysfs_remove_file(&dev
->kobj
,
686 dpot_attrib_otp
[rdac
]);
690 __devinit
int ad_dpot_probe(struct device
*dev
,
691 struct ad_dpot_bus_data
*bdata
, const struct ad_dpot_id
*id
)
694 struct dpot_data
*data
;
697 data
= kzalloc(sizeof(struct dpot_data
), GFP_KERNEL
);
703 dev_set_drvdata(dev
, data
);
704 mutex_init(&data
->update_lock
);
706 data
->bdata
= *bdata
;
707 data
->devid
= id
->devid
;
709 data
->max_pos
= 1 << DPOT_MAX_POS(data
->devid
);
710 data
->rdac_mask
= data
->max_pos
- 1;
711 data
->feat
= DPOT_FEAT(data
->devid
);
712 data
->uid
= DPOT_UID(data
->devid
);
713 data
->wipers
= DPOT_WIPERS(data
->devid
);
715 for (i
= DPOT_RDAC0
; i
< MAX_RDACS
; i
++)
716 if (data
->wipers
& (1 << i
)) {
717 err
= ad_dpot_add_files(dev
, data
->feat
, i
);
719 goto exit_remove_files
;
720 /* power-up midscale */
721 if (data
->feat
& F_RDACS_WONLY
)
722 data
->rdac_cache
[i
] = data
->max_pos
/ 2;
725 if (data
->feat
& F_CMD_INC
)
726 err
= sysfs_create_group(&dev
->kobj
, &ad525x_group_commands
);
729 dev_err(dev
, "failed to register sysfs hooks\n");
733 dev_info(dev
, "%s %d-Position Digital Potentiometer registered\n",
734 id
->name
, data
->max_pos
);
739 for (i
= DPOT_RDAC0
; i
< MAX_RDACS
; i
++)
740 if (data
->wipers
& (1 << i
))
741 ad_dpot_remove_files(dev
, data
->feat
, i
);
745 dev_set_drvdata(dev
, NULL
);
747 dev_err(dev
, "failed to create client for %s ID 0x%lX\n",
748 id
->name
, id
->devid
);
751 EXPORT_SYMBOL(ad_dpot_probe
);
753 __devexit
int ad_dpot_remove(struct device
*dev
)
755 struct dpot_data
*data
= dev_get_drvdata(dev
);
758 for (i
= DPOT_RDAC0
; i
< MAX_RDACS
; i
++)
759 if (data
->wipers
& (1 << i
))
760 ad_dpot_remove_files(dev
, data
->feat
, i
);
766 EXPORT_SYMBOL(ad_dpot_remove
);
769 MODULE_AUTHOR("Chris Verges <chrisv@cyberswitching.com>, "
770 "Michael Hennerich <hennerich@blackfin.uclinux.org>");
771 MODULE_DESCRIPTION("Digital potentiometer driver");
772 MODULE_LICENSE("GPL");
773 MODULE_VERSION(DRIVER_VERSION
);