1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
22
23#include <linux/module.h>
24#include <linux/init.h>
25#include <linux/slab.h>
26#include <linux/jiffies.h>
27#include <linux/platform_device.h>
28#include <linux/hwmon.h>
29#include <linux/hwmon-sysfs.h>
30#include <linux/err.h>
31#include <linux/mutex.h>
32#include <linux/io.h>
33#include <linux/acpi.h>
34
35#define DRVNAME "f71882fg"
36
37#define SIO_F71858FG_LD_HWM 0x02
38#define SIO_F71882FG_LD_HWM 0x04
39#define SIO_UNLOCK_KEY 0x87
40#define SIO_LOCK_KEY 0xAA
41
42#define SIO_REG_LDSEL 0x07
43#define SIO_REG_DEVID 0x20
44#define SIO_REG_DEVREV 0x22
45#define SIO_REG_MANID 0x23
46#define SIO_REG_ENABLE 0x30
47#define SIO_REG_ADDR 0x60
48
49#define SIO_FINTEK_ID 0x1934
50#define SIO_F71808E_ID 0x0901
51#define SIO_F71808A_ID 0x1001
52#define SIO_F71858_ID 0x0507
53#define SIO_F71862_ID 0x0601
54#define SIO_F71868_ID 0x1106
55#define SIO_F71869_ID 0x0814
56#define SIO_F71869A_ID 0x1007
57#define SIO_F71882_ID 0x0541
58#define SIO_F71889_ID 0x0723
59#define SIO_F71889E_ID 0x0909
60#define SIO_F71889A_ID 0x1005
61#define SIO_F8000_ID 0x0581
62#define SIO_F81768D_ID 0x1210
63#define SIO_F81865_ID 0x0704
64#define SIO_F81866_ID 0x1010
65
66#define REGION_LENGTH 8
67#define ADDR_REG_OFFSET 5
68#define DATA_REG_OFFSET 6
69
70#define F71882FG_REG_IN_STATUS 0x12
71#define F71882FG_REG_IN_BEEP 0x13
72#define F71882FG_REG_IN(nr) (0x20 + (nr))
73#define F71882FG_REG_IN1_HIGH 0x32
74
75#define F81866_REG_IN_STATUS 0x16
76#define F81866_REG_IN_BEEP 0x17
77#define F81866_REG_IN1_HIGH 0x3a
78
79#define F71882FG_REG_FAN(nr) (0xA0 + (16 * (nr)))
80#define F71882FG_REG_FAN_TARGET(nr) (0xA2 + (16 * (nr)))
81#define F71882FG_REG_FAN_FULL_SPEED(nr) (0xA4 + (16 * (nr)))
82#define F71882FG_REG_FAN_STATUS 0x92
83#define F71882FG_REG_FAN_BEEP 0x93
84
85#define F71882FG_REG_TEMP(nr) (0x70 + 2 * (nr))
86#define F71882FG_REG_TEMP_OVT(nr) (0x80 + 2 * (nr))
87#define F71882FG_REG_TEMP_HIGH(nr) (0x81 + 2 * (nr))
88#define F71882FG_REG_TEMP_STATUS 0x62
89#define F71882FG_REG_TEMP_BEEP 0x63
90#define F71882FG_REG_TEMP_CONFIG 0x69
91#define F71882FG_REG_TEMP_HYST(nr) (0x6C + (nr))
92#define F71882FG_REG_TEMP_TYPE 0x6B
93#define F71882FG_REG_TEMP_DIODE_OPEN 0x6F
94
95#define F71882FG_REG_PWM(nr) (0xA3 + (16 * (nr)))
96#define F71882FG_REG_PWM_TYPE 0x94
97#define F71882FG_REG_PWM_ENABLE 0x96
98
99#define F71882FG_REG_FAN_HYST(nr) (0x98 + (nr))
100
101#define F71882FG_REG_FAN_FAULT_T 0x9F
102#define F71882FG_FAN_NEG_TEMP_EN 0x20
103#define F71882FG_FAN_PROG_SEL 0x80
104
105#define F71882FG_REG_POINT_PWM(pwm, point) (0xAA + (point) + (16 * (pwm)))
106#define F71882FG_REG_POINT_TEMP(pwm, point) (0xA6 + (point) + (16 * (pwm)))
107#define F71882FG_REG_POINT_MAPPING(nr) (0xAF + 16 * (nr))
108
109#define F71882FG_REG_START 0x01
110
111#define F71882FG_MAX_INS 11
112
113#define FAN_MIN_DETECT 366
114
115static unsigned short force_id;
116module_param(force_id, ushort, 0);
117MODULE_PARM_DESC(force_id, "Override the detected device ID");
118
119enum chips { f71808e, f71808a, f71858fg, f71862fg, f71868a, f71869, f71869a,
120 f71882fg, f71889fg, f71889ed, f71889a, f8000, f81768d, f81865f,
121 f81866a};
122
123static const char *const f71882fg_names[] = {
124 "f71808e",
125 "f71808a",
126 "f71858fg",
127 "f71862fg",
128 "f71868a",
129 "f71869",
130 "f71869a",
131 "f71882fg",
132 "f71889fg",
133 "f71889ed",
134 "f71889a",
135 "f8000",
136 "f81768d",
137 "f81865f",
138 "f81866a",
139};
140
141static const char f71882fg_has_in[][F71882FG_MAX_INS] = {
142 [f71808e] = { 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0 },
143 [f71808a] = { 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0 },
144 [f71858fg] = { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
145 [f71862fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
146 [f71868a] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
147 [f71869] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
148 [f71869a] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
149 [f71882fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
150 [f71889fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
151 [f71889ed] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
152 [f71889a] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
153 [f8000] = { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
154 [f81768d] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
155 [f81865f] = { 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
156 [f81866a] = { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
157};
158
159static const char f71882fg_has_in1_alarm[] = {
160 [f71808e] = 0,
161 [f71808a] = 0,
162 [f71858fg] = 0,
163 [f71862fg] = 0,
164 [f71868a] = 0,
165 [f71869] = 0,
166 [f71869a] = 0,
167 [f71882fg] = 1,
168 [f71889fg] = 1,
169 [f71889ed] = 1,
170 [f71889a] = 1,
171 [f8000] = 0,
172 [f81768d] = 1,
173 [f81865f] = 1,
174 [f81866a] = 1,
175};
176
177static const char f71882fg_fan_has_beep[] = {
178 [f71808e] = 0,
179 [f71808a] = 0,
180 [f71858fg] = 0,
181 [f71862fg] = 1,
182 [f71868a] = 1,
183 [f71869] = 1,
184 [f71869a] = 1,
185 [f71882fg] = 1,
186 [f71889fg] = 1,
187 [f71889ed] = 1,
188 [f71889a] = 1,
189 [f8000] = 0,
190 [f81768d] = 1,
191 [f81865f] = 1,
192 [f81866a] = 1,
193};
194
195static const char f71882fg_nr_fans[] = {
196 [f71808e] = 3,
197 [f71808a] = 2,
198 [f71858fg] = 3,
199 [f71862fg] = 3,
200 [f71868a] = 3,
201 [f71869] = 3,
202 [f71869a] = 3,
203 [f71882fg] = 4,
204 [f71889fg] = 3,
205 [f71889ed] = 3,
206 [f71889a] = 3,
207 [f8000] = 3,
208 [f81768d] = 3,
209 [f81865f] = 2,
210 [f81866a] = 3,
211};
212
213static const char f71882fg_temp_has_beep[] = {
214 [f71808e] = 0,
215 [f71808a] = 1,
216 [f71858fg] = 0,
217 [f71862fg] = 1,
218 [f71868a] = 1,
219 [f71869] = 1,
220 [f71869a] = 1,
221 [f71882fg] = 1,
222 [f71889fg] = 1,
223 [f71889ed] = 1,
224 [f71889a] = 1,
225 [f8000] = 0,
226 [f81768d] = 1,
227 [f81865f] = 1,
228 [f81866a] = 1,
229};
230
231static const char f71882fg_nr_temps[] = {
232 [f71808e] = 2,
233 [f71808a] = 2,
234 [f71858fg] = 3,
235 [f71862fg] = 3,
236 [f71868a] = 3,
237 [f71869] = 3,
238 [f71869a] = 3,
239 [f71882fg] = 3,
240 [f71889fg] = 3,
241 [f71889ed] = 3,
242 [f71889a] = 3,
243 [f8000] = 3,
244 [f81768d] = 3,
245 [f81865f] = 2,
246 [f81866a] = 3,
247};
248
249static struct platform_device *f71882fg_pdev;
250
251
252static inline int superio_inb(int base, int reg);
253static inline int superio_inw(int base, int reg);
254static inline int superio_enter(int base);
255static inline void superio_select(int base, int ld);
256static inline void superio_exit(int base);
257
258struct f71882fg_sio_data {
259 enum chips type;
260};
261
262struct f71882fg_data {
263 unsigned short addr;
264 enum chips type;
265 struct device *hwmon_dev;
266
267 struct mutex update_lock;
268 int temp_start;
269 char valid;
270 char auto_point_temp_signed;
271 unsigned long last_updated;
272 unsigned long last_limits;
273
274
275 u8 in[F71882FG_MAX_INS];
276 u8 in1_max;
277 u8 in_status;
278 u8 in_beep;
279 u16 fan[4];
280 u16 fan_target[4];
281 u16 fan_full_speed[4];
282 u8 fan_status;
283 u8 fan_beep;
284
285
286
287
288
289 u16 temp[4];
290 u8 temp_ovt[4];
291 u8 temp_high[4];
292 u8 temp_hyst[2];
293 u8 temp_type[4];
294 u8 temp_status;
295 u8 temp_beep;
296 u8 temp_diode_open;
297 u8 temp_config;
298 u8 pwm[4];
299 u8 pwm_enable;
300 u8 pwm_auto_point_hyst[2];
301 u8 pwm_auto_point_mapping[4];
302 u8 pwm_auto_point_pwm[4][5];
303 s8 pwm_auto_point_temp[4][4];
304};
305
306
307static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
308 char *buf);
309static ssize_t show_in_max(struct device *dev, struct device_attribute
310 *devattr, char *buf);
311static ssize_t store_in_max(struct device *dev, struct device_attribute
312 *devattr, const char *buf, size_t count);
313static ssize_t show_in_beep(struct device *dev, struct device_attribute
314 *devattr, char *buf);
315static ssize_t store_in_beep(struct device *dev, struct device_attribute
316 *devattr, const char *buf, size_t count);
317static ssize_t show_in_alarm(struct device *dev, struct device_attribute
318 *devattr, char *buf);
319
320static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
321 char *buf);
322static ssize_t show_fan_full_speed(struct device *dev,
323 struct device_attribute *devattr, char *buf);
324static ssize_t store_fan_full_speed(struct device *dev,
325 struct device_attribute *devattr, const char *buf, size_t count);
326static ssize_t show_fan_beep(struct device *dev, struct device_attribute
327 *devattr, char *buf);
328static ssize_t store_fan_beep(struct device *dev, struct device_attribute
329 *devattr, const char *buf, size_t count);
330static ssize_t show_fan_alarm(struct device *dev, struct device_attribute
331 *devattr, char *buf);
332
333static ssize_t show_temp(struct device *dev, struct device_attribute
334 *devattr, char *buf);
335static ssize_t show_temp_max(struct device *dev, struct device_attribute
336 *devattr, char *buf);
337static ssize_t store_temp_max(struct device *dev, struct device_attribute
338 *devattr, const char *buf, size_t count);
339static ssize_t show_temp_max_hyst(struct device *dev, struct device_attribute
340 *devattr, char *buf);
341static ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute
342 *devattr, const char *buf, size_t count);
343static ssize_t show_temp_crit(struct device *dev, struct device_attribute
344 *devattr, char *buf);
345static ssize_t store_temp_crit(struct device *dev, struct device_attribute
346 *devattr, const char *buf, size_t count);
347static ssize_t show_temp_crit_hyst(struct device *dev, struct device_attribute
348 *devattr, char *buf);
349static ssize_t show_temp_type(struct device *dev, struct device_attribute
350 *devattr, char *buf);
351static ssize_t show_temp_beep(struct device *dev, struct device_attribute
352 *devattr, char *buf);
353static ssize_t store_temp_beep(struct device *dev, struct device_attribute
354 *devattr, const char *buf, size_t count);
355static ssize_t show_temp_alarm(struct device *dev, struct device_attribute
356 *devattr, char *buf);
357static ssize_t show_temp_fault(struct device *dev, struct device_attribute
358 *devattr, char *buf);
359
360static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr,
361 char *buf);
362static ssize_t store_pwm(struct device *dev, struct device_attribute *devattr,
363 const char *buf, size_t count);
364static ssize_t show_simple_pwm(struct device *dev,
365 struct device_attribute *devattr, char *buf);
366static ssize_t store_simple_pwm(struct device *dev,
367 struct device_attribute *devattr, const char *buf, size_t count);
368static ssize_t show_pwm_enable(struct device *dev,
369 struct device_attribute *devattr, char *buf);
370static ssize_t store_pwm_enable(struct device *dev,
371 struct device_attribute *devattr, const char *buf, size_t count);
372static ssize_t show_pwm_interpolate(struct device *dev,
373 struct device_attribute *devattr, char *buf);
374static ssize_t store_pwm_interpolate(struct device *dev,
375 struct device_attribute *devattr, const char *buf, size_t count);
376static ssize_t show_pwm_auto_point_channel(struct device *dev,
377 struct device_attribute *devattr, char *buf);
378static ssize_t store_pwm_auto_point_channel(struct device *dev,
379 struct device_attribute *devattr, const char *buf, size_t count);
380static ssize_t show_pwm_auto_point_temp_hyst(struct device *dev,
381 struct device_attribute *devattr, char *buf);
382static ssize_t store_pwm_auto_point_temp_hyst(struct device *dev,
383 struct device_attribute *devattr, const char *buf, size_t count);
384static ssize_t show_pwm_auto_point_pwm(struct device *dev,
385 struct device_attribute *devattr, char *buf);
386static ssize_t store_pwm_auto_point_pwm(struct device *dev,
387 struct device_attribute *devattr, const char *buf, size_t count);
388static ssize_t show_pwm_auto_point_temp(struct device *dev,
389 struct device_attribute *devattr, char *buf);
390static ssize_t store_pwm_auto_point_temp(struct device *dev,
391 struct device_attribute *devattr, const char *buf, size_t count);
392
393static ssize_t show_name(struct device *dev, struct device_attribute *devattr,
394 char *buf);
395
396static int f71882fg_probe(struct platform_device *pdev);
397static int f71882fg_remove(struct platform_device *pdev);
398
399static struct platform_driver f71882fg_driver = {
400 .driver = {
401 .name = DRVNAME,
402 },
403 .probe = f71882fg_probe,
404 .remove = f71882fg_remove,
405};
406
407static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
408
409
410
411
412
413static struct sensor_device_attribute_2 f71858fg_temp_attr[] = {
414 SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0),
415 SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max,
416 store_temp_max, 0, 0),
417 SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
418 store_temp_max_hyst, 0, 0),
419 SENSOR_ATTR_2(temp1_max_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 0),
420 SENSOR_ATTR_2(temp1_crit, S_IRUGO|S_IWUSR, show_temp_crit,
421 store_temp_crit, 0, 0),
422 SENSOR_ATTR_2(temp1_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
423 0, 0),
424 SENSOR_ATTR_2(temp1_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 4),
425 SENSOR_ATTR_2(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0, 0),
426 SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1),
427 SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_max,
428 store_temp_max, 0, 1),
429 SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
430 store_temp_max_hyst, 0, 1),
431 SENSOR_ATTR_2(temp2_max_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 1),
432 SENSOR_ATTR_2(temp2_crit, S_IRUGO|S_IWUSR, show_temp_crit,
433 store_temp_crit, 0, 1),
434 SENSOR_ATTR_2(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
435 0, 1),
436 SENSOR_ATTR_2(temp2_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5),
437 SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 1),
438 SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2),
439 SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max,
440 store_temp_max, 0, 2),
441 SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
442 store_temp_max_hyst, 0, 2),
443 SENSOR_ATTR_2(temp3_max_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 2),
444 SENSOR_ATTR_2(temp3_crit, S_IRUGO|S_IWUSR, show_temp_crit,
445 store_temp_crit, 0, 2),
446 SENSOR_ATTR_2(temp3_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
447 0, 2),
448 SENSOR_ATTR_2(temp3_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6),
449 SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
450};
451
452
453static struct sensor_device_attribute_2 fxxxx_temp_attr[3][9] = { {
454 SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 1),
455 SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max,
456 store_temp_max, 0, 1),
457 SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
458 store_temp_max_hyst, 0, 1),
459
460
461
462
463
464 SENSOR_ATTR_2(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 1),
465 SENSOR_ATTR_2(temp1_crit, S_IRUGO|S_IWUSR, show_temp_crit,
466 store_temp_crit, 0, 1),
467 SENSOR_ATTR_2(temp1_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
468 0, 1),
469 SENSOR_ATTR_2(temp1_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5),
470 SENSOR_ATTR_2(temp1_type, S_IRUGO, show_temp_type, NULL, 0, 1),
471 SENSOR_ATTR_2(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0, 1),
472}, {
473 SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 2),
474 SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_max,
475 store_temp_max, 0, 2),
476 SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
477 store_temp_max_hyst, 0, 2),
478
479 SENSOR_ATTR_2(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 2),
480 SENSOR_ATTR_2(temp2_crit, S_IRUGO|S_IWUSR, show_temp_crit,
481 store_temp_crit, 0, 2),
482 SENSOR_ATTR_2(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
483 0, 2),
484 SENSOR_ATTR_2(temp2_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6),
485 SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 2),
486 SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
487}, {
488 SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 3),
489 SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max,
490 store_temp_max, 0, 3),
491 SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
492 store_temp_max_hyst, 0, 3),
493
494 SENSOR_ATTR_2(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 3),
495 SENSOR_ATTR_2(temp3_crit, S_IRUGO|S_IWUSR, show_temp_crit,
496 store_temp_crit, 0, 3),
497 SENSOR_ATTR_2(temp3_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
498 0, 3),
499 SENSOR_ATTR_2(temp3_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 7),
500 SENSOR_ATTR_2(temp3_type, S_IRUGO, show_temp_type, NULL, 0, 3),
501 SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 3),
502} };
503
504
505static struct sensor_device_attribute_2 fxxxx_temp_beep_attr[3][2] = { {
506 SENSOR_ATTR_2(temp1_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
507 store_temp_beep, 0, 1),
508 SENSOR_ATTR_2(temp1_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
509 store_temp_beep, 0, 5),
510}, {
511 SENSOR_ATTR_2(temp2_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
512 store_temp_beep, 0, 2),
513 SENSOR_ATTR_2(temp2_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
514 store_temp_beep, 0, 6),
515}, {
516 SENSOR_ATTR_2(temp3_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
517 store_temp_beep, 0, 3),
518 SENSOR_ATTR_2(temp3_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
519 store_temp_beep, 0, 7),
520} };
521
522static struct sensor_device_attribute_2 f81866_temp_beep_attr[3][2] = { {
523 SENSOR_ATTR_2(temp1_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
524 store_temp_beep, 0, 0),
525 SENSOR_ATTR_2(temp1_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
526 store_temp_beep, 0, 4),
527}, {
528 SENSOR_ATTR_2(temp2_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
529 store_temp_beep, 0, 1),
530 SENSOR_ATTR_2(temp2_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
531 store_temp_beep, 0, 5),
532}, {
533 SENSOR_ATTR_2(temp3_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
534 store_temp_beep, 0, 2),
535 SENSOR_ATTR_2(temp3_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
536 store_temp_beep, 0, 6),
537} };
538
539
540
541
542
543
544
545static struct sensor_device_attribute_2 f8000_temp_attr[] = {
546 SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0),
547 SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_crit,
548 store_temp_crit, 0, 0),
549 SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max,
550 store_temp_max, 0, 0),
551 SENSOR_ATTR_2(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 4),
552 SENSOR_ATTR_2(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0, 0),
553 SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1),
554 SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_crit,
555 store_temp_crit, 0, 1),
556 SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max,
557 store_temp_max, 0, 1),
558 SENSOR_ATTR_2(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5),
559 SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 1),
560 SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2),
561 SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_crit,
562 store_temp_crit, 0, 2),
563 SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max,
564 store_temp_max, 0, 2),
565 SENSOR_ATTR_2(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6),
566 SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
567};
568
569
570static struct sensor_device_attribute_2 fxxxx_in_attr[] = {
571 SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
572 SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
573 SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
574 SENSOR_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 0, 3),
575 SENSOR_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 0, 4),
576 SENSOR_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 0, 5),
577 SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 6),
578 SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 7),
579 SENSOR_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 0, 8),
580 SENSOR_ATTR_2(in9_input, S_IRUGO, show_in, NULL, 0, 9),
581 SENSOR_ATTR_2(in10_input, S_IRUGO, show_in, NULL, 0, 10),
582};
583
584
585static struct sensor_device_attribute_2 fxxxx_in1_alarm_attr[] = {
586 SENSOR_ATTR_2(in1_max, S_IRUGO|S_IWUSR, show_in_max, store_in_max,
587 0, 1),
588 SENSOR_ATTR_2(in1_beep, S_IRUGO|S_IWUSR, show_in_beep, store_in_beep,
589 0, 1),
590 SENSOR_ATTR_2(in1_alarm, S_IRUGO, show_in_alarm, NULL, 0, 1),
591};
592
593
594static struct sensor_device_attribute_2 fxxxx_fan_attr[4][6] = { {
595 SENSOR_ATTR_2(fan1_input, S_IRUGO, show_fan, NULL, 0, 0),
596 SENSOR_ATTR_2(fan1_full_speed, S_IRUGO|S_IWUSR,
597 show_fan_full_speed,
598 store_fan_full_speed, 0, 0),
599 SENSOR_ATTR_2(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 0),
600 SENSOR_ATTR_2(pwm1, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 0),
601 SENSOR_ATTR_2(pwm1_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
602 store_pwm_enable, 0, 0),
603 SENSOR_ATTR_2(pwm1_interpolate, S_IRUGO|S_IWUSR,
604 show_pwm_interpolate, store_pwm_interpolate, 0, 0),
605}, {
606 SENSOR_ATTR_2(fan2_input, S_IRUGO, show_fan, NULL, 0, 1),
607 SENSOR_ATTR_2(fan2_full_speed, S_IRUGO|S_IWUSR,
608 show_fan_full_speed,
609 store_fan_full_speed, 0, 1),
610 SENSOR_ATTR_2(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 1),
611 SENSOR_ATTR_2(pwm2, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 1),
612 SENSOR_ATTR_2(pwm2_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
613 store_pwm_enable, 0, 1),
614 SENSOR_ATTR_2(pwm2_interpolate, S_IRUGO|S_IWUSR,
615 show_pwm_interpolate, store_pwm_interpolate, 0, 1),
616}, {
617 SENSOR_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 0, 2),
618 SENSOR_ATTR_2(fan3_full_speed, S_IRUGO|S_IWUSR,
619 show_fan_full_speed,
620 store_fan_full_speed, 0, 2),
621 SENSOR_ATTR_2(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 2),
622 SENSOR_ATTR_2(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 2),
623 SENSOR_ATTR_2(pwm3_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
624 store_pwm_enable, 0, 2),
625 SENSOR_ATTR_2(pwm3_interpolate, S_IRUGO|S_IWUSR,
626 show_pwm_interpolate, store_pwm_interpolate, 0, 2),
627}, {
628 SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
629 SENSOR_ATTR_2(fan4_full_speed, S_IRUGO|S_IWUSR,
630 show_fan_full_speed,
631 store_fan_full_speed, 0, 3),
632 SENSOR_ATTR_2(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 3),
633 SENSOR_ATTR_2(pwm4, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 3),
634 SENSOR_ATTR_2(pwm4_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
635 store_pwm_enable, 0, 3),
636 SENSOR_ATTR_2(pwm4_interpolate, S_IRUGO|S_IWUSR,
637 show_pwm_interpolate, store_pwm_interpolate, 0, 3),
638} };
639
640
641static struct sensor_device_attribute_2 f71808a_fan3_attr[] = {
642 SENSOR_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 0, 2),
643 SENSOR_ATTR_2(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 2),
644 SENSOR_ATTR_2(pwm3, S_IRUGO|S_IWUSR,
645 show_simple_pwm, store_simple_pwm, 0, 2),
646};
647
648
649static struct sensor_device_attribute_2 fxxxx_fan_beep_attr[] = {
650 SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep,
651 store_fan_beep, 0, 0),
652 SENSOR_ATTR_2(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep,
653 store_fan_beep, 0, 1),
654 SENSOR_ATTR_2(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep,
655 store_fan_beep, 0, 2),
656 SENSOR_ATTR_2(fan4_beep, S_IRUGO|S_IWUSR, show_fan_beep,
657 store_fan_beep, 0, 3),
658};
659
660
661
662
663
664static struct sensor_device_attribute_2 f71862fg_auto_pwm_attr[3][7] = { {
665 SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
666 show_pwm_auto_point_channel,
667 store_pwm_auto_point_channel, 0, 0),
668 SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,
669 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
670 1, 0),
671 SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO|S_IWUSR,
672 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
673 4, 0),
674 SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IRUGO|S_IWUSR,
675 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
676 0, 0),
677 SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IRUGO|S_IWUSR,
678 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
679 3, 0),
680 SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
681 show_pwm_auto_point_temp_hyst,
682 store_pwm_auto_point_temp_hyst,
683 0, 0),
684 SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO,
685 show_pwm_auto_point_temp_hyst, NULL, 3, 0),
686}, {
687 SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,
688 show_pwm_auto_point_channel,
689 store_pwm_auto_point_channel, 0, 1),
690 SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR,
691 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
692 1, 1),
693 SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO|S_IWUSR,
694 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
695 4, 1),
696 SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IRUGO|S_IWUSR,
697 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
698 0, 1),
699 SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IRUGO|S_IWUSR,
700 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
701 3, 1),
702 SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
703 show_pwm_auto_point_temp_hyst,
704 store_pwm_auto_point_temp_hyst,
705 0, 1),
706 SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO,
707 show_pwm_auto_point_temp_hyst, NULL, 3, 1),
708}, {
709 SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
710 show_pwm_auto_point_channel,
711 store_pwm_auto_point_channel, 0, 2),
712 SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR,
713 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
714 1, 2),
715 SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO|S_IWUSR,
716 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
717 4, 2),
718 SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IRUGO|S_IWUSR,
719 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
720 0, 2),
721 SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IRUGO|S_IWUSR,
722 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
723 3, 2),
724 SENSOR_ATTR_2(pwm3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
725 show_pwm_auto_point_temp_hyst,
726 store_pwm_auto_point_temp_hyst,
727 0, 2),
728 SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst, S_IRUGO,
729 show_pwm_auto_point_temp_hyst, NULL, 3, 2),
730} };
731
732
733
734
735
736
737static struct sensor_device_attribute_2 f71869_auto_pwm_attr[3][8] = { {
738 SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
739 show_pwm_auto_point_channel,
740 store_pwm_auto_point_channel, 0, 0),
741 SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,
742 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
743 0, 0),
744 SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO|S_IWUSR,
745 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
746 1, 0),
747 SENSOR_ATTR_2(pwm1_auto_point3_pwm, S_IRUGO|S_IWUSR,
748 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
749 4, 0),
750 SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IRUGO|S_IWUSR,
751 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
752 0, 0),
753 SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IRUGO|S_IWUSR,
754 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
755 3, 0),
756 SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
757 show_pwm_auto_point_temp_hyst,
758 store_pwm_auto_point_temp_hyst,
759 0, 0),
760 SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO,
761 show_pwm_auto_point_temp_hyst, NULL, 3, 0),
762}, {
763 SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,
764 show_pwm_auto_point_channel,
765 store_pwm_auto_point_channel, 0, 1),
766 SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR,
767 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
768 0, 1),
769 SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO|S_IWUSR,
770 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
771 1, 1),
772 SENSOR_ATTR_2(pwm2_auto_point3_pwm, S_IRUGO|S_IWUSR,
773 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
774 4, 1),
775 SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IRUGO|S_IWUSR,
776 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
777 0, 1),
778 SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IRUGO|S_IWUSR,
779 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
780 3, 1),
781 SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
782 show_pwm_auto_point_temp_hyst,
783 store_pwm_auto_point_temp_hyst,
784 0, 1),
785 SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO,
786 show_pwm_auto_point_temp_hyst, NULL, 3, 1),
787}, {
788 SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
789 show_pwm_auto_point_channel,
790 store_pwm_auto_point_channel, 0, 2),
791 SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR,
792 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
793 0, 2),
794 SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO|S_IWUSR,
795 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
796 1, 2),
797 SENSOR_ATTR_2(pwm3_auto_point3_pwm, S_IRUGO|S_IWUSR,
798 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
799 4, 2),
800 SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IRUGO|S_IWUSR,
801 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
802 0, 2),
803 SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IRUGO|S_IWUSR,
804 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
805 3, 2),
806 SENSOR_ATTR_2(pwm3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
807 show_pwm_auto_point_temp_hyst,
808 store_pwm_auto_point_temp_hyst,
809 0, 2),
810 SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst, S_IRUGO,
811 show_pwm_auto_point_temp_hyst, NULL, 3, 2),
812} };
813
814
815static struct sensor_device_attribute_2 fxxxx_auto_pwm_attr[4][14] = { {
816 SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
817 show_pwm_auto_point_channel,
818 store_pwm_auto_point_channel, 0, 0),
819 SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,
820 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
821 0, 0),
822 SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO|S_IWUSR,
823 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
824 1, 0),
825 SENSOR_ATTR_2(pwm1_auto_point3_pwm, S_IRUGO|S_IWUSR,
826 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
827 2, 0),
828 SENSOR_ATTR_2(pwm1_auto_point4_pwm, S_IRUGO|S_IWUSR,
829 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
830 3, 0),
831 SENSOR_ATTR_2(pwm1_auto_point5_pwm, S_IRUGO|S_IWUSR,
832 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
833 4, 0),
834 SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IRUGO|S_IWUSR,
835 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
836 0, 0),
837 SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IRUGO|S_IWUSR,
838 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
839 1, 0),
840 SENSOR_ATTR_2(pwm1_auto_point3_temp, S_IRUGO|S_IWUSR,
841 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
842 2, 0),
843 SENSOR_ATTR_2(pwm1_auto_point4_temp, S_IRUGO|S_IWUSR,
844 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
845 3, 0),
846 SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
847 show_pwm_auto_point_temp_hyst,
848 store_pwm_auto_point_temp_hyst,
849 0, 0),
850 SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO,
851 show_pwm_auto_point_temp_hyst, NULL, 1, 0),
852 SENSOR_ATTR_2(pwm1_auto_point3_temp_hyst, S_IRUGO,
853 show_pwm_auto_point_temp_hyst, NULL, 2, 0),
854 SENSOR_ATTR_2(pwm1_auto_point4_temp_hyst, S_IRUGO,
855 show_pwm_auto_point_temp_hyst, NULL, 3, 0),
856}, {
857 SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,
858 show_pwm_auto_point_channel,
859 store_pwm_auto_point_channel, 0, 1),
860 SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR,
861 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
862 0, 1),
863 SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO|S_IWUSR,
864 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
865 1, 1),
866 SENSOR_ATTR_2(pwm2_auto_point3_pwm, S_IRUGO|S_IWUSR,
867 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
868 2, 1),
869 SENSOR_ATTR_2(pwm2_auto_point4_pwm, S_IRUGO|S_IWUSR,
870 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
871 3, 1),
872 SENSOR_ATTR_2(pwm2_auto_point5_pwm, S_IRUGO|S_IWUSR,
873 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
874 4, 1),
875 SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IRUGO|S_IWUSR,
876 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
877 0, 1),
878 SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IRUGO|S_IWUSR,
879 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
880 1, 1),
881 SENSOR_ATTR_2(pwm2_auto_point3_temp, S_IRUGO|S_IWUSR,
882 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
883 2, 1),
884 SENSOR_ATTR_2(pwm2_auto_point4_temp, S_IRUGO|S_IWUSR,
885 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
886 3, 1),
887 SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
888 show_pwm_auto_point_temp_hyst,
889 store_pwm_auto_point_temp_hyst,
890 0, 1),
891 SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO,
892 show_pwm_auto_point_temp_hyst, NULL, 1, 1),
893 SENSOR_ATTR_2(pwm2_auto_point3_temp_hyst, S_IRUGO,
894 show_pwm_auto_point_temp_hyst, NULL, 2, 1),
895 SENSOR_ATTR_2(pwm2_auto_point4_temp_hyst, S_IRUGO,
896 show_pwm_auto_point_temp_hyst, NULL, 3, 1),
897}, {
898 SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
899 show_pwm_auto_point_channel,
900 store_pwm_auto_point_channel, 0, 2),
901 SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR,
902 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
903 0, 2),
904 SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO|S_IWUSR,
905 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
906 1, 2),
907 SENSOR_ATTR_2(pwm3_auto_point3_pwm, S_IRUGO|S_IWUSR,
908 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
909 2, 2),
910 SENSOR_ATTR_2(pwm3_auto_point4_pwm, S_IRUGO|S_IWUSR,
911 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
912 3, 2),
913 SENSOR_ATTR_2(pwm3_auto_point5_pwm, S_IRUGO|S_IWUSR,
914 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
915 4, 2),
916 SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IRUGO|S_IWUSR,
917 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
918 0, 2),
919 SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IRUGO|S_IWUSR,
920 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
921 1, 2),
922 SENSOR_ATTR_2(pwm3_auto_point3_temp, S_IRUGO|S_IWUSR,
923 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
924 2, 2),
925 SENSOR_ATTR_2(pwm3_auto_point4_temp, S_IRUGO|S_IWUSR,
926 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
927 3, 2),
928 SENSOR_ATTR_2(pwm3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
929 show_pwm_auto_point_temp_hyst,
930 store_pwm_auto_point_temp_hyst,
931 0, 2),
932 SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst, S_IRUGO,
933 show_pwm_auto_point_temp_hyst, NULL, 1, 2),
934 SENSOR_ATTR_2(pwm3_auto_point3_temp_hyst, S_IRUGO,
935 show_pwm_auto_point_temp_hyst, NULL, 2, 2),
936 SENSOR_ATTR_2(pwm3_auto_point4_temp_hyst, S_IRUGO,
937 show_pwm_auto_point_temp_hyst, NULL, 3, 2),
938}, {
939 SENSOR_ATTR_2(pwm4_auto_channels_temp, S_IRUGO|S_IWUSR,
940 show_pwm_auto_point_channel,
941 store_pwm_auto_point_channel, 0, 3),
942 SENSOR_ATTR_2(pwm4_auto_point1_pwm, S_IRUGO|S_IWUSR,
943 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
944 0, 3),
945 SENSOR_ATTR_2(pwm4_auto_point2_pwm, S_IRUGO|S_IWUSR,
946 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
947 1, 3),
948 SENSOR_ATTR_2(pwm4_auto_point3_pwm, S_IRUGO|S_IWUSR,
949 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
950 2, 3),
951 SENSOR_ATTR_2(pwm4_auto_point4_pwm, S_IRUGO|S_IWUSR,
952 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
953 3, 3),
954 SENSOR_ATTR_2(pwm4_auto_point5_pwm, S_IRUGO|S_IWUSR,
955 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
956 4, 3),
957 SENSOR_ATTR_2(pwm4_auto_point1_temp, S_IRUGO|S_IWUSR,
958 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
959 0, 3),
960 SENSOR_ATTR_2(pwm4_auto_point2_temp, S_IRUGO|S_IWUSR,
961 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
962 1, 3),
963 SENSOR_ATTR_2(pwm4_auto_point3_temp, S_IRUGO|S_IWUSR,
964 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
965 2, 3),
966 SENSOR_ATTR_2(pwm4_auto_point4_temp, S_IRUGO|S_IWUSR,
967 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
968 3, 3),
969 SENSOR_ATTR_2(pwm4_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
970 show_pwm_auto_point_temp_hyst,
971 store_pwm_auto_point_temp_hyst,
972 0, 3),
973 SENSOR_ATTR_2(pwm4_auto_point2_temp_hyst, S_IRUGO,
974 show_pwm_auto_point_temp_hyst, NULL, 1, 3),
975 SENSOR_ATTR_2(pwm4_auto_point3_temp_hyst, S_IRUGO,
976 show_pwm_auto_point_temp_hyst, NULL, 2, 3),
977 SENSOR_ATTR_2(pwm4_auto_point4_temp_hyst, S_IRUGO,
978 show_pwm_auto_point_temp_hyst, NULL, 3, 3),
979} };
980
981
982static struct sensor_device_attribute_2 f8000_fan_attr[] = {
983 SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
984};
985
986
987
988
989
990
991static struct sensor_device_attribute_2 f8000_auto_pwm_attr[3][14] = { {
992 SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
993 show_pwm_auto_point_channel,
994 store_pwm_auto_point_channel, 0, 0),
995 SENSOR_ATTR_2(temp1_auto_point1_pwm, S_IRUGO|S_IWUSR,
996 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
997 0, 2),
998 SENSOR_ATTR_2(temp1_auto_point2_pwm, S_IRUGO|S_IWUSR,
999 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
1000 1, 2),
1001 SENSOR_ATTR_2(temp1_auto_point3_pwm, S_IRUGO|S_IWUSR,
1002 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
1003 2, 2),
1004 SENSOR_ATTR_2(temp1_auto_point4_pwm, S_IRUGO|S_IWUSR,
1005 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
1006 3, 2),
1007 SENSOR_ATTR_2(temp1_auto_point5_pwm, S_IRUGO|S_IWUSR,
1008 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
1009 4, 2),
1010 SENSOR_ATTR_2(temp1_auto_point1_temp, S_IRUGO|S_IWUSR,
1011 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
1012 0, 2),
1013 SENSOR_ATTR_2(temp1_auto_point2_temp, S_IRUGO|S_IWUSR,
1014 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
1015 1, 2),
1016 SENSOR_ATTR_2(temp1_auto_point3_temp, S_IRUGO|S_IWUSR,
1017 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
1018 2, 2),
1019 SENSOR_ATTR_2(temp1_auto_point4_temp, S_IRUGO|S_IWUSR,
1020 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
1021 3, 2),
1022 SENSOR_ATTR_2(temp1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
1023 show_pwm_auto_point_temp_hyst,
1024 store_pwm_auto_point_temp_hyst,
1025 0, 2),
1026 SENSOR_ATTR_2(temp1_auto_point2_temp_hyst, S_IRUGO,
1027 show_pwm_auto_point_temp_hyst, NULL, 1, 2),
1028 SENSOR_ATTR_2(temp1_auto_point3_temp_hyst, S_IRUGO,
1029 show_pwm_auto_point_temp_hyst, NULL, 2, 2),
1030 SENSOR_ATTR_2(temp1_auto_point4_temp_hyst, S_IRUGO,
1031 show_pwm_auto_point_temp_hyst, NULL, 3, 2),
1032}, {
1033 SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,
1034 show_pwm_auto_point_channel,
1035 store_pwm_auto_point_channel, 0, 1),
1036 SENSOR_ATTR_2(temp2_auto_point1_pwm, S_IRUGO|S_IWUSR,
1037 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
1038 0, 0),
1039 SENSOR_ATTR_2(temp2_auto_point2_pwm, S_IRUGO|S_IWUSR,
1040 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
1041 1, 0),
1042 SENSOR_ATTR_2(temp2_auto_point3_pwm, S_IRUGO|S_IWUSR,
1043 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
1044 2, 0),
1045 SENSOR_ATTR_2(temp2_auto_point4_pwm, S_IRUGO|S_IWUSR,
1046 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
1047 3, 0),
1048 SENSOR_ATTR_2(temp2_auto_point5_pwm, S_IRUGO|S_IWUSR,
1049 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
1050 4, 0),
1051 SENSOR_ATTR_2(temp2_auto_point1_temp, S_IRUGO|S_IWUSR,
1052 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
1053 0, 0),
1054 SENSOR_ATTR_2(temp2_auto_point2_temp, S_IRUGO|S_IWUSR,
1055 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
1056 1, 0),
1057 SENSOR_ATTR_2(temp2_auto_point3_temp, S_IRUGO|S_IWUSR,
1058 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
1059 2, 0),
1060 SENSOR_ATTR_2(temp2_auto_point4_temp, S_IRUGO|S_IWUSR,
1061 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
1062 3, 0),
1063 SENSOR_ATTR_2(temp2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
1064 show_pwm_auto_point_temp_hyst,
1065 store_pwm_auto_point_temp_hyst,
1066 0, 0),
1067 SENSOR_ATTR_2(temp2_auto_point2_temp_hyst, S_IRUGO,
1068 show_pwm_auto_point_temp_hyst, NULL, 1, 0),
1069 SENSOR_ATTR_2(temp2_auto_point3_temp_hyst, S_IRUGO,
1070 show_pwm_auto_point_temp_hyst, NULL, 2, 0),
1071 SENSOR_ATTR_2(temp2_auto_point4_temp_hyst, S_IRUGO,
1072 show_pwm_auto_point_temp_hyst, NULL, 3, 0),
1073}, {
1074 SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
1075 show_pwm_auto_point_channel,
1076 store_pwm_auto_point_channel, 0, 2),
1077 SENSOR_ATTR_2(temp3_auto_point1_pwm, S_IRUGO|S_IWUSR,
1078 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
1079 0, 1),
1080 SENSOR_ATTR_2(temp3_auto_point2_pwm, S_IRUGO|S_IWUSR,
1081 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
1082 1, 1),
1083 SENSOR_ATTR_2(temp3_auto_point3_pwm, S_IRUGO|S_IWUSR,
1084 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
1085 2, 1),
1086 SENSOR_ATTR_2(temp3_auto_point4_pwm, S_IRUGO|S_IWUSR,
1087 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
1088 3, 1),
1089 SENSOR_ATTR_2(temp3_auto_point5_pwm, S_IRUGO|S_IWUSR,
1090 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
1091 4, 1),
1092 SENSOR_ATTR_2(temp3_auto_point1_temp, S_IRUGO|S_IWUSR,
1093 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
1094 0, 1),
1095 SENSOR_ATTR_2(temp3_auto_point2_temp, S_IRUGO|S_IWUSR,
1096 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
1097 1, 1),
1098 SENSOR_ATTR_2(temp3_auto_point3_temp, S_IRUGO|S_IWUSR,
1099 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
1100 2, 1),
1101 SENSOR_ATTR_2(temp3_auto_point4_temp, S_IRUGO|S_IWUSR,
1102 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
1103 3, 1),
1104 SENSOR_ATTR_2(temp3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
1105 show_pwm_auto_point_temp_hyst,
1106 store_pwm_auto_point_temp_hyst,
1107 0, 1),
1108 SENSOR_ATTR_2(temp3_auto_point2_temp_hyst, S_IRUGO,
1109 show_pwm_auto_point_temp_hyst, NULL, 1, 1),
1110 SENSOR_ATTR_2(temp3_auto_point3_temp_hyst, S_IRUGO,
1111 show_pwm_auto_point_temp_hyst, NULL, 2, 1),
1112 SENSOR_ATTR_2(temp3_auto_point4_temp_hyst, S_IRUGO,
1113 show_pwm_auto_point_temp_hyst, NULL, 3, 1),
1114} };
1115
1116
1117static inline int superio_inb(int base, int reg)
1118{
1119 outb(reg, base);
1120 return inb(base + 1);
1121}
1122
1123static int superio_inw(int base, int reg)
1124{
1125 int val;
1126 val = superio_inb(base, reg) << 8;
1127 val |= superio_inb(base, reg + 1);
1128 return val;
1129}
1130
1131static inline int superio_enter(int base)
1132{
1133
1134 if (!request_muxed_region(base, 2, DRVNAME)) {
1135 pr_err("I/O address 0x%04x already in use\n", base);
1136 return -EBUSY;
1137 }
1138
1139
1140 outb(SIO_UNLOCK_KEY, base);
1141 outb(SIO_UNLOCK_KEY, base);
1142
1143 return 0;
1144}
1145
1146static inline void superio_select(int base, int ld)
1147{
1148 outb(SIO_REG_LDSEL, base);
1149 outb(ld, base + 1);
1150}
1151
1152static inline void superio_exit(int base)
1153{
1154 outb(SIO_LOCK_KEY, base);
1155 release_region(base, 2);
1156}
1157
1158static inline int fan_from_reg(u16 reg)
1159{
1160 return reg ? (1500000 / reg) : 0;
1161}
1162
1163static inline u16 fan_to_reg(int fan)
1164{
1165 return fan ? (1500000 / fan) : 0;
1166}
1167
1168static u8 f71882fg_read8(struct f71882fg_data *data, u8 reg)
1169{
1170 u8 val;
1171
1172 outb(reg, data->addr + ADDR_REG_OFFSET);
1173 val = inb(data->addr + DATA_REG_OFFSET);
1174
1175 return val;
1176}
1177
1178static u16 f71882fg_read16(struct f71882fg_data *data, u8 reg)
1179{
1180 u16 val;
1181
1182 val = f71882fg_read8(data, reg) << 8;
1183 val |= f71882fg_read8(data, reg + 1);
1184
1185 return val;
1186}
1187
1188static void f71882fg_write8(struct f71882fg_data *data, u8 reg, u8 val)
1189{
1190 outb(reg, data->addr + ADDR_REG_OFFSET);
1191 outb(val, data->addr + DATA_REG_OFFSET);
1192}
1193
1194static void f71882fg_write16(struct f71882fg_data *data, u8 reg, u16 val)
1195{
1196 f71882fg_write8(data, reg, val >> 8);
1197 f71882fg_write8(data, reg + 1, val & 0xff);
1198}
1199
1200static u16 f71882fg_read_temp(struct f71882fg_data *data, int nr)
1201{
1202 if (data->type == f71858fg)
1203 return f71882fg_read16(data, F71882FG_REG_TEMP(nr));
1204 else
1205 return f71882fg_read8(data, F71882FG_REG_TEMP(nr));
1206}
1207
1208static struct f71882fg_data *f71882fg_update_device(struct device *dev)
1209{
1210 struct f71882fg_data *data = dev_get_drvdata(dev);
1211 int nr_fans = f71882fg_nr_fans[data->type];
1212 int nr_temps = f71882fg_nr_temps[data->type];
1213 int nr, reg, point;
1214
1215 mutex_lock(&data->update_lock);
1216
1217
1218 if (time_after(jiffies, data->last_limits + 60 * HZ) ||
1219 !data->valid) {
1220 if (f71882fg_has_in1_alarm[data->type]) {
1221 if (data->type == f81866a) {
1222 data->in1_max =
1223 f71882fg_read8(data,
1224 F81866_REG_IN1_HIGH);
1225 data->in_beep =
1226 f71882fg_read8(data,
1227 F81866_REG_IN_BEEP);
1228 } else {
1229 data->in1_max =
1230 f71882fg_read8(data,
1231 F71882FG_REG_IN1_HIGH);
1232 data->in_beep =
1233 f71882fg_read8(data,
1234 F71882FG_REG_IN_BEEP);
1235 }
1236 }
1237
1238
1239 for (nr = data->temp_start; nr < nr_temps + data->temp_start;
1240 nr++) {
1241 data->temp_ovt[nr] = f71882fg_read8(data,
1242 F71882FG_REG_TEMP_OVT(nr));
1243 data->temp_high[nr] = f71882fg_read8(data,
1244 F71882FG_REG_TEMP_HIGH(nr));
1245 }
1246
1247 if (data->type != f8000) {
1248 data->temp_hyst[0] = f71882fg_read8(data,
1249 F71882FG_REG_TEMP_HYST(0));
1250 data->temp_hyst[1] = f71882fg_read8(data,
1251 F71882FG_REG_TEMP_HYST(1));
1252 }
1253
1254 if ((data->type != f71858fg) && (data->type != f8000)) {
1255 reg = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE);
1256 data->temp_type[1] = (reg & 0x02) ? 2 : 4;
1257 data->temp_type[2] = (reg & 0x04) ? 2 : 4;
1258 data->temp_type[3] = (reg & 0x08) ? 2 : 4;
1259 }
1260
1261 if (f71882fg_fan_has_beep[data->type])
1262 data->fan_beep = f71882fg_read8(data,
1263 F71882FG_REG_FAN_BEEP);
1264
1265 if (f71882fg_temp_has_beep[data->type])
1266 data->temp_beep = f71882fg_read8(data,
1267 F71882FG_REG_TEMP_BEEP);
1268
1269 data->pwm_enable = f71882fg_read8(data,
1270 F71882FG_REG_PWM_ENABLE);
1271 data->pwm_auto_point_hyst[0] =
1272 f71882fg_read8(data, F71882FG_REG_FAN_HYST(0));
1273 data->pwm_auto_point_hyst[1] =
1274 f71882fg_read8(data, F71882FG_REG_FAN_HYST(1));
1275
1276 for (nr = 0; nr < nr_fans; nr++) {
1277 data->pwm_auto_point_mapping[nr] =
1278 f71882fg_read8(data,
1279 F71882FG_REG_POINT_MAPPING(nr));
1280
1281 switch (data->type) {
1282 default:
1283 for (point = 0; point < 5; point++) {
1284 data->pwm_auto_point_pwm[nr][point] =
1285 f71882fg_read8(data,
1286 F71882FG_REG_POINT_PWM
1287 (nr, point));
1288 }
1289 for (point = 0; point < 4; point++) {
1290 data->pwm_auto_point_temp[nr][point] =
1291 f71882fg_read8(data,
1292 F71882FG_REG_POINT_TEMP
1293 (nr, point));
1294 }
1295 break;
1296 case f71808e:
1297 case f71869:
1298 data->pwm_auto_point_pwm[nr][0] =
1299 f71882fg_read8(data,
1300 F71882FG_REG_POINT_PWM(nr, 0));
1301
1302 case f71862fg:
1303 data->pwm_auto_point_pwm[nr][1] =
1304 f71882fg_read8(data,
1305 F71882FG_REG_POINT_PWM
1306 (nr, 1));
1307 data->pwm_auto_point_pwm[nr][4] =
1308 f71882fg_read8(data,
1309 F71882FG_REG_POINT_PWM
1310 (nr, 4));
1311 data->pwm_auto_point_temp[nr][0] =
1312 f71882fg_read8(data,
1313 F71882FG_REG_POINT_TEMP
1314 (nr, 0));
1315 data->pwm_auto_point_temp[nr][3] =
1316 f71882fg_read8(data,
1317 F71882FG_REG_POINT_TEMP
1318 (nr, 3));
1319 break;
1320 }
1321 }
1322 data->last_limits = jiffies;
1323 }
1324
1325
1326 if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
1327 data->temp_status = f71882fg_read8(data,
1328 F71882FG_REG_TEMP_STATUS);
1329 data->temp_diode_open = f71882fg_read8(data,
1330 F71882FG_REG_TEMP_DIODE_OPEN);
1331 for (nr = data->temp_start; nr < nr_temps + data->temp_start;
1332 nr++)
1333 data->temp[nr] = f71882fg_read_temp(data, nr);
1334
1335 data->fan_status = f71882fg_read8(data,
1336 F71882FG_REG_FAN_STATUS);
1337 for (nr = 0; nr < nr_fans; nr++) {
1338 data->fan[nr] = f71882fg_read16(data,
1339 F71882FG_REG_FAN(nr));
1340 data->fan_target[nr] =
1341 f71882fg_read16(data, F71882FG_REG_FAN_TARGET(nr));
1342 data->fan_full_speed[nr] =
1343 f71882fg_read16(data,
1344 F71882FG_REG_FAN_FULL_SPEED(nr));
1345 data->pwm[nr] =
1346 f71882fg_read8(data, F71882FG_REG_PWM(nr));
1347 }
1348
1349 if (data->type == f71808a) {
1350 data->fan[2] = f71882fg_read16(data,
1351 F71882FG_REG_FAN(2));
1352 data->pwm[2] = f71882fg_read8(data,
1353 F71882FG_REG_PWM(2));
1354 }
1355 if (data->type == f8000)
1356 data->fan[3] = f71882fg_read16(data,
1357 F71882FG_REG_FAN(3));
1358
1359 if (f71882fg_has_in1_alarm[data->type]) {
1360 if (data->type == f81866a)
1361 data->in_status = f71882fg_read8(data,
1362 F81866_REG_IN_STATUS);
1363
1364 else
1365 data->in_status = f71882fg_read8(data,
1366 F71882FG_REG_IN_STATUS);
1367 }
1368
1369 for (nr = 0; nr < F71882FG_MAX_INS; nr++)
1370 if (f71882fg_has_in[data->type][nr])
1371 data->in[nr] = f71882fg_read8(data,
1372 F71882FG_REG_IN(nr));
1373
1374 data->last_updated = jiffies;
1375 data->valid = 1;
1376 }
1377
1378 mutex_unlock(&data->update_lock);
1379
1380 return data;
1381}
1382
1383
1384static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
1385 char *buf)
1386{
1387 struct f71882fg_data *data = f71882fg_update_device(dev);
1388 int nr = to_sensor_dev_attr_2(devattr)->index;
1389 int speed = fan_from_reg(data->fan[nr]);
1390
1391 if (speed == FAN_MIN_DETECT)
1392 speed = 0;
1393
1394 return sprintf(buf, "%d\n", speed);
1395}
1396
1397static ssize_t show_fan_full_speed(struct device *dev,
1398 struct device_attribute *devattr, char *buf)
1399{
1400 struct f71882fg_data *data = f71882fg_update_device(dev);
1401 int nr = to_sensor_dev_attr_2(devattr)->index;
1402 int speed = fan_from_reg(data->fan_full_speed[nr]);
1403 return sprintf(buf, "%d\n", speed);
1404}
1405
1406static ssize_t store_fan_full_speed(struct device *dev,
1407 struct device_attribute *devattr,
1408 const char *buf, size_t count)
1409{
1410 struct f71882fg_data *data = dev_get_drvdata(dev);
1411 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1412 long val;
1413
1414 err = kstrtol(buf, 10, &val);
1415 if (err)
1416 return err;
1417
1418 val = clamp_val(val, 23, 1500000);
1419 val = fan_to_reg(val);
1420
1421 mutex_lock(&data->update_lock);
1422 f71882fg_write16(data, F71882FG_REG_FAN_FULL_SPEED(nr), val);
1423 data->fan_full_speed[nr] = val;
1424 mutex_unlock(&data->update_lock);
1425
1426 return count;
1427}
1428
1429static ssize_t show_fan_beep(struct device *dev, struct device_attribute
1430 *devattr, char *buf)
1431{
1432 struct f71882fg_data *data = f71882fg_update_device(dev);
1433 int nr = to_sensor_dev_attr_2(devattr)->index;
1434
1435 if (data->fan_beep & (1 << nr))
1436 return sprintf(buf, "1\n");
1437 else
1438 return sprintf(buf, "0\n");
1439}
1440
1441static ssize_t store_fan_beep(struct device *dev, struct device_attribute
1442 *devattr, const char *buf, size_t count)
1443{
1444 struct f71882fg_data *data = dev_get_drvdata(dev);
1445 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1446 unsigned long val;
1447
1448 err = kstrtoul(buf, 10, &val);
1449 if (err)
1450 return err;
1451
1452 mutex_lock(&data->update_lock);
1453 data->fan_beep = f71882fg_read8(data, F71882FG_REG_FAN_BEEP);
1454 if (val)
1455 data->fan_beep |= 1 << nr;
1456 else
1457 data->fan_beep &= ~(1 << nr);
1458
1459 f71882fg_write8(data, F71882FG_REG_FAN_BEEP, data->fan_beep);
1460 mutex_unlock(&data->update_lock);
1461
1462 return count;
1463}
1464
1465static ssize_t show_fan_alarm(struct device *dev, struct device_attribute
1466 *devattr, char *buf)
1467{
1468 struct f71882fg_data *data = f71882fg_update_device(dev);
1469 int nr = to_sensor_dev_attr_2(devattr)->index;
1470
1471 if (data->fan_status & (1 << nr))
1472 return sprintf(buf, "1\n");
1473 else
1474 return sprintf(buf, "0\n");
1475}
1476
1477static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
1478 char *buf)
1479{
1480 struct f71882fg_data *data = f71882fg_update_device(dev);
1481 int nr = to_sensor_dev_attr_2(devattr)->index;
1482
1483 return sprintf(buf, "%d\n", data->in[nr] * 8);
1484}
1485
1486static ssize_t show_in_max(struct device *dev, struct device_attribute
1487 *devattr, char *buf)
1488{
1489 struct f71882fg_data *data = f71882fg_update_device(dev);
1490
1491 return sprintf(buf, "%d\n", data->in1_max * 8);
1492}
1493
1494static ssize_t store_in_max(struct device *dev, struct device_attribute
1495 *devattr, const char *buf, size_t count)
1496{
1497 struct f71882fg_data *data = dev_get_drvdata(dev);
1498 int err;
1499 long val;
1500
1501 err = kstrtol(buf, 10, &val);
1502 if (err)
1503 return err;
1504
1505 val /= 8;
1506 val = clamp_val(val, 0, 255);
1507
1508 mutex_lock(&data->update_lock);
1509 if (data->type == f81866a)
1510 f71882fg_write8(data, F81866_REG_IN1_HIGH, val);
1511 else
1512 f71882fg_write8(data, F71882FG_REG_IN1_HIGH, val);
1513 data->in1_max = val;
1514 mutex_unlock(&data->update_lock);
1515
1516 return count;
1517}
1518
1519static ssize_t show_in_beep(struct device *dev, struct device_attribute
1520 *devattr, char *buf)
1521{
1522 struct f71882fg_data *data = f71882fg_update_device(dev);
1523 int nr = to_sensor_dev_attr_2(devattr)->index;
1524
1525 if (data->in_beep & (1 << nr))
1526 return sprintf(buf, "1\n");
1527 else
1528 return sprintf(buf, "0\n");
1529}
1530
1531static ssize_t store_in_beep(struct device *dev, struct device_attribute
1532 *devattr, const char *buf, size_t count)
1533{
1534 struct f71882fg_data *data = dev_get_drvdata(dev);
1535 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1536 unsigned long val;
1537
1538 err = kstrtoul(buf, 10, &val);
1539 if (err)
1540 return err;
1541
1542 mutex_lock(&data->update_lock);
1543 if (data->type == f81866a)
1544 data->in_beep = f71882fg_read8(data, F81866_REG_IN_BEEP);
1545 else
1546 data->in_beep = f71882fg_read8(data, F71882FG_REG_IN_BEEP);
1547
1548 if (val)
1549 data->in_beep |= 1 << nr;
1550 else
1551 data->in_beep &= ~(1 << nr);
1552
1553 if (data->type == f81866a)
1554 f71882fg_write8(data, F81866_REG_IN_BEEP, data->in_beep);
1555 else
1556 f71882fg_write8(data, F71882FG_REG_IN_BEEP, data->in_beep);
1557 mutex_unlock(&data->update_lock);
1558
1559 return count;
1560}
1561
1562static ssize_t show_in_alarm(struct device *dev, struct device_attribute
1563 *devattr, char *buf)
1564{
1565 struct f71882fg_data *data = f71882fg_update_device(dev);
1566 int nr = to_sensor_dev_attr_2(devattr)->index;
1567
1568 if (data->in_status & (1 << nr))
1569 return sprintf(buf, "1\n");
1570 else
1571 return sprintf(buf, "0\n");
1572}
1573
1574static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
1575 char *buf)
1576{
1577 struct f71882fg_data *data = f71882fg_update_device(dev);
1578 int nr = to_sensor_dev_attr_2(devattr)->index;
1579 int sign, temp;
1580
1581 if (data->type == f71858fg) {
1582
1583 if (data->temp_config & 1) {
1584 sign = data->temp[nr] & 0x0001;
1585 temp = (data->temp[nr] >> 5) & 0x7ff;
1586 } else {
1587 sign = data->temp[nr] & 0x8000;
1588 temp = (data->temp[nr] >> 5) & 0x3ff;
1589 }
1590 temp *= 125;
1591 if (sign)
1592 temp -= 128000;
1593 } else
1594 temp = data->temp[nr] * 1000;
1595
1596 return sprintf(buf, "%d\n", temp);
1597}
1598
1599static ssize_t show_temp_max(struct device *dev, struct device_attribute
1600 *devattr, char *buf)
1601{
1602 struct f71882fg_data *data = f71882fg_update_device(dev);
1603 int nr = to_sensor_dev_attr_2(devattr)->index;
1604
1605 return sprintf(buf, "%d\n", data->temp_high[nr] * 1000);
1606}
1607
1608static ssize_t store_temp_max(struct device *dev, struct device_attribute
1609 *devattr, const char *buf, size_t count)
1610{
1611 struct f71882fg_data *data = dev_get_drvdata(dev);
1612 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1613 long val;
1614
1615 err = kstrtol(buf, 10, &val);
1616 if (err)
1617 return err;
1618
1619 val /= 1000;
1620 val = clamp_val(val, 0, 255);
1621
1622 mutex_lock(&data->update_lock);
1623 f71882fg_write8(data, F71882FG_REG_TEMP_HIGH(nr), val);
1624 data->temp_high[nr] = val;
1625 mutex_unlock(&data->update_lock);
1626
1627 return count;
1628}
1629
1630static ssize_t show_temp_max_hyst(struct device *dev, struct device_attribute
1631 *devattr, char *buf)
1632{
1633 struct f71882fg_data *data = f71882fg_update_device(dev);
1634 int nr = to_sensor_dev_attr_2(devattr)->index;
1635 int temp_max_hyst;
1636
1637 mutex_lock(&data->update_lock);
1638 if (nr & 1)
1639 temp_max_hyst = data->temp_hyst[nr / 2] >> 4;
1640 else
1641 temp_max_hyst = data->temp_hyst[nr / 2] & 0x0f;
1642 temp_max_hyst = (data->temp_high[nr] - temp_max_hyst) * 1000;
1643 mutex_unlock(&data->update_lock);
1644
1645 return sprintf(buf, "%d\n", temp_max_hyst);
1646}
1647
1648static ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute
1649 *devattr, const char *buf, size_t count)
1650{
1651 struct f71882fg_data *data = dev_get_drvdata(dev);
1652 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1653 ssize_t ret = count;
1654 u8 reg;
1655 long val;
1656
1657 err = kstrtol(buf, 10, &val);
1658 if (err)
1659 return err;
1660
1661 val /= 1000;
1662
1663 mutex_lock(&data->update_lock);
1664
1665
1666 data->temp_high[nr] = f71882fg_read8(data, F71882FG_REG_TEMP_HIGH(nr));
1667 val = clamp_val(val, data->temp_high[nr] - 15, data->temp_high[nr]);
1668 val = data->temp_high[nr] - val;
1669
1670
1671 reg = f71882fg_read8(data, F71882FG_REG_TEMP_HYST(nr / 2));
1672 if (nr & 1)
1673 reg = (reg & 0x0f) | (val << 4);
1674 else
1675 reg = (reg & 0xf0) | val;
1676 f71882fg_write8(data, F71882FG_REG_TEMP_HYST(nr / 2), reg);
1677 data->temp_hyst[nr / 2] = reg;
1678
1679 mutex_unlock(&data->update_lock);
1680 return ret;
1681}
1682
1683static ssize_t show_temp_crit(struct device *dev, struct device_attribute
1684 *devattr, char *buf)
1685{
1686 struct f71882fg_data *data = f71882fg_update_device(dev);
1687 int nr = to_sensor_dev_attr_2(devattr)->index;
1688
1689 return sprintf(buf, "%d\n", data->temp_ovt[nr] * 1000);
1690}
1691
1692static ssize_t store_temp_crit(struct device *dev, struct device_attribute
1693 *devattr, const char *buf, size_t count)
1694{
1695 struct f71882fg_data *data = dev_get_drvdata(dev);
1696 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1697 long val;
1698
1699 err = kstrtol(buf, 10, &val);
1700 if (err)
1701 return err;
1702
1703 val /= 1000;
1704 val = clamp_val(val, 0, 255);
1705
1706 mutex_lock(&data->update_lock);
1707 f71882fg_write8(data, F71882FG_REG_TEMP_OVT(nr), val);
1708 data->temp_ovt[nr] = val;
1709 mutex_unlock(&data->update_lock);
1710
1711 return count;
1712}
1713
1714static ssize_t show_temp_crit_hyst(struct device *dev, struct device_attribute
1715 *devattr, char *buf)
1716{
1717 struct f71882fg_data *data = f71882fg_update_device(dev);
1718 int nr = to_sensor_dev_attr_2(devattr)->index;
1719 int temp_crit_hyst;
1720
1721 mutex_lock(&data->update_lock);
1722 if (nr & 1)
1723 temp_crit_hyst = data->temp_hyst[nr / 2] >> 4;
1724 else
1725 temp_crit_hyst = data->temp_hyst[nr / 2] & 0x0f;
1726 temp_crit_hyst = (data->temp_ovt[nr] - temp_crit_hyst) * 1000;
1727 mutex_unlock(&data->update_lock);
1728
1729 return sprintf(buf, "%d\n", temp_crit_hyst);
1730}
1731
1732static ssize_t show_temp_type(struct device *dev, struct device_attribute
1733 *devattr, char *buf)
1734{
1735 struct f71882fg_data *data = f71882fg_update_device(dev);
1736 int nr = to_sensor_dev_attr_2(devattr)->index;
1737
1738 return sprintf(buf, "%d\n", data->temp_type[nr]);
1739}
1740
1741static ssize_t show_temp_beep(struct device *dev, struct device_attribute
1742 *devattr, char *buf)
1743{
1744 struct f71882fg_data *data = f71882fg_update_device(dev);
1745 int nr = to_sensor_dev_attr_2(devattr)->index;
1746
1747 if (data->temp_beep & (1 << nr))
1748 return sprintf(buf, "1\n");
1749 else
1750 return sprintf(buf, "0\n");
1751}
1752
1753static ssize_t store_temp_beep(struct device *dev, struct device_attribute
1754 *devattr, const char *buf, size_t count)
1755{
1756 struct f71882fg_data *data = dev_get_drvdata(dev);
1757 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1758 unsigned long val;
1759
1760 err = kstrtoul(buf, 10, &val);
1761 if (err)
1762 return err;
1763
1764 mutex_lock(&data->update_lock);
1765 data->temp_beep = f71882fg_read8(data, F71882FG_REG_TEMP_BEEP);
1766 if (val)
1767 data->temp_beep |= 1 << nr;
1768 else
1769 data->temp_beep &= ~(1 << nr);
1770
1771 f71882fg_write8(data, F71882FG_REG_TEMP_BEEP, data->temp_beep);
1772 mutex_unlock(&data->update_lock);
1773
1774 return count;
1775}
1776
1777static ssize_t show_temp_alarm(struct device *dev, struct device_attribute
1778 *devattr, char *buf)
1779{
1780 struct f71882fg_data *data = f71882fg_update_device(dev);
1781 int nr = to_sensor_dev_attr_2(devattr)->index;
1782
1783 if (data->temp_status & (1 << nr))
1784 return sprintf(buf, "1\n");
1785 else
1786 return sprintf(buf, "0\n");
1787}
1788
1789static ssize_t show_temp_fault(struct device *dev, struct device_attribute
1790 *devattr, char *buf)
1791{
1792 struct f71882fg_data *data = f71882fg_update_device(dev);
1793 int nr = to_sensor_dev_attr_2(devattr)->index;
1794
1795 if (data->temp_diode_open & (1 << nr))
1796 return sprintf(buf, "1\n");
1797 else
1798 return sprintf(buf, "0\n");
1799}
1800
1801static ssize_t show_pwm(struct device *dev,
1802 struct device_attribute *devattr, char *buf)
1803{
1804 struct f71882fg_data *data = f71882fg_update_device(dev);
1805 int val, nr = to_sensor_dev_attr_2(devattr)->index;
1806 mutex_lock(&data->update_lock);
1807 if (data->pwm_enable & (1 << (2 * nr)))
1808
1809 val = data->pwm[nr];
1810 else {
1811
1812 val = 255 * fan_from_reg(data->fan_target[nr])
1813 / fan_from_reg(data->fan_full_speed[nr]);
1814 }
1815 mutex_unlock(&data->update_lock);
1816 return sprintf(buf, "%d\n", val);
1817}
1818
1819static ssize_t store_pwm(struct device *dev,
1820 struct device_attribute *devattr, const char *buf,
1821 size_t count)
1822{
1823 struct f71882fg_data *data = dev_get_drvdata(dev);
1824 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1825 long val;
1826
1827 err = kstrtol(buf, 10, &val);
1828 if (err)
1829 return err;
1830
1831 val = clamp_val(val, 0, 255);
1832
1833 mutex_lock(&data->update_lock);
1834 data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
1835 if ((data->type == f8000 && ((data->pwm_enable >> 2 * nr) & 3) != 2) ||
1836 (data->type != f8000 && !((data->pwm_enable >> 2 * nr) & 2))) {
1837 count = -EROFS;
1838 goto leave;
1839 }
1840 if (data->pwm_enable & (1 << (2 * nr))) {
1841
1842 f71882fg_write8(data, F71882FG_REG_PWM(nr), val);
1843 data->pwm[nr] = val;
1844 } else {
1845
1846 int target, full_speed;
1847 full_speed = f71882fg_read16(data,
1848 F71882FG_REG_FAN_FULL_SPEED(nr));
1849 target = fan_to_reg(val * fan_from_reg(full_speed) / 255);
1850 f71882fg_write16(data, F71882FG_REG_FAN_TARGET(nr), target);
1851 data->fan_target[nr] = target;
1852 data->fan_full_speed[nr] = full_speed;
1853 }
1854leave:
1855 mutex_unlock(&data->update_lock);
1856
1857 return count;
1858}
1859
1860static ssize_t show_simple_pwm(struct device *dev,
1861 struct device_attribute *devattr, char *buf)
1862{
1863 struct f71882fg_data *data = f71882fg_update_device(dev);
1864 int val, nr = to_sensor_dev_attr_2(devattr)->index;
1865
1866 val = data->pwm[nr];
1867 return sprintf(buf, "%d\n", val);
1868}
1869
1870static ssize_t store_simple_pwm(struct device *dev,
1871 struct device_attribute *devattr,
1872 const char *buf, size_t count)
1873{
1874 struct f71882fg_data *data = dev_get_drvdata(dev);
1875 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1876 long val;
1877
1878 err = kstrtol(buf, 10, &val);
1879 if (err)
1880 return err;
1881
1882 val = clamp_val(val, 0, 255);
1883
1884 mutex_lock(&data->update_lock);
1885 f71882fg_write8(data, F71882FG_REG_PWM(nr), val);
1886 data->pwm[nr] = val;
1887 mutex_unlock(&data->update_lock);
1888
1889 return count;
1890}
1891
1892static ssize_t show_pwm_enable(struct device *dev,
1893 struct device_attribute *devattr, char *buf)
1894{
1895 int result = 0;
1896 struct f71882fg_data *data = f71882fg_update_device(dev);
1897 int nr = to_sensor_dev_attr_2(devattr)->index;
1898
1899 switch ((data->pwm_enable >> 2 * nr) & 3) {
1900 case 0:
1901 case 1:
1902 result = 2;
1903 break;
1904 case 2:
1905 result = 1;
1906 break;
1907 case 3:
1908 if (data->type == f8000)
1909 result = 3;
1910 else
1911 result = 1;
1912 break;
1913 }
1914
1915 return sprintf(buf, "%d\n", result);
1916}
1917
1918static ssize_t store_pwm_enable(struct device *dev, struct device_attribute
1919 *devattr, const char *buf, size_t count)
1920{
1921 struct f71882fg_data *data = dev_get_drvdata(dev);
1922 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1923 long val;
1924
1925 err = kstrtol(buf, 10, &val);
1926 if (err)
1927 return err;
1928
1929
1930 if (data->type == f8000 && nr == 2 && val != 2)
1931 return -EINVAL;
1932
1933 mutex_lock(&data->update_lock);
1934 data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
1935
1936 if (data->type == f8000 && ((data->pwm_enable >> 2 * nr) & 1)) {
1937 switch (val) {
1938 case 2:
1939 data->pwm_enable &= ~(2 << (2 * nr));
1940 break;
1941 case 3:
1942 data->pwm_enable |= 2 << (2 * nr);
1943 break;
1944 default:
1945 count = -EINVAL;
1946 goto leave;
1947 }
1948 } else {
1949 switch (val) {
1950 case 1:
1951
1952 if (data->type == f71858fg &&
1953 ((data->pwm_enable >> (2 * nr)) & 1)) {
1954 count = -EINVAL;
1955 goto leave;
1956 }
1957 data->pwm_enable |= 2 << (2 * nr);
1958 break;
1959 case 2:
1960 data->pwm_enable &= ~(2 << (2 * nr));
1961 break;
1962 default:
1963 count = -EINVAL;
1964 goto leave;
1965 }
1966 }
1967 f71882fg_write8(data, F71882FG_REG_PWM_ENABLE, data->pwm_enable);
1968leave:
1969 mutex_unlock(&data->update_lock);
1970
1971 return count;
1972}
1973
1974static ssize_t show_pwm_auto_point_pwm(struct device *dev,
1975 struct device_attribute *devattr,
1976 char *buf)
1977{
1978 int result;
1979 struct f71882fg_data *data = f71882fg_update_device(dev);
1980 int pwm = to_sensor_dev_attr_2(devattr)->index;
1981 int point = to_sensor_dev_attr_2(devattr)->nr;
1982
1983 mutex_lock(&data->update_lock);
1984 if (data->pwm_enable & (1 << (2 * pwm))) {
1985
1986 result = data->pwm_auto_point_pwm[pwm][point];
1987 } else {
1988
1989 result = 32 * 255 / (32 + data->pwm_auto_point_pwm[pwm][point]);
1990 }
1991 mutex_unlock(&data->update_lock);
1992
1993 return sprintf(buf, "%d\n", result);
1994}
1995
1996static ssize_t store_pwm_auto_point_pwm(struct device *dev,
1997 struct device_attribute *devattr,
1998 const char *buf, size_t count)
1999{
2000 struct f71882fg_data *data = dev_get_drvdata(dev);
2001 int err, pwm = to_sensor_dev_attr_2(devattr)->index;
2002 int point = to_sensor_dev_attr_2(devattr)->nr;
2003 long val;
2004
2005 err = kstrtol(buf, 10, &val);
2006 if (err)
2007 return err;
2008
2009 val = clamp_val(val, 0, 255);
2010
2011 mutex_lock(&data->update_lock);
2012 data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
2013 if (data->pwm_enable & (1 << (2 * pwm))) {
2014
2015 } else {
2016
2017 if (val < 29)
2018 val = 255;
2019 else
2020 val = (255 - val) * 32 / val;
2021 }
2022 f71882fg_write8(data, F71882FG_REG_POINT_PWM(pwm, point), val);
2023 data->pwm_auto_point_pwm[pwm][point] = val;
2024 mutex_unlock(&data->update_lock);
2025
2026 return count;
2027}
2028
2029static ssize_t show_pwm_auto_point_temp_hyst(struct device *dev,
2030 struct device_attribute *devattr,
2031 char *buf)
2032{
2033 int result = 0;
2034 struct f71882fg_data *data = f71882fg_update_device(dev);
2035 int nr = to_sensor_dev_attr_2(devattr)->index;
2036 int point = to_sensor_dev_attr_2(devattr)->nr;
2037
2038 mutex_lock(&data->update_lock);
2039 if (nr & 1)
2040 result = data->pwm_auto_point_hyst[nr / 2] >> 4;
2041 else
2042 result = data->pwm_auto_point_hyst[nr / 2] & 0x0f;
2043 result = 1000 * (data->pwm_auto_point_temp[nr][point] - result);
2044 mutex_unlock(&data->update_lock);
2045
2046 return sprintf(buf, "%d\n", result);
2047}
2048
2049static ssize_t store_pwm_auto_point_temp_hyst(struct device *dev,
2050 struct device_attribute *devattr,
2051 const char *buf, size_t count)
2052{
2053 struct f71882fg_data *data = dev_get_drvdata(dev);
2054 int err, nr = to_sensor_dev_attr_2(devattr)->index;
2055 int point = to_sensor_dev_attr_2(devattr)->nr;
2056 u8 reg;
2057 long val;
2058
2059 err = kstrtol(buf, 10, &val);
2060 if (err)
2061 return err;
2062
2063 val /= 1000;
2064
2065 mutex_lock(&data->update_lock);
2066 data->pwm_auto_point_temp[nr][point] =
2067 f71882fg_read8(data, F71882FG_REG_POINT_TEMP(nr, point));
2068 val = clamp_val(val, data->pwm_auto_point_temp[nr][point] - 15,
2069 data->pwm_auto_point_temp[nr][point]);
2070 val = data->pwm_auto_point_temp[nr][point] - val;
2071
2072 reg = f71882fg_read8(data, F71882FG_REG_FAN_HYST(nr / 2));
2073 if (nr & 1)
2074 reg = (reg & 0x0f) | (val << 4);
2075 else
2076 reg = (reg & 0xf0) | val;
2077
2078 f71882fg_write8(data, F71882FG_REG_FAN_HYST(nr / 2), reg);
2079 data->pwm_auto_point_hyst[nr / 2] = reg;
2080 mutex_unlock(&data->update_lock);
2081
2082 return count;
2083}
2084
2085static ssize_t show_pwm_interpolate(struct device *dev,
2086 struct device_attribute *devattr, char *buf)
2087{
2088 int result;
2089 struct f71882fg_data *data = f71882fg_update_device(dev);
2090 int nr = to_sensor_dev_attr_2(devattr)->index;
2091
2092 result = (data->pwm_auto_point_mapping[nr] >> 4) & 1;
2093
2094 return sprintf(buf, "%d\n", result);
2095}
2096
2097static ssize_t store_pwm_interpolate(struct device *dev,
2098 struct device_attribute *devattr,
2099 const char *buf, size_t count)
2100{
2101 struct f71882fg_data *data = dev_get_drvdata(dev);
2102 int err, nr = to_sensor_dev_attr_2(devattr)->index;
2103 unsigned long val;
2104
2105 err = kstrtoul(buf, 10, &val);
2106 if (err)
2107 return err;
2108
2109 mutex_lock(&data->update_lock);
2110 data->pwm_auto_point_mapping[nr] =
2111 f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(nr));
2112 if (val)
2113 val = data->pwm_auto_point_mapping[nr] | (1 << 4);
2114 else
2115 val = data->pwm_auto_point_mapping[nr] & (~(1 << 4));
2116 f71882fg_write8(data, F71882FG_REG_POINT_MAPPING(nr), val);
2117 data->pwm_auto_point_mapping[nr] = val;
2118 mutex_unlock(&data->update_lock);
2119
2120 return count;
2121}
2122
2123static ssize_t show_pwm_auto_point_channel(struct device *dev,
2124 struct device_attribute *devattr,
2125 char *buf)
2126{
2127 int result;
2128 struct f71882fg_data *data = f71882fg_update_device(dev);
2129 int nr = to_sensor_dev_attr_2(devattr)->index;
2130
2131 result = 1 << ((data->pwm_auto_point_mapping[nr] & 3) -
2132 data->temp_start);
2133
2134 return sprintf(buf, "%d\n", result);
2135}
2136
2137static ssize_t store_pwm_auto_point_channel(struct device *dev,
2138 struct device_attribute *devattr,
2139 const char *buf, size_t count)
2140{
2141 struct f71882fg_data *data = dev_get_drvdata(dev);
2142 int err, nr = to_sensor_dev_attr_2(devattr)->index;
2143 long val;
2144
2145 err = kstrtol(buf, 10, &val);
2146 if (err)
2147 return err;
2148
2149 switch (val) {
2150 case 1:
2151 val = 0;
2152 break;
2153 case 2:
2154 val = 1;
2155 break;
2156 case 4:
2157 val = 2;
2158 break;
2159 default:
2160 return -EINVAL;
2161 }
2162 val += data->temp_start;
2163 mutex_lock(&data->update_lock);
2164 data->pwm_auto_point_mapping[nr] =
2165 f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(nr));
2166 val = (data->pwm_auto_point_mapping[nr] & 0xfc) | val;
2167 f71882fg_write8(data, F71882FG_REG_POINT_MAPPING(nr), val);
2168 data->pwm_auto_point_mapping[nr] = val;
2169 mutex_unlock(&data->update_lock);
2170
2171 return count;
2172}
2173
2174static ssize_t show_pwm_auto_point_temp(struct device *dev,
2175 struct device_attribute *devattr,
2176 char *buf)
2177{
2178 int result;
2179 struct f71882fg_data *data = f71882fg_update_device(dev);
2180 int pwm = to_sensor_dev_attr_2(devattr)->index;
2181 int point = to_sensor_dev_attr_2(devattr)->nr;
2182
2183 result = data->pwm_auto_point_temp[pwm][point];
2184 return sprintf(buf, "%d\n", 1000 * result);
2185}
2186
2187static ssize_t store_pwm_auto_point_temp(struct device *dev,
2188 struct device_attribute *devattr,
2189 const char *buf, size_t count)
2190{
2191 struct f71882fg_data *data = dev_get_drvdata(dev);
2192 int err, pwm = to_sensor_dev_attr_2(devattr)->index;
2193 int point = to_sensor_dev_attr_2(devattr)->nr;
2194 long val;
2195
2196 err = kstrtol(buf, 10, &val);
2197 if (err)
2198 return err;
2199
2200 val /= 1000;
2201
2202 if (data->auto_point_temp_signed)
2203 val = clamp_val(val, -128, 127);
2204 else
2205 val = clamp_val(val, 0, 127);
2206
2207 mutex_lock(&data->update_lock);
2208 f71882fg_write8(data, F71882FG_REG_POINT_TEMP(pwm, point), val);
2209 data->pwm_auto_point_temp[pwm][point] = val;
2210 mutex_unlock(&data->update_lock);
2211
2212 return count;
2213}
2214
2215static ssize_t show_name(struct device *dev, struct device_attribute *devattr,
2216 char *buf)
2217{
2218 struct f71882fg_data *data = dev_get_drvdata(dev);
2219 return sprintf(buf, "%s\n", f71882fg_names[data->type]);
2220}
2221
2222static int f71882fg_create_sysfs_files(struct platform_device *pdev,
2223 struct sensor_device_attribute_2 *attr, int count)
2224{
2225 int err, i;
2226
2227 for (i = 0; i < count; i++) {
2228 err = device_create_file(&pdev->dev, &attr[i].dev_attr);
2229 if (err)
2230 return err;
2231 }
2232 return 0;
2233}
2234
2235static void f71882fg_remove_sysfs_files(struct platform_device *pdev,
2236 struct sensor_device_attribute_2 *attr, int count)
2237{
2238 int i;
2239
2240 for (i = 0; i < count; i++)
2241 device_remove_file(&pdev->dev, &attr[i].dev_attr);
2242}
2243
2244static int f71882fg_create_fan_sysfs_files(
2245 struct platform_device *pdev, int idx)
2246{
2247 struct f71882fg_data *data = platform_get_drvdata(pdev);
2248 int err;
2249
2250
2251 err = 0;
2252 switch (data->type) {
2253 case f71858fg:
2254 if (((data->pwm_enable >> (idx * 2)) & 3) == 3)
2255 err = 1;
2256 break;
2257 case f71862fg:
2258 if (((data->pwm_enable >> (idx * 2)) & 1) != 1)
2259 err = 1;
2260 break;
2261 case f8000:
2262 if (idx == 2)
2263 err = data->pwm_enable & 0x20;
2264 break;
2265 default:
2266 break;
2267 }
2268 if (err) {
2269 dev_err(&pdev->dev,
2270 "Invalid (reserved) pwm settings: 0x%02x, "
2271 "skipping fan %d\n",
2272 (data->pwm_enable >> (idx * 2)) & 3, idx + 1);
2273 return 0;
2274 }
2275
2276 err = f71882fg_create_sysfs_files(pdev, &fxxxx_fan_attr[idx][0],
2277 ARRAY_SIZE(fxxxx_fan_attr[0]));
2278 if (err)
2279 return err;
2280
2281 if (f71882fg_fan_has_beep[data->type]) {
2282 err = f71882fg_create_sysfs_files(pdev,
2283 &fxxxx_fan_beep_attr[idx],
2284 1);
2285 if (err)
2286 return err;
2287 }
2288
2289 dev_info(&pdev->dev, "Fan: %d is in %s mode\n", idx + 1,
2290 (data->pwm_enable & (1 << (2 * idx))) ? "duty-cycle" : "RPM");
2291
2292
2293 switch (data->type) {
2294 case f71808e:
2295 case f71808a:
2296 case f71869:
2297 case f71869a:
2298 case f71889fg:
2299 case f71889ed:
2300 case f71889a:
2301 data->pwm_auto_point_mapping[idx] =
2302 f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(idx));
2303 if ((data->pwm_auto_point_mapping[idx] & 0x80) ||
2304 (data->pwm_auto_point_mapping[idx] & 3) == 0) {
2305 dev_warn(&pdev->dev,
2306 "Auto pwm controlled by raw digital "
2307 "data, disabling pwm auto_point "
2308 "sysfs attributes for fan %d\n", idx + 1);
2309 return 0;
2310 }
2311 break;
2312 default:
2313 break;
2314 }
2315
2316 switch (data->type) {
2317 case f71862fg:
2318 err = f71882fg_create_sysfs_files(pdev,
2319 &f71862fg_auto_pwm_attr[idx][0],
2320 ARRAY_SIZE(f71862fg_auto_pwm_attr[0]));
2321 break;
2322 case f71808e:
2323 case f71869:
2324 err = f71882fg_create_sysfs_files(pdev,
2325 &f71869_auto_pwm_attr[idx][0],
2326 ARRAY_SIZE(f71869_auto_pwm_attr[0]));
2327 break;
2328 case f8000:
2329 err = f71882fg_create_sysfs_files(pdev,
2330 &f8000_auto_pwm_attr[idx][0],
2331 ARRAY_SIZE(f8000_auto_pwm_attr[0]));
2332 break;
2333 default:
2334 err = f71882fg_create_sysfs_files(pdev,
2335 &fxxxx_auto_pwm_attr[idx][0],
2336 ARRAY_SIZE(fxxxx_auto_pwm_attr[0]));
2337 }
2338
2339 return err;
2340}
2341
2342static int f71882fg_probe(struct platform_device *pdev)
2343{
2344 struct f71882fg_data *data;
2345 struct f71882fg_sio_data *sio_data = dev_get_platdata(&pdev->dev);
2346 int nr_fans = f71882fg_nr_fans[sio_data->type];
2347 int nr_temps = f71882fg_nr_temps[sio_data->type];
2348 int err, i;
2349 int size;
2350 u8 start_reg, reg;
2351
2352 data = devm_kzalloc(&pdev->dev, sizeof(struct f71882fg_data),
2353 GFP_KERNEL);
2354 if (!data)
2355 return -ENOMEM;
2356
2357 data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start;
2358 data->type = sio_data->type;
2359 data->temp_start =
2360 (data->type == f71858fg || data->type == f8000 ||
2361 data->type == f81866a) ? 0 : 1;
2362 mutex_init(&data->update_lock);
2363 platform_set_drvdata(pdev, data);
2364
2365 start_reg = f71882fg_read8(data, F71882FG_REG_START);
2366 if (start_reg & 0x04) {
2367 dev_warn(&pdev->dev, "Hardware monitor is powered down\n");
2368 return -ENODEV;
2369 }
2370 if (!(start_reg & 0x03)) {
2371 dev_warn(&pdev->dev, "Hardware monitoring not activated\n");
2372 return -ENODEV;
2373 }
2374
2375
2376 err = device_create_file(&pdev->dev, &dev_attr_name);
2377 if (err)
2378 goto exit_unregister_sysfs;
2379
2380 if (start_reg & 0x01) {
2381 switch (data->type) {
2382 case f71858fg:
2383 data->temp_config =
2384 f71882fg_read8(data, F71882FG_REG_TEMP_CONFIG);
2385 if (data->temp_config & 0x10)
2386
2387
2388
2389
2390 err = f71882fg_create_sysfs_files(pdev,
2391 f8000_temp_attr,
2392 ARRAY_SIZE(f8000_temp_attr));
2393 else
2394 err = f71882fg_create_sysfs_files(pdev,
2395 f71858fg_temp_attr,
2396 ARRAY_SIZE(f71858fg_temp_attr));
2397 break;
2398 case f8000:
2399 err = f71882fg_create_sysfs_files(pdev,
2400 f8000_temp_attr,
2401 ARRAY_SIZE(f8000_temp_attr));
2402 break;
2403 case f81866a:
2404 err = f71882fg_create_sysfs_files(pdev,
2405 f71858fg_temp_attr,
2406 ARRAY_SIZE(f71858fg_temp_attr));
2407 break;
2408 default:
2409 err = f71882fg_create_sysfs_files(pdev,
2410 &fxxxx_temp_attr[0][0],
2411 ARRAY_SIZE(fxxxx_temp_attr[0]) * nr_temps);
2412 }
2413 if (err)
2414 goto exit_unregister_sysfs;
2415
2416 if (f71882fg_temp_has_beep[data->type]) {
2417 if (data->type == f81866a) {
2418 size = ARRAY_SIZE(f81866_temp_beep_attr[0]);
2419 err = f71882fg_create_sysfs_files(pdev,
2420 &f81866_temp_beep_attr[0][0],
2421 size * nr_temps);
2422
2423 } else {
2424 size = ARRAY_SIZE(fxxxx_temp_beep_attr[0]);
2425 err = f71882fg_create_sysfs_files(pdev,
2426 &fxxxx_temp_beep_attr[0][0],
2427 size * nr_temps);
2428 }
2429 if (err)
2430 goto exit_unregister_sysfs;
2431 }
2432
2433 for (i = 0; i < F71882FG_MAX_INS; i++) {
2434 if (f71882fg_has_in[data->type][i]) {
2435 err = device_create_file(&pdev->dev,
2436 &fxxxx_in_attr[i].dev_attr);
2437 if (err)
2438 goto exit_unregister_sysfs;
2439 }
2440 }
2441 if (f71882fg_has_in1_alarm[data->type]) {
2442 err = f71882fg_create_sysfs_files(pdev,
2443 fxxxx_in1_alarm_attr,
2444 ARRAY_SIZE(fxxxx_in1_alarm_attr));
2445 if (err)
2446 goto exit_unregister_sysfs;
2447 }
2448 }
2449
2450 if (start_reg & 0x02) {
2451 switch (data->type) {
2452 case f71808e:
2453 case f71808a:
2454 case f71869:
2455 case f71869a:
2456
2457 data->auto_point_temp_signed = 1;
2458
2459 case f71889fg:
2460 case f71889ed:
2461 case f71889a:
2462 reg = f71882fg_read8(data, F71882FG_REG_FAN_FAULT_T);
2463 if (reg & F71882FG_FAN_NEG_TEMP_EN)
2464 data->auto_point_temp_signed = 1;
2465
2466 reg &= ~F71882FG_FAN_PROG_SEL;
2467 f71882fg_write8(data, F71882FG_REG_FAN_FAULT_T, reg);
2468 break;
2469 default:
2470 break;
2471 }
2472
2473 data->pwm_enable =
2474 f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
2475
2476 for (i = 0; i < nr_fans; i++) {
2477 err = f71882fg_create_fan_sysfs_files(pdev, i);
2478 if (err)
2479 goto exit_unregister_sysfs;
2480 }
2481
2482
2483 switch (data->type) {
2484 case f71808a:
2485 err = f71882fg_create_sysfs_files(pdev,
2486 f71808a_fan3_attr,
2487 ARRAY_SIZE(f71808a_fan3_attr));
2488 break;
2489 case f8000:
2490 err = f71882fg_create_sysfs_files(pdev,
2491 f8000_fan_attr,
2492 ARRAY_SIZE(f8000_fan_attr));
2493 break;
2494 default:
2495 break;
2496 }
2497 if (err)
2498 goto exit_unregister_sysfs;
2499 }
2500
2501 data->hwmon_dev = hwmon_device_register(&pdev->dev);
2502 if (IS_ERR(data->hwmon_dev)) {
2503 err = PTR_ERR(data->hwmon_dev);
2504 data->hwmon_dev = NULL;
2505 goto exit_unregister_sysfs;
2506 }
2507
2508 return 0;
2509
2510exit_unregister_sysfs:
2511 f71882fg_remove(pdev);
2512 return err;
2513}
2514
2515static int f71882fg_remove(struct platform_device *pdev)
2516{
2517 struct f71882fg_data *data = platform_get_drvdata(pdev);
2518 int nr_fans = f71882fg_nr_fans[data->type];
2519 int nr_temps = f71882fg_nr_temps[data->type];
2520 int i;
2521 u8 start_reg = f71882fg_read8(data, F71882FG_REG_START);
2522
2523 if (data->hwmon_dev)
2524 hwmon_device_unregister(data->hwmon_dev);
2525
2526 device_remove_file(&pdev->dev, &dev_attr_name);
2527
2528 if (start_reg & 0x01) {
2529 switch (data->type) {
2530 case f71858fg:
2531 if (data->temp_config & 0x10)
2532 f71882fg_remove_sysfs_files(pdev,
2533 f8000_temp_attr,
2534 ARRAY_SIZE(f8000_temp_attr));
2535 else
2536 f71882fg_remove_sysfs_files(pdev,
2537 f71858fg_temp_attr,
2538 ARRAY_SIZE(f71858fg_temp_attr));
2539 break;
2540 case f8000:
2541 f71882fg_remove_sysfs_files(pdev,
2542 f8000_temp_attr,
2543 ARRAY_SIZE(f8000_temp_attr));
2544 break;
2545 case f81866a:
2546 f71882fg_remove_sysfs_files(pdev,
2547 f71858fg_temp_attr,
2548 ARRAY_SIZE(f71858fg_temp_attr));
2549 break;
2550 default:
2551 f71882fg_remove_sysfs_files(pdev,
2552 &fxxxx_temp_attr[0][0],
2553 ARRAY_SIZE(fxxxx_temp_attr[0]) * nr_temps);
2554 }
2555 if (f71882fg_temp_has_beep[data->type]) {
2556 if (data->type == f81866a)
2557 f71882fg_remove_sysfs_files(pdev,
2558 &f81866_temp_beep_attr[0][0],
2559 ARRAY_SIZE(f81866_temp_beep_attr[0])
2560 * nr_temps);
2561 else
2562 f71882fg_remove_sysfs_files(pdev,
2563 &fxxxx_temp_beep_attr[0][0],
2564 ARRAY_SIZE(fxxxx_temp_beep_attr[0])
2565 * nr_temps);
2566 }
2567
2568 for (i = 0; i < F71882FG_MAX_INS; i++) {
2569 if (f71882fg_has_in[data->type][i]) {
2570 device_remove_file(&pdev->dev,
2571 &fxxxx_in_attr[i].dev_attr);
2572 }
2573 }
2574 if (f71882fg_has_in1_alarm[data->type]) {
2575 f71882fg_remove_sysfs_files(pdev,
2576 fxxxx_in1_alarm_attr,
2577 ARRAY_SIZE(fxxxx_in1_alarm_attr));
2578 }
2579 }
2580
2581 if (start_reg & 0x02) {
2582 f71882fg_remove_sysfs_files(pdev, &fxxxx_fan_attr[0][0],
2583 ARRAY_SIZE(fxxxx_fan_attr[0]) * nr_fans);
2584
2585 if (f71882fg_fan_has_beep[data->type]) {
2586 f71882fg_remove_sysfs_files(pdev,
2587 fxxxx_fan_beep_attr, nr_fans);
2588 }
2589
2590 switch (data->type) {
2591 case f71808a:
2592 f71882fg_remove_sysfs_files(pdev,
2593 &fxxxx_auto_pwm_attr[0][0],
2594 ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans);
2595 f71882fg_remove_sysfs_files(pdev,
2596 f71808a_fan3_attr,
2597 ARRAY_SIZE(f71808a_fan3_attr));
2598 break;
2599 case f71862fg:
2600 f71882fg_remove_sysfs_files(pdev,
2601 &f71862fg_auto_pwm_attr[0][0],
2602 ARRAY_SIZE(f71862fg_auto_pwm_attr[0]) *
2603 nr_fans);
2604 break;
2605 case f71808e:
2606 case f71869:
2607 f71882fg_remove_sysfs_files(pdev,
2608 &f71869_auto_pwm_attr[0][0],
2609 ARRAY_SIZE(f71869_auto_pwm_attr[0]) * nr_fans);
2610 break;
2611 case f8000:
2612 f71882fg_remove_sysfs_files(pdev,
2613 f8000_fan_attr,
2614 ARRAY_SIZE(f8000_fan_attr));
2615 f71882fg_remove_sysfs_files(pdev,
2616 &f8000_auto_pwm_attr[0][0],
2617 ARRAY_SIZE(f8000_auto_pwm_attr[0]) * nr_fans);
2618 break;
2619 default:
2620 f71882fg_remove_sysfs_files(pdev,
2621 &fxxxx_auto_pwm_attr[0][0],
2622 ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans);
2623 }
2624 }
2625 return 0;
2626}
2627
2628static int __init f71882fg_find(int sioaddr, struct f71882fg_sio_data *sio_data)
2629{
2630 u16 devid;
2631 unsigned short address;
2632 int err = superio_enter(sioaddr);
2633 if (err)
2634 return err;
2635
2636 devid = superio_inw(sioaddr, SIO_REG_MANID);
2637 if (devid != SIO_FINTEK_ID) {
2638 pr_debug("Not a Fintek device\n");
2639 err = -ENODEV;
2640 goto exit;
2641 }
2642
2643 devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID);
2644 switch (devid) {
2645 case SIO_F71808E_ID:
2646 sio_data->type = f71808e;
2647 break;
2648 case SIO_F71808A_ID:
2649 sio_data->type = f71808a;
2650 break;
2651 case SIO_F71858_ID:
2652 sio_data->type = f71858fg;
2653 break;
2654 case SIO_F71862_ID:
2655 sio_data->type = f71862fg;
2656 break;
2657 case SIO_F71868_ID:
2658 sio_data->type = f71868a;
2659 break;
2660 case SIO_F71869_ID:
2661 sio_data->type = f71869;
2662 break;
2663 case SIO_F71869A_ID:
2664 sio_data->type = f71869a;
2665 break;
2666 case SIO_F71882_ID:
2667 sio_data->type = f71882fg;
2668 break;
2669 case SIO_F71889_ID:
2670 sio_data->type = f71889fg;
2671 break;
2672 case SIO_F71889E_ID:
2673 sio_data->type = f71889ed;
2674 break;
2675 case SIO_F71889A_ID:
2676 sio_data->type = f71889a;
2677 break;
2678 case SIO_F8000_ID:
2679 sio_data->type = f8000;
2680 break;
2681 case SIO_F81768D_ID:
2682 sio_data->type = f81768d;
2683 break;
2684 case SIO_F81865_ID:
2685 sio_data->type = f81865f;
2686 break;
2687 case SIO_F81866_ID:
2688 sio_data->type = f81866a;
2689 break;
2690 default:
2691 pr_info("Unsupported Fintek device: %04x\n",
2692 (unsigned int)devid);
2693 err = -ENODEV;
2694 goto exit;
2695 }
2696
2697 if (sio_data->type == f71858fg)
2698 superio_select(sioaddr, SIO_F71858FG_LD_HWM);
2699 else
2700 superio_select(sioaddr, SIO_F71882FG_LD_HWM);
2701
2702 if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) {
2703 pr_warn("Device not activated\n");
2704 err = -ENODEV;
2705 goto exit;
2706 }
2707
2708 address = superio_inw(sioaddr, SIO_REG_ADDR);
2709 if (address == 0) {
2710 pr_warn("Base address not set\n");
2711 err = -ENODEV;
2712 goto exit;
2713 }
2714 address &= ~(REGION_LENGTH - 1);
2715
2716 err = address;
2717 pr_info("Found %s chip at %#x, revision %d\n",
2718 f71882fg_names[sio_data->type], (unsigned int)address,
2719 (int)superio_inb(sioaddr, SIO_REG_DEVREV));
2720exit:
2721 superio_exit(sioaddr);
2722 return err;
2723}
2724
2725static int __init f71882fg_device_add(int address,
2726 const struct f71882fg_sio_data *sio_data)
2727{
2728 struct resource res = {
2729 .start = address,
2730 .end = address + REGION_LENGTH - 1,
2731 .flags = IORESOURCE_IO,
2732 };
2733 int err;
2734
2735 f71882fg_pdev = platform_device_alloc(DRVNAME, address);
2736 if (!f71882fg_pdev)
2737 return -ENOMEM;
2738
2739 res.name = f71882fg_pdev->name;
2740 err = acpi_check_resource_conflict(&res);
2741 if (err)
2742 goto exit_device_put;
2743
2744 err = platform_device_add_resources(f71882fg_pdev, &res, 1);
2745 if (err) {
2746 pr_err("Device resource addition failed\n");
2747 goto exit_device_put;
2748 }
2749
2750 err = platform_device_add_data(f71882fg_pdev, sio_data,
2751 sizeof(struct f71882fg_sio_data));
2752 if (err) {
2753 pr_err("Platform data allocation failed\n");
2754 goto exit_device_put;
2755 }
2756
2757 err = platform_device_add(f71882fg_pdev);
2758 if (err) {
2759 pr_err("Device addition failed\n");
2760 goto exit_device_put;
2761 }
2762
2763 return 0;
2764
2765exit_device_put:
2766 platform_device_put(f71882fg_pdev);
2767
2768 return err;
2769}
2770
2771static int __init f71882fg_init(void)
2772{
2773 int err;
2774 int address;
2775 struct f71882fg_sio_data sio_data;
2776
2777 memset(&sio_data, 0, sizeof(sio_data));
2778
2779 address = f71882fg_find(0x2e, &sio_data);
2780 if (address < 0)
2781 address = f71882fg_find(0x4e, &sio_data);
2782 if (address < 0)
2783 return address;
2784
2785 err = platform_driver_register(&f71882fg_driver);
2786 if (err)
2787 return err;
2788
2789 err = f71882fg_device_add(address, &sio_data);
2790 if (err)
2791 goto exit_driver;
2792
2793 return 0;
2794
2795exit_driver:
2796 platform_driver_unregister(&f71882fg_driver);
2797 return err;
2798}
2799
2800static void __exit f71882fg_exit(void)
2801{
2802 platform_device_unregister(f71882fg_pdev);
2803 platform_driver_unregister(&f71882fg_driver);
2804}
2805
2806MODULE_DESCRIPTION("F71882FG Hardware Monitoring Driver");
2807MODULE_AUTHOR("Hans Edgington, Hans de Goede <hdegoede@redhat.com>");
2808MODULE_LICENSE("GPL");
2809
2810module_init(f71882fg_init);
2811module_exit(f71882fg_exit);
2812