Unreachable code
File: drivers/misc/.tmp_ad525x_dpot.o.preproc
Full description: The code is unreachable by any path. Superfluous semicolon, break or return statement.
Importance: 3
Checker: ReachabilityChecker
Trace:
This one is:
False positive index (the lower the better): 0
File contents (this file is distributed under the terms specified in the original file):
1|struct dpot_data {
2| struct ad_dpot_bus_data bdata;
3| struct mutex update_lock;
4| unsigned rdac_mask;
5| unsigned max_pos;
6| unsigned long devid;
7| unsigned uid;
8| unsigned feat;
9| unsigned wipers;
10| u16 rdac_cache[6];
11| unsigned long otp_en_mask[(((6) + (8 * sizeof(long)) - 1) / (8 * sizeof(long)))];
12|};
13|
14|static inline int dpot_read_d8(struct dpot_data *dpot)
15|{
16| return dpot->bdata.bops->read_d8(dpot->bdata.client);
17|}
18|
19|static inline int dpot_read_r8d8(struct dpot_data *dpot, u8 reg)
20|{
21| return dpot->bdata.bops->read_r8d8(dpot->bdata.client, reg);
22|}
23|
24|static inline int dpot_read_r8d16(struct dpot_data *dpot, u8 reg)
25|{
26| return dpot->bdata.bops->read_r8d16(dpot->bdata.client, reg);
27|}
28|
29|static inline int dpot_write_d8(struct dpot_data *dpot, u8 val)
30|{
31| return dpot->bdata.bops->write_d8(dpot->bdata.client, val);
32|}
33|
34|static inline int dpot_write_r8d8(struct dpot_data *dpot, u8 reg, u16 val)
35|{
36| return dpot->bdata.bops->write_r8d8(dpot->bdata.client, reg, val);
37|}
38|
39|static inline int dpot_write_r8d16(struct dpot_data *dpot, u8 reg, u16 val)
40|{
41| return dpot->bdata.bops->write_r8d16(dpot->bdata.client, reg, val);
42|}
43|
44|static s32 dpot_read_spi(struct dpot_data *dpot, u8 reg)
45|{
46| unsigned ctrl = 0;
47| int value;
48|
49| if (!(reg & ((0x1 << 5) | (0x1 << 7)))) {
50|
51| if (dpot->feat & (1 << 5))
52| return dpot->rdac_cache[reg & 0x1F];
53| if (dpot->uid == (AD5291_ID & 0x3F) ||
54| dpot->uid == (AD5292_ID & 0x3F) ||
55| dpot->uid == (AD5293_ID & 0x3F)) {
56|
57| value = dpot_read_r8d8(dpot,
58| 0x02 << 2);
59|
60| if (dpot->uid == (AD5291_ID & 0x3F))
61| value = value >> 2;
62|
63| return value;
64| } else if (dpot->uid == (AD5270_ID & 0x3F) ||
65| dpot->uid == (AD5271_ID & 0x3F)) {
66|
67| value = dpot_read_r8d8(dpot,
68| 0x02 << 2);
69|
70| if (value < 0)
71| return value;
72|
73| if (dpot->uid == (AD5271_ID & 0x3F))
74| value = value >> 2;
75|
76| return value;
77| }
78|
79| ctrl = 0xA0;
80| } else if (reg & (0x1 << 5)) {
81| ctrl = 0x90;
82| }
83|
84| if (dpot->feat & (1 << 8))
85| return dpot_read_r8d8(dpot, ctrl);
86| else if (dpot->feat & (1 << 9))
87| return dpot_read_r8d16(dpot, ctrl);
88|
89| return -14;
90|}
91|
92|static s32 dpot_read_i2c(struct dpot_data *dpot, u8 reg)
93|{
94| int value;
95| unsigned ctrl = 0;
96| switch (dpot->uid) {
97| case (AD5246_ID & 0x3F):
98| case (AD5247_ID & 0x3F):
99| return dpot_read_d8(dpot);
100| case (AD5245_ID & 0x3F):
101| case (AD5241_ID & 0x3F):
102| case (AD5242_ID & 0x3F):
103| case (AD5243_ID & 0x3F):
104| case (AD5248_ID & 0x3F):
105| case (AD5280_ID & 0x3F):
106| case (AD5282_ID & 0x3F):
107| ctrl = ((reg & 0x1F) == 0) ?
108| 0 : 0x80;
109| return dpot_read_r8d8(dpot, ctrl);
110| case (AD5170_ID & 0x3F):
111| case (AD5171_ID & 0x3F):
112| case (AD5273_ID & 0x3F):
113| return dpot_read_d8(dpot);
114| case (AD5172_ID & 0x3F):
115| case (AD5173_ID & 0x3F):
116| ctrl = ((reg & 0x1F) == 0) ?
117| 0 : 0x08;
118| return dpot_read_r8d8(dpot, ctrl);
119| case (AD5272_ID & 0x3F):
120| case (AD5274_ID & 0x3F):
121| dpot_write_r8d8(dpot,
122| (0x02 << 2), 0);
123|
124| value = dpot_read_r8d16(dpot,
125| 0x01 << 2);
126|
127| if (value < 0)
128| return value;
129|
130|
131|
132|
133| value = (__builtin_constant_p((__u16)(value)) ? ((__u16)( (((__u16)(value) & (__u16)0x00ffU) << 8) | (((__u16)(value) & (__u16)0xff00U) >> 8))) : __fswab16(value));
134|
135| if (dpot->uid == (AD5271_ID & 0x3F))
136| value = value >> 2;
137| return value;
138| default:
139| if ((reg & 0x18) || (dpot->max_pos > 256))
140| return dpot_read_r8d16(dpot, (reg & 0xF8) |
141| ((reg & 0x7) << 1));
142| else
143| return dpot_read_r8d8(dpot, reg);
144| }
145|}
146|
147|static s32 dpot_read(struct dpot_data *dpot, u8 reg)
148|{
149| if (dpot->feat & ((1 << 7) | (1 << 8) | (1 << 9)))
150| return dpot_read_spi(dpot, reg);
151| else
152| return dpot_read_i2c(dpot, reg);
153|}
154|
155|static s32 dpot_write_spi(struct dpot_data *dpot, u8 reg, u16 value)
156|{
157| unsigned val = 0;
158|
159| if (!(reg & ((0x1 << 5) | (0x1 << 7) | (0x1 << 6)))) {
160| if (dpot->feat & (1 << 5))
161| dpot->rdac_cache[reg & 0x1F] = value;
162|
163| if (dpot->feat & (1 << 6)) {
164| if (dpot->feat & (1 << 7)) {
165| val = ((reg & 0x1F) <<
166| ((dpot->devid >> 6) & 0xF)) |
167| value;
168| return dpot_write_d8(dpot, val);
169| } else if (dpot->feat & (1 << 8)) {
170| val = ((reg & 0x1F) <<
171| ((dpot->devid >> 6) & 0xF)) |
172| value;
173| return dpot_write_r8d8(dpot, val >> 8,
174| val & 0xFF);
175| } else
176| __st_BUG_st__();
177| } else {
178| if (dpot->uid == (AD5291_ID & 0x3F) ||
179| dpot->uid == (AD5292_ID & 0x3F) ||
180| dpot->uid == (AD5293_ID & 0x3F)) {
181|
182| dpot_write_r8d8(dpot, 0x06 << 2,
183| 0x03);
184|
185| if (dpot->uid == (AD5291_ID & 0x3F))
186| value = value << 2;
187|
188| return dpot_write_r8d8(dpot,
189| (0x01 << 2) |
190| (value >> 8), value & 0xFF);
191| } else if (dpot->uid == (AD5270_ID & 0x3F) ||
192| dpot->uid == (AD5271_ID & 0x3F)) {
193| dpot_write_r8d8(dpot,
194| 0x07 << 2,
195| 0x03);
196|
197| if (dpot->uid == (AD5271_ID & 0x3F))
198| value = value << 2;
199|
200| return dpot_write_r8d8(dpot,
201| (0x01 << 2) |
202| (value >> 8), value & 0xFF);
203| }
204| val = 0xB0 | (reg & 0x1F);
205| }
206| } else if (reg & (0x1 << 5)) {
207| val = 0x30 | (reg & 0x1F);
208| } else if (reg & (0x1 << 7)) {
209| switch (reg) {
210| case ((0x1 << 7) | (0x4 << 3)):
211| val = 0x50;
212| break;
213| case ((0x1 << 7) | (0x9 << 3)):
214| val = 0xD0;
215| break;
216| case ((0x1 << 7) | (0x6 << 3)):
217| val = 0x70;
218| break;
219| case ((0x1 << 7) | (0xB << 3)):
220| val = 0xF0;
221| break;
222| }
223| } else if (reg & (0x1 << 6)) {
224| if (dpot->uid == (AD5291_ID & 0x3F) ||
225| dpot->uid == (AD5292_ID & 0x3F)) {
226| return dpot_write_r8d8(dpot,
227| 0x03 << 2, 0);
228| } else if (dpot->uid == (AD5270_ID & 0x3F) ||
229| dpot->uid == (AD5271_ID & 0x3F)) {
230| return dpot_write_r8d8(dpot,
231| 0x03 << 2, 0);
232| }
233| } else
234| __st_BUG_st__();
235|
236| if (dpot->feat & (1 << 8))
237| return dpot_write_r8d8(dpot, val, value);
238| else if (dpot->feat & (1 << 9))
239| return dpot_write_r8d16(dpot, val, value);
240|
241| return -14;
242|}
243|
244|static s32 dpot_write_i2c(struct dpot_data *dpot, u8 reg, u16 value)
245|{
246|
247| unsigned tmp = 0, ctrl = 0;
248|
249| switch (dpot->uid) {
250| case (AD5246_ID & 0x3F):
251| case (AD5247_ID & 0x3F):
252| return dpot_write_d8(dpot, value);
253| break;
|This node is unreachable prev next
254|
255| case (AD5245_ID & 0x3F):
256| case (AD5241_ID & 0x3F):
257| case (AD5242_ID & 0x3F):
258| case (AD5243_ID & 0x3F):
259| case (AD5248_ID & 0x3F):
260| case (AD5280_ID & 0x3F):
261| case (AD5282_ID & 0x3F):
262| ctrl = ((reg & 0x1F) == 0) ?
263| 0 : 0x80;
264| return dpot_write_r8d8(dpot, ctrl, value);
265| break;
266| case (AD5171_ID & 0x3F):
267| case (AD5273_ID & 0x3F):
268| if (reg & (0x1 << 6)) {
269| tmp = dpot_read_d8(dpot);
270| if (tmp >> 6)
271| return -14;
272| ctrl = 0x80;
273| }
274| return dpot_write_r8d8(dpot, ctrl, value);
275| break;
276| case (AD5172_ID & 0x3F):
277| case (AD5173_ID & 0x3F):
278| ctrl = ((reg & 0x1F) == 0) ?
279| 0 : 0x08;
280| if (reg & (0x1 << 6)) {
281| tmp = dpot_read_r8d16(dpot, ctrl);
282| if (tmp >> 14)
283| return -14;
284| ctrl |= 0x20;
285| }
286| return dpot_write_r8d8(dpot, ctrl, value);
287| break;
288| case (AD5170_ID & 0x3F):
289| if (reg & (0x1 << 6)) {
290| tmp = dpot_read_r8d16(dpot, tmp);
291| if (tmp >> 14)
292| return -14;
293| ctrl = 0x20;
294| }
295| return dpot_write_r8d8(dpot, ctrl, value);
296| break;
297| case (AD5272_ID & 0x3F):
298| case (AD5274_ID & 0x3F):
299| dpot_write_r8d8(dpot, 0x07 << 2,
300| 0x03);
301|
302| if (reg & (0x1 << 6))
303| return dpot_write_r8d8(dpot,
304| 0x03 << 2, 0);
305|
306| if (dpot->uid == (AD5274_ID & 0x3F))
307| value = value << 2;
308|
309| return dpot_write_r8d8(dpot, (0x01 << 2) |
310| (value >> 8), value & 0xFF);
311| break;
312| default:
313| if (reg & (0x1 << 7))
314| return dpot_write_d8(dpot, reg);
315|
316| if (dpot->max_pos > 256)
317| return dpot_write_r8d16(dpot, (reg & 0xF8) |
318| ((reg & 0x7) << 1), value);
319| else
320|
321| return dpot_write_r8d8(dpot, reg, value);
322| }
323|}
324|
325|static s32 dpot_write(struct dpot_data *dpot, u8 reg, u16 value)
326|{
327| if (dpot->feat & ((1 << 7) | (1 << 8) | (1 << 9)))
328| return dpot_write_spi(dpot, reg, value);
329| else
330| return dpot_write_i2c(dpot, reg, value);
331|}
332|
333|
334|
335|static ssize_t sysfs_show_reg(struct device *dev,
336| struct device_attribute *attr,
337| char *buf, u32 reg)
338|{
339| struct dpot_data *data = dev_get_drvdata(dev);
340| s32 value;
341|
342| if (reg & (0x1 << 9))
343| return sprintf(buf, "%s\n",
344| (__builtin_constant_p((0x1F & reg)) ? constant_test_bit((0x1F & reg), (data->otp_en_mask)) : variable_test_bit((0x1F & reg), (data->otp_en_mask))) ?
345| "enabled" : "disabled");
346|
347|
348| __st_mutex_lock_st__(&data->update_lock);
349| value = dpot_read(data, reg);
350| __st_mutex_unlock_st__(&data->update_lock);
351|
352| if (value < 0)
353| return -22;
354| if (reg & 0x18)
355| return sprintf(buf, "0x%04x\n", value & 0xFFFF);
356| else
357| return sprintf(buf, "%u\n", value & data->rdac_mask);
358|}
359|
360|static ssize_t sysfs_set_reg(struct device *dev,
361| struct device_attribute *attr,
362| const char *buf, size_t count, u32 reg)
363|{
364| struct dpot_data *data = dev_get_drvdata(dev);
365| unsigned long value;
366| int err;
367|
368| if (reg & (0x1 << 9)) {
369| if (!strncmp(buf, "enabled", sizeof("enabled")))
370| set_bit(0x1F & reg, data->otp_en_mask);
371| else
372| clear_bit(0x1F & reg, data->otp_en_mask);
373|
374| return count;
375| }
376|
377| if ((reg & (0x1 << 6)) &&
378| !(__builtin_constant_p((0x1F & reg)) ? constant_test_bit((0x1F & reg), (data->otp_en_mask)) : variable_test_bit((0x1F & reg), (data->otp_en_mask))))
379| return -1;
380|
381| err = strict_strtoul(buf, 10, &value);
382| if (err)
383| return err;
384|
385| if (value > data->rdac_mask)
386| value = data->rdac_mask;
387|
388| __st_mutex_lock_st__(&data->update_lock);
389| dpot_write(data, reg, value);
390| if (reg & (0x1 << 5))
391| msleep(26);
392| else if (reg & (0x1 << 6))
393| msleep(400);
394| __st_mutex_unlock_st__(&data->update_lock);
395|
396| return count;
397|}
398|
399|static ssize_t sysfs_do_cmd(struct device *dev,
400| struct device_attribute *attr,
401| const char *buf, size_t count, u32 reg)
402|{
403| struct dpot_data *data = dev_get_drvdata(dev);
404|
405| __st_mutex_lock_st__(&data->update_lock);
406| dpot_write(data, reg, 0);
407| __st_mutex_unlock_st__(&data->update_lock);
408|
409| return count;
410|}
411|static ssize_t show_rdac0(struct device *dev, struct device_attribute *attr, char *buf) { return sysfs_show_reg(dev, attr, buf, (0x0 << 5) | 0); } static ssize_t set_rdac0(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { return sysfs_set_reg(dev, attr, buf, count, (0x0 << 5) | 0); } static struct device_attribute dev_attr_rdac0 = { .attr = {.name = "rdac0", .mode = 00200 | (00400|00040|00004) }, .show = show_rdac0, .store = set_rdac0, };;
412|static ssize_t show_eeprom0(struct device *dev, struct device_attribute *attr, char *buf) { return sysfs_show_reg(dev, attr, buf, (0x1 << 5) | 0); } static ssize_t set_eeprom0(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { return sysfs_set_reg(dev, attr, buf, count, (0x1 << 5) | 0); } static struct device_attribute dev_attr_eeprom0 = { .attr = {.name = "eeprom0", .mode = 00200 | (00400|00040|00004) }, .show = show_eeprom0, .store = set_eeprom0, };;
413|static ssize_t show_tolerance0(struct device *dev, struct device_attribute *attr, char *buf) { return sysfs_show_reg(dev, attr, buf, (0x1 << 5) | (0x18 | 0)); } static struct device_attribute dev_attr_tolerance0 = { .attr = {.name = "tolerance0", .mode = 00200 | (00400|00040|00004) }, .show = show_tolerance0, .store = ((void *)0), };;
414|static ssize_t show_otp0(struct device *dev, struct device_attribute *attr, char *buf) { return sysfs_show_reg(dev, attr, buf, (0x1 << 6) | 0); } static ssize_t set_otp0(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { return sysfs_set_reg(dev, attr, buf, count, (0x1 << 6) | 0); } static struct device_attribute dev_attr_otp0 = { .attr = {.name = "otp0", .mode = 00200 | (00400|00040|00004) }, .show = show_otp0, .store = set_otp0, };;
415|static ssize_t show_otp0en(struct device *dev, struct device_attribute *attr, char *buf) { return sysfs_show_reg(dev, attr, buf, (0x1 << 9) | 0); } static ssize_t set_otp0en(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { return sysfs_set_reg(dev, attr, buf, count, (0x1 << 9) | 0); } static struct device_attribute dev_attr_otp0en = { .attr = {.name = "otp0en", .mode = 00200 | (00400|00040|00004) }, .show = show_otp0en, .store = set_otp0en, };;
416|
417|static ssize_t show_rdac1(struct device *dev, struct device_attribute *attr, char *buf) { return sysfs_show_reg(dev, attr, buf, (0x0 << 5) | 1); } static ssize_t set_rdac1(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { return sysfs_set_reg(dev, attr, buf, count, (0x0 << 5) | 1); } static struct device_attribute dev_attr_rdac1 = { .attr = {.name = "rdac1", .mode = 00200 | (00400|00040|00004) }, .show = show_rdac1, .store = set_rdac1, };;
418|static ssize_t show_eeprom1(struct device *dev, struct device_attribute *attr, char *buf) { return sysfs_show_reg(dev, attr, buf, (0x1 << 5) | 1); } static ssize_t set_eeprom1(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { return sysfs_set_reg(dev, attr, buf, count, (0x1 << 5) | 1); } static struct device_attribute dev_attr_eeprom1 = { .attr = {.name = "eeprom1", .mode = 00200 | (00400|00040|00004) }, .show = show_eeprom1, .store = set_eeprom1, };;
419|static ssize_t show_tolerance1(struct device *dev, struct device_attribute *attr, char *buf) { return sysfs_show_reg(dev, attr, buf, (0x1 << 5) | (0x18 | 1)); } static struct device_attribute dev_attr_tolerance1 = { .attr = {.name = "tolerance1", .mode = 00200 | (00400|00040|00004) }, .show = show_tolerance1, .store = ((void *)0), };;
420|static ssize_t show_otp1(struct device *dev, struct device_attribute *attr, char *buf) { return sysfs_show_reg(dev, attr, buf, (0x1 << 6) | 1); } static ssize_t set_otp1(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { return sysfs_set_reg(dev, attr, buf, count, (0x1 << 6) | 1); } static struct device_attribute dev_attr_otp1 = { .attr = {.name = "otp1", .mode = 00200 | (00400|00040|00004) }, .show = show_otp1, .store = set_otp1, };;
421|static ssize_t show_otp1en(struct device *dev, struct device_attribute *attr, char *buf) { return sysfs_show_reg(dev, attr, buf, (0x1 << 9) | 1); } static ssize_t set_otp1en(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { return sysfs_set_reg(dev, attr, buf, count, (0x1 << 9) | 1); } static struct device_attribute dev_attr_otp1en = { .attr = {.name = "otp1en", .mode = 00200 | (00400|00040|00004) }, .show = show_otp1en, .store = set_otp1en, };;
422|
423|static ssize_t show_rdac2(struct device *dev, struct device_attribute *attr, char *buf) { return sysfs_show_reg(dev, attr, buf, (0x0 << 5) | 2); } static ssize_t set_rdac2(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { return sysfs_set_reg(dev, attr, buf, count, (0x0 << 5) | 2); } static struct device_attribute dev_attr_rdac2 = { .attr = {.name = "rdac2", .mode = 00200 | (00400|00040|00004) }, .show = show_rdac2, .store = set_rdac2, };;
424|static ssize_t show_eeprom2(struct device *dev, struct device_attribute *attr, char *buf) { return sysfs_show_reg(dev, attr, buf, (0x1 << 5) | 2); } static ssize_t set_eeprom2(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { return sysfs_set_reg(dev, attr, buf, count, (0x1 << 5) | 2); } static struct device_attribute dev_attr_eeprom2 = { .attr = {.name = "eeprom2", .mode = 00200 | (00400|00040|00004) }, .show = show_eeprom2, .store = set_eeprom2, };;
425|static ssize_t show_tolerance2(struct device *dev, struct device_attribute *attr, char *buf) { return sysfs_show_reg(dev, attr, buf, (0x1 << 5) | (0x18 | 2)); } static struct device_attribute dev_attr_tolerance2 = { .attr = {.name = "tolerance2", .mode = 00200 | (00400|00040|00004) }, .show = show_tolerance2, .store = ((void *)0), };;
426|static ssize_t show_otp2(struct device *dev, struct device_attribute *attr, char *buf) { return sysfs_show_reg(dev, attr, buf, (0x1 << 6) | 2); } static ssize_t set_otp2(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { return sysfs_set_reg(dev, attr, buf, count, (0x1 << 6) | 2); } static struct device_attribute dev_attr_otp2 = { .attr = {.name = "otp2", .mode = 00200 | (00400|00040|00004) }, .show = show_otp2, .store = set_otp2, };;
427|static ssize_t show_otp2en(struct device *dev, struct device_attribute *attr, char *buf) { return sysfs_show_reg(dev, attr, buf, (0x1 << 9) | 2); } static ssize_t set_otp2en(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { return sysfs_set_reg(dev, attr, buf, count, (0x1 << 9) | 2); } static struct device_attribute dev_attr_otp2en = { .attr = {.name = "otp2en", .mode = 00200 | (00400|00040|00004) }, .show = show_otp2en, .store = set_otp2en, };;
428|
429|static ssize_t show_rdac3(struct device *dev, struct device_attribute *attr, char *buf) { return sysfs_show_reg(dev, attr, buf, (0x0 << 5) | 3); } static ssize_t set_rdac3(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { return sysfs_set_reg(dev, attr, buf, count, (0x0 << 5) | 3); } static struct device_attribute dev_attr_rdac3 = { .attr = {.name = "rdac3", .mode = 00200 | (00400|00040|00004) }, .show = show_rdac3, .store = set_rdac3, };;
430|static ssize_t show_eeprom3(struct device *dev, struct device_attribute *attr, char *buf) { return sysfs_show_reg(dev, attr, buf, (0x1 << 5) | 3); } static ssize_t set_eeprom3(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { return sysfs_set_reg(dev, attr, buf, count, (0x1 << 5) | 3); } static struct device_attribute dev_attr_eeprom3 = { .attr = {.name = "eeprom3", .mode = 00200 | (00400|00040|00004) }, .show = show_eeprom3, .store = set_eeprom3, };;
431|static ssize_t show_tolerance3(struct device *dev, struct device_attribute *attr, char *buf) { return sysfs_show_reg(dev, attr, buf, (0x1 << 5) | (0x18 | 3)); } static struct device_attribute dev_attr_tolerance3 = { .attr = {.name = "tolerance3", .mode = 00200 | (00400|00040|00004) }, .show = show_tolerance3, .store = ((void *)0), };;
432|static ssize_t show_otp3(struct device *dev, struct device_attribute *attr, char *buf) { return sysfs_show_reg(dev, attr, buf, (0x1 << 6) | 3); } static ssize_t set_otp3(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { return sysfs_set_reg(dev, attr, buf, count, (0x1 << 6) | 3); } static struct device_attribute dev_attr_otp3 = { .attr = {.name = "otp3", .mode = 00200 | (00400|00040|00004) }, .show = show_otp3, .store = set_otp3, };;
433|static ssize_t show_otp3en(struct device *dev, struct device_attribute *attr, char *buf) { return sysfs_show_reg(dev, attr, buf, (0x1 << 9) | 3); } static ssize_t set_otp3en(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { return sysfs_set_reg(dev, attr, buf, count, (0x1 << 9) | 3); } static struct device_attribute dev_attr_otp3en = { .attr = {.name = "otp3en", .mode = 00200 | (00400|00040|00004) }, .show = show_otp3en, .store = set_otp3en, };;
434|
435|static ssize_t show_rdac4(struct device *dev, struct device_attribute *attr, char *buf) { return sysfs_show_reg(dev, attr, buf, (0x0 << 5) | 4); } static ssize_t set_rdac4(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { return sysfs_set_reg(dev, attr, buf, count, (0x0 << 5) | 4); } static struct device_attribute dev_attr_rdac4 = { .attr = {.name = "rdac4", .mode = 00200 | (00400|00040|00004) }, .show = show_rdac4, .store = set_rdac4, };;
436|static ssize_t show_eeprom4(struct device *dev, struct device_attribute *attr, char *buf) { return sysfs_show_reg(dev, attr, buf, (0x1 << 5) | 4); } static ssize_t set_eeprom4(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { return sysfs_set_reg(dev, attr, buf, count, (0x1 << 5) | 4); } static struct device_attribute dev_attr_eeprom4 = { .attr = {.name = "eeprom4", .mode = 00200 | (00400|00040|00004) }, .show = show_eeprom4, .store = set_eeprom4, };;
437|static ssize_t show_tolerance4(struct device *dev, struct device_attribute *attr, char *buf) { return sysfs_show_reg(dev, attr, buf, (0x1 << 5) | (0x18 | 4)); } static struct device_attribute dev_attr_tolerance4 = { .attr = {.name = "tolerance4", .mode = 00200 | (00400|00040|00004) }, .show = show_tolerance4, .store = ((void *)0), };;
438|static ssize_t show_otp4(struct device *dev, struct device_attribute *attr, char *buf) { return sysfs_show_reg(dev, attr, buf, (0x1 << 6) | 4); } static ssize_t set_otp4(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { return sysfs_set_reg(dev, attr, buf, count, (0x1 << 6) | 4); } static struct device_attribute dev_attr_otp4 = { .attr = {.name = "otp4", .mode = 00200 | (00400|00040|00004) }, .show = show_otp4, .store = set_otp4, };;
439|static ssize_t show_otp4en(struct device *dev, struct device_attribute *attr, char *buf) { return sysfs_show_reg(dev, attr, buf, (0x1 << 9) | 4); } static ssize_t set_otp4en(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { return sysfs_set_reg(dev, attr, buf, count, (0x1 << 9) | 4); } static struct device_attribute dev_attr_otp4en = { .attr = {.name = "otp4en", .mode = 00200 | (00400|00040|00004) }, .show = show_otp4en, .store = set_otp4en, };;
440|
441|static ssize_t show_rdac5(struct device *dev, struct device_attribute *attr, char *buf) { return sysfs_show_reg(dev, attr, buf, (0x0 << 5) | 5); } static ssize_t set_rdac5(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { return sysfs_set_reg(dev, attr, buf, count, (0x0 << 5) | 5); } static struct device_attribute dev_attr_rdac5 = { .attr = {.name = "rdac5", .mode = 00200 | (00400|00040|00004) }, .show = show_rdac5, .store = set_rdac5, };;
442|static ssize_t show_eeprom5(struct device *dev, struct device_attribute *attr, char *buf) { return sysfs_show_reg(dev, attr, buf, (0x1 << 5) | 5); } static ssize_t set_eeprom5(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { return sysfs_set_reg(dev, attr, buf, count, (0x1 << 5) | 5); } static struct device_attribute dev_attr_eeprom5 = { .attr = {.name = "eeprom5", .mode = 00200 | (00400|00040|00004) }, .show = show_eeprom5, .store = set_eeprom5, };;
443|static ssize_t show_tolerance5(struct device *dev, struct device_attribute *attr, char *buf) { return sysfs_show_reg(dev, attr, buf, (0x1 << 5) | (0x18 | 5)); } static struct device_attribute dev_attr_tolerance5 = { .attr = {.name = "tolerance5", .mode = 00200 | (00400|00040|00004) }, .show = show_tolerance5, .store = ((void *)0), };;
444|static ssize_t show_otp5(struct device *dev, struct device_attribute *attr, char *buf) { return sysfs_show_reg(dev, attr, buf, (0x1 << 6) | 5); } static ssize_t set_otp5(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { return sysfs_set_reg(dev, attr, buf, count, (0x1 << 6) | 5); } static struct device_attribute dev_attr_otp5 = { .attr = {.name = "otp5", .mode = 00200 | (00400|00040|00004) }, .show = show_otp5, .store = set_otp5, };;
445|static ssize_t show_otp5en(struct device *dev, struct device_attribute *attr, char *buf) { return sysfs_show_reg(dev, attr, buf, (0x1 << 9) | 5); } static ssize_t set_otp5en(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { return sysfs_set_reg(dev, attr, buf, count, (0x1 << 9) | 5); } static struct device_attribute dev_attr_otp5en = { .attr = {.name = "otp5en", .mode = 00200 | (00400|00040|00004) }, .show = show_otp5en, .store = set_otp5en, };;
446|
447|static const struct attribute *dpot_attrib_wipers[] = {
448| &dev_attr_rdac0.attr,
449| &dev_attr_rdac1.attr,
450| &dev_attr_rdac2.attr,
451| &dev_attr_rdac3.attr,
452| &dev_attr_rdac4.attr,
453| &dev_attr_rdac5.attr,
454| ((void *)0)
455|};
456|
457|static const struct attribute *dpot_attrib_eeprom[] = {
458| &dev_attr_eeprom0.attr,
459| &dev_attr_eeprom1.attr,
460| &dev_attr_eeprom2.attr,
461| &dev_attr_eeprom3.attr,
462| &dev_attr_eeprom4.attr,
463| &dev_attr_eeprom5.attr,
464| ((void *)0)
465|};
466|
467|static const struct attribute *dpot_attrib_otp[] = {
468| &dev_attr_otp0.attr,
469| &dev_attr_otp1.attr,
470| &dev_attr_otp2.attr,
471| &dev_attr_otp3.attr,
472| &dev_attr_otp4.attr,
473| &dev_attr_otp5.attr,
474| ((void *)0)
475|};
476|
477|static const struct attribute *dpot_attrib_otp_en[] = {
478| &dev_attr_otp0en.attr,
479| &dev_attr_otp1en.attr,
480| &dev_attr_otp2en.attr,
481| &dev_attr_otp3en.attr,
482| &dev_attr_otp4en.attr,
483| &dev_attr_otp5en.attr,
484| ((void *)0)
485|};
486|
487|static const struct attribute *dpot_attrib_tolerance[] = {
488| &dev_attr_tolerance0.attr,
489| &dev_attr_tolerance1.attr,
490| &dev_attr_tolerance2.attr,
491| &dev_attr_tolerance3.attr,
492| &dev_attr_tolerance4.attr,
493| &dev_attr_tolerance5.attr,
494| ((void *)0)
495|};
496|static ssize_t set_inc_all(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { return sysfs_do_cmd(dev, attr, buf, count, ((0x1 << 7) | (0xB << 3))); } static struct device_attribute dev_attr_inc_all = { .attr = {.name = "inc_all", .mode = 00200 | (00400|00040|00004) }, .show = ((void *)0), .store = set_inc_all, };;
497|static ssize_t set_dec_all(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { return sysfs_do_cmd(dev, attr, buf, count, ((0x1 << 7) | (0x6 << 3))); } static struct device_attribute dev_attr_dec_all = { .attr = {.name = "dec_all", .mode = 00200 | (00400|00040|00004) }, .show = ((void *)0), .store = set_dec_all, };;
498|static ssize_t set_inc_all_6db(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { return sysfs_do_cmd(dev, attr, buf, count, ((0x1 << 7) | (0x9 << 3))); } static struct device_attribute dev_attr_inc_all_6db = { .attr = {.name = "inc_all_6db", .mode = 00200 | (00400|00040|00004) }, .show = ((void *)0), .store = set_inc_all_6db, };;
499|static ssize_t set_dec_all_6db(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { return sysfs_do_cmd(dev, attr, buf, count, ((0x1 << 7) | (0x4 << 3))); } static struct device_attribute dev_attr_dec_all_6db = { .attr = {.name = "dec_all_6db", .mode = 00200 | (00400|00040|00004) }, .show = ((void *)0), .store = set_dec_all_6db, };;
500|
501|static struct attribute *ad525x_attributes_commands[] = {
502| &dev_attr_inc_all.attr,
503| &dev_attr_dec_all.attr,
504| &dev_attr_inc_all_6db.attr,
505| &dev_attr_dec_all_6db.attr,
506| ((void *)0)
507|};
508|
509|static const struct attribute_group ad525x_group_commands = {
510| .attrs = ad525x_attributes_commands,
511|};
512|
513| int ad_dpot_add_files(struct device *dev,
514| unsigned features, unsigned rdac)
515|{
516| int err = sysfs_create_file(&dev->kobj,
517| dpot_attrib_wipers[rdac]);
518| if (features & (1 << 1))
519| err |= sysfs_create_file(&dev->kobj,
520| dpot_attrib_eeprom[rdac]);
521| if (features & (1 << 3))
522| err |= sysfs_create_file(&dev->kobj,
523| dpot_attrib_tolerance[rdac]);
524| if (features & (1 << 2)) {
525| err |= sysfs_create_file(&dev->kobj,
526| dpot_attrib_otp_en[rdac]);
527| err |= sysfs_create_file(&dev->kobj,
528| dpot_attrib_otp[rdac]);
529| }
530|
531| if (err)
532| dev_err(dev, "failed to register sysfs hooks for RDAC%d\n",
533| rdac);
534|
535| return err;
536|}
537|
538|inline void ad_dpot_remove_files(struct device *dev,
539| unsigned features, unsigned rdac)
540|{
541| sysfs_remove_file(&dev->kobj,
542| dpot_attrib_wipers[rdac]);
543| if (features & (1 << 1))
544| sysfs_remove_file(&dev->kobj,
545| dpot_attrib_eeprom[rdac]);
546| if (features & (1 << 3))
547| sysfs_remove_file(&dev->kobj,
548| dpot_attrib_tolerance[rdac]);
549| if (features & (1 << 2)) {
550| sysfs_remove_file(&dev->kobj,
551| dpot_attrib_otp_en[rdac]);
552| sysfs_remove_file(&dev->kobj,
553| dpot_attrib_otp[rdac]);
554| }
555|}
556|
557| int ad_dpot_probe(struct device *dev,
558| struct ad_dpot_bus_data *bdata, const struct ad_dpot_id *id)
559|{
560|
561| struct dpot_data *data;
562| int i, err = 0;
563|
564| data = kzalloc(sizeof(struct dpot_data), __st_GFP_KERNEL_st__);
565| if (!data) {
566| err = -12;
567| goto exit;
568| }
569|
570| dev_set_drvdata(dev, data);
571| do { static struct lock_class_key __key; __mutex_init((&data->update_lock), "&data->update_lock", &__key); } while (0);
572|
573| data->bdata = *bdata;
574| data->devid = id->devid;
575|
576| data->max_pos = 1 << ((data->devid >> 6) & 0xF);
577| data->rdac_mask = data->max_pos - 1;
578| data->feat = (data->devid >> 18);
579| data->uid = (data->devid & 0x3F);
580| data->wipers = ((data->devid >> 10) & 0xFF);
581|
582| for (i = 0; i < 6; i++)
583| if (data->wipers & (1 << i)) {
584| err = ad_dpot_add_files(dev, data->feat, i);
585| if (err)
586| goto exit_remove_files;
587|
588| if (data->feat & (1 << 5))
589| data->rdac_cache[i] = data->max_pos / 2;
590| }
591|
592| if (data->feat & (1 << 0))
593| err = sysfs_create_group(&dev->kobj, &ad525x_group_commands);
594|
595| if (err) {
596| dev_err(dev, "failed to register sysfs hooks\n");
597| goto exit_free;
598| }
599|
600| _dev_info(dev, "%s %d-Position Digital Potentiometer registered\n", id->name, data->max_pos)
601| ;
602|
603| return 0;
604|
605|exit_remove_files:
606| for (i = 0; i < 6; i++)
607| if (data->wipers & (1 << i))
608| ad_dpot_remove_files(dev, data->feat, i);
609|
610|exit_free:
611| kfree(data);
612| dev_set_drvdata(dev, ((void *)0));
613|exit:
614| dev_err(dev, "failed to create client for %s ID 0x%lX\n",
615| id->name, id->devid);
616| return err;
617|}
618|extern typeof(ad_dpot_probe) ad_dpot_probe; extern void *__crc_ad_dpot_probe ; static const unsigned long __kcrctab_ad_dpot_probe = (unsigned long) &__crc_ad_dpot_probe; static const char __kstrtab_ad_dpot_probe[] = "" "ad_dpot_probe"; static const struct kernel_symbol __ksymtab_ad_dpot_probe = { (unsigned long)&ad_dpot_probe, __kstrtab_ad_dpot_probe };
619|
620| int ad_dpot_remove(struct device *dev)
621|{
622| struct dpot_data *data = dev_get_drvdata(dev);
623| int i;
624|
625| for (i = 0; i < 6; i++)
626| if (data->wipers & (1 << i))
627| ad_dpot_remove_files(dev, data->feat, i);
628|
629| kfree(data);
630|
631| return 0;
632|}
633|extern typeof(ad_dpot_remove) ad_dpot_remove; extern void *__crc_ad_dpot_remove ; static const unsigned long __kcrctab_ad_dpot_remove = (unsigned long) &__crc_ad_dpot_remove; static const char __kstrtab_ad_dpot_remove[] = "" "ad_dpot_remove"; static const struct kernel_symbol __ksymtab_ad_dpot_remove = { (unsigned long)&ad_dpot_remove, __kstrtab_ad_dpot_remove };
634|
635|
636|static const char
637| __mod_author770
638| [] = "author" "=" "Chris Verges , " "Michael Hennerich "
639| ;
640|static const char __mod_description771[] = "description" "=" "Digital potentiometer driver";
641|static const char __mod_license772[] = "license" "=" "GPL";
642|static const char __mod_version773[] = "version" "=" "0.2";