Blame view

drivers/misc/ad525x_dpot.c 20.3 KB
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
1
  /*
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
2
3
   * ad525x_dpot: Driver for the Analog Devices digital potentiometers
   * Copyright (c) 2009-2010 Analog Devices, Inc.
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
4
5
6
7
8
9
10
11
12
13
   * Author: Michael Hennerich <hennerich@blackfin.uclinux.org>
   *
   * DEVID		#Wipers		#Positions 	Resistor Options (kOhm)
   * AD5258		1		64		1, 10, 50, 100
   * AD5259		1		256		5, 10, 50, 100
   * AD5251		2		64		1, 10, 50, 100
   * AD5252		2		256		1, 10, 50, 100
   * AD5255		3		512		25, 250
   * AD5253		4		64		1, 10, 50, 100
   * AD5254		4		256		1, 10, 50, 100
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
   * AD5160		1		256		5, 10, 50, 100
   * AD5161		1		256		5, 10, 50, 100
   * AD5162		2		256		2.5, 10, 50, 100
   * AD5165		1		256		100
   * AD5200		1		256		10, 50
   * AD5201		1		33		10, 50
   * AD5203		4		64		10, 100
   * AD5204		4		256		10, 50, 100
   * AD5206		6		256		10, 50, 100
   * AD5207		2		256		10, 50, 100
   * AD5231		1		1024		10, 50, 100
   * AD5232		2		256		10, 50, 100
   * AD5233		4		64		10, 50, 100
   * AD5235		2		1024		25, 250
   * AD5260		1		256		20, 50, 200
   * AD5262		2		256		20, 50, 200
   * AD5263		4		256		20, 50, 200
   * AD5290		1		256		10, 50, 100
a4bd39495   Michael Hennerich   drivers/misc/ad52...
32
33
34
   * AD5291		1		256		20, 50, 100  (20-TP)
   * AD5292		1		1024		20, 50, 100  (20-TP)
   * AD5293		1		1024		20, 50, 100
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
35
36
37
38
39
   * AD7376		1		128		10, 50, 100, 1M
   * AD8400		1		256		1, 10, 50, 100
   * AD8402		2		256		1, 10, 50, 100
   * AD8403		4		256		1, 10, 50, 100
   * ADN2850		3		512		25, 250
e3ae68476   Michael Hennerich   ad525x_dpot: add ...
40
41
42
43
44
45
46
   * AD5241		1		256		10, 100, 1M
   * AD5246		1		128		5, 10, 50, 100
   * AD5247		1		128		5, 10, 50, 100
   * AD5245		1		256		5, 10, 50, 100
   * AD5243		2		256		2.5, 10, 50, 100
   * AD5248		2		256		2.5, 10, 50, 100
   * AD5242		2		256		20, 50, 200
c74cba610   Michael Hennerich   ad525x_dpot: add ...
47
48
49
   * AD5280		1		256		20, 50, 200
   * AD5282		2		256		20, 50, 200
   * ADN2860		3		512		25, 250
59592d0cc   Michael Hennerich   ad525x_dpot: add ...
50
51
52
53
54
   * AD5273		1		64		1, 10, 50, 100 (OTP)
   * AD5171		1		64		5, 10, 50, 100 (OTP)
   * AD5170		1		256		2.5, 10, 50, 100 (OTP)
   * AD5172		2		256		2.5, 10, 50, 100 (OTP)
   * AD5173		2		256		2.5, 10, 50, 100 (OTP)
a4bd39495   Michael Hennerich   drivers/misc/ad52...
55
56
57
58
   * AD5270		1		1024		20, 50, 100 (50-TP)
   * AD5271		1		256		20, 50, 100 (50-TP)
   * AD5272		1		1024		20, 50, 100 (50-TP)
   * AD5274		1		256		20, 50, 100 (50-TP)
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
   *
   * See Documentation/misc-devices/ad525x_dpot.txt for more info.
   *
   * derived from ad5258.c
   * Copyright (c) 2009 Cyber Switching, Inc.
   * Author: Chris Verges <chrisv@cyberswitching.com>
   *
   * derived from ad5252.c
   * Copyright (c) 2006 Michael Hennerich <hennerich@blackfin.uclinux.org>
   *
   * Licensed under the GPL-2 or later.
   */
  
  #include <linux/module.h>
  #include <linux/device.h>
  #include <linux/kernel.h>
  #include <linux/init.h>
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
76
  #include <linux/delay.h>
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
77
  #include <linux/slab.h>
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
78

6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
79
  #define DRIVER_VERSION			"0.2"
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
80

