aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/f71882fg.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/f71882fg.c')
-rw-r--r--drivers/hwmon/f71882fg.c1549
1 files changed, 1302 insertions, 247 deletions
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 67067e9a323e..609cafff86bc 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -1,6 +1,6 @@
1/*************************************************************************** 1/***************************************************************************
2 * Copyright (C) 2006 by Hans Edgington <hans@edgington.nl> * 2 * Copyright (C) 2006 by Hans Edgington <hans@edgington.nl> *
3 * Copyright (C) 2007 by Hans de Goede <j.w.r.degoede@hhs.nl> * 3 * Copyright (C) 2007,2008 by Hans de Goede <hdegoede@redhat.com> *
4 * * 4 * *
5 * This program is free software; you can redistribute it and/or modify * 5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by * 6 * it under the terms of the GNU General Public License as published by *
@@ -27,11 +27,12 @@
27#include <linux/hwmon-sysfs.h> 27#include <linux/hwmon-sysfs.h>
28#include <linux/err.h> 28#include <linux/err.h>
29#include <linux/mutex.h> 29#include <linux/mutex.h>
30#include <asm/io.h> 30#include <linux/io.h>
31#include <linux/acpi.h>
31 32
32#define DRVNAME "f71882fg" 33#define DRVNAME "f71882fg"
33 34
34#define SIO_F71882FG_LD_HWM 0x04 /* Hardware monitor logical device*/ 35#define SIO_F71882FG_LD_HWM 0x04 /* Hardware monitor logical device */
35#define SIO_UNLOCK_KEY 0x87 /* Key to enable Super-I/O */ 36#define SIO_UNLOCK_KEY 0x87 /* Key to enable Super-I/O */
36#define SIO_LOCK_KEY 0xAA /* Key to diasble Super-I/O */ 37#define SIO_LOCK_KEY 0xAA /* Key to diasble Super-I/O */
37 38
@@ -43,7 +44,9 @@
43#define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ 44#define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */
44 45
45#define SIO_FINTEK_ID 0x1934 /* Manufacturers ID */ 46#define SIO_FINTEK_ID 0x1934 /* Manufacturers ID */
47#define SIO_F71862_ID 0x0601 /* Chipset ID */
46#define SIO_F71882_ID 0x0541 /* Chipset ID */ 48#define SIO_F71882_ID 0x0541 /* Chipset ID */
49#define SIO_F8000_ID 0x0581 /* Chipset ID */
47 50
48#define REGION_LENGTH 8 51#define REGION_LENGTH 8
49#define ADDR_REG_OFFSET 5 52#define ADDR_REG_OFFSET 5
@@ -51,25 +54,36 @@
51 54
52#define F71882FG_REG_PECI 0x0A 55#define F71882FG_REG_PECI 0x0A
53 56
54#define F71882FG_REG_IN_STATUS 0x12 57#define F71882FG_REG_IN_STATUS 0x12 /* f71882fg only */
55#define F71882FG_REG_IN_BEEP 0x13 58#define F71882FG_REG_IN_BEEP 0x13 /* f71882fg only */
56#define F71882FG_REG_IN(nr) (0x20 + (nr)) 59#define F71882FG_REG_IN(nr) (0x20 + (nr))
57#define F71882FG_REG_IN1_HIGH 0x32 60#define F71882FG_REG_IN1_HIGH 0x32 /* f71882fg only */
58 61
59#define F71882FG_REG_FAN(nr) (0xA0 + (16 * (nr))) 62#define F71882FG_REG_FAN(nr) (0xA0 + (16 * (nr)))
63#define F71882FG_REG_FAN_TARGET(nr) (0xA2 + (16 * (nr)))
64#define F71882FG_REG_FAN_FULL_SPEED(nr) (0xA4 + (16 * (nr)))
60#define F71882FG_REG_FAN_STATUS 0x92 65#define F71882FG_REG_FAN_STATUS 0x92
61#define F71882FG_REG_FAN_BEEP 0x93 66#define F71882FG_REG_FAN_BEEP 0x93
62 67
63#define F71882FG_REG_TEMP(nr) (0x72 + 2 * (nr)) 68#define F71882FG_REG_TEMP(nr) (0x70 + 2 * (nr))
64#define F71882FG_REG_TEMP_OVT(nr) (0x82 + 2 * (nr)) 69#define F71882FG_REG_TEMP_OVT(nr) (0x80 + 2 * (nr))
65#define F71882FG_REG_TEMP_HIGH(nr) (0x83 + 2 * (nr)) 70#define F71882FG_REG_TEMP_HIGH(nr) (0x81 + 2 * (nr))
66#define F71882FG_REG_TEMP_STATUS 0x62 71#define F71882FG_REG_TEMP_STATUS 0x62
67#define F71882FG_REG_TEMP_BEEP 0x63 72#define F71882FG_REG_TEMP_BEEP 0x63
68#define F71882FG_REG_TEMP_HYST1 0x6C 73#define F71882FG_REG_TEMP_HYST(nr) (0x6C + (nr))
69#define F71882FG_REG_TEMP_HYST23 0x6D
70#define F71882FG_REG_TEMP_TYPE 0x6B 74#define F71882FG_REG_TEMP_TYPE 0x6B
71#define F71882FG_REG_TEMP_DIODE_OPEN 0x6F 75#define F71882FG_REG_TEMP_DIODE_OPEN 0x6F
72 76
77#define F71882FG_REG_PWM(nr) (0xA3 + (16 * (nr)))
78#define F71882FG_REG_PWM_TYPE 0x94
79#define F71882FG_REG_PWM_ENABLE 0x96
80
81#define F71882FG_REG_FAN_HYST(nr) (0x98 + (nr))
82
83#define F71882FG_REG_POINT_PWM(pwm, point) (0xAA + (point) + (16 * (pwm)))
84#define F71882FG_REG_POINT_TEMP(pwm, point) (0xA6 + (point) + (16 * (pwm)))
85#define F71882FG_REG_POINT_MAPPING(nr) (0xAF + 16 * (nr))
86
73#define F71882FG_REG_START 0x01 87#define F71882FG_REG_START 0x01
74 88
75#define FAN_MIN_DETECT 366 /* Lowest detectable fanspeed */ 89#define FAN_MIN_DETECT 366 /* Lowest detectable fanspeed */
@@ -78,7 +92,15 @@ static unsigned short force_id;
78module_param(force_id, ushort, 0); 92module_param(force_id, ushort, 0);
79MODULE_PARM_DESC(force_id, "Override the detected device ID"); 93MODULE_PARM_DESC(force_id, "Override the detected device ID");
80 94
81static struct platform_device *f71882fg_pdev = NULL; 95enum chips { f71862fg, f71882fg, f8000 };
96
97static const char *f71882fg_names[] = {
98 "f71862fg",
99 "f71882fg",
100 "f8000",
101};
102
103static struct platform_device *f71882fg_pdev;
82 104
83/* Super-I/O Function prototypes */ 105/* Super-I/O Function prototypes */
84static inline int superio_inb(int base, int reg); 106static inline int superio_inb(int base, int reg);
@@ -87,8 +109,13 @@ static inline void superio_enter(int base);
87static inline void superio_select(int base, int ld); 109static inline void superio_select(int base, int ld);
88static inline void superio_exit(int base); 110static inline void superio_exit(int base);
89 111
112struct f71882fg_sio_data {
113 enum chips type;
114};
115
90struct f71882fg_data { 116struct f71882fg_data {
91 unsigned short addr; 117 unsigned short addr;
118 enum chips type;
92 struct device *hwmon_dev; 119 struct device *hwmon_dev;
93 120
94 struct mutex update_lock; 121 struct mutex update_lock;
@@ -102,19 +129,30 @@ struct f71882fg_data {
102 u8 in_status; 129 u8 in_status;
103 u8 in_beep; 130 u8 in_beep;
104 u16 fan[4]; 131 u16 fan[4];
132 u16 fan_target[4];
133 u16 fan_full_speed[4];
105 u8 fan_status; 134 u8 fan_status;
106 u8 fan_beep; 135 u8 fan_beep;
107 u8 temp[3]; 136 /* Note: all models have only 3 temperature channels, but on some
108 u8 temp_ovt[3]; 137 they are addressed as 0-2 and on others as 1-3, so for coding
109 u8 temp_high[3]; 138 convenience we reserve space for 4 channels */
110 u8 temp_hyst[3]; 139 u8 temp[4];
111 u8 temp_type[3]; 140 u8 temp_ovt[4];
141 u8 temp_high[4];
142 u8 temp_hyst[2]; /* 2 hysts stored per reg */
143 u8 temp_type[4];
112 u8 temp_status; 144 u8 temp_status;
113 u8 temp_beep; 145 u8 temp_beep;
114 u8 temp_diode_open; 146 u8 temp_diode_open;
147 u8 pwm[4];
148 u8 pwm_enable;
149 u8 pwm_auto_point_hyst[2];
150 u8 pwm_auto_point_mapping[4];
151 u8 pwm_auto_point_pwm[4][5];
152 u8 pwm_auto_point_temp[4][4];
115}; 153};
116 154
117/* Sysfs in*/ 155/* Sysfs in */
118static ssize_t show_in(struct device *dev, struct device_attribute *devattr, 156static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
119 char *buf); 157 char *buf);
120static ssize_t show_in_max(struct device *dev, struct device_attribute 158static ssize_t show_in_max(struct device *dev, struct device_attribute
@@ -130,6 +168,10 @@ static ssize_t show_in_alarm(struct device *dev, struct device_attribute
130/* Sysfs Fan */ 168/* Sysfs Fan */
131static ssize_t show_fan(struct device *dev, struct device_attribute *devattr, 169static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
132 char *buf); 170 char *buf);
171static ssize_t show_fan_full_speed(struct device *dev,
172 struct device_attribute *devattr, char *buf);
173static ssize_t store_fan_full_speed(struct device *dev,
174 struct device_attribute *devattr, const char *buf, size_t count);
133static ssize_t show_fan_beep(struct device *dev, struct device_attribute 175static ssize_t show_fan_beep(struct device *dev, struct device_attribute
134 *devattr, char *buf); 176 *devattr, char *buf);
135static ssize_t store_fan_beep(struct device *dev, struct device_attribute 177static ssize_t store_fan_beep(struct device *dev, struct device_attribute
@@ -163,16 +205,41 @@ static ssize_t show_temp_alarm(struct device *dev, struct device_attribute
163 *devattr, char *buf); 205 *devattr, char *buf);
164static ssize_t show_temp_fault(struct device *dev, struct device_attribute 206static ssize_t show_temp_fault(struct device *dev, struct device_attribute
165 *devattr, char *buf); 207 *devattr, char *buf);
208/* PWM and Auto point control */
209static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr,
210 char *buf);
211static ssize_t store_pwm(struct device *dev, struct device_attribute *devattr,
212 const char *buf, size_t count);
213static ssize_t show_pwm_enable(struct device *dev,
214 struct device_attribute *devattr, char *buf);
215static ssize_t store_pwm_enable(struct device *dev,
216 struct device_attribute *devattr, const char *buf, size_t count);
217static ssize_t show_pwm_interpolate(struct device *dev,
218 struct device_attribute *devattr, char *buf);
219static ssize_t store_pwm_interpolate(struct device *dev,
220 struct device_attribute *devattr, const char *buf, size_t count);
221static ssize_t show_pwm_auto_point_channel(struct device *dev,
222 struct device_attribute *devattr, char *buf);
223static ssize_t store_pwm_auto_point_channel(struct device *dev,
224 struct device_attribute *devattr, const char *buf, size_t count);
225static ssize_t show_pwm_auto_point_temp_hyst(struct device *dev,
226 struct device_attribute *devattr, char *buf);
227static ssize_t store_pwm_auto_point_temp_hyst(struct device *dev,
228 struct device_attribute *devattr, const char *buf, size_t count);
229static ssize_t show_pwm_auto_point_pwm(struct device *dev,
230 struct device_attribute *devattr, char *buf);
231static ssize_t store_pwm_auto_point_pwm(struct device *dev,
232 struct device_attribute *devattr, const char *buf, size_t count);
233static ssize_t show_pwm_auto_point_temp(struct device *dev,
234 struct device_attribute *devattr, char *buf);
235static ssize_t store_pwm_auto_point_temp(struct device *dev,
236 struct device_attribute *devattr, const char *buf, size_t count);
166/* Sysfs misc */ 237/* Sysfs misc */
167static ssize_t show_name(struct device *dev, struct device_attribute *devattr, 238static ssize_t show_name(struct device *dev, struct device_attribute *devattr,
168 char *buf); 239 char *buf);
169 240
170static int __devinit f71882fg_probe(struct platform_device * pdev); 241static int __devinit f71882fg_probe(struct platform_device * pdev);
171static int __devexit f71882fg_remove(struct platform_device *pdev); 242static int f71882fg_remove(struct platform_device *pdev);
172static int __init f71882fg_init(void);
173static int __init f71882fg_find(int sioaddr, unsigned short *address);
174static int __init f71882fg_device_add(unsigned short address);
175static void __exit f71882fg_exit(void);
176 243
177static struct platform_driver f71882fg_driver = { 244static struct platform_driver f71882fg_driver = {
178 .driver = { 245 .driver = {
@@ -183,86 +250,531 @@ static struct platform_driver f71882fg_driver = {
183 .remove = __devexit_p(f71882fg_remove), 250 .remove = __devexit_p(f71882fg_remove),
184}; 251};
185 252
186static struct device_attribute f71882fg_dev_attr[] = 253static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
187{ 254
188 __ATTR( name, S_IRUGO, show_name, NULL ), 255/* Temp and in attr common to both the f71862fg and f71882fg */
256static struct sensor_device_attribute_2 f718x2fg_in_temp_attr[] = {
257 SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
258 SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
259 SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
260 SENSOR_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 0, 3),
261 SENSOR_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 0, 4),
262 SENSOR_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 0, 5),
263 SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 6),
264 SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 7),
265 SENSOR_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 0, 8),
266 SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 1),
267 SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max,
268 store_temp_max, 0, 1),
269 SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
270 store_temp_max_hyst, 0, 1),
271 /* Should really be temp1_max_alarm, but older versions did not handle
272 the max and crit alarms separately and lm_sensors v2 depends on the
273 presence of temp#_alarm files. The same goes for temp2/3 _alarm. */
274 SENSOR_ATTR_2(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 1),
275 SENSOR_ATTR_2(temp1_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
276 store_temp_beep, 0, 1),
277 SENSOR_ATTR_2(temp1_crit, S_IRUGO|S_IWUSR, show_temp_crit,
278 store_temp_crit, 0, 1),
279 SENSOR_ATTR_2(temp1_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
280 0, 1),
281 SENSOR_ATTR_2(temp1_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5),
282 SENSOR_ATTR_2(temp1_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
283 store_temp_beep, 0, 5),
284 SENSOR_ATTR_2(temp1_type, S_IRUGO, show_temp_type, NULL, 0, 1),
285 SENSOR_ATTR_2(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0, 1),
286 SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 2),
287 SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_max,
288 store_temp_max, 0, 2),
289 SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
290 store_temp_max_hyst, 0, 2),
291 /* Should be temp2_max_alarm, see temp1_alarm note */
292 SENSOR_ATTR_2(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 2),
293 SENSOR_ATTR_2(temp2_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
294 store_temp_beep, 0, 2),
295 SENSOR_ATTR_2(temp2_crit, S_IRUGO|S_IWUSR, show_temp_crit,
296 store_temp_crit, 0, 2),
297 SENSOR_ATTR_2(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
298 0, 2),
299 SENSOR_ATTR_2(temp2_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6),
300 SENSOR_ATTR_2(temp2_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
301 store_temp_beep, 0, 6),
302 SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 2),
303 SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
304 SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 3),
305 SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max,
306 store_temp_max, 0, 3),
307 SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
308 store_temp_max_hyst, 0, 3),
309 /* Should be temp3_max_alarm, see temp1_alarm note */
310 SENSOR_ATTR_2(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 3),
311 SENSOR_ATTR_2(temp3_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
312 store_temp_beep, 0, 3),
313 SENSOR_ATTR_2(temp3_crit, S_IRUGO|S_IWUSR, show_temp_crit,
314 store_temp_crit, 0, 3),
315 SENSOR_ATTR_2(temp3_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
316 0, 3),
317 SENSOR_ATTR_2(temp3_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 7),
318 SENSOR_ATTR_2(temp3_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
319 store_temp_beep, 0, 7),
320 SENSOR_ATTR_2(temp3_type, S_IRUGO, show_temp_type, NULL, 0, 3),
321 SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 3),
322};
323
324/* Temp and in attr found only on the f71882fg */
325static struct sensor_device_attribute_2 f71882fg_in_temp_attr[] = {
326 SENSOR_ATTR_2(in1_max, S_IRUGO|S_IWUSR, show_in_max, store_in_max,
327 0, 1),
328 SENSOR_ATTR_2(in1_beep, S_IRUGO|S_IWUSR, show_in_beep, store_in_beep,
329 0, 1),
330 SENSOR_ATTR_2(in1_alarm, S_IRUGO, show_in_alarm, NULL, 0, 1),
331};
332
333/* Temp and in attr for the f8000
334 Note on the f8000 temp_ovt (crit) is used as max, and temp_high (max)
335 is used as hysteresis value to clear alarms
336 */
337static struct sensor_device_attribute_2 f8000_in_temp_attr[] = {
338 SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
339 SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
340 SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
341 SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0),
342 SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_crit,
343 store_temp_crit, 0, 0),
344 SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max,
345 store_temp_max, 0, 0),
346 SENSOR_ATTR_2(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 4),
347 SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1),
348 SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_crit,
349 store_temp_crit, 0, 1),
350 SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max,
351 store_temp_max, 0, 1),
352 SENSOR_ATTR_2(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5),
353 SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 1),
354 SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2),
355 SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_crit,
356 store_temp_crit, 0, 2),
357 SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max,
358 store_temp_max, 0, 2),
359 SENSOR_ATTR_2(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6),
360};
361
362/* Fan / PWM attr common to all models */
363static struct sensor_device_attribute_2 fxxxx_fan_attr[] = {
364 SENSOR_ATTR_2(fan1_input, S_IRUGO, show_fan, NULL, 0, 0),
365 SENSOR_ATTR_2(fan1_full_speed, S_IRUGO|S_IWUSR,
366 show_fan_full_speed,
367 store_fan_full_speed, 0, 0),
368 SENSOR_ATTR_2(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 0),
369 SENSOR_ATTR_2(fan2_input, S_IRUGO, show_fan, NULL, 0, 1),
370 SENSOR_ATTR_2(fan2_full_speed, S_IRUGO|S_IWUSR,
371 show_fan_full_speed,
372 store_fan_full_speed, 0, 1),
373 SENSOR_ATTR_2(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 1),
374 SENSOR_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 0, 2),
375 SENSOR_ATTR_2(fan3_full_speed, S_IRUGO|S_IWUSR,
376 show_fan_full_speed,
377 store_fan_full_speed, 0, 2),
378 SENSOR_ATTR_2(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 2),
379
380 SENSOR_ATTR_2(pwm1, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 0),
381 SENSOR_ATTR_2(pwm1_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
382 store_pwm_enable, 0, 0),
383 SENSOR_ATTR_2(pwm1_interpolate, S_IRUGO|S_IWUSR,
384 show_pwm_interpolate, store_pwm_interpolate, 0, 0),
385 SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
386 show_pwm_auto_point_channel,
387 store_pwm_auto_point_channel, 0, 0),
388
389 SENSOR_ATTR_2(pwm2, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 1),
390 SENSOR_ATTR_2(pwm2_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
391 store_pwm_enable, 0, 1),
392 SENSOR_ATTR_2(pwm2_interpolate, S_IRUGO|S_IWUSR,
393 show_pwm_interpolate, store_pwm_interpolate, 0, 1),
394 SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,
395 show_pwm_auto_point_channel,
396 store_pwm_auto_point_channel, 0, 1),
397
398 SENSOR_ATTR_2(pwm3_interpolate, S_IRUGO|S_IWUSR,
399 show_pwm_interpolate, store_pwm_interpolate, 0, 2),
400 SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
401 show_pwm_auto_point_channel,
402 store_pwm_auto_point_channel, 0, 2),
189}; 403};
190 404
191static struct sensor_device_attribute f71882fg_in_temp_attr[] = 405/* Fan / PWM attr for the f71862fg, less pwms and less zones per pwm than the
192{ 406 f71882fg */
193 SENSOR_ATTR(in0_input, S_IRUGO, show_in, NULL, 0), 407static struct sensor_device_attribute_2 f71862fg_fan_attr[] = {
194 SENSOR_ATTR(in1_input, S_IRUGO, show_in, NULL, 1), 408 SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep,
195 SENSOR_ATTR(in1_max, S_IRUGO|S_IWUSR, show_in_max, store_in_max, 1), 409 store_fan_beep, 0, 0),
196 SENSOR_ATTR(in1_beep, S_IRUGO|S_IWUSR, show_in_beep, store_in_beep, 1), 410 SENSOR_ATTR_2(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep,
197 SENSOR_ATTR(in1_alarm, S_IRUGO, show_in_alarm, NULL, 1), 411 store_fan_beep, 0, 1),
198 SENSOR_ATTR(in2_input, S_IRUGO, show_in, NULL, 2), 412 SENSOR_ATTR_2(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep,
199 SENSOR_ATTR(in3_input, S_IRUGO, show_in, NULL, 3), 413 store_fan_beep, 0, 2),
200 SENSOR_ATTR(in4_input, S_IRUGO, show_in, NULL, 4), 414
201 SENSOR_ATTR(in5_input, S_IRUGO, show_in, NULL, 5), 415 SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,
202 SENSOR_ATTR(in6_input, S_IRUGO, show_in, NULL, 6), 416 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
203 SENSOR_ATTR(in7_input, S_IRUGO, show_in, NULL, 7), 417 1, 0),
204 SENSOR_ATTR(in8_input, S_IRUGO, show_in, NULL, 8), 418 SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO|S_IWUSR,
205 SENSOR_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0), 419 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
206 SENSOR_ATTR(temp1_max, S_IRUGO|S_IWUSR, show_temp_max, 420 4, 0),
207 store_temp_max, 0), 421 SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IRUGO|S_IWUSR,
208 SENSOR_ATTR(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst, 422 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
209 store_temp_max_hyst, 0), 423 0, 0),
210 SENSOR_ATTR(temp1_crit, S_IRUGO|S_IWUSR, show_temp_crit, 424 SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IRUGO|S_IWUSR,
211 store_temp_crit, 0), 425 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
212 SENSOR_ATTR(temp1_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 0), 426 3, 0),
213 SENSOR_ATTR(temp1_type, S_IRUGO, show_temp_type, NULL, 0), 427 SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
214 SENSOR_ATTR(temp1_beep, S_IRUGO|S_IWUSR, show_temp_beep, 428 show_pwm_auto_point_temp_hyst,
215 store_temp_beep, 0), 429 store_pwm_auto_point_temp_hyst,
216 SENSOR_ATTR(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0), 430 0, 0),
217 SENSOR_ATTR(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0), 431 SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO,
218 SENSOR_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1), 432 show_pwm_auto_point_temp_hyst, NULL, 3, 0),
219 SENSOR_ATTR(temp2_max, S_IRUGO|S_IWUSR, show_temp_max, 433
220 store_temp_max, 1), 434 SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR,
221 SENSOR_ATTR(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst, 435 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
222 store_temp_max_hyst, 1), 436 1, 1),
223 SENSOR_ATTR(temp2_crit, S_IRUGO|S_IWUSR, show_temp_crit, 437 SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO|S_IWUSR,
224 store_temp_crit, 1), 438 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
225 SENSOR_ATTR(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 1), 439 4, 1),
226 SENSOR_ATTR(temp2_type, S_IRUGO, show_temp_type, NULL, 1), 440 SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IRUGO|S_IWUSR,
227 SENSOR_ATTR(temp2_beep, S_IRUGO|S_IWUSR, show_temp_beep, 441 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
228 store_temp_beep, 1), 442 0, 1),
229 SENSOR_ATTR(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 1), 443 SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IRUGO|S_IWUSR,
230 SENSOR_ATTR(temp2_fault, S_IRUGO, show_temp_fault, NULL, 1), 444 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
231 SENSOR_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2), 445 3, 1),
232 SENSOR_ATTR(temp3_max, S_IRUGO|S_IWUSR, show_temp_max, 446 SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
233 store_temp_max, 2), 447 show_pwm_auto_point_temp_hyst,
234 SENSOR_ATTR(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst, 448 store_pwm_auto_point_temp_hyst,
235 store_temp_max_hyst, 2), 449 0, 1),
236 SENSOR_ATTR(temp3_crit, S_IRUGO|S_IWUSR, show_temp_crit, 450 SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO,
237 store_temp_crit, 2), 451 show_pwm_auto_point_temp_hyst, NULL, 3, 1),
238 SENSOR_ATTR(temp3_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 2), 452
239 SENSOR_ATTR(temp3_type, S_IRUGO, show_temp_type, NULL, 2), 453 SENSOR_ATTR_2(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 2),
240 SENSOR_ATTR(temp3_beep, S_IRUGO|S_IWUSR, show_temp_beep, 454 SENSOR_ATTR_2(pwm3_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
241 store_temp_beep, 2), 455 store_pwm_enable, 0, 2),
242 SENSOR_ATTR(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 2), 456 SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR,
243 SENSOR_ATTR(temp3_fault, S_IRUGO, show_temp_fault, NULL, 2) 457 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
458 1, 2),
459 SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO|S_IWUSR,
460 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
461 4, 2),
462 SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IRUGO|S_IWUSR,
463 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
464 0, 2),
465 SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IRUGO|S_IWUSR,
466 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
467 3, 2),
468 SENSOR_ATTR_2(pwm3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
469 show_pwm_auto_point_temp_hyst,
470 store_pwm_auto_point_temp_hyst,
471 0, 2),
472 SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst, S_IRUGO,
473 show_pwm_auto_point_temp_hyst, NULL, 3, 2),
244}; 474};
245 475
246static struct sensor_device_attribute f71882fg_fan_attr[] = 476/* Fan / PWM attr for the f71882fg */
247{ 477static struct sensor_device_attribute_2 f71882fg_fan_attr[] = {
248 SENSOR_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0), 478 SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep,
249 SENSOR_ATTR(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep, 479 store_fan_beep, 0, 0),
250 store_fan_beep, 0), 480 SENSOR_ATTR_2(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep,
251 SENSOR_ATTR(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0), 481 store_fan_beep, 0, 1),
252 SENSOR_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1), 482 SENSOR_ATTR_2(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep,
253 SENSOR_ATTR(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep, 483 store_fan_beep, 0, 2),
254 store_fan_beep, 1), 484 SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
255 SENSOR_ATTR(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 1), 485 SENSOR_ATTR_2(fan4_full_speed, S_IRUGO|S_IWUSR,
256 SENSOR_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2), 486 show_fan_full_speed,
257 SENSOR_ATTR(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep, 487 store_fan_full_speed, 0, 3),
258 store_fan_beep, 2), 488 SENSOR_ATTR_2(fan4_beep, S_IRUGO|S_IWUSR, show_fan_beep,
259 SENSOR_ATTR(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 2), 489 store_fan_beep, 0, 3),
260 SENSOR_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3), 490 SENSOR_ATTR_2(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 3),
261 SENSOR_ATTR(fan4_beep, S_IRUGO|S_IWUSR, show_fan_beep, 491
262 store_fan_beep, 3), 492 SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,
263 SENSOR_ATTR(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 3) 493 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
494 0, 0),
495 SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO|S_IWUSR,
496 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
497 1, 0),
498 SENSOR_ATTR_2(pwm1_auto_point3_pwm, S_IRUGO|S_IWUSR,
499 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
500 2, 0),
501 SENSOR_ATTR_2(pwm1_auto_point4_pwm, S_IRUGO|S_IWUSR,
502 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
503 3, 0),
504 SENSOR_ATTR_2(pwm1_auto_point5_pwm, S_IRUGO|S_IWUSR,
505 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
506 4, 0),
507 SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IRUGO|S_IWUSR,
508 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
509 0, 0),
510 SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IRUGO|S_IWUSR,
511 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
512 1, 0),
513 SENSOR_ATTR_2(pwm1_auto_point3_temp, S_IRUGO|S_IWUSR,
514 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
515 2, 0),
516 SENSOR_ATTR_2(pwm1_auto_point4_temp, S_IRUGO|S_IWUSR,
517 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
518 3, 0),
519 SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
520 show_pwm_auto_point_temp_hyst,
521 store_pwm_auto_point_temp_hyst,
522 0, 0),
523 SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO,
524 show_pwm_auto_point_temp_hyst, NULL, 1, 0),
525 SENSOR_ATTR_2(pwm1_auto_point3_temp_hyst, S_IRUGO,
526 show_pwm_auto_point_temp_hyst, NULL, 2, 0),
527 SENSOR_ATTR_2(pwm1_auto_point4_temp_hyst, S_IRUGO,
528 show_pwm_auto_point_temp_hyst, NULL, 3, 0),
529
530 SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR,
531 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
532 0, 1),
533 SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO|S_IWUSR,
534 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
535 1, 1),
536 SENSOR_ATTR_2(pwm2_auto_point3_pwm, S_IRUGO|S_IWUSR,
537 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
538 2, 1),
539 SENSOR_ATTR_2(pwm2_auto_point4_pwm, S_IRUGO|S_IWUSR,
540 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
541 3, 1),
542 SENSOR_ATTR_2(pwm2_auto_point5_pwm, S_IRUGO|S_IWUSR,
543 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
544 4, 1),
545 SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IRUGO|S_IWUSR,
546 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
547 0, 1),
548 SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IRUGO|S_IWUSR,
549 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
550 1, 1),
551 SENSOR_ATTR_2(pwm2_auto_point3_temp, S_IRUGO|S_IWUSR,
552 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
553 2, 1),
554 SENSOR_ATTR_2(pwm2_auto_point4_temp, S_IRUGO|S_IWUSR,
555 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
556 3, 1),
557 SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
558 show_pwm_auto_point_temp_hyst,
559 store_pwm_auto_point_temp_hyst,
560 0, 1),
561 SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO,
562 show_pwm_auto_point_temp_hyst, NULL, 1, 1),
563 SENSOR_ATTR_2(pwm2_auto_point3_temp_hyst, S_IRUGO,
564 show_pwm_auto_point_temp_hyst, NULL, 2, 1),
565 SENSOR_ATTR_2(pwm2_auto_point4_temp_hyst, S_IRUGO,
566 show_pwm_auto_point_temp_hyst, NULL, 3, 1),
567
568 SENSOR_ATTR_2(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 2),
569 SENSOR_ATTR_2(pwm3_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
570 store_pwm_enable, 0, 2),
571 SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR,
572 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
573 0, 2),
574 SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO|S_IWUSR,
575 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
576 1, 2),
577 SENSOR_ATTR_2(pwm3_auto_point3_pwm, S_IRUGO|S_IWUSR,
578 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
579 2, 2),
580 SENSOR_ATTR_2(pwm3_auto_point4_pwm, S_IRUGO|S_IWUSR,
581 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
582 3, 2),
583 SENSOR_ATTR_2(pwm3_auto_point5_pwm, S_IRUGO|S_IWUSR,
584 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
585 4, 2),
586 SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IRUGO|S_IWUSR,
587 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
588 0, 2),
589 SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IRUGO|S_IWUSR,
590 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
591 1, 2),
592 SENSOR_ATTR_2(pwm3_auto_point3_temp, S_IRUGO|S_IWUSR,
593 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
594 2, 2),
595 SENSOR_ATTR_2(pwm3_auto_point4_temp, S_IRUGO|S_IWUSR,
596 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
597 3, 2),
598 SENSOR_ATTR_2(pwm3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
599 show_pwm_auto_point_temp_hyst,
600 store_pwm_auto_point_temp_hyst,
601 0, 2),
602 SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst, S_IRUGO,
603 show_pwm_auto_point_temp_hyst, NULL, 1, 2),
604 SENSOR_ATTR_2(pwm3_auto_point3_temp_hyst, S_IRUGO,
605 show_pwm_auto_point_temp_hyst, NULL, 2, 2),
606 SENSOR_ATTR_2(pwm3_auto_point4_temp_hyst, S_IRUGO,
607 show_pwm_auto_point_temp_hyst, NULL, 3, 2),
608
609 SENSOR_ATTR_2(pwm4, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 3),
610 SENSOR_ATTR_2(pwm4_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
611 store_pwm_enable, 0, 3),
612 SENSOR_ATTR_2(pwm4_interpolate, S_IRUGO|S_IWUSR,
613 show_pwm_interpolate, store_pwm_interpolate, 0, 3),
614 SENSOR_ATTR_2(pwm4_auto_channels_temp, S_IRUGO|S_IWUSR,
615 show_pwm_auto_point_channel,
616 store_pwm_auto_point_channel, 0, 3),
617 SENSOR_ATTR_2(pwm4_auto_point1_pwm, S_IRUGO|S_IWUSR,
618 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
619 0, 3),
620 SENSOR_ATTR_2(pwm4_auto_point2_pwm, S_IRUGO|S_IWUSR,
621 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
622 1, 3),
623 SENSOR_ATTR_2(pwm4_auto_point3_pwm, S_IRUGO|S_IWUSR,
624 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
625 2, 3),
626 SENSOR_ATTR_2(pwm4_auto_point4_pwm, S_IRUGO|S_IWUSR,
627 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
628 3, 3),
629 SENSOR_ATTR_2(pwm4_auto_point5_pwm, S_IRUGO|S_IWUSR,
630 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
631 4, 3),
632 SENSOR_ATTR_2(pwm4_auto_point1_temp, S_IRUGO|S_IWUSR,
633 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
634 0, 3),
635 SENSOR_ATTR_2(pwm4_auto_point2_temp, S_IRUGO|S_IWUSR,
636 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
637 1, 3),
638 SENSOR_ATTR_2(pwm4_auto_point3_temp, S_IRUGO|S_IWUSR,
639 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
640 2, 3),
641 SENSOR_ATTR_2(pwm4_auto_point4_temp, S_IRUGO|S_IWUSR,
642 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
643 3, 3),
644 SENSOR_ATTR_2(pwm4_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
645 show_pwm_auto_point_temp_hyst,
646 store_pwm_auto_point_temp_hyst,
647 0, 3),
648 SENSOR_ATTR_2(pwm4_auto_point2_temp_hyst, S_IRUGO,
649 show_pwm_auto_point_temp_hyst, NULL, 1, 3),
650 SENSOR_ATTR_2(pwm4_auto_point3_temp_hyst, S_IRUGO,
651 show_pwm_auto_point_temp_hyst, NULL, 2, 3),
652 SENSOR_ATTR_2(pwm4_auto_point4_temp_hyst, S_IRUGO,
653 show_pwm_auto_point_temp_hyst, NULL, 3, 3),
264}; 654};
265 655
656/* Fan / PWM attr for the f8000, zones mapped to temp instead of to pwm!
657 Also the register block at offset A0 maps to TEMP1 (so our temp2, as the
658 F8000 starts counting temps at 0), B0 maps the TEMP2 and C0 maps to TEMP0 */
659static struct sensor_device_attribute_2 f8000_fan_attr[] = {
660 SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
661
662 SENSOR_ATTR_2(pwm3, S_IRUGO, show_pwm, NULL, 0, 2),
663
664 SENSOR_ATTR_2(temp1_auto_point1_pwm, S_IRUGO|S_IWUSR,
665 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
666 0, 2),
667 SENSOR_ATTR_2(temp1_auto_point2_pwm, S_IRUGO|S_IWUSR,
668 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
669 1, 2),
670 SENSOR_ATTR_2(temp1_auto_point3_pwm, S_IRUGO|S_IWUSR,
671 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
672 2, 2),
673 SENSOR_ATTR_2(temp1_auto_point4_pwm, S_IRUGO|S_IWUSR,
674 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
675 3, 2),
676 SENSOR_ATTR_2(temp1_auto_point5_pwm, S_IRUGO|S_IWUSR,
677 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
678 4, 2),
679 SENSOR_ATTR_2(temp1_auto_point1_temp, S_IRUGO|S_IWUSR,
680 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
681 0, 2),
682 SENSOR_ATTR_2(temp1_auto_point2_temp, S_IRUGO|S_IWUSR,
683 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
684 1, 2),
685 SENSOR_ATTR_2(temp1_auto_point3_temp, S_IRUGO|S_IWUSR,
686 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
687 2, 2),
688 SENSOR_ATTR_2(temp1_auto_point4_temp, S_IRUGO|S_IWUSR,
689 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
690 3, 2),
691 SENSOR_ATTR_2(temp1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
692 show_pwm_auto_point_temp_hyst,
693 store_pwm_auto_point_temp_hyst,
694 0, 2),
695 SENSOR_ATTR_2(temp1_auto_point2_temp_hyst, S_IRUGO,
696 show_pwm_auto_point_temp_hyst, NULL, 1, 2),
697 SENSOR_ATTR_2(temp1_auto_point3_temp_hyst, S_IRUGO,
698 show_pwm_auto_point_temp_hyst, NULL, 2, 2),
699 SENSOR_ATTR_2(temp1_auto_point4_temp_hyst, S_IRUGO,
700 show_pwm_auto_point_temp_hyst, NULL, 3, 2),
701
702 SENSOR_ATTR_2(temp2_auto_point1_pwm, S_IRUGO|S_IWUSR,
703 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
704 0, 0),
705 SENSOR_ATTR_2(temp2_auto_point2_pwm, S_IRUGO|S_IWUSR,
706 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
707 1, 0),
708 SENSOR_ATTR_2(temp2_auto_point3_pwm, S_IRUGO|S_IWUSR,
709 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
710 2, 0),
711 SENSOR_ATTR_2(temp2_auto_point4_pwm, S_IRUGO|S_IWUSR,
712 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
713 3, 0),
714 SENSOR_ATTR_2(temp2_auto_point5_pwm, S_IRUGO|S_IWUSR,
715 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
716 4, 0),
717 SENSOR_ATTR_2(temp2_auto_point1_temp, S_IRUGO|S_IWUSR,
718 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
719 0, 0),
720 SENSOR_ATTR_2(temp2_auto_point2_temp, S_IRUGO|S_IWUSR,
721 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
722 1, 0),
723 SENSOR_ATTR_2(temp2_auto_point3_temp, S_IRUGO|S_IWUSR,
724 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
725 2, 0),
726 SENSOR_ATTR_2(temp2_auto_point4_temp, S_IRUGO|S_IWUSR,
727 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
728 3, 0),
729 SENSOR_ATTR_2(temp2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
730 show_pwm_auto_point_temp_hyst,
731 store_pwm_auto_point_temp_hyst,
732 0, 0),
733 SENSOR_ATTR_2(temp2_auto_point2_temp_hyst, S_IRUGO,
734 show_pwm_auto_point_temp_hyst, NULL, 1, 0),
735 SENSOR_ATTR_2(temp2_auto_point3_temp_hyst, S_IRUGO,
736 show_pwm_auto_point_temp_hyst, NULL, 2, 0),
737 SENSOR_ATTR_2(temp2_auto_point4_temp_hyst, S_IRUGO,
738 show_pwm_auto_point_temp_hyst, NULL, 3, 0),
739
740 SENSOR_ATTR_2(temp3_auto_point1_pwm, S_IRUGO|S_IWUSR,
741 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
742 0, 1),
743 SENSOR_ATTR_2(temp3_auto_point2_pwm, S_IRUGO|S_IWUSR,
744 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
745 1, 1),
746 SENSOR_ATTR_2(temp3_auto_point3_pwm, S_IRUGO|S_IWUSR,
747 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
748 2, 1),
749 SENSOR_ATTR_2(temp3_auto_point4_pwm, S_IRUGO|S_IWUSR,
750 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
751 3, 1),
752 SENSOR_ATTR_2(temp3_auto_point5_pwm, S_IRUGO|S_IWUSR,
753 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
754 4, 1),
755 SENSOR_ATTR_2(temp3_auto_point1_temp, S_IRUGO|S_IWUSR,
756 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
757 0, 1),
758 SENSOR_ATTR_2(temp3_auto_point2_temp, S_IRUGO|S_IWUSR,
759 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
760 1, 1),
761 SENSOR_ATTR_2(temp3_auto_point3_temp, S_IRUGO|S_IWUSR,
762 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
763 2, 1),
764 SENSOR_ATTR_2(temp3_auto_point4_temp, S_IRUGO|S_IWUSR,
765 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
766 3, 1),
767 SENSOR_ATTR_2(temp3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
768 show_pwm_auto_point_temp_hyst,
769 store_pwm_auto_point_temp_hyst,
770 0, 1),
771 SENSOR_ATTR_2(temp3_auto_point2_temp_hyst, S_IRUGO,
772 show_pwm_auto_point_temp_hyst, NULL, 1, 1),
773 SENSOR_ATTR_2(temp3_auto_point3_temp_hyst, S_IRUGO,
774 show_pwm_auto_point_temp_hyst, NULL, 2, 1),
775 SENSOR_ATTR_2(temp3_auto_point4_temp_hyst, S_IRUGO,
776 show_pwm_auto_point_temp_hyst, NULL, 3, 1),
777};
266 778
267/* Super I/O functions */ 779/* Super I/O functions */
268static inline int superio_inb(int base, int reg) 780static inline int superio_inb(int base, int reg)
@@ -299,11 +811,16 @@ static inline void superio_exit(int base)
299 outb(SIO_LOCK_KEY, base); 811 outb(SIO_LOCK_KEY, base);
300} 812}
301 813
302static inline u16 fan_from_reg(u16 reg) 814static inline int fan_from_reg(u16 reg)
303{ 815{
304 return reg ? (1500000 / reg) : 0; 816 return reg ? (1500000 / reg) : 0;
305} 817}
306 818
819static inline u16 fan_to_reg(int fan)
820{
821 return fan ? (1500000 / fan) : 0;
822}
823
307static u8 f71882fg_read8(struct f71882fg_data *data, u8 reg) 824static u8 f71882fg_read8(struct f71882fg_data *data, u8 reg)
308{ 825{
309 u8 val; 826 u8 val;
@@ -332,52 +849,111 @@ static void f71882fg_write8(struct f71882fg_data *data, u8 reg, u8 val)
332 outb(val, data->addr + DATA_REG_OFFSET); 849 outb(val, data->addr + DATA_REG_OFFSET);
333} 850}
334 851
335static struct f71882fg_data *f71882fg_update_device(struct device * dev) 852static void f71882fg_write16(struct f71882fg_data *data, u8 reg, u16 val)
853{
854 outb(reg++, data->addr + ADDR_REG_OFFSET);
855 outb(val >> 8, data->addr + DATA_REG_OFFSET);
856 outb(reg, data->addr + ADDR_REG_OFFSET);
857 outb(val & 255, data->addr + DATA_REG_OFFSET);
858}
859
860static struct f71882fg_data *f71882fg_update_device(struct device *dev)
336{ 861{
337 struct f71882fg_data *data = dev_get_drvdata(dev); 862 struct f71882fg_data *data = dev_get_drvdata(dev);
338 int nr, reg, reg2; 863 int nr, reg = 0, reg2;
864 int nr_fans = (data->type == f71882fg) ? 4 : 3;
865 int nr_ins = (data->type == f8000) ? 3 : 9;
866 int temp_start = (data->type == f8000) ? 0 : 1;
339 867
340 mutex_lock(&data->update_lock); 868 mutex_lock(&data->update_lock);
341 869
342 /* Update once every 60 seconds */ 870 /* Update once every 60 seconds */
343 if ( time_after(jiffies, data->last_limits + 60 * HZ ) || 871 if ( time_after(jiffies, data->last_limits + 60 * HZ ) ||
344 !data->valid) { 872 !data->valid) {
345 data->in1_max = f71882fg_read8(data, F71882FG_REG_IN1_HIGH); 873 if (data->type == f71882fg) {
346 data->in_beep = f71882fg_read8(data, F71882FG_REG_IN_BEEP); 874 data->in1_max =
875 f71882fg_read8(data, F71882FG_REG_IN1_HIGH);
876 data->in_beep =
877 f71882fg_read8(data, F71882FG_REG_IN_BEEP);
878 }
347 879
348 /* Get High & boundary temps*/ 880 /* Get High & boundary temps*/
349 for (nr = 0; nr < 3; nr++) { 881 for (nr = temp_start; nr < 3 + temp_start; nr++) {
350 data->temp_ovt[nr] = f71882fg_read8(data, 882 data->temp_ovt[nr] = f71882fg_read8(data,
351 F71882FG_REG_TEMP_OVT(nr)); 883 F71882FG_REG_TEMP_OVT(nr));
352 data->temp_high[nr] = f71882fg_read8(data, 884 data->temp_high[nr] = f71882fg_read8(data,
353 F71882FG_REG_TEMP_HIGH(nr)); 885 F71882FG_REG_TEMP_HIGH(nr));
354 } 886 }
355 887
356 /* Have to hardcode hyst*/ 888 if (data->type != f8000) {
357 data->temp_hyst[0] = f71882fg_read8(data, 889 data->fan_beep = f71882fg_read8(data,
358 F71882FG_REG_TEMP_HYST1) >> 4; 890 F71882FG_REG_FAN_BEEP);
359 /* Hyst temps 2 & 3 stored in same register */ 891 data->temp_beep = f71882fg_read8(data,
360 reg = f71882fg_read8(data, F71882FG_REG_TEMP_HYST23); 892 F71882FG_REG_TEMP_BEEP);
361 data->temp_hyst[1] = reg & 0x0F; 893 data->temp_hyst[0] = f71882fg_read8(data,
362 data->temp_hyst[2] = reg >> 4; 894 F71882FG_REG_TEMP_HYST(0));
363 895 data->temp_hyst[1] = f71882fg_read8(data,
364 /* Have to hardcode type, because temp1 is special */ 896 F71882FG_REG_TEMP_HYST(1));
365 reg = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE); 897 /* Have to hardcode type, because temp1 is special */
898 reg = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE);
899 data->temp_type[2] = (reg & 0x04) ? 2 : 4;
900 data->temp_type[3] = (reg & 0x08) ? 2 : 4;
901 }
366 reg2 = f71882fg_read8(data, F71882FG_REG_PECI); 902 reg2 = f71882fg_read8(data, F71882FG_REG_PECI);
367 if ((reg2 & 0x03) == 0x01) 903 if ((reg2 & 0x03) == 0x01)
368 data->temp_type[0] = 6 /* PECI */; 904 data->temp_type[1] = 6 /* PECI */;
369 else if ((reg2 & 0x03) == 0x02) 905 else if ((reg2 & 0x03) == 0x02)
370 data->temp_type[0] = 5 /* AMDSI */; 906 data->temp_type[1] = 5 /* AMDSI */;
907 else if (data->type != f8000)
908 data->temp_type[1] = (reg & 0x02) ? 2 : 4;
371 else 909 else
372 data->temp_type[0] = (reg & 0x02) ? 2 : 4; 910 data->temp_type[1] = 2; /* F8000 only supports BJT */
373 911
374 data->temp_type[1] = (reg & 0x04) ? 2 : 4; 912 data->pwm_enable = f71882fg_read8(data,
375 data->temp_type[2] = (reg & 0x08) ? 2 : 4; 913 F71882FG_REG_PWM_ENABLE);
376 914 data->pwm_auto_point_hyst[0] =
377 data->temp_beep = f71882fg_read8(data, F71882FG_REG_TEMP_BEEP); 915 f71882fg_read8(data, F71882FG_REG_FAN_HYST(0));
378 916 data->pwm_auto_point_hyst[1] =
379 data->fan_beep = f71882fg_read8(data, F71882FG_REG_FAN_BEEP); 917 f71882fg_read8(data, F71882FG_REG_FAN_HYST(1));
380 918
919 for (nr = 0; nr < nr_fans; nr++) {
920 data->pwm_auto_point_mapping[nr] =
921 f71882fg_read8(data,
922 F71882FG_REG_POINT_MAPPING(nr));
923
924 if (data->type != f71862fg) {
925 int point;
926 for (point = 0; point < 5; point++) {
927 data->pwm_auto_point_pwm[nr][point] =
928 f71882fg_read8(data,
929 F71882FG_REG_POINT_PWM
930 (nr, point));
931 }
932 for (point = 0; point < 4; point++) {
933 data->pwm_auto_point_temp[nr][point] =
934 f71882fg_read8(data,
935 F71882FG_REG_POINT_TEMP
936 (nr, point));
937 }
938 } else {
939 data->pwm_auto_point_pwm[nr][1] =
940 f71882fg_read8(data,
941 F71882FG_REG_POINT_PWM
942 (nr, 1));
943 data->pwm_auto_point_pwm[nr][4] =
944 f71882fg_read8(data,
945 F71882FG_REG_POINT_PWM
946 (nr, 4));
947 data->pwm_auto_point_temp[nr][0] =
948 f71882fg_read8(data,
949 F71882FG_REG_POINT_TEMP
950 (nr, 0));
951 data->pwm_auto_point_temp[nr][3] =
952 f71882fg_read8(data,
953 F71882FG_REG_POINT_TEMP
954 (nr, 3));
955 }
956 }
381 data->last_limits = jiffies; 957 data->last_limits = jiffies;
382 } 958 }
383 959
@@ -387,19 +963,32 @@ static struct f71882fg_data *f71882fg_update_device(struct device * dev)
387 F71882FG_REG_TEMP_STATUS); 963 F71882FG_REG_TEMP_STATUS);
388 data->temp_diode_open = f71882fg_read8(data, 964 data->temp_diode_open = f71882fg_read8(data,
389 F71882FG_REG_TEMP_DIODE_OPEN); 965 F71882FG_REG_TEMP_DIODE_OPEN);
390 for (nr = 0; nr < 3; nr++) 966 for (nr = temp_start; nr < 3 + temp_start; nr++)
391 data->temp[nr] = f71882fg_read8(data, 967 data->temp[nr] = f71882fg_read8(data,
392 F71882FG_REG_TEMP(nr)); 968 F71882FG_REG_TEMP(nr));
393 969
394 data->fan_status = f71882fg_read8(data, 970 data->fan_status = f71882fg_read8(data,
395 F71882FG_REG_FAN_STATUS); 971 F71882FG_REG_FAN_STATUS);
396 for (nr = 0; nr < 4; nr++) 972 for (nr = 0; nr < nr_fans; nr++) {
397 data->fan[nr] = f71882fg_read16(data, 973 data->fan[nr] = f71882fg_read16(data,
398 F71882FG_REG_FAN(nr)); 974 F71882FG_REG_FAN(nr));
975 data->fan_target[nr] =
976 f71882fg_read16(data, F71882FG_REG_FAN_TARGET(nr));
977 data->fan_full_speed[nr] =
978 f71882fg_read16(data,
979 F71882FG_REG_FAN_FULL_SPEED(nr));
980 data->pwm[nr] =
981 f71882fg_read8(data, F71882FG_REG_PWM(nr));
982 }
399 983
400 data->in_status = f71882fg_read8(data, 984 /* The f8000 can monitor 1 more fan, but has no pwm for it */
985 if (data->type == f8000)
986 data->fan[3] = f71882fg_read16(data,
987 F71882FG_REG_FAN(3));
988 if (data->type == f71882fg)
989 data->in_status = f71882fg_read8(data,
401 F71882FG_REG_IN_STATUS); 990 F71882FG_REG_IN_STATUS);
402 for (nr = 0; nr < 9; nr++) 991 for (nr = 0; nr < nr_ins; nr++)
403 data->in[nr] = f71882fg_read8(data, 992 data->in[nr] = f71882fg_read8(data,
404 F71882FG_REG_IN(nr)); 993 F71882FG_REG_IN(nr));
405 994
@@ -417,7 +1006,7 @@ static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
417 char *buf) 1006 char *buf)
418{ 1007{
419 struct f71882fg_data *data = f71882fg_update_device(dev); 1008 struct f71882fg_data *data = f71882fg_update_device(dev);
420 int nr = to_sensor_dev_attr(devattr)->index; 1009 int nr = to_sensor_dev_attr_2(devattr)->index;
421 int speed = fan_from_reg(data->fan[nr]); 1010 int speed = fan_from_reg(data->fan[nr]);
422 1011
423 if (speed == FAN_MIN_DETECT) 1012 if (speed == FAN_MIN_DETECT)
@@ -426,11 +1015,39 @@ static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
426 return sprintf(buf, "%d\n", speed); 1015 return sprintf(buf, "%d\n", speed);
427} 1016}
428 1017
1018static ssize_t show_fan_full_speed(struct device *dev,
1019 struct device_attribute *devattr, char *buf)
1020{
1021 struct f71882fg_data *data = f71882fg_update_device(dev);
1022 int nr = to_sensor_dev_attr_2(devattr)->index;
1023 int speed = fan_from_reg(data->fan_full_speed[nr]);
1024 return sprintf(buf, "%d\n", speed);
1025}
1026
1027static ssize_t store_fan_full_speed(struct device *dev,
1028 struct device_attribute *devattr,
1029 const char *buf, size_t count)
1030{
1031 struct f71882fg_data *data = dev_get_drvdata(dev);
1032 int nr = to_sensor_dev_attr_2(devattr)->index;
1033 long val = simple_strtol(buf, NULL, 10);
1034
1035 val = SENSORS_LIMIT(val, 23, 1500000);
1036 val = fan_to_reg(val);
1037
1038 mutex_lock(&data->update_lock);
1039 f71882fg_write16(data, F71882FG_REG_FAN_FULL_SPEED(nr), val);
1040 data->fan_full_speed[nr] = val;
1041 mutex_unlock(&data->update_lock);
1042
1043 return count;
1044}
1045
429static ssize_t show_fan_beep(struct device *dev, struct device_attribute 1046static ssize_t show_fan_beep(struct device *dev, struct device_attribute
430 *devattr, char *buf) 1047 *devattr, char *buf)
431{ 1048{
432 struct f71882fg_data *data = f71882fg_update_device(dev); 1049 struct f71882fg_data *data = f71882fg_update_device(dev);
433 int nr = to_sensor_dev_attr(devattr)->index; 1050 int nr = to_sensor_dev_attr_2(devattr)->index;
434 1051
435 if (data->fan_beep & (1 << nr)) 1052 if (data->fan_beep & (1 << nr))
436 return sprintf(buf, "1\n"); 1053 return sprintf(buf, "1\n");
@@ -442,10 +1059,11 @@ static ssize_t store_fan_beep(struct device *dev, struct device_attribute
442 *devattr, const char *buf, size_t count) 1059 *devattr, const char *buf, size_t count)
443{ 1060{
444 struct f71882fg_data *data = dev_get_drvdata(dev); 1061 struct f71882fg_data *data = dev_get_drvdata(dev);
445 int nr = to_sensor_dev_attr(devattr)->index; 1062 int nr = to_sensor_dev_attr_2(devattr)->index;
446 int val = simple_strtoul(buf, NULL, 10); 1063 unsigned long val = simple_strtoul(buf, NULL, 10);
447 1064
448 mutex_lock(&data->update_lock); 1065 mutex_lock(&data->update_lock);
1066 data->fan_beep = f71882fg_read8(data, F71882FG_REG_FAN_BEEP);
449 if (val) 1067 if (val)
450 data->fan_beep |= 1 << nr; 1068 data->fan_beep |= 1 << nr;
451 else 1069 else
@@ -461,7 +1079,7 @@ static ssize_t show_fan_alarm(struct device *dev, struct device_attribute
461 *devattr, char *buf) 1079 *devattr, char *buf)
462{ 1080{
463 struct f71882fg_data *data = f71882fg_update_device(dev); 1081 struct f71882fg_data *data = f71882fg_update_device(dev);
464 int nr = to_sensor_dev_attr(devattr)->index; 1082 int nr = to_sensor_dev_attr_2(devattr)->index;
465 1083
466 if (data->fan_status & (1 << nr)) 1084 if (data->fan_status & (1 << nr))
467 return sprintf(buf, "1\n"); 1085 return sprintf(buf, "1\n");
@@ -473,7 +1091,7 @@ static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
473 char *buf) 1091 char *buf)
474{ 1092{
475 struct f71882fg_data *data = f71882fg_update_device(dev); 1093 struct f71882fg_data *data = f71882fg_update_device(dev);
476 int nr = to_sensor_dev_attr(devattr)->index; 1094 int nr = to_sensor_dev_attr_2(devattr)->index;
477 1095
478 return sprintf(buf, "%d\n", data->in[nr] * 8); 1096 return sprintf(buf, "%d\n", data->in[nr] * 8);
479} 1097}
@@ -490,10 +1108,8 @@ static ssize_t store_in_max(struct device *dev, struct device_attribute
490 *devattr, const char *buf, size_t count) 1108 *devattr, const char *buf, size_t count)
491{ 1109{
492 struct f71882fg_data *data = dev_get_drvdata(dev); 1110 struct f71882fg_data *data = dev_get_drvdata(dev);
493 int val = simple_strtoul(buf, NULL, 10) / 8; 1111 long val = simple_strtol(buf, NULL, 10) / 8;
494 1112 val = SENSORS_LIMIT(val, 0, 255);
495 if (val > 255)
496 val = 255;
497 1113
498 mutex_lock(&data->update_lock); 1114 mutex_lock(&data->update_lock);
499 f71882fg_write8(data, F71882FG_REG_IN1_HIGH, val); 1115 f71882fg_write8(data, F71882FG_REG_IN1_HIGH, val);
@@ -507,7 +1123,7 @@ static ssize_t show_in_beep(struct device *dev, struct device_attribute
507 *devattr, char *buf) 1123 *devattr, char *buf)
508{ 1124{
509 struct f71882fg_data *data = f71882fg_update_device(dev); 1125 struct f71882fg_data *data = f71882fg_update_device(dev);
510 int nr = to_sensor_dev_attr(devattr)->index; 1126 int nr = to_sensor_dev_attr_2(devattr)->index;
511 1127
512 if (data->in_beep & (1 << nr)) 1128 if (data->in_beep & (1 << nr))
513 return sprintf(buf, "1\n"); 1129 return sprintf(buf, "1\n");
@@ -519,10 +1135,11 @@ static ssize_t store_in_beep(struct device *dev, struct device_attribute
519 *devattr, const char *buf, size_t count) 1135 *devattr, const char *buf, size_t count)
520{ 1136{
521 struct f71882fg_data *data = dev_get_drvdata(dev); 1137 struct f71882fg_data *data = dev_get_drvdata(dev);
522 int nr = to_sensor_dev_attr(devattr)->index; 1138 int nr = to_sensor_dev_attr_2(devattr)->index;
523 int val = simple_strtoul(buf, NULL, 10); 1139 unsigned long val = simple_strtoul(buf, NULL, 10);
524 1140
525 mutex_lock(&data->update_lock); 1141 mutex_lock(&data->update_lock);
1142 data->in_beep = f71882fg_read8(data, F71882FG_REG_IN_BEEP);
526 if (val) 1143 if (val)
527 data->in_beep |= 1 << nr; 1144 data->in_beep |= 1 << nr;
528 else 1145 else
@@ -538,7 +1155,7 @@ static ssize_t show_in_alarm(struct device *dev, struct device_attribute
538 *devattr, char *buf) 1155 *devattr, char *buf)
539{ 1156{
540 struct f71882fg_data *data = f71882fg_update_device(dev); 1157 struct f71882fg_data *data = f71882fg_update_device(dev);
541 int nr = to_sensor_dev_attr(devattr)->index; 1158 int nr = to_sensor_dev_attr_2(devattr)->index;
542 1159
543 if (data->in_status & (1 << nr)) 1160 if (data->in_status & (1 << nr))
544 return sprintf(buf, "1\n"); 1161 return sprintf(buf, "1\n");
@@ -550,7 +1167,7 @@ static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
550 char *buf) 1167 char *buf)
551{ 1168{
552 struct f71882fg_data *data = f71882fg_update_device(dev); 1169 struct f71882fg_data *data = f71882fg_update_device(dev);
553 int nr = to_sensor_dev_attr(devattr)->index; 1170 int nr = to_sensor_dev_attr_2(devattr)->index;
554 1171
555 return sprintf(buf, "%d\n", data->temp[nr] * 1000); 1172 return sprintf(buf, "%d\n", data->temp[nr] * 1000);
556} 1173}
@@ -559,7 +1176,7 @@ static ssize_t show_temp_max(struct device *dev, struct device_attribute
559 *devattr, char *buf) 1176 *devattr, char *buf)
560{ 1177{
561 struct f71882fg_data *data = f71882fg_update_device(dev); 1178 struct f71882fg_data *data = f71882fg_update_device(dev);
562 int nr = to_sensor_dev_attr(devattr)->index; 1179 int nr = to_sensor_dev_attr_2(devattr)->index;
563 1180
564 return sprintf(buf, "%d\n", data->temp_high[nr] * 1000); 1181 return sprintf(buf, "%d\n", data->temp_high[nr] * 1000);
565} 1182}
@@ -568,11 +1185,9 @@ static ssize_t store_temp_max(struct device *dev, struct device_attribute
568 *devattr, const char *buf, size_t count) 1185 *devattr, const char *buf, size_t count)
569{ 1186{
570 struct f71882fg_data *data = dev_get_drvdata(dev); 1187 struct f71882fg_data *data = dev_get_drvdata(dev);
571 int nr = to_sensor_dev_attr(devattr)->index; 1188 int nr = to_sensor_dev_attr_2(devattr)->index;
572 int val = simple_strtoul(buf, NULL, 10) / 1000; 1189 long val = simple_strtol(buf, NULL, 10) / 1000;
573 1190 val = SENSORS_LIMIT(val, 0, 255);
574 if (val > 255)
575 val = 255;
576 1191
577 mutex_lock(&data->update_lock); 1192 mutex_lock(&data->update_lock);
578 f71882fg_write8(data, F71882FG_REG_TEMP_HIGH(nr), val); 1193 f71882fg_write8(data, F71882FG_REG_TEMP_HIGH(nr), val);
@@ -586,48 +1201,46 @@ static ssize_t show_temp_max_hyst(struct device *dev, struct device_attribute
586 *devattr, char *buf) 1201 *devattr, char *buf)
587{ 1202{
588 struct f71882fg_data *data = f71882fg_update_device(dev); 1203 struct f71882fg_data *data = f71882fg_update_device(dev);
589 int nr = to_sensor_dev_attr(devattr)->index; 1204 int nr = to_sensor_dev_attr_2(devattr)->index;
1205 int temp_max_hyst;
1206
1207 mutex_lock(&data->update_lock);
1208 if (nr & 1)
1209 temp_max_hyst = data->temp_hyst[nr / 2] >> 4;
1210 else
1211 temp_max_hyst = data->temp_hyst[nr / 2] & 0x0f;
1212 temp_max_hyst = (data->temp_high[nr] - temp_max_hyst) * 1000;
1213 mutex_unlock(&data->update_lock);
590 1214
591 return sprintf(buf, "%d\n", 1215 return sprintf(buf, "%d\n", temp_max_hyst);
592 (data->temp_high[nr] - data->temp_hyst[nr]) * 1000);
593} 1216}
594 1217
595static ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute 1218static ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute
596 *devattr, const char *buf, size_t count) 1219 *devattr, const char *buf, size_t count)
597{ 1220{
598 struct f71882fg_data *data = dev_get_drvdata(dev); 1221 struct f71882fg_data *data = dev_get_drvdata(dev);
599 int nr = to_sensor_dev_attr(devattr)->index; 1222 int nr = to_sensor_dev_attr_2(devattr)->index;
600 int val = simple_strtoul(buf, NULL, 10) / 1000; 1223 long val = simple_strtol(buf, NULL, 10) / 1000;
601 ssize_t ret = count; 1224 ssize_t ret = count;
1225 u8 reg;
602 1226
603 mutex_lock(&data->update_lock); 1227 mutex_lock(&data->update_lock);
604 1228
605 /* convert abs to relative and check */ 1229 /* convert abs to relative and check */
1230 data->temp_high[nr] = f71882fg_read8(data, F71882FG_REG_TEMP_HIGH(nr));
1231 val = SENSORS_LIMIT(val, data->temp_high[nr] - 15,
1232 data->temp_high[nr]);
606 val = data->temp_high[nr] - val; 1233 val = data->temp_high[nr] - val;
607 if (val < 0 || val > 15) {
608 ret = -EINVAL;
609 goto store_temp_max_hyst_exit;
610 }
611
612 data->temp_hyst[nr] = val;
613 1234
614 /* convert value to register contents */ 1235 /* convert value to register contents */
615 switch (nr) { 1236 reg = f71882fg_read8(data, F71882FG_REG_TEMP_HYST(nr / 2));
616 case 0: 1237 if (nr & 1)
617 val = val << 4; 1238 reg = (reg & 0x0f) | (val << 4);
618 break; 1239 else
619 case 1: 1240 reg = (reg & 0xf0) | val;
620 val = val | (data->temp_hyst[2] << 4); 1241 f71882fg_write8(data, F71882FG_REG_TEMP_HYST(nr / 2), reg);
621 break; 1242 data->temp_hyst[nr / 2] = reg;
622 case 2:
623 val = data->temp_hyst[1] | (val << 4);
624 break;
625 }
626
627 f71882fg_write8(data, nr ? F71882FG_REG_TEMP_HYST23 :
628 F71882FG_REG_TEMP_HYST1, val);
629 1243
630store_temp_max_hyst_exit:
631 mutex_unlock(&data->update_lock); 1244 mutex_unlock(&data->update_lock);
632 return ret; 1245 return ret;
633} 1246}
@@ -636,7 +1249,7 @@ static ssize_t show_temp_crit(struct device *dev, struct device_attribute
636 *devattr, char *buf) 1249 *devattr, char *buf)
637{ 1250{
638 struct f71882fg_data *data = f71882fg_update_device(dev); 1251 struct f71882fg_data *data = f71882fg_update_device(dev);
639 int nr = to_sensor_dev_attr(devattr)->index; 1252 int nr = to_sensor_dev_attr_2(devattr)->index;
640 1253
641 return sprintf(buf, "%d\n", data->temp_ovt[nr] * 1000); 1254 return sprintf(buf, "%d\n", data->temp_ovt[nr] * 1000);
642} 1255}
@@ -645,11 +1258,9 @@ static ssize_t store_temp_crit(struct device *dev, struct device_attribute
645 *devattr, const char *buf, size_t count) 1258 *devattr, const char *buf, size_t count)
646{ 1259{
647 struct f71882fg_data *data = dev_get_drvdata(dev); 1260 struct f71882fg_data *data = dev_get_drvdata(dev);
648 int nr = to_sensor_dev_attr(devattr)->index; 1261 int nr = to_sensor_dev_attr_2(devattr)->index;
649 int val = simple_strtoul(buf, NULL, 10) / 1000; 1262 long val = simple_strtol(buf, NULL, 10) / 1000;
650 1263 val = SENSORS_LIMIT(val, 0, 255);
651 if (val > 255)
652 val = 255;
653 1264
654 mutex_lock(&data->update_lock); 1265 mutex_lock(&data->update_lock);
655 f71882fg_write8(data, F71882FG_REG_TEMP_OVT(nr), val); 1266 f71882fg_write8(data, F71882FG_REG_TEMP_OVT(nr), val);
@@ -663,17 +1274,25 @@ static ssize_t show_temp_crit_hyst(struct device *dev, struct device_attribute
663 *devattr, char *buf) 1274 *devattr, char *buf)
664{ 1275{
665 struct f71882fg_data *data = f71882fg_update_device(dev); 1276 struct f71882fg_data *data = f71882fg_update_device(dev);
666 int nr = to_sensor_dev_attr(devattr)->index; 1277 int nr = to_sensor_dev_attr_2(devattr)->index;
1278 int temp_crit_hyst;
1279
1280 mutex_lock(&data->update_lock);
1281 if (nr & 1)
1282 temp_crit_hyst = data->temp_hyst[nr / 2] >> 4;
1283 else
1284 temp_crit_hyst = data->temp_hyst[nr / 2] & 0x0f;
1285 temp_crit_hyst = (data->temp_ovt[nr] - temp_crit_hyst) * 1000;
1286 mutex_unlock(&data->update_lock);
667 1287
668 return sprintf(buf, "%d\n", 1288 return sprintf(buf, "%d\n", temp_crit_hyst);
669 (data->temp_ovt[nr] - data->temp_hyst[nr]) * 1000);
670} 1289}
671 1290
672static ssize_t show_temp_type(struct device *dev, struct device_attribute 1291static ssize_t show_temp_type(struct device *dev, struct device_attribute
673 *devattr, char *buf) 1292 *devattr, char *buf)
674{ 1293{
675 struct f71882fg_data *data = f71882fg_update_device(dev); 1294 struct f71882fg_data *data = f71882fg_update_device(dev);
676 int nr = to_sensor_dev_attr(devattr)->index; 1295 int nr = to_sensor_dev_attr_2(devattr)->index;
677 1296
678 return sprintf(buf, "%d\n", data->temp_type[nr]); 1297 return sprintf(buf, "%d\n", data->temp_type[nr]);
679} 1298}
@@ -682,9 +1301,9 @@ static ssize_t show_temp_beep(struct device *dev, struct device_attribute
682 *devattr, char *buf) 1301 *devattr, char *buf)
683{ 1302{
684 struct f71882fg_data *data = f71882fg_update_device(dev); 1303 struct f71882fg_data *data = f71882fg_update_device(dev);
685 int nr = to_sensor_dev_attr(devattr)->index; 1304 int nr = to_sensor_dev_attr_2(devattr)->index;
686 1305
687 if (data->temp_beep & (1 << (nr + 1))) 1306 if (data->temp_beep & (1 << nr))
688 return sprintf(buf, "1\n"); 1307 return sprintf(buf, "1\n");
689 else 1308 else
690 return sprintf(buf, "0\n"); 1309 return sprintf(buf, "0\n");
@@ -694,14 +1313,15 @@ static ssize_t store_temp_beep(struct device *dev, struct device_attribute
694 *devattr, const char *buf, size_t count) 1313 *devattr, const char *buf, size_t count)
695{ 1314{
696 struct f71882fg_data *data = dev_get_drvdata(dev); 1315 struct f71882fg_data *data = dev_get_drvdata(dev);
697 int nr = to_sensor_dev_attr(devattr)->index; 1316 int nr = to_sensor_dev_attr_2(devattr)->index;
698 int val = simple_strtoul(buf, NULL, 10); 1317 unsigned long val = simple_strtoul(buf, NULL, 10);
699 1318
700 mutex_lock(&data->update_lock); 1319 mutex_lock(&data->update_lock);
1320 data->temp_beep = f71882fg_read8(data, F71882FG_REG_TEMP_BEEP);
701 if (val) 1321 if (val)
702 data->temp_beep |= 1 << (nr + 1); 1322 data->temp_beep |= 1 << nr;
703 else 1323 else
704 data->temp_beep &= ~(1 << (nr + 1)); 1324 data->temp_beep &= ~(1 << nr);
705 1325
706 f71882fg_write8(data, F71882FG_REG_TEMP_BEEP, data->temp_beep); 1326 f71882fg_write8(data, F71882FG_REG_TEMP_BEEP, data->temp_beep);
707 mutex_unlock(&data->update_lock); 1327 mutex_unlock(&data->update_lock);
@@ -713,9 +1333,9 @@ static ssize_t show_temp_alarm(struct device *dev, struct device_attribute
713 *devattr, char *buf) 1333 *devattr, char *buf)
714{ 1334{
715 struct f71882fg_data *data = f71882fg_update_device(dev); 1335 struct f71882fg_data *data = f71882fg_update_device(dev);
716 int nr = to_sensor_dev_attr(devattr)->index; 1336 int nr = to_sensor_dev_attr_2(devattr)->index;
717 1337
718 if (data->temp_status & (1 << (nr + 1))) 1338 if (data->temp_status & (1 << nr))
719 return sprintf(buf, "1\n"); 1339 return sprintf(buf, "1\n");
720 else 1340 else
721 return sprintf(buf, "0\n"); 1341 return sprintf(buf, "0\n");
@@ -725,113 +1345,528 @@ static ssize_t show_temp_fault(struct device *dev, struct device_attribute
725 *devattr, char *buf) 1345 *devattr, char *buf)
726{ 1346{
727 struct f71882fg_data *data = f71882fg_update_device(dev); 1347 struct f71882fg_data *data = f71882fg_update_device(dev);
728 int nr = to_sensor_dev_attr(devattr)->index; 1348 int nr = to_sensor_dev_attr_2(devattr)->index;
729 1349
730 if (data->temp_diode_open & (1 << (nr + 1))) 1350 if (data->temp_diode_open & (1 << nr))
731 return sprintf(buf, "1\n"); 1351 return sprintf(buf, "1\n");
732 else 1352 else
733 return sprintf(buf, "0\n"); 1353 return sprintf(buf, "0\n");
734} 1354}
735 1355
1356static ssize_t show_pwm(struct device *dev,
1357 struct device_attribute *devattr, char *buf)
1358{
1359 struct f71882fg_data *data = f71882fg_update_device(dev);
1360 int val, nr = to_sensor_dev_attr_2(devattr)->index;
1361 mutex_lock(&data->update_lock);
1362 if (data->pwm_enable & (1 << (2 * nr)))
1363 /* PWM mode */
1364 val = data->pwm[nr];
1365 else {
1366 /* RPM mode */
1367 val = 255 * fan_from_reg(data->fan_target[nr])
1368 / fan_from_reg(data->fan_full_speed[nr]);
1369 }
1370 mutex_unlock(&data->update_lock);
1371 return sprintf(buf, "%d\n", val);
1372}
1373
1374static ssize_t store_pwm(struct device *dev,
1375 struct device_attribute *devattr, const char *buf,
1376 size_t count)
1377{
1378 struct f71882fg_data *data = dev_get_drvdata(dev);
1379 int nr = to_sensor_dev_attr_2(devattr)->index;
1380 long val = simple_strtol(buf, NULL, 10);
1381 val = SENSORS_LIMIT(val, 0, 255);
1382
1383 mutex_lock(&data->update_lock);
1384 data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
1385 if ((data->type == f8000 && ((data->pwm_enable >> 2 * nr) & 3) != 2) ||
1386 (data->type != f8000 && !((data->pwm_enable >> 2 * nr) & 2))) {
1387 count = -EROFS;
1388 goto leave;
1389 }
1390 if (data->pwm_enable & (1 << (2 * nr))) {
1391 /* PWM mode */
1392 f71882fg_write8(data, F71882FG_REG_PWM(nr), val);
1393 data->pwm[nr] = val;
1394 } else {
1395 /* RPM mode */
1396 int target, full_speed;
1397 full_speed = f71882fg_read16(data,
1398 F71882FG_REG_FAN_FULL_SPEED(nr));
1399 target = fan_to_reg(val * fan_from_reg(full_speed) / 255);
1400 f71882fg_write16(data, F71882FG_REG_FAN_TARGET(nr), target);
1401 data->fan_target[nr] = target;
1402 data->fan_full_speed[nr] = full_speed;
1403 }
1404leave:
1405 mutex_unlock(&data->update_lock);
1406
1407 return count;
1408}
1409
1410static ssize_t show_pwm_enable(struct device *dev,
1411 struct device_attribute *devattr, char *buf)
1412{
1413 int result = 0;
1414 struct f71882fg_data *data = f71882fg_update_device(dev);
1415 int nr = to_sensor_dev_attr_2(devattr)->index;
1416
1417 switch ((data->pwm_enable >> 2 * nr) & 3) {
1418 case 0:
1419 case 1:
1420 result = 2; /* Normal auto mode */
1421 break;
1422 case 2:
1423 result = 1; /* Manual mode */
1424 break;
1425 case 3:
1426 if (data->type == f8000)
1427 result = 3; /* Thermostat mode */
1428 else
1429 result = 1; /* Manual mode */
1430 break;
1431 }
1432
1433 return sprintf(buf, "%d\n", result);
1434}
1435
1436static ssize_t store_pwm_enable(struct device *dev, struct device_attribute
1437 *devattr, const char *buf, size_t count)
1438{
1439 struct f71882fg_data *data = dev_get_drvdata(dev);
1440 int nr = to_sensor_dev_attr_2(devattr)->index;
1441 long val = simple_strtol(buf, NULL, 10);
1442
1443 mutex_lock(&data->update_lock);
1444 data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
1445 /* Special case for F8000 auto PWM mode / Thermostat mode */
1446 if (data->type == f8000 && ((data->pwm_enable >> 2 * nr) & 1)) {
1447 switch (val) {
1448 case 2:
1449 data->pwm_enable &= ~(2 << (2 * nr));
1450 break; /* Normal auto mode */
1451 case 3:
1452 data->pwm_enable |= 2 << (2 * nr);
1453 break; /* Thermostat mode */
1454 default:
1455 count = -EINVAL;
1456 goto leave;
1457 }
1458 } else {
1459 switch (val) {
1460 case 1:
1461 data->pwm_enable |= 2 << (2 * nr);
1462 break; /* Manual */
1463 case 2:
1464 data->pwm_enable &= ~(2 << (2 * nr));
1465 break; /* Normal auto mode */
1466 default:
1467 count = -EINVAL;
1468 goto leave;
1469 }
1470 }
1471 f71882fg_write8(data, F71882FG_REG_PWM_ENABLE, data->pwm_enable);
1472leave:
1473 mutex_unlock(&data->update_lock);
1474
1475 return count;
1476}
1477
1478static ssize_t show_pwm_auto_point_pwm(struct device *dev,
1479 struct device_attribute *devattr,
1480 char *buf)
1481{
1482 int result;
1483 struct f71882fg_data *data = f71882fg_update_device(dev);
1484 int pwm = to_sensor_dev_attr_2(devattr)->index;
1485 int point = to_sensor_dev_attr_2(devattr)->nr;
1486
1487 mutex_lock(&data->update_lock);
1488 if (data->pwm_enable & (1 << (2 * pwm))) {
1489 /* PWM mode */
1490 result = data->pwm_auto_point_pwm[pwm][point];
1491 } else {
1492 /* RPM mode */
1493 result = 32 * 255 / (32 + data->pwm_auto_point_pwm[pwm][point]);
1494 }
1495 mutex_unlock(&data->update_lock);
1496
1497 return sprintf(buf, "%d\n", result);
1498}
1499
1500static ssize_t store_pwm_auto_point_pwm(struct device *dev,
1501 struct device_attribute *devattr,
1502 const char *buf, size_t count)
1503{
1504 struct f71882fg_data *data = dev_get_drvdata(dev);
1505 int pwm = to_sensor_dev_attr_2(devattr)->index;
1506 int point = to_sensor_dev_attr_2(devattr)->nr;
1507 long val = simple_strtol(buf, NULL, 10);
1508 val = SENSORS_LIMIT(val, 0, 255);
1509
1510 mutex_lock(&data->update_lock);
1511 data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
1512 if (data->pwm_enable & (1 << (2 * pwm))) {
1513 /* PWM mode */
1514 } else {
1515 /* RPM mode */
1516 if (val < 29) /* Prevent negative numbers */
1517 val = 255;
1518 else
1519 val = (255 - val) * 32 / val;
1520 }
1521 f71882fg_write8(data, F71882FG_REG_POINT_PWM(pwm, point), val);
1522 data->pwm_auto_point_pwm[pwm][point] = val;
1523 mutex_unlock(&data->update_lock);
1524
1525 return count;
1526}
1527
1528static ssize_t show_pwm_auto_point_temp_hyst(struct device *dev,
1529 struct device_attribute *devattr,
1530 char *buf)
1531{
1532 int result = 0;
1533 struct f71882fg_data *data = f71882fg_update_device(dev);
1534 int nr = to_sensor_dev_attr_2(devattr)->index;
1535 int point = to_sensor_dev_attr_2(devattr)->nr;
1536
1537 mutex_lock(&data->update_lock);
1538 if (nr & 1)
1539 result = data->pwm_auto_point_hyst[nr / 2] >> 4;
1540 else
1541 result = data->pwm_auto_point_hyst[nr / 2] & 0x0f;
1542 result = 1000 * (data->pwm_auto_point_temp[nr][point] - result);
1543 mutex_unlock(&data->update_lock);
1544
1545 return sprintf(buf, "%d\n", result);
1546}
1547
1548static ssize_t store_pwm_auto_point_temp_hyst(struct device *dev,
1549 struct device_attribute *devattr,
1550 const char *buf, size_t count)
1551{
1552 struct f71882fg_data *data = dev_get_drvdata(dev);
1553 int nr = to_sensor_dev_attr_2(devattr)->index;
1554 int point = to_sensor_dev_attr_2(devattr)->nr;
1555 long val = simple_strtol(buf, NULL, 10) / 1000;
1556 u8 reg;
1557
1558 mutex_lock(&data->update_lock);
1559 data->pwm_auto_point_temp[nr][point] =
1560 f71882fg_read8(data, F71882FG_REG_POINT_TEMP(nr, point));
1561 val = SENSORS_LIMIT(val, data->pwm_auto_point_temp[nr][point] - 15,
1562 data->pwm_auto_point_temp[nr][point]);
1563 val = data->pwm_auto_point_temp[nr][point] - val;
1564
1565 reg = f71882fg_read8(data, F71882FG_REG_FAN_HYST(nr / 2));
1566 if (nr & 1)
1567 reg = (reg & 0x0f) | (val << 4);
1568 else
1569 reg = (reg & 0xf0) | val;
1570
1571 f71882fg_write8(data, F71882FG_REG_FAN_HYST(nr / 2), reg);
1572 data->pwm_auto_point_hyst[nr / 2] = reg;
1573 mutex_unlock(&data->update_lock);
1574
1575 return count;
1576}
1577
1578static ssize_t show_pwm_interpolate(struct device *dev,
1579 struct device_attribute *devattr, char *buf)
1580{
1581 int result;
1582 struct f71882fg_data *data = f71882fg_update_device(dev);
1583 int nr = to_sensor_dev_attr_2(devattr)->index;
1584
1585 result = (data->pwm_auto_point_mapping[nr] >> 4) & 1;
1586
1587 return sprintf(buf, "%d\n", result);
1588}
1589
1590static ssize_t store_pwm_interpolate(struct device *dev,
1591 struct device_attribute *devattr,
1592 const char *buf, size_t count)
1593{
1594 struct f71882fg_data *data = dev_get_drvdata(dev);
1595 int nr = to_sensor_dev_attr_2(devattr)->index;
1596 unsigned long val = simple_strtoul(buf, NULL, 10);
1597
1598 mutex_lock(&data->update_lock);
1599 data->pwm_auto_point_mapping[nr] =
1600 f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(nr));
1601 if (val)
1602 val = data->pwm_auto_point_mapping[nr] | (1 << 4);
1603 else
1604 val = data->pwm_auto_point_mapping[nr] & (~(1 << 4));
1605 f71882fg_write8(data, F71882FG_REG_POINT_MAPPING(nr), val);
1606 data->pwm_auto_point_mapping[nr] = val;
1607 mutex_unlock(&data->update_lock);
1608
1609 return count;
1610}
1611
1612static ssize_t show_pwm_auto_point_channel(struct device *dev,
1613 struct device_attribute *devattr,
1614 char *buf)
1615{
1616 int result;
1617 struct f71882fg_data *data = f71882fg_update_device(dev);
1618 int nr = to_sensor_dev_attr_2(devattr)->index;
1619 int temp_start = (data->type == f8000) ? 0 : 1;
1620
1621 result = 1 << ((data->pwm_auto_point_mapping[nr] & 3) - temp_start);
1622
1623 return sprintf(buf, "%d\n", result);
1624}
1625
1626static ssize_t store_pwm_auto_point_channel(struct device *dev,
1627 struct device_attribute *devattr,
1628 const char *buf, size_t count)
1629{
1630 struct f71882fg_data *data = dev_get_drvdata(dev);
1631 int nr = to_sensor_dev_attr_2(devattr)->index;
1632 int temp_start = (data->type == f8000) ? 0 : 1;
1633 long val = simple_strtol(buf, NULL, 10);
1634
1635 switch (val) {
1636 case 1:
1637 val = 0;
1638 break;
1639 case 2:
1640 val = 1;
1641 break;
1642 case 4:
1643 val = 2;
1644 break;
1645 default:
1646 return -EINVAL;
1647 }
1648 val += temp_start;
1649 mutex_lock(&data->update_lock);
1650 data->pwm_auto_point_mapping[nr] =
1651 f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(nr));
1652 val = (data->pwm_auto_point_mapping[nr] & 0xfc) | val;
1653 f71882fg_write8(data, F71882FG_REG_POINT_MAPPING(nr), val);
1654 data->pwm_auto_point_mapping[nr] = val;
1655 mutex_unlock(&data->update_lock);
1656
1657 return count;
1658}
1659
1660static ssize_t show_pwm_auto_point_temp(struct device *dev,
1661 struct device_attribute *devattr,
1662 char *buf)
1663{
1664 int result;
1665 struct f71882fg_data *data = f71882fg_update_device(dev);
1666 int pwm = to_sensor_dev_attr_2(devattr)->index;
1667 int point = to_sensor_dev_attr_2(devattr)->nr;
1668
1669 result = data->pwm_auto_point_temp[pwm][point];
1670 return sprintf(buf, "%d\n", 1000 * result);
1671}
1672
1673static ssize_t store_pwm_auto_point_temp(struct device *dev,
1674 struct device_attribute *devattr,
1675 const char *buf, size_t count)
1676{
1677 struct f71882fg_data *data = dev_get_drvdata(dev);
1678 int pwm = to_sensor_dev_attr_2(devattr)->index;
1679 int point = to_sensor_dev_attr_2(devattr)->nr;
1680 long val = simple_strtol(buf, NULL, 10) / 1000;
1681 val = SENSORS_LIMIT(val, 0, 255);
1682
1683 mutex_lock(&data->update_lock);
1684 f71882fg_write8(data, F71882FG_REG_POINT_TEMP(pwm, point), val);
1685 data->pwm_auto_point_temp[pwm][point] = val;
1686 mutex_unlock(&data->update_lock);
1687
1688 return count;
1689}
1690
736static ssize_t show_name(struct device *dev, struct device_attribute *devattr, 1691static ssize_t show_name(struct device *dev, struct device_attribute *devattr,
737 char *buf) 1692 char *buf)
738{ 1693{
739 return sprintf(buf, DRVNAME "\n"); 1694 struct f71882fg_data *data = dev_get_drvdata(dev);
1695 return sprintf(buf, "%s\n", f71882fg_names[data->type]);
740} 1696}
741 1697
1698static int __devinit f71882fg_create_sysfs_files(struct platform_device *pdev,
1699 struct sensor_device_attribute_2 *attr, int count)
1700{
1701 int err, i;
1702
1703 for (i = 0; i < count; i++) {
1704 err = device_create_file(&pdev->dev, &attr[i].dev_attr);
1705 if (err)
1706 return err;
1707 }
1708 return 0;
1709}
742 1710
743static int __devinit f71882fg_probe(struct platform_device * pdev) 1711static int __devinit f71882fg_probe(struct platform_device *pdev)
744{ 1712{
745 struct f71882fg_data *data; 1713 struct f71882fg_data *data;
746 int err, i; 1714 struct f71882fg_sio_data *sio_data = pdev->dev.platform_data;
1715 int err, i, nr_fans = (sio_data->type == f71882fg) ? 4 : 3;
747 u8 start_reg; 1716 u8 start_reg;
748 1717
749 if (!(data = kzalloc(sizeof(struct f71882fg_data), GFP_KERNEL))) 1718 data = kzalloc(sizeof(struct f71882fg_data), GFP_KERNEL);
1719 if (!data)
750 return -ENOMEM; 1720 return -ENOMEM;
751 1721
752 data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start; 1722 data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start;
1723 data->type = sio_data->type;
753 mutex_init(&data->update_lock); 1724 mutex_init(&data->update_lock);
754 platform_set_drvdata(pdev, data); 1725 platform_set_drvdata(pdev, data);
755 1726
756 /* Register sysfs interface files */ 1727 start_reg = f71882fg_read8(data, F71882FG_REG_START);
757 for (i = 0; i < ARRAY_SIZE(f71882fg_dev_attr); i++) { 1728 if (start_reg & 0x04) {
758 err = device_create_file(&pdev->dev, &f71882fg_dev_attr[i]); 1729 dev_warn(&pdev->dev, "Hardware monitor is powered down\n");
759 if (err) 1730 err = -ENODEV;
760 goto exit_unregister_sysfs; 1731 goto exit_free;
1732 }
1733 if (!(start_reg & 0x03)) {
1734 dev_warn(&pdev->dev, "Hardware monitoring not activated\n");
1735 err = -ENODEV;
1736 goto exit_free;
761 } 1737 }
762 1738
763 start_reg = f71882fg_read8(data, F71882FG_REG_START); 1739 data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
1740 /* If it is a 71862 and the fan / pwm part is enabled sanity check
1741 the pwm settings */
1742 if (data->type == f71862fg && (start_reg & 0x02)) {
1743 if ((data->pwm_enable & 0x15) != 0x15) {
1744 dev_err(&pdev->dev,
1745 "Invalid (reserved) pwm settings: 0x%02x\n",
1746 (unsigned int)data->pwm_enable);
1747 err = -ENODEV;
1748 goto exit_free;
1749 }
1750 }
1751
1752 /* Register sysfs interface files */
1753 err = device_create_file(&pdev->dev, &dev_attr_name);
1754 if (err)
1755 goto exit_unregister_sysfs;
1756
764 if (start_reg & 0x01) { 1757 if (start_reg & 0x01) {
765 for (i = 0; i < ARRAY_SIZE(f71882fg_in_temp_attr); i++) { 1758 switch (data->type) {
766 err = device_create_file(&pdev->dev, 1759 case f71882fg:
767 &f71882fg_in_temp_attr[i].dev_attr); 1760 err = f71882fg_create_sysfs_files(pdev,
1761 f71882fg_in_temp_attr,
1762 ARRAY_SIZE(f71882fg_in_temp_attr));
768 if (err) 1763 if (err)
769 goto exit_unregister_sysfs; 1764 goto exit_unregister_sysfs;
1765 /* fall through! */
1766 case f71862fg:
1767 err = f71882fg_create_sysfs_files(pdev,
1768 f718x2fg_in_temp_attr,
1769 ARRAY_SIZE(f718x2fg_in_temp_attr));
1770 break;
1771 case f8000:
1772 err = f71882fg_create_sysfs_files(pdev,
1773 f8000_in_temp_attr,
1774 ARRAY_SIZE(f8000_in_temp_attr));
1775 break;
770 } 1776 }
1777 if (err)
1778 goto exit_unregister_sysfs;
771 } 1779 }
772 1780
773 if (start_reg & 0x02) { 1781 if (start_reg & 0x02) {
774 for (i = 0; i < ARRAY_SIZE(f71882fg_fan_attr); i++) { 1782 err = f71882fg_create_sysfs_files(pdev, fxxxx_fan_attr,
775 err = device_create_file(&pdev->dev, 1783 ARRAY_SIZE(fxxxx_fan_attr));
776 &f71882fg_fan_attr[i].dev_attr); 1784 if (err)
777 if (err) 1785 goto exit_unregister_sysfs;
778 goto exit_unregister_sysfs; 1786
1787 switch (data->type) {
1788 case f71862fg:
1789 err = f71882fg_create_sysfs_files(pdev,
1790 f71862fg_fan_attr,
1791 ARRAY_SIZE(f71862fg_fan_attr));
1792 break;
1793 case f71882fg:
1794 err = f71882fg_create_sysfs_files(pdev,
1795 f71882fg_fan_attr,
1796 ARRAY_SIZE(f71882fg_fan_attr));
1797 break;
1798 case f8000:
1799 err = f71882fg_create_sysfs_files(pdev,
1800 f8000_fan_attr,
1801 ARRAY_SIZE(f8000_fan_attr));
1802 break;
779 } 1803 }
1804 if (err)
1805 goto exit_unregister_sysfs;
1806
1807 for (i = 0; i < nr_fans; i++)
1808 dev_info(&pdev->dev, "Fan: %d is in %s mode\n", i + 1,
1809 (data->pwm_enable & (1 << 2 * i)) ?
1810 "duty-cycle" : "RPM");
780 } 1811 }
781 1812
782 data->hwmon_dev = hwmon_device_register(&pdev->dev); 1813 data->hwmon_dev = hwmon_device_register(&pdev->dev);
783 if (IS_ERR(data->hwmon_dev)) { 1814 if (IS_ERR(data->hwmon_dev)) {
784 err = PTR_ERR(data->hwmon_dev); 1815 err = PTR_ERR(data->hwmon_dev);
1816 data->hwmon_dev = NULL;
785 goto exit_unregister_sysfs; 1817 goto exit_unregister_sysfs;
786 } 1818 }
787 1819
788 return 0; 1820 return 0;
789 1821
790exit_unregister_sysfs: 1822exit_unregister_sysfs:
791 for (i = 0; i < ARRAY_SIZE(f71882fg_dev_attr); i++) 1823 f71882fg_remove(pdev); /* Will unregister the sysfs files for us */
792 device_remove_file(&pdev->dev, &f71882fg_dev_attr[i]); 1824 return err; /* f71882fg_remove() also frees our data */
793 1825exit_free:
794 for (i = 0; i < ARRAY_SIZE(f71882fg_in_temp_attr); i++)
795 device_remove_file(&pdev->dev,
796 &f71882fg_in_temp_attr[i].dev_attr);
797
798 for (i = 0; i < ARRAY_SIZE(f71882fg_fan_attr); i++)
799 device_remove_file(&pdev->dev, &f71882fg_fan_attr[i].dev_attr);
800
801 kfree(data); 1826 kfree(data);
802
803 return err; 1827 return err;
804} 1828}
805 1829
806static int __devexit f71882fg_remove(struct platform_device *pdev) 1830static int f71882fg_remove(struct platform_device *pdev)
807{ 1831{
808 int i; 1832 int i;
809 struct f71882fg_data *data = platform_get_drvdata(pdev); 1833 struct f71882fg_data *data = platform_get_drvdata(pdev);
810 1834
811 platform_set_drvdata(pdev, NULL); 1835 platform_set_drvdata(pdev, NULL);
812 hwmon_device_unregister(data->hwmon_dev); 1836 if (data->hwmon_dev)
1837 hwmon_device_unregister(data->hwmon_dev);
1838
1839 /* Note we are not looping over all attr arrays we have as the ones
1840 below are supersets of the ones skipped. */
1841 device_remove_file(&pdev->dev, &dev_attr_name);
813 1842
814 for (i = 0; i < ARRAY_SIZE(f71882fg_dev_attr); i++) 1843 for (i = 0; i < ARRAY_SIZE(f718x2fg_in_temp_attr); i++)
815 device_remove_file(&pdev->dev, &f71882fg_dev_attr[i]); 1844 device_remove_file(&pdev->dev,
1845 &f718x2fg_in_temp_attr[i].dev_attr);
816 1846
817 for (i = 0; i < ARRAY_SIZE(f71882fg_in_temp_attr); i++) 1847 for (i = 0; i < ARRAY_SIZE(f71882fg_in_temp_attr); i++)
818 device_remove_file(&pdev->dev, 1848 device_remove_file(&pdev->dev,
819 &f71882fg_in_temp_attr[i].dev_attr); 1849 &f71882fg_in_temp_attr[i].dev_attr);
820 1850
1851 for (i = 0; i < ARRAY_SIZE(fxxxx_fan_attr); i++)
1852 device_remove_file(&pdev->dev, &fxxxx_fan_attr[i].dev_attr);
1853
821 for (i = 0; i < ARRAY_SIZE(f71882fg_fan_attr); i++) 1854 for (i = 0; i < ARRAY_SIZE(f71882fg_fan_attr); i++)
822 device_remove_file(&pdev->dev, &f71882fg_fan_attr[i].dev_attr); 1855 device_remove_file(&pdev->dev, &f71882fg_fan_attr[i].dev_attr);
823 1856
1857 for (i = 0; i < ARRAY_SIZE(f8000_fan_attr); i++)
1858 device_remove_file(&pdev->dev, &f8000_fan_attr[i].dev_attr);
1859
824 kfree(data); 1860 kfree(data);
825 1861
826 return 0; 1862 return 0;
827} 1863}
828 1864
829static int __init f71882fg_find(int sioaddr, unsigned short *address) 1865static int __init f71882fg_find(int sioaddr, unsigned short *address,
1866 struct f71882fg_sio_data *sio_data)
830{ 1867{
831 int err = -ENODEV; 1868 int err = -ENODEV;
832 u16 devid; 1869 u16 devid;
833 u8 start_reg;
834 struct f71882fg_data data;
835 1870
836 superio_enter(sioaddr); 1871 superio_enter(sioaddr);
837 1872
@@ -842,7 +1877,17 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address)
842 } 1877 }
843 1878
844 devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID); 1879 devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID);
845 if (devid != SIO_F71882_ID) { 1880 switch (devid) {
1881 case SIO_F71862_ID:
1882 sio_data->type = f71862fg;
1883 break;
1884 case SIO_F71882_ID:
1885 sio_data->type = f71882fg;
1886 break;
1887 case SIO_F8000_ID:
1888 sio_data->type = f8000;
1889 break;
1890 default:
846 printk(KERN_INFO DRVNAME ": Unsupported Fintek device\n"); 1891 printk(KERN_INFO DRVNAME ": Unsupported Fintek device\n");
847 goto exit; 1892 goto exit;
848 } 1893 }
@@ -861,24 +1906,17 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address)
861 } 1906 }
862 *address &= ~(REGION_LENGTH - 1); /* Ignore 3 LSB */ 1907 *address &= ~(REGION_LENGTH - 1); /* Ignore 3 LSB */
863 1908
864 data.addr = *address;
865 start_reg = f71882fg_read8(&data, F71882FG_REG_START);
866 if (!(start_reg & 0x03)) {
867 printk(KERN_WARNING DRVNAME
868 ": Hardware monitoring not activated\n");
869 goto exit;
870 }
871
872 err = 0; 1909 err = 0;
873 printk(KERN_INFO DRVNAME ": Found F71882FG chip at %#x, revision %d\n", 1910 printk(KERN_INFO DRVNAME ": Found %s chip at %#x, revision %d\n",
874 (unsigned int)*address, 1911 f71882fg_names[sio_data->type], (unsigned int)*address,
875 (int)superio_inb(sioaddr, SIO_REG_DEVREV)); 1912 (int)superio_inb(sioaddr, SIO_REG_DEVREV));
876exit: 1913exit:
877 superio_exit(sioaddr); 1914 superio_exit(sioaddr);
878 return err; 1915 return err;
879} 1916}
880 1917
881static int __init f71882fg_device_add(unsigned short address) 1918static int __init f71882fg_device_add(unsigned short address,
1919 const struct f71882fg_sio_data *sio_data)
882{ 1920{
883 struct resource res = { 1921 struct resource res = {
884 .start = address, 1922 .start = address,
@@ -892,12 +1930,23 @@ static int __init f71882fg_device_add(unsigned short address)
892 return -ENOMEM; 1930 return -ENOMEM;
893 1931
894 res.name = f71882fg_pdev->name; 1932 res.name = f71882fg_pdev->name;
1933 err = acpi_check_resource_conflict(&res);
1934 if (err)
1935 return err;
1936
895 err = platform_device_add_resources(f71882fg_pdev, &res, 1); 1937 err = platform_device_add_resources(f71882fg_pdev, &res, 1);
896 if (err) { 1938 if (err) {
897 printk(KERN_ERR DRVNAME ": Device resource addition failed\n"); 1939 printk(KERN_ERR DRVNAME ": Device resource addition failed\n");
898 goto exit_device_put; 1940 goto exit_device_put;
899 } 1941 }
900 1942
1943 err = platform_device_add_data(f71882fg_pdev, sio_data,
1944 sizeof(struct f71882fg_sio_data));
1945 if (err) {
1946 printk(KERN_ERR DRVNAME ": Platform data allocation failed\n");
1947 goto exit_device_put;
1948 }
1949
901 err = platform_device_add(f71882fg_pdev); 1950 err = platform_device_add(f71882fg_pdev);
902 if (err) { 1951 if (err) {
903 printk(KERN_ERR DRVNAME ": Device addition failed\n"); 1952 printk(KERN_ERR DRVNAME ": Device addition failed\n");
@@ -916,14 +1965,20 @@ static int __init f71882fg_init(void)
916{ 1965{
917 int err = -ENODEV; 1966 int err = -ENODEV;
918 unsigned short address; 1967 unsigned short address;
1968 struct f71882fg_sio_data sio_data;
1969
1970 memset(&sio_data, 0, sizeof(sio_data));
919 1971
920 if (f71882fg_find(0x2e, &address) && f71882fg_find(0x4e, &address)) 1972 if (f71882fg_find(0x2e, &address, &sio_data) &&
1973 f71882fg_find(0x4e, &address, &sio_data))
921 goto exit; 1974 goto exit;
922 1975
923 if ((err = platform_driver_register(&f71882fg_driver))) 1976 err = platform_driver_register(&f71882fg_driver);
1977 if (err)
924 goto exit; 1978 goto exit;
925 1979
926 if ((err = f71882fg_device_add(address))) 1980 err = f71882fg_device_add(address, &sio_data);
1981 if (err)
927 goto exit_driver; 1982 goto exit_driver;
928 1983
929 return 0; 1984 return 0;
@@ -941,7 +1996,7 @@ static void __exit f71882fg_exit(void)
941} 1996}
942 1997
943MODULE_DESCRIPTION("F71882FG Hardware Monitoring Driver"); 1998MODULE_DESCRIPTION("F71882FG Hardware Monitoring Driver");
944MODULE_AUTHOR("Hans Edgington (hans@edgington.nl)"); 1999MODULE_AUTHOR("Hans Edgington, Hans de Goede (hdegoede@redhat.com)");
945MODULE_LICENSE("GPL"); 2000MODULE_LICENSE("GPL");
946 2001
947module_init(f71882fg_init); 2002module_init(f71882fg_init);