2 * ad525x_dpot: Driver for the Analog Devices AD525x digital potentiometers
3 * Copyright (c) 2009 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
15 * See Documentation/misc-devices/ad525x_dpot.txt for more info.
17 * derived from ad5258.c
18 * Copyright (c) 2009 Cyber Switching, Inc.
19 * Author: Chris Verges <chrisv@cyberswitching.com>
21 * derived from ad5252.c
22 * Copyright (c) 2006 Michael Hennerich <hennerich@blackfin.uclinux.org>
24 * Licensed under the GPL-2 or later.
27 #include <linux/module.h>
28 #include <linux/device.h>
29 #include <linux/kernel.h>
30 #include <linux/init.h>
31 #include <linux/slab.h>
32 #include <linux/i2c.h>
33 #include <linux/delay.h>
35 #define DRIVER_NAME "ad525x_dpot"
36 #define DRIVER_VERSION "0.1"
48 #define AD5258_MAX_POSITION 64
49 #define AD5259_MAX_POSITION 256
50 #define AD5251_MAX_POSITION 64
51 #define AD5252_MAX_POSITION 256
52 #define AD5253_MAX_POSITION 64
53 #define AD5254_MAX_POSITION 256
54 #define AD5255_MAX_POSITION 512
56 #define AD525X_RDAC0 0
57 #define AD525X_RDAC1 1
58 #define AD525X_RDAC2 2
59 #define AD525X_RDAC3 3
61 #define AD525X_REG_TOL 0x18
62 #define AD525X_TOL_RDAC0 (AD525X_REG_TOL | AD525X_RDAC0)
63 #define AD525X_TOL_RDAC1 (AD525X_REG_TOL | AD525X_RDAC1)
64 #define AD525X_TOL_RDAC2 (AD525X_REG_TOL | AD525X_RDAC2)
65 #define AD525X_TOL_RDAC3 (AD525X_REG_TOL | AD525X_RDAC3)
67 /* RDAC-to-EEPROM Interface Commands */
68 #define AD525X_I2C_RDAC (0x00 << 5)
69 #define AD525X_I2C_EEPROM (0x01 << 5)
70 #define AD525X_I2C_CMD (0x80)
72 #define AD525X_DEC_ALL_6DB (AD525X_I2C_CMD | (0x4 << 3))
73 #define AD525X_INC_ALL_6DB (AD525X_I2C_CMD | (0x9 << 3))
74 #define AD525X_DEC_ALL (AD525X_I2C_CMD | (0x6 << 3))
75 #define AD525X_INC_ALL (AD525X_I2C_CMD | (0xB << 3))
77 static s32
ad525x_read(struct i2c_client
*client
, u8 reg
);
78 static s32
ad525x_write(struct i2c_client
*client
, u8 reg
, u8 value
);
81 * Client data (each client gets its own)
85 struct mutex update_lock
;
93 static ssize_t
sysfs_show_reg(struct device
*dev
,
94 struct device_attribute
*attr
, char *buf
, u32 reg
)
96 struct i2c_client
*client
= to_i2c_client(dev
);
97 struct dpot_data
*data
= i2c_get_clientdata(client
);
100 mutex_lock(&data
->update_lock
);
101 value
= ad525x_read(client
, reg
);
102 mutex_unlock(&data
->update_lock
);
107 * Let someone else deal with converting this ...
108 * the tolerance is a two-byte value where the MSB
109 * is a sign + integer value, and the LSB is a
110 * decimal value. See page 18 of the AD5258
111 * datasheet (Rev. A) for more details.
114 if (reg
& AD525X_REG_TOL
)
115 return sprintf(buf
, "0x%04x\n", value
& 0xFFFF);
117 return sprintf(buf
, "%u\n", value
& data
->rdac_mask
);
120 static ssize_t
sysfs_set_reg(struct device
*dev
,
121 struct device_attribute
*attr
,
122 const char *buf
, size_t count
, u32 reg
)
124 struct i2c_client
*client
= to_i2c_client(dev
);
125 struct dpot_data
*data
= i2c_get_clientdata(client
);
129 err
= strict_strtoul(buf
, 10, &value
);
133 if (value
> data
->rdac_mask
)
134 value
= data
->rdac_mask
;
136 mutex_lock(&data
->update_lock
);
137 ad525x_write(client
, reg
, value
);
138 if (reg
& AD525X_I2C_EEPROM
)
139 msleep(26); /* Sleep while the EEPROM updates */
140 mutex_unlock(&data
->update_lock
);
145 static ssize_t
sysfs_do_cmd(struct device
*dev
,
146 struct device_attribute
*attr
,
147 const char *buf
, size_t count
, u32 reg
)
149 struct i2c_client
*client
= to_i2c_client(dev
);
150 struct dpot_data
*data
= i2c_get_clientdata(client
);
152 mutex_lock(&data
->update_lock
);
153 ad525x_write(client
, reg
, 0);
154 mutex_unlock(&data
->update_lock
);
159 /* ------------------------------------------------------------------------- */
161 static ssize_t
show_rdac0(struct device
*dev
,
162 struct device_attribute
*attr
, char *buf
)
164 return sysfs_show_reg(dev
, attr
, buf
, AD525X_I2C_RDAC
| AD525X_RDAC0
);
167 static ssize_t
set_rdac0(struct device
*dev
,
168 struct device_attribute
*attr
,
169 const char *buf
, size_t count
)
171 return sysfs_set_reg(dev
, attr
, buf
, count
,
172 AD525X_I2C_RDAC
| AD525X_RDAC0
);
175 static DEVICE_ATTR(rdac0
, S_IWUSR
| S_IRUGO
, show_rdac0
, set_rdac0
);
177 static ssize_t
show_eeprom0(struct device
*dev
,
178 struct device_attribute
*attr
, char *buf
)
180 return sysfs_show_reg(dev
, attr
, buf
, AD525X_I2C_EEPROM
| AD525X_RDAC0
);
183 static ssize_t
set_eeprom0(struct device
*dev
,
184 struct device_attribute
*attr
,
185 const char *buf
, size_t count
)
187 return sysfs_set_reg(dev
, attr
, buf
, count
,
188 AD525X_I2C_EEPROM
| AD525X_RDAC0
);
191 static DEVICE_ATTR(eeprom0
, S_IWUSR
| S_IRUGO
, show_eeprom0
, set_eeprom0
);
193 static ssize_t
show_tolerance0(struct device
*dev
,
194 struct device_attribute
*attr
, char *buf
)
196 return sysfs_show_reg(dev
, attr
, buf
,
197 AD525X_I2C_EEPROM
| AD525X_TOL_RDAC0
);
200 static DEVICE_ATTR(tolerance0
, S_IRUGO
, show_tolerance0
, NULL
);
202 /* ------------------------------------------------------------------------- */
204 static ssize_t
show_rdac1(struct device
*dev
,
205 struct device_attribute
*attr
, char *buf
)
207 return sysfs_show_reg(dev
, attr
, buf
, AD525X_I2C_RDAC
| AD525X_RDAC1
);
210 static ssize_t
set_rdac1(struct device
*dev
,
211 struct device_attribute
*attr
,
212 const char *buf
, size_t count
)
214 return sysfs_set_reg(dev
, attr
, buf
, count
,
215 AD525X_I2C_RDAC
| AD525X_RDAC1
);
218 static DEVICE_ATTR(rdac1
, S_IWUSR
| S_IRUGO
, show_rdac1
, set_rdac1
);
220 static ssize_t
show_eeprom1(struct device
*dev
,
221 struct device_attribute
*attr
, char *buf
)
223 return sysfs_show_reg(dev
, attr
, buf
, AD525X_I2C_EEPROM
| AD525X_RDAC1
);
226 static ssize_t
set_eeprom1(struct device
*dev
,
227 struct device_attribute
*attr
,
228 const char *buf
, size_t count
)
230 return sysfs_set_reg(dev
, attr
, buf
, count
,
231 AD525X_I2C_EEPROM
| AD525X_RDAC1
);
234 static DEVICE_ATTR(eeprom1
, S_IWUSR
| S_IRUGO
, show_eeprom1
, set_eeprom1
);
236 static ssize_t
show_tolerance1(struct device
*dev
,
237 struct device_attribute
*attr
, char *buf
)
239 return sysfs_show_reg(dev
, attr
, buf
,
240 AD525X_I2C_EEPROM
| AD525X_TOL_RDAC1
);
243 static DEVICE_ATTR(tolerance1
, S_IRUGO
, show_tolerance1
, NULL
);
245 /* ------------------------------------------------------------------------- */
247 static ssize_t
show_rdac2(struct device
*dev
,
248 struct device_attribute
*attr
, char *buf
)
250 return sysfs_show_reg(dev
, attr
, buf
, AD525X_I2C_RDAC
| AD525X_RDAC2
);
253 static ssize_t
set_rdac2(struct device
*dev
,
254 struct device_attribute
*attr
,
255 const char *buf
, size_t count
)
257 return sysfs_set_reg(dev
, attr
, buf
, count
,
258 AD525X_I2C_RDAC
| AD525X_RDAC2
);
261 static DEVICE_ATTR(rdac2
, S_IWUSR
| S_IRUGO
, show_rdac2
, set_rdac2
);
263 static ssize_t
show_eeprom2(struct device
*dev
,
264 struct device_attribute
*attr
, char *buf
)
266 return sysfs_show_reg(dev
, attr
, buf
, AD525X_I2C_EEPROM
| AD525X_RDAC2
);
269 static ssize_t
set_eeprom2(struct device
*dev
,
270 struct device_attribute
*attr
,
271 const char *buf
, size_t count
)
273 return sysfs_set_reg(dev
, attr
, buf
, count
,
274 AD525X_I2C_EEPROM
| AD525X_RDAC2
);
277 static DEVICE_ATTR(eeprom2
, S_IWUSR
| S_IRUGO
, show_eeprom2
, set_eeprom2
);
279 static ssize_t
show_tolerance2(struct device
*dev
,
280 struct device_attribute
*attr
, char *buf
)
282 return sysfs_show_reg(dev
, attr
, buf
,
283 AD525X_I2C_EEPROM
| AD525X_TOL_RDAC2
);
286 static DEVICE_ATTR(tolerance2
, S_IRUGO
, show_tolerance2
, NULL
);
288 /* ------------------------------------------------------------------------- */
290 static ssize_t
show_rdac3(struct device
*dev
,
291 struct device_attribute
*attr
, char *buf
)
293 return sysfs_show_reg(dev
, attr
, buf
, AD525X_I2C_RDAC
| AD525X_RDAC3
);
296 static ssize_t
set_rdac3(struct device
*dev
,
297 struct device_attribute
*attr
,
298 const char *buf
, size_t count
)
300 return sysfs_set_reg(dev
, attr
, buf
, count
,
301 AD525X_I2C_RDAC
| AD525X_RDAC3
);
304 static DEVICE_ATTR(rdac3
, S_IWUSR
| S_IRUGO
, show_rdac3
, set_rdac3
);
306 static ssize_t
show_eeprom3(struct device
*dev
,
307 struct device_attribute
*attr
, char *buf
)
309 return sysfs_show_reg(dev
, attr
, buf
, AD525X_I2C_EEPROM
| AD525X_RDAC3
);
312 static ssize_t
set_eeprom3(struct device
*dev
,
313 struct device_attribute
*attr
,
314 const char *buf
, size_t count
)
316 return sysfs_set_reg(dev
, attr
, buf
, count
,
317 AD525X_I2C_EEPROM
| AD525X_RDAC3
);
320 static DEVICE_ATTR(eeprom3
, S_IWUSR
| S_IRUGO
, show_eeprom3
, set_eeprom3
);
322 static ssize_t
show_tolerance3(struct device
*dev
,
323 struct device_attribute
*attr
, char *buf
)
325 return sysfs_show_reg(dev
, attr
, buf
,
326 AD525X_I2C_EEPROM
| AD525X_TOL_RDAC3
);
329 static DEVICE_ATTR(tolerance3
, S_IRUGO
, show_tolerance3
, NULL
);
331 static struct attribute
*ad525x_attributes_wipers
[4][4] = {
333 &dev_attr_rdac0
.attr
,
334 &dev_attr_eeprom0
.attr
,
335 &dev_attr_tolerance0
.attr
,
338 &dev_attr_rdac1
.attr
,
339 &dev_attr_eeprom1
.attr
,
340 &dev_attr_tolerance1
.attr
,
343 &dev_attr_rdac2
.attr
,
344 &dev_attr_eeprom2
.attr
,
345 &dev_attr_tolerance2
.attr
,
348 &dev_attr_rdac3
.attr
,
349 &dev_attr_eeprom3
.attr
,
350 &dev_attr_tolerance3
.attr
,
355 static const struct attribute_group ad525x_group_wipers
[] = {
356 {.attrs
= ad525x_attributes_wipers
[AD525X_RDAC0
]},
357 {.attrs
= ad525x_attributes_wipers
[AD525X_RDAC1
]},
358 {.attrs
= ad525x_attributes_wipers
[AD525X_RDAC2
]},
359 {.attrs
= ad525x_attributes_wipers
[AD525X_RDAC3
]},
362 /* ------------------------------------------------------------------------- */
364 static ssize_t
set_inc_all(struct device
*dev
,
365 struct device_attribute
*attr
,
366 const char *buf
, size_t count
)
368 return sysfs_do_cmd(dev
, attr
, buf
, count
, AD525X_INC_ALL
);
371 static DEVICE_ATTR(inc_all
, S_IWUSR
, NULL
, set_inc_all
);
373 static ssize_t
set_dec_all(struct device
*dev
,
374 struct device_attribute
*attr
,
375 const char *buf
, size_t count
)
377 return sysfs_do_cmd(dev
, attr
, buf
, count
, AD525X_DEC_ALL
);
380 static DEVICE_ATTR(dec_all
, S_IWUSR
, NULL
, set_dec_all
);
382 static ssize_t
set_inc_all_6db(struct device
*dev
,
383 struct device_attribute
*attr
,
384 const char *buf
, size_t count
)
386 return sysfs_do_cmd(dev
, attr
, buf
, count
, AD525X_INC_ALL_6DB
);
389 static DEVICE_ATTR(inc_all_6db
, S_IWUSR
, NULL
, set_inc_all_6db
);
391 static ssize_t
set_dec_all_6db(struct device
*dev
,
392 struct device_attribute
*attr
,
393 const char *buf
, size_t count
)
395 return sysfs_do_cmd(dev
, attr
, buf
, count
, AD525X_DEC_ALL_6DB
);
398 static DEVICE_ATTR(dec_all_6db
, S_IWUSR
, NULL
, set_dec_all_6db
);
400 static struct attribute
*ad525x_attributes_commands
[] = {
401 &dev_attr_inc_all
.attr
,
402 &dev_attr_dec_all
.attr
,
403 &dev_attr_inc_all_6db
.attr
,
404 &dev_attr_dec_all_6db
.attr
,
408 static const struct attribute_group ad525x_group_commands
= {
409 .attrs
= ad525x_attributes_commands
,
412 /* ------------------------------------------------------------------------- */
414 /* i2c device functions */
417 * ad525x_read - return the value contained in the specified register
418 * on the AD5258 device.
419 * @client: value returned from i2c_new_device()
420 * @reg: the register to read
422 * If the tolerance register is specified, 2 bytes are returned.
423 * Otherwise, 1 byte is returned. A negative value indicates an error
424 * occurred while reading the register.
426 static s32
ad525x_read(struct i2c_client
*client
, u8 reg
)
428 struct dpot_data
*data
= i2c_get_clientdata(client
);
430 if ((reg
& AD525X_REG_TOL
) || (data
->max_pos
> 256))
431 return i2c_smbus_read_word_data(client
, (reg
& 0xF8) |
434 return i2c_smbus_read_byte_data(client
, reg
);
438 * ad525x_write - store the given value in the specified register on
440 * @client: value returned from i2c_new_device()
441 * @reg: the register to write
442 * @value: the byte to store in the register
444 * For certain instructions that do not require a data byte, "NULL"
445 * should be specified for the "value" parameter. These instructions
446 * include NOP, RESTORE_FROM_EEPROM, and STORE_TO_EEPROM.
448 * A negative return value indicates an error occurred while reading
451 static s32
ad525x_write(struct i2c_client
*client
, u8 reg
, u8 value
)
453 struct dpot_data
*data
= i2c_get_clientdata(client
);
455 /* Only write the instruction byte for certain commands */
456 if (reg
& AD525X_I2C_CMD
)
457 return i2c_smbus_write_byte(client
, reg
);
459 if (data
->max_pos
> 256)
460 return i2c_smbus_write_word_data(client
, (reg
& 0xF8) |
461 ((reg
& 0x7) << 1), value
);
463 /* All other registers require instruction + data bytes */
464 return i2c_smbus_write_byte_data(client
, reg
, value
);
467 static int ad525x_probe(struct i2c_client
*client
,
468 const struct i2c_device_id
*id
)
470 struct device
*dev
= &client
->dev
;
471 struct dpot_data
*data
;
474 dev_dbg(dev
, "%s\n", __func__
);
476 if (!i2c_check_functionality(client
->adapter
, I2C_FUNC_SMBUS_BYTE
)) {
477 dev_err(dev
, "missing I2C functionality for this driver\n");
481 data
= kzalloc(sizeof(struct dpot_data
), GFP_KERNEL
);
487 i2c_set_clientdata(client
, data
);
488 mutex_init(&data
->update_lock
);
490 switch (id
->driver_data
) {
492 data
->max_pos
= AD5258_MAX_POSITION
;
493 err
= sysfs_create_group(&dev
->kobj
,
494 &ad525x_group_wipers
[AD525X_RDAC0
]);
497 data
->max_pos
= AD5259_MAX_POSITION
;
498 err
= sysfs_create_group(&dev
->kobj
,
499 &ad525x_group_wipers
[AD525X_RDAC0
]);
502 data
->max_pos
= AD5251_MAX_POSITION
;
503 err
= sysfs_create_group(&dev
->kobj
,
504 &ad525x_group_wipers
[AD525X_RDAC1
]);
505 err
|= sysfs_create_group(&dev
->kobj
,
506 &ad525x_group_wipers
[AD525X_RDAC3
]);
507 err
|= sysfs_create_group(&dev
->kobj
, &ad525x_group_commands
);
510 data
->max_pos
= AD5252_MAX_POSITION
;
511 err
= sysfs_create_group(&dev
->kobj
,
512 &ad525x_group_wipers
[AD525X_RDAC1
]);
513 err
|= sysfs_create_group(&dev
->kobj
,
514 &ad525x_group_wipers
[AD525X_RDAC3
]);
515 err
|= sysfs_create_group(&dev
->kobj
, &ad525x_group_commands
);
518 data
->max_pos
= AD5253_MAX_POSITION
;
519 err
= sysfs_create_group(&dev
->kobj
,
520 &ad525x_group_wipers
[AD525X_RDAC0
]);
521 err
|= sysfs_create_group(&dev
->kobj
,
522 &ad525x_group_wipers
[AD525X_RDAC1
]);
523 err
|= sysfs_create_group(&dev
->kobj
,
524 &ad525x_group_wipers
[AD525X_RDAC2
]);
525 err
|= sysfs_create_group(&dev
->kobj
,
526 &ad525x_group_wipers
[AD525X_RDAC3
]);
527 err
|= sysfs_create_group(&dev
->kobj
, &ad525x_group_commands
);
530 data
->max_pos
= AD5254_MAX_POSITION
;
531 err
= sysfs_create_group(&dev
->kobj
,
532 &ad525x_group_wipers
[AD525X_RDAC0
]);
533 err
|= sysfs_create_group(&dev
->kobj
,
534 &ad525x_group_wipers
[AD525X_RDAC1
]);
535 err
|= sysfs_create_group(&dev
->kobj
,
536 &ad525x_group_wipers
[AD525X_RDAC2
]);
537 err
|= sysfs_create_group(&dev
->kobj
,
538 &ad525x_group_wipers
[AD525X_RDAC3
]);
539 err
|= sysfs_create_group(&dev
->kobj
, &ad525x_group_commands
);
542 data
->max_pos
= AD5255_MAX_POSITION
;
543 err
= sysfs_create_group(&dev
->kobj
,
544 &ad525x_group_wipers
[AD525X_RDAC0
]);
545 err
|= sysfs_create_group(&dev
->kobj
,
546 &ad525x_group_wipers
[AD525X_RDAC1
]);
547 err
|= sysfs_create_group(&dev
->kobj
,
548 &ad525x_group_wipers
[AD525X_RDAC2
]);
549 err
|= sysfs_create_group(&dev
->kobj
, &ad525x_group_commands
);
557 dev_err(dev
, "failed to register sysfs hooks\n");
561 data
->devid
= id
->driver_data
;
562 data
->rdac_mask
= data
->max_pos
- 1;
564 dev_info(dev
, "%s %d-Position Digital Potentiometer registered\n",
565 id
->name
, data
->max_pos
);
571 i2c_set_clientdata(client
, NULL
);
573 dev_err(dev
, "failed to create client\n");
577 static int __devexit
ad525x_remove(struct i2c_client
*client
)
579 struct dpot_data
*data
= i2c_get_clientdata(client
);
580 struct device
*dev
= &client
->dev
;
582 switch (data
->devid
) {
585 sysfs_remove_group(&dev
->kobj
,
586 &ad525x_group_wipers
[AD525X_RDAC0
]);
590 sysfs_remove_group(&dev
->kobj
,
591 &ad525x_group_wipers
[AD525X_RDAC1
]);
592 sysfs_remove_group(&dev
->kobj
,
593 &ad525x_group_wipers
[AD525X_RDAC3
]);
594 sysfs_remove_group(&dev
->kobj
, &ad525x_group_commands
);
598 sysfs_remove_group(&dev
->kobj
,
599 &ad525x_group_wipers
[AD525X_RDAC0
]);
600 sysfs_remove_group(&dev
->kobj
,
601 &ad525x_group_wipers
[AD525X_RDAC1
]);
602 sysfs_remove_group(&dev
->kobj
,
603 &ad525x_group_wipers
[AD525X_RDAC2
]);
604 sysfs_remove_group(&dev
->kobj
,
605 &ad525x_group_wipers
[AD525X_RDAC3
]);
606 sysfs_remove_group(&dev
->kobj
, &ad525x_group_commands
);
609 sysfs_remove_group(&dev
->kobj
,
610 &ad525x_group_wipers
[AD525X_RDAC0
]);
611 sysfs_remove_group(&dev
->kobj
,
612 &ad525x_group_wipers
[AD525X_RDAC1
]);
613 sysfs_remove_group(&dev
->kobj
,
614 &ad525x_group_wipers
[AD525X_RDAC2
]);
615 sysfs_remove_group(&dev
->kobj
, &ad525x_group_commands
);
619 i2c_set_clientdata(client
, NULL
);
625 static const struct i2c_device_id ad525x_idtable
[] = {
626 {"ad5258", AD5258_ID
},
627 {"ad5259", AD5259_ID
},
628 {"ad5251", AD5251_ID
},
629 {"ad5252", AD5252_ID
},
630 {"ad5253", AD5253_ID
},
631 {"ad5254", AD5254_ID
},
632 {"ad5255", AD5255_ID
},
636 MODULE_DEVICE_TABLE(i2c
, ad525x_idtable
);
638 static struct i2c_driver ad525x_driver
= {
640 .owner
= THIS_MODULE
,
643 .id_table
= ad525x_idtable
,
644 .probe
= ad525x_probe
,
645 .remove
= __devexit_p(ad525x_remove
),
648 static int __init
ad525x_init(void)
650 return i2c_add_driver(&ad525x_driver
);
653 module_init(ad525x_init
);
655 static void __exit
ad525x_exit(void)
657 i2c_del_driver(&ad525x_driver
);
660 module_exit(ad525x_exit
);
662 MODULE_AUTHOR("Chris Verges <chrisv@cyberswitching.com>, "
663 "Michael Hennerich <hennerich@blackfin.uclinux.org>, ");
664 MODULE_DESCRIPTION("AD5258/9 digital potentiometer driver");
665 MODULE_LICENSE("GPL");
666 MODULE_VERSION(DRIVER_VERSION
);