6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
81
  #include "ad525x_dpot.h"
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
82
83
84
85
86
87
  
  /*
   * Client data (each client gets its own)
   */
  
  struct dpot_data {
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
88
  	struct ad_dpot_bus_data	bdata;
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
89
90
91
  	struct mutex update_lock;
  	unsigned rdac_mask;
  	unsigned max_pos;
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
92
93
94
95
  	unsigned long devid;
  	unsigned uid;
  	unsigned feat;
  	unsigned wipers;
59592d0cc   Michael Hennerich   ad525x_dpot: add ...
96
97
  	u16 rdac_cache[MAX_RDACS];
  	DECLARE_BITMAP(otp_en_mask, MAX_RDACS);
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
98
  };
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
  static inline int dpot_read_d8(struct dpot_data *dpot)
  {
  	return dpot->bdata.bops->read_d8(dpot->bdata.client);
  }
  
  static inline int dpot_read_r8d8(struct dpot_data *dpot, u8 reg)
  {
  	return dpot->bdata.bops->read_r8d8(dpot->bdata.client, reg);
  }
  
  static inline int dpot_read_r8d16(struct dpot_data *dpot, u8 reg)
  {
  	return dpot->bdata.bops->read_r8d16(dpot->bdata.client, reg);
  }
  
  static inline int dpot_write_d8(struct dpot_data *dpot, u8 val)
  {
  	return dpot->bdata.bops->write_d8(dpot->bdata.client, val);
  }
  
  static inline int dpot_write_r8d8(struct dpot_data *dpot, u8 reg, u16 val)
  {
  	return dpot->bdata.bops->write_r8d8(dpot->bdata.client, reg, val);
  }
  
  static inline int dpot_write_r8d16(struct dpot_data *dpot, u8 reg, u16 val)
  {
  	return dpot->bdata.bops->write_r8d16(dpot->bdata.client, reg, val);
  }
e3ae68476   Michael Hennerich   ad525x_dpot: add ...
128
  static s32 dpot_read_spi(struct dpot_data *dpot, u8 reg)
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
129
  {
e3ae68476   Michael Hennerich   ad525x_dpot: add ...
130
  	unsigned ctrl = 0;
a4bd39495   Michael Hennerich   drivers/misc/ad52...
131
  	int value;
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
132

e3ae68476   Michael Hennerich   ad525x_dpot: add ...
133
  	if (!(reg & (DPOT_ADDR_EEPROM | DPOT_ADDR_CMD))) {
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
134

e3ae68476   Michael Hennerich   ad525x_dpot: add ...
135
136
  		if (dpot->feat & F_RDACS_WONLY)
  			return dpot->rdac_cache[reg & DPOT_RDAC_MASK];
e3ae68476   Michael Hennerich   ad525x_dpot: add ...
137
138
  		if (dpot->uid == DPOT_UID(AD5291_ID) ||
  			dpot->uid == DPOT_UID(AD5292_ID) ||
a4bd39495   Michael Hennerich   drivers/misc/ad52...
139
140
141
  			dpot->uid == DPOT_UID(AD5293_ID)) {
  
  			value = dpot_read_r8d8(dpot,
e3ae68476   Michael Hennerich   ad525x_dpot: add ...
142
  				DPOT_AD5291_READ_RDAC << 2);
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
143

a4bd39495   Michael Hennerich   drivers/misc/ad52...
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
  			if (dpot->uid == DPOT_UID(AD5291_ID))
  				value = value >> 2;
  
  			return value;
  		} else if (dpot->uid == DPOT_UID(AD5270_ID) ||
  			dpot->uid == DPOT_UID(AD5271_ID)) {
  
  			value = dpot_read_r8d8(dpot,
  				DPOT_AD5270_1_2_4_READ_RDAC << 2);
  
  			if (value < 0)
  				return value;
  
  			if (dpot->uid == DPOT_UID(AD5271_ID))
  				value = value >> 2;
  
  			return value;
  		}
e3ae68476   Michael Hennerich   ad525x_dpot: add ...
162
163
164
165
  		ctrl = DPOT_SPI_READ_RDAC;
  	} else if (reg & DPOT_ADDR_EEPROM) {
  		ctrl = DPOT_SPI_READ_EEPROM;
  	}
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
166

e3ae68476   Michael Hennerich   ad525x_dpot: add ...
167
168
169
170
  	if (dpot->feat & F_SPI_16BIT)
  		return dpot_read_r8d8(dpot, ctrl);
  	else if (dpot->feat & F_SPI_24BIT)
  		return dpot_read_r8d16(dpot, ctrl);
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
171

e3ae68476   Michael Hennerich   ad525x_dpot: add ...
172
173
  	return -EFAULT;
  }
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
174

