ad525x_dpot: simplify duplicated sysfs defines
[linux-2.6.git] / drivers / misc / ad525x_dpot.c
1 /*
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>
5  *
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  *
15  * See Documentation/misc-devices/ad525x_dpot.txt for more info.
16  *
17  * derived from ad5258.c
18  * Copyright (c) 2009 Cyber Switching, Inc.
19  * Author: Chris Verges <chrisv@cyberswitching.com>
20  *
21  * derived from ad5252.c
22  * Copyright (c) 2006 Michael Hennerich <hennerich@blackfin.uclinux.org>
23  *
24  * Licensed under the GPL-2 or later.
25  */
26
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>
34
35 #define DRIVER_NAME                     "ad525x_dpot"
36 #define DRIVER_VERSION                  "0.1"
37
38 enum dpot_devid {
39         AD5258_ID,
40         AD5259_ID,
41         AD5251_ID,
42         AD5252_ID,
43         AD5253_ID,
44         AD5254_ID,
45         AD5255_ID,
46 };
47
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
55
56 #define AD525X_RDAC0            0
57 #define AD525X_RDAC1            1
58 #define AD525X_RDAC2            2
59 #define AD525X_RDAC3            3
60
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)
66
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)
71
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))
76
77 static s32 ad525x_read(struct i2c_client *client, u8 reg);
78 static s32 ad525x_write(struct i2c_client *client, u8 reg, u8 value);
79
80 /*
81  * Client data (each client gets its own)
82  */
83
84 struct dpot_data {
85         struct mutex update_lock;
86         unsigned rdac_mask;
87         unsigned max_pos;
88         unsigned devid;
89 };
90
91 /* sysfs functions */
92
93 static ssize_t sysfs_show_reg(struct device *dev,
94                               struct device_attribute *attr, char *buf, u32 reg)
95 {
96         struct i2c_client *client = to_i2c_client(dev);
97         struct dpot_data *data = i2c_get_clientdata(client);
98         s32 value;
99
100         mutex_lock(&data->update_lock);
101         value = ad525x_read(client, reg);
102         mutex_unlock(&data->update_lock);
103
104         if (value < 0)
105                 return -EINVAL;
106         /*
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.
112          */
113
114         if (reg & AD525X_REG_TOL)
115                 return sprintf(buf, "0x%04x\n", value & 0xFFFF);
116         else
117                 return sprintf(buf, "%u\n", value & data->rdac_mask);
118 }
119
120 static ssize_t sysfs_set_reg(struct device *dev,
121                              struct device_attribute *attr,
122                              const char *buf, size_t count, u32 reg)
123 {
124         struct i2c_client *client = to_i2c_client(dev);
125         struct dpot_data *data = i2c_get_clientdata(client);
126         unsigned long value;
127         int err;
128
129         err = strict_strtoul(buf, 10, &value);
130         if (err)
131                 return err;
132
133         if (value > data->rdac_mask)
134                 value = data->rdac_mask;
135
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);
141
142         return count;
143 }
144
145 static ssize_t sysfs_do_cmd(struct device *dev,
146                             struct device_attribute *attr,
147                             const char *buf, size_t count, u32 reg)
148 {
149         struct i2c_client *client = to_i2c_client(dev);
150         struct dpot_data *data = i2c_get_clientdata(client);
151
152         mutex_lock(&data->update_lock);
153         ad525x_write(client, reg, 0);
154         mutex_unlock(&data->update_lock);
155
156         return count;
157 }
158
159 /* ------------------------------------------------------------------------- */
160
161 #define DPOT_DEVICE_SHOW(_name, _reg) static ssize_t \
162 show_##_name(struct device *dev, \
163                           struct device_attribute *attr, char *buf) \
164 { \
165         return sysfs_show_reg(dev, attr, buf, _reg); \
166 }
167
168 #define DPOT_DEVICE_SET(_name, _reg) static ssize_t \
169 set_##_name(struct device *dev, \
170                          struct device_attribute *attr, \
171                          const char *buf, size_t count) \
172 { \
173         return sysfs_set_reg(dev, attr, buf, count, _reg); \
174 }
175
176 #define DPOT_DEVICE_SHOW_SET(name, reg) \
177 DPOT_DEVICE_SHOW(name, reg) \
178 DPOT_DEVICE_SET(name, reg) \
179 static DEVICE_ATTR(name, S_IWUSR | S_IRUGO, show_##name, set_##name);
180
181 #define DPOT_DEVICE_SHOW_ONLY(name, reg) \
182 DPOT_DEVICE_SHOW(name, reg) \
183 static DEVICE_ATTR(name, S_IWUSR | S_IRUGO, show_##name, NULL);
184
185 DPOT_DEVICE_SHOW_SET(rdac0, AD525X_I2C_RDAC | AD525X_RDAC0);
186 DPOT_DEVICE_SHOW_SET(eeprom0, AD525X_I2C_EEPROM | AD525X_RDAC0);
187 DPOT_DEVICE_SHOW_ONLY(tolerance0, AD525X_I2C_EEPROM | AD525X_TOL_RDAC0);
188
189 DPOT_DEVICE_SHOW_SET(rdac1, AD525X_I2C_RDAC | AD525X_RDAC1);
190 DPOT_DEVICE_SHOW_SET(eeprom1, AD525X_I2C_EEPROM | AD525X_RDAC1);
191 DPOT_DEVICE_SHOW_ONLY(tolerance1, AD525X_I2C_EEPROM | AD525X_TOL_RDAC1);
192
193 DPOT_DEVICE_SHOW_SET(rdac2, AD525X_I2C_RDAC | AD525X_RDAC2);
194 DPOT_DEVICE_SHOW_SET(eeprom2, AD525X_I2C_EEPROM | AD525X_RDAC2);
195 DPOT_DEVICE_SHOW_ONLY(tolerance2, AD525X_I2C_EEPROM | AD525X_TOL_RDAC2);
196
197 DPOT_DEVICE_SHOW_SET(rdac3, AD525X_I2C_RDAC | AD525X_RDAC3);
198 DPOT_DEVICE_SHOW_SET(eeprom3, AD525X_I2C_EEPROM | AD525X_RDAC3);
199 DPOT_DEVICE_SHOW_ONLY(tolerance3, AD525X_I2C_EEPROM | AD525X_TOL_RDAC3);
200
201 static struct attribute *ad525x_attributes_wipers[4][4] = {
202         {
203                 &dev_attr_rdac0.attr,
204                 &dev_attr_eeprom0.attr,
205                 &dev_attr_tolerance0.attr,
206                 NULL
207         }, {
208                 &dev_attr_rdac1.attr,
209                 &dev_attr_eeprom1.attr,
210                 &dev_attr_tolerance1.attr,
211                 NULL
212         }, {
213                 &dev_attr_rdac2.attr,
214                 &dev_attr_eeprom2.attr,
215                 &dev_attr_tolerance2.attr,
216                 NULL
217         }, {
218                 &dev_attr_rdac3.attr,
219                 &dev_attr_eeprom3.attr,
220                 &dev_attr_tolerance3.attr,
221                 NULL
222         }
223 };
224
225 static const struct attribute_group ad525x_group_wipers[] = {
226         {.attrs = ad525x_attributes_wipers[AD525X_RDAC0]},
227         {.attrs = ad525x_attributes_wipers[AD525X_RDAC1]},
228         {.attrs = ad525x_attributes_wipers[AD525X_RDAC2]},
229         {.attrs = ad525x_attributes_wipers[AD525X_RDAC3]},
230 };
231
232 /* ------------------------------------------------------------------------- */
233
234 #define DPOT_DEVICE_DO_CMD(_name, _cmd) static ssize_t \
235 set_##_name(struct device *dev, \
236                          struct device_attribute *attr, \
237                          const char *buf, size_t count) \
238 { \
239         return sysfs_do_cmd(dev, attr, buf, count, _cmd); \
240 } \
241 static DEVICE_ATTR(_name, S_IWUSR | S_IRUGO, NULL, set_##_name);
242
243 DPOT_DEVICE_DO_CMD(inc_all, AD525X_INC_ALL);
244 DPOT_DEVICE_DO_CMD(dec_all, AD525X_DEC_ALL);
245 DPOT_DEVICE_DO_CMD(inc_all_6db, AD525X_INC_ALL_6DB);
246 DPOT_DEVICE_DO_CMD(dec_all_6db, AD525X_DEC_ALL_6DB);
247
248 static struct attribute *ad525x_attributes_commands[] = {
249         &dev_attr_inc_all.attr,
250         &dev_attr_dec_all.attr,
251         &dev_attr_inc_all_6db.attr,
252         &dev_attr_dec_all_6db.attr,
253         NULL
254 };
255
256 static const struct attribute_group ad525x_group_commands = {
257         .attrs = ad525x_attributes_commands,
258 };
259
260 /* ------------------------------------------------------------------------- */
261
262 /* i2c device functions */
263
264 /**
265  * ad525x_read - return the value contained in the specified register
266  * on the AD5258 device.
267  * @client: value returned from i2c_new_device()
268  * @reg: the register to read
269  *
270  * If the tolerance register is specified, 2 bytes are returned.
271  * Otherwise, 1 byte is returned.  A negative value indicates an error
272  * occurred while reading the register.
273  */
274 static s32 ad525x_read(struct i2c_client *client, u8 reg)
275 {
276         struct dpot_data *data = i2c_get_clientdata(client);
277
278         if ((reg & AD525X_REG_TOL) || (data->max_pos > 256))
279                 return i2c_smbus_read_word_data(client, (reg & 0xF8) |
280                                                 ((reg & 0x7) << 1));
281         else
282                 return i2c_smbus_read_byte_data(client, reg);
283 }
284
285 /**
286  * ad525x_write - store the given value in the specified register on
287  * the AD5258 device.
288  * @client: value returned from i2c_new_device()
289  * @reg: the register to write
290  * @value: the byte to store in the register
291  *
292  * For certain instructions that do not require a data byte, "NULL"
293  * should be specified for the "value" parameter.  These instructions
294  * include NOP, RESTORE_FROM_EEPROM, and STORE_TO_EEPROM.
295  *
296  * A negative return value indicates an error occurred while reading
297  * the register.
298  */
299 static s32 ad525x_write(struct i2c_client *client, u8 reg, u8 value)
300 {
301         struct dpot_data *data = i2c_get_clientdata(client);
302
303         /* Only write the instruction byte for certain commands */
304         if (reg & AD525X_I2C_CMD)
305                 return i2c_smbus_write_byte(client, reg);
306
307         if (data->max_pos > 256)
308                 return i2c_smbus_write_word_data(client, (reg & 0xF8) |
309                                                 ((reg & 0x7) << 1), value);
310         else
311                 /* All other registers require instruction + data bytes */
312                 return i2c_smbus_write_byte_data(client, reg, value);
313 }
314
315 static int ad525x_probe(struct i2c_client *client,
316                         const struct i2c_device_id *id)
317 {
318         struct device *dev = &client->dev;
319         struct dpot_data *data;
320         int err = 0;
321
322         dev_dbg(dev, "%s\n", __func__);
323
324         if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)) {
325                 dev_err(dev, "missing I2C functionality for this driver\n");
326                 goto exit;
327         }
328
329         data = kzalloc(sizeof(struct dpot_data), GFP_KERNEL);
330         if (!data) {
331                 err = -ENOMEM;
332                 goto exit;
333         }
334
335         i2c_set_clientdata(client, data);
336         mutex_init(&data->update_lock);
337
338         switch (id->driver_data) {
339         case AD5258_ID:
340                 data->max_pos = AD5258_MAX_POSITION;
341                 err = sysfs_create_group(&dev->kobj,
342                                        &ad525x_group_wipers[AD525X_RDAC0]);
343                 break;
344         case AD5259_ID:
345                 data->max_pos = AD5259_MAX_POSITION;
346                 err = sysfs_create_group(&dev->kobj,
347                                        &ad525x_group_wipers[AD525X_RDAC0]);
348                 break;
349         case AD5251_ID:
350                 data->max_pos = AD5251_MAX_POSITION;
351                 err = sysfs_create_group(&dev->kobj,
352                                        &ad525x_group_wipers[AD525X_RDAC1]);
353                 err |= sysfs_create_group(&dev->kobj,
354                                        &ad525x_group_wipers[AD525X_RDAC3]);
355                 err |= sysfs_create_group(&dev->kobj, &ad525x_group_commands);
356                 break;
357         case AD5252_ID:
358                 data->max_pos = AD5252_MAX_POSITION;
359                 err = sysfs_create_group(&dev->kobj,
360                                        &ad525x_group_wipers[AD525X_RDAC1]);
361                 err |= sysfs_create_group(&dev->kobj,
362                                        &ad525x_group_wipers[AD525X_RDAC3]);
363                 err |= sysfs_create_group(&dev->kobj, &ad525x_group_commands);
364                 break;
365         case AD5253_ID:
366                 data->max_pos = AD5253_MAX_POSITION;
367                 err = sysfs_create_group(&dev->kobj,
368                                        &ad525x_group_wipers[AD525X_RDAC0]);
369                 err |= sysfs_create_group(&dev->kobj,
370                                        &ad525x_group_wipers[AD525X_RDAC1]);
371                 err |= sysfs_create_group(&dev->kobj,
372                                        &ad525x_group_wipers[AD525X_RDAC2]);
373                 err |= sysfs_create_group(&dev->kobj,
374                                        &ad525x_group_wipers[AD525X_RDAC3]);
375                 err |= sysfs_create_group(&dev->kobj, &ad525x_group_commands);
376                 break;
377         case AD5254_ID:
378                 data->max_pos = AD5254_MAX_POSITION;
379                 err = sysfs_create_group(&dev->kobj,
380                                        &ad525x_group_wipers[AD525X_RDAC0]);
381                 err |= sysfs_create_group(&dev->kobj,
382                                        &ad525x_group_wipers[AD525X_RDAC1]);
383                 err |= sysfs_create_group(&dev->kobj,
384                                        &ad525x_group_wipers[AD525X_RDAC2]);
385                 err |= sysfs_create_group(&dev->kobj,
386                                        &ad525x_group_wipers[AD525X_RDAC3]);
387                 err |= sysfs_create_group(&dev->kobj, &ad525x_group_commands);
388                 break;
389         case AD5255_ID:
390                 data->max_pos = AD5255_MAX_POSITION;
391                 err = sysfs_create_group(&dev->kobj,
392                                        &ad525x_group_wipers[AD525X_RDAC0]);
393                 err |= sysfs_create_group(&dev->kobj,
394                                        &ad525x_group_wipers[AD525X_RDAC1]);
395                 err |= sysfs_create_group(&dev->kobj,
396                                        &ad525x_group_wipers[AD525X_RDAC2]);
397                 err |= sysfs_create_group(&dev->kobj, &ad525x_group_commands);
398                 break;
399         default:
400                 err = -ENODEV;
401                 goto exit_free;
402         }
403
404         if (err) {
405                 dev_err(dev, "failed to register sysfs hooks\n");
406                 goto exit_free;
407         }
408
409         data->devid = id->driver_data;
410         data->rdac_mask = data->max_pos - 1;
411
412         dev_info(dev, "%s %d-Position Digital Potentiometer registered\n",
413                  id->name, data->max_pos);
414
415         return 0;
416
417 exit_free:
418         kfree(data);
419         i2c_set_clientdata(client, NULL);
420 exit:
421         dev_err(dev, "failed to create client\n");
422         return err;
423 }
424
425 static int __devexit ad525x_remove(struct i2c_client *client)
426 {
427         struct dpot_data *data = i2c_get_clientdata(client);
428         struct device *dev = &client->dev;
429
430         switch (data->devid) {
431         case AD5258_ID:
432         case AD5259_ID:
433                 sysfs_remove_group(&dev->kobj,
434                                    &ad525x_group_wipers[AD525X_RDAC0]);
435                 break;
436         case AD5251_ID:
437         case AD5252_ID:
438                 sysfs_remove_group(&dev->kobj,
439                                    &ad525x_group_wipers[AD525X_RDAC1]);
440                 sysfs_remove_group(&dev->kobj,
441                                    &ad525x_group_wipers[AD525X_RDAC3]);
442                 sysfs_remove_group(&dev->kobj, &ad525x_group_commands);
443                 break;
444         case AD5253_ID:
445         case AD5254_ID:
446                 sysfs_remove_group(&dev->kobj,
447                                    &ad525x_group_wipers[AD525X_RDAC0]);
448                 sysfs_remove_group(&dev->kobj,
449                                    &ad525x_group_wipers[AD525X_RDAC1]);
450                 sysfs_remove_group(&dev->kobj,
451                                    &ad525x_group_wipers[AD525X_RDAC2]);
452                 sysfs_remove_group(&dev->kobj,
453                                    &ad525x_group_wipers[AD525X_RDAC3]);
454                 sysfs_remove_group(&dev->kobj, &ad525x_group_commands);
455                 break;
456         case AD5255_ID:
457                 sysfs_remove_group(&dev->kobj,
458                                    &ad525x_group_wipers[AD525X_RDAC0]);
459                 sysfs_remove_group(&dev->kobj,
460                                    &ad525x_group_wipers[AD525X_RDAC1]);
461                 sysfs_remove_group(&dev->kobj,
462                                    &ad525x_group_wipers[AD525X_RDAC2]);
463                 sysfs_remove_group(&dev->kobj, &ad525x_group_commands);
464                 break;
465         }
466
467         i2c_set_clientdata(client, NULL);
468         kfree(data);
469
470         return 0;
471 }
472
473 static const struct i2c_device_id ad525x_idtable[] = {
474         {"ad5258", AD5258_ID},
475         {"ad5259", AD5259_ID},
476         {"ad5251", AD5251_ID},
477         {"ad5252", AD5252_ID},
478         {"ad5253", AD5253_ID},
479         {"ad5254", AD5254_ID},
480         {"ad5255", AD5255_ID},
481         {}
482 };
483
484 MODULE_DEVICE_TABLE(i2c, ad525x_idtable);
485
486 static struct i2c_driver ad525x_driver = {
487         .driver = {
488                    .owner = THIS_MODULE,
489                    .name = DRIVER_NAME,
490                    },
491         .id_table = ad525x_idtable,
492         .probe = ad525x_probe,
493         .remove = __devexit_p(ad525x_remove),
494 };
495
496 static int __init ad525x_init(void)
497 {
498         return i2c_add_driver(&ad525x_driver);
499 }
500
501 module_init(ad525x_init);
502
503 static void __exit ad525x_exit(void)
504 {
505         i2c_del_driver(&ad525x_driver);
506 }
507
508 module_exit(ad525x_exit);
509
510 MODULE_AUTHOR("Chris Verges <chrisv@cyberswitching.com>, "
511               "Michael Hennerich <hennerich@blackfin.uclinux.org>, ");
512 MODULE_DESCRIPTION("AD5258/9 digital potentiometer driver");
513 MODULE_LICENSE("GPL");
514 MODULE_VERSION(DRIVER_VERSION);