1 /***************************************************************************
2 * Copyright (C) 2006 by Hans Edgington <hans@edgington.nl> *
3 * Copyright (C) 2007-2009 Hans de Goede <hdegoede@redhat.com> *
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. *
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. *
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 ***************************************************************************/
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>
31 #include <linux/acpi.h>
33 #define DRVNAME "f71882fg"
35 #define SIO_F71858FG_LD_HWM 0x02 /* Hardware monitor logical device */
36 #define SIO_F71882FG_LD_HWM 0x04 /* Hardware monitor logical device */
37 #define SIO_UNLOCK_KEY 0x87 /* Key to enable Super-I/O */
38 #define SIO_LOCK_KEY 0xAA /* Key to diasble Super-I/O */
40 #define SIO_REG_LDSEL 0x07 /* Logical device select */
41 #define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */
42 #define SIO_REG_DEVREV 0x22 /* Device revision */
43 #define SIO_REG_MANID 0x23 /* Fintek ID (2 bytes) */
44 #define SIO_REG_ENABLE 0x30 /* Logical device enable */
45 #define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */
47 #define SIO_FINTEK_ID 0x1934 /* Manufacturers ID */
48 #define SIO_F71808_ID 0x0901 /* Chipset ID */
49 #define SIO_F71858_ID 0x0507 /* Chipset ID */
50 #define SIO_F71862_ID 0x0601 /* Chipset ID */
51 #define SIO_F71882_ID 0x0541 /* Chipset ID */
52 #define SIO_F71889_ID 0x0723 /* Chipset ID */
53 #define SIO_F8000_ID 0x0581 /* Chipset ID */
55 #define REGION_LENGTH 8
56 #define ADDR_REG_OFFSET 5
57 #define DATA_REG_OFFSET 6
59 #define F71882FG_REG_PECI 0x0A
61 #define F71882FG_REG_IN_STATUS 0x12 /* f71882fg only */
62 #define F71882FG_REG_IN_BEEP 0x13 /* f71882fg only */
63 #define F71882FG_REG_IN(nr) (0x20 + (nr))
64 #define F71882FG_REG_IN1_HIGH 0x32 /* f71882fg only */
66 #define F71882FG_REG_FAN(nr) (0xA0 + (16 * (nr)))
67 #define F71882FG_REG_FAN_TARGET(nr) (0xA2 + (16 * (nr)))
68 #define F71882FG_REG_FAN_FULL_SPEED(nr) (0xA4 + (16 * (nr)))
69 #define F71882FG_REG_FAN_STATUS 0x92
70 #define F71882FG_REG_FAN_BEEP 0x93
72 #define F71882FG_REG_TEMP(nr) (0x70 + 2 * (nr))
73 #define F71882FG_REG_TEMP_OVT(nr) (0x80 + 2 * (nr))
74 #define F71882FG_REG_TEMP_HIGH(nr) (0x81 + 2 * (nr))
75 #define F71882FG_REG_TEMP_STATUS 0x62
76 #define F71882FG_REG_TEMP_BEEP 0x63
77 #define F71882FG_REG_TEMP_CONFIG 0x69
78 #define F71882FG_REG_TEMP_HYST(nr) (0x6C + (nr))
79 #define F71882FG_REG_TEMP_TYPE 0x6B
80 #define F71882FG_REG_TEMP_DIODE_OPEN 0x6F
82 #define F71882FG_REG_PWM(nr) (0xA3 + (16 * (nr)))
83 #define F71882FG_REG_PWM_TYPE 0x94
84 #define F71882FG_REG_PWM_ENABLE 0x96
86 #define F71882FG_REG_FAN_HYST(nr) (0x98 + (nr))
88 #define F71882FG_REG_POINT_PWM(pwm, point) (0xAA + (point) + (16 * (pwm)))
89 #define F71882FG_REG_POINT_TEMP(pwm, point) (0xA6 + (point) + (16 * (pwm)))
90 #define F71882FG_REG_POINT_MAPPING(nr) (0xAF + 16 * (nr))
92 #define F71882FG_REG_START 0x01
94 #define FAN_MIN_DETECT 366 /* Lowest detectable fanspeed */
96 static unsigned short force_id;
97 module_param(force_id, ushort, 0);
98 MODULE_PARM_DESC(force_id, "Override the detected device ID");
100 enum chips { f71808fg, f71858fg, f71862fg, f71882fg, f71889fg, f8000 };
102 static const char *f71882fg_names[] = {
111 static struct platform_device *f71882fg_pdev;
113 /* Super-I/O Function prototypes */
114 static inline int superio_inb(int base, int reg);
115 static inline int superio_inw(int base, int reg);
116 static inline void superio_enter(int base);
117 static inline void superio_select(int base, int ld);
118 static inline void superio_exit(int base);
120 struct f71882fg_sio_data {
124 struct f71882fg_data {
127 struct device *hwmon_dev;
129 struct mutex update_lock;
130 int temp_start; /* temp numbering start (0 or 1) */
131 char valid; /* !=0 if following fields are valid */
132 unsigned long last_updated; /* In jiffies */
133 unsigned long last_limits; /* In jiffies */
135 /* Register Values */
142 u16 fan_full_speed[4];
145 /* Note: all models have only 3 temperature channels, but on some
146 they are addressed as 0-2 and on others as 1-3, so for coding
147 convenience we reserve space for 4 channels */
151 u8 temp_hyst[2]; /* 2 hysts stored per reg */
159 u8 pwm_auto_point_hyst[2];
160 u8 pwm_auto_point_mapping[4];
161 u8 pwm_auto_point_pwm[4][5];
162 s8 pwm_auto_point_temp[4][4];
166 static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
168 static ssize_t show_in_max(struct device *dev, struct device_attribute
169 *devattr, char *buf);
170 static ssize_t store_in_max(struct device *dev, struct device_attribute
171 *devattr, const char *buf, size_t count);
172 static ssize_t show_in_beep(struct device *dev, struct device_attribute
173 *devattr, char *buf);
174 static ssize_t store_in_beep(struct device *dev, struct device_attribute
175 *devattr, const char *buf, size_t count);
176 static ssize_t show_in_alarm(struct device *dev, struct device_attribute
177 *devattr, char *buf);
179 static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
181 static ssize_t show_fan_full_speed(struct device *dev,
182 struct device_attribute *devattr, char *buf);
183 static ssize_t store_fan_full_speed(struct device *dev,
184 struct device_attribute *devattr, const char *buf, size_t count);
185 static ssize_t show_fan_beep(struct device *dev, struct device_attribute
186 *devattr, char *buf);
187 static ssize_t store_fan_beep(struct device *dev, struct device_attribute
188 *devattr, const char *buf, size_t count);
189 static ssize_t show_fan_alarm(struct device *dev, struct device_attribute
190 *devattr, char *buf);
192 static ssize_t show_temp(struct device *dev, struct device_attribute
193 *devattr, char *buf);
194 static ssize_t show_temp_max(struct device *dev, struct device_attribute
195 *devattr, char *buf);
196 static ssize_t store_temp_max(struct device *dev, struct device_attribute
197 *devattr, const char *buf, size_t count);
198 static ssize_t show_temp_max_hyst(struct device *dev, struct device_attribute
199 *devattr, char *buf);
200 static ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute
201 *devattr, const char *buf, size_t count);
202 static ssize_t show_temp_crit(struct device *dev, struct device_attribute
203 *devattr, char *buf);
204 static ssize_t store_temp_crit(struct device *dev, struct device_attribute
205 *devattr, const char *buf, size_t count);
206 static ssize_t show_temp_crit_hyst(struct device *dev, struct device_attribute
207 *devattr, char *buf);
208 static ssize_t show_temp_type(struct device *dev, struct device_attribute
209 *devattr, char *buf);
210 static ssize_t show_temp_beep(struct device *dev, struct device_attribute
211 *devattr, char *buf);
212 static ssize_t store_temp_beep(struct device *dev, struct device_attribute
213 *devattr, const char *buf, size_t count);
214 static ssize_t show_temp_alarm(struct device *dev, struct device_attribute
215 *devattr, char *buf);
216 static ssize_t show_temp_fault(struct device *dev, struct device_attribute
217 *devattr, char *buf);
218 /* PWM and Auto point control */
219 static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr,
221 static ssize_t store_pwm(struct device *dev, struct device_attribute *devattr,
222 const char *buf, size_t count);
223 static ssize_t show_pwm_enable(struct device *dev,
224 struct device_attribute *devattr, char *buf);
225 static ssize_t store_pwm_enable(struct device *dev,
226 struct device_attribute *devattr, const char *buf, size_t count);
227 static ssize_t show_pwm_interpolate(struct device *dev,
228 struct device_attribute *devattr, char *buf);
229 static ssize_t store_pwm_interpolate(struct device *dev,
230 struct device_attribute *devattr, const char *buf, size_t count);
231 static ssize_t show_pwm_auto_point_channel(struct device *dev,
232 struct device_attribute *devattr, char *buf);
233 static ssize_t store_pwm_auto_point_channel(struct device *dev,
234 struct device_attribute *devattr, const char *buf, size_t count);
235 static ssize_t show_pwm_auto_point_temp_hyst(struct device *dev,
236 struct device_attribute *devattr, char *buf);
237 static ssize_t store_pwm_auto_point_temp_hyst(struct device *dev,
238 struct device_attribute *devattr, const char *buf, size_t count);
239 static ssize_t show_pwm_auto_point_pwm(struct device *dev,
240 struct device_attribute *devattr, char *buf);
241 static ssize_t store_pwm_auto_point_pwm(struct device *dev,
242 struct device_attribute *devattr, const char *buf, size_t count);
243 static ssize_t show_pwm_auto_point_temp(struct device *dev,
244 struct device_attribute *devattr, char *buf);
245 static ssize_t store_pwm_auto_point_temp(struct device *dev,
246 struct device_attribute *devattr, const char *buf, size_t count);
248 static ssize_t show_name(struct device *dev, struct device_attribute *devattr,
251 static int __devinit f71882fg_probe(struct platform_device * pdev);
252 static int f71882fg_remove(struct platform_device *pdev);
254 static struct platform_driver f71882fg_driver = {
256 .owner = THIS_MODULE,
259 .probe = f71882fg_probe,
260 .remove = f71882fg_remove,
263 static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
265 /* Temp and in attr for the f71858fg, the f71858fg is special as it
266 has its temperature indexes start at 0 (the others start at 1) and
267 it only has 3 voltage inputs */
268 static struct sensor_device_attribute_2 f71858fg_in_temp_attr[] = {
269 SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
270 SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
271 SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
272 SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0),
273 SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max,
274 store_temp_max, 0, 0),
275 SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
276 store_temp_max_hyst, 0, 0),
277 SENSOR_ATTR_2(temp1_max_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 0),
278 SENSOR_ATTR_2(temp1_crit, S_IRUGO|S_IWUSR, show_temp_crit,
279 store_temp_crit, 0, 0),
280 SENSOR_ATTR_2(temp1_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
282 SENSOR_ATTR_2(temp1_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 4),
283 SENSOR_ATTR_2(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0, 0),
284 SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1),
285 SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_max,
286 store_temp_max, 0, 1),
287 SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
288 store_temp_max_hyst, 0, 1),
289 SENSOR_ATTR_2(temp2_max_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 1),
290 SENSOR_ATTR_2(temp2_crit, S_IRUGO|S_IWUSR, show_temp_crit,
291 store_temp_crit, 0, 1),
292 SENSOR_ATTR_2(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
294 SENSOR_ATTR_2(temp2_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5),
295 SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 1),
296 SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 1),
297 SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2),
298 SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max,
299 store_temp_max, 0, 2),
300 SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
301 store_temp_max_hyst, 0, 2),
302 SENSOR_ATTR_2(temp3_max_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 2),
303 SENSOR_ATTR_2(temp3_crit, S_IRUGO|S_IWUSR, show_temp_crit,
304 store_temp_crit, 0, 2),
305 SENSOR_ATTR_2(temp3_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
307 SENSOR_ATTR_2(temp3_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6),
308 SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
311 /* In attr common to the f71862fg, f71882fg and f71889fg */
312 static struct sensor_device_attribute_2 fxxxx_in_attr[] = {
313 SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
314 SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
315 SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
316 SENSOR_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 0, 3),
317 SENSOR_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 0, 4),
318 SENSOR_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 0, 5),
319 SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 6),
320 SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 7),
321 SENSOR_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 0, 8),
324 /* In attr for the f71808fg */
325 static struct sensor_device_attribute_2 f71808_in_attr[] = {
326 SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
327 SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
328 SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
329 SENSOR_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 0, 3),
330 SENSOR_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 0, 4),
331 SENSOR_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 0, 5),
332 SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 7),
333 SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 8),
336 /* Temp attr common to the f71808fg, f71862fg, f71882fg and f71889fg */
337 static struct sensor_device_attribute_2 fxxxx_temp_attr[] = {
338 SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 1),
339 SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max,
340 store_temp_max, 0, 1),
341 SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
342 store_temp_max_hyst, 0, 1),
343 /* Should really be temp1_max_alarm, but older versions did not handle
344 the max and crit alarms separately and lm_sensors v2 depends on the
345 presence of temp#_alarm files. The same goes for temp2/3 _alarm. */
346 SENSOR_ATTR_2(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 1),
347 SENSOR_ATTR_2(temp1_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
348 store_temp_beep, 0, 1),
349 SENSOR_ATTR_2(temp1_crit, S_IRUGO|S_IWUSR, show_temp_crit,
350 store_temp_crit, 0, 1),
351 SENSOR_ATTR_2(temp1_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
353 SENSOR_ATTR_2(temp1_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5),
354 SENSOR_ATTR_2(temp1_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
355 store_temp_beep, 0, 5),
356 SENSOR_ATTR_2(temp1_type, S_IRUGO, show_temp_type, NULL, 0, 1),
357 SENSOR_ATTR_2(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0, 1),
358 SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 2),
359 SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_max,
360 store_temp_max, 0, 2),
361 SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
362 store_temp_max_hyst, 0, 2),
363 /* Should be temp2_max_alarm, see temp1_alarm note */
364 SENSOR_ATTR_2(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 2),
365 SENSOR_ATTR_2(temp2_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
366 store_temp_beep, 0, 2),
367 SENSOR_ATTR_2(temp2_crit, S_IRUGO|S_IWUSR, show_temp_crit,
368 store_temp_crit, 0, 2),
369 SENSOR_ATTR_2(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
371 SENSOR_ATTR_2(temp2_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6),
372 SENSOR_ATTR_2(temp2_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
373 store_temp_beep, 0, 6),
374 SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 2),
375 SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
378 /* Temp and in attr common to the f71862fg, f71882fg and f71889fg */
379 static struct sensor_device_attribute_2 f71862_temp_attr[] = {
380 SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 3),
381 SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max,
382 store_temp_max, 0, 3),
383 SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
384 store_temp_max_hyst, 0, 3),
385 /* Should be temp3_max_alarm, see temp1_alarm note */
386 SENSOR_ATTR_2(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 3),
387 SENSOR_ATTR_2(temp3_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
388 store_temp_beep, 0, 3),
389 SENSOR_ATTR_2(temp3_crit, S_IRUGO|S_IWUSR, show_temp_crit,
390 store_temp_crit, 0, 3),
391 SENSOR_ATTR_2(temp3_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
393 SENSOR_ATTR_2(temp3_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 7),
394 SENSOR_ATTR_2(temp3_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
395 store_temp_beep, 0, 7),
396 SENSOR_ATTR_2(temp3_type, S_IRUGO, show_temp_type, NULL, 0, 3),
397 SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 3),
400 /* For models with in1 alarm capability */
401 static struct sensor_device_attribute_2 fxxxx_in1_alarm_attr[] = {
402 SENSOR_ATTR_2(in1_max, S_IRUGO|S_IWUSR, show_in_max, store_in_max,
404 SENSOR_ATTR_2(in1_beep, S_IRUGO|S_IWUSR, show_in_beep, store_in_beep,
406 SENSOR_ATTR_2(in1_alarm, S_IRUGO, show_in_alarm, NULL, 0, 1),
409 /* Temp and in attr for the f8000
410 Note on the f8000 temp_ovt (crit) is used as max, and temp_high (max)
411 is used as hysteresis value to clear alarms
412 Also like the f71858fg its temperature indexes start at 0
414 static struct sensor_device_attribute_2 f8000_in_temp_attr[] = {
415 SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
416 SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
417 SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
418 SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0),
419 SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_crit,
420 store_temp_crit, 0, 0),
421 SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max,
422 store_temp_max, 0, 0),
423 SENSOR_ATTR_2(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 4),
424 SENSOR_ATTR_2(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0, 0),
425 SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1),
426 SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_crit,
427 store_temp_crit, 0, 1),
428 SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max,
429 store_temp_max, 0, 1),
430 SENSOR_ATTR_2(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5),
431 SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 1),
432 SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 1),
433 SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2),
434 SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_crit,
435 store_temp_crit, 0, 2),
436 SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max,
437 store_temp_max, 0, 2),
438 SENSOR_ATTR_2(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6),
439 SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
442 /* Fan / PWM attr common to all models */
443 static struct sensor_device_attribute_2 fxxxx_fan_attr[4][6] = { {
444 SENSOR_ATTR_2(fan1_input, S_IRUGO, show_fan, NULL, 0, 0),
445 SENSOR_ATTR_2(fan1_full_speed, S_IRUGO|S_IWUSR,
447 store_fan_full_speed, 0, 0),
448 SENSOR_ATTR_2(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 0),
449 SENSOR_ATTR_2(pwm1, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 0),
450 SENSOR_ATTR_2(pwm1_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
451 store_pwm_enable, 0, 0),
452 SENSOR_ATTR_2(pwm1_interpolate, S_IRUGO|S_IWUSR,
453 show_pwm_interpolate, store_pwm_interpolate, 0, 0),
455 SENSOR_ATTR_2(fan2_input, S_IRUGO, show_fan, NULL, 0, 1),
456 SENSOR_ATTR_2(fan2_full_speed, S_IRUGO|S_IWUSR,
458 store_fan_full_speed, 0, 1),
459 SENSOR_ATTR_2(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 1),
460 SENSOR_ATTR_2(pwm2, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 1),
461 SENSOR_ATTR_2(pwm2_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
462 store_pwm_enable, 0, 1),
463 SENSOR_ATTR_2(pwm2_interpolate, S_IRUGO|S_IWUSR,
464 show_pwm_interpolate, store_pwm_interpolate, 0, 1),
466 SENSOR_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 0, 2),
467 SENSOR_ATTR_2(fan3_full_speed, S_IRUGO|S_IWUSR,
469 store_fan_full_speed, 0, 2),
470 SENSOR_ATTR_2(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 2),
471 SENSOR_ATTR_2(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 2),
472 SENSOR_ATTR_2(pwm3_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
473 store_pwm_enable, 0, 2),
474 SENSOR_ATTR_2(pwm3_interpolate, S_IRUGO|S_IWUSR,
475 show_pwm_interpolate, store_pwm_interpolate, 0, 2),
477 SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
478 SENSOR_ATTR_2(fan4_full_speed, S_IRUGO|S_IWUSR,
480 store_fan_full_speed, 0, 3),
481 SENSOR_ATTR_2(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 3),
482 SENSOR_ATTR_2(pwm4, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 3),
483 SENSOR_ATTR_2(pwm4_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
484 store_pwm_enable, 0, 3),
485 SENSOR_ATTR_2(pwm4_interpolate, S_IRUGO|S_IWUSR,
486 show_pwm_interpolate, store_pwm_interpolate, 0, 3),
489 /* Attr for models which can beep on Fan alarm */
490 static struct sensor_device_attribute_2 fxxxx_fan_beep_attr[] = {
491 SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep,
492 store_fan_beep, 0, 0),
493 SENSOR_ATTR_2(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep,
494 store_fan_beep, 0, 1),
495 SENSOR_ATTR_2(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep,
496 store_fan_beep, 0, 2),
497 SENSOR_ATTR_2(fan4_beep, S_IRUGO|S_IWUSR, show_fan_beep,
498 store_fan_beep, 0, 3),
501 /* PWM attr for the f71862fg, fewer pwms and fewer zones per pwm than the
502 f71858fg / f71882fg / f71889fg */
503 static struct sensor_device_attribute_2 f71862fg_auto_pwm_attr[] = {
504 SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
505 show_pwm_auto_point_channel,
506 store_pwm_auto_point_channel, 0, 0),
507 SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,
508 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
510 SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO|S_IWUSR,
511 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
513 SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IRUGO|S_IWUSR,
514 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
516 SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IRUGO|S_IWUSR,
517 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
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,
523 SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO,
524 show_pwm_auto_point_temp_hyst, NULL, 3, 0),
526 SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,
527 show_pwm_auto_point_channel,
528 store_pwm_auto_point_channel, 0, 1),
529 SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR,
530 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
532 SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO|S_IWUSR,
533 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
535 SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IRUGO|S_IWUSR,
536 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
538 SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IRUGO|S_IWUSR,
539 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
541 SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
542 show_pwm_auto_point_temp_hyst,
543 store_pwm_auto_point_temp_hyst,
545 SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO,
546 show_pwm_auto_point_temp_hyst, NULL, 3, 1),
548 SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
549 show_pwm_auto_point_channel,
550 store_pwm_auto_point_channel, 0, 2),
551 SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR,
552 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
554 SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO|S_IWUSR,
555 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
557 SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IRUGO|S_IWUSR,
558 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
560 SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IRUGO|S_IWUSR,
561 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
563 SENSOR_ATTR_2(pwm3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
564 show_pwm_auto_point_temp_hyst,
565 store_pwm_auto_point_temp_hyst,
567 SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst, S_IRUGO,
568 show_pwm_auto_point_temp_hyst, NULL, 3, 2),
571 /* PWM attr common to the f71858fg, f71882fg and f71889fg */
572 static struct sensor_device_attribute_2 fxxxx_auto_pwm_attr[4][14] = { {
573 SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
574 show_pwm_auto_point_channel,
575 store_pwm_auto_point_channel, 0, 0),
576 SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,
577 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
579 SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO|S_IWUSR,
580 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
582 SENSOR_ATTR_2(pwm1_auto_point3_pwm, S_IRUGO|S_IWUSR,
583 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
585 SENSOR_ATTR_2(pwm1_auto_point4_pwm, S_IRUGO|S_IWUSR,
586 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
588 SENSOR_ATTR_2(pwm1_auto_point5_pwm, S_IRUGO|S_IWUSR,
589 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
591 SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IRUGO|S_IWUSR,
592 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
594 SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IRUGO|S_IWUSR,
595 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
597 SENSOR_ATTR_2(pwm1_auto_point3_temp, S_IRUGO|S_IWUSR,
598 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
600 SENSOR_ATTR_2(pwm1_auto_point4_temp, S_IRUGO|S_IWUSR,
601 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
603 SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
604 show_pwm_auto_point_temp_hyst,
605 store_pwm_auto_point_temp_hyst,
607 SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO,
608 show_pwm_auto_point_temp_hyst, NULL, 1, 0),
609 SENSOR_ATTR_2(pwm1_auto_point3_temp_hyst, S_IRUGO,
610 show_pwm_auto_point_temp_hyst, NULL, 2, 0),
611 SENSOR_ATTR_2(pwm1_auto_point4_temp_hyst, S_IRUGO,
612 show_pwm_auto_point_temp_hyst, NULL, 3, 0),
614 SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,
615 show_pwm_auto_point_channel,
616 store_pwm_auto_point_channel, 0, 1),
617 SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR,
618 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
620 SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO|S_IWUSR,
621 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
623 SENSOR_ATTR_2(pwm2_auto_point3_pwm, S_IRUGO|S_IWUSR,
624 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
626 SENSOR_ATTR_2(pwm2_auto_point4_pwm, S_IRUGO|S_IWUSR,
627 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
629 SENSOR_ATTR_2(pwm2_auto_point5_pwm, S_IRUGO|S_IWUSR,
630 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
632 SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IRUGO|S_IWUSR,
633 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
635 SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IRUGO|S_IWUSR,
636 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
638 SENSOR_ATTR_2(pwm2_auto_point3_temp, S_IRUGO|S_IWUSR,
639 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
641 SENSOR_ATTR_2(pwm2_auto_point4_temp, S_IRUGO|S_IWUSR,
642 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
644 SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
645 show_pwm_auto_point_temp_hyst,
646 store_pwm_auto_point_temp_hyst,
648 SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO,
649 show_pwm_auto_point_temp_hyst, NULL, 1, 1),
650 SENSOR_ATTR_2(pwm2_auto_point3_temp_hyst, S_IRUGO,
651 show_pwm_auto_point_temp_hyst, NULL, 2, 1),
652 SENSOR_ATTR_2(pwm2_auto_point4_temp_hyst, S_IRUGO,
653 show_pwm_auto_point_temp_hyst, NULL, 3, 1),
655 SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
656 show_pwm_auto_point_channel,
657 store_pwm_auto_point_channel, 0, 2),
658 SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR,
659 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
661 SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO|S_IWUSR,
662 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
664 SENSOR_ATTR_2(pwm3_auto_point3_pwm, S_IRUGO|S_IWUSR,
665 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
667 SENSOR_ATTR_2(pwm3_auto_point4_pwm, S_IRUGO|S_IWUSR,
668 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
670 SENSOR_ATTR_2(pwm3_auto_point5_pwm, S_IRUGO|S_IWUSR,
671 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
673 SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IRUGO|S_IWUSR,
674 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
676 SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IRUGO|S_IWUSR,
677 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
679 SENSOR_ATTR_2(pwm3_auto_point3_temp, S_IRUGO|S_IWUSR,
680 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
682 SENSOR_ATTR_2(pwm3_auto_point4_temp, S_IRUGO|S_IWUSR,
683 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
685 SENSOR_ATTR_2(pwm3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
686 show_pwm_auto_point_temp_hyst,
687 store_pwm_auto_point_temp_hyst,
689 SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst, S_IRUGO,
690 show_pwm_auto_point_temp_hyst, NULL, 1, 2),
691 SENSOR_ATTR_2(pwm3_auto_point3_temp_hyst, S_IRUGO,
692 show_pwm_auto_point_temp_hyst, NULL, 2, 2),
693 SENSOR_ATTR_2(pwm3_auto_point4_temp_hyst, S_IRUGO,
694 show_pwm_auto_point_temp_hyst, NULL, 3, 2),
696 SENSOR_ATTR_2(pwm4_auto_channels_temp, S_IRUGO|S_IWUSR,
697 show_pwm_auto_point_channel,
698 store_pwm_auto_point_channel, 0, 3),
699 SENSOR_ATTR_2(pwm4_auto_point1_pwm, S_IRUGO|S_IWUSR,
700 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
702 SENSOR_ATTR_2(pwm4_auto_point2_pwm, S_IRUGO|S_IWUSR,
703 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
705 SENSOR_ATTR_2(pwm4_auto_point3_pwm, S_IRUGO|S_IWUSR,
706 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
708 SENSOR_ATTR_2(pwm4_auto_point4_pwm, S_IRUGO|S_IWUSR,
709 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
711 SENSOR_ATTR_2(pwm4_auto_point5_pwm, S_IRUGO|S_IWUSR,
712 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
714 SENSOR_ATTR_2(pwm4_auto_point1_temp, S_IRUGO|S_IWUSR,
715 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
717 SENSOR_ATTR_2(pwm4_auto_point2_temp, S_IRUGO|S_IWUSR,
718 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
720 SENSOR_ATTR_2(pwm4_auto_point3_temp, S_IRUGO|S_IWUSR,
721 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
723 SENSOR_ATTR_2(pwm4_auto_point4_temp, S_IRUGO|S_IWUSR,
724 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
726 SENSOR_ATTR_2(pwm4_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
727 show_pwm_auto_point_temp_hyst,
728 store_pwm_auto_point_temp_hyst,
730 SENSOR_ATTR_2(pwm4_auto_point2_temp_hyst, S_IRUGO,
731 show_pwm_auto_point_temp_hyst, NULL, 1, 3),
732 SENSOR_ATTR_2(pwm4_auto_point3_temp_hyst, S_IRUGO,
733 show_pwm_auto_point_temp_hyst, NULL, 2, 3),
734 SENSOR_ATTR_2(pwm4_auto_point4_temp_hyst, S_IRUGO,
735 show_pwm_auto_point_temp_hyst, NULL, 3, 3),
738 /* Fan attr specific to the f8000 (4th fan input can only measure speed) */
739 static struct sensor_device_attribute_2 f8000_fan_attr[] = {
740 SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
743 /* PWM attr for the f8000, zones mapped to temp instead of to pwm!
744 Also the register block at offset A0 maps to TEMP1 (so our temp2, as the
745 F8000 starts counting temps at 0), B0 maps the TEMP2 and C0 maps to TEMP0 */
746 static struct sensor_device_attribute_2 f8000_auto_pwm_attr[] = {
747 SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
748 show_pwm_auto_point_channel,
749 store_pwm_auto_point_channel, 0, 0),
750 SENSOR_ATTR_2(temp1_auto_point1_pwm, S_IRUGO|S_IWUSR,
751 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
753 SENSOR_ATTR_2(temp1_auto_point2_pwm, S_IRUGO|S_IWUSR,
754 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
756 SENSOR_ATTR_2(temp1_auto_point3_pwm, S_IRUGO|S_IWUSR,
757 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
759 SENSOR_ATTR_2(temp1_auto_point4_pwm, S_IRUGO|S_IWUSR,
760 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
762 SENSOR_ATTR_2(temp1_auto_point5_pwm, S_IRUGO|S_IWUSR,
763 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
765 SENSOR_ATTR_2(temp1_auto_point1_temp, S_IRUGO|S_IWUSR,
766 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
768 SENSOR_ATTR_2(temp1_auto_point2_temp, S_IRUGO|S_IWUSR,
769 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
771 SENSOR_ATTR_2(temp1_auto_point3_temp, S_IRUGO|S_IWUSR,
772 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
774 SENSOR_ATTR_2(temp1_auto_point4_temp, S_IRUGO|S_IWUSR,
775 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
777 SENSOR_ATTR_2(temp1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
778 show_pwm_auto_point_temp_hyst,
779 store_pwm_auto_point_temp_hyst,
781 SENSOR_ATTR_2(temp1_auto_point2_temp_hyst, S_IRUGO,
782 show_pwm_auto_point_temp_hyst, NULL, 1, 2),
783 SENSOR_ATTR_2(temp1_auto_point3_temp_hyst, S_IRUGO,
784 show_pwm_auto_point_temp_hyst, NULL, 2, 2),
785 SENSOR_ATTR_2(temp1_auto_point4_temp_hyst, S_IRUGO,
786 show_pwm_auto_point_temp_hyst, NULL, 3, 2),
788 SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,
789 show_pwm_auto_point_channel,
790 store_pwm_auto_point_channel, 0, 1),
791 SENSOR_ATTR_2(temp2_auto_point1_pwm, S_IRUGO|S_IWUSR,
792 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
794 SENSOR_ATTR_2(temp2_auto_point2_pwm, S_IRUGO|S_IWUSR,
795 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
797 SENSOR_ATTR_2(temp2_auto_point3_pwm, S_IRUGO|S_IWUSR,
798 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
800 SENSOR_ATTR_2(temp2_auto_point4_pwm, S_IRUGO|S_IWUSR,
801 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
803 SENSOR_ATTR_2(temp2_auto_point5_pwm, S_IRUGO|S_IWUSR,
804 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
806 SENSOR_ATTR_2(temp2_auto_point1_temp, S_IRUGO|S_IWUSR,
807 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
809 SENSOR_ATTR_2(temp2_auto_point2_temp, S_IRUGO|S_IWUSR,
810 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
812 SENSOR_ATTR_2(temp2_auto_point3_temp, S_IRUGO|S_IWUSR,
813 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
815 SENSOR_ATTR_2(temp2_auto_point4_temp, S_IRUGO|S_IWUSR,
816 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
818 SENSOR_ATTR_2(temp2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
819 show_pwm_auto_point_temp_hyst,
820 store_pwm_auto_point_temp_hyst,
822 SENSOR_ATTR_2(temp2_auto_point2_temp_hyst, S_IRUGO,
823 show_pwm_auto_point_temp_hyst, NULL, 1, 0),
824 SENSOR_ATTR_2(temp2_auto_point3_temp_hyst, S_IRUGO,
825 show_pwm_auto_point_temp_hyst, NULL, 2, 0),
826 SENSOR_ATTR_2(temp2_auto_point4_temp_hyst, S_IRUGO,
827 show_pwm_auto_point_temp_hyst, NULL, 3, 0),
829 SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
830 show_pwm_auto_point_channel,
831 store_pwm_auto_point_channel, 0, 2),
832 SENSOR_ATTR_2(temp3_auto_point1_pwm, S_IRUGO|S_IWUSR,
833 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
835 SENSOR_ATTR_2(temp3_auto_point2_pwm, S_IRUGO|S_IWUSR,
836 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
838 SENSOR_ATTR_2(temp3_auto_point3_pwm, S_IRUGO|S_IWUSR,
839 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
841 SENSOR_ATTR_2(temp3_auto_point4_pwm, S_IRUGO|S_IWUSR,
842 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
844 SENSOR_ATTR_2(temp3_auto_point5_pwm, S_IRUGO|S_IWUSR,
845 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
847 SENSOR_ATTR_2(temp3_auto_point1_temp, S_IRUGO|S_IWUSR,
848 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
850 SENSOR_ATTR_2(temp3_auto_point2_temp, S_IRUGO|S_IWUSR,
851 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
853 SENSOR_ATTR_2(temp3_auto_point3_temp, S_IRUGO|S_IWUSR,
854 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
856 SENSOR_ATTR_2(temp3_auto_point4_temp, S_IRUGO|S_IWUSR,
857 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
859 SENSOR_ATTR_2(temp3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
860 show_pwm_auto_point_temp_hyst,
861 store_pwm_auto_point_temp_hyst,
863 SENSOR_ATTR_2(temp3_auto_point2_temp_hyst, S_IRUGO,
864 show_pwm_auto_point_temp_hyst, NULL, 1, 1),
865 SENSOR_ATTR_2(temp3_auto_point3_temp_hyst, S_IRUGO,
866 show_pwm_auto_point_temp_hyst, NULL, 2, 1),
867 SENSOR_ATTR_2(temp3_auto_point4_temp_hyst, S_IRUGO,
868 show_pwm_auto_point_temp_hyst, NULL, 3, 1),
871 /* Super I/O functions */
872 static inline int superio_inb(int base, int reg)
875 return inb(base + 1);
878 static int superio_inw(int base, int reg)
881 val = superio_inb(base, reg) << 8;
882 val |= superio_inb(base, reg + 1);
886 static inline void superio_enter(int base)
888 /* according to the datasheet the key must be send twice! */
889 outb(SIO_UNLOCK_KEY, base);
890 outb(SIO_UNLOCK_KEY, base);
893 static inline void superio_select(int base, int ld)
895 outb(SIO_REG_LDSEL, base);
899 static inline void superio_exit(int base)
901 outb(SIO_LOCK_KEY, base);
904 static inline int fan_from_reg(u16 reg)
906 return reg ? (1500000 / reg) : 0;
909 static inline u16 fan_to_reg(int fan)
911 return fan ? (1500000 / fan) : 0;
914 static u8 f71882fg_read8(struct f71882fg_data *data, u8 reg)
918 outb(reg, data->addr + ADDR_REG_OFFSET);
919 val = inb(data->addr + DATA_REG_OFFSET);
924 static u16 f71882fg_read16(struct f71882fg_data *data, u8 reg)
928 val = f71882fg_read8(data, reg) << 8;
929 val |= f71882fg_read8(data, reg + 1);
934 static void f71882fg_write8(struct f71882fg_data *data, u8 reg, u8 val)
936 outb(reg, data->addr + ADDR_REG_OFFSET);
937 outb(val, data->addr + DATA_REG_OFFSET);
940 static void f71882fg_write16(struct f71882fg_data *data, u8 reg, u16 val)
942 f71882fg_write8(data, reg, val >> 8);
943 f71882fg_write8(data, reg + 1, val & 0xff);
946 static u16 f71882fg_read_temp(struct f71882fg_data *data, int nr)
948 if (data->type == f71858fg)
949 return f71882fg_read16(data, F71882FG_REG_TEMP(nr));
951 return f71882fg_read8(data, F71882FG_REG_TEMP(nr));
954 static struct f71882fg_data *f71882fg_update_device(struct device *dev)
956 struct f71882fg_data *data = dev_get_drvdata(dev);
957 int nr, reg = 0, reg2;
958 int nr_fans = (data->type == f71882fg) ? 4 : 3;
959 int nr_ins = (data->type == f71858fg || data->type == f8000) ? 3 : 9;
961 mutex_lock(&data->update_lock);
963 /* Update once every 60 seconds */
964 if (time_after(jiffies, data->last_limits + 60 * HZ) ||
966 if (data->type == f71882fg || data->type == f71889fg) {
968 f71882fg_read8(data, F71882FG_REG_IN1_HIGH);
970 f71882fg_read8(data, F71882FG_REG_IN_BEEP);
973 /* Get High & boundary temps*/
974 for (nr = data->temp_start; nr < 3 + data->temp_start; nr++) {
975 data->temp_ovt[nr] = f71882fg_read8(data,
976 F71882FG_REG_TEMP_OVT(nr));
977 data->temp_high[nr] = f71882fg_read8(data,
978 F71882FG_REG_TEMP_HIGH(nr));
981 if (data->type != f8000) {
982 data->temp_hyst[0] = f71882fg_read8(data,
983 F71882FG_REG_TEMP_HYST(0));
984 data->temp_hyst[1] = f71882fg_read8(data,
985 F71882FG_REG_TEMP_HYST(1));
988 if (data->type == f71862fg || data->type == f71882fg ||
989 data->type == f71889fg) {
990 data->fan_beep = f71882fg_read8(data,
991 F71882FG_REG_FAN_BEEP);
992 data->temp_beep = f71882fg_read8(data,
993 F71882FG_REG_TEMP_BEEP);
994 /* Have to hardcode type, because temp1 is special */
995 reg = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE);
996 data->temp_type[2] = (reg & 0x04) ? 2 : 4;
997 data->temp_type[3] = (reg & 0x08) ? 2 : 4;
999 /* Determine temp index 1 sensor type */
1000 if (data->type == f71889fg) {
1001 reg2 = f71882fg_read8(data, F71882FG_REG_START);
1002 switch ((reg2 & 0x60) >> 5) {
1003 case 0x00: /* BJT / Thermistor */
1004 data->temp_type[1] = (reg & 0x02) ? 2 : 4;
1006 case 0x01: /* AMDSI */
1007 data->temp_type[1] = 5;
1009 case 0x02: /* PECI */
1010 case 0x03: /* Ibex Peak ?? Report as PECI for now */
1011 data->temp_type[1] = 6;
1014 } else if (data->type == f71808fg) {
1015 reg = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE);
1016 data->temp_type[1] = (reg & 0x02) ? 2 : 4;
1017 data->temp_type[2] = (reg & 0x04) ? 2 : 4;
1020 reg2 = f71882fg_read8(data, F71882FG_REG_PECI);
1021 if ((reg2 & 0x03) == 0x01)
1022 data->temp_type[1] = 6; /* PECI */
1023 else if ((reg2 & 0x03) == 0x02)
1024 data->temp_type[1] = 5; /* AMDSI */
1025 else if (data->type == f71862fg ||
1026 data->type == f71882fg)
1027 data->temp_type[1] = (reg & 0x02) ? 2 : 4;
1028 else /* f71858fg and f8000 only support BJT */
1029 data->temp_type[1] = 2;
1032 data->pwm_enable = f71882fg_read8(data,
1033 F71882FG_REG_PWM_ENABLE);
1034 data->pwm_auto_point_hyst[0] =
1035 f71882fg_read8(data, F71882FG_REG_FAN_HYST(0));
1036 data->pwm_auto_point_hyst[1] =
1037 f71882fg_read8(data, F71882FG_REG_FAN_HYST(1));
1039 for (nr = 0; nr < nr_fans; nr++) {
1040 data->pwm_auto_point_mapping[nr] =
1041 f71882fg_read8(data,
1042 F71882FG_REG_POINT_MAPPING(nr));
1044 if (data->type != f71862fg) {
1046 for (point = 0; point < 5; point++) {
1047 data->pwm_auto_point_pwm[nr][point] =
1048 f71882fg_read8(data,
1049 F71882FG_REG_POINT_PWM
1052 for (point = 0; point < 4; point++) {
1053 data->pwm_auto_point_temp[nr][point] =
1054 f71882fg_read8(data,
1055 F71882FG_REG_POINT_TEMP
1059 data->pwm_auto_point_pwm[nr][1] =
1060 f71882fg_read8(data,
1061 F71882FG_REG_POINT_PWM
1063 data->pwm_auto_point_pwm[nr][4] =
1064 f71882fg_read8(data,
1065 F71882FG_REG_POINT_PWM
1067 data->pwm_auto_point_temp[nr][0] =
1068 f71882fg_read8(data,
1069 F71882FG_REG_POINT_TEMP
1071 data->pwm_auto_point_temp[nr][3] =
1072 f71882fg_read8(data,
1073 F71882FG_REG_POINT_TEMP
1077 data->last_limits = jiffies;
1080 /* Update every second */
1081 if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
1082 data->temp_status = f71882fg_read8(data,
1083 F71882FG_REG_TEMP_STATUS);
1084 data->temp_diode_open = f71882fg_read8(data,
1085 F71882FG_REG_TEMP_DIODE_OPEN);
1086 for (nr = data->temp_start; nr < 3 + data->temp_start; nr++)
1087 data->temp[nr] = f71882fg_read_temp(data, nr);
1089 data->fan_status = f71882fg_read8(data,
1090 F71882FG_REG_FAN_STATUS);
1091 for (nr = 0; nr < nr_fans; nr++) {
1092 data->fan[nr] = f71882fg_read16(data,
1093 F71882FG_REG_FAN(nr));
1094 data->fan_target[nr] =
1095 f71882fg_read16(data, F71882FG_REG_FAN_TARGET(nr));
1096 data->fan_full_speed[nr] =
1097 f71882fg_read16(data,
1098 F71882FG_REG_FAN_FULL_SPEED(nr));
1100 f71882fg_read8(data, F71882FG_REG_PWM(nr));
1103 /* The f8000 can monitor 1 more fan, but has no pwm for it */
1104 if (data->type == f8000)
1105 data->fan[3] = f71882fg_read16(data,
1106 F71882FG_REG_FAN(3));
1107 if (data->type == f71882fg || data->type == f71889fg)
1108 data->in_status = f71882fg_read8(data,
1109 F71882FG_REG_IN_STATUS);
1110 for (nr = 0; nr < nr_ins; nr++)
1111 data->in[nr] = f71882fg_read8(data,
1112 F71882FG_REG_IN(nr));
1114 data->last_updated = jiffies;
1118 mutex_unlock(&data->update_lock);
1123 /* Sysfs Interface */
1124 static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
1127 struct f71882fg_data *data = f71882fg_update_device(dev);
1128 int nr = to_sensor_dev_attr_2(devattr)->index;
1129 int speed = fan_from_reg(data->fan[nr]);
1131 if (speed == FAN_MIN_DETECT)
1134 return sprintf(buf, "%d\n", speed);
1137 static ssize_t show_fan_full_speed(struct device *dev,
1138 struct device_attribute *devattr, char *buf)
1140 struct f71882fg_data *data = f71882fg_update_device(dev);
1141 int nr = to_sensor_dev_attr_2(devattr)->index;
1142 int speed = fan_from_reg(data->fan_full_speed[nr]);
1143 return sprintf(buf, "%d\n", speed);
1146 static ssize_t store_fan_full_speed(struct device *dev,
1147 struct device_attribute *devattr,
1148 const char *buf, size_t count)
1150 struct f71882fg_data *data = dev_get_drvdata(dev);
1151 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1154 err = strict_strtol(buf, 10, &val);
1158 val = SENSORS_LIMIT(val, 23, 1500000);
1159 val = fan_to_reg(val);
1161 mutex_lock(&data->update_lock);
1162 f71882fg_write16(data, F71882FG_REG_FAN_FULL_SPEED(nr), val);
1163 data->fan_full_speed[nr] = val;
1164 mutex_unlock(&data->update_lock);
1169 static ssize_t show_fan_beep(struct device *dev, struct device_attribute
1170 *devattr, char *buf)
1172 struct f71882fg_data *data = f71882fg_update_device(dev);
1173 int nr = to_sensor_dev_attr_2(devattr)->index;
1175 if (data->fan_beep & (1 << nr))
1176 return sprintf(buf, "1\n");
1178 return sprintf(buf, "0\n");
1181 static ssize_t store_fan_beep(struct device *dev, struct device_attribute
1182 *devattr, const char *buf, size_t count)
1184 struct f71882fg_data *data = dev_get_drvdata(dev);
1185 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1188 err = strict_strtoul(buf, 10, &val);
1192 mutex_lock(&data->update_lock);
1193 data->fan_beep = f71882fg_read8(data, F71882FG_REG_FAN_BEEP);
1195 data->fan_beep |= 1 << nr;
1197 data->fan_beep &= ~(1 << nr);
1199 f71882fg_write8(data, F71882FG_REG_FAN_BEEP, data->fan_beep);
1200 mutex_unlock(&data->update_lock);
1205 static ssize_t show_fan_alarm(struct device *dev, struct device_attribute
1206 *devattr, char *buf)
1208 struct f71882fg_data *data = f71882fg_update_device(dev);
1209 int nr = to_sensor_dev_attr_2(devattr)->index;
1211 if (data->fan_status & (1 << nr))
1212 return sprintf(buf, "1\n");
1214 return sprintf(buf, "0\n");
1217 static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
1220 struct f71882fg_data *data = f71882fg_update_device(dev);
1221 int nr = to_sensor_dev_attr_2(devattr)->index;
1223 return sprintf(buf, "%d\n", data->in[nr] * 8);
1226 static ssize_t show_in_max(struct device *dev, struct device_attribute
1227 *devattr, char *buf)
1229 struct f71882fg_data *data = f71882fg_update_device(dev);
1231 return sprintf(buf, "%d\n", data->in1_max * 8);
1234 static ssize_t store_in_max(struct device *dev, struct device_attribute
1235 *devattr, const char *buf, size_t count)
1237 struct f71882fg_data *data = dev_get_drvdata(dev);
1241 err = strict_strtol(buf, 10, &val);
1246 val = SENSORS_LIMIT(val, 0, 255);
1248 mutex_lock(&data->update_lock);
1249 f71882fg_write8(data, F71882FG_REG_IN1_HIGH, val);
1250 data->in1_max = val;
1251 mutex_unlock(&data->update_lock);
1256 static ssize_t show_in_beep(struct device *dev, struct device_attribute
1257 *devattr, char *buf)
1259 struct f71882fg_data *data = f71882fg_update_device(dev);
1260 int nr = to_sensor_dev_attr_2(devattr)->index;
1262 if (data->in_beep & (1 << nr))
1263 return sprintf(buf, "1\n");
1265 return sprintf(buf, "0\n");
1268 static ssize_t store_in_beep(struct device *dev, struct device_attribute
1269 *devattr, const char *buf, size_t count)
1271 struct f71882fg_data *data = dev_get_drvdata(dev);
1272 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1275 err = strict_strtoul(buf, 10, &val);
1279 mutex_lock(&data->update_lock);
1280 data->in_beep = f71882fg_read8(data, F71882FG_REG_IN_BEEP);
1282 data->in_beep |= 1 << nr;
1284 data->in_beep &= ~(1 << nr);
1286 f71882fg_write8(data, F71882FG_REG_IN_BEEP, data->in_beep);
1287 mutex_unlock(&data->update_lock);
1292 static ssize_t show_in_alarm(struct device *dev, struct device_attribute
1293 *devattr, char *buf)
1295 struct f71882fg_data *data = f71882fg_update_device(dev);
1296 int nr = to_sensor_dev_attr_2(devattr)->index;
1298 if (data->in_status & (1 << nr))
1299 return sprintf(buf, "1\n");
1301 return sprintf(buf, "0\n");
1304 static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
1307 struct f71882fg_data *data = f71882fg_update_device(dev);
1308 int nr = to_sensor_dev_attr_2(devattr)->index;
1311 if (data->type == f71858fg) {
1312 /* TEMP_TABLE_SEL 1 or 3 ? */
1313 if (data->temp_config & 1) {
1314 sign = data->temp[nr] & 0x0001;
1315 temp = (data->temp[nr] >> 5) & 0x7ff;
1317 sign = data->temp[nr] & 0x8000;
1318 temp = (data->temp[nr] >> 5) & 0x3ff;
1324 temp = data->temp[nr] * 1000;
1326 return sprintf(buf, "%d\n", temp);
1329 static ssize_t show_temp_max(struct device *dev, struct device_attribute
1330 *devattr, char *buf)
1332 struct f71882fg_data *data = f71882fg_update_device(dev);
1333 int nr = to_sensor_dev_attr_2(devattr)->index;
1335 return sprintf(buf, "%d\n", data->temp_high[nr] * 1000);
1338 static ssize_t store_temp_max(struct device *dev, struct device_attribute
1339 *devattr, const char *buf, size_t count)
1341 struct f71882fg_data *data = dev_get_drvdata(dev);
1342 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1345 err = strict_strtol(buf, 10, &val);
1350 val = SENSORS_LIMIT(val, 0, 255);
1352 mutex_lock(&data->update_lock);
1353 f71882fg_write8(data, F71882FG_REG_TEMP_HIGH(nr), val);
1354 data->temp_high[nr] = val;
1355 mutex_unlock(&data->update_lock);
1360 static ssize_t show_temp_max_hyst(struct device *dev, struct device_attribute
1361 *devattr, char *buf)
1363 struct f71882fg_data *data = f71882fg_update_device(dev);
1364 int nr = to_sensor_dev_attr_2(devattr)->index;
1367 mutex_lock(&data->update_lock);
1369 temp_max_hyst = data->temp_hyst[nr / 2] >> 4;
1371 temp_max_hyst = data->temp_hyst[nr / 2] & 0x0f;
1372 temp_max_hyst = (data->temp_high[nr] - temp_max_hyst) * 1000;
1373 mutex_unlock(&data->update_lock);
1375 return sprintf(buf, "%d\n", temp_max_hyst);
1378 static ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute
1379 *devattr, const char *buf, size_t count)
1381 struct f71882fg_data *data = dev_get_drvdata(dev);
1382 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1383 ssize_t ret = count;
1387 err = strict_strtol(buf, 10, &val);
1393 mutex_lock(&data->update_lock);
1395 /* convert abs to relative and check */
1396 data->temp_high[nr] = f71882fg_read8(data, F71882FG_REG_TEMP_HIGH(nr));
1397 val = SENSORS_LIMIT(val, data->temp_high[nr] - 15,
1398 data->temp_high[nr]);
1399 val = data->temp_high[nr] - val;
1401 /* convert value to register contents */
1402 reg = f71882fg_read8(data, F71882FG_REG_TEMP_HYST(nr / 2));
1404 reg = (reg & 0x0f) | (val << 4);
1406 reg = (reg & 0xf0) | val;
1407 f71882fg_write8(data, F71882FG_REG_TEMP_HYST(nr / 2), reg);
1408 data->temp_hyst[nr / 2] = reg;
1410 mutex_unlock(&data->update_lock);
1414 static ssize_t show_temp_crit(struct device *dev, struct device_attribute
1415 *devattr, char *buf)
1417 struct f71882fg_data *data = f71882fg_update_device(dev);
1418 int nr = to_sensor_dev_attr_2(devattr)->index;
1420 return sprintf(buf, "%d\n", data->temp_ovt[nr] * 1000);
1423 static ssize_t store_temp_crit(struct device *dev, struct device_attribute
1424 *devattr, const char *buf, size_t count)
1426 struct f71882fg_data *data = dev_get_drvdata(dev);
1427 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1430 err = strict_strtol(buf, 10, &val);
1435 val = SENSORS_LIMIT(val, 0, 255);
1437 mutex_lock(&data->update_lock);
1438 f71882fg_write8(data, F71882FG_REG_TEMP_OVT(nr), val);
1439 data->temp_ovt[nr] = val;
1440 mutex_unlock(&data->update_lock);
1445 static ssize_t show_temp_crit_hyst(struct device *dev, struct device_attribute
1446 *devattr, char *buf)
1448 struct f71882fg_data *data = f71882fg_update_device(dev);
1449 int nr = to_sensor_dev_attr_2(devattr)->index;
1452 mutex_lock(&data->update_lock);
1454 temp_crit_hyst = data->temp_hyst[nr / 2] >> 4;
1456 temp_crit_hyst = data->temp_hyst[nr / 2] & 0x0f;
1457 temp_crit_hyst = (data->temp_ovt[nr] - temp_crit_hyst) * 1000;
1458 mutex_unlock(&data->update_lock);
1460 return sprintf(buf, "%d\n", temp_crit_hyst);
1463 static ssize_t show_temp_type(struct device *dev, struct device_attribute
1464 *devattr, char *buf)
1466 struct f71882fg_data *data = f71882fg_update_device(dev);
1467 int nr = to_sensor_dev_attr_2(devattr)->index;
1469 return sprintf(buf, "%d\n", data->temp_type[nr]);
1472 static ssize_t show_temp_beep(struct device *dev, struct device_attribute
1473 *devattr, char *buf)
1475 struct f71882fg_data *data = f71882fg_update_device(dev);
1476 int nr = to_sensor_dev_attr_2(devattr)->index;
1478 if (data->temp_beep & (1 << nr))
1479 return sprintf(buf, "1\n");
1481 return sprintf(buf, "0\n");
1484 static ssize_t store_temp_beep(struct device *dev, struct device_attribute
1485 *devattr, const char *buf, size_t count)
1487 struct f71882fg_data *data = dev_get_drvdata(dev);
1488 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1491 err = strict_strtoul(buf, 10, &val);
1495 mutex_lock(&data->update_lock);
1496 data->temp_beep = f71882fg_read8(data, F71882FG_REG_TEMP_BEEP);
1498 data->temp_beep |= 1 << nr;
1500 data->temp_beep &= ~(1 << nr);
1502 f71882fg_write8(data, F71882FG_REG_TEMP_BEEP, data->temp_beep);
1503 mutex_unlock(&data->update_lock);
1508 static ssize_t show_temp_alarm(struct device *dev, struct device_attribute
1509 *devattr, char *buf)
1511 struct f71882fg_data *data = f71882fg_update_device(dev);
1512 int nr = to_sensor_dev_attr_2(devattr)->index;
1514 if (data->temp_status & (1 << nr))
1515 return sprintf(buf, "1\n");
1517 return sprintf(buf, "0\n");
1520 static ssize_t show_temp_fault(struct device *dev, struct device_attribute
1521 *devattr, char *buf)
1523 struct f71882fg_data *data = f71882fg_update_device(dev);
1524 int nr = to_sensor_dev_attr_2(devattr)->index;
1526 if (data->temp_diode_open & (1 << nr))
1527 return sprintf(buf, "1\n");
1529 return sprintf(buf, "0\n");
1532 static ssize_t show_pwm(struct device *dev,
1533 struct device_attribute *devattr, char *buf)
1535 struct f71882fg_data *data = f71882fg_update_device(dev);
1536 int val, nr = to_sensor_dev_attr_2(devattr)->index;
1537 mutex_lock(&data->update_lock);
1538 if (data->pwm_enable & (1 << (2 * nr)))
1540 val = data->pwm[nr];
1543 val = 255 * fan_from_reg(data->fan_target[nr])
1544 / fan_from_reg(data->fan_full_speed[nr]);
1546 mutex_unlock(&data->update_lock);
1547 return sprintf(buf, "%d\n", val);
1550 static ssize_t store_pwm(struct device *dev,
1551 struct device_attribute *devattr, const char *buf,
1554 struct f71882fg_data *data = dev_get_drvdata(dev);
1555 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1558 err = strict_strtol(buf, 10, &val);
1562 val = SENSORS_LIMIT(val, 0, 255);
1564 mutex_lock(&data->update_lock);
1565 data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
1566 if ((data->type == f8000 && ((data->pwm_enable >> 2 * nr) & 3) != 2) ||
1567 (data->type != f8000 && !((data->pwm_enable >> 2 * nr) & 2))) {
1571 if (data->pwm_enable & (1 << (2 * nr))) {
1573 f71882fg_write8(data, F71882FG_REG_PWM(nr), val);
1574 data->pwm[nr] = val;
1577 int target, full_speed;
1578 full_speed = f71882fg_read16(data,
1579 F71882FG_REG_FAN_FULL_SPEED(nr));
1580 target = fan_to_reg(val * fan_from_reg(full_speed) / 255);
1581 f71882fg_write16(data, F71882FG_REG_FAN_TARGET(nr), target);
1582 data->fan_target[nr] = target;
1583 data->fan_full_speed[nr] = full_speed;
1586 mutex_unlock(&data->update_lock);
1591 static ssize_t show_pwm_enable(struct device *dev,
1592 struct device_attribute *devattr, char *buf)
1595 struct f71882fg_data *data = f71882fg_update_device(dev);
1596 int nr = to_sensor_dev_attr_2(devattr)->index;
1598 switch ((data->pwm_enable >> 2 * nr) & 3) {
1601 result = 2; /* Normal auto mode */
1604 result = 1; /* Manual mode */
1607 if (data->type == f8000)
1608 result = 3; /* Thermostat mode */
1610 result = 1; /* Manual mode */
1614 return sprintf(buf, "%d\n", result);
1617 static ssize_t store_pwm_enable(struct device *dev, struct device_attribute
1618 *devattr, const char *buf, size_t count)
1620 struct f71882fg_data *data = dev_get_drvdata(dev);
1621 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1624 err = strict_strtol(buf, 10, &val);
1628 /* Special case for F8000 pwm channel 3 which only does auto mode */
1629 if (data->type == f8000 && nr == 2 && val != 2)
1632 mutex_lock(&data->update_lock);
1633 data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
1634 /* Special case for F8000 auto PWM mode / Thermostat mode */
1635 if (data->type == f8000 && ((data->pwm_enable >> 2 * nr) & 1)) {
1638 data->pwm_enable &= ~(2 << (2 * nr));
1639 break; /* Normal auto mode */
1641 data->pwm_enable |= 2 << (2 * nr);
1642 break; /* Thermostat mode */
1650 /* The f71858fg does not support manual RPM mode */
1651 if (data->type == f71858fg &&
1652 ((data->pwm_enable >> (2 * nr)) & 1)) {
1656 data->pwm_enable |= 2 << (2 * nr);
1659 data->pwm_enable &= ~(2 << (2 * nr));
1660 break; /* Normal auto mode */
1666 f71882fg_write8(data, F71882FG_REG_PWM_ENABLE, data->pwm_enable);
1668 mutex_unlock(&data->update_lock);
1673 static ssize_t show_pwm_auto_point_pwm(struct device *dev,
1674 struct device_attribute *devattr,
1678 struct f71882fg_data *data = f71882fg_update_device(dev);
1679 int pwm = to_sensor_dev_attr_2(devattr)->index;
1680 int point = to_sensor_dev_attr_2(devattr)->nr;
1682 mutex_lock(&data->update_lock);
1683 if (data->pwm_enable & (1 << (2 * pwm))) {
1685 result = data->pwm_auto_point_pwm[pwm][point];
1688 result = 32 * 255 / (32 + data->pwm_auto_point_pwm[pwm][point]);
1690 mutex_unlock(&data->update_lock);
1692 return sprintf(buf, "%d\n", result);
1695 static ssize_t store_pwm_auto_point_pwm(struct device *dev,
1696 struct device_attribute *devattr,
1697 const char *buf, size_t count)
1699 struct f71882fg_data *data = dev_get_drvdata(dev);
1700 int err, pwm = to_sensor_dev_attr_2(devattr)->index;
1701 int point = to_sensor_dev_attr_2(devattr)->nr;
1704 err = strict_strtol(buf, 10, &val);
1708 val = SENSORS_LIMIT(val, 0, 255);
1710 mutex_lock(&data->update_lock);
1711 data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
1712 if (data->pwm_enable & (1 << (2 * pwm))) {
1716 if (val < 29) /* Prevent negative numbers */
1719 val = (255 - val) * 32 / val;
1721 f71882fg_write8(data, F71882FG_REG_POINT_PWM(pwm, point), val);
1722 data->pwm_auto_point_pwm[pwm][point] = val;
1723 mutex_unlock(&data->update_lock);
1728 static ssize_t show_pwm_auto_point_temp_hyst(struct device *dev,
1729 struct device_attribute *devattr,
1733 struct f71882fg_data *data = f71882fg_update_device(dev);
1734 int nr = to_sensor_dev_attr_2(devattr)->index;
1735 int point = to_sensor_dev_attr_2(devattr)->nr;
1737 mutex_lock(&data->update_lock);
1739 result = data->pwm_auto_point_hyst[nr / 2] >> 4;
1741 result = data->pwm_auto_point_hyst[nr / 2] & 0x0f;
1742 result = 1000 * (data->pwm_auto_point_temp[nr][point] - result);
1743 mutex_unlock(&data->update_lock);
1745 return sprintf(buf, "%d\n", result);
1748 static ssize_t store_pwm_auto_point_temp_hyst(struct device *dev,
1749 struct device_attribute *devattr,
1750 const char *buf, size_t count)
1752 struct f71882fg_data *data = dev_get_drvdata(dev);
1753 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1754 int point = to_sensor_dev_attr_2(devattr)->nr;
1758 err = strict_strtol(buf, 10, &val);
1764 mutex_lock(&data->update_lock);
1765 data->pwm_auto_point_temp[nr][point] =
1766 f71882fg_read8(data, F71882FG_REG_POINT_TEMP(nr, point));
1767 val = SENSORS_LIMIT(val, data->pwm_auto_point_temp[nr][point] - 15,
1768 data->pwm_auto_point_temp[nr][point]);
1769 val = data->pwm_auto_point_temp[nr][point] - val;
1771 reg = f71882fg_read8(data, F71882FG_REG_FAN_HYST(nr / 2));
1773 reg = (reg & 0x0f) | (val << 4);
1775 reg = (reg & 0xf0) | val;
1777 f71882fg_write8(data, F71882FG_REG_FAN_HYST(nr / 2), reg);
1778 data->pwm_auto_point_hyst[nr / 2] = reg;
1779 mutex_unlock(&data->update_lock);
1784 static ssize_t show_pwm_interpolate(struct device *dev,
1785 struct device_attribute *devattr, char *buf)
1788 struct f71882fg_data *data = f71882fg_update_device(dev);
1789 int nr = to_sensor_dev_attr_2(devattr)->index;
1791 result = (data->pwm_auto_point_mapping[nr] >> 4) & 1;
1793 return sprintf(buf, "%d\n", result);
1796 static ssize_t store_pwm_interpolate(struct device *dev,
1797 struct device_attribute *devattr,
1798 const char *buf, size_t count)
1800 struct f71882fg_data *data = dev_get_drvdata(dev);
1801 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1804 err = strict_strtoul(buf, 10, &val);
1808 mutex_lock(&data->update_lock);
1809 data->pwm_auto_point_mapping[nr] =
1810 f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(nr));
1812 val = data->pwm_auto_point_mapping[nr] | (1 << 4);
1814 val = data->pwm_auto_point_mapping[nr] & (~(1 << 4));
1815 f71882fg_write8(data, F71882FG_REG_POINT_MAPPING(nr), val);
1816 data->pwm_auto_point_mapping[nr] = val;
1817 mutex_unlock(&data->update_lock);
1822 static ssize_t show_pwm_auto_point_channel(struct device *dev,
1823 struct device_attribute *devattr,
1827 struct f71882fg_data *data = f71882fg_update_device(dev);
1828 int nr = to_sensor_dev_attr_2(devattr)->index;
1830 result = 1 << ((data->pwm_auto_point_mapping[nr] & 3) -
1833 return sprintf(buf, "%d\n", result);
1836 static ssize_t store_pwm_auto_point_channel(struct device *dev,
1837 struct device_attribute *devattr,
1838 const char *buf, size_t count)
1840 struct f71882fg_data *data = dev_get_drvdata(dev);
1841 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1844 err = strict_strtol(buf, 10, &val);
1861 val += data->temp_start;
1862 mutex_lock(&data->update_lock);
1863 data->pwm_auto_point_mapping[nr] =
1864 f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(nr));
1865 val = (data->pwm_auto_point_mapping[nr] & 0xfc) | val;
1866 f71882fg_write8(data, F71882FG_REG_POINT_MAPPING(nr), val);
1867 data->pwm_auto_point_mapping[nr] = val;
1868 mutex_unlock(&data->update_lock);
1873 static ssize_t show_pwm_auto_point_temp(struct device *dev,
1874 struct device_attribute *devattr,
1878 struct f71882fg_data *data = f71882fg_update_device(dev);
1879 int pwm = to_sensor_dev_attr_2(devattr)->index;
1880 int point = to_sensor_dev_attr_2(devattr)->nr;
1882 result = data->pwm_auto_point_temp[pwm][point];
1883 return sprintf(buf, "%d\n", 1000 * result);
1886 static ssize_t store_pwm_auto_point_temp(struct device *dev,
1887 struct device_attribute *devattr,
1888 const char *buf, size_t count)
1890 struct f71882fg_data *data = dev_get_drvdata(dev);
1891 int err, pwm = to_sensor_dev_attr_2(devattr)->index;
1892 int point = to_sensor_dev_attr_2(devattr)->nr;
1895 err = strict_strtol(buf, 10, &val);
1901 if (data->type == f71889fg
1902 || data->type == f71808fg)
1903 val = SENSORS_LIMIT(val, -128, 127);
1905 val = SENSORS_LIMIT(val, 0, 127);
1907 mutex_lock(&data->update_lock);
1908 f71882fg_write8(data, F71882FG_REG_POINT_TEMP(pwm, point), val);
1909 data->pwm_auto_point_temp[pwm][point] = val;
1910 mutex_unlock(&data->update_lock);
1915 static ssize_t show_name(struct device *dev, struct device_attribute *devattr,
1918 struct f71882fg_data *data = dev_get_drvdata(dev);
1919 return sprintf(buf, "%s\n", f71882fg_names[data->type]);
1922 static int __devinit f71882fg_create_sysfs_files(struct platform_device *pdev,
1923 struct sensor_device_attribute_2 *attr, int count)
1927 for (i = 0; i < count; i++) {
1928 err = device_create_file(&pdev->dev, &attr[i].dev_attr);
1935 static void f71882fg_remove_sysfs_files(struct platform_device *pdev,
1936 struct sensor_device_attribute_2 *attr, int count)
1940 for (i = 0; i < count; i++)
1941 device_remove_file(&pdev->dev, &attr[i].dev_attr);
1944 static int __devinit f71882fg_probe(struct platform_device *pdev)
1946 struct f71882fg_data *data;
1947 struct f71882fg_sio_data *sio_data = pdev->dev.platform_data;
1948 int err, i, nr_fans = (sio_data->type == f71882fg) ? 4 : 3;
1951 data = kzalloc(sizeof(struct f71882fg_data), GFP_KERNEL);
1955 data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start;
1956 data->type = sio_data->type;
1958 (data->type == f71858fg || data->type == f8000) ? 0 : 1;
1959 mutex_init(&data->update_lock);
1960 platform_set_drvdata(pdev, data);
1962 start_reg = f71882fg_read8(data, F71882FG_REG_START);
1963 if (start_reg & 0x04) {
1964 dev_warn(&pdev->dev, "Hardware monitor is powered down\n");
1968 if (!(start_reg & 0x03)) {
1969 dev_warn(&pdev->dev, "Hardware monitoring not activated\n");
1974 /* Register sysfs interface files */
1975 err = device_create_file(&pdev->dev, &dev_attr_name);
1977 goto exit_unregister_sysfs;
1979 if (start_reg & 0x01) {
1980 switch (data->type) {
1983 f71882fg_read8(data, F71882FG_REG_TEMP_CONFIG);
1984 if (data->temp_config & 0x10)
1985 /* The f71858fg temperature alarms behave as
1986 the f8000 alarms in this mode */
1987 err = f71882fg_create_sysfs_files(pdev,
1989 ARRAY_SIZE(f8000_in_temp_attr));
1991 err = f71882fg_create_sysfs_files(pdev,
1992 f71858fg_in_temp_attr,
1993 ARRAY_SIZE(f71858fg_in_temp_attr));
1997 err = f71882fg_create_sysfs_files(pdev,
1998 fxxxx_in1_alarm_attr,
1999 ARRAY_SIZE(fxxxx_in1_alarm_attr));
2001 goto exit_unregister_sysfs;
2004 err = f71882fg_create_sysfs_files(pdev,
2006 ARRAY_SIZE(f71862_temp_attr));
2008 goto exit_unregister_sysfs;
2009 err = f71882fg_create_sysfs_files(pdev,
2011 ARRAY_SIZE(fxxxx_in_attr));
2013 goto exit_unregister_sysfs;
2014 err = f71882fg_create_sysfs_files(pdev,
2016 ARRAY_SIZE(fxxxx_temp_attr));
2019 err = f71882fg_create_sysfs_files(pdev,
2021 ARRAY_SIZE(f71808_in_attr));
2023 goto exit_unregister_sysfs;
2024 err = f71882fg_create_sysfs_files(pdev,
2026 ARRAY_SIZE(fxxxx_temp_attr));
2029 err = f71882fg_create_sysfs_files(pdev,
2031 ARRAY_SIZE(f8000_in_temp_attr));
2035 goto exit_unregister_sysfs;
2038 if (start_reg & 0x02) {
2040 f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
2042 /* Sanity check the pwm settings */
2043 switch (data->type) {
2046 for (i = 0; i < nr_fans; i++)
2047 if (((data->pwm_enable >> (i * 2)) & 3) == 3)
2051 err = (data->pwm_enable & 0x15) != 0x15;
2059 err = data->pwm_enable & 0x20;
2064 "Invalid (reserved) pwm settings: 0x%02x\n",
2065 (unsigned int)data->pwm_enable);
2067 goto exit_unregister_sysfs;
2070 err = f71882fg_create_sysfs_files(pdev, &fxxxx_fan_attr[0][0],
2071 ARRAY_SIZE(fxxxx_fan_attr[0]) * nr_fans);
2073 goto exit_unregister_sysfs;
2075 if (data->type == f71862fg || data->type == f71882fg ||
2076 data->type == f71889fg) {
2077 err = f71882fg_create_sysfs_files(pdev,
2078 fxxxx_fan_beep_attr, nr_fans);
2080 goto exit_unregister_sysfs;
2083 switch (data->type) {
2085 err = f71882fg_create_sysfs_files(pdev,
2086 f71862fg_auto_pwm_attr,
2087 ARRAY_SIZE(f71862fg_auto_pwm_attr));
2090 err = f71882fg_create_sysfs_files(pdev,
2092 ARRAY_SIZE(f8000_fan_attr));
2094 goto exit_unregister_sysfs;
2095 err = f71882fg_create_sysfs_files(pdev,
2096 f8000_auto_pwm_attr,
2097 ARRAY_SIZE(f8000_auto_pwm_attr));
2101 for (i = 0; i < nr_fans; i++) {
2102 data->pwm_auto_point_mapping[i] =
2103 f71882fg_read8(data,
2104 F71882FG_REG_POINT_MAPPING(i));
2105 if (data->pwm_auto_point_mapping[i] & 0x80)
2109 dev_warn(&pdev->dev,
2110 "Auto pwm controlled by raw digital "
2111 "data, disabling pwm auto_point "
2112 "sysfs attributes\n");
2116 default: /* f71858fg / f71882fg */
2117 err = f71882fg_create_sysfs_files(pdev,
2118 &fxxxx_auto_pwm_attr[0][0],
2119 ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans);
2122 goto exit_unregister_sysfs;
2124 for (i = 0; i < nr_fans; i++)
2125 dev_info(&pdev->dev, "Fan: %d is in %s mode\n", i + 1,
2126 (data->pwm_enable & (1 << 2 * i)) ?
2127 "duty-cycle" : "RPM");
2130 data->hwmon_dev = hwmon_device_register(&pdev->dev);
2131 if (IS_ERR(data->hwmon_dev)) {
2132 err = PTR_ERR(data->hwmon_dev);
2133 data->hwmon_dev = NULL;
2134 goto exit_unregister_sysfs;
2139 exit_unregister_sysfs:
2140 f71882fg_remove(pdev); /* Will unregister the sysfs files for us */
2141 return err; /* f71882fg_remove() also frees our data */
2147 static int f71882fg_remove(struct platform_device *pdev)
2149 struct f71882fg_data *data = platform_get_drvdata(pdev);
2150 int nr_fans = (data->type == f71882fg) ? 4 : 3;
2151 u8 start_reg = f71882fg_read8(data, F71882FG_REG_START);
2153 platform_set_drvdata(pdev, NULL);
2154 if (data->hwmon_dev)
2155 hwmon_device_unregister(data->hwmon_dev);
2157 device_remove_file(&pdev->dev, &dev_attr_name);
2159 if (start_reg & 0x01) {
2160 switch (data->type) {
2162 if (data->temp_config & 0x10)
2163 f71882fg_remove_sysfs_files(pdev,
2165 ARRAY_SIZE(f8000_in_temp_attr));
2167 f71882fg_remove_sysfs_files(pdev,
2168 f71858fg_in_temp_attr,
2169 ARRAY_SIZE(f71858fg_in_temp_attr));
2173 f71882fg_remove_sysfs_files(pdev,
2174 fxxxx_in1_alarm_attr,
2175 ARRAY_SIZE(fxxxx_in1_alarm_attr));
2178 f71882fg_remove_sysfs_files(pdev,
2180 ARRAY_SIZE(f71862_temp_attr));
2181 f71882fg_remove_sysfs_files(pdev,
2183 ARRAY_SIZE(fxxxx_in_attr));
2184 f71882fg_remove_sysfs_files(pdev,
2186 ARRAY_SIZE(fxxxx_temp_attr));
2189 f71882fg_remove_sysfs_files(pdev,
2191 ARRAY_SIZE(f71808_in_attr));
2192 f71882fg_remove_sysfs_files(pdev,
2194 ARRAY_SIZE(fxxxx_temp_attr));
2197 f71882fg_remove_sysfs_files(pdev,
2199 ARRAY_SIZE(f8000_in_temp_attr));
2204 if (start_reg & 0x02) {
2205 f71882fg_remove_sysfs_files(pdev, &fxxxx_fan_attr[0][0],
2206 ARRAY_SIZE(fxxxx_fan_attr[0]) * nr_fans);
2208 if (data->type == f71862fg || data->type == f71882fg ||
2209 data->type == f71889fg)
2210 f71882fg_remove_sysfs_files(pdev,
2211 fxxxx_fan_beep_attr, nr_fans);
2213 switch (data->type) {
2215 f71882fg_remove_sysfs_files(pdev,
2216 f71862fg_auto_pwm_attr,
2217 ARRAY_SIZE(f71862fg_auto_pwm_attr));
2220 f71882fg_remove_sysfs_files(pdev,
2222 ARRAY_SIZE(f8000_fan_attr));
2223 f71882fg_remove_sysfs_files(pdev,
2224 f8000_auto_pwm_attr,
2225 ARRAY_SIZE(f8000_auto_pwm_attr));
2227 default: /* f71858fg / f71882fg / f71889fg */
2228 f71882fg_remove_sysfs_files(pdev,
2229 &fxxxx_auto_pwm_attr[0][0],
2230 ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans);
2239 static int __init f71882fg_find(int sioaddr, unsigned short *address,
2240 struct f71882fg_sio_data *sio_data)
2245 /* Don't step on other drivers' I/O space by accident */
2246 if (!request_region(sioaddr, 2, DRVNAME)) {
2247 printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
2252 superio_enter(sioaddr);
2254 devid = superio_inw(sioaddr, SIO_REG_MANID);
2255 if (devid != SIO_FINTEK_ID) {
2256 pr_debug(DRVNAME ": Not a Fintek device\n");
2260 devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID);
2263 sio_data->type = f71808fg;
2266 sio_data->type = f71858fg;
2269 sio_data->type = f71862fg;
2272 sio_data->type = f71882fg;
2275 sio_data->type = f71889fg;
2278 sio_data->type = f8000;
2281 printk(KERN_INFO DRVNAME ": Unsupported Fintek device: %04x\n",
2282 (unsigned int)devid);
2286 if (sio_data->type == f71858fg)
2287 superio_select(sioaddr, SIO_F71858FG_LD_HWM);
2289 superio_select(sioaddr, SIO_F71882FG_LD_HWM);
2291 if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) {
2292 printk(KERN_WARNING DRVNAME ": Device not activated\n");
2296 *address = superio_inw(sioaddr, SIO_REG_ADDR);
2297 if (*address == 0) {
2298 printk(KERN_WARNING DRVNAME ": Base address not set\n");
2301 *address &= ~(REGION_LENGTH - 1); /* Ignore 3 LSB */
2304 printk(KERN_INFO DRVNAME ": Found %s chip at %#x, revision %d\n",
2305 f71882fg_names[sio_data->type], (unsigned int)*address,
2306 (int)superio_inb(sioaddr, SIO_REG_DEVREV));
2308 superio_exit(sioaddr);
2309 release_region(sioaddr, 2);
2313 static int __init f71882fg_device_add(unsigned short address,
2314 const struct f71882fg_sio_data *sio_data)
2316 struct resource res = {
2318 .end = address + REGION_LENGTH - 1,
2319 .flags = IORESOURCE_IO,
2323 f71882fg_pdev = platform_device_alloc(DRVNAME, address);
2327 res.name = f71882fg_pdev->name;
2328 err = acpi_check_resource_conflict(&res);
2330 goto exit_device_put;
2332 err = platform_device_add_resources(f71882fg_pdev, &res, 1);
2334 printk(KERN_ERR DRVNAME ": Device resource addition failed\n");
2335 goto exit_device_put;
2338 err = platform_device_add_data(f71882fg_pdev, sio_data,
2339 sizeof(struct f71882fg_sio_data));
2341 printk(KERN_ERR DRVNAME ": Platform data allocation failed\n");
2342 goto exit_device_put;
2345 err = platform_device_add(f71882fg_pdev);
2347 printk(KERN_ERR DRVNAME ": Device addition failed\n");
2348 goto exit_device_put;
2354 platform_device_put(f71882fg_pdev);
2359 static int __init f71882fg_init(void)
2362 unsigned short address;
2363 struct f71882fg_sio_data sio_data;
2365 memset(&sio_data, 0, sizeof(sio_data));
2367 if (f71882fg_find(0x2e, &address, &sio_data) &&
2368 f71882fg_find(0x4e, &address, &sio_data))
2371 err = platform_driver_register(&f71882fg_driver);
2375 err = f71882fg_device_add(address, &sio_data);
2382 platform_driver_unregister(&f71882fg_driver);
2387 static void __exit f71882fg_exit(void)
2389 platform_device_unregister(f71882fg_pdev);
2390 platform_driver_unregister(&f71882fg_driver);
2393 MODULE_DESCRIPTION("F71882FG Hardware Monitoring Driver");
2394 MODULE_AUTHOR("Hans Edgington, Hans de Goede (hdegoede@redhat.com)");
2395 MODULE_LICENSE("GPL");
2397 module_init(f71882fg_init);
2398 module_exit(f71882fg_exit);