e3ae68476   Michael Hennerich   ad525x_dpot: add ...
175
176
  static s32 dpot_read_i2c(struct dpot_data *dpot, u8 reg)
  {
a4bd39495   Michael Hennerich   drivers/misc/ad52...
177
  	int value;
e3ae68476   Michael Hennerich   ad525x_dpot: add ...
178
179
180
181
182
183
184
185
186
187
  	unsigned ctrl = 0;
  	switch (dpot->uid) {
  	case DPOT_UID(AD5246_ID):
  	case DPOT_UID(AD5247_ID):
  		return dpot_read_d8(dpot);
  	case DPOT_UID(AD5245_ID):
  	case DPOT_UID(AD5241_ID):
  	case DPOT_UID(AD5242_ID):
  	case DPOT_UID(AD5243_ID):
  	case DPOT_UID(AD5248_ID):
c74cba610   Michael Hennerich   ad525x_dpot: add ...
188
189
  	case DPOT_UID(AD5280_ID):
  	case DPOT_UID(AD5282_ID):
e3ae68476   Michael Hennerich   ad525x_dpot: add ...
190
  		ctrl = ((reg & DPOT_RDAC_MASK) == DPOT_RDAC0) ?
5f400cf40   Michael Hennerich   drivers/misc/ad52...
191
  			0 : DPOT_AD5282_RDAC_AB;
e3ae68476   Michael Hennerich   ad525x_dpot: add ...
192
  		return dpot_read_r8d8(dpot, ctrl);
59592d0cc   Michael Hennerich   ad525x_dpot: add ...
193
194
195
196
197
198
199
  	case DPOT_UID(AD5170_ID):
  	case DPOT_UID(AD5171_ID):
  	case DPOT_UID(AD5273_ID):
  			return dpot_read_d8(dpot);
  	case DPOT_UID(AD5172_ID):
  	case DPOT_UID(AD5173_ID):
  		ctrl = ((reg & DPOT_RDAC_MASK) == DPOT_RDAC0) ?
5f400cf40   Michael Hennerich   drivers/misc/ad52...
200
  			0 : DPOT_AD5172_3_A0;
59592d0cc   Michael Hennerich   ad525x_dpot: add ...
201
  		return dpot_read_r8d8(dpot, ctrl);
a4bd39495   Michael Hennerich   drivers/misc/ad52...
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
  	case DPOT_UID(AD5272_ID):
  	case DPOT_UID(AD5274_ID):
  			dpot_write_r8d8(dpot,
  				(DPOT_AD5270_1_2_4_READ_RDAC << 2), 0);
  
  			value = dpot_read_r8d16(dpot,
  				DPOT_AD5270_1_2_4_RDAC << 2);
  
  			if (value < 0)
  				return value;
  			/*
  			 * AD5272/AD5274 returns high byte first, however
  			 * underling smbus expects low byte first.
  			 */
  			value = swab16(value);
  
  			if (dpot->uid == DPOT_UID(AD5271_ID))
  				value = value >> 2;
  		return value;
e3ae68476   Michael Hennerich   ad525x_dpot: add ...
221
  	default:
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
222
223
224
225
226
  		if ((reg & DPOT_REG_TOL) || (dpot->max_pos > 256))
  			return dpot_read_r8d16(dpot, (reg & 0xF8) |
  					((reg & 0x7) << 1));
  		else
  			return dpot_read_r8d8(dpot, reg);
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
227
  	}
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
228
  }
e3ae68476   Michael Hennerich   ad525x_dpot: add ...
229
230
231
232
233
234
235
236
237
  static s32 dpot_read(struct dpot_data *dpot, u8 reg)
  {
  	if (dpot->feat & F_SPI)
  		return dpot_read_spi(dpot, reg);
  	else
  		return dpot_read_i2c(dpot, reg);
  }
  
  static s32 dpot_write_spi(struct dpot_data *dpot, u8 reg, u16 value)
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
238
239
  {
  	unsigned val = 0;
a4bd39495   Michael Hennerich   drivers/misc/ad52...
240
  	if (!(reg & (DPOT_ADDR_EEPROM | DPOT_ADDR_CMD | DPOT_ADDR_OTP))) {
e3ae68476   Michael Hennerich   ad525x_dpot: add ...
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
  		if (dpot->feat & F_RDACS_WONLY)
  			dpot->rdac_cache[reg & DPOT_RDAC_MASK] = value;
  
  		if (dpot->feat & F_AD_APPDATA) {
  			if (dpot->feat & F_SPI_8BIT) {
  				val = ((reg & DPOT_RDAC_MASK) <<
  					DPOT_MAX_POS(dpot->devid)) |
  					value;
  				return dpot_write_d8(dpot, val);
  			} else if (dpot->feat & F_SPI_16BIT) {
  				val = ((reg & DPOT_RDAC_MASK) <<
  					DPOT_MAX_POS(dpot->devid)) |
  					value;
  				return dpot_write_r8d8(dpot, val >> 8,
  					val & 0xFF);
  			} else
  				BUG();
  		} else {
  			if (dpot->uid == DPOT_UID(AD5291_ID) ||
  				dpot->uid == DPOT_UID(AD5292_ID) ||
a4bd39495   Michael Hennerich   drivers/misc/ad52...
261
262
263
264
265
266
267
  				dpot->uid == DPOT_UID(AD5293_ID)) {
  
  				dpot_write_r8d8(dpot, DPOT_AD5291_CTRLREG << 2,
  						DPOT_AD5291_UNLOCK_CMD);
  
  				if (dpot->uid == DPOT_UID(AD5291_ID))
  					value = value << 2;
e3ae68476   Michael Hennerich   ad525x_dpot: add ...
268
269
270
  				return dpot_write_r8d8(dpot,
  					(DPOT_AD5291_RDAC << 2) |
  					(value >> 8), value & 0xFF);
a4bd39495   Michael Hennerich   drivers/misc/ad52...
271
272
273
274
275
276
277
278
  			} else if (dpot->uid == DPOT_UID(AD5270_ID) ||
  				dpot->uid == DPOT_UID(AD5271_ID)) {
  				dpot_write_r8d8(dpot,
  						DPOT_AD5270_1_2_4_CTRLREG << 2,
  						DPOT_AD5270_1_2_4_UNLOCK_CMD);
  
  				if (dpot->uid == DPOT_UID(AD5271_ID))
  					value = value << 2;
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
279

a4bd39495   Michael Hennerich   drivers/misc/ad52...
280
281
282
283
  				return dpot_write_r8d8(dpot,
  					(DPOT_AD5270_1_2_4_RDAC << 2) |
  					(value >> 8), value & 0xFF);
  			}
e3ae68476   Michael Hennerich   ad525x_dpot: add ...
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
  			val = DPOT_SPI_RDAC | (reg & DPOT_RDAC_MASK);
  		}
  	} else if (reg & DPOT_ADDR_EEPROM) {
  		val = DPOT_SPI_EEPROM | (reg & DPOT_RDAC_MASK);
  	} else if (reg & DPOT_ADDR_CMD) {
  		switch (reg) {
  		case DPOT_DEC_ALL_6DB:
  			val = DPOT_SPI_DEC_ALL_6DB;
  			break;
  		case DPOT_INC_ALL_6DB:
  			val = DPOT_SPI_INC_ALL_6DB;
  			break;
  		case DPOT_DEC_ALL:
  			val = DPOT_SPI_DEC_ALL;
  			break;
  		case DPOT_INC_ALL:
  			val = DPOT_SPI_INC_ALL;
  			break;
  		}
a4bd39495   Michael Hennerich   drivers/misc/ad52...
303
304
305
306
307
308
309
310
311
312
  	} else if (reg & DPOT_ADDR_OTP) {
  		if (dpot->uid == DPOT_UID(AD5291_ID) ||
  			dpot->uid == DPOT_UID(AD5292_ID)) {
  			return dpot_write_r8d8(dpot,
  				DPOT_AD5291_STORE_XTPM << 2, 0);
  		} else if (dpot->uid == DPOT_UID(AD5270_ID) ||
  			dpot->uid == DPOT_UID(AD5271_ID)) {
  			return dpot_write_r8d8(dpot,
  				DPOT_AD5270_1_2_4_STORE_XTPM << 2, 0);
  		}
e3ae68476   Michael Hennerich   ad525x_dpot: add ...
313
314
315
316
317
318
319
  	} else
  		BUG();
  
  	if (dpot->feat & F_SPI_16BIT)
  		return dpot_write_r8d8(dpot, val, value);
  	else if (dpot->feat & F_SPI_24BIT)
  		return dpot_write_r8d16(dpot, val, value);
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
320
321
322
  
  	return -EFAULT;
  }
