Merge branch 'hpet' into release
[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 #include <linux/acpi.h>
32
33 #define DRVNAME "f71882fg"
34
35 #define SIO_F71882FG_LD_HWM     0x04    /* Hardware monitor logical device */
36 #define SIO_UNLOCK_KEY          0x87    /* Key to enable Super-I/O */
37 #define SIO_LOCK_KEY            0xAA    /* Key to diasble Super-I/O */
38
39 #define SIO_REG_LDSEL           0x07    /* Logical device select */
40 #define SIO_REG_DEVID           0x20    /* Device ID (2 bytes) */
41 #define SIO_REG_DEVREV          0x22    /* Device revision */
42 #define SIO_REG_MANID           0x23    /* Fintek ID (2 bytes) */
43 #define SIO_REG_ENABLE          0x30    /* Logical device enable */
44 #define SIO_REG_ADDR            0x60    /* Logical device address (2 bytes) */
45
46 #define SIO_FINTEK_ID           0x1934  /* Manufacturers ID */
47 #define SIO_F71862_ID           0x0601  /* Chipset ID */
48 #define SIO_F71882_ID           0x0541  /* Chipset ID */
49 #define SIO_F8000_ID            0x0581  /* Chipset ID */
50
51 #define REGION_LENGTH           8
52 #define ADDR_REG_OFFSET         5
53 #define DATA_REG_OFFSET         6
54
55 #define F71882FG_REG_PECI               0x0A
56
57 #define F71882FG_REG_IN_STATUS          0x12 /* f71882fg only */
58 #define F71882FG_REG_IN_BEEP            0x13 /* f71882fg only */
59 #define F71882FG_REG_IN(nr)             (0x20  + (nr))
60 #define F71882FG_REG_IN1_HIGH           0x32 /* f71882fg only */
61
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)))
65 #define F71882FG_REG_FAN_STATUS         0x92
66 #define F71882FG_REG_FAN_BEEP           0x93
67
68 #define F71882FG_REG_TEMP(nr)           (0x70 + 2 * (nr))
69 #define F71882FG_REG_TEMP_OVT(nr)       (0x80 + 2 * (nr))
70 #define F71882FG_REG_TEMP_HIGH(nr)      (0x81 + 2 * (nr))
71 #define F71882FG_REG_TEMP_STATUS        0x62
72 #define F71882FG_REG_TEMP_BEEP          0x63
73 #define F71882FG_REG_TEMP_HYST(nr)      (0x6C + (nr))
74 #define F71882FG_REG_TEMP_TYPE          0x6B
75 #define F71882FG_REG_TEMP_DIODE_OPEN    0x6F
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
87 #define F71882FG_REG_START              0x01
88
89 #define FAN_MIN_DETECT                  366 /* Lowest detectable fanspeed */
90
91 static unsigned short force_id;
92 module_param(force_id, ushort, 0);
93 MODULE_PARM_DESC(force_id, "Override the detected device ID");
94
95 enum chips { f71862fg, f71882fg, f8000 };
96
97 static const char *f71882fg_names[] = {
98         "f71862fg",
99         "f71882fg",
100         "f8000",
101 };
102
103 static struct platform_device *f71882fg_pdev;
104
105 /* Super-I/O Function prototypes */
106 static inline int superio_inb(int base, int reg);
107 static inline int superio_inw(int base, int reg);
108 static inline void superio_enter(int base);
109 static inline void superio_select(int base, int ld);
110 static inline void superio_exit(int base);
111
112 struct f71882fg_sio_data {
113         enum chips type;
114 };
115
116 struct f71882fg_data {
117         unsigned short addr;
118         enum chips type;
119         struct device *hwmon_dev;
120
121         struct mutex update_lock;
122         char valid;                     /* !=0 if following fields are valid */
123         unsigned long last_updated;     /* In jiffies */
124         unsigned long last_limits;      /* In jiffies */
125
126         /* Register Values */
127         u8      in[9];
128         u8      in1_max;
129         u8      in_status;
130         u8      in_beep;
131         u16     fan[4];
132         u16     fan_target[4];
133         u16     fan_full_speed[4];
134         u8      fan_status;
135         u8      fan_beep;
136         /* Note: all models have only 3 temperature channels, but on some
137            they are addressed as 0-2 and on others as 1-3, so for coding
138            convenience we reserve space for 4 channels */
139         u8      temp[4];
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];
144         u8      temp_status;
145         u8      temp_beep;
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];
153 };
154
155 /* Sysfs in */
156 static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
157         char *buf);
158 static ssize_t show_in_max(struct device *dev, struct device_attribute
159         *devattr, char *buf);
160 static ssize_t store_in_max(struct device *dev, struct device_attribute
161         *devattr, const char *buf, size_t count);
162 static ssize_t show_in_beep(struct device *dev, struct device_attribute
163         *devattr, char *buf);
164 static ssize_t store_in_beep(struct device *dev, struct device_attribute
165         *devattr, const char *buf, size_t count);
166 static ssize_t show_in_alarm(struct device *dev, struct device_attribute
167         *devattr, char *buf);
168 /* Sysfs Fan */
169 static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
170         char *buf);
171 static ssize_t show_fan_full_speed(struct device *dev,
172         struct device_attribute *devattr, char *buf);
173 static ssize_t store_fan_full_speed(struct device *dev,
174         struct device_attribute *devattr, const char *buf, size_t count);
175 static ssize_t show_fan_beep(struct device *dev, struct device_attribute
176         *devattr, char *buf);
177 static ssize_t store_fan_beep(struct device *dev, struct device_attribute
178         *devattr, const char *buf, size_t count);
179 static ssize_t show_fan_alarm(struct device *dev, struct device_attribute
180         *devattr, char *buf);
181 /* Sysfs Temp */
182 static ssize_t show_temp(struct device *dev, struct device_attribute
183         *devattr, char *buf);
184 static ssize_t show_temp_max(struct device *dev, struct device_attribute
185         *devattr, char *buf);
186 static ssize_t store_temp_max(struct device *dev, struct device_attribute
187         *devattr, const char *buf, size_t count);
188 static ssize_t show_temp_max_hyst(struct device *dev, struct device_attribute
189         *devattr, char *buf);
190 static ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute
191         *devattr, const char *buf, size_t count);
192 static ssize_t show_temp_crit(struct device *dev, struct device_attribute
193         *devattr, char *buf);
194 static ssize_t store_temp_crit(struct device *dev, struct device_attribute
195         *devattr, const char *buf, size_t count);
196 static ssize_t show_temp_crit_hyst(struct device *dev, struct device_attribute
197         *devattr, char *buf);
198 static ssize_t show_temp_type(struct device *dev, struct device_attribute
199         *devattr, char *buf);
200 static ssize_t show_temp_beep(struct device *dev, struct device_attribute
201         *devattr, char *buf);
202 static ssize_t store_temp_beep(struct device *dev, struct device_attribute
203         *devattr, const char *buf, size_t count);
204 static ssize_t show_temp_alarm(struct device *dev, struct device_attribute
205         *devattr, char *buf);
206 static ssize_t show_temp_fault(struct device *dev, struct device_attribute
207         *devattr, char *buf);
208 /* PWM and Auto point control */
209 static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr,
210         char *buf);
211 static ssize_t store_pwm(struct device *dev, struct device_attribute *devattr,
212         const char *buf, size_t count);
213 static ssize_t show_pwm_enable(struct device *dev,
214         struct device_attribute *devattr, char *buf);
215 static ssize_t store_pwm_enable(struct device *dev,
216         struct device_attribute *devattr, const char *buf, size_t count);
217 static ssize_t show_pwm_interpolate(struct device *dev,
218         struct device_attribute *devattr, char *buf);
219 static ssize_t store_pwm_interpolate(struct device *dev,
220         struct device_attribute *devattr, const char *buf, size_t count);
221 static ssize_t show_pwm_auto_point_channel(struct device *dev,
222         struct device_attribute *devattr, char *buf);
223 static ssize_t store_pwm_auto_point_channel(struct device *dev,
224         struct device_attribute *devattr, const char *buf, size_t count);
225 static ssize_t show_pwm_auto_point_temp_hyst(struct device *dev,
226         struct device_attribute *devattr, char *buf);
227 static ssize_t store_pwm_auto_point_temp_hyst(struct device *dev,
228         struct device_attribute *devattr, const char *buf, size_t count);
229 static ssize_t show_pwm_auto_point_pwm(struct device *dev,
230         struct device_attribute *devattr, char *buf);
231 static ssize_t store_pwm_auto_point_pwm(struct device *dev,
232         struct device_attribute *devattr, const char *buf, size_t count);
233 static ssize_t show_pwm_auto_point_temp(struct device *dev,
234         struct device_attribute *devattr, char *buf);
235 static ssize_t store_pwm_auto_point_temp(struct device *dev,
236         struct device_attribute *devattr, const char *buf, size_t count);
237 /* Sysfs misc */
238 static ssize_t show_name(struct device *dev, struct device_attribute *devattr,
239         char *buf);
240
241 static int __devinit f71882fg_probe(struct platform_device * pdev);
242 static int f71882fg_remove(struct platform_device *pdev);
243
244 static struct platform_driver f71882fg_driver = {
245         .driver = {
246                 .owner  = THIS_MODULE,
247                 .name   = DRVNAME,
248         },
249         .probe          = f71882fg_probe,
250         .remove         = __devexit_p(f71882fg_remove),
251 };
252
253 static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
254
255 /* Temp and in attr common to both the f71862fg and f71882fg */
256 static 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 */
325 static 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  */
337 static 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 */
363 static 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),
403 };
404
405 /* Fan / PWM attr for the f71862fg, less pwms and less zones per pwm than the
406    f71882fg */
407 static struct sensor_device_attribute_2 f71862fg_fan_attr[] = {
408         SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep,
409                 store_fan_beep, 0, 0),
410         SENSOR_ATTR_2(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep,
411                 store_fan_beep, 0, 1),
412         SENSOR_ATTR_2(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep,
413                 store_fan_beep, 0, 2),
414
415         SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,
416                       show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
417                       1, 0),
418         SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO|S_IWUSR,
419                       show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
420                       4, 0),
421         SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IRUGO|S_IWUSR,
422                       show_pwm_auto_point_temp, store_pwm_auto_point_temp,
423                       0, 0),
424         SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IRUGO|S_IWUSR,
425                       show_pwm_auto_point_temp, store_pwm_auto_point_temp,
426                       3, 0),
427         SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
428                       show_pwm_auto_point_temp_hyst,
429                       store_pwm_auto_point_temp_hyst,
430                       0, 0),
431         SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO,
432                       show_pwm_auto_point_temp_hyst, NULL, 3, 0),
433
434         SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR,
435                       show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
436                       1, 1),
437         SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO|S_IWUSR,
438                       show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
439                       4, 1),
440         SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IRUGO|S_IWUSR,
441                       show_pwm_auto_point_temp, store_pwm_auto_point_temp,
442                       0, 1),
443         SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IRUGO|S_IWUSR,
444                       show_pwm_auto_point_temp, store_pwm_auto_point_temp,
445                       3, 1),
446         SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
447                       show_pwm_auto_point_temp_hyst,
448                       store_pwm_auto_point_temp_hyst,
449                       0, 1),
450         SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO,
451                       show_pwm_auto_point_temp_hyst, NULL, 3, 1),
452
453         SENSOR_ATTR_2(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 2),
454         SENSOR_ATTR_2(pwm3_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
455                       store_pwm_enable, 0, 2),
456         SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR,
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),
474 };
475
476 /* Fan / PWM attr for the f71882fg */
477 static struct sensor_device_attribute_2 f71882fg_fan_attr[] = {
478         SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep,
479                 store_fan_beep, 0, 0),
480         SENSOR_ATTR_2(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep,
481                 store_fan_beep, 0, 1),
482         SENSOR_ATTR_2(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep,
483                 store_fan_beep, 0, 2),
484         SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
485         SENSOR_ATTR_2(fan4_full_speed, S_IRUGO|S_IWUSR,
486                       show_fan_full_speed,
487                       store_fan_full_speed, 0, 3),
488         SENSOR_ATTR_2(fan4_beep, S_IRUGO|S_IWUSR, show_fan_beep,
489                 store_fan_beep, 0, 3),
490         SENSOR_ATTR_2(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 3),
491
492         SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,
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),
654 };
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 */
659 static 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 };
778
779 /* Super I/O functions */
780 static inline int superio_inb(int base, int reg)
781 {
782         outb(reg, base);
783         return inb(base + 1);
784 }
785
786 static int superio_inw(int base, int reg)
787 {
788         int val;
789         outb(reg++, base);
790         val = inb(base + 1) << 8;
791         outb(reg, base);
792         val |= inb(base + 1);
793         return val;
794 }
795
796 static inline void superio_enter(int base)
797 {
798         /* according to the datasheet the key must be send twice! */
799         outb( SIO_UNLOCK_KEY, base);
800         outb( SIO_UNLOCK_KEY, base);
801 }
802
803 static inline void superio_select( int base, int ld)
804 {
805         outb(SIO_REG_LDSEL, base);
806         outb(ld, base + 1);
807 }
808
809 static inline void superio_exit(int base)
810 {
811         outb(SIO_LOCK_KEY, base);
812 }
813
814 static inline int fan_from_reg(u16 reg)
815 {
816         return reg ? (1500000 / reg) : 0;
817 }
818
819 static inline u16 fan_to_reg(int fan)
820 {
821         return fan ? (1500000 / fan) : 0;
822 }
823
824 static u8 f71882fg_read8(struct f71882fg_data *data, u8 reg)
825 {
826         u8 val;
827
828         outb(reg, data->addr + ADDR_REG_OFFSET);
829         val = inb(data->addr + DATA_REG_OFFSET);
830
831         return val;
832 }
833
834 static u16 f71882fg_read16(struct f71882fg_data *data, u8 reg)
835 {
836         u16 val;
837
838         outb(reg++, data->addr + ADDR_REG_OFFSET);
839         val = inb(data->addr + DATA_REG_OFFSET) << 8;
840         outb(reg, data->addr + ADDR_REG_OFFSET);
841         val |= inb(data->addr + DATA_REG_OFFSET);
842
843         return val;
844 }
845
846 static void f71882fg_write8(struct f71882fg_data *data, u8 reg, u8 val)
847 {
848         outb(reg, data->addr + ADDR_REG_OFFSET);
849         outb(val, data->addr + DATA_REG_OFFSET);
850 }
851
852 static 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
860 static struct f71882fg_data *f71882fg_update_device(struct device *dev)
861 {
862         struct f71882fg_data *data = dev_get_drvdata(dev);
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;
867
868         mutex_lock(&data->update_lock);
869
870         /* Update once every 60 seconds */
871         if ( time_after(jiffies, data->last_limits + 60 * HZ ) ||
872                         !data->valid) {
873                 if (data->type == f71882fg) {
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                 }
879
880                 /* Get High & boundary temps*/
881                 for (nr = temp_start; nr < 3 + temp_start; nr++) {
882                         data->temp_ovt[nr] = f71882fg_read8(data,
883                                                 F71882FG_REG_TEMP_OVT(nr));
884                         data->temp_high[nr] = f71882fg_read8(data,
885                                                 F71882FG_REG_TEMP_HIGH(nr));
886                 }
887
888                 if (data->type != f8000) {
889                         data->fan_beep = f71882fg_read8(data,
890                                                 F71882FG_REG_FAN_BEEP);
891                         data->temp_beep = f71882fg_read8(data,
892                                                 F71882FG_REG_TEMP_BEEP);
893                         data->temp_hyst[0] = f71882fg_read8(data,
894                                                 F71882FG_REG_TEMP_HYST(0));
895                         data->temp_hyst[1] = f71882fg_read8(data,
896                                                 F71882FG_REG_TEMP_HYST(1));
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                 }
902                 reg2 = f71882fg_read8(data, F71882FG_REG_PECI);
903                 if ((reg2 & 0x03) == 0x01)
904                         data->temp_type[1] = 6 /* PECI */;
905                 else if ((reg2 & 0x03) == 0x02)
906                         data->temp_type[1] = 5 /* AMDSI */;
907                 else if (data->type != f8000)
908                         data->temp_type[1] = (reg & 0x02) ? 2 : 4;
909                 else
910                         data->temp_type[1] = 2; /* F8000 only supports BJT */
911
912                 data->pwm_enable = f71882fg_read8(data,
913                                                   F71882FG_REG_PWM_ENABLE);
914                 data->pwm_auto_point_hyst[0] =
915                         f71882fg_read8(data, F71882FG_REG_FAN_HYST(0));
916                 data->pwm_auto_point_hyst[1] =
917                         f71882fg_read8(data, F71882FG_REG_FAN_HYST(1));
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                 }
957                 data->last_limits = jiffies;
958         }
959
960         /* Update every second */
961         if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
962                 data->temp_status = f71882fg_read8(data,
963                                                 F71882FG_REG_TEMP_STATUS);
964                 data->temp_diode_open = f71882fg_read8(data,
965                                                 F71882FG_REG_TEMP_DIODE_OPEN);
966                 for (nr = temp_start; nr < 3 + temp_start; nr++)
967                         data->temp[nr] = f71882fg_read8(data,
968                                                 F71882FG_REG_TEMP(nr));
969
970                 data->fan_status = f71882fg_read8(data,
971                                                 F71882FG_REG_FAN_STATUS);
972                 for (nr = 0; nr < nr_fans; nr++) {
973                         data->fan[nr] = f71882fg_read16(data,
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                 }
983
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,
990                                                 F71882FG_REG_IN_STATUS);
991                 for (nr = 0; nr < nr_ins; nr++)
992                         data->in[nr] = f71882fg_read8(data,
993                                                 F71882FG_REG_IN(nr));
994
995                 data->last_updated = jiffies;
996                 data->valid = 1;
997         }
998
999         mutex_unlock(&data->update_lock);
1000
1001         return data;
1002 }
1003
1004 /* Sysfs Interface */
1005 static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
1006         char *buf)
1007 {
1008         struct f71882fg_data *data = f71882fg_update_device(dev);
1009         int nr = to_sensor_dev_attr_2(devattr)->index;
1010         int speed = fan_from_reg(data->fan[nr]);
1011
1012         if (speed == FAN_MIN_DETECT)
1013                 speed = 0;
1014
1015         return sprintf(buf, "%d\n", speed);
1016 }
1017
1018 static 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
1027 static 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
1046 static ssize_t show_fan_beep(struct device *dev, struct device_attribute
1047         *devattr, char *buf)
1048 {
1049         struct f71882fg_data *data = f71882fg_update_device(dev);
1050         int nr = to_sensor_dev_attr_2(devattr)->index;
1051
1052         if (data->fan_beep & (1 << nr))
1053                 return sprintf(buf, "1\n");
1054         else
1055                 return sprintf(buf, "0\n");
1056 }
1057
1058 static ssize_t store_fan_beep(struct device *dev, struct device_attribute
1059         *devattr, const char *buf, size_t count)
1060 {
1061         struct f71882fg_data *data = dev_get_drvdata(dev);
1062         int nr = to_sensor_dev_attr_2(devattr)->index;
1063         unsigned long val = simple_strtoul(buf, NULL, 10);
1064
1065         mutex_lock(&data->update_lock);
1066         data->fan_beep = f71882fg_read8(data, F71882FG_REG_FAN_BEEP);
1067         if (val)
1068                 data->fan_beep |= 1 << nr;
1069         else
1070                 data->fan_beep &= ~(1 << nr);
1071
1072         f71882fg_write8(data, F71882FG_REG_FAN_BEEP, data->fan_beep);
1073         mutex_unlock(&data->update_lock);
1074
1075         return count;
1076 }
1077
1078 static ssize_t show_fan_alarm(struct device *dev, struct device_attribute
1079         *devattr, char *buf)
1080 {
1081         struct f71882fg_data *data = f71882fg_update_device(dev);
1082         int nr = to_sensor_dev_attr_2(devattr)->index;
1083
1084         if (data->fan_status & (1 << nr))
1085                 return sprintf(buf, "1\n");
1086         else
1087                 return sprintf(buf, "0\n");
1088 }
1089
1090 static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
1091         char *buf)
1092 {
1093         struct f71882fg_data *data = f71882fg_update_device(dev);
1094         int nr = to_sensor_dev_attr_2(devattr)->index;
1095
1096         return sprintf(buf, "%d\n", data->in[nr] * 8);
1097 }
1098
1099 static ssize_t show_in_max(struct device *dev, struct device_attribute
1100         *devattr, char *buf)
1101 {
1102         struct f71882fg_data *data = f71882fg_update_device(dev);
1103
1104         return sprintf(buf, "%d\n", data->in1_max * 8);
1105 }
1106
1107 static ssize_t store_in_max(struct device *dev, struct device_attribute
1108         *devattr, const char *buf, size_t count)
1109 {
1110         struct f71882fg_data *data = dev_get_drvdata(dev);
1111         long val = simple_strtol(buf, NULL, 10) / 8;
1112         val = SENSORS_LIMIT(val, 0, 255);
1113
1114         mutex_lock(&data->update_lock);
1115         f71882fg_write8(data, F71882FG_REG_IN1_HIGH, val);
1116         data->in1_max = val;
1117         mutex_unlock(&data->update_lock);
1118
1119         return count;
1120 }
1121
1122 static ssize_t show_in_beep(struct device *dev, struct device_attribute
1123         *devattr, char *buf)
1124 {
1125         struct f71882fg_data *data = f71882fg_update_device(dev);
1126         int nr = to_sensor_dev_attr_2(devattr)->index;
1127
1128         if (data->in_beep & (1 << nr))
1129                 return sprintf(buf, "1\n");
1130         else
1131                 return sprintf(buf, "0\n");
1132 }
1133
1134 static ssize_t store_in_beep(struct device *dev, struct device_attribute
1135         *devattr, const char *buf, size_t count)
1136 {
1137         struct f71882fg_data *data = dev_get_drvdata(dev);
1138         int nr = to_sensor_dev_attr_2(devattr)->index;
1139         unsigned long val = simple_strtoul(buf, NULL, 10);
1140
1141         mutex_lock(&data->update_lock);
1142         data->in_beep = f71882fg_read8(data, F71882FG_REG_IN_BEEP);
1143         if (val)
1144                 data->in_beep |= 1 << nr;
1145         else
1146                 data->in_beep &= ~(1 << nr);
1147
1148         f71882fg_write8(data, F71882FG_REG_IN_BEEP, data->in_beep);
1149         mutex_unlock(&data->update_lock);
1150
1151         return count;
1152 }
1153
1154 static ssize_t show_in_alarm(struct device *dev, struct device_attribute
1155         *devattr, char *buf)
1156 {
1157         struct f71882fg_data *data = f71882fg_update_device(dev);
1158         int nr = to_sensor_dev_attr_2(devattr)->index;
1159
1160         if (data->in_status & (1 << nr))
1161                 return sprintf(buf, "1\n");
1162         else
1163                 return sprintf(buf, "0\n");
1164 }
1165
1166 static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
1167         char *buf)
1168 {
1169         struct f71882fg_data *data = f71882fg_update_device(dev);
1170         int nr = to_sensor_dev_attr_2(devattr)->index;
1171
1172         return sprintf(buf, "%d\n", data->temp[nr] * 1000);
1173 }
1174
1175 static ssize_t show_temp_max(struct device *dev, struct device_attribute
1176         *devattr, char *buf)
1177 {
1178         struct f71882fg_data *data = f71882fg_update_device(dev);
1179         int nr = to_sensor_dev_attr_2(devattr)->index;
1180
1181         return sprintf(buf, "%d\n", data->temp_high[nr] * 1000);
1182 }
1183
1184 static ssize_t store_temp_max(struct device *dev, struct device_attribute
1185         *devattr, const char *buf, size_t count)
1186 {
1187         struct f71882fg_data *data = dev_get_drvdata(dev);
1188         int nr = to_sensor_dev_attr_2(devattr)->index;
1189         long val = simple_strtol(buf, NULL, 10) / 1000;
1190         val = SENSORS_LIMIT(val, 0, 255);
1191
1192         mutex_lock(&data->update_lock);
1193         f71882fg_write8(data, F71882FG_REG_TEMP_HIGH(nr), val);
1194         data->temp_high[nr] = val;
1195         mutex_unlock(&data->update_lock);
1196
1197         return count;
1198 }
1199
1200 static ssize_t show_temp_max_hyst(struct device *dev, struct device_attribute
1201         *devattr, char *buf)
1202 {
1203         struct f71882fg_data *data = f71882fg_update_device(dev);
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);
1214
1215         return sprintf(buf, "%d\n", temp_max_hyst);
1216 }
1217
1218 static ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute
1219         *devattr, const char *buf, size_t count)
1220 {
1221         struct f71882fg_data *data = dev_get_drvdata(dev);
1222         int nr = to_sensor_dev_attr_2(devattr)->index;
1223         long val = simple_strtol(buf, NULL, 10) / 1000;
1224         ssize_t ret = count;
1225         u8 reg;
1226
1227         mutex_lock(&data->update_lock);
1228
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]);
1233         val = data->temp_high[nr] - val;
1234
1235         /* convert value to register contents */
1236         reg = f71882fg_read8(data, F71882FG_REG_TEMP_HYST(nr / 2));
1237         if (nr & 1)
1238                 reg = (reg & 0x0f) | (val << 4);
1239         else
1240                 reg = (reg & 0xf0) | val;
1241         f71882fg_write8(data, F71882FG_REG_TEMP_HYST(nr / 2), reg);
1242         data->temp_hyst[nr / 2] = reg;
1243
1244         mutex_unlock(&data->update_lock);
1245         return ret;
1246 }
1247
1248 static ssize_t show_temp_crit(struct device *dev, struct device_attribute
1249         *devattr, char *buf)
1250 {
1251         struct f71882fg_data *data = f71882fg_update_device(dev);
1252         int nr = to_sensor_dev_attr_2(devattr)->index;
1253
1254         return sprintf(buf, "%d\n", data->temp_ovt[nr] * 1000);
1255 }
1256
1257 static ssize_t store_temp_crit(struct device *dev, struct device_attribute
1258         *devattr, const char *buf, size_t count)
1259 {
1260         struct f71882fg_data *data = dev_get_drvdata(dev);
1261         int nr = to_sensor_dev_attr_2(devattr)->index;
1262         long val = simple_strtol(buf, NULL, 10) / 1000;
1263         val = SENSORS_LIMIT(val, 0, 255);
1264
1265         mutex_lock(&data->update_lock);
1266         f71882fg_write8(data, F71882FG_REG_TEMP_OVT(nr), val);
1267         data->temp_ovt[nr] = val;
1268         mutex_unlock(&data->update_lock);
1269
1270         return count;
1271 }
1272
1273 static ssize_t show_temp_crit_hyst(struct device *dev, struct device_attribute
1274         *devattr, char *buf)
1275 {
1276         struct f71882fg_data *data = f71882fg_update_device(dev);
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);
1287
1288         return sprintf(buf, "%d\n", temp_crit_hyst);
1289 }
1290
1291 static ssize_t show_temp_type(struct device *dev, struct device_attribute
1292         *devattr, char *buf)
1293 {
1294         struct f71882fg_data *data = f71882fg_update_device(dev);
1295         int nr = to_sensor_dev_attr_2(devattr)->index;
1296
1297         return sprintf(buf, "%d\n", data->temp_type[nr]);
1298 }
1299
1300 static ssize_t show_temp_beep(struct device *dev, struct device_attribute
1301         *devattr, char *buf)
1302 {
1303         struct f71882fg_data *data = f71882fg_update_device(dev);
1304         int nr = to_sensor_dev_attr_2(devattr)->index;
1305
1306         if (data->temp_beep & (1 << nr))
1307                 return sprintf(buf, "1\n");
1308         else
1309                 return sprintf(buf, "0\n");
1310 }
1311
1312 static ssize_t store_temp_beep(struct device *dev, struct device_attribute
1313         *devattr, const char *buf, size_t count)
1314 {
1315         struct f71882fg_data *data = dev_get_drvdata(dev);
1316         int nr = to_sensor_dev_attr_2(devattr)->index;
1317         unsigned long val = simple_strtoul(buf, NULL, 10);
1318
1319         mutex_lock(&data->update_lock);
1320         data->temp_beep = f71882fg_read8(data, F71882FG_REG_TEMP_BEEP);
1321         if (val)
1322                 data->temp_beep |= 1 << nr;
1323         else
1324                 data->temp_beep &= ~(1 << nr);
1325
1326         f71882fg_write8(data, F71882FG_REG_TEMP_BEEP, data->temp_beep);
1327         mutex_unlock(&data->update_lock);
1328
1329         return count;
1330 }
1331
1332 static ssize_t show_temp_alarm(struct device *dev, struct device_attribute
1333         *devattr, char *buf)
1334 {
1335         struct f71882fg_data *data = f71882fg_update_device(dev);
1336         int nr = to_sensor_dev_attr_2(devattr)->index;
1337
1338         if (data->temp_status & (1 << nr))
1339                 return sprintf(buf, "1\n");
1340         else
1341                 return sprintf(buf, "0\n");
1342 }
1343
1344 static ssize_t show_temp_fault(struct device *dev, struct device_attribute
1345         *devattr, char *buf)
1346 {
1347         struct f71882fg_data *data = f71882fg_update_device(dev);
1348         int nr = to_sensor_dev_attr_2(devattr)->index;
1349
1350         if (data->temp_diode_open & (1 << nr))
1351                 return sprintf(buf, "1\n");
1352         else
1353                 return sprintf(buf, "0\n");
1354 }
1355
1356 static 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
1374 static 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         }
1404 leave:
1405         mutex_unlock(&data->update_lock);
1406
1407         return count;
1408 }
1409
1410 static 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
1436 static 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);
1472 leave:
1473         mutex_unlock(&data->update_lock);
1474
1475         return count;
1476 }
1477
1478 static 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
1500 static 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
1528 static 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
1548 static 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
1578 static 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
1590 static 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
1612 static 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
1626 static 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
1660 static 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
1673 static 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
1691 static ssize_t show_name(struct device *dev, struct device_attribute *devattr,
1692         char *buf)
1693 {
1694         struct f71882fg_data *data = dev_get_drvdata(dev);
1695         return sprintf(buf, "%s\n", f71882fg_names[data->type]);
1696 }
1697
1698 static 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 }
1710
1711 static int __devinit f71882fg_probe(struct platform_device *pdev)
1712 {
1713         struct f71882fg_data *data;
1714         struct f71882fg_sio_data *sio_data = pdev->dev.platform_data;
1715         int err, i, nr_fans = (sio_data->type == f71882fg) ? 4 : 3;
1716         u8 start_reg;
1717
1718         data = kzalloc(sizeof(struct f71882fg_data), GFP_KERNEL);
1719         if (!data)
1720                 return -ENOMEM;
1721
1722         data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start;
1723         data->type = sio_data->type;
1724         mutex_init(&data->update_lock);
1725         platform_set_drvdata(pdev, data);
1726
1727         start_reg = f71882fg_read8(data, F71882FG_REG_START);
1728         if (start_reg & 0x04) {
1729                 dev_warn(&pdev->dev, "Hardware monitor is powered down\n");
1730                 err = -ENODEV;
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;
1737         }
1738
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
1757         if (start_reg & 0x01) {
1758                 switch (data->type) {
1759                 case f71882fg:
1760                         err = f71882fg_create_sysfs_files(pdev,
1761                                         f71882fg_in_temp_attr,
1762                                         ARRAY_SIZE(f71882fg_in_temp_attr));
1763                         if (err)
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;
1776                 }
1777                 if (err)
1778                         goto exit_unregister_sysfs;
1779         }
1780
1781         if (start_reg & 0x02) {
1782                 err = f71882fg_create_sysfs_files(pdev, fxxxx_fan_attr,
1783                                         ARRAY_SIZE(fxxxx_fan_attr));
1784                 if (err)
1785                         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;
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");
1811         }
1812
1813         data->hwmon_dev = hwmon_device_register(&pdev->dev);
1814         if (IS_ERR(data->hwmon_dev)) {
1815                 err = PTR_ERR(data->hwmon_dev);
1816                 data->hwmon_dev = NULL;
1817                 goto exit_unregister_sysfs;
1818         }
1819
1820         return 0;
1821
1822 exit_unregister_sysfs:
1823         f71882fg_remove(pdev); /* Will unregister the sysfs files for us */
1824         return err; /* f71882fg_remove() also frees our data */
1825 exit_free:
1826         kfree(data);
1827         return err;
1828 }
1829
1830 static int f71882fg_remove(struct platform_device *pdev)
1831 {
1832         int i;
1833         struct f71882fg_data *data = platform_get_drvdata(pdev);
1834
1835         platform_set_drvdata(pdev, NULL);
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);
1842
1843         for (i = 0; i < ARRAY_SIZE(f718x2fg_in_temp_attr); i++)
1844                 device_remove_file(&pdev->dev,
1845                                         &f718x2fg_in_temp_attr[i].dev_attr);
1846
1847         for (i = 0; i < ARRAY_SIZE(f71882fg_in_temp_attr); i++)
1848                 device_remove_file(&pdev->dev,
1849                                         &f71882fg_in_temp_attr[i].dev_attr);
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
1854         for (i = 0; i < ARRAY_SIZE(f71882fg_fan_attr); i++)
1855                 device_remove_file(&pdev->dev, &f71882fg_fan_attr[i].dev_attr);
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
1860         kfree(data);
1861
1862         return 0;
1863 }
1864
1865 static int __init f71882fg_find(int sioaddr, unsigned short *address,
1866         struct f71882fg_sio_data *sio_data)
1867 {
1868         int err = -ENODEV;
1869         u16 devid;
1870
1871         superio_enter(sioaddr);
1872
1873         devid = superio_inw(sioaddr, SIO_REG_MANID);
1874         if (devid != SIO_FINTEK_ID) {
1875                 pr_debug(DRVNAME ": Not a Fintek device\n");
1876                 goto exit;
1877         }
1878
1879         devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID);
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:
1891                 printk(KERN_INFO DRVNAME ": Unsupported Fintek device\n");
1892                 goto exit;
1893         }
1894
1895         superio_select(sioaddr, SIO_F71882FG_LD_HWM);
1896         if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) {
1897                 printk(KERN_WARNING DRVNAME ": Device not activated\n");
1898                 goto exit;
1899         }
1900
1901         *address = superio_inw(sioaddr, SIO_REG_ADDR);
1902         if (*address == 0)
1903         {
1904                 printk(KERN_WARNING DRVNAME ": Base address not set\n");
1905                 goto exit;
1906         }
1907         *address &= ~(REGION_LENGTH - 1);       /* Ignore 3 LSB */
1908
1909         err = 0;
1910         printk(KERN_INFO DRVNAME ": Found %s chip at %#x, revision %d\n",
1911                 f71882fg_names[sio_data->type], (unsigned int)*address,
1912                 (int)superio_inb(sioaddr, SIO_REG_DEVREV));
1913 exit:
1914         superio_exit(sioaddr);
1915         return err;
1916 }
1917
1918 static int __init f71882fg_device_add(unsigned short address,
1919         const struct f71882fg_sio_data *sio_data)
1920 {
1921         struct resource res = {
1922                 .start  = address,
1923                 .end    = address + REGION_LENGTH - 1,
1924                 .flags  = IORESOURCE_IO,
1925         };
1926         int err;
1927
1928         f71882fg_pdev = platform_device_alloc(DRVNAME, address);
1929         if (!f71882fg_pdev)
1930                 return -ENOMEM;
1931
1932         res.name = f71882fg_pdev->name;
1933         err = acpi_check_resource_conflict(&res);
1934         if (err)
1935                 goto exit_device_put;
1936
1937         err = platform_device_add_resources(f71882fg_pdev, &res, 1);
1938         if (err) {
1939                 printk(KERN_ERR DRVNAME ": Device resource addition failed\n");
1940                 goto exit_device_put;
1941         }
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
1950         err = platform_device_add(f71882fg_pdev);
1951         if (err) {
1952                 printk(KERN_ERR DRVNAME ": Device addition failed\n");
1953                 goto exit_device_put;
1954         }
1955
1956         return 0;
1957
1958 exit_device_put:
1959         platform_device_put(f71882fg_pdev);
1960
1961         return err;
1962 }
1963
1964 static int __init f71882fg_init(void)
1965 {
1966         int err = -ENODEV;
1967         unsigned short address;
1968         struct f71882fg_sio_data sio_data;
1969
1970         memset(&sio_data, 0, sizeof(sio_data));
1971
1972         if (f71882fg_find(0x2e, &address, &sio_data) &&
1973             f71882fg_find(0x4e, &address, &sio_data))
1974                 goto exit;
1975
1976         err = platform_driver_register(&f71882fg_driver);
1977         if (err)
1978                 goto exit;
1979
1980         err = f71882fg_device_add(address, &sio_data);
1981         if (err)
1982                 goto exit_driver;
1983
1984         return 0;
1985
1986 exit_driver:
1987         platform_driver_unregister(&f71882fg_driver);
1988 exit:
1989         return err;
1990 }
1991
1992 static void __exit f71882fg_exit(void)
1993 {
1994         platform_device_unregister(f71882fg_pdev);
1995         platform_driver_unregister(&f71882fg_driver);
1996 }
1997
1998 MODULE_DESCRIPTION("F71882FG Hardware Monitoring Driver");
1999 MODULE_AUTHOR("Hans Edgington, Hans de Goede (hdegoede@redhat.com)");
2000 MODULE_LICENSE("GPL");
2001
2002 module_init(f71882fg_init);
2003 module_exit(f71882fg_exit);