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