e3ae68476   Michael Hennerich   ad525x_dpot: add ...
323
324
325
  static s32 dpot_write_i2c(struct dpot_data *dpot, u8 reg, u16 value)
  {
  	/* Only write the instruction byte for certain commands */
59592d0cc   Michael Hennerich   ad525x_dpot: add ...
326
  	unsigned tmp = 0, ctrl = 0;
e3ae68476   Michael Hennerich   ad525x_dpot: add ...
327
328
329
330
331
332
333
334
335
336
337
338
  
  	switch (dpot->uid) {
  	case DPOT_UID(AD5246_ID):
  	case DPOT_UID(AD5247_ID):
  		return dpot_write_d8(dpot, value);
  		break;
  
  	case DPOT_UID(AD5245_ID):
  	case DPOT_UID(AD5241_ID):
  	case DPOT_UID(AD5242_ID):
  	case DPOT_UID(AD5243_ID):
  	case DPOT_UID(AD5248_ID):
c74cba610   Michael Hennerich   ad525x_dpot: add ...
339
340
341
  	case DPOT_UID(AD5280_ID):
  	case DPOT_UID(AD5282_ID):
  		ctrl = ((reg & DPOT_RDAC_MASK) == DPOT_RDAC0) ?
5f400cf40   Michael Hennerich   drivers/misc/ad52...
342
  			0 : DPOT_AD5282_RDAC_AB;
e3ae68476   Michael Hennerich   ad525x_dpot: add ...
343
344
  		return dpot_write_r8d8(dpot, ctrl, value);
  		break;
59592d0cc   Michael Hennerich   ad525x_dpot: add ...
345
346
347
348
349
350
351
352
353
354
355
356
357
  	case DPOT_UID(AD5171_ID):
  	case DPOT_UID(AD5273_ID):
  		if (reg & DPOT_ADDR_OTP) {
  			tmp = dpot_read_d8(dpot);
  			if (tmp >> 6) /* Ready to Program? */
  				return -EFAULT;
  			ctrl = DPOT_AD5273_FUSE;
  		}
  		return dpot_write_r8d8(dpot, ctrl, value);
  		break;
  	case DPOT_UID(AD5172_ID):
  	case DPOT_UID(AD5173_ID):
  		ctrl = ((reg & DPOT_RDAC_MASK) == DPOT_RDAC0) ?
5f400cf40   Michael Hennerich   drivers/misc/ad52...
358
  			0 : DPOT_AD5172_3_A0;
59592d0cc   Michael Hennerich   ad525x_dpot: add ...
359
360
361
362
  		if (reg & DPOT_ADDR_OTP) {
  			tmp = dpot_read_r8d16(dpot, ctrl);
  			if (tmp >> 14) /* Ready to Program? */
  				return -EFAULT;
5f400cf40   Michael Hennerich   drivers/misc/ad52...
363
  			ctrl |= DPOT_AD5170_2_3_FUSE;
59592d0cc   Michael Hennerich   ad525x_dpot: add ...
364
365
366
367
368
369
370
371
  		}
  		return dpot_write_r8d8(dpot, ctrl, value);
  		break;
  	case DPOT_UID(AD5170_ID):
  		if (reg & DPOT_ADDR_OTP) {
  			tmp = dpot_read_r8d16(dpot, tmp);
  			if (tmp >> 14) /* Ready to Program? */
  				return -EFAULT;
a4bd39495   Michael Hennerich   drivers/misc/ad52...
372
  			ctrl = DPOT_AD5170_2_3_FUSE;
59592d0cc   Michael Hennerich   ad525x_dpot: add ...
373
374
375
  		}
  		return dpot_write_r8d8(dpot, ctrl, value);
  		break;
a4bd39495   Michael Hennerich   drivers/misc/ad52...
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
  	case DPOT_UID(AD5272_ID):
  	case DPOT_UID(AD5274_ID):
  		dpot_write_r8d8(dpot, DPOT_AD5270_1_2_4_CTRLREG << 2,
  				DPOT_AD5270_1_2_4_UNLOCK_CMD);
  
  		if (reg & DPOT_ADDR_OTP)
  			return dpot_write_r8d8(dpot,
  					DPOT_AD5270_1_2_4_STORE_XTPM << 2, 0);
  
  		if (dpot->uid == DPOT_UID(AD5274_ID))
  			value = value << 2;
  
  		return dpot_write_r8d8(dpot, (DPOT_AD5270_1_2_4_RDAC << 2) |
  				       (value >> 8), value & 0xFF);
  		break;
e3ae68476   Michael Hennerich   ad525x_dpot: add ...
391
  	default:
c74cba610   Michael Hennerich   ad525x_dpot: add ...
392
393
  		if (reg & DPOT_ADDR_CMD)
  			return dpot_write_d8(dpot, reg);
e3ae68476   Michael Hennerich   ad525x_dpot: add ...
394

c74cba610   Michael Hennerich   ad525x_dpot: add ...
395
396
397
398
399
400
  		if (dpot->max_pos > 256)
  			return dpot_write_r8d16(dpot, (reg & 0xF8) |
  						((reg & 0x7) << 1), value);
  		else
  			/* All other registers require instruction + data bytes */
  			return dpot_write_r8d8(dpot, reg, value);
e3ae68476   Michael Hennerich   ad525x_dpot: add ...
401
402
  	}
  }
