xref: /linux/drivers/misc/ad525x_dpot.c (revision d39d0ed196aa1685bb24771e92f78633c66ac9cb)
1 /*
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>
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  * AD5160		1		256		5, 10, 50, 100
15  * AD5161		1		256		5, 10, 50, 100
16  * AD5162		2		256		2.5, 10, 50, 100
17  * AD5165		1		256		100
18  * AD5200		1		256		10, 50
19  * AD5201		1		33		10, 50
20  * AD5203		4		64		10, 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
33  * AD5292		1		1024		20
34  * AD5293		1		1024		20
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  *
56  * See Documentation/misc-devices/ad525x_dpot.txt for more info.
57  *
58  * derived from ad5258.c
59  * Copyright (c) 2009 Cyber Switching, Inc.
60  * Author: Chris Verges <chrisv@cyberswitching.com>
61  *
62  * derived from ad5252.c
63  * Copyright (c) 2006 Michael Hennerich <hennerich@blackfin.uclinux.org>
64  *
65  * Licensed under the GPL-2 or later.
66  */
67 
68 #include <linux/module.h>
69 #include <linux/device.h>
70 #include <linux/kernel.h>
71 #include <linux/init.h>
72 #include <linux/delay.h>
73 #include <linux/slab.h>
74 
75 #define DRIVER_VERSION			"0.2"
76 
77 #include "ad525x_dpot.h"
78 
79 /*
80  * Client data (each client gets its own)
81  */
82 
83 struct dpot_data {
84 	struct ad_dpot_bus_data	bdata;
85 	struct mutex update_lock;
86 	unsigned rdac_mask;
87 	unsigned max_pos;
88 	unsigned long devid;
89 	unsigned uid;
90 	unsigned feat;
91 	unsigned wipers;
92 	u16 rdac_cache[MAX_RDACS];
93 	DECLARE_BITMAP(otp_en_mask, MAX_RDACS);
94 };
95 
96 static inline int dpot_read_d8(struct dpot_data *dpot)
97 {
98 	return dpot->bdata.bops->read_d8(dpot->bdata.client);
99 }
100 
101 static inline int dpot_read_r8d8(struct dpot_data *dpot, u8 reg)
102 {
103 	return dpot->bdata.bops->read_r8d8(dpot->bdata.client, reg);
104 }
105 
106 static inline int dpot_read_r8d16(struct dpot_data *dpot, u8 reg)
107 {
108 	return dpot->bdata.bops->read_r8d16(dpot->bdata.client, reg);
109 }
110 
111 static inline int dpot_write_d8(struct dpot_data *dpot, u8 val)
112 {
113 	return dpot->bdata.bops->write_d8(dpot->bdata.client, val);
114 }
115 
116 static inline int dpot_write_r8d8(struct dpot_data *dpot, u8 reg, u16 val)
117 {
118 	return dpot->bdata.bops->write_r8d8(dpot->bdata.client, reg, val);
119 }
120 
121 static inline int dpot_write_r8d16(struct dpot_data *dpot, u8 reg, u16 val)
122 {
123 	return dpot->bdata.bops->write_r8d16(dpot->bdata.client, reg, val);
124 }
125 
126 static s32 dpot_read_spi(struct dpot_data *dpot, u8 reg)
127 {
128 	unsigned ctrl = 0;
129 
130 	if (!(reg & (DPOT_ADDR_EEPROM | DPOT_ADDR_CMD))) {
131 
132 		if (dpot->feat & F_RDACS_WONLY)
133 			return dpot->rdac_cache[reg & DPOT_RDAC_MASK];
134 
135 		if (dpot->uid == DPOT_UID(AD5291_ID) ||
136 			dpot->uid == DPOT_UID(AD5292_ID) ||
137 			dpot->uid == DPOT_UID(AD5293_ID))
138 			return dpot_read_r8d8(dpot,
139 				DPOT_AD5291_READ_RDAC << 2);
140 
141 		ctrl = DPOT_SPI_READ_RDAC;
142 	} else if (reg & DPOT_ADDR_EEPROM) {
143 		ctrl = DPOT_SPI_READ_EEPROM;
144 	}
145 
146 	if (dpot->feat & F_SPI_16BIT)
147 		return dpot_read_r8d8(dpot, ctrl);
148 	else if (dpot->feat & F_SPI_24BIT)
149 		return dpot_read_r8d16(dpot, ctrl);
150 
151 	return -EFAULT;
152 }
153 
154 static s32 dpot_read_i2c(struct dpot_data *dpot, u8 reg)
155 {
156 	unsigned ctrl = 0;
157 	switch (dpot->uid) {
158 	case DPOT_UID(AD5246_ID):
159 	case DPOT_UID(AD5247_ID):
160 		return dpot_read_d8(dpot);
161 	case DPOT_UID(AD5245_ID):
162 	case DPOT_UID(AD5241_ID):
163 	case DPOT_UID(AD5242_ID):
164 	case DPOT_UID(AD5243_ID):
165 	case DPOT_UID(AD5248_ID):
166 	case DPOT_UID(AD5280_ID):
167 	case DPOT_UID(AD5282_ID):
168 		ctrl = ((reg & DPOT_RDAC_MASK) == DPOT_RDAC0) ?
169 			0 : DPOT_AD5291_RDAC_AB;
170 		return dpot_read_r8d8(dpot, ctrl);
171 	case DPOT_UID(AD5170_ID):
172 	case DPOT_UID(AD5171_ID):
173 	case DPOT_UID(AD5273_ID):
174 			return dpot_read_d8(dpot);
175 	case DPOT_UID(AD5172_ID):
176 	case DPOT_UID(AD5173_ID):
177 		ctrl = ((reg & DPOT_RDAC_MASK) == DPOT_RDAC0) ?
178 			0 : DPOT_AD5272_3_A0;
179 		return dpot_read_r8d8(dpot, ctrl);
180 	default:
181 		if ((reg & DPOT_REG_TOL) || (dpot->max_pos > 256))
182 			return dpot_read_r8d16(dpot, (reg & 0xF8) |
183 					((reg & 0x7) << 1));
184 		else
185 			return dpot_read_r8d8(dpot, reg);
186 	}
187 }
188 
189 static s32 dpot_read(struct dpot_data *dpot, u8 reg)
190 {
191 	if (dpot->feat & F_SPI)
192 		return dpot_read_spi(dpot, reg);
193 	else
194 		return dpot_read_i2c(dpot, reg);
195 }
196 
197 static s32 dpot_write_spi(struct dpot_data *dpot, u8 reg, u16 value)
198 {
199 	unsigned val = 0;
200 
201 	if (!(reg & (DPOT_ADDR_EEPROM | DPOT_ADDR_CMD))) {
202 		if (dpot->feat & F_RDACS_WONLY)
203 			dpot->rdac_cache[reg & DPOT_RDAC_MASK] = value;
204 
205 		if (dpot->feat & F_AD_APPDATA) {
206 			if (dpot->feat & F_SPI_8BIT) {
207 				val = ((reg & DPOT_RDAC_MASK) <<
208 					DPOT_MAX_POS(dpot->devid)) |
209 					value;
210 				return dpot_write_d8(dpot, val);
211 			} else if (dpot->feat & F_SPI_16BIT) {
212 				val = ((reg & DPOT_RDAC_MASK) <<
213 					DPOT_MAX_POS(dpot->devid)) |
214 					value;
215 				return dpot_write_r8d8(dpot, val >> 8,
216 					val & 0xFF);
217 			} else
218 				BUG();
219 		} else {
220 			if (dpot->uid == DPOT_UID(AD5291_ID) ||
221 				dpot->uid == DPOT_UID(AD5292_ID) ||
222 				dpot->uid == DPOT_UID(AD5293_ID))
223 				return dpot_write_r8d8(dpot,
224 					(DPOT_AD5291_RDAC << 2) |
225 					(value >> 8), value & 0xFF);
226 
227 			val = DPOT_SPI_RDAC | (reg & DPOT_RDAC_MASK);
228 		}
229 	} else if (reg & DPOT_ADDR_EEPROM) {
230 		val = DPOT_SPI_EEPROM | (reg & DPOT_RDAC_MASK);
231 	} else if (reg & DPOT_ADDR_CMD) {
232 		switch (reg) {
233 		case DPOT_DEC_ALL_6DB:
234 			val = DPOT_SPI_DEC_ALL_6DB;
235 			break;
236 		case DPOT_INC_ALL_6DB:
237 			val = DPOT_SPI_INC_ALL_6DB;
238 			break;
239 		case DPOT_DEC_ALL:
240 			val = DPOT_SPI_DEC_ALL;
241 			break;
242 		case DPOT_INC_ALL:
243 			val = DPOT_SPI_INC_ALL;
244 			break;
245 		}
246 	} else
247 		BUG();
248 
249 	if (dpot->feat & F_SPI_16BIT)
250 		return dpot_write_r8d8(dpot, val, value);
251 	else if (dpot->feat & F_SPI_24BIT)
252 		return dpot_write_r8d16(dpot, val, value);
253 
254 	return -EFAULT;
255 }
256 
257 static s32 dpot_write_i2c(struct dpot_data *dpot, u8 reg, u16 value)
258 {
259 	/* Only write the instruction byte for certain commands */
260 	unsigned tmp = 0, ctrl = 0;
261 
262 	switch (dpot->uid) {
263 	case DPOT_UID(AD5246_ID):
264 	case DPOT_UID(AD5247_ID):
265 		return dpot_write_d8(dpot, value);
266 		break;
267 
268 	case DPOT_UID(AD5245_ID):
269 	case DPOT_UID(AD5241_ID):
270 	case DPOT_UID(AD5242_ID):
271 	case DPOT_UID(AD5243_ID):
272 	case DPOT_UID(AD5248_ID):
273 	case DPOT_UID(AD5280_ID):
274 	case DPOT_UID(AD5282_ID):
275 		ctrl = ((reg & DPOT_RDAC_MASK) == DPOT_RDAC0) ?
276 			0 : DPOT_AD5291_RDAC_AB;
277 		return dpot_write_r8d8(dpot, ctrl, value);
278 		break;
279 	case DPOT_UID(AD5171_ID):
280 	case DPOT_UID(AD5273_ID):
281 		if (reg & DPOT_ADDR_OTP) {
282 			tmp = dpot_read_d8(dpot);
283 			if (tmp >> 6) /* Ready to Program? */
284 				return -EFAULT;
285 			ctrl = DPOT_AD5273_FUSE;
286 		}
287 		return dpot_write_r8d8(dpot, ctrl, value);
288 		break;
289 	case DPOT_UID(AD5172_ID):
290 	case DPOT_UID(AD5173_ID):
291 		ctrl = ((reg & DPOT_RDAC_MASK) == DPOT_RDAC0) ?
292 			0 : DPOT_AD5272_3_A0;
293 		if (reg & DPOT_ADDR_OTP) {
294 			tmp = dpot_read_r8d16(dpot, ctrl);
295 			if (tmp >> 14) /* Ready to Program? */
296 				return -EFAULT;
297 			ctrl |= DPOT_AD5270_2_3_FUSE;
298 		}
299 		return dpot_write_r8d8(dpot, ctrl, value);
300 		break;
301 	case DPOT_UID(AD5170_ID):
302 		if (reg & DPOT_ADDR_OTP) {
303 			tmp = dpot_read_r8d16(dpot, tmp);
304 			if (tmp >> 14) /* Ready to Program? */
305 				return -EFAULT;
306 			ctrl = DPOT_AD5270_2_3_FUSE;
307 		}
308 		return dpot_write_r8d8(dpot, ctrl, value);
309 		break;
310 	default:
311 		if (reg & DPOT_ADDR_CMD)
312 			return dpot_write_d8(dpot, reg);
313 
314 		if (dpot->max_pos > 256)
315 			return dpot_write_r8d16(dpot, (reg & 0xF8) |
316 						((reg & 0x7) << 1), value);
317 		else
318 			/* All other registers require instruction + data bytes */
319 			return dpot_write_r8d8(dpot, reg, value);
320 	}
321 }
322 
323 
324 static s32 dpot_write(struct dpot_data *dpot, u8 reg, u16 value)
325 {
326 	if (dpot->feat & F_SPI)
327 		return dpot_write_spi(dpot, reg, value);
328 	else
329 		return dpot_write_i2c(dpot, reg, value);
330 }
331 
332 /* sysfs functions */
333 
334 static ssize_t sysfs_show_reg(struct device *dev,
335 			      struct device_attribute *attr,
336 			      char *buf, u32 reg)
337 {
338 	struct dpot_data *data = dev_get_drvdata(dev);
339 	s32 value;
340 
341 	if (reg & DPOT_ADDR_OTP_EN)
342 		return sprintf(buf, "%s\n",
343 			test_bit(DPOT_RDAC_MASK & reg, data->otp_en_mask) ?
344 			"enabled" : "disabled");
345 
346 
347 	mutex_lock(&data->update_lock);
348 	value = dpot_read(data, reg);
349 	mutex_unlock(&data->update_lock);
350 
351 	if (value < 0)
352 		return -EINVAL;
353 	/*
354 	 * Let someone else deal with converting this ...
355 	 * the tolerance is a two-byte value where the MSB
356 	 * is a sign + integer value, and the LSB is a
357 	 * decimal value.  See page 18 of the AD5258
358 	 * datasheet (Rev. A) for more details.
359 	 */
360 
361 	if (reg & DPOT_REG_TOL)
362 		return sprintf(buf, "0x%04x\n", value & 0xFFFF);
363 	else
364 		return sprintf(buf, "%u\n", value & data->rdac_mask);
365 }
366 
367 static ssize_t sysfs_set_reg(struct device *dev,
368 			     struct device_attribute *attr,
369 			     const char *buf, size_t count, u32 reg)
370 {
371 	struct dpot_data *data = dev_get_drvdata(dev);
372 	unsigned long value;
373 	int err;
374 
375 	if (reg & DPOT_ADDR_OTP_EN) {
376 		if (!strncmp(buf, "enabled", sizeof("enabled")))
377 			set_bit(DPOT_RDAC_MASK & reg, data->otp_en_mask);
378 		else
379 			clear_bit(DPOT_RDAC_MASK & reg, data->otp_en_mask);
380 
381 		return count;
382 	}
383 
384 	if ((reg & DPOT_ADDR_OTP) &&
385 		!test_bit(DPOT_RDAC_MASK & reg, data->otp_en_mask))
386 		return -EPERM;
387 
388 	err = strict_strtoul(buf, 10, &value);
389 	if (err)
390 		return err;
391 
392 	if (value > data->rdac_mask)
393 		value = data->rdac_mask;
394 
395 	mutex_lock(&data->update_lock);
396 	dpot_write(data, reg, value);
397 	if (reg & DPOT_ADDR_EEPROM)
398 		msleep(26);	/* Sleep while the EEPROM updates */
399 	else if (reg & DPOT_ADDR_OTP)
400 		msleep(400);	/* Sleep while the OTP updates */
401 	mutex_unlock(&data->update_lock);
402 
403 	return count;
404 }
405 
406 static ssize_t sysfs_do_cmd(struct device *dev,
407 			    struct device_attribute *attr,
408 			    const char *buf, size_t count, u32 reg)
409 {
410 	struct dpot_data *data = dev_get_drvdata(dev);
411 
412 	mutex_lock(&data->update_lock);
413 	dpot_write(data, reg, 0);
414 	mutex_unlock(&data->update_lock);
415 
416 	return count;
417 }
418 
419 /* ------------------------------------------------------------------------- */
420 
421 #define DPOT_DEVICE_SHOW(_name, _reg) static ssize_t \
422 show_##_name(struct device *dev, \
423 			  struct device_attribute *attr, char *buf) \
424 { \
425 	return sysfs_show_reg(dev, attr, buf, _reg); \
426 }
427 
428 #define DPOT_DEVICE_SET(_name, _reg) static ssize_t \
429 set_##_name(struct device *dev, \
430 			 struct device_attribute *attr, \
431 			 const char *buf, size_t count) \
432 { \
433 	return sysfs_set_reg(dev, attr, buf, count, _reg); \
434 }
435 
436 #define DPOT_DEVICE_SHOW_SET(name, reg) \
437 DPOT_DEVICE_SHOW(name, reg) \
438 DPOT_DEVICE_SET(name, reg) \
439 static DEVICE_ATTR(name, S_IWUSR | S_IRUGO, show_##name, set_##name);
440 
441 #define DPOT_DEVICE_SHOW_ONLY(name, reg) \
442 DPOT_DEVICE_SHOW(name, reg) \
443 static DEVICE_ATTR(name, S_IWUSR | S_IRUGO, show_##name, NULL);
444 
445 DPOT_DEVICE_SHOW_SET(rdac0, DPOT_ADDR_RDAC | DPOT_RDAC0);
446 DPOT_DEVICE_SHOW_SET(eeprom0, DPOT_ADDR_EEPROM | DPOT_RDAC0);
447 DPOT_DEVICE_SHOW_ONLY(tolerance0, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC0);
448 DPOT_DEVICE_SHOW_SET(otp0, DPOT_ADDR_OTP | DPOT_RDAC0);
449 DPOT_DEVICE_SHOW_SET(otp0en, DPOT_ADDR_OTP_EN | DPOT_RDAC0);
450 
451 DPOT_DEVICE_SHOW_SET(rdac1, DPOT_ADDR_RDAC | DPOT_RDAC1);
452 DPOT_DEVICE_SHOW_SET(eeprom1, DPOT_ADDR_EEPROM | DPOT_RDAC1);
453 DPOT_DEVICE_SHOW_ONLY(tolerance1, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC1);
454 DPOT_DEVICE_SHOW_SET(otp1, DPOT_ADDR_OTP | DPOT_RDAC1);
455 DPOT_DEVICE_SHOW_SET(otp1en, DPOT_ADDR_OTP_EN | DPOT_RDAC1);
456 
457 DPOT_DEVICE_SHOW_SET(rdac2, DPOT_ADDR_RDAC | DPOT_RDAC2);
458 DPOT_DEVICE_SHOW_SET(eeprom2, DPOT_ADDR_EEPROM | DPOT_RDAC2);
459 DPOT_DEVICE_SHOW_ONLY(tolerance2, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC2);
460 DPOT_DEVICE_SHOW_SET(otp2, DPOT_ADDR_OTP | DPOT_RDAC2);
461 DPOT_DEVICE_SHOW_SET(otp2en, DPOT_ADDR_OTP_EN | DPOT_RDAC2);
462 
463 DPOT_DEVICE_SHOW_SET(rdac3, DPOT_ADDR_RDAC | DPOT_RDAC3);
464 DPOT_DEVICE_SHOW_SET(eeprom3, DPOT_ADDR_EEPROM | DPOT_RDAC3);
465 DPOT_DEVICE_SHOW_ONLY(tolerance3, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC3);
466 DPOT_DEVICE_SHOW_SET(otp3, DPOT_ADDR_OTP | DPOT_RDAC3);
467 DPOT_DEVICE_SHOW_SET(otp3en, DPOT_ADDR_OTP_EN | DPOT_RDAC3);
468 
469 DPOT_DEVICE_SHOW_SET(rdac4, DPOT_ADDR_RDAC | DPOT_RDAC4);
470 DPOT_DEVICE_SHOW_SET(eeprom4, DPOT_ADDR_EEPROM | DPOT_RDAC4);
471 DPOT_DEVICE_SHOW_ONLY(tolerance4, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC4);
472 DPOT_DEVICE_SHOW_SET(otp4, DPOT_ADDR_OTP | DPOT_RDAC4);
473 DPOT_DEVICE_SHOW_SET(otp4en, DPOT_ADDR_OTP_EN | DPOT_RDAC4);
474 
475 DPOT_DEVICE_SHOW_SET(rdac5, DPOT_ADDR_RDAC | DPOT_RDAC5);
476 DPOT_DEVICE_SHOW_SET(eeprom5, DPOT_ADDR_EEPROM | DPOT_RDAC5);
477 DPOT_DEVICE_SHOW_ONLY(tolerance5, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC5);
478 DPOT_DEVICE_SHOW_SET(otp5, DPOT_ADDR_OTP | DPOT_RDAC5);
479 DPOT_DEVICE_SHOW_SET(otp5en, DPOT_ADDR_OTP_EN | DPOT_RDAC5);
480 
481 static const struct attribute *dpot_attrib_wipers[] = {
482 	&dev_attr_rdac0.attr,
483 	&dev_attr_rdac1.attr,
484 	&dev_attr_rdac2.attr,
485 	&dev_attr_rdac3.attr,
486 	&dev_attr_rdac4.attr,
487 	&dev_attr_rdac5.attr,
488 	NULL
489 };
490 
491 static const struct attribute *dpot_attrib_eeprom[] = {
492 	&dev_attr_eeprom0.attr,
493 	&dev_attr_eeprom1.attr,
494 	&dev_attr_eeprom2.attr,
495 	&dev_attr_eeprom3.attr,
496 	&dev_attr_eeprom4.attr,
497 	&dev_attr_eeprom5.attr,
498 	NULL
499 };
500 
501 static const struct attribute *dpot_attrib_otp[] = {
502 	&dev_attr_otp0.attr,
503 	&dev_attr_otp1.attr,
504 	&dev_attr_otp2.attr,
505 	&dev_attr_otp3.attr,
506 	&dev_attr_otp4.attr,
507 	&dev_attr_otp5.attr,
508 	NULL
509 };
510 
511 static const struct attribute *dpot_attrib_otp_en[] = {
512 	&dev_attr_otp0en.attr,
513 	&dev_attr_otp1en.attr,
514 	&dev_attr_otp2en.attr,
515 	&dev_attr_otp3en.attr,
516 	&dev_attr_otp4en.attr,
517 	&dev_attr_otp5en.attr,
518 	NULL
519 };
520 
521 static const struct attribute *dpot_attrib_tolerance[] = {
522 	&dev_attr_tolerance0.attr,
523 	&dev_attr_tolerance1.attr,
524 	&dev_attr_tolerance2.attr,
525 	&dev_attr_tolerance3.attr,
526 	&dev_attr_tolerance4.attr,
527 	&dev_attr_tolerance5.attr,
528 	NULL
529 };
530 
531 /* ------------------------------------------------------------------------- */
532 
533 #define DPOT_DEVICE_DO_CMD(_name, _cmd) static ssize_t \
534 set_##_name(struct device *dev, \
535 			 struct device_attribute *attr, \
536 			 const char *buf, size_t count) \
537 { \
538 	return sysfs_do_cmd(dev, attr, buf, count, _cmd); \
539 } \
540 static DEVICE_ATTR(_name, S_IWUSR | S_IRUGO, NULL, set_##_name);
541 
542 DPOT_DEVICE_DO_CMD(inc_all, DPOT_INC_ALL);
543 DPOT_DEVICE_DO_CMD(dec_all, DPOT_DEC_ALL);
544 DPOT_DEVICE_DO_CMD(inc_all_6db, DPOT_INC_ALL_6DB);
545 DPOT_DEVICE_DO_CMD(dec_all_6db, DPOT_DEC_ALL_6DB);
546 
547 static struct attribute *ad525x_attributes_commands[] = {
548 	&dev_attr_inc_all.attr,
549 	&dev_attr_dec_all.attr,
550 	&dev_attr_inc_all_6db.attr,
551 	&dev_attr_dec_all_6db.attr,
552 	NULL
553 };
554 
555 static const struct attribute_group ad525x_group_commands = {
556 	.attrs = ad525x_attributes_commands,
557 };
558 
559 __devinit int ad_dpot_add_files(struct device *dev,
560 		unsigned features, unsigned rdac)
561 {
562 	int err = sysfs_create_file(&dev->kobj,
563 		dpot_attrib_wipers[rdac]);
564 	if (features & F_CMD_EEP)
565 		err |= sysfs_create_file(&dev->kobj,
566 			dpot_attrib_eeprom[rdac]);
567 	if (features & F_CMD_TOL)
568 		err |= sysfs_create_file(&dev->kobj,
569 			dpot_attrib_tolerance[rdac]);
570 	if (features & F_CMD_OTP) {
571 		err |= sysfs_create_file(&dev->kobj,
572 			dpot_attrib_otp_en[rdac]);
573 		err |= sysfs_create_file(&dev->kobj,
574 			dpot_attrib_otp[rdac]);
575 	}
576 
577 	if (err)
578 		dev_err(dev, "failed to register sysfs hooks for RDAC%d\n",
579 			rdac);
580 
581 	return err;
582 }
583 
584 inline void ad_dpot_remove_files(struct device *dev,
585 		unsigned features, unsigned rdac)
586 {
587 	sysfs_remove_file(&dev->kobj,
588 		dpot_attrib_wipers[rdac]);
589 	if (features & F_CMD_EEP)
590 		sysfs_remove_file(&dev->kobj,
591 			dpot_attrib_eeprom[rdac]);
592 	if (features & F_CMD_TOL)
593 		sysfs_remove_file(&dev->kobj,
594 			dpot_attrib_tolerance[rdac]);
595 	if (features & F_CMD_OTP) {
596 		sysfs_remove_file(&dev->kobj,
597 			dpot_attrib_otp_en[rdac]);
598 		sysfs_remove_file(&dev->kobj,
599 			dpot_attrib_otp[rdac]);
600 	}
601 }
602 
603 __devinit int ad_dpot_probe(struct device *dev,
604 		struct ad_dpot_bus_data *bdata, const struct ad_dpot_id *id)
605 {
606 
607 	struct dpot_data *data;
608 	int i, err = 0;
609 
610 	data = kzalloc(sizeof(struct dpot_data), GFP_KERNEL);
611 	if (!data) {
612 		err = -ENOMEM;
613 		goto exit;
614 	}
615 
616 	dev_set_drvdata(dev, data);
617 	mutex_init(&data->update_lock);
618 
619 	data->bdata = *bdata;
620 	data->devid = id->devid;
621 
622 	data->max_pos = 1 << DPOT_MAX_POS(data->devid);
623 	data->rdac_mask = data->max_pos - 1;
624 	data->feat = DPOT_FEAT(data->devid);
625 	data->uid = DPOT_UID(data->devid);
626 	data->wipers = DPOT_WIPERS(data->devid);
627 
628 	for (i = DPOT_RDAC0; i < MAX_RDACS; i++)
629 		if (data->wipers & (1 << i)) {
630 			err = ad_dpot_add_files(dev, data->feat, i);
631 			if (err)
632 				goto exit_remove_files;
633 			/* power-up midscale */
634 			if (data->feat & F_RDACS_WONLY)
635 				data->rdac_cache[i] = data->max_pos / 2;
636 		}
637 
638 	if (data->feat & F_CMD_INC)
639 		err = sysfs_create_group(&dev->kobj, &ad525x_group_commands);
640 
641 	if (err) {
642 		dev_err(dev, "failed to register sysfs hooks\n");
643 		goto exit_free;
644 	}
645 
646 	dev_info(dev, "%s %d-Position Digital Potentiometer registered\n",
647 		 id->name, data->max_pos);
648 
649 	return 0;
650 
651 exit_remove_files:
652 	for (i = DPOT_RDAC0; i < MAX_RDACS; i++)
653 		if (data->wipers & (1 << i))
654 			ad_dpot_remove_files(dev, data->feat, i);
655 
656 exit_free:
657 	kfree(data);
658 	dev_set_drvdata(dev, NULL);
659 exit:
660 	dev_err(dev, "failed to create client for %s ID 0x%lX\n",
661 			id->name, id->devid);
662 	return err;
663 }
664 EXPORT_SYMBOL(ad_dpot_probe);
665 
666 __devexit int ad_dpot_remove(struct device *dev)
667 {
668 	struct dpot_data *data = dev_get_drvdata(dev);
669 	int i;
670 
671 	for (i = DPOT_RDAC0; i < MAX_RDACS; i++)
672 		if (data->wipers & (1 << i))
673 			ad_dpot_remove_files(dev, data->feat, i);
674 
675 	kfree(data);
676 
677 	return 0;
678 }
679 EXPORT_SYMBOL(ad_dpot_remove);
680 
681 
682 MODULE_AUTHOR("Chris Verges <chrisv@cyberswitching.com>, "
683 	      "Michael Hennerich <hennerich@blackfin.uclinux.org>");
684 MODULE_DESCRIPTION("Digital potentiometer driver");
685 MODULE_LICENSE("GPL");
686 MODULE_VERSION(DRIVER_VERSION);
687