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/delay.h>
76 #include <linux/slab.h>
78 #include "ad525x_dpot.h"
81 * Client data (each client gets its own)
85 struct ad_dpot_bus_data bdata
;
86 struct mutex update_lock
;
93 u16 rdac_cache
[MAX_RDACS
];
94 DECLARE_BITMAP(otp_en_mask
, MAX_RDACS
);
97 static inline int dpot_read_d8(struct dpot_data
*dpot
)
99 return dpot
->bdata
.bops
->read_d8(dpot
->bdata
.client
);
102 static inline int dpot_read_r8d8(struct dpot_data
*dpot
, u8 reg
)
104 return dpot
->bdata
.bops
->read_r8d8(dpot
->bdata
.client
, reg
);
107 static inline int dpot_read_r8d16(struct dpot_data
*dpot
, u8 reg
)
109 return dpot
->bdata
.bops
->read_r8d16(dpot
->bdata
.client
, reg
);
112 static inline int dpot_write_d8(struct dpot_data
*dpot
, u8 val
)
114 return dpot
->bdata
.bops
->write_d8(dpot
->bdata
.client
, val
);
117 static inline int dpot_write_r8d8(struct dpot_data
*dpot
, u8 reg
, u16 val
)
119 return dpot
->bdata
.bops
->write_r8d8(dpot
->bdata
.client
, reg
, val
);
122 static inline int dpot_write_r8d16(struct dpot_data
*dpot
, u8 reg
, u16 val
)
124 return dpot
->bdata
.bops
->write_r8d16(dpot
->bdata
.client
, reg
, val
);
127 static s32
dpot_read_spi(struct dpot_data
*dpot
, u8 reg
)
132 if (!(reg
& (DPOT_ADDR_EEPROM
| DPOT_ADDR_CMD
))) {
134 if (dpot
->feat
& F_RDACS_WONLY
)
135 return dpot
->rdac_cache
[reg
& DPOT_RDAC_MASK
];
136 if (dpot
->uid
== DPOT_UID(AD5291_ID
) ||
137 dpot
->uid
== DPOT_UID(AD5292_ID
) ||
138 dpot
->uid
== DPOT_UID(AD5293_ID
)) {
140 value
= dpot_read_r8d8(dpot
,
141 DPOT_AD5291_READ_RDAC
<< 2);
143 if (dpot
->uid
== DPOT_UID(AD5291_ID
))
147 } else if (dpot
->uid
== DPOT_UID(AD5270_ID
) ||
148 dpot
->uid
== DPOT_UID(AD5271_ID
)) {
150 value
= dpot_read_r8d8(dpot
,
151 DPOT_AD5270_1_2_4_READ_RDAC
<< 2);
156 if (dpot
->uid
== DPOT_UID(AD5271_ID
))
162 ctrl
= DPOT_SPI_READ_RDAC
;
163 } else if (reg
& DPOT_ADDR_EEPROM
) {
164 ctrl
= DPOT_SPI_READ_EEPROM
;
167 if (dpot
->feat
& F_SPI_16BIT
)
168 return dpot_read_r8d8(dpot
, ctrl
);
169 else if (dpot
->feat
& F_SPI_24BIT
)
170 return dpot_read_r8d16(dpot
, ctrl
);
175 static s32
dpot_read_i2c(struct dpot_data
*dpot
, u8 reg
)
180 case DPOT_UID(AD5246_ID
):
181 case DPOT_UID(AD5247_ID
):
182 return dpot_read_d8(dpot
);
183 case DPOT_UID(AD5245_ID
):
184 case DPOT_UID(AD5241_ID
):
185 case DPOT_UID(AD5242_ID
):
186 case DPOT_UID(AD5243_ID
):
187 case DPOT_UID(AD5248_ID
):
188 case DPOT_UID(AD5280_ID
):
189 case DPOT_UID(AD5282_ID
):
190 ctrl
= ((reg
& DPOT_RDAC_MASK
) == DPOT_RDAC0
) ?
191 0 : DPOT_AD5282_RDAC_AB
;
192 return dpot_read_r8d8(dpot
, ctrl
);
193 case DPOT_UID(AD5170_ID
):
194 case DPOT_UID(AD5171_ID
):
195 case DPOT_UID(AD5273_ID
):
196 return dpot_read_d8(dpot
);
197 case DPOT_UID(AD5172_ID
):
198 case DPOT_UID(AD5173_ID
):
199 ctrl
= ((reg
& DPOT_RDAC_MASK
) == DPOT_RDAC0
) ?
200 0 : DPOT_AD5172_3_A0
;
201 return dpot_read_r8d8(dpot
, ctrl
);
202 case DPOT_UID(AD5272_ID
):
203 case DPOT_UID(AD5274_ID
):
204 dpot_write_r8d8(dpot
,
205 (DPOT_AD5270_1_2_4_READ_RDAC
<< 2), 0);
207 value
= dpot_read_r8d16(dpot
,
208 DPOT_AD5270_1_2_4_RDAC
<< 2);
213 * AD5272/AD5274 returns high byte first, however
214 * underling smbus expects low byte first.
216 value
= swab16(value
);
218 if (dpot
->uid
== DPOT_UID(AD5271_ID
))
222 if ((reg
& DPOT_REG_TOL
) || (dpot
->max_pos
> 256))
223 return dpot_read_r8d16(dpot
, (reg
& 0xF8) |
226 return dpot_read_r8d8(dpot
, reg
);
230 static s32
dpot_read(struct dpot_data
*dpot
, u8 reg
)
232 if (dpot
->feat
& F_SPI
)
233 return dpot_read_spi(dpot
, reg
);
235 return dpot_read_i2c(dpot
, reg
);
238 static s32
dpot_write_spi(struct dpot_data
*dpot
, u8 reg
, u16 value
)
242 if (!(reg
& (DPOT_ADDR_EEPROM
| DPOT_ADDR_CMD
| DPOT_ADDR_OTP
))) {
243 if (dpot
->feat
& F_RDACS_WONLY
)
244 dpot
->rdac_cache
[reg
& DPOT_RDAC_MASK
] = value
;
246 if (dpot
->feat
& F_AD_APPDATA
) {
247 if (dpot
->feat
& F_SPI_8BIT
) {
248 val
= ((reg
& DPOT_RDAC_MASK
) <<
249 DPOT_MAX_POS(dpot
->devid
)) |
251 return dpot_write_d8(dpot
, val
);
252 } else if (dpot
->feat
& F_SPI_16BIT
) {
253 val
= ((reg
& DPOT_RDAC_MASK
) <<
254 DPOT_MAX_POS(dpot
->devid
)) |
256 return dpot_write_r8d8(dpot
, val
>> 8,
261 if (dpot
->uid
== DPOT_UID(AD5291_ID
) ||
262 dpot
->uid
== DPOT_UID(AD5292_ID
) ||
263 dpot
->uid
== DPOT_UID(AD5293_ID
)) {
265 dpot_write_r8d8(dpot
, DPOT_AD5291_CTRLREG
<< 2,
266 DPOT_AD5291_UNLOCK_CMD
);
268 if (dpot
->uid
== DPOT_UID(AD5291_ID
))
271 return dpot_write_r8d8(dpot
,
272 (DPOT_AD5291_RDAC
<< 2) |
273 (value
>> 8), value
& 0xFF);
274 } else if (dpot
->uid
== DPOT_UID(AD5270_ID
) ||
275 dpot
->uid
== DPOT_UID(AD5271_ID
)) {
276 dpot_write_r8d8(dpot
,
277 DPOT_AD5270_1_2_4_CTRLREG
<< 2,
278 DPOT_AD5270_1_2_4_UNLOCK_CMD
);
280 if (dpot
->uid
== DPOT_UID(AD5271_ID
))
283 return dpot_write_r8d8(dpot
,
284 (DPOT_AD5270_1_2_4_RDAC
<< 2) |
285 (value
>> 8), value
& 0xFF);
287 val
= DPOT_SPI_RDAC
| (reg
& DPOT_RDAC_MASK
);
289 } else if (reg
& DPOT_ADDR_EEPROM
) {
290 val
= DPOT_SPI_EEPROM
| (reg
& DPOT_RDAC_MASK
);
291 } else if (reg
& DPOT_ADDR_CMD
) {
293 case DPOT_DEC_ALL_6DB
:
294 val
= DPOT_SPI_DEC_ALL_6DB
;
296 case DPOT_INC_ALL_6DB
:
297 val
= DPOT_SPI_INC_ALL_6DB
;
300 val
= DPOT_SPI_DEC_ALL
;
303 val
= DPOT_SPI_INC_ALL
;
306 } else if (reg
& DPOT_ADDR_OTP
) {
307 if (dpot
->uid
== DPOT_UID(AD5291_ID
) ||
308 dpot
->uid
== DPOT_UID(AD5292_ID
)) {
309 return dpot_write_r8d8(dpot
,
310 DPOT_AD5291_STORE_XTPM
<< 2, 0);
311 } else if (dpot
->uid
== DPOT_UID(AD5270_ID
) ||
312 dpot
->uid
== DPOT_UID(AD5271_ID
)) {
313 return dpot_write_r8d8(dpot
,
314 DPOT_AD5270_1_2_4_STORE_XTPM
<< 2, 0);
319 if (dpot
->feat
& F_SPI_16BIT
)
320 return dpot_write_r8d8(dpot
, val
, value
);
321 else if (dpot
->feat
& F_SPI_24BIT
)
322 return dpot_write_r8d16(dpot
, val
, value
);
327 static s32
dpot_write_i2c(struct dpot_data
*dpot
, u8 reg
, u16 value
)
329 /* Only write the instruction byte for certain commands */
330 unsigned tmp
= 0, ctrl
= 0;
333 case DPOT_UID(AD5246_ID
):
334 case DPOT_UID(AD5247_ID
):
335 return dpot_write_d8(dpot
, value
);
338 case DPOT_UID(AD5245_ID
):
339 case DPOT_UID(AD5241_ID
):
340 case DPOT_UID(AD5242_ID
):
341 case DPOT_UID(AD5243_ID
):
342 case DPOT_UID(AD5248_ID
):
343 case DPOT_UID(AD5280_ID
):
344 case DPOT_UID(AD5282_ID
):
345 ctrl
= ((reg
& DPOT_RDAC_MASK
) == DPOT_RDAC0
) ?
346 0 : DPOT_AD5282_RDAC_AB
;
347 return dpot_write_r8d8(dpot
, ctrl
, value
);
349 case DPOT_UID(AD5171_ID
):
350 case DPOT_UID(AD5273_ID
):
351 if (reg
& DPOT_ADDR_OTP
) {
352 tmp
= dpot_read_d8(dpot
);
353 if (tmp
>> 6) /* Ready to Program? */
355 ctrl
= DPOT_AD5273_FUSE
;
357 return dpot_write_r8d8(dpot
, ctrl
, value
);
359 case DPOT_UID(AD5172_ID
):
360 case DPOT_UID(AD5173_ID
):
361 ctrl
= ((reg
& DPOT_RDAC_MASK
) == DPOT_RDAC0
) ?
362 0 : DPOT_AD5172_3_A0
;
363 if (reg
& DPOT_ADDR_OTP
) {
364 tmp
= dpot_read_r8d16(dpot
, ctrl
);
365 if (tmp
>> 14) /* Ready to Program? */
367 ctrl
|= DPOT_AD5170_2_3_FUSE
;
369 return dpot_write_r8d8(dpot
, ctrl
, value
);
371 case DPOT_UID(AD5170_ID
):
372 if (reg
& DPOT_ADDR_OTP
) {
373 tmp
= dpot_read_r8d16(dpot
, tmp
);
374 if (tmp
>> 14) /* Ready to Program? */
376 ctrl
= DPOT_AD5170_2_3_FUSE
;
378 return dpot_write_r8d8(dpot
, ctrl
, value
);
380 case DPOT_UID(AD5272_ID
):
381 case DPOT_UID(AD5274_ID
):
382 dpot_write_r8d8(dpot
, DPOT_AD5270_1_2_4_CTRLREG
<< 2,
383 DPOT_AD5270_1_2_4_UNLOCK_CMD
);
385 if (reg
& DPOT_ADDR_OTP
)
386 return dpot_write_r8d8(dpot
,
387 DPOT_AD5270_1_2_4_STORE_XTPM
<< 2, 0);
389 if (dpot
->uid
== DPOT_UID(AD5274_ID
))
392 return dpot_write_r8d8(dpot
, (DPOT_AD5270_1_2_4_RDAC
<< 2) |
393 (value
>> 8), value
& 0xFF);
396 if (reg
& DPOT_ADDR_CMD
)
397 return dpot_write_d8(dpot
, reg
);
399 if (dpot
->max_pos
> 256)
400 return dpot_write_r8d16(dpot
, (reg
& 0xF8) |
401 ((reg
& 0x7) << 1), value
);
403 /* All other registers require instruction + data bytes */
404 return dpot_write_r8d8(dpot
, reg
, value
);
408 static s32
dpot_write(struct dpot_data
*dpot
, u8 reg
, u16 value
)
410 if (dpot
->feat
& F_SPI
)
411 return dpot_write_spi(dpot
, reg
, value
);
413 return dpot_write_i2c(dpot
, reg
, value
);
416 /* sysfs functions */
418 static ssize_t
sysfs_show_reg(struct device
*dev
,
419 struct device_attribute
*attr
,
422 struct dpot_data
*data
= dev_get_drvdata(dev
);
425 if (reg
& DPOT_ADDR_OTP_EN
)
426 return sprintf(buf
, "%s\n",
427 test_bit(DPOT_RDAC_MASK
& reg
, data
->otp_en_mask
) ?
428 "enabled" : "disabled");
431 mutex_lock(&data
->update_lock
);
432 value
= dpot_read(data
, reg
);
433 mutex_unlock(&data
->update_lock
);
438 * Let someone else deal with converting this ...
439 * the tolerance is a two-byte value where the MSB
440 * is a sign + integer value, and the LSB is a
441 * decimal value. See page 18 of the AD5258
442 * datasheet (Rev. A) for more details.
445 if (reg
& DPOT_REG_TOL
)
446 return sprintf(buf
, "0x%04x\n", value
& 0xFFFF);
448 return sprintf(buf
, "%u\n", value
& data
->rdac_mask
);
451 static ssize_t
sysfs_set_reg(struct device
*dev
,
452 struct device_attribute
*attr
,
453 const char *buf
, size_t count
, u32 reg
)
455 struct dpot_data
*data
= dev_get_drvdata(dev
);
459 if (reg
& DPOT_ADDR_OTP_EN
) {
460 if (!strncmp(buf
, "enabled", sizeof("enabled")))
461 set_bit(DPOT_RDAC_MASK
& reg
, data
->otp_en_mask
);
463 clear_bit(DPOT_RDAC_MASK
& reg
, data
->otp_en_mask
);
468 if ((reg
& DPOT_ADDR_OTP
) &&
469 !test_bit(DPOT_RDAC_MASK
& reg
, data
->otp_en_mask
))
472 err
= kstrtoul(buf
, 10, &value
);
476 if (value
> data
->rdac_mask
)
477 value
= data
->rdac_mask
;
479 mutex_lock(&data
->update_lock
);
480 dpot_write(data
, reg
, value
);
481 if (reg
& DPOT_ADDR_EEPROM
)
482 msleep(26); /* Sleep while the EEPROM updates */
483 else if (reg
& DPOT_ADDR_OTP
)
484 msleep(400); /* Sleep while the OTP updates */
485 mutex_unlock(&data
->update_lock
);
490 static ssize_t
sysfs_do_cmd(struct device
*dev
,
491 struct device_attribute
*attr
,
492 const char *buf
, size_t count
, u32 reg
)
494 struct dpot_data
*data
= dev_get_drvdata(dev
);
496 mutex_lock(&data
->update_lock
);
497 dpot_write(data
, reg
, 0);
498 mutex_unlock(&data
->update_lock
);
503 /* ------------------------------------------------------------------------- */
505 #define DPOT_DEVICE_SHOW(_name, _reg) static ssize_t \
506 show_##_name(struct device *dev, \
507 struct device_attribute *attr, char *buf) \
509 return sysfs_show_reg(dev, attr, buf, _reg); \
512 #define DPOT_DEVICE_SET(_name, _reg) static ssize_t \
513 set_##_name(struct device *dev, \
514 struct device_attribute *attr, \
515 const char *buf, size_t count) \
517 return sysfs_set_reg(dev, attr, buf, count, _reg); \
520 #define DPOT_DEVICE_SHOW_SET(name, reg) \
521 DPOT_DEVICE_SHOW(name, reg) \
522 DPOT_DEVICE_SET(name, reg) \
523 static DEVICE_ATTR(name, S_IWUSR | S_IRUGO, show_##name, set_##name);
525 #define DPOT_DEVICE_SHOW_ONLY(name, reg) \
526 DPOT_DEVICE_SHOW(name, reg) \
527 static DEVICE_ATTR(name, S_IWUSR | S_IRUGO, show_##name, NULL);
529 DPOT_DEVICE_SHOW_SET(rdac0
, DPOT_ADDR_RDAC
| DPOT_RDAC0
);
530 DPOT_DEVICE_SHOW_SET(eeprom0
, DPOT_ADDR_EEPROM
| DPOT_RDAC0
);
531 DPOT_DEVICE_SHOW_ONLY(tolerance0
, DPOT_ADDR_EEPROM
| DPOT_TOL_RDAC0
);
532 DPOT_DEVICE_SHOW_SET(otp0
, DPOT_ADDR_OTP
| DPOT_RDAC0
);
533 DPOT_DEVICE_SHOW_SET(otp0en
, DPOT_ADDR_OTP_EN
| DPOT_RDAC0
);
535 DPOT_DEVICE_SHOW_SET(rdac1
, DPOT_ADDR_RDAC
| DPOT_RDAC1
);
536 DPOT_DEVICE_SHOW_SET(eeprom1
, DPOT_ADDR_EEPROM
| DPOT_RDAC1
);
537 DPOT_DEVICE_SHOW_ONLY(tolerance1
, DPOT_ADDR_EEPROM
| DPOT_TOL_RDAC1
);
538 DPOT_DEVICE_SHOW_SET(otp1
, DPOT_ADDR_OTP
| DPOT_RDAC1
);
539 DPOT_DEVICE_SHOW_SET(otp1en
, DPOT_ADDR_OTP_EN
| DPOT_RDAC1
);
541 DPOT_DEVICE_SHOW_SET(rdac2
, DPOT_ADDR_RDAC
| DPOT_RDAC2
);
542 DPOT_DEVICE_SHOW_SET(eeprom2
, DPOT_ADDR_EEPROM
| DPOT_RDAC2
);
543 DPOT_DEVICE_SHOW_ONLY(tolerance2
, DPOT_ADDR_EEPROM
| DPOT_TOL_RDAC2
);
544 DPOT_DEVICE_SHOW_SET(otp2
, DPOT_ADDR_OTP
| DPOT_RDAC2
);
545 DPOT_DEVICE_SHOW_SET(otp2en
, DPOT_ADDR_OTP_EN
| DPOT_RDAC2
);
547 DPOT_DEVICE_SHOW_SET(rdac3
, DPOT_ADDR_RDAC
| DPOT_RDAC3
);
548 DPOT_DEVICE_SHOW_SET(eeprom3
, DPOT_ADDR_EEPROM
| DPOT_RDAC3
);
549 DPOT_DEVICE_SHOW_ONLY(tolerance3
, DPOT_ADDR_EEPROM
| DPOT_TOL_RDAC3
);
550 DPOT_DEVICE_SHOW_SET(otp3
, DPOT_ADDR_OTP
| DPOT_RDAC3
);
551 DPOT_DEVICE_SHOW_SET(otp3en
, DPOT_ADDR_OTP_EN
| DPOT_RDAC3
);
553 DPOT_DEVICE_SHOW_SET(rdac4
, DPOT_ADDR_RDAC
| DPOT_RDAC4
);
554 DPOT_DEVICE_SHOW_SET(eeprom4
, DPOT_ADDR_EEPROM
| DPOT_RDAC4
);
555 DPOT_DEVICE_SHOW_ONLY(tolerance4
, DPOT_ADDR_EEPROM
| DPOT_TOL_RDAC4
);
556 DPOT_DEVICE_SHOW_SET(otp4
, DPOT_ADDR_OTP
| DPOT_RDAC4
);
557 DPOT_DEVICE_SHOW_SET(otp4en
, DPOT_ADDR_OTP_EN
| DPOT_RDAC4
);
559 DPOT_DEVICE_SHOW_SET(rdac5
, DPOT_ADDR_RDAC
| DPOT_RDAC5
);
560 DPOT_DEVICE_SHOW_SET(eeprom5
, DPOT_ADDR_EEPROM
| DPOT_RDAC5
);
561 DPOT_DEVICE_SHOW_ONLY(tolerance5
, DPOT_ADDR_EEPROM
| DPOT_TOL_RDAC5
);
562 DPOT_DEVICE_SHOW_SET(otp5
, DPOT_ADDR_OTP
| DPOT_RDAC5
);
563 DPOT_DEVICE_SHOW_SET(otp5en
, DPOT_ADDR_OTP_EN
| DPOT_RDAC5
);
565 static const struct attribute
*dpot_attrib_wipers
[] = {
566 &dev_attr_rdac0
.attr
,
567 &dev_attr_rdac1
.attr
,
568 &dev_attr_rdac2
.attr
,
569 &dev_attr_rdac3
.attr
,
570 &dev_attr_rdac4
.attr
,
571 &dev_attr_rdac5
.attr
,
575 static const struct attribute
*dpot_attrib_eeprom
[] = {
576 &dev_attr_eeprom0
.attr
,
577 &dev_attr_eeprom1
.attr
,
578 &dev_attr_eeprom2
.attr
,
579 &dev_attr_eeprom3
.attr
,
580 &dev_attr_eeprom4
.attr
,
581 &dev_attr_eeprom5
.attr
,
585 static const struct attribute
*dpot_attrib_otp
[] = {
595 static const struct attribute
*dpot_attrib_otp_en
[] = {
596 &dev_attr_otp0en
.attr
,
597 &dev_attr_otp1en
.attr
,
598 &dev_attr_otp2en
.attr
,
599 &dev_attr_otp3en
.attr
,
600 &dev_attr_otp4en
.attr
,
601 &dev_attr_otp5en
.attr
,
605 static const struct attribute
*dpot_attrib_tolerance
[] = {
606 &dev_attr_tolerance0
.attr
,
607 &dev_attr_tolerance1
.attr
,
608 &dev_attr_tolerance2
.attr
,
609 &dev_attr_tolerance3
.attr
,
610 &dev_attr_tolerance4
.attr
,
611 &dev_attr_tolerance5
.attr
,
615 /* ------------------------------------------------------------------------- */
617 #define DPOT_DEVICE_DO_CMD(_name, _cmd) static ssize_t \
618 set_##_name(struct device *dev, \
619 struct device_attribute *attr, \
620 const char *buf, size_t count) \
622 return sysfs_do_cmd(dev, attr, buf, count, _cmd); \
624 static DEVICE_ATTR(_name, S_IWUSR | S_IRUGO, NULL, set_##_name);
626 DPOT_DEVICE_DO_CMD(inc_all
, DPOT_INC_ALL
);
627 DPOT_DEVICE_DO_CMD(dec_all
, DPOT_DEC_ALL
);
628 DPOT_DEVICE_DO_CMD(inc_all_6db
, DPOT_INC_ALL_6DB
);
629 DPOT_DEVICE_DO_CMD(dec_all_6db
, DPOT_DEC_ALL_6DB
);
631 static struct attribute
*ad525x_attributes_commands
[] = {
632 &dev_attr_inc_all
.attr
,
633 &dev_attr_dec_all
.attr
,
634 &dev_attr_inc_all_6db
.attr
,
635 &dev_attr_dec_all_6db
.attr
,
639 static const struct attribute_group ad525x_group_commands
= {
640 .attrs
= ad525x_attributes_commands
,
643 static int ad_dpot_add_files(struct device
*dev
,
644 unsigned features
, unsigned rdac
)
646 int err
= sysfs_create_file(&dev
->kobj
,
647 dpot_attrib_wipers
[rdac
]);
648 if (features
& F_CMD_EEP
)
649 err
|= sysfs_create_file(&dev
->kobj
,
650 dpot_attrib_eeprom
[rdac
]);
651 if (features
& F_CMD_TOL
)
652 err
|= sysfs_create_file(&dev
->kobj
,
653 dpot_attrib_tolerance
[rdac
]);
654 if (features
& F_CMD_OTP
) {
655 err
|= sysfs_create_file(&dev
->kobj
,
656 dpot_attrib_otp_en
[rdac
]);
657 err
|= sysfs_create_file(&dev
->kobj
,
658 dpot_attrib_otp
[rdac
]);
662 dev_err(dev
, "failed to register sysfs hooks for RDAC%d\n",
668 static inline void ad_dpot_remove_files(struct device
*dev
,
669 unsigned features
, unsigned rdac
)
671 sysfs_remove_file(&dev
->kobj
,
672 dpot_attrib_wipers
[rdac
]);
673 if (features
& F_CMD_EEP
)
674 sysfs_remove_file(&dev
->kobj
,
675 dpot_attrib_eeprom
[rdac
]);
676 if (features
& F_CMD_TOL
)
677 sysfs_remove_file(&dev
->kobj
,
678 dpot_attrib_tolerance
[rdac
]);
679 if (features
& F_CMD_OTP
) {
680 sysfs_remove_file(&dev
->kobj
,
681 dpot_attrib_otp_en
[rdac
]);
682 sysfs_remove_file(&dev
->kobj
,
683 dpot_attrib_otp
[rdac
]);
687 int ad_dpot_probe(struct device
*dev
,
688 struct ad_dpot_bus_data
*bdata
, unsigned long devid
,
692 struct dpot_data
*data
;
695 data
= kzalloc(sizeof(struct dpot_data
), GFP_KERNEL
);
701 dev_set_drvdata(dev
, data
);
702 mutex_init(&data
->update_lock
);
704 data
->bdata
= *bdata
;
707 data
->max_pos
= 1 << DPOT_MAX_POS(devid
);
708 data
->rdac_mask
= data
->max_pos
- 1;
709 data
->feat
= DPOT_FEAT(devid
);
710 data
->uid
= DPOT_UID(devid
);
711 data
->wipers
= DPOT_WIPERS(devid
);
713 for (i
= DPOT_RDAC0
; i
< MAX_RDACS
; i
++)
714 if (data
->wipers
& (1 << i
)) {
715 err
= ad_dpot_add_files(dev
, data
->feat
, i
);
717 goto exit_remove_files
;
718 /* power-up midscale */
719 if (data
->feat
& F_RDACS_WONLY
)
720 data
->rdac_cache
[i
] = data
->max_pos
/ 2;
723 if (data
->feat
& F_CMD_INC
)
724 err
= sysfs_create_group(&dev
->kobj
, &ad525x_group_commands
);
727 dev_err(dev
, "failed to register sysfs hooks\n");
731 dev_info(dev
, "%s %d-Position Digital Potentiometer registered\n",
732 name
, data
->max_pos
);
737 for (i
= DPOT_RDAC0
; i
< MAX_RDACS
; i
++)
738 if (data
->wipers
& (1 << i
))
739 ad_dpot_remove_files(dev
, data
->feat
, i
);
743 dev_set_drvdata(dev
, NULL
);
745 dev_err(dev
, "failed to create client for %s ID 0x%lX\n",
749 EXPORT_SYMBOL(ad_dpot_probe
);
751 int ad_dpot_remove(struct device
*dev
)
753 struct dpot_data
*data
= dev_get_drvdata(dev
);
756 for (i
= DPOT_RDAC0
; i
< MAX_RDACS
; i
++)
757 if (data
->wipers
& (1 << i
))
758 ad_dpot_remove_files(dev
, data
->feat
, i
);
764 EXPORT_SYMBOL(ad_dpot_remove
);
767 MODULE_AUTHOR("Chris Verges <chrisv@cyberswitching.com>, "
768 "Michael Hennerich <hennerich@blackfin.uclinux.org>");
769 MODULE_DESCRIPTION("Digital potentiometer driver");
770 MODULE_LICENSE("GPL");