e3ae68476   Michael Hennerich   ad525x_dpot: add ...
403
404
405
406
407
408
409
  static s32 dpot_write(struct dpot_data *dpot, u8 reg, u16 value)
  {
  	if (dpot->feat & F_SPI)
  		return dpot_write_spi(dpot, reg, value);
  	else
  		return dpot_write_i2c(dpot, reg, value);
  }
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
410
411
412
  /* sysfs functions */
  
  static ssize_t sysfs_show_reg(struct device *dev,
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
413
414
  			      struct device_attribute *attr,
  			      char *buf, u32 reg)
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
415
  {
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
416
  	struct dpot_data *data = dev_get_drvdata(dev);
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
417
  	s32 value;
59592d0cc   Michael Hennerich   ad525x_dpot: add ...
418
419
420
421
422
  	if (reg & DPOT_ADDR_OTP_EN)
  		return sprintf(buf, "%s
  ",
  			test_bit(DPOT_RDAC_MASK & reg, data->otp_en_mask) ?
  			"enabled" : "disabled");
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
423
  	mutex_lock(&data->update_lock);
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
424
  	value = dpot_read(data, reg);
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
425
426
427
428
429
430
431
432
433
434
435
  	mutex_unlock(&data->update_lock);
  
  	if (value < 0)
  		return -EINVAL;
  	/*
  	 * Let someone else deal with converting this ...
  	 * the tolerance is a two-byte value where the MSB
  	 * is a sign + integer value, and the LSB is a
  	 * decimal value.  See page 18 of the AD5258
  	 * datasheet (Rev. A) for more details.
  	 */
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
436
  	if (reg & DPOT_REG_TOL)
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
437
438
439
440
441
442
443
444
445
446
447
  		return sprintf(buf, "0x%04x
  ", value & 0xFFFF);
  	else
  		return sprintf(buf, "%u
  ", value & data->rdac_mask);
  }
  
  static ssize_t sysfs_set_reg(struct device *dev,
  			     struct device_attribute *attr,
  			     const char *buf, size_t count, u32 reg)
  {
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
448
  	struct dpot_data *data = dev_get_drvdata(dev);
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
449
450
  	unsigned long value;
  	int err;
59592d0cc   Michael Hennerich   ad525x_dpot: add ...
451
452
453
454
455
456
457
458
459
460
461
462
  	if (reg & DPOT_ADDR_OTP_EN) {
  		if (!strncmp(buf, "enabled", sizeof("enabled")))
  			set_bit(DPOT_RDAC_MASK & reg, data->otp_en_mask);
  		else
  			clear_bit(DPOT_RDAC_MASK & reg, data->otp_en_mask);
  
  		return count;
  	}
  
  	if ((reg & DPOT_ADDR_OTP) &&
  		!test_bit(DPOT_RDAC_MASK & reg, data->otp_en_mask))
  		return -EPERM;
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
463
464
465
466
467
468
469
470
  	err = strict_strtoul(buf, 10, &value);
  	if (err)
  		return err;
  
  	if (value > data->rdac_mask)
  		value = data->rdac_mask;
  
  	mutex_lock(&data->update_lock);
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
471
472
  	dpot_write(data, reg, value);
  	if (reg & DPOT_ADDR_EEPROM)
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
473
  		msleep(26);	/* Sleep while the EEPROM updates */
59592d0cc   Michael Hennerich   ad525x_dpot: add ...
474
475
  	else if (reg & DPOT_ADDR_OTP)
  		msleep(400);	/* Sleep while the OTP updates */
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
476
477
478
479
480
481
482
483
484
  	mutex_unlock(&data->update_lock);
  
  	return count;
  }
  
  static ssize_t sysfs_do_cmd(struct device *dev,
  			    struct device_attribute *attr,
  			    const char *buf, size_t count, u32 reg)
  {
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
485
  	struct dpot_data *data = dev_get_drvdata(dev);
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
486
487
  
  	mutex_lock(&data->update_lock);
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
488
  	dpot_write(data, reg, 0);
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
489
490
491
492
493
494
  	mutex_unlock(&data->update_lock);
  
  	return count;
  }
  
  /* ------------------------------------------------------------------------- */
0993dbedf   Michael Hennerich   ad525x_dpot: simp...
495
496
497
498
499
  #define DPOT_DEVICE_SHOW(_name, _reg) static ssize_t \
  show_##_name(struct device *dev, \
  			  struct device_attribute *attr, char *buf) \
  { \
  	return sysfs_show_reg(dev, attr, buf, _reg); \
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
500
  }
0993dbedf   Michael Hennerich   ad525x_dpot: simp...
501
502
503
504
505
506
  #define DPOT_DEVICE_SET(_name, _reg) static ssize_t \
  set_##_name(struct device *dev, \
  			 struct device_attribute *attr, \
  			 const char *buf, size_t count) \
  { \
  	return sysfs_set_reg(dev, attr, buf, count, _reg); \
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
507
  }
