hwmon: (f71882fg) Cleanup f8000 pwm handling
[pandora-kernel.git] / drivers / hwmon / f71882fg.c
1 /***************************************************************************
2  *   Copyright (C) 2006 by Hans Edgington <hans@edgington.nl>              *
3  *   Copyright (C) 2007-2009 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         = 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, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 2),
399         SENSOR_ATTR_2(pwm3_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
400                       store_pwm_enable, 0, 2),
401         SENSOR_ATTR_2(pwm3_interpolate, S_IRUGO|S_IWUSR,
402                       show_pwm_interpolate, store_pwm_interpolate, 0, 2),
403         SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
404                       show_pwm_auto_point_channel,
405                       store_pwm_auto_point_channel, 0, 2),
406 };
407
408 /* Fan / PWM attr for the f71862fg, less pwms and less zones per pwm than the
409    f71882fg */
410 static struct sensor_device_attribute_2 f71862fg_fan_attr[] = {
411         SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep,
412                 store_fan_beep, 0, 0),
413         SENSOR_ATTR_2(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep,
414                 store_fan_beep, 0, 1),
415         SENSOR_ATTR_2(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep,
416                 store_fan_beep, 0, 2),
417
418         SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,
419                       show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
420                       1, 0),
421         SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO|S_IWUSR,
422                       show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
423                       4, 0),
424         SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IRUGO|S_IWUSR,
425                       show_pwm_auto_point_temp, store_pwm_auto_point_temp,
426                       0, 0),
427         SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IRUGO|S_IWUSR,
428                       show_pwm_auto_point_temp, store_pwm_auto_point_temp,
429                       3, 0),
430         SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
431                       show_pwm_auto_point_temp_hyst,
432                       store_pwm_auto_point_temp_hyst,
433                       0, 0),
434         SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO,
435                       show_pwm_auto_point_temp_hyst, NULL, 3, 0),
436
437         SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR,
438                       show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
439                       1, 1),
440         SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO|S_IWUSR,
441                       show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
442                       4, 1),
443         SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IRUGO|S_IWUSR,
444                       show_pwm_auto_point_temp, store_pwm_auto_point_temp,
445                       0, 1),
446         SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IRUGO|S_IWUSR,
447                       show_pwm_auto_point_temp, store_pwm_auto_point_temp,
448                       3, 1),
449         SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
450                       show_pwm_auto_point_temp_hyst,
451                       store_pwm_auto_point_temp_hyst,
452                       0, 1),
453         SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO,
454                       show_pwm_auto_point_temp_hyst, NULL, 3, 1),
455
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_auto_point1_pwm, S_IRUGO|S_IWUSR,
569                       show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
570                       0, 2),
571         SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO|S_IWUSR,
572                       show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
573                       1, 2),
574         SENSOR_ATTR_2(pwm3_auto_point3_pwm, S_IRUGO|S_IWUSR,
575                       show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
576                       2, 2),
577         SENSOR_ATTR_2(pwm3_auto_point4_pwm, S_IRUGO|S_IWUSR,
578                       show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
579                       3, 2),
580         SENSOR_ATTR_2(pwm3_auto_point5_pwm, S_IRUGO|S_IWUSR,
581                       show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
582                       4, 2),
583         SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IRUGO|S_IWUSR,
584                       show_pwm_auto_point_temp, store_pwm_auto_point_temp,
585                       0, 2),
586         SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IRUGO|S_IWUSR,
587                       show_pwm_auto_point_temp, store_pwm_auto_point_temp,
588                       1, 2),
589         SENSOR_ATTR_2(pwm3_auto_point3_temp, S_IRUGO|S_IWUSR,
590                       show_pwm_auto_point_temp, store_pwm_auto_point_temp,
591                       2, 2),
592         SENSOR_ATTR_2(pwm3_auto_point4_temp, S_IRUGO|S_IWUSR,
593                       show_pwm_auto_point_temp, store_pwm_auto_point_temp,
594                       3, 2),
595         SENSOR_ATTR_2(pwm3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
596                       show_pwm_auto_point_temp_hyst,
597                       store_pwm_auto_point_temp_hyst,
598                       0, 2),
599         SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst, S_IRUGO,
600                       show_pwm_auto_point_temp_hyst, NULL, 1, 2),
601         SENSOR_ATTR_2(pwm3_auto_point3_temp_hyst, S_IRUGO,
602                       show_pwm_auto_point_temp_hyst, NULL, 2, 2),
603         SENSOR_ATTR_2(pwm3_auto_point4_temp_hyst, S_IRUGO,
604                       show_pwm_auto_point_temp_hyst, NULL, 3, 2),
605
606         SENSOR_ATTR_2(pwm4, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 3),
607         SENSOR_ATTR_2(pwm4_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
608                       store_pwm_enable, 0, 3),
609         SENSOR_ATTR_2(pwm4_interpolate, S_IRUGO|S_IWUSR,
610                       show_pwm_interpolate, store_pwm_interpolate, 0, 3),
611         SENSOR_ATTR_2(pwm4_auto_channels_temp, S_IRUGO|S_IWUSR,
612                       show_pwm_auto_point_channel,
613                       store_pwm_auto_point_channel, 0, 3),
614         SENSOR_ATTR_2(pwm4_auto_point1_pwm, S_IRUGO|S_IWUSR,
615                       show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
616                       0, 3),
617         SENSOR_ATTR_2(pwm4_auto_point2_pwm, S_IRUGO|S_IWUSR,
618                       show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
619                       1, 3),
620         SENSOR_ATTR_2(pwm4_auto_point3_pwm, S_IRUGO|S_IWUSR,
621                       show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
622                       2, 3),
623         SENSOR_ATTR_2(pwm4_auto_point4_pwm, S_IRUGO|S_IWUSR,
624                       show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
625                       3, 3),
626         SENSOR_ATTR_2(pwm4_auto_point5_pwm, S_IRUGO|S_IWUSR,
627                       show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
628                       4, 3),
629         SENSOR_ATTR_2(pwm4_auto_point1_temp, S_IRUGO|S_IWUSR,
630                       show_pwm_auto_point_temp, store_pwm_auto_point_temp,
631                       0, 3),
632         SENSOR_ATTR_2(pwm4_auto_point2_temp, S_IRUGO|S_IWUSR,
633                       show_pwm_auto_point_temp, store_pwm_auto_point_temp,
634                       1, 3),
635         SENSOR_ATTR_2(pwm4_auto_point3_temp, S_IRUGO|S_IWUSR,
636                       show_pwm_auto_point_temp, store_pwm_auto_point_temp,
637                       2, 3),
638         SENSOR_ATTR_2(pwm4_auto_point4_temp, S_IRUGO|S_IWUSR,
639                       show_pwm_auto_point_temp, store_pwm_auto_point_temp,
640                       3, 3),
641         SENSOR_ATTR_2(pwm4_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
642                       show_pwm_auto_point_temp_hyst,
643                       store_pwm_auto_point_temp_hyst,
644                       0, 3),
645         SENSOR_ATTR_2(pwm4_auto_point2_temp_hyst, S_IRUGO,
646                       show_pwm_auto_point_temp_hyst, NULL, 1, 3),
647         SENSOR_ATTR_2(pwm4_auto_point3_temp_hyst, S_IRUGO,
648                       show_pwm_auto_point_temp_hyst, NULL, 2, 3),
649         SENSOR_ATTR_2(pwm4_auto_point4_temp_hyst, S_IRUGO,
650                       show_pwm_auto_point_temp_hyst, NULL, 3, 3),
651 };
652
653 /* Fan / PWM attr for the f8000, zones mapped to temp instead of to pwm!
654    Also the register block at offset A0 maps to TEMP1 (so our temp2, as the
655    F8000 starts counting temps at 0), B0 maps the TEMP2 and C0 maps to TEMP0 */
656 static struct sensor_device_attribute_2 f8000_fan_attr[] = {
657         SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
658
659         SENSOR_ATTR_2(temp1_auto_point1_pwm, S_IRUGO|S_IWUSR,
660                       show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
661                       0, 2),
662         SENSOR_ATTR_2(temp1_auto_point2_pwm, S_IRUGO|S_IWUSR,
663                       show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
664                       1, 2),
665         SENSOR_ATTR_2(temp1_auto_point3_pwm, S_IRUGO|S_IWUSR,
666                       show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
667                       2, 2),
668         SENSOR_ATTR_2(temp1_auto_point4_pwm, S_IRUGO|S_IWUSR,
669                       show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
670                       3, 2),
671         SENSOR_ATTR_2(temp1_auto_point5_pwm, S_IRUGO|S_IWUSR,
672                       show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
673                       4, 2),
674         SENSOR_ATTR_2(temp1_auto_point1_temp, S_IRUGO|S_IWUSR,
675                       show_pwm_auto_point_temp, store_pwm_auto_point_temp,
676                       0, 2),
677         SENSOR_ATTR_2(temp1_auto_point2_temp, S_IRUGO|S_IWUSR,
678                       show_pwm_auto_point_temp, store_pwm_auto_point_temp,
679                       1, 2),
680         SENSOR_ATTR_2(temp1_auto_point3_temp, S_IRUGO|S_IWUSR,
681                       show_pwm_auto_point_temp, store_pwm_auto_point_temp,
682                       2, 2),
683         SENSOR_ATTR_2(temp1_auto_point4_temp, S_IRUGO|S_IWUSR,
684                       show_pwm_auto_point_temp, store_pwm_auto_point_temp,
685                       3, 2),
686         SENSOR_ATTR_2(temp1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
687                       show_pwm_auto_point_temp_hyst,
688                       store_pwm_auto_point_temp_hyst,
689                       0, 2),
690         SENSOR_ATTR_2(temp1_auto_point2_temp_hyst, S_IRUGO,
691                       show_pwm_auto_point_temp_hyst, NULL, 1, 2),
692         SENSOR_ATTR_2(temp1_auto_point3_temp_hyst, S_IRUGO,
693                       show_pwm_auto_point_temp_hyst, NULL, 2, 2),
694         SENSOR_ATTR_2(temp1_auto_point4_temp_hyst, S_IRUGO,
695                       show_pwm_auto_point_temp_hyst, NULL, 3, 2),
696
697         SENSOR_ATTR_2(temp2_auto_point1_pwm, S_IRUGO|S_IWUSR,
698                       show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
699                       0, 0),
700         SENSOR_ATTR_2(temp2_auto_point2_pwm, S_IRUGO|S_IWUSR,
701                       show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
702                       1, 0),
703         SENSOR_ATTR_2(temp2_auto_point3_pwm, S_IRUGO|S_IWUSR,
704                       show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
705                       2, 0),
706         SENSOR_ATTR_2(temp2_auto_point4_pwm, S_IRUGO|S_IWUSR,
707                       show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
708                       3, 0),
709         SENSOR_ATTR_2(temp2_auto_point5_pwm, S_IRUGO|S_IWUSR,
710                       show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
711                       4, 0),
712         SENSOR_ATTR_2(temp2_auto_point1_temp, S_IRUGO|S_IWUSR,
713                       show_pwm_auto_point_temp, store_pwm_auto_point_temp,
714                       0, 0),
715         SENSOR_ATTR_2(temp2_auto_point2_temp, S_IRUGO|S_IWUSR,
716                       show_pwm_auto_point_temp, store_pwm_auto_point_temp,
717                       1, 0),
718         SENSOR_ATTR_2(temp2_auto_point3_temp, S_IRUGO|S_IWUSR,
719                       show_pwm_auto_point_temp, store_pwm_auto_point_temp,
720                       2, 0),
721         SENSOR_ATTR_2(temp2_auto_point4_temp, S_IRUGO|S_IWUSR,
722                       show_pwm_auto_point_temp, store_pwm_auto_point_temp,
723                       3, 0),
724         SENSOR_ATTR_2(temp2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
725                       show_pwm_auto_point_temp_hyst,
726                       store_pwm_auto_point_temp_hyst,
727                       0, 0),
728         SENSOR_ATTR_2(temp2_auto_point2_temp_hyst, S_IRUGO,
729                       show_pwm_auto_point_temp_hyst, NULL, 1, 0),
730         SENSOR_ATTR_2(temp2_auto_point3_temp_hyst, S_IRUGO,
731                       show_pwm_auto_point_temp_hyst, NULL, 2, 0),
732         SENSOR_ATTR_2(temp2_auto_point4_temp_hyst, S_IRUGO,
733                       show_pwm_auto_point_temp_hyst, NULL, 3, 0),
734
735         SENSOR_ATTR_2(temp3_auto_point1_pwm, S_IRUGO|S_IWUSR,
736                       show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
737                       0, 1),
738         SENSOR_ATTR_2(temp3_auto_point2_pwm, S_IRUGO|S_IWUSR,
739                       show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
740                       1, 1),
741         SENSOR_ATTR_2(temp3_auto_point3_pwm, S_IRUGO|S_IWUSR,
742                       show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
743                       2, 1),
744         SENSOR_ATTR_2(temp3_auto_point4_pwm, S_IRUGO|S_IWUSR,
745                       show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
746                       3, 1),
747         SENSOR_ATTR_2(temp3_auto_point5_pwm, S_IRUGO|S_IWUSR,
748                       show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
749                       4, 1),
750         SENSOR_ATTR_2(temp3_auto_point1_temp, S_IRUGO|S_IWUSR,
751                       show_pwm_auto_point_temp, store_pwm_auto_point_temp,
752                       0, 1),
753         SENSOR_ATTR_2(temp3_auto_point2_temp, S_IRUGO|S_IWUSR,
754                       show_pwm_auto_point_temp, store_pwm_auto_point_temp,
755                       1, 1),
756         SENSOR_ATTR_2(temp3_auto_point3_temp, S_IRUGO|S_IWUSR,
757                       show_pwm_auto_point_temp, store_pwm_auto_point_temp,
758                       2, 1),
759         SENSOR_ATTR_2(temp3_auto_point4_temp, S_IRUGO|S_IWUSR,
760                       show_pwm_auto_point_temp, store_pwm_auto_point_temp,
761                       3, 1),
762         SENSOR_ATTR_2(temp3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
763                       show_pwm_auto_point_temp_hyst,
764                       store_pwm_auto_point_temp_hyst,
765                       0, 1),
766         SENSOR_ATTR_2(temp3_auto_point2_temp_hyst, S_IRUGO,
767                       show_pwm_auto_point_temp_hyst, NULL, 1, 1),
768         SENSOR_ATTR_2(temp3_auto_point3_temp_hyst, S_IRUGO,
769                       show_pwm_auto_point_temp_hyst, NULL, 2, 1),
770         SENSOR_ATTR_2(temp3_auto_point4_temp_hyst, S_IRUGO,
771                       show_pwm_auto_point_temp_hyst, NULL, 3, 1),
772 };
773
774 /* Super I/O functions */
775 static inline int superio_inb(int base, int reg)
776 {
777         outb(reg, base);
778         return inb(base + 1);
779 }
780
781 static int superio_inw(int base, int reg)
782 {
783         int val;
784         outb(reg++, base);
785         val = inb(base + 1) << 8;
786         outb(reg, base);
787         val |= inb(base + 1);
788         return val;
789 }
790
791 static inline void superio_enter(int base)
792 {
793         /* according to the datasheet the key must be send twice! */
794         outb( SIO_UNLOCK_KEY, base);
795         outb( SIO_UNLOCK_KEY, base);
796 }
797
798 static inline void superio_select( int base, int ld)
799 {
800         outb(SIO_REG_LDSEL, base);
801         outb(ld, base + 1);
802 }
803
804 static inline void superio_exit(int base)
805 {
806         outb(SIO_LOCK_KEY, base);
807 }
808
809 static inline int fan_from_reg(u16 reg)
810 {
811         return reg ? (1500000 / reg) : 0;
812 }
813
814 static inline u16 fan_to_reg(int fan)
815 {
816         return fan ? (1500000 / fan) : 0;
817 }
818
819 static u8 f71882fg_read8(struct f71882fg_data *data, u8 reg)
820 {
821         u8 val;
822
823         outb(reg, data->addr + ADDR_REG_OFFSET);
824         val = inb(data->addr + DATA_REG_OFFSET);
825
826         return val;
827 }
828
829 static u16 f71882fg_read16(struct f71882fg_data *data, u8 reg)
830 {
831         u16 val;
832
833         outb(reg++, data->addr + ADDR_REG_OFFSET);
834         val = inb(data->addr + DATA_REG_OFFSET) << 8;
835         outb(reg, data->addr + ADDR_REG_OFFSET);
836         val |= inb(data->addr + DATA_REG_OFFSET);
837
838         return val;
839 }
840
841 static void f71882fg_write8(struct f71882fg_data *data, u8 reg, u8 val)
842 {
843         outb(reg, data->addr + ADDR_REG_OFFSET);
844         outb(val, data->addr + DATA_REG_OFFSET);
845 }
846
847 static void f71882fg_write16(struct f71882fg_data *data, u8 reg, u16 val)
848 {
849         outb(reg++, data->addr + ADDR_REG_OFFSET);
850         outb(val >> 8, data->addr + DATA_REG_OFFSET);
851         outb(reg, data->addr + ADDR_REG_OFFSET);
852         outb(val & 255, data->addr + DATA_REG_OFFSET);
853 }
854
855 static struct f71882fg_data *f71882fg_update_device(struct device *dev)
856 {
857         struct f71882fg_data *data = dev_get_drvdata(dev);
858         int nr, reg = 0, reg2;
859         int nr_fans = (data->type == f71882fg) ? 4 : 3;
860         int nr_ins = (data->type == f8000) ? 3 : 9;
861         int temp_start = (data->type == f8000) ? 0 : 1;
862
863         mutex_lock(&data->update_lock);
864
865         /* Update once every 60 seconds */
866         if ( time_after(jiffies, data->last_limits + 60 * HZ ) ||
867                         !data->valid) {
868                 if (data->type == f71882fg) {
869                         data->in1_max =
870                                 f71882fg_read8(data, F71882FG_REG_IN1_HIGH);
871                         data->in_beep =
872                                 f71882fg_read8(data, F71882FG_REG_IN_BEEP);
873                 }
874
875                 /* Get High & boundary temps*/
876                 for (nr = temp_start; nr < 3 + temp_start; nr++) {
877                         data->temp_ovt[nr] = f71882fg_read8(data,
878                                                 F71882FG_REG_TEMP_OVT(nr));
879                         data->temp_high[nr] = f71882fg_read8(data,
880                                                 F71882FG_REG_TEMP_HIGH(nr));
881                 }
882
883                 if (data->type != f8000) {
884                         data->fan_beep = f71882fg_read8(data,
885                                                 F71882FG_REG_FAN_BEEP);
886                         data->temp_beep = f71882fg_read8(data,
887                                                 F71882FG_REG_TEMP_BEEP);
888                         data->temp_hyst[0] = f71882fg_read8(data,
889                                                 F71882FG_REG_TEMP_HYST(0));
890                         data->temp_hyst[1] = f71882fg_read8(data,
891                                                 F71882FG_REG_TEMP_HYST(1));
892                         /* Have to hardcode type, because temp1 is special */
893                         reg  = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE);
894                         data->temp_type[2] = (reg & 0x04) ? 2 : 4;
895                         data->temp_type[3] = (reg & 0x08) ? 2 : 4;
896                 }
897                 reg2 = f71882fg_read8(data, F71882FG_REG_PECI);
898                 if ((reg2 & 0x03) == 0x01)
899                         data->temp_type[1] = 6 /* PECI */;
900                 else if ((reg2 & 0x03) == 0x02)
901                         data->temp_type[1] = 5 /* AMDSI */;
902                 else if (data->type != f8000)
903                         data->temp_type[1] = (reg & 0x02) ? 2 : 4;
904                 else
905                         data->temp_type[1] = 2; /* F8000 only supports BJT */
906
907                 data->pwm_enable = f71882fg_read8(data,
908                                                   F71882FG_REG_PWM_ENABLE);
909                 data->pwm_auto_point_hyst[0] =
910                         f71882fg_read8(data, F71882FG_REG_FAN_HYST(0));
911                 data->pwm_auto_point_hyst[1] =
912                         f71882fg_read8(data, F71882FG_REG_FAN_HYST(1));
913
914                 for (nr = 0; nr < nr_fans; nr++) {
915                         data->pwm_auto_point_mapping[nr] =
916                             f71882fg_read8(data,
917                                            F71882FG_REG_POINT_MAPPING(nr));
918
919                         if (data->type != f71862fg) {
920                                 int point;
921                                 for (point = 0; point < 5; point++) {
922                                         data->pwm_auto_point_pwm[nr][point] =
923                                                 f71882fg_read8(data,
924                                                         F71882FG_REG_POINT_PWM
925                                                         (nr, point));
926                                 }
927                                 for (point = 0; point < 4; point++) {
928                                         data->pwm_auto_point_temp[nr][point] =
929                                                 f71882fg_read8(data,
930                                                         F71882FG_REG_POINT_TEMP
931                                                         (nr, point));
932                                 }
933                         } else {
934                                 data->pwm_auto_point_pwm[nr][1] =
935                                         f71882fg_read8(data,
936                                                 F71882FG_REG_POINT_PWM
937                                                 (nr, 1));
938                                 data->pwm_auto_point_pwm[nr][4] =
939                                         f71882fg_read8(data,
940                                                 F71882FG_REG_POINT_PWM
941                                                 (nr, 4));
942                                 data->pwm_auto_point_temp[nr][0] =
943                                         f71882fg_read8(data,
944                                                 F71882FG_REG_POINT_TEMP
945                                                 (nr, 0));
946                                 data->pwm_auto_point_temp[nr][3] =
947                                         f71882fg_read8(data,
948                                                 F71882FG_REG_POINT_TEMP
949                                                 (nr, 3));
950                         }
951                 }
952                 data->last_limits = jiffies;
953         }
954
955         /* Update every second */
956         if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
957                 data->temp_status = f71882fg_read8(data,
958                                                 F71882FG_REG_TEMP_STATUS);
959                 data->temp_diode_open = f71882fg_read8(data,
960                                                 F71882FG_REG_TEMP_DIODE_OPEN);
961                 for (nr = temp_start; nr < 3 + temp_start; nr++)
962                         data->temp[nr] = f71882fg_read8(data,
963                                                 F71882FG_REG_TEMP(nr));
964
965                 data->fan_status = f71882fg_read8(data,
966                                                 F71882FG_REG_FAN_STATUS);
967                 for (nr = 0; nr < nr_fans; nr++) {
968                         data->fan[nr] = f71882fg_read16(data,
969                                                 F71882FG_REG_FAN(nr));
970                         data->fan_target[nr] =
971                             f71882fg_read16(data, F71882FG_REG_FAN_TARGET(nr));
972                         data->fan_full_speed[nr] =
973                             f71882fg_read16(data,
974                                             F71882FG_REG_FAN_FULL_SPEED(nr));
975                         data->pwm[nr] =
976                             f71882fg_read8(data, F71882FG_REG_PWM(nr));
977                 }
978
979                 /* The f8000 can monitor 1 more fan, but has no pwm for it */
980                 if (data->type == f8000)
981                         data->fan[3] = f71882fg_read16(data,
982                                                 F71882FG_REG_FAN(3));
983                 if (data->type == f71882fg)
984                         data->in_status = f71882fg_read8(data,
985                                                 F71882FG_REG_IN_STATUS);
986                 for (nr = 0; nr < nr_ins; nr++)
987                         data->in[nr] = f71882fg_read8(data,
988                                                 F71882FG_REG_IN(nr));
989
990                 data->last_updated = jiffies;
991                 data->valid = 1;
992         }
993
994         mutex_unlock(&data->update_lock);
995
996         return data;
997 }
998
999 /* Sysfs Interface */
1000 static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
1001         char *buf)
1002 {
1003         struct f71882fg_data *data = f71882fg_update_device(dev);
1004         int nr = to_sensor_dev_attr_2(devattr)->index;
1005         int speed = fan_from_reg(data->fan[nr]);
1006
1007         if (speed == FAN_MIN_DETECT)
1008                 speed = 0;
1009
1010         return sprintf(buf, "%d\n", speed);
1011 }
1012
1013 static ssize_t show_fan_full_speed(struct device *dev,
1014                                    struct device_attribute *devattr, char *buf)
1015 {
1016         struct f71882fg_data *data = f71882fg_update_device(dev);
1017         int nr = to_sensor_dev_attr_2(devattr)->index;
1018         int speed = fan_from_reg(data->fan_full_speed[nr]);
1019         return sprintf(buf, "%d\n", speed);
1020 }
1021
1022 static ssize_t store_fan_full_speed(struct device *dev,
1023                                     struct device_attribute *devattr,
1024                                     const char *buf, size_t count)
1025 {
1026         struct f71882fg_data *data = dev_get_drvdata(dev);
1027         int nr = to_sensor_dev_attr_2(devattr)->index;
1028         long val = simple_strtol(buf, NULL, 10);
1029
1030         val = SENSORS_LIMIT(val, 23, 1500000);
1031         val = fan_to_reg(val);
1032
1033         mutex_lock(&data->update_lock);
1034         f71882fg_write16(data, F71882FG_REG_FAN_FULL_SPEED(nr), val);
1035         data->fan_full_speed[nr] = val;
1036         mutex_unlock(&data->update_lock);
1037
1038         return count;
1039 }
1040
1041 static ssize_t show_fan_beep(struct device *dev, struct device_attribute
1042         *devattr, char *buf)
1043 {
1044         struct f71882fg_data *data = f71882fg_update_device(dev);
1045         int nr = to_sensor_dev_attr_2(devattr)->index;
1046
1047         if (data->fan_beep & (1 << nr))
1048                 return sprintf(buf, "1\n");
1049         else
1050                 return sprintf(buf, "0\n");
1051 }
1052
1053 static ssize_t store_fan_beep(struct device *dev, struct device_attribute
1054         *devattr, const char *buf, size_t count)
1055 {
1056         struct f71882fg_data *data = dev_get_drvdata(dev);
1057         int nr = to_sensor_dev_attr_2(devattr)->index;
1058         unsigned long val = simple_strtoul(buf, NULL, 10);
1059
1060         mutex_lock(&data->update_lock);
1061         data->fan_beep = f71882fg_read8(data, F71882FG_REG_FAN_BEEP);
1062         if (val)
1063                 data->fan_beep |= 1 << nr;
1064         else
1065                 data->fan_beep &= ~(1 << nr);
1066
1067         f71882fg_write8(data, F71882FG_REG_FAN_BEEP, data->fan_beep);
1068         mutex_unlock(&data->update_lock);
1069
1070         return count;
1071 }
1072
1073 static ssize_t show_fan_alarm(struct device *dev, struct device_attribute
1074         *devattr, char *buf)
1075 {
1076         struct f71882fg_data *data = f71882fg_update_device(dev);
1077         int nr = to_sensor_dev_attr_2(devattr)->index;
1078
1079         if (data->fan_status & (1 << nr))
1080                 return sprintf(buf, "1\n");
1081         else
1082                 return sprintf(buf, "0\n");
1083 }
1084
1085 static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
1086         char *buf)
1087 {
1088         struct f71882fg_data *data = f71882fg_update_device(dev);
1089         int nr = to_sensor_dev_attr_2(devattr)->index;
1090
1091         return sprintf(buf, "%d\n", data->in[nr] * 8);
1092 }
1093
1094 static ssize_t show_in_max(struct device *dev, struct device_attribute
1095         *devattr, char *buf)
1096 {
1097         struct f71882fg_data *data = f71882fg_update_device(dev);
1098
1099         return sprintf(buf, "%d\n", data->in1_max * 8);
1100 }
1101
1102 static ssize_t store_in_max(struct device *dev, struct device_attribute
1103         *devattr, const char *buf, size_t count)
1104 {
1105         struct f71882fg_data *data = dev_get_drvdata(dev);
1106         long val = simple_strtol(buf, NULL, 10) / 8;
1107         val = SENSORS_LIMIT(val, 0, 255);
1108
1109         mutex_lock(&data->update_lock);
1110         f71882fg_write8(data, F71882FG_REG_IN1_HIGH, val);
1111         data->in1_max = val;
1112         mutex_unlock(&data->update_lock);
1113
1114         return count;
1115 }
1116
1117 static ssize_t show_in_beep(struct device *dev, struct device_attribute
1118         *devattr, char *buf)
1119 {
1120         struct f71882fg_data *data = f71882fg_update_device(dev);
1121         int nr = to_sensor_dev_attr_2(devattr)->index;
1122
1123         if (data->in_beep & (1 << nr))
1124                 return sprintf(buf, "1\n");
1125         else
1126                 return sprintf(buf, "0\n");
1127 }
1128
1129 static ssize_t store_in_beep(struct device *dev, struct device_attribute
1130         *devattr, const char *buf, size_t count)
1131 {
1132         struct f71882fg_data *data = dev_get_drvdata(dev);
1133         int nr = to_sensor_dev_attr_2(devattr)->index;
1134         unsigned long val = simple_strtoul(buf, NULL, 10);
1135
1136         mutex_lock(&data->update_lock);
1137         data->in_beep = f71882fg_read8(data, F71882FG_REG_IN_BEEP);
1138         if (val)
1139                 data->in_beep |= 1 << nr;
1140         else
1141                 data->in_beep &= ~(1 << nr);
1142
1143         f71882fg_write8(data, F71882FG_REG_IN_BEEP, data->in_beep);
1144         mutex_unlock(&data->update_lock);
1145
1146         return count;
1147 }
1148
1149 static ssize_t show_in_alarm(struct device *dev, struct device_attribute
1150         *devattr, char *buf)
1151 {
1152         struct f71882fg_data *data = f71882fg_update_device(dev);
1153         int nr = to_sensor_dev_attr_2(devattr)->index;
1154
1155         if (data->in_status & (1 << nr))
1156                 return sprintf(buf, "1\n");
1157         else
1158                 return sprintf(buf, "0\n");
1159 }
1160
1161 static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
1162         char *buf)
1163 {
1164         struct f71882fg_data *data = f71882fg_update_device(dev);
1165         int nr = to_sensor_dev_attr_2(devattr)->index;
1166
1167         return sprintf(buf, "%d\n", data->temp[nr] * 1000);
1168 }
1169
1170 static ssize_t show_temp_max(struct device *dev, struct device_attribute
1171         *devattr, char *buf)
1172 {
1173         struct f71882fg_data *data = f71882fg_update_device(dev);
1174         int nr = to_sensor_dev_attr_2(devattr)->index;
1175
1176         return sprintf(buf, "%d\n", data->temp_high[nr] * 1000);
1177 }
1178
1179 static ssize_t store_temp_max(struct device *dev, struct device_attribute
1180         *devattr, const char *buf, size_t count)
1181 {
1182         struct f71882fg_data *data = dev_get_drvdata(dev);
1183         int nr = to_sensor_dev_attr_2(devattr)->index;
1184         long val = simple_strtol(buf, NULL, 10) / 1000;
1185         val = SENSORS_LIMIT(val, 0, 255);
1186
1187         mutex_lock(&data->update_lock);
1188         f71882fg_write8(data, F71882FG_REG_TEMP_HIGH(nr), val);
1189         data->temp_high[nr] = val;
1190         mutex_unlock(&data->update_lock);
1191
1192         return count;
1193 }
1194
1195 static ssize_t show_temp_max_hyst(struct device *dev, struct device_attribute
1196         *devattr, char *buf)
1197 {
1198         struct f71882fg_data *data = f71882fg_update_device(dev);
1199         int nr = to_sensor_dev_attr_2(devattr)->index;
1200         int temp_max_hyst;
1201
1202         mutex_lock(&data->update_lock);
1203         if (nr & 1)
1204                 temp_max_hyst = data->temp_hyst[nr / 2] >> 4;
1205         else
1206                 temp_max_hyst = data->temp_hyst[nr / 2] & 0x0f;
1207         temp_max_hyst = (data->temp_high[nr] - temp_max_hyst) * 1000;
1208         mutex_unlock(&data->update_lock);
1209
1210         return sprintf(buf, "%d\n", temp_max_hyst);
1211 }
1212
1213 static ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute
1214         *devattr, const char *buf, size_t count)
1215 {
1216         struct f71882fg_data *data = dev_get_drvdata(dev);
1217         int nr = to_sensor_dev_attr_2(devattr)->index;
1218         long val = simple_strtol(buf, NULL, 10) / 1000;
1219         ssize_t ret = count;
1220         u8 reg;
1221
1222         mutex_lock(&data->update_lock);
1223
1224         /* convert abs to relative and check */
1225         data->temp_high[nr] = f71882fg_read8(data, F71882FG_REG_TEMP_HIGH(nr));
1226         val = SENSORS_LIMIT(val, data->temp_high[nr] - 15,
1227                             data->temp_high[nr]);
1228         val = data->temp_high[nr] - val;
1229
1230         /* convert value to register contents */
1231         reg = f71882fg_read8(data, F71882FG_REG_TEMP_HYST(nr / 2));
1232         if (nr & 1)
1233                 reg = (reg & 0x0f) | (val << 4);
1234         else
1235                 reg = (reg & 0xf0) | val;
1236         f71882fg_write8(data, F71882FG_REG_TEMP_HYST(nr / 2), reg);
1237         data->temp_hyst[nr / 2] = reg;
1238
1239         mutex_unlock(&data->update_lock);
1240         return ret;
1241 }
1242
1243 static ssize_t show_temp_crit(struct device *dev, struct device_attribute
1244         *devattr, char *buf)
1245 {
1246         struct f71882fg_data *data = f71882fg_update_device(dev);
1247         int nr = to_sensor_dev_attr_2(devattr)->index;
1248
1249         return sprintf(buf, "%d\n", data->temp_ovt[nr] * 1000);
1250 }
1251
1252 static ssize_t store_temp_crit(struct device *dev, struct device_attribute
1253         *devattr, const char *buf, size_t count)
1254 {
1255         struct f71882fg_data *data = dev_get_drvdata(dev);
1256         int nr = to_sensor_dev_attr_2(devattr)->index;
1257         long val = simple_strtol(buf, NULL, 10) / 1000;
1258         val = SENSORS_LIMIT(val, 0, 255);
1259
1260         mutex_lock(&data->update_lock);
1261         f71882fg_write8(data, F71882FG_REG_TEMP_OVT(nr), val);
1262         data->temp_ovt[nr] = val;
1263         mutex_unlock(&data->update_lock);
1264
1265         return count;
1266 }
1267
1268 static ssize_t show_temp_crit_hyst(struct device *dev, struct device_attribute
1269         *devattr, char *buf)
1270 {
1271         struct f71882fg_data *data = f71882fg_update_device(dev);
1272         int nr = to_sensor_dev_attr_2(devattr)->index;
1273         int temp_crit_hyst;
1274
1275         mutex_lock(&data->update_lock);
1276         if (nr & 1)
1277                 temp_crit_hyst = data->temp_hyst[nr / 2] >> 4;
1278         else
1279                 temp_crit_hyst = data->temp_hyst[nr / 2] & 0x0f;
1280         temp_crit_hyst = (data->temp_ovt[nr] - temp_crit_hyst) * 1000;
1281         mutex_unlock(&data->update_lock);
1282
1283         return sprintf(buf, "%d\n", temp_crit_hyst);
1284 }
1285
1286 static ssize_t show_temp_type(struct device *dev, struct device_attribute
1287         *devattr, char *buf)
1288 {
1289         struct f71882fg_data *data = f71882fg_update_device(dev);
1290         int nr = to_sensor_dev_attr_2(devattr)->index;
1291
1292         return sprintf(buf, "%d\n", data->temp_type[nr]);
1293 }
1294
1295 static ssize_t show_temp_beep(struct device *dev, struct device_attribute
1296         *devattr, char *buf)
1297 {
1298         struct f71882fg_data *data = f71882fg_update_device(dev);
1299         int nr = to_sensor_dev_attr_2(devattr)->index;
1300
1301         if (data->temp_beep & (1 << nr))
1302                 return sprintf(buf, "1\n");
1303         else
1304                 return sprintf(buf, "0\n");
1305 }
1306
1307 static ssize_t store_temp_beep(struct device *dev, struct device_attribute
1308         *devattr, const char *buf, size_t count)
1309 {
1310         struct f71882fg_data *data = dev_get_drvdata(dev);
1311         int nr = to_sensor_dev_attr_2(devattr)->index;
1312         unsigned long val = simple_strtoul(buf, NULL, 10);
1313
1314         mutex_lock(&data->update_lock);
1315         data->temp_beep = f71882fg_read8(data, F71882FG_REG_TEMP_BEEP);
1316         if (val)
1317                 data->temp_beep |= 1 << nr;
1318         else
1319                 data->temp_beep &= ~(1 << nr);
1320
1321         f71882fg_write8(data, F71882FG_REG_TEMP_BEEP, data->temp_beep);
1322         mutex_unlock(&data->update_lock);
1323
1324         return count;
1325 }
1326
1327 static ssize_t show_temp_alarm(struct device *dev, struct device_attribute
1328         *devattr, char *buf)
1329 {
1330         struct f71882fg_data *data = f71882fg_update_device(dev);
1331         int nr = to_sensor_dev_attr_2(devattr)->index;
1332
1333         if (data->temp_status & (1 << nr))
1334                 return sprintf(buf, "1\n");
1335         else
1336                 return sprintf(buf, "0\n");
1337 }
1338
1339 static ssize_t show_temp_fault(struct device *dev, struct device_attribute
1340         *devattr, char *buf)
1341 {
1342         struct f71882fg_data *data = f71882fg_update_device(dev);
1343         int nr = to_sensor_dev_attr_2(devattr)->index;
1344
1345         if (data->temp_diode_open & (1 << nr))
1346                 return sprintf(buf, "1\n");
1347         else
1348                 return sprintf(buf, "0\n");
1349 }
1350
1351 static ssize_t show_pwm(struct device *dev,
1352                         struct device_attribute *devattr, char *buf)
1353 {
1354         struct f71882fg_data *data = f71882fg_update_device(dev);
1355         int val, nr = to_sensor_dev_attr_2(devattr)->index;
1356         mutex_lock(&data->update_lock);
1357         if (data->pwm_enable & (1 << (2 * nr)))
1358                 /* PWM mode */
1359                 val = data->pwm[nr];
1360         else {
1361                 /* RPM mode */
1362                 val = 255 * fan_from_reg(data->fan_target[nr])
1363                         / fan_from_reg(data->fan_full_speed[nr]);
1364         }
1365         mutex_unlock(&data->update_lock);
1366         return sprintf(buf, "%d\n", val);
1367 }
1368
1369 static ssize_t store_pwm(struct device *dev,
1370                          struct device_attribute *devattr, const char *buf,
1371                          size_t count)
1372 {
1373         struct f71882fg_data *data = dev_get_drvdata(dev);
1374         int nr = to_sensor_dev_attr_2(devattr)->index;
1375         long val = simple_strtol(buf, NULL, 10);
1376         val = SENSORS_LIMIT(val, 0, 255);
1377
1378         mutex_lock(&data->update_lock);
1379         data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
1380         if ((data->type == f8000 && ((data->pwm_enable >> 2 * nr) & 3) != 2) ||
1381             (data->type != f8000 && !((data->pwm_enable >> 2 * nr) & 2))) {
1382                 count = -EROFS;
1383                 goto leave;
1384         }
1385         if (data->pwm_enable & (1 << (2 * nr))) {
1386                 /* PWM mode */
1387                 f71882fg_write8(data, F71882FG_REG_PWM(nr), val);
1388                 data->pwm[nr] = val;
1389         } else {
1390                 /* RPM mode */
1391                 int target, full_speed;
1392                 full_speed = f71882fg_read16(data,
1393                                              F71882FG_REG_FAN_FULL_SPEED(nr));
1394                 target = fan_to_reg(val * fan_from_reg(full_speed) / 255);
1395                 f71882fg_write16(data, F71882FG_REG_FAN_TARGET(nr), target);
1396                 data->fan_target[nr] = target;
1397                 data->fan_full_speed[nr] = full_speed;
1398         }
1399 leave:
1400         mutex_unlock(&data->update_lock);
1401
1402         return count;
1403 }
1404
1405 static ssize_t show_pwm_enable(struct device *dev,
1406                                struct device_attribute *devattr, char *buf)
1407 {
1408         int result = 0;
1409         struct f71882fg_data *data = f71882fg_update_device(dev);
1410         int nr = to_sensor_dev_attr_2(devattr)->index;
1411
1412         switch ((data->pwm_enable >> 2 * nr) & 3) {
1413         case 0:
1414         case 1:
1415                 result = 2; /* Normal auto mode */
1416                 break;
1417         case 2:
1418                 result = 1; /* Manual mode */
1419                 break;
1420         case 3:
1421                 if (data->type == f8000)
1422                         result = 3; /* Thermostat mode */
1423                 else
1424                         result = 1; /* Manual mode */
1425                 break;
1426         }
1427
1428         return sprintf(buf, "%d\n", result);
1429 }
1430
1431 static ssize_t store_pwm_enable(struct device *dev, struct device_attribute
1432                                 *devattr, const char *buf, size_t count)
1433 {
1434         struct f71882fg_data *data = dev_get_drvdata(dev);
1435         int nr = to_sensor_dev_attr_2(devattr)->index;
1436         long val = simple_strtol(buf, NULL, 10);
1437
1438         /* Special case for F8000 pwm channel 3 which only does auto mode */
1439         if (data->type == f8000 && nr == 2 && val != 2)
1440                 return -EINVAL;
1441
1442         mutex_lock(&data->update_lock);
1443         data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
1444         /* Special case for F8000 auto PWM mode / Thermostat mode */
1445         if (data->type == f8000 && ((data->pwm_enable >> 2 * nr) & 1)) {
1446                 switch (val) {
1447                 case 2:
1448                         data->pwm_enable &= ~(2 << (2 * nr));
1449                         break;          /* Normal auto mode */
1450                 case 3:
1451                         data->pwm_enable |= 2 << (2 * nr);
1452                         break;          /* Thermostat mode */
1453                 default:
1454                         count = -EINVAL;
1455                         goto leave;
1456                 }
1457         } else {
1458                 switch (val) {
1459                 case 1:
1460                         data->pwm_enable |= 2 << (2 * nr);
1461                         break;          /* Manual */
1462                 case 2:
1463                         data->pwm_enable &= ~(2 << (2 * nr));
1464                         break;          /* Normal auto mode */
1465                 default:
1466                         count = -EINVAL;
1467                         goto leave;
1468                 }
1469         }
1470         f71882fg_write8(data, F71882FG_REG_PWM_ENABLE, data->pwm_enable);
1471 leave:
1472         mutex_unlock(&data->update_lock);
1473
1474         return count;
1475 }
1476
1477 static ssize_t show_pwm_auto_point_pwm(struct device *dev,
1478                                        struct device_attribute *devattr,
1479                                        char *buf)
1480 {
1481         int result;
1482         struct f71882fg_data *data = f71882fg_update_device(dev);
1483         int pwm = to_sensor_dev_attr_2(devattr)->index;
1484         int point = to_sensor_dev_attr_2(devattr)->nr;
1485
1486         mutex_lock(&data->update_lock);
1487         if (data->pwm_enable & (1 << (2 * pwm))) {
1488                 /* PWM mode */
1489                 result = data->pwm_auto_point_pwm[pwm][point];
1490         } else {
1491                 /* RPM mode */
1492                 result = 32 * 255 / (32 + data->pwm_auto_point_pwm[pwm][point]);
1493         }
1494         mutex_unlock(&data->update_lock);
1495
1496         return sprintf(buf, "%d\n", result);
1497 }
1498
1499 static ssize_t store_pwm_auto_point_pwm(struct device *dev,
1500                                         struct device_attribute *devattr,
1501                                         const char *buf, size_t count)
1502 {
1503         struct f71882fg_data *data = dev_get_drvdata(dev);
1504         int pwm = to_sensor_dev_attr_2(devattr)->index;
1505         int point = to_sensor_dev_attr_2(devattr)->nr;
1506         long val = simple_strtol(buf, NULL, 10);
1507         val = SENSORS_LIMIT(val, 0, 255);
1508
1509         mutex_lock(&data->update_lock);
1510         data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
1511         if (data->pwm_enable & (1 << (2 * pwm))) {
1512                 /* PWM mode */
1513         } else {
1514                 /* RPM mode */
1515                 if (val < 29)   /* Prevent negative numbers */
1516                         val = 255;
1517                 else
1518                         val = (255 - val) * 32 / val;
1519         }
1520         f71882fg_write8(data, F71882FG_REG_POINT_PWM(pwm, point), val);
1521         data->pwm_auto_point_pwm[pwm][point] = val;
1522         mutex_unlock(&data->update_lock);
1523
1524         return count;
1525 }
1526
1527 static ssize_t show_pwm_auto_point_temp_hyst(struct device *dev,
1528                                              struct device_attribute *devattr,
1529                                              char *buf)
1530 {
1531         int result = 0;
1532         struct f71882fg_data *data = f71882fg_update_device(dev);
1533         int nr = to_sensor_dev_attr_2(devattr)->index;
1534         int point = to_sensor_dev_attr_2(devattr)->nr;
1535
1536         mutex_lock(&data->update_lock);
1537         if (nr & 1)
1538                 result = data->pwm_auto_point_hyst[nr / 2] >> 4;
1539         else
1540                 result = data->pwm_auto_point_hyst[nr / 2] & 0x0f;
1541         result = 1000 * (data->pwm_auto_point_temp[nr][point] - result);
1542         mutex_unlock(&data->update_lock);
1543
1544         return sprintf(buf, "%d\n", result);
1545 }
1546
1547 static ssize_t store_pwm_auto_point_temp_hyst(struct device *dev,
1548                                               struct device_attribute *devattr,
1549                                               const char *buf, size_t count)
1550 {
1551         struct f71882fg_data *data = dev_get_drvdata(dev);
1552         int nr = to_sensor_dev_attr_2(devattr)->index;
1553         int point = to_sensor_dev_attr_2(devattr)->nr;
1554         long val = simple_strtol(buf, NULL, 10) / 1000;
1555         u8 reg;
1556
1557         mutex_lock(&data->update_lock);
1558         data->pwm_auto_point_temp[nr][point] =
1559                 f71882fg_read8(data, F71882FG_REG_POINT_TEMP(nr, point));
1560         val = SENSORS_LIMIT(val, data->pwm_auto_point_temp[nr][point] - 15,
1561                                 data->pwm_auto_point_temp[nr][point]);
1562         val = data->pwm_auto_point_temp[nr][point] - val;
1563
1564         reg = f71882fg_read8(data, F71882FG_REG_FAN_HYST(nr / 2));
1565         if (nr & 1)
1566                 reg = (reg & 0x0f) | (val << 4);
1567         else
1568                 reg = (reg & 0xf0) | val;
1569
1570         f71882fg_write8(data, F71882FG_REG_FAN_HYST(nr / 2), reg);
1571         data->pwm_auto_point_hyst[nr / 2] = reg;
1572         mutex_unlock(&data->update_lock);
1573
1574         return count;
1575 }
1576
1577 static ssize_t show_pwm_interpolate(struct device *dev,
1578                                     struct device_attribute *devattr, char *buf)
1579 {
1580         int result;
1581         struct f71882fg_data *data = f71882fg_update_device(dev);
1582         int nr = to_sensor_dev_attr_2(devattr)->index;
1583
1584         result = (data->pwm_auto_point_mapping[nr] >> 4) & 1;
1585
1586         return sprintf(buf, "%d\n", result);
1587 }
1588
1589 static ssize_t store_pwm_interpolate(struct device *dev,
1590                                      struct device_attribute *devattr,
1591                                      const char *buf, size_t count)
1592 {
1593         struct f71882fg_data *data = dev_get_drvdata(dev);
1594         int nr = to_sensor_dev_attr_2(devattr)->index;
1595         unsigned long val = simple_strtoul(buf, NULL, 10);
1596
1597         mutex_lock(&data->update_lock);
1598         data->pwm_auto_point_mapping[nr] =
1599                 f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(nr));
1600         if (val)
1601                 val = data->pwm_auto_point_mapping[nr] | (1 << 4);
1602         else
1603                 val = data->pwm_auto_point_mapping[nr] & (~(1 << 4));
1604         f71882fg_write8(data, F71882FG_REG_POINT_MAPPING(nr), val);
1605         data->pwm_auto_point_mapping[nr] = val;
1606         mutex_unlock(&data->update_lock);
1607
1608         return count;
1609 }
1610
1611 static ssize_t show_pwm_auto_point_channel(struct device *dev,
1612                                            struct device_attribute *devattr,
1613                                            char *buf)
1614 {
1615         int result;
1616         struct f71882fg_data *data = f71882fg_update_device(dev);
1617         int nr = to_sensor_dev_attr_2(devattr)->index;
1618         int temp_start = (data->type == f8000) ? 0 : 1;
1619
1620         result = 1 << ((data->pwm_auto_point_mapping[nr] & 3) - temp_start);
1621
1622         return sprintf(buf, "%d\n", result);
1623 }
1624
1625 static ssize_t store_pwm_auto_point_channel(struct device *dev,
1626                                             struct device_attribute *devattr,
1627                                             const char *buf, size_t count)
1628 {
1629         struct f71882fg_data *data = dev_get_drvdata(dev);
1630         int nr = to_sensor_dev_attr_2(devattr)->index;
1631         int temp_start = (data->type == f8000) ? 0 : 1;
1632         long val = simple_strtol(buf, NULL, 10);
1633
1634         switch (val) {
1635         case 1:
1636                 val = 0;
1637                 break;
1638         case 2:
1639                 val = 1;
1640                 break;
1641         case 4:
1642                 val = 2;
1643                 break;
1644         default:
1645                 return -EINVAL;
1646         }
1647         val += temp_start;
1648         mutex_lock(&data->update_lock);
1649         data->pwm_auto_point_mapping[nr] =
1650                 f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(nr));
1651         val = (data->pwm_auto_point_mapping[nr] & 0xfc) | val;
1652         f71882fg_write8(data, F71882FG_REG_POINT_MAPPING(nr), val);
1653         data->pwm_auto_point_mapping[nr] = val;
1654         mutex_unlock(&data->update_lock);
1655
1656         return count;
1657 }
1658
1659 static ssize_t show_pwm_auto_point_temp(struct device *dev,
1660                                         struct device_attribute *devattr,
1661                                         char *buf)
1662 {
1663         int result;
1664         struct f71882fg_data *data = f71882fg_update_device(dev);
1665         int pwm = to_sensor_dev_attr_2(devattr)->index;
1666         int point = to_sensor_dev_attr_2(devattr)->nr;
1667
1668         result = data->pwm_auto_point_temp[pwm][point];
1669         return sprintf(buf, "%d\n", 1000 * result);
1670 }
1671
1672 static ssize_t store_pwm_auto_point_temp(struct device *dev,
1673                                          struct device_attribute *devattr,
1674                                          const char *buf, size_t count)
1675 {
1676         struct f71882fg_data *data = dev_get_drvdata(dev);
1677         int pwm = to_sensor_dev_attr_2(devattr)->index;
1678         int point = to_sensor_dev_attr_2(devattr)->nr;
1679         long val = simple_strtol(buf, NULL, 10) / 1000;
1680         val = SENSORS_LIMIT(val, 0, 255);
1681
1682         mutex_lock(&data->update_lock);
1683         f71882fg_write8(data, F71882FG_REG_POINT_TEMP(pwm, point), val);
1684         data->pwm_auto_point_temp[pwm][point] = val;
1685         mutex_unlock(&data->update_lock);
1686
1687         return count;
1688 }
1689
1690 static ssize_t show_name(struct device *dev, struct device_attribute *devattr,
1691         char *buf)
1692 {
1693         struct f71882fg_data *data = dev_get_drvdata(dev);
1694         return sprintf(buf, "%s\n", f71882fg_names[data->type]);
1695 }
1696
1697 static int __devinit f71882fg_create_sysfs_files(struct platform_device *pdev,
1698         struct sensor_device_attribute_2 *attr, int count)
1699 {
1700         int err, i;
1701
1702         for (i = 0; i < count; i++) {
1703                 err = device_create_file(&pdev->dev, &attr[i].dev_attr);
1704                 if (err)
1705                         return err;
1706         }
1707         return 0;
1708 }
1709
1710 static int __devinit f71882fg_probe(struct platform_device *pdev)
1711 {
1712         struct f71882fg_data *data;
1713         struct f71882fg_sio_data *sio_data = pdev->dev.platform_data;
1714         int err, i, nr_fans = (sio_data->type == f71882fg) ? 4 : 3;
1715         u8 start_reg;
1716
1717         data = kzalloc(sizeof(struct f71882fg_data), GFP_KERNEL);
1718         if (!data)
1719                 return -ENOMEM;
1720
1721         data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start;
1722         data->type = sio_data->type;
1723         mutex_init(&data->update_lock);
1724         platform_set_drvdata(pdev, data);
1725
1726         start_reg = f71882fg_read8(data, F71882FG_REG_START);
1727         if (start_reg & 0x04) {
1728                 dev_warn(&pdev->dev, "Hardware monitor is powered down\n");
1729                 err = -ENODEV;
1730                 goto exit_free;
1731         }
1732         if (!(start_reg & 0x03)) {
1733                 dev_warn(&pdev->dev, "Hardware monitoring not activated\n");
1734                 err = -ENODEV;
1735                 goto exit_free;
1736         }
1737
1738         data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
1739         /* If it is a 71862 and the fan / pwm part is enabled sanity check
1740            the pwm settings */
1741         if (data->type == f71862fg && (start_reg & 0x02)) {
1742                 if ((data->pwm_enable & 0x15) != 0x15) {
1743                         dev_err(&pdev->dev,
1744                                 "Invalid (reserved) pwm settings: 0x%02x\n",
1745                                 (unsigned int)data->pwm_enable);
1746                         err = -ENODEV;
1747                         goto exit_free;
1748                 }
1749         }
1750
1751         /* Register sysfs interface files */
1752         err = device_create_file(&pdev->dev, &dev_attr_name);
1753         if (err)
1754                 goto exit_unregister_sysfs;
1755
1756         if (start_reg & 0x01) {
1757                 switch (data->type) {
1758                 case f71882fg:
1759                         err = f71882fg_create_sysfs_files(pdev,
1760                                         f71882fg_in_temp_attr,
1761                                         ARRAY_SIZE(f71882fg_in_temp_attr));
1762                         if (err)
1763                                 goto exit_unregister_sysfs;
1764                         /* fall through! */
1765                 case f71862fg:
1766                         err = f71882fg_create_sysfs_files(pdev,
1767                                         f718x2fg_in_temp_attr,
1768                                         ARRAY_SIZE(f718x2fg_in_temp_attr));
1769                         break;
1770                 case f8000:
1771                         err = f71882fg_create_sysfs_files(pdev,
1772                                         f8000_in_temp_attr,
1773                                         ARRAY_SIZE(f8000_in_temp_attr));
1774                         break;
1775                 }
1776                 if (err)
1777                         goto exit_unregister_sysfs;
1778         }
1779
1780         if (start_reg & 0x02) {
1781                 err = f71882fg_create_sysfs_files(pdev, fxxxx_fan_attr,
1782                                         ARRAY_SIZE(fxxxx_fan_attr));
1783                 if (err)
1784                         goto exit_unregister_sysfs;
1785
1786                 switch (data->type) {
1787                 case f71862fg:
1788                         err = f71882fg_create_sysfs_files(pdev,
1789                                         f71862fg_fan_attr,
1790                                         ARRAY_SIZE(f71862fg_fan_attr));
1791                         break;
1792                 case f71882fg:
1793                         err = f71882fg_create_sysfs_files(pdev,
1794                                         f71882fg_fan_attr,
1795                                         ARRAY_SIZE(f71882fg_fan_attr));
1796                         break;
1797                 case f8000:
1798                         err = f71882fg_create_sysfs_files(pdev,
1799                                         f8000_fan_attr,
1800                                         ARRAY_SIZE(f8000_fan_attr));
1801                         break;
1802                 }
1803                 if (err)
1804                         goto exit_unregister_sysfs;
1805
1806                 for (i = 0; i < nr_fans; i++)
1807                         dev_info(&pdev->dev, "Fan: %d is in %s mode\n", i + 1,
1808                                  (data->pwm_enable & (1 << 2 * i)) ?
1809                                  "duty-cycle" : "RPM");
1810         }
1811
1812         data->hwmon_dev = hwmon_device_register(&pdev->dev);
1813         if (IS_ERR(data->hwmon_dev)) {
1814                 err = PTR_ERR(data->hwmon_dev);
1815                 data->hwmon_dev = NULL;
1816                 goto exit_unregister_sysfs;
1817         }
1818
1819         return 0;
1820
1821 exit_unregister_sysfs:
1822         f71882fg_remove(pdev); /* Will unregister the sysfs files for us */
1823         return err; /* f71882fg_remove() also frees our data */
1824 exit_free:
1825         kfree(data);
1826         return err;
1827 }
1828
1829 static int f71882fg_remove(struct platform_device *pdev)
1830 {
1831         int i;
1832         struct f71882fg_data *data = platform_get_drvdata(pdev);
1833
1834         platform_set_drvdata(pdev, NULL);
1835         if (data->hwmon_dev)
1836                 hwmon_device_unregister(data->hwmon_dev);
1837
1838         /* Note we are not looping over all attr arrays we have as the ones
1839            below are supersets of the ones skipped. */
1840         device_remove_file(&pdev->dev, &dev_attr_name);
1841
1842         for (i = 0; i < ARRAY_SIZE(f718x2fg_in_temp_attr); i++)
1843                 device_remove_file(&pdev->dev,
1844                                         &f718x2fg_in_temp_attr[i].dev_attr);
1845
1846         for (i = 0; i < ARRAY_SIZE(f71882fg_in_temp_attr); i++)
1847                 device_remove_file(&pdev->dev,
1848                                         &f71882fg_in_temp_attr[i].dev_attr);
1849
1850         for (i = 0; i < ARRAY_SIZE(fxxxx_fan_attr); i++)
1851                 device_remove_file(&pdev->dev, &fxxxx_fan_attr[i].dev_attr);
1852
1853         for (i = 0; i < ARRAY_SIZE(f71882fg_fan_attr); i++)
1854                 device_remove_file(&pdev->dev, &f71882fg_fan_attr[i].dev_attr);
1855
1856         for (i = 0; i < ARRAY_SIZE(f8000_fan_attr); i++)
1857                 device_remove_file(&pdev->dev, &f8000_fan_attr[i].dev_attr);
1858
1859         kfree(data);
1860
1861         return 0;
1862 }
1863
1864 static int __init f71882fg_find(int sioaddr, unsigned short *address,
1865         struct f71882fg_sio_data *sio_data)
1866 {
1867         int err = -ENODEV;
1868         u16 devid;
1869
1870         superio_enter(sioaddr);
1871
1872         devid = superio_inw(sioaddr, SIO_REG_MANID);
1873         if (devid != SIO_FINTEK_ID) {
1874                 pr_debug(DRVNAME ": Not a Fintek device\n");
1875                 goto exit;
1876         }
1877
1878         devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID);
1879         switch (devid) {
1880         case SIO_F71862_ID:
1881                 sio_data->type = f71862fg;
1882                 break;
1883         case SIO_F71882_ID:
1884                 sio_data->type = f71882fg;
1885                 break;
1886         case SIO_F8000_ID:
1887                 sio_data->type = f8000;
1888                 break;
1889         default:
1890                 printk(KERN_INFO DRVNAME ": Unsupported Fintek device\n");
1891                 goto exit;
1892         }
1893
1894         superio_select(sioaddr, SIO_F71882FG_LD_HWM);
1895         if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) {
1896                 printk(KERN_WARNING DRVNAME ": Device not activated\n");
1897                 goto exit;
1898         }
1899
1900         *address = superio_inw(sioaddr, SIO_REG_ADDR);
1901         if (*address == 0)
1902         {
1903                 printk(KERN_WARNING DRVNAME ": Base address not set\n");
1904                 goto exit;
1905         }
1906         *address &= ~(REGION_LENGTH - 1);       /* Ignore 3 LSB */
1907
1908         err = 0;
1909         printk(KERN_INFO DRVNAME ": Found %s chip at %#x, revision %d\n",
1910                 f71882fg_names[sio_data->type], (unsigned int)*address,
1911                 (int)superio_inb(sioaddr, SIO_REG_DEVREV));
1912 exit:
1913         superio_exit(sioaddr);
1914         return err;
1915 }
1916
1917 static int __init f71882fg_device_add(unsigned short address,
1918         const struct f71882fg_sio_data *sio_data)
1919 {
1920         struct resource res = {
1921                 .start  = address,
1922                 .end    = address + REGION_LENGTH - 1,
1923                 .flags  = IORESOURCE_IO,
1924         };
1925         int err;
1926
1927         f71882fg_pdev = platform_device_alloc(DRVNAME, address);
1928         if (!f71882fg_pdev)
1929                 return -ENOMEM;
1930
1931         res.name = f71882fg_pdev->name;
1932         err = acpi_check_resource_conflict(&res);
1933         if (err)
1934                 goto exit_device_put;
1935
1936         err = platform_device_add_resources(f71882fg_pdev, &res, 1);
1937         if (err) {
1938                 printk(KERN_ERR DRVNAME ": Device resource addition failed\n");
1939                 goto exit_device_put;
1940         }
1941
1942         err = platform_device_add_data(f71882fg_pdev, sio_data,
1943                                        sizeof(struct f71882fg_sio_data));
1944         if (err) {
1945                 printk(KERN_ERR DRVNAME ": Platform data allocation failed\n");
1946                 goto exit_device_put;
1947         }
1948
1949         err = platform_device_add(f71882fg_pdev);
1950         if (err) {
1951                 printk(KERN_ERR DRVNAME ": Device addition failed\n");
1952                 goto exit_device_put;
1953         }
1954
1955         return 0;
1956
1957 exit_device_put:
1958         platform_device_put(f71882fg_pdev);
1959
1960         return err;
1961 }
1962
1963 static int __init f71882fg_init(void)
1964 {
1965         int err = -ENODEV;
1966         unsigned short address;
1967         struct f71882fg_sio_data sio_data;
1968
1969         memset(&sio_data, 0, sizeof(sio_data));
1970
1971         if (f71882fg_find(0x2e, &address, &sio_data) &&
1972             f71882fg_find(0x4e, &address, &sio_data))
1973                 goto exit;
1974
1975         err = platform_driver_register(&f71882fg_driver);
1976         if (err)
1977                 goto exit;
1978
1979         err = f71882fg_device_add(address, &sio_data);
1980         if (err)
1981                 goto exit_driver;
1982
1983         return 0;
1984
1985 exit_driver:
1986         platform_driver_unregister(&f71882fg_driver);
1987 exit:
1988         return err;
1989 }
1990
1991 static void __exit f71882fg_exit(void)
1992 {
1993         platform_device_unregister(f71882fg_pdev);
1994         platform_driver_unregister(&f71882fg_driver);
1995 }
1996
1997 MODULE_DESCRIPTION("F71882FG Hardware Monitoring Driver");
1998 MODULE_AUTHOR("Hans Edgington, Hans de Goede (hdegoede@redhat.com)");
1999 MODULE_LICENSE("GPL");
2000
2001 module_init(f71882fg_init);
2002 module_exit(f71882fg_exit);