0993dbedf   Michael Hennerich   ad525x_dpot: simp...
508
509
510
511
  #define DPOT_DEVICE_SHOW_SET(name, reg) \
  DPOT_DEVICE_SHOW(name, reg) \
  DPOT_DEVICE_SET(name, reg) \
  static DEVICE_ATTR(name, S_IWUSR | S_IRUGO, show_##name, set_##name);
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
512

0993dbedf   Michael Hennerich   ad525x_dpot: simp...
513
514
515
  #define DPOT_DEVICE_SHOW_ONLY(name, reg) \
  DPOT_DEVICE_SHOW(name, reg) \
  static DEVICE_ATTR(name, S_IWUSR | S_IRUGO, show_##name, NULL);
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
516

6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
517
518
519
  DPOT_DEVICE_SHOW_SET(rdac0, DPOT_ADDR_RDAC | DPOT_RDAC0);
  DPOT_DEVICE_SHOW_SET(eeprom0, DPOT_ADDR_EEPROM | DPOT_RDAC0);
  DPOT_DEVICE_SHOW_ONLY(tolerance0, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC0);
59592d0cc   Michael Hennerich   ad525x_dpot: add ...
520
521
  DPOT_DEVICE_SHOW_SET(otp0, DPOT_ADDR_OTP | DPOT_RDAC0);
  DPOT_DEVICE_SHOW_SET(otp0en, DPOT_ADDR_OTP_EN | DPOT_RDAC0);
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
522
523
524
525
  
  DPOT_DEVICE_SHOW_SET(rdac1, DPOT_ADDR_RDAC | DPOT_RDAC1);
  DPOT_DEVICE_SHOW_SET(eeprom1, DPOT_ADDR_EEPROM | DPOT_RDAC1);
  DPOT_DEVICE_SHOW_ONLY(tolerance1, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC1);
59592d0cc   Michael Hennerich   ad525x_dpot: add ...
526
527
  DPOT_DEVICE_SHOW_SET(otp1, DPOT_ADDR_OTP | DPOT_RDAC1);
  DPOT_DEVICE_SHOW_SET(otp1en, DPOT_ADDR_OTP_EN | DPOT_RDAC1);
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
528
529
530
531
  
  DPOT_DEVICE_SHOW_SET(rdac2, DPOT_ADDR_RDAC | DPOT_RDAC2);
  DPOT_DEVICE_SHOW_SET(eeprom2, DPOT_ADDR_EEPROM | DPOT_RDAC2);
  DPOT_DEVICE_SHOW_ONLY(tolerance2, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC2);
59592d0cc   Michael Hennerich   ad525x_dpot: add ...
532
533
  DPOT_DEVICE_SHOW_SET(otp2, DPOT_ADDR_OTP | DPOT_RDAC2);
  DPOT_DEVICE_SHOW_SET(otp2en, DPOT_ADDR_OTP_EN | DPOT_RDAC2);
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
534
535
536
537
  
  DPOT_DEVICE_SHOW_SET(rdac3, DPOT_ADDR_RDAC | DPOT_RDAC3);
  DPOT_DEVICE_SHOW_SET(eeprom3, DPOT_ADDR_EEPROM | DPOT_RDAC3);
  DPOT_DEVICE_SHOW_ONLY(tolerance3, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC3);
59592d0cc   Michael Hennerich   ad525x_dpot: add ...
538
539
  DPOT_DEVICE_SHOW_SET(otp3, DPOT_ADDR_OTP | DPOT_RDAC3);
  DPOT_DEVICE_SHOW_SET(otp3en, DPOT_ADDR_OTP_EN | DPOT_RDAC3);
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
540
541
542
543
  
  DPOT_DEVICE_SHOW_SET(rdac4, DPOT_ADDR_RDAC | DPOT_RDAC4);
  DPOT_DEVICE_SHOW_SET(eeprom4, DPOT_ADDR_EEPROM | DPOT_RDAC4);
  DPOT_DEVICE_SHOW_ONLY(tolerance4, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC4);
59592d0cc   Michael Hennerich   ad525x_dpot: add ...
544
545
  DPOT_DEVICE_SHOW_SET(otp4, DPOT_ADDR_OTP | DPOT_RDAC4);
  DPOT_DEVICE_SHOW_SET(otp4en, DPOT_ADDR_OTP_EN | DPOT_RDAC4);
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
546
547
548
549
  
  DPOT_DEVICE_SHOW_SET(rdac5, DPOT_ADDR_RDAC | DPOT_RDAC5);
  DPOT_DEVICE_SHOW_SET(eeprom5, DPOT_ADDR_EEPROM | DPOT_RDAC5);
  DPOT_DEVICE_SHOW_ONLY(tolerance5, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC5);
59592d0cc   Michael Hennerich   ad525x_dpot: add ...
550
551
  DPOT_DEVICE_SHOW_SET(otp5, DPOT_ADDR_OTP | DPOT_RDAC5);
  DPOT_DEVICE_SHOW_SET(otp5en, DPOT_ADDR_OTP_EN | DPOT_RDAC5);
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
  
  static const struct attribute *dpot_attrib_wipers[] = {
  	&dev_attr_rdac0.attr,
  	&dev_attr_rdac1.attr,
  	&dev_attr_rdac2.attr,
  	&dev_attr_rdac3.attr,
  	&dev_attr_rdac4.attr,
  	&dev_attr_rdac5.attr,
  	NULL
  };
  
  static const struct attribute *dpot_attrib_eeprom[] = {
  	&dev_attr_eeprom0.attr,
  	&dev_attr_eeprom1.attr,
  	&dev_attr_eeprom2.attr,
  	&dev_attr_eeprom3.attr,
  	&dev_attr_eeprom4.attr,
  	&dev_attr_eeprom5.attr,
  	NULL
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
571
  };
59592d0cc   Michael Hennerich   ad525x_dpot: add ...
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
  static const struct attribute *dpot_attrib_otp[] = {
  	&dev_attr_otp0.attr,
  	&dev_attr_otp1.attr,
  	&dev_attr_otp2.attr,
  	&dev_attr_otp3.attr,
  	&dev_attr_otp4.attr,
  	&dev_attr_otp5.attr,
  	NULL
  };
  
  static const struct attribute *dpot_attrib_otp_en[] = {
  	&dev_attr_otp0en.attr,
  	&dev_attr_otp1en.attr,
  	&dev_attr_otp2en.attr,
  	&dev_attr_otp3en.attr,
  	&dev_attr_otp4en.attr,
  	&dev_attr_otp5en.attr,
  	NULL
  };
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
591
592
593
594
595
596
597
598
  static const struct attribute *dpot_attrib_tolerance[] = {
  	&dev_attr_tolerance0.attr,
  	&dev_attr_tolerance1.attr,
  	&dev_attr_tolerance2.attr,
  	&dev_attr_tolerance3.attr,
  	&dev_attr_tolerance4.attr,
  	&dev_attr_tolerance5.attr,
  	NULL
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
599
600
601
  };
  
  /* ------------------------------------------------------------------------- */
0993dbedf   Michael Hennerich   ad525x_dpot: simp...
602
603
604
605
606
607
608
609
  #define DPOT_DEVICE_DO_CMD(_name, _cmd) static ssize_t \
  set_##_name(struct device *dev, \
  			 struct device_attribute *attr, \
  			 const char *buf, size_t count) \
  { \
  	return sysfs_do_cmd(dev, attr, buf, count, _cmd); \
  } \
  static DEVICE_ATTR(_name, S_IWUSR | S_IRUGO, NULL, set_##_name);
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
610
611
612
613
  DPOT_DEVICE_DO_CMD(inc_all, DPOT_INC_ALL);
  DPOT_DEVICE_DO_CMD(dec_all, DPOT_DEC_ALL);
  DPOT_DEVICE_DO_CMD(inc_all_6db, DPOT_INC_ALL_6DB);
  DPOT_DEVICE_DO_CMD(dec_all_6db, DPOT_DEC_ALL_6DB);
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
614
615
616
617
618
619
620
621
622
623
624
625
  
  static struct attribute *ad525x_attributes_commands[] = {
  	&dev_attr_inc_all.attr,
  	&dev_attr_dec_all.attr,
  	&dev_attr_inc_all_6db.attr,
  	&dev_attr_dec_all_6db.attr,
  	NULL
  };
  
  static const struct attribute_group ad525x_group_commands = {
  	.attrs = ad525x_attributes_commands,
  };
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
626
627
  __devinit int ad_dpot_add_files(struct device *dev,
  		unsigned features, unsigned rdac)
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
628
  {
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
629
630
631
632
633
634
635
636
  	int err = sysfs_create_file(&dev->kobj,
  		dpot_attrib_wipers[rdac]);
  	if (features & F_CMD_EEP)
  		err |= sysfs_create_file(&dev->kobj,
  			dpot_attrib_eeprom[rdac]);
  	if (features & F_CMD_TOL)
  		err |= sysfs_create_file(&dev->kobj,
  			dpot_attrib_tolerance[rdac]);
59592d0cc   Michael Hennerich   ad525x_dpot: add ...
637
638
639
640
641
642
  	if (features & F_CMD_OTP) {
  		err |= sysfs_create_file(&dev->kobj,
  			dpot_attrib_otp_en[rdac]);
  		err |= sysfs_create_file(&dev->kobj,
  			dpot_attrib_otp[rdac]);
  	}
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
643

6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
644
645
646
647
648
649
  	if (err)
  		dev_err(dev, "failed to register sysfs hooks for RDAC%d
  ",
  			rdac);
  
  	return err;
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
650
  }
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
651
652
  inline void ad_dpot_remove_files(struct device *dev,
  		unsigned features, unsigned rdac)
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
653
  {
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
654
655
656
657
658
659
660
661
  	sysfs_remove_file(&dev->kobj,
  		dpot_attrib_wipers[rdac]);
  	if (features & F_CMD_EEP)
  		sysfs_remove_file(&dev->kobj,
  			dpot_attrib_eeprom[rdac]);
  	if (features & F_CMD_TOL)
  		sysfs_remove_file(&dev->kobj,
  			dpot_attrib_tolerance[rdac]);
59592d0cc   Michael Hennerich   ad525x_dpot: add ...
662
663
664
665
666
667
  	if (features & F_CMD_OTP) {
  		sysfs_remove_file(&dev->kobj,
  			dpot_attrib_otp_en[rdac]);
  		sysfs_remove_file(&dev->kobj,
  			dpot_attrib_otp[rdac]);
  	}
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
668
  }
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
669
670
  __devinit int ad_dpot_probe(struct device *dev,
  		struct ad_dpot_bus_data *bdata, const struct ad_dpot_id *id)
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
671
  {
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
672

6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
673
674
  	struct dpot_data *data;
  	int i, err = 0;
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
675
676
677
678
679
680
  
  	data = kzalloc(sizeof(struct dpot_data), GFP_KERNEL);
  	if (!data) {
  		err = -ENOMEM;
  		goto exit;
  	}
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
681
  	dev_set_drvdata(dev, data);
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
682
  	mutex_init(&data->update_lock);
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
683
684
685
686
687
688
689
690
  	data->bdata = *bdata;
  	data->devid = id->devid;
  
  	data->max_pos = 1 << DPOT_MAX_POS(data->devid);
  	data->rdac_mask = data->max_pos - 1;
  	data->feat = DPOT_FEAT(data->devid);
  	data->uid = DPOT_UID(data->devid);
  	data->wipers = DPOT_WIPERS(data->devid);
59592d0cc   Michael Hennerich   ad525x_dpot: add ...
691
  	for (i = DPOT_RDAC0; i < MAX_RDACS; i++)
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
692
693
694
695
696
697
698
699
700
701
702
  		if (data->wipers & (1 << i)) {
  			err = ad_dpot_add_files(dev, data->feat, i);
  			if (err)
  				goto exit_remove_files;
  			/* power-up midscale */
  			if (data->feat & F_RDACS_WONLY)
  				data->rdac_cache[i] = data->max_pos / 2;
  		}
  
  	if (data->feat & F_CMD_INC)
  		err = sysfs_create_group(&dev->kobj, &ad525x_group_commands);
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
703
704
705
706
707
708
  
  	if (err) {
  		dev_err(dev, "failed to register sysfs hooks
  ");
  		goto exit_free;
  	}
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
709
710
711
712
713
  	dev_info(dev, "%s %d-Position Digital Potentiometer registered
  ",
  		 id->name, data->max_pos);
  
  	return 0;
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
714
  exit_remove_files:
59592d0cc   Michael Hennerich   ad525x_dpot: add ...
715
  	for (i = DPOT_RDAC0; i < MAX_RDACS; i++)
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
716
717
  		if (data->wipers & (1 << i))
  			ad_dpot_remove_files(dev, data->feat, i);
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
718
719
  exit_free:
  	kfree(data);
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
720
  	dev_set_drvdata(dev, NULL);
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
721
  exit:
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
722
723
724
  	dev_err(dev, "failed to create client for %s ID 0x%lX
  ",
  			id->name, id->devid);
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
725
726
  	return err;
  }
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
727
  EXPORT_SYMBOL(ad_dpot_probe);
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
728

6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
729
  __devexit int ad_dpot_remove(struct device *dev)
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
730
  {
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
731
732
  	struct dpot_data *data = dev_get_drvdata(dev);
  	int i;
59592d0cc   Michael Hennerich   ad525x_dpot: add ...
733
  	for (i = DPOT_RDAC0; i < MAX_RDACS; i++)
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
734
735
  		if (data->wipers & (1 << i))
  			ad_dpot_remove_files(dev, data->feat, i);
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
736

4eb174bee   Michael Hennerich   ad525x_dpot: new ...
737
738
739
740
  	kfree(data);
  
  	return 0;
  }
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
741
  EXPORT_SYMBOL(ad_dpot_remove);
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
742

4eb174bee   Michael Hennerich   ad525x_dpot: new ...
743
744
  
  MODULE_AUTHOR("Chris Verges <chrisv@cyberswitching.com>, "
6c536e4ce   Michael Hennerich   ad525x_dpot: add ...
745
746
  	      "Michael Hennerich <hennerich@blackfin.uclinux.org>");
  MODULE_DESCRIPTION("Digital potentiometer driver");
4eb174bee   Michael Hennerich   ad525x_dpot: new ...
747
748
  MODULE_LICENSE("GPL");
  MODULE_VERSION(DRIVER_VERSION);