Linux 3.3-rc6
[linux/fpc-iii.git] / drivers / hwmon / f71882fg.c
blobe50305819f013282d8656d905b0587c69e629640
1 /***************************************************************************
2 * Copyright (C) 2006 by Hans Edgington <hans@edgington.nl> *
3 * Copyright (C) 2007-2011 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 ***************************************************************************/
21 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
23 #include <linux/module.h>
24 #include <linux/init.h>
25 #include <linux/slab.h>
26 #include <linux/jiffies.h>
27 #include <linux/platform_device.h>
28 #include <linux/hwmon.h>
29 #include <linux/hwmon-sysfs.h>
30 #include <linux/err.h>
31 #include <linux/mutex.h>
32 #include <linux/io.h>
33 #include <linux/acpi.h>
35 #define DRVNAME "f71882fg"
37 #define SIO_F71858FG_LD_HWM 0x02 /* Hardware monitor logical device */
38 #define SIO_F71882FG_LD_HWM 0x04 /* Hardware monitor logical device */
39 #define SIO_UNLOCK_KEY 0x87 /* Key to enable Super-I/O */
40 #define SIO_LOCK_KEY 0xAA /* Key to disable Super-I/O */
42 #define SIO_REG_LDSEL 0x07 /* Logical device select */
43 #define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */
44 #define SIO_REG_DEVREV 0x22 /* Device revision */
45 #define SIO_REG_MANID 0x23 /* Fintek ID (2 bytes) */
46 #define SIO_REG_ENABLE 0x30 /* Logical device enable */
47 #define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */
49 #define SIO_FINTEK_ID 0x1934 /* Manufacturers ID */
50 #define SIO_F71808E_ID 0x0901 /* Chipset ID */
51 #define SIO_F71808A_ID 0x1001 /* Chipset ID */
52 #define SIO_F71858_ID 0x0507 /* Chipset ID */
53 #define SIO_F71862_ID 0x0601 /* Chipset ID */
54 #define SIO_F71869_ID 0x0814 /* Chipset ID */
55 #define SIO_F71869A_ID 0x1007 /* Chipset ID */
56 #define SIO_F71882_ID 0x0541 /* Chipset ID */
57 #define SIO_F71889_ID 0x0723 /* Chipset ID */
58 #define SIO_F71889E_ID 0x0909 /* Chipset ID */
59 #define SIO_F71889A_ID 0x1005 /* Chipset ID */
60 #define SIO_F8000_ID 0x0581 /* Chipset ID */
61 #define SIO_F81865_ID 0x0704 /* Chipset ID */
63 #define REGION_LENGTH 8
64 #define ADDR_REG_OFFSET 5
65 #define DATA_REG_OFFSET 6
67 #define F71882FG_REG_IN_STATUS 0x12 /* f7188x only */
68 #define F71882FG_REG_IN_BEEP 0x13 /* f7188x only */
69 #define F71882FG_REG_IN(nr) (0x20 + (nr))
70 #define F71882FG_REG_IN1_HIGH 0x32 /* f7188x only */
72 #define F71882FG_REG_FAN(nr) (0xA0 + (16 * (nr)))
73 #define F71882FG_REG_FAN_TARGET(nr) (0xA2 + (16 * (nr)))
74 #define F71882FG_REG_FAN_FULL_SPEED(nr) (0xA4 + (16 * (nr)))
75 #define F71882FG_REG_FAN_STATUS 0x92
76 #define F71882FG_REG_FAN_BEEP 0x93
78 #define F71882FG_REG_TEMP(nr) (0x70 + 2 * (nr))
79 #define F71882FG_REG_TEMP_OVT(nr) (0x80 + 2 * (nr))
80 #define F71882FG_REG_TEMP_HIGH(nr) (0x81 + 2 * (nr))
81 #define F71882FG_REG_TEMP_STATUS 0x62
82 #define F71882FG_REG_TEMP_BEEP 0x63
83 #define F71882FG_REG_TEMP_CONFIG 0x69
84 #define F71882FG_REG_TEMP_HYST(nr) (0x6C + (nr))
85 #define F71882FG_REG_TEMP_TYPE 0x6B
86 #define F71882FG_REG_TEMP_DIODE_OPEN 0x6F
88 #define F71882FG_REG_PWM(nr) (0xA3 + (16 * (nr)))
89 #define F71882FG_REG_PWM_TYPE 0x94
90 #define F71882FG_REG_PWM_ENABLE 0x96
92 #define F71882FG_REG_FAN_HYST(nr) (0x98 + (nr))
94 #define F71882FG_REG_FAN_FAULT_T 0x9F
95 #define F71882FG_FAN_NEG_TEMP_EN 0x20
96 #define F71882FG_FAN_PROG_SEL 0x80
98 #define F71882FG_REG_POINT_PWM(pwm, point) (0xAA + (point) + (16 * (pwm)))
99 #define F71882FG_REG_POINT_TEMP(pwm, point) (0xA6 + (point) + (16 * (pwm)))
100 #define F71882FG_REG_POINT_MAPPING(nr) (0xAF + 16 * (nr))
102 #define F71882FG_REG_START 0x01
104 #define F71882FG_MAX_INS 9
106 #define FAN_MIN_DETECT 366 /* Lowest detectable fanspeed */
108 static unsigned short force_id;
109 module_param(force_id, ushort, 0);
110 MODULE_PARM_DESC(force_id, "Override the detected device ID");
112 enum chips { f71808e, f71808a, f71858fg, f71862fg, f71869, f71869a, f71882fg,
113 f71889fg, f71889ed, f71889a, f8000, f81865f };
115 static const char *f71882fg_names[] = {
116 "f71808e",
117 "f71808a",
118 "f71858fg",
119 "f71862fg",
120 "f71869", /* Both f71869f and f71869e, reg. compatible and same id */
121 "f71869a",
122 "f71882fg",
123 "f71889fg", /* f81801u too, same id */
124 "f71889ed",
125 "f71889a",
126 "f8000",
127 "f81865f",
130 static const char f71882fg_has_in[][F71882FG_MAX_INS] = {
131 [f71808e] = { 1, 1, 1, 1, 1, 1, 0, 1, 1 },
132 [f71808a] = { 1, 1, 1, 1, 0, 0, 0, 1, 1 },
133 [f71858fg] = { 1, 1, 1, 0, 0, 0, 0, 0, 0 },
134 [f71862fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
135 [f71869] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
136 [f71869a] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
137 [f71882fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
138 [f71889fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
139 [f71889ed] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
140 [f71889a] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
141 [f8000] = { 1, 1, 1, 0, 0, 0, 0, 0, 0 },
142 [f81865f] = { 1, 1, 1, 1, 1, 1, 1, 0, 0 },
145 static const char f71882fg_has_in1_alarm[] = {
146 [f71808e] = 0,
147 [f71808a] = 0,
148 [f71858fg] = 0,
149 [f71862fg] = 0,
150 [f71869] = 0,
151 [f71869a] = 0,
152 [f71882fg] = 1,
153 [f71889fg] = 1,
154 [f71889ed] = 1,
155 [f71889a] = 1,
156 [f8000] = 0,
157 [f81865f] = 1,
160 static const char f71882fg_fan_has_beep[] = {
161 [f71808e] = 0,
162 [f71808a] = 0,
163 [f71858fg] = 0,
164 [f71862fg] = 1,
165 [f71869] = 1,
166 [f71869a] = 1,
167 [f71882fg] = 1,
168 [f71889fg] = 1,
169 [f71889ed] = 1,
170 [f71889a] = 1,
171 [f8000] = 0,
172 [f81865f] = 1,
175 static const char f71882fg_nr_fans[] = {
176 [f71808e] = 3,
177 [f71808a] = 2, /* +1 fan which is monitor + simple pwm only */
178 [f71858fg] = 3,
179 [f71862fg] = 3,
180 [f71869] = 3,
181 [f71869a] = 3,
182 [f71882fg] = 4,
183 [f71889fg] = 3,
184 [f71889ed] = 3,
185 [f71889a] = 3,
186 [f8000] = 3, /* +1 fan which is monitor only */
187 [f81865f] = 2,
190 static const char f71882fg_temp_has_beep[] = {
191 [f71808e] = 0,
192 [f71808a] = 1,
193 [f71858fg] = 0,
194 [f71862fg] = 1,
195 [f71869] = 1,
196 [f71869a] = 1,
197 [f71882fg] = 1,
198 [f71889fg] = 1,
199 [f71889ed] = 1,
200 [f71889a] = 1,
201 [f8000] = 0,
202 [f81865f] = 1,
205 static const char f71882fg_nr_temps[] = {
206 [f71808e] = 2,
207 [f71808a] = 2,
208 [f71858fg] = 3,
209 [f71862fg] = 3,
210 [f71869] = 3,
211 [f71869a] = 3,
212 [f71882fg] = 3,
213 [f71889fg] = 3,
214 [f71889ed] = 3,
215 [f71889a] = 3,
216 [f8000] = 3,
217 [f81865f] = 2,
220 static struct platform_device *f71882fg_pdev;
222 /* Super-I/O Function prototypes */
223 static inline int superio_inb(int base, int reg);
224 static inline int superio_inw(int base, int reg);
225 static inline int superio_enter(int base);
226 static inline void superio_select(int base, int ld);
227 static inline void superio_exit(int base);
229 struct f71882fg_sio_data {
230 enum chips type;
233 struct f71882fg_data {
234 unsigned short addr;
235 enum chips type;
236 struct device *hwmon_dev;
238 struct mutex update_lock;
239 int temp_start; /* temp numbering start (0 or 1) */
240 char valid; /* !=0 if following fields are valid */
241 char auto_point_temp_signed;
242 unsigned long last_updated; /* In jiffies */
243 unsigned long last_limits; /* In jiffies */
245 /* Register Values */
246 u8 in[F71882FG_MAX_INS];
247 u8 in1_max;
248 u8 in_status;
249 u8 in_beep;
250 u16 fan[4];
251 u16 fan_target[4];
252 u16 fan_full_speed[4];
253 u8 fan_status;
254 u8 fan_beep;
255 /* Note: all models have max 3 temperature channels, but on some
256 they are addressed as 0-2 and on others as 1-3, so for coding
257 convenience we reserve space for 4 channels */
258 u16 temp[4];
259 u8 temp_ovt[4];
260 u8 temp_high[4];
261 u8 temp_hyst[2]; /* 2 hysts stored per reg */
262 u8 temp_type[4];
263 u8 temp_status;
264 u8 temp_beep;
265 u8 temp_diode_open;
266 u8 temp_config;
267 u8 pwm[4];
268 u8 pwm_enable;
269 u8 pwm_auto_point_hyst[2];
270 u8 pwm_auto_point_mapping[4];
271 u8 pwm_auto_point_pwm[4][5];
272 s8 pwm_auto_point_temp[4][4];
275 /* Sysfs in */
276 static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
277 char *buf);
278 static ssize_t show_in_max(struct device *dev, struct device_attribute
279 *devattr, char *buf);
280 static ssize_t store_in_max(struct device *dev, struct device_attribute
281 *devattr, const char *buf, size_t count);
282 static ssize_t show_in_beep(struct device *dev, struct device_attribute
283 *devattr, char *buf);
284 static ssize_t store_in_beep(struct device *dev, struct device_attribute
285 *devattr, const char *buf, size_t count);
286 static ssize_t show_in_alarm(struct device *dev, struct device_attribute
287 *devattr, char *buf);
288 /* Sysfs Fan */
289 static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
290 char *buf);
291 static ssize_t show_fan_full_speed(struct device *dev,
292 struct device_attribute *devattr, char *buf);
293 static ssize_t store_fan_full_speed(struct device *dev,
294 struct device_attribute *devattr, const char *buf, size_t count);
295 static ssize_t show_fan_beep(struct device *dev, struct device_attribute
296 *devattr, char *buf);
297 static ssize_t store_fan_beep(struct device *dev, struct device_attribute
298 *devattr, const char *buf, size_t count);
299 static ssize_t show_fan_alarm(struct device *dev, struct device_attribute
300 *devattr, char *buf);
301 /* Sysfs Temp */
302 static ssize_t show_temp(struct device *dev, struct device_attribute
303 *devattr, char *buf);
304 static ssize_t show_temp_max(struct device *dev, struct device_attribute
305 *devattr, char *buf);
306 static ssize_t store_temp_max(struct device *dev, struct device_attribute
307 *devattr, const char *buf, size_t count);
308 static ssize_t show_temp_max_hyst(struct device *dev, struct device_attribute
309 *devattr, char *buf);
310 static ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute
311 *devattr, const char *buf, size_t count);
312 static ssize_t show_temp_crit(struct device *dev, struct device_attribute
313 *devattr, char *buf);
314 static ssize_t store_temp_crit(struct device *dev, struct device_attribute
315 *devattr, const char *buf, size_t count);
316 static ssize_t show_temp_crit_hyst(struct device *dev, struct device_attribute
317 *devattr, char *buf);
318 static ssize_t show_temp_type(struct device *dev, struct device_attribute
319 *devattr, char *buf);
320 static ssize_t show_temp_beep(struct device *dev, struct device_attribute
321 *devattr, char *buf);
322 static ssize_t store_temp_beep(struct device *dev, struct device_attribute
323 *devattr, const char *buf, size_t count);
324 static ssize_t show_temp_alarm(struct device *dev, struct device_attribute
325 *devattr, char *buf);
326 static ssize_t show_temp_fault(struct device *dev, struct device_attribute
327 *devattr, char *buf);
328 /* PWM and Auto point control */
329 static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr,
330 char *buf);
331 static ssize_t store_pwm(struct device *dev, struct device_attribute *devattr,
332 const char *buf, size_t count);
333 static ssize_t show_simple_pwm(struct device *dev,
334 struct device_attribute *devattr, char *buf);
335 static ssize_t store_simple_pwm(struct device *dev,
336 struct device_attribute *devattr, const char *buf, size_t count);
337 static ssize_t show_pwm_enable(struct device *dev,
338 struct device_attribute *devattr, char *buf);
339 static ssize_t store_pwm_enable(struct device *dev,
340 struct device_attribute *devattr, const char *buf, size_t count);
341 static ssize_t show_pwm_interpolate(struct device *dev,
342 struct device_attribute *devattr, char *buf);
343 static ssize_t store_pwm_interpolate(struct device *dev,
344 struct device_attribute *devattr, const char *buf, size_t count);
345 static ssize_t show_pwm_auto_point_channel(struct device *dev,
346 struct device_attribute *devattr, char *buf);
347 static ssize_t store_pwm_auto_point_channel(struct device *dev,
348 struct device_attribute *devattr, const char *buf, size_t count);
349 static ssize_t show_pwm_auto_point_temp_hyst(struct device *dev,
350 struct device_attribute *devattr, char *buf);
351 static ssize_t store_pwm_auto_point_temp_hyst(struct device *dev,
352 struct device_attribute *devattr, const char *buf, size_t count);
353 static ssize_t show_pwm_auto_point_pwm(struct device *dev,
354 struct device_attribute *devattr, char *buf);
355 static ssize_t store_pwm_auto_point_pwm(struct device *dev,
356 struct device_attribute *devattr, const char *buf, size_t count);
357 static ssize_t show_pwm_auto_point_temp(struct device *dev,
358 struct device_attribute *devattr, char *buf);
359 static ssize_t store_pwm_auto_point_temp(struct device *dev,
360 struct device_attribute *devattr, const char *buf, size_t count);
361 /* Sysfs misc */
362 static ssize_t show_name(struct device *dev, struct device_attribute *devattr,
363 char *buf);
365 static int __devinit f71882fg_probe(struct platform_device * pdev);
366 static int f71882fg_remove(struct platform_device *pdev);
368 static struct platform_driver f71882fg_driver = {
369 .driver = {
370 .owner = THIS_MODULE,
371 .name = DRVNAME,
373 .probe = f71882fg_probe,
374 .remove = f71882fg_remove,
377 static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
379 /* Temp attr for the f71858fg, the f71858fg is special as it has its
380 temperature indexes start at 0 (the others start at 1) */
381 static struct sensor_device_attribute_2 f71858fg_temp_attr[] = {
382 SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0),
383 SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max,
384 store_temp_max, 0, 0),
385 SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
386 store_temp_max_hyst, 0, 0),
387 SENSOR_ATTR_2(temp1_max_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 0),
388 SENSOR_ATTR_2(temp1_crit, S_IRUGO|S_IWUSR, show_temp_crit,
389 store_temp_crit, 0, 0),
390 SENSOR_ATTR_2(temp1_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
391 0, 0),
392 SENSOR_ATTR_2(temp1_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 4),
393 SENSOR_ATTR_2(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0, 0),
394 SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1),
395 SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_max,
396 store_temp_max, 0, 1),
397 SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
398 store_temp_max_hyst, 0, 1),
399 SENSOR_ATTR_2(temp2_max_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 1),
400 SENSOR_ATTR_2(temp2_crit, S_IRUGO|S_IWUSR, show_temp_crit,
401 store_temp_crit, 0, 1),
402 SENSOR_ATTR_2(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
403 0, 1),
404 SENSOR_ATTR_2(temp2_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5),
405 SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 1),
406 SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2),
407 SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max,
408 store_temp_max, 0, 2),
409 SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
410 store_temp_max_hyst, 0, 2),
411 SENSOR_ATTR_2(temp3_max_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 2),
412 SENSOR_ATTR_2(temp3_crit, S_IRUGO|S_IWUSR, show_temp_crit,
413 store_temp_crit, 0, 2),
414 SENSOR_ATTR_2(temp3_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
415 0, 2),
416 SENSOR_ATTR_2(temp3_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6),
417 SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
420 /* Temp attr for the standard models */
421 static struct sensor_device_attribute_2 fxxxx_temp_attr[3][9] = { {
422 SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 1),
423 SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max,
424 store_temp_max, 0, 1),
425 SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
426 store_temp_max_hyst, 0, 1),
427 /* Should really be temp1_max_alarm, but older versions did not handle
428 the max and crit alarms separately and lm_sensors v2 depends on the
429 presence of temp#_alarm files. The same goes for temp2/3 _alarm. */
430 SENSOR_ATTR_2(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 1),
431 SENSOR_ATTR_2(temp1_crit, S_IRUGO|S_IWUSR, show_temp_crit,
432 store_temp_crit, 0, 1),
433 SENSOR_ATTR_2(temp1_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
434 0, 1),
435 SENSOR_ATTR_2(temp1_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5),
436 SENSOR_ATTR_2(temp1_type, S_IRUGO, show_temp_type, NULL, 0, 1),
437 SENSOR_ATTR_2(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0, 1),
438 }, {
439 SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 2),
440 SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_max,
441 store_temp_max, 0, 2),
442 SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
443 store_temp_max_hyst, 0, 2),
444 /* Should be temp2_max_alarm, see temp1_alarm note */
445 SENSOR_ATTR_2(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 2),
446 SENSOR_ATTR_2(temp2_crit, S_IRUGO|S_IWUSR, show_temp_crit,
447 store_temp_crit, 0, 2),
448 SENSOR_ATTR_2(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
449 0, 2),
450 SENSOR_ATTR_2(temp2_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6),
451 SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 2),
452 SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
453 }, {
454 SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 3),
455 SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max,
456 store_temp_max, 0, 3),
457 SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
458 store_temp_max_hyst, 0, 3),
459 /* Should be temp3_max_alarm, see temp1_alarm note */
460 SENSOR_ATTR_2(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 3),
461 SENSOR_ATTR_2(temp3_crit, S_IRUGO|S_IWUSR, show_temp_crit,
462 store_temp_crit, 0, 3),
463 SENSOR_ATTR_2(temp3_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
464 0, 3),
465 SENSOR_ATTR_2(temp3_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 7),
466 SENSOR_ATTR_2(temp3_type, S_IRUGO, show_temp_type, NULL, 0, 3),
467 SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 3),
468 } };
470 /* Temp attr for models which can beep on temp alarm */
471 static struct sensor_device_attribute_2 fxxxx_temp_beep_attr[3][2] = { {
472 SENSOR_ATTR_2(temp1_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
473 store_temp_beep, 0, 1),
474 SENSOR_ATTR_2(temp1_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
475 store_temp_beep, 0, 5),
476 }, {
477 SENSOR_ATTR_2(temp2_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
478 store_temp_beep, 0, 2),
479 SENSOR_ATTR_2(temp2_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
480 store_temp_beep, 0, 6),
481 }, {
482 SENSOR_ATTR_2(temp3_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
483 store_temp_beep, 0, 3),
484 SENSOR_ATTR_2(temp3_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
485 store_temp_beep, 0, 7),
486 } };
488 /* Temp attr for the f8000
489 Note on the f8000 temp_ovt (crit) is used as max, and temp_high (max)
490 is used as hysteresis value to clear alarms
491 Also like the f71858fg its temperature indexes start at 0
493 static struct sensor_device_attribute_2 f8000_temp_attr[] = {
494 SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0),
495 SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_crit,
496 store_temp_crit, 0, 0),
497 SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max,
498 store_temp_max, 0, 0),
499 SENSOR_ATTR_2(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 4),
500 SENSOR_ATTR_2(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0, 0),
501 SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1),
502 SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_crit,
503 store_temp_crit, 0, 1),
504 SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max,
505 store_temp_max, 0, 1),
506 SENSOR_ATTR_2(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5),
507 SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 1),
508 SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2),
509 SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_crit,
510 store_temp_crit, 0, 2),
511 SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max,
512 store_temp_max, 0, 2),
513 SENSOR_ATTR_2(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6),
514 SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
517 /* in attr for all models */
518 static struct sensor_device_attribute_2 fxxxx_in_attr[] = {
519 SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
520 SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
521 SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
522 SENSOR_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 0, 3),
523 SENSOR_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 0, 4),
524 SENSOR_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 0, 5),
525 SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 6),
526 SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 7),
527 SENSOR_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 0, 8),
530 /* For models with in1 alarm capability */
531 static struct sensor_device_attribute_2 fxxxx_in1_alarm_attr[] = {
532 SENSOR_ATTR_2(in1_max, S_IRUGO|S_IWUSR, show_in_max, store_in_max,
533 0, 1),
534 SENSOR_ATTR_2(in1_beep, S_IRUGO|S_IWUSR, show_in_beep, store_in_beep,
535 0, 1),
536 SENSOR_ATTR_2(in1_alarm, S_IRUGO, show_in_alarm, NULL, 0, 1),
539 /* Fan / PWM attr common to all models */
540 static struct sensor_device_attribute_2 fxxxx_fan_attr[4][6] = { {
541 SENSOR_ATTR_2(fan1_input, S_IRUGO, show_fan, NULL, 0, 0),
542 SENSOR_ATTR_2(fan1_full_speed, S_IRUGO|S_IWUSR,
543 show_fan_full_speed,
544 store_fan_full_speed, 0, 0),
545 SENSOR_ATTR_2(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 0),
546 SENSOR_ATTR_2(pwm1, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 0),
547 SENSOR_ATTR_2(pwm1_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
548 store_pwm_enable, 0, 0),
549 SENSOR_ATTR_2(pwm1_interpolate, S_IRUGO|S_IWUSR,
550 show_pwm_interpolate, store_pwm_interpolate, 0, 0),
551 }, {
552 SENSOR_ATTR_2(fan2_input, S_IRUGO, show_fan, NULL, 0, 1),
553 SENSOR_ATTR_2(fan2_full_speed, S_IRUGO|S_IWUSR,
554 show_fan_full_speed,
555 store_fan_full_speed, 0, 1),
556 SENSOR_ATTR_2(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 1),
557 SENSOR_ATTR_2(pwm2, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 1),
558 SENSOR_ATTR_2(pwm2_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
559 store_pwm_enable, 0, 1),
560 SENSOR_ATTR_2(pwm2_interpolate, S_IRUGO|S_IWUSR,
561 show_pwm_interpolate, store_pwm_interpolate, 0, 1),
562 }, {
563 SENSOR_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 0, 2),
564 SENSOR_ATTR_2(fan3_full_speed, S_IRUGO|S_IWUSR,
565 show_fan_full_speed,
566 store_fan_full_speed, 0, 2),
567 SENSOR_ATTR_2(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 2),
568 SENSOR_ATTR_2(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 2),
569 SENSOR_ATTR_2(pwm3_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
570 store_pwm_enable, 0, 2),
571 SENSOR_ATTR_2(pwm3_interpolate, S_IRUGO|S_IWUSR,
572 show_pwm_interpolate, store_pwm_interpolate, 0, 2),
573 }, {
574 SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
575 SENSOR_ATTR_2(fan4_full_speed, S_IRUGO|S_IWUSR,
576 show_fan_full_speed,
577 store_fan_full_speed, 0, 3),
578 SENSOR_ATTR_2(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 3),
579 SENSOR_ATTR_2(pwm4, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 3),
580 SENSOR_ATTR_2(pwm4_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
581 store_pwm_enable, 0, 3),
582 SENSOR_ATTR_2(pwm4_interpolate, S_IRUGO|S_IWUSR,
583 show_pwm_interpolate, store_pwm_interpolate, 0, 3),
584 } };
586 /* Attr for the third fan of the f71808a, which only has manual pwm */
587 static struct sensor_device_attribute_2 f71808a_fan3_attr[] = {
588 SENSOR_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 0, 2),
589 SENSOR_ATTR_2(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 2),
590 SENSOR_ATTR_2(pwm3, S_IRUGO|S_IWUSR,
591 show_simple_pwm, store_simple_pwm, 0, 2),
594 /* Attr for models which can beep on Fan alarm */
595 static struct sensor_device_attribute_2 fxxxx_fan_beep_attr[] = {
596 SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep,
597 store_fan_beep, 0, 0),
598 SENSOR_ATTR_2(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep,
599 store_fan_beep, 0, 1),
600 SENSOR_ATTR_2(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep,
601 store_fan_beep, 0, 2),
602 SENSOR_ATTR_2(fan4_beep, S_IRUGO|S_IWUSR, show_fan_beep,
603 store_fan_beep, 0, 3),
606 /* PWM attr for the f71862fg, fewer pwms and fewer zones per pwm than the
607 standard models */
608 static struct sensor_device_attribute_2 f71862fg_auto_pwm_attr[3][7] = { {
609 SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
610 show_pwm_auto_point_channel,
611 store_pwm_auto_point_channel, 0, 0),
612 SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,
613 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
614 1, 0),
615 SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO|S_IWUSR,
616 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
617 4, 0),
618 SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IRUGO|S_IWUSR,
619 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
620 0, 0),
621 SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IRUGO|S_IWUSR,
622 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
623 3, 0),
624 SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
625 show_pwm_auto_point_temp_hyst,
626 store_pwm_auto_point_temp_hyst,
627 0, 0),
628 SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO,
629 show_pwm_auto_point_temp_hyst, NULL, 3, 0),
630 }, {
631 SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,
632 show_pwm_auto_point_channel,
633 store_pwm_auto_point_channel, 0, 1),
634 SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR,
635 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
636 1, 1),
637 SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO|S_IWUSR,
638 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
639 4, 1),
640 SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IRUGO|S_IWUSR,
641 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
642 0, 1),
643 SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IRUGO|S_IWUSR,
644 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
645 3, 1),
646 SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
647 show_pwm_auto_point_temp_hyst,
648 store_pwm_auto_point_temp_hyst,
649 0, 1),
650 SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO,
651 show_pwm_auto_point_temp_hyst, NULL, 3, 1),
652 }, {
653 SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
654 show_pwm_auto_point_channel,
655 store_pwm_auto_point_channel, 0, 2),
656 SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR,
657 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
658 1, 2),
659 SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO|S_IWUSR,
660 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
661 4, 2),
662 SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IRUGO|S_IWUSR,
663 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
664 0, 2),
665 SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IRUGO|S_IWUSR,
666 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
667 3, 2),
668 SENSOR_ATTR_2(pwm3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
669 show_pwm_auto_point_temp_hyst,
670 store_pwm_auto_point_temp_hyst,
671 0, 2),
672 SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst, S_IRUGO,
673 show_pwm_auto_point_temp_hyst, NULL, 3, 2),
674 } };
676 /* PWM attr for the f71808e/f71869, almost identical to the f71862fg, but the
677 pwm setting when the temperature is above the pwmX_auto_point1_temp can be
678 programmed instead of being hardcoded to 0xff */
679 static struct sensor_device_attribute_2 f71869_auto_pwm_attr[3][8] = { {
680 SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
681 show_pwm_auto_point_channel,
682 store_pwm_auto_point_channel, 0, 0),
683 SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,
684 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
685 0, 0),
686 SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO|S_IWUSR,
687 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
688 1, 0),
689 SENSOR_ATTR_2(pwm1_auto_point3_pwm, S_IRUGO|S_IWUSR,
690 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
691 4, 0),
692 SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IRUGO|S_IWUSR,
693 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
694 0, 0),
695 SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IRUGO|S_IWUSR,
696 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
697 3, 0),
698 SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
699 show_pwm_auto_point_temp_hyst,
700 store_pwm_auto_point_temp_hyst,
701 0, 0),
702 SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO,
703 show_pwm_auto_point_temp_hyst, NULL, 3, 0),
704 }, {
705 SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,
706 show_pwm_auto_point_channel,
707 store_pwm_auto_point_channel, 0, 1),
708 SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR,
709 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
710 0, 1),
711 SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO|S_IWUSR,
712 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
713 1, 1),
714 SENSOR_ATTR_2(pwm2_auto_point3_pwm, S_IRUGO|S_IWUSR,
715 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
716 4, 1),
717 SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IRUGO|S_IWUSR,
718 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
719 0, 1),
720 SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IRUGO|S_IWUSR,
721 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
722 3, 1),
723 SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
724 show_pwm_auto_point_temp_hyst,
725 store_pwm_auto_point_temp_hyst,
726 0, 1),
727 SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO,
728 show_pwm_auto_point_temp_hyst, NULL, 3, 1),
729 }, {
730 SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
731 show_pwm_auto_point_channel,
732 store_pwm_auto_point_channel, 0, 2),
733 SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR,
734 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
735 0, 2),
736 SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO|S_IWUSR,
737 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
738 1, 2),
739 SENSOR_ATTR_2(pwm3_auto_point3_pwm, S_IRUGO|S_IWUSR,
740 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
741 4, 2),
742 SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IRUGO|S_IWUSR,
743 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
744 0, 2),
745 SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IRUGO|S_IWUSR,
746 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
747 3, 2),
748 SENSOR_ATTR_2(pwm3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
749 show_pwm_auto_point_temp_hyst,
750 store_pwm_auto_point_temp_hyst,
751 0, 2),
752 SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst, S_IRUGO,
753 show_pwm_auto_point_temp_hyst, NULL, 3, 2),
754 } };
756 /* PWM attr for the standard models */
757 static struct sensor_device_attribute_2 fxxxx_auto_pwm_attr[4][14] = { {
758 SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
759 show_pwm_auto_point_channel,
760 store_pwm_auto_point_channel, 0, 0),
761 SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,
762 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
763 0, 0),
764 SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO|S_IWUSR,
765 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
766 1, 0),
767 SENSOR_ATTR_2(pwm1_auto_point3_pwm, S_IRUGO|S_IWUSR,
768 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
769 2, 0),
770 SENSOR_ATTR_2(pwm1_auto_point4_pwm, S_IRUGO|S_IWUSR,
771 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
772 3, 0),
773 SENSOR_ATTR_2(pwm1_auto_point5_pwm, S_IRUGO|S_IWUSR,
774 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
775 4, 0),
776 SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IRUGO|S_IWUSR,
777 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
778 0, 0),
779 SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IRUGO|S_IWUSR,
780 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
781 1, 0),
782 SENSOR_ATTR_2(pwm1_auto_point3_temp, S_IRUGO|S_IWUSR,
783 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
784 2, 0),
785 SENSOR_ATTR_2(pwm1_auto_point4_temp, S_IRUGO|S_IWUSR,
786 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
787 3, 0),
788 SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
789 show_pwm_auto_point_temp_hyst,
790 store_pwm_auto_point_temp_hyst,
791 0, 0),
792 SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO,
793 show_pwm_auto_point_temp_hyst, NULL, 1, 0),
794 SENSOR_ATTR_2(pwm1_auto_point3_temp_hyst, S_IRUGO,
795 show_pwm_auto_point_temp_hyst, NULL, 2, 0),
796 SENSOR_ATTR_2(pwm1_auto_point4_temp_hyst, S_IRUGO,
797 show_pwm_auto_point_temp_hyst, NULL, 3, 0),
798 }, {
799 SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,
800 show_pwm_auto_point_channel,
801 store_pwm_auto_point_channel, 0, 1),
802 SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR,
803 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
804 0, 1),
805 SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO|S_IWUSR,
806 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
807 1, 1),
808 SENSOR_ATTR_2(pwm2_auto_point3_pwm, S_IRUGO|S_IWUSR,
809 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
810 2, 1),
811 SENSOR_ATTR_2(pwm2_auto_point4_pwm, S_IRUGO|S_IWUSR,
812 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
813 3, 1),
814 SENSOR_ATTR_2(pwm2_auto_point5_pwm, S_IRUGO|S_IWUSR,
815 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
816 4, 1),
817 SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IRUGO|S_IWUSR,
818 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
819 0, 1),
820 SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IRUGO|S_IWUSR,
821 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
822 1, 1),
823 SENSOR_ATTR_2(pwm2_auto_point3_temp, S_IRUGO|S_IWUSR,
824 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
825 2, 1),
826 SENSOR_ATTR_2(pwm2_auto_point4_temp, S_IRUGO|S_IWUSR,
827 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
828 3, 1),
829 SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
830 show_pwm_auto_point_temp_hyst,
831 store_pwm_auto_point_temp_hyst,
832 0, 1),
833 SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO,
834 show_pwm_auto_point_temp_hyst, NULL, 1, 1),
835 SENSOR_ATTR_2(pwm2_auto_point3_temp_hyst, S_IRUGO,
836 show_pwm_auto_point_temp_hyst, NULL, 2, 1),
837 SENSOR_ATTR_2(pwm2_auto_point4_temp_hyst, S_IRUGO,
838 show_pwm_auto_point_temp_hyst, NULL, 3, 1),
839 }, {
840 SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
841 show_pwm_auto_point_channel,
842 store_pwm_auto_point_channel, 0, 2),
843 SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR,
844 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
845 0, 2),
846 SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO|S_IWUSR,
847 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
848 1, 2),
849 SENSOR_ATTR_2(pwm3_auto_point3_pwm, S_IRUGO|S_IWUSR,
850 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
851 2, 2),
852 SENSOR_ATTR_2(pwm3_auto_point4_pwm, S_IRUGO|S_IWUSR,
853 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
854 3, 2),
855 SENSOR_ATTR_2(pwm3_auto_point5_pwm, S_IRUGO|S_IWUSR,
856 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
857 4, 2),
858 SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IRUGO|S_IWUSR,
859 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
860 0, 2),
861 SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IRUGO|S_IWUSR,
862 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
863 1, 2),
864 SENSOR_ATTR_2(pwm3_auto_point3_temp, S_IRUGO|S_IWUSR,
865 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
866 2, 2),
867 SENSOR_ATTR_2(pwm3_auto_point4_temp, S_IRUGO|S_IWUSR,
868 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
869 3, 2),
870 SENSOR_ATTR_2(pwm3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
871 show_pwm_auto_point_temp_hyst,
872 store_pwm_auto_point_temp_hyst,
873 0, 2),
874 SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst, S_IRUGO,
875 show_pwm_auto_point_temp_hyst, NULL, 1, 2),
876 SENSOR_ATTR_2(pwm3_auto_point3_temp_hyst, S_IRUGO,
877 show_pwm_auto_point_temp_hyst, NULL, 2, 2),
878 SENSOR_ATTR_2(pwm3_auto_point4_temp_hyst, S_IRUGO,
879 show_pwm_auto_point_temp_hyst, NULL, 3, 2),
880 }, {
881 SENSOR_ATTR_2(pwm4_auto_channels_temp, S_IRUGO|S_IWUSR,
882 show_pwm_auto_point_channel,
883 store_pwm_auto_point_channel, 0, 3),
884 SENSOR_ATTR_2(pwm4_auto_point1_pwm, S_IRUGO|S_IWUSR,
885 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
886 0, 3),
887 SENSOR_ATTR_2(pwm4_auto_point2_pwm, S_IRUGO|S_IWUSR,
888 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
889 1, 3),
890 SENSOR_ATTR_2(pwm4_auto_point3_pwm, S_IRUGO|S_IWUSR,
891 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
892 2, 3),
893 SENSOR_ATTR_2(pwm4_auto_point4_pwm, S_IRUGO|S_IWUSR,
894 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
895 3, 3),
896 SENSOR_ATTR_2(pwm4_auto_point5_pwm, S_IRUGO|S_IWUSR,
897 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
898 4, 3),
899 SENSOR_ATTR_2(pwm4_auto_point1_temp, S_IRUGO|S_IWUSR,
900 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
901 0, 3),
902 SENSOR_ATTR_2(pwm4_auto_point2_temp, S_IRUGO|S_IWUSR,
903 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
904 1, 3),
905 SENSOR_ATTR_2(pwm4_auto_point3_temp, S_IRUGO|S_IWUSR,
906 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
907 2, 3),
908 SENSOR_ATTR_2(pwm4_auto_point4_temp, S_IRUGO|S_IWUSR,
909 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
910 3, 3),
911 SENSOR_ATTR_2(pwm4_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
912 show_pwm_auto_point_temp_hyst,
913 store_pwm_auto_point_temp_hyst,
914 0, 3),
915 SENSOR_ATTR_2(pwm4_auto_point2_temp_hyst, S_IRUGO,
916 show_pwm_auto_point_temp_hyst, NULL, 1, 3),
917 SENSOR_ATTR_2(pwm4_auto_point3_temp_hyst, S_IRUGO,
918 show_pwm_auto_point_temp_hyst, NULL, 2, 3),
919 SENSOR_ATTR_2(pwm4_auto_point4_temp_hyst, S_IRUGO,
920 show_pwm_auto_point_temp_hyst, NULL, 3, 3),
921 } };
923 /* Fan attr specific to the f8000 (4th fan input can only measure speed) */
924 static struct sensor_device_attribute_2 f8000_fan_attr[] = {
925 SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
928 /* PWM attr for the f8000, zones mapped to temp instead of to pwm!
929 Also the register block at offset A0 maps to TEMP1 (so our temp2, as the
930 F8000 starts counting temps at 0), B0 maps the TEMP2 and C0 maps to TEMP0 */
931 static struct sensor_device_attribute_2 f8000_auto_pwm_attr[3][14] = { {
932 SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
933 show_pwm_auto_point_channel,
934 store_pwm_auto_point_channel, 0, 0),
935 SENSOR_ATTR_2(temp1_auto_point1_pwm, S_IRUGO|S_IWUSR,
936 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
937 0, 2),
938 SENSOR_ATTR_2(temp1_auto_point2_pwm, S_IRUGO|S_IWUSR,
939 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
940 1, 2),
941 SENSOR_ATTR_2(temp1_auto_point3_pwm, S_IRUGO|S_IWUSR,
942 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
943 2, 2),
944 SENSOR_ATTR_2(temp1_auto_point4_pwm, S_IRUGO|S_IWUSR,
945 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
946 3, 2),
947 SENSOR_ATTR_2(temp1_auto_point5_pwm, S_IRUGO|S_IWUSR,
948 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
949 4, 2),
950 SENSOR_ATTR_2(temp1_auto_point1_temp, S_IRUGO|S_IWUSR,
951 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
952 0, 2),
953 SENSOR_ATTR_2(temp1_auto_point2_temp, S_IRUGO|S_IWUSR,
954 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
955 1, 2),
956 SENSOR_ATTR_2(temp1_auto_point3_temp, S_IRUGO|S_IWUSR,
957 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
958 2, 2),
959 SENSOR_ATTR_2(temp1_auto_point4_temp, S_IRUGO|S_IWUSR,
960 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
961 3, 2),
962 SENSOR_ATTR_2(temp1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
963 show_pwm_auto_point_temp_hyst,
964 store_pwm_auto_point_temp_hyst,
965 0, 2),
966 SENSOR_ATTR_2(temp1_auto_point2_temp_hyst, S_IRUGO,
967 show_pwm_auto_point_temp_hyst, NULL, 1, 2),
968 SENSOR_ATTR_2(temp1_auto_point3_temp_hyst, S_IRUGO,
969 show_pwm_auto_point_temp_hyst, NULL, 2, 2),
970 SENSOR_ATTR_2(temp1_auto_point4_temp_hyst, S_IRUGO,
971 show_pwm_auto_point_temp_hyst, NULL, 3, 2),
972 }, {
973 SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,
974 show_pwm_auto_point_channel,
975 store_pwm_auto_point_channel, 0, 1),
976 SENSOR_ATTR_2(temp2_auto_point1_pwm, S_IRUGO|S_IWUSR,
977 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
978 0, 0),
979 SENSOR_ATTR_2(temp2_auto_point2_pwm, S_IRUGO|S_IWUSR,
980 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
981 1, 0),
982 SENSOR_ATTR_2(temp2_auto_point3_pwm, S_IRUGO|S_IWUSR,
983 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
984 2, 0),
985 SENSOR_ATTR_2(temp2_auto_point4_pwm, S_IRUGO|S_IWUSR,
986 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
987 3, 0),
988 SENSOR_ATTR_2(temp2_auto_point5_pwm, S_IRUGO|S_IWUSR,
989 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
990 4, 0),
991 SENSOR_ATTR_2(temp2_auto_point1_temp, S_IRUGO|S_IWUSR,
992 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
993 0, 0),
994 SENSOR_ATTR_2(temp2_auto_point2_temp, S_IRUGO|S_IWUSR,
995 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
996 1, 0),
997 SENSOR_ATTR_2(temp2_auto_point3_temp, S_IRUGO|S_IWUSR,
998 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
999 2, 0),
1000 SENSOR_ATTR_2(temp2_auto_point4_temp, S_IRUGO|S_IWUSR,
1001 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
1002 3, 0),
1003 SENSOR_ATTR_2(temp2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
1004 show_pwm_auto_point_temp_hyst,
1005 store_pwm_auto_point_temp_hyst,
1006 0, 0),
1007 SENSOR_ATTR_2(temp2_auto_point2_temp_hyst, S_IRUGO,
1008 show_pwm_auto_point_temp_hyst, NULL, 1, 0),
1009 SENSOR_ATTR_2(temp2_auto_point3_temp_hyst, S_IRUGO,
1010 show_pwm_auto_point_temp_hyst, NULL, 2, 0),
1011 SENSOR_ATTR_2(temp2_auto_point4_temp_hyst, S_IRUGO,
1012 show_pwm_auto_point_temp_hyst, NULL, 3, 0),
1013 }, {
1014 SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
1015 show_pwm_auto_point_channel,
1016 store_pwm_auto_point_channel, 0, 2),
1017 SENSOR_ATTR_2(temp3_auto_point1_pwm, S_IRUGO|S_IWUSR,
1018 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
1019 0, 1),
1020 SENSOR_ATTR_2(temp3_auto_point2_pwm, S_IRUGO|S_IWUSR,
1021 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
1022 1, 1),
1023 SENSOR_ATTR_2(temp3_auto_point3_pwm, S_IRUGO|S_IWUSR,
1024 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
1025 2, 1),
1026 SENSOR_ATTR_2(temp3_auto_point4_pwm, S_IRUGO|S_IWUSR,
1027 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
1028 3, 1),
1029 SENSOR_ATTR_2(temp3_auto_point5_pwm, S_IRUGO|S_IWUSR,
1030 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
1031 4, 1),
1032 SENSOR_ATTR_2(temp3_auto_point1_temp, S_IRUGO|S_IWUSR,
1033 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
1034 0, 1),
1035 SENSOR_ATTR_2(temp3_auto_point2_temp, S_IRUGO|S_IWUSR,
1036 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
1037 1, 1),
1038 SENSOR_ATTR_2(temp3_auto_point3_temp, S_IRUGO|S_IWUSR,
1039 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
1040 2, 1),
1041 SENSOR_ATTR_2(temp3_auto_point4_temp, S_IRUGO|S_IWUSR,
1042 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
1043 3, 1),
1044 SENSOR_ATTR_2(temp3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
1045 show_pwm_auto_point_temp_hyst,
1046 store_pwm_auto_point_temp_hyst,
1047 0, 1),
1048 SENSOR_ATTR_2(temp3_auto_point2_temp_hyst, S_IRUGO,
1049 show_pwm_auto_point_temp_hyst, NULL, 1, 1),
1050 SENSOR_ATTR_2(temp3_auto_point3_temp_hyst, S_IRUGO,
1051 show_pwm_auto_point_temp_hyst, NULL, 2, 1),
1052 SENSOR_ATTR_2(temp3_auto_point4_temp_hyst, S_IRUGO,
1053 show_pwm_auto_point_temp_hyst, NULL, 3, 1),
1054 } };
1056 /* Super I/O functions */
1057 static inline int superio_inb(int base, int reg)
1059 outb(reg, base);
1060 return inb(base + 1);
1063 static int superio_inw(int base, int reg)
1065 int val;
1066 val = superio_inb(base, reg) << 8;
1067 val |= superio_inb(base, reg + 1);
1068 return val;
1071 static inline int superio_enter(int base)
1073 /* Don't step on other drivers' I/O space by accident */
1074 if (!request_muxed_region(base, 2, DRVNAME)) {
1075 pr_err("I/O address 0x%04x already in use\n", base);
1076 return -EBUSY;
1079 /* according to the datasheet the key must be send twice! */
1080 outb(SIO_UNLOCK_KEY, base);
1081 outb(SIO_UNLOCK_KEY, base);
1083 return 0;
1086 static inline void superio_select(int base, int ld)
1088 outb(SIO_REG_LDSEL, base);
1089 outb(ld, base + 1);
1092 static inline void superio_exit(int base)
1094 outb(SIO_LOCK_KEY, base);
1095 release_region(base, 2);
1098 static inline int fan_from_reg(u16 reg)
1100 return reg ? (1500000 / reg) : 0;
1103 static inline u16 fan_to_reg(int fan)
1105 return fan ? (1500000 / fan) : 0;
1108 static u8 f71882fg_read8(struct f71882fg_data *data, u8 reg)
1110 u8 val;
1112 outb(reg, data->addr + ADDR_REG_OFFSET);
1113 val = inb(data->addr + DATA_REG_OFFSET);
1115 return val;
1118 static u16 f71882fg_read16(struct f71882fg_data *data, u8 reg)
1120 u16 val;
1122 val = f71882fg_read8(data, reg) << 8;
1123 val |= f71882fg_read8(data, reg + 1);
1125 return val;
1128 static void f71882fg_write8(struct f71882fg_data *data, u8 reg, u8 val)
1130 outb(reg, data->addr + ADDR_REG_OFFSET);
1131 outb(val, data->addr + DATA_REG_OFFSET);
1134 static void f71882fg_write16(struct f71882fg_data *data, u8 reg, u16 val)
1136 f71882fg_write8(data, reg, val >> 8);
1137 f71882fg_write8(data, reg + 1, val & 0xff);
1140 static u16 f71882fg_read_temp(struct f71882fg_data *data, int nr)
1142 if (data->type == f71858fg)
1143 return f71882fg_read16(data, F71882FG_REG_TEMP(nr));
1144 else
1145 return f71882fg_read8(data, F71882FG_REG_TEMP(nr));
1148 static struct f71882fg_data *f71882fg_update_device(struct device *dev)
1150 struct f71882fg_data *data = dev_get_drvdata(dev);
1151 int nr_fans = f71882fg_nr_fans[data->type];
1152 int nr_temps = f71882fg_nr_temps[data->type];
1153 int nr, reg, point;
1155 mutex_lock(&data->update_lock);
1157 /* Update once every 60 seconds */
1158 if (time_after(jiffies, data->last_limits + 60 * HZ) ||
1159 !data->valid) {
1160 if (f71882fg_has_in1_alarm[data->type]) {
1161 data->in1_max =
1162 f71882fg_read8(data, F71882FG_REG_IN1_HIGH);
1163 data->in_beep =
1164 f71882fg_read8(data, F71882FG_REG_IN_BEEP);
1167 /* Get High & boundary temps*/
1168 for (nr = data->temp_start; nr < nr_temps + data->temp_start;
1169 nr++) {
1170 data->temp_ovt[nr] = f71882fg_read8(data,
1171 F71882FG_REG_TEMP_OVT(nr));
1172 data->temp_high[nr] = f71882fg_read8(data,
1173 F71882FG_REG_TEMP_HIGH(nr));
1176 if (data->type != f8000) {
1177 data->temp_hyst[0] = f71882fg_read8(data,
1178 F71882FG_REG_TEMP_HYST(0));
1179 data->temp_hyst[1] = f71882fg_read8(data,
1180 F71882FG_REG_TEMP_HYST(1));
1182 /* All but the f71858fg / f8000 have this register */
1183 if ((data->type != f71858fg) && (data->type != f8000)) {
1184 reg = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE);
1185 data->temp_type[1] = (reg & 0x02) ? 2 : 4;
1186 data->temp_type[2] = (reg & 0x04) ? 2 : 4;
1187 data->temp_type[3] = (reg & 0x08) ? 2 : 4;
1190 if (f71882fg_fan_has_beep[data->type])
1191 data->fan_beep = f71882fg_read8(data,
1192 F71882FG_REG_FAN_BEEP);
1194 if (f71882fg_temp_has_beep[data->type])
1195 data->temp_beep = f71882fg_read8(data,
1196 F71882FG_REG_TEMP_BEEP);
1198 data->pwm_enable = f71882fg_read8(data,
1199 F71882FG_REG_PWM_ENABLE);
1200 data->pwm_auto_point_hyst[0] =
1201 f71882fg_read8(data, F71882FG_REG_FAN_HYST(0));
1202 data->pwm_auto_point_hyst[1] =
1203 f71882fg_read8(data, F71882FG_REG_FAN_HYST(1));
1205 for (nr = 0; nr < nr_fans; nr++) {
1206 data->pwm_auto_point_mapping[nr] =
1207 f71882fg_read8(data,
1208 F71882FG_REG_POINT_MAPPING(nr));
1210 switch (data->type) {
1211 default:
1212 for (point = 0; point < 5; point++) {
1213 data->pwm_auto_point_pwm[nr][point] =
1214 f71882fg_read8(data,
1215 F71882FG_REG_POINT_PWM
1216 (nr, point));
1218 for (point = 0; point < 4; point++) {
1219 data->pwm_auto_point_temp[nr][point] =
1220 f71882fg_read8(data,
1221 F71882FG_REG_POINT_TEMP
1222 (nr, point));
1224 break;
1225 case f71808e:
1226 case f71869:
1227 data->pwm_auto_point_pwm[nr][0] =
1228 f71882fg_read8(data,
1229 F71882FG_REG_POINT_PWM(nr, 0));
1230 /* Fall through */
1231 case f71862fg:
1232 data->pwm_auto_point_pwm[nr][1] =
1233 f71882fg_read8(data,
1234 F71882FG_REG_POINT_PWM
1235 (nr, 1));
1236 data->pwm_auto_point_pwm[nr][4] =
1237 f71882fg_read8(data,
1238 F71882FG_REG_POINT_PWM
1239 (nr, 4));
1240 data->pwm_auto_point_temp[nr][0] =
1241 f71882fg_read8(data,
1242 F71882FG_REG_POINT_TEMP
1243 (nr, 0));
1244 data->pwm_auto_point_temp[nr][3] =
1245 f71882fg_read8(data,
1246 F71882FG_REG_POINT_TEMP
1247 (nr, 3));
1248 break;
1251 data->last_limits = jiffies;
1254 /* Update every second */
1255 if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
1256 data->temp_status = f71882fg_read8(data,
1257 F71882FG_REG_TEMP_STATUS);
1258 data->temp_diode_open = f71882fg_read8(data,
1259 F71882FG_REG_TEMP_DIODE_OPEN);
1260 for (nr = data->temp_start; nr < nr_temps + data->temp_start;
1261 nr++)
1262 data->temp[nr] = f71882fg_read_temp(data, nr);
1264 data->fan_status = f71882fg_read8(data,
1265 F71882FG_REG_FAN_STATUS);
1266 for (nr = 0; nr < nr_fans; nr++) {
1267 data->fan[nr] = f71882fg_read16(data,
1268 F71882FG_REG_FAN(nr));
1269 data->fan_target[nr] =
1270 f71882fg_read16(data, F71882FG_REG_FAN_TARGET(nr));
1271 data->fan_full_speed[nr] =
1272 f71882fg_read16(data,
1273 F71882FG_REG_FAN_FULL_SPEED(nr));
1274 data->pwm[nr] =
1275 f71882fg_read8(data, F71882FG_REG_PWM(nr));
1277 /* Some models have 1 more fan with limited capabilities */
1278 if (data->type == f71808a) {
1279 data->fan[2] = f71882fg_read16(data,
1280 F71882FG_REG_FAN(2));
1281 data->pwm[2] = f71882fg_read8(data,
1282 F71882FG_REG_PWM(2));
1284 if (data->type == f8000)
1285 data->fan[3] = f71882fg_read16(data,
1286 F71882FG_REG_FAN(3));
1288 if (f71882fg_has_in1_alarm[data->type])
1289 data->in_status = f71882fg_read8(data,
1290 F71882FG_REG_IN_STATUS);
1291 for (nr = 0; nr < F71882FG_MAX_INS; nr++)
1292 if (f71882fg_has_in[data->type][nr])
1293 data->in[nr] = f71882fg_read8(data,
1294 F71882FG_REG_IN(nr));
1296 data->last_updated = jiffies;
1297 data->valid = 1;
1300 mutex_unlock(&data->update_lock);
1302 return data;
1305 /* Sysfs Interface */
1306 static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
1307 char *buf)
1309 struct f71882fg_data *data = f71882fg_update_device(dev);
1310 int nr = to_sensor_dev_attr_2(devattr)->index;
1311 int speed = fan_from_reg(data->fan[nr]);
1313 if (speed == FAN_MIN_DETECT)
1314 speed = 0;
1316 return sprintf(buf, "%d\n", speed);
1319 static ssize_t show_fan_full_speed(struct device *dev,
1320 struct device_attribute *devattr, char *buf)
1322 struct f71882fg_data *data = f71882fg_update_device(dev);
1323 int nr = to_sensor_dev_attr_2(devattr)->index;
1324 int speed = fan_from_reg(data->fan_full_speed[nr]);
1325 return sprintf(buf, "%d\n", speed);
1328 static ssize_t store_fan_full_speed(struct device *dev,
1329 struct device_attribute *devattr,
1330 const char *buf, size_t count)
1332 struct f71882fg_data *data = dev_get_drvdata(dev);
1333 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1334 long val;
1336 err = kstrtol(buf, 10, &val);
1337 if (err)
1338 return err;
1340 val = SENSORS_LIMIT(val, 23, 1500000);
1341 val = fan_to_reg(val);
1343 mutex_lock(&data->update_lock);
1344 f71882fg_write16(data, F71882FG_REG_FAN_FULL_SPEED(nr), val);
1345 data->fan_full_speed[nr] = val;
1346 mutex_unlock(&data->update_lock);
1348 return count;
1351 static ssize_t show_fan_beep(struct device *dev, struct device_attribute
1352 *devattr, char *buf)
1354 struct f71882fg_data *data = f71882fg_update_device(dev);
1355 int nr = to_sensor_dev_attr_2(devattr)->index;
1357 if (data->fan_beep & (1 << nr))
1358 return sprintf(buf, "1\n");
1359 else
1360 return sprintf(buf, "0\n");
1363 static ssize_t store_fan_beep(struct device *dev, struct device_attribute
1364 *devattr, const char *buf, size_t count)
1366 struct f71882fg_data *data = dev_get_drvdata(dev);
1367 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1368 unsigned long val;
1370 err = kstrtoul(buf, 10, &val);
1371 if (err)
1372 return err;
1374 mutex_lock(&data->update_lock);
1375 data->fan_beep = f71882fg_read8(data, F71882FG_REG_FAN_BEEP);
1376 if (val)
1377 data->fan_beep |= 1 << nr;
1378 else
1379 data->fan_beep &= ~(1 << nr);
1381 f71882fg_write8(data, F71882FG_REG_FAN_BEEP, data->fan_beep);
1382 mutex_unlock(&data->update_lock);
1384 return count;
1387 static ssize_t show_fan_alarm(struct device *dev, struct device_attribute
1388 *devattr, char *buf)
1390 struct f71882fg_data *data = f71882fg_update_device(dev);
1391 int nr = to_sensor_dev_attr_2(devattr)->index;
1393 if (data->fan_status & (1 << nr))
1394 return sprintf(buf, "1\n");
1395 else
1396 return sprintf(buf, "0\n");
1399 static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
1400 char *buf)
1402 struct f71882fg_data *data = f71882fg_update_device(dev);
1403 int nr = to_sensor_dev_attr_2(devattr)->index;
1405 return sprintf(buf, "%d\n", data->in[nr] * 8);
1408 static ssize_t show_in_max(struct device *dev, struct device_attribute
1409 *devattr, char *buf)
1411 struct f71882fg_data *data = f71882fg_update_device(dev);
1413 return sprintf(buf, "%d\n", data->in1_max * 8);
1416 static ssize_t store_in_max(struct device *dev, struct device_attribute
1417 *devattr, const char *buf, size_t count)
1419 struct f71882fg_data *data = dev_get_drvdata(dev);
1420 int err;
1421 long val;
1423 err = kstrtol(buf, 10, &val);
1424 if (err)
1425 return err;
1427 val /= 8;
1428 val = SENSORS_LIMIT(val, 0, 255);
1430 mutex_lock(&data->update_lock);
1431 f71882fg_write8(data, F71882FG_REG_IN1_HIGH, val);
1432 data->in1_max = val;
1433 mutex_unlock(&data->update_lock);
1435 return count;
1438 static ssize_t show_in_beep(struct device *dev, struct device_attribute
1439 *devattr, char *buf)
1441 struct f71882fg_data *data = f71882fg_update_device(dev);
1442 int nr = to_sensor_dev_attr_2(devattr)->index;
1444 if (data->in_beep & (1 << nr))
1445 return sprintf(buf, "1\n");
1446 else
1447 return sprintf(buf, "0\n");
1450 static ssize_t store_in_beep(struct device *dev, struct device_attribute
1451 *devattr, const char *buf, size_t count)
1453 struct f71882fg_data *data = dev_get_drvdata(dev);
1454 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1455 unsigned long val;
1457 err = kstrtoul(buf, 10, &val);
1458 if (err)
1459 return err;
1461 mutex_lock(&data->update_lock);
1462 data->in_beep = f71882fg_read8(data, F71882FG_REG_IN_BEEP);
1463 if (val)
1464 data->in_beep |= 1 << nr;
1465 else
1466 data->in_beep &= ~(1 << nr);
1468 f71882fg_write8(data, F71882FG_REG_IN_BEEP, data->in_beep);
1469 mutex_unlock(&data->update_lock);
1471 return count;
1474 static ssize_t show_in_alarm(struct device *dev, struct device_attribute
1475 *devattr, char *buf)
1477 struct f71882fg_data *data = f71882fg_update_device(dev);
1478 int nr = to_sensor_dev_attr_2(devattr)->index;
1480 if (data->in_status & (1 << nr))
1481 return sprintf(buf, "1\n");
1482 else
1483 return sprintf(buf, "0\n");
1486 static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
1487 char *buf)
1489 struct f71882fg_data *data = f71882fg_update_device(dev);
1490 int nr = to_sensor_dev_attr_2(devattr)->index;
1491 int sign, temp;
1493 if (data->type == f71858fg) {
1494 /* TEMP_TABLE_SEL 1 or 3 ? */
1495 if (data->temp_config & 1) {
1496 sign = data->temp[nr] & 0x0001;
1497 temp = (data->temp[nr] >> 5) & 0x7ff;
1498 } else {
1499 sign = data->temp[nr] & 0x8000;
1500 temp = (data->temp[nr] >> 5) & 0x3ff;
1502 temp *= 125;
1503 if (sign)
1504 temp -= 128000;
1505 } else
1506 temp = data->temp[nr] * 1000;
1508 return sprintf(buf, "%d\n", temp);
1511 static ssize_t show_temp_max(struct device *dev, struct device_attribute
1512 *devattr, char *buf)
1514 struct f71882fg_data *data = f71882fg_update_device(dev);
1515 int nr = to_sensor_dev_attr_2(devattr)->index;
1517 return sprintf(buf, "%d\n", data->temp_high[nr] * 1000);
1520 static ssize_t store_temp_max(struct device *dev, struct device_attribute
1521 *devattr, const char *buf, size_t count)
1523 struct f71882fg_data *data = dev_get_drvdata(dev);
1524 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1525 long val;
1527 err = kstrtol(buf, 10, &val);
1528 if (err)
1529 return err;
1531 val /= 1000;
1532 val = SENSORS_LIMIT(val, 0, 255);
1534 mutex_lock(&data->update_lock);
1535 f71882fg_write8(data, F71882FG_REG_TEMP_HIGH(nr), val);
1536 data->temp_high[nr] = val;
1537 mutex_unlock(&data->update_lock);
1539 return count;
1542 static ssize_t show_temp_max_hyst(struct device *dev, struct device_attribute
1543 *devattr, char *buf)
1545 struct f71882fg_data *data = f71882fg_update_device(dev);
1546 int nr = to_sensor_dev_attr_2(devattr)->index;
1547 int temp_max_hyst;
1549 mutex_lock(&data->update_lock);
1550 if (nr & 1)
1551 temp_max_hyst = data->temp_hyst[nr / 2] >> 4;
1552 else
1553 temp_max_hyst = data->temp_hyst[nr / 2] & 0x0f;
1554 temp_max_hyst = (data->temp_high[nr] - temp_max_hyst) * 1000;
1555 mutex_unlock(&data->update_lock);
1557 return sprintf(buf, "%d\n", temp_max_hyst);
1560 static ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute
1561 *devattr, const char *buf, size_t count)
1563 struct f71882fg_data *data = dev_get_drvdata(dev);
1564 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1565 ssize_t ret = count;
1566 u8 reg;
1567 long val;
1569 err = kstrtol(buf, 10, &val);
1570 if (err)
1571 return err;
1573 val /= 1000;
1575 mutex_lock(&data->update_lock);
1577 /* convert abs to relative and check */
1578 data->temp_high[nr] = f71882fg_read8(data, F71882FG_REG_TEMP_HIGH(nr));
1579 val = SENSORS_LIMIT(val, data->temp_high[nr] - 15,
1580 data->temp_high[nr]);
1581 val = data->temp_high[nr] - val;
1583 /* convert value to register contents */
1584 reg = f71882fg_read8(data, F71882FG_REG_TEMP_HYST(nr / 2));
1585 if (nr & 1)
1586 reg = (reg & 0x0f) | (val << 4);
1587 else
1588 reg = (reg & 0xf0) | val;
1589 f71882fg_write8(data, F71882FG_REG_TEMP_HYST(nr / 2), reg);
1590 data->temp_hyst[nr / 2] = reg;
1592 mutex_unlock(&data->update_lock);
1593 return ret;
1596 static ssize_t show_temp_crit(struct device *dev, struct device_attribute
1597 *devattr, char *buf)
1599 struct f71882fg_data *data = f71882fg_update_device(dev);
1600 int nr = to_sensor_dev_attr_2(devattr)->index;
1602 return sprintf(buf, "%d\n", data->temp_ovt[nr] * 1000);
1605 static ssize_t store_temp_crit(struct device *dev, struct device_attribute
1606 *devattr, const char *buf, size_t count)
1608 struct f71882fg_data *data = dev_get_drvdata(dev);
1609 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1610 long val;
1612 err = kstrtol(buf, 10, &val);
1613 if (err)
1614 return err;
1616 val /= 1000;
1617 val = SENSORS_LIMIT(val, 0, 255);
1619 mutex_lock(&data->update_lock);
1620 f71882fg_write8(data, F71882FG_REG_TEMP_OVT(nr), val);
1621 data->temp_ovt[nr] = val;
1622 mutex_unlock(&data->update_lock);
1624 return count;
1627 static ssize_t show_temp_crit_hyst(struct device *dev, struct device_attribute
1628 *devattr, char *buf)
1630 struct f71882fg_data *data = f71882fg_update_device(dev);
1631 int nr = to_sensor_dev_attr_2(devattr)->index;
1632 int temp_crit_hyst;
1634 mutex_lock(&data->update_lock);
1635 if (nr & 1)
1636 temp_crit_hyst = data->temp_hyst[nr / 2] >> 4;
1637 else
1638 temp_crit_hyst = data->temp_hyst[nr / 2] & 0x0f;
1639 temp_crit_hyst = (data->temp_ovt[nr] - temp_crit_hyst) * 1000;
1640 mutex_unlock(&data->update_lock);
1642 return sprintf(buf, "%d\n", temp_crit_hyst);
1645 static ssize_t show_temp_type(struct device *dev, struct device_attribute
1646 *devattr, char *buf)
1648 struct f71882fg_data *data = f71882fg_update_device(dev);
1649 int nr = to_sensor_dev_attr_2(devattr)->index;
1651 return sprintf(buf, "%d\n", data->temp_type[nr]);
1654 static ssize_t show_temp_beep(struct device *dev, struct device_attribute
1655 *devattr, char *buf)
1657 struct f71882fg_data *data = f71882fg_update_device(dev);
1658 int nr = to_sensor_dev_attr_2(devattr)->index;
1660 if (data->temp_beep & (1 << nr))
1661 return sprintf(buf, "1\n");
1662 else
1663 return sprintf(buf, "0\n");
1666 static ssize_t store_temp_beep(struct device *dev, struct device_attribute
1667 *devattr, const char *buf, size_t count)
1669 struct f71882fg_data *data = dev_get_drvdata(dev);
1670 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1671 unsigned long val;
1673 err = kstrtoul(buf, 10, &val);
1674 if (err)
1675 return err;
1677 mutex_lock(&data->update_lock);
1678 data->temp_beep = f71882fg_read8(data, F71882FG_REG_TEMP_BEEP);
1679 if (val)
1680 data->temp_beep |= 1 << nr;
1681 else
1682 data->temp_beep &= ~(1 << nr);
1684 f71882fg_write8(data, F71882FG_REG_TEMP_BEEP, data->temp_beep);
1685 mutex_unlock(&data->update_lock);
1687 return count;
1690 static ssize_t show_temp_alarm(struct device *dev, struct device_attribute
1691 *devattr, char *buf)
1693 struct f71882fg_data *data = f71882fg_update_device(dev);
1694 int nr = to_sensor_dev_attr_2(devattr)->index;
1696 if (data->temp_status & (1 << nr))
1697 return sprintf(buf, "1\n");
1698 else
1699 return sprintf(buf, "0\n");
1702 static ssize_t show_temp_fault(struct device *dev, struct device_attribute
1703 *devattr, char *buf)
1705 struct f71882fg_data *data = f71882fg_update_device(dev);
1706 int nr = to_sensor_dev_attr_2(devattr)->index;
1708 if (data->temp_diode_open & (1 << nr))
1709 return sprintf(buf, "1\n");
1710 else
1711 return sprintf(buf, "0\n");
1714 static ssize_t show_pwm(struct device *dev,
1715 struct device_attribute *devattr, char *buf)
1717 struct f71882fg_data *data = f71882fg_update_device(dev);
1718 int val, nr = to_sensor_dev_attr_2(devattr)->index;
1719 mutex_lock(&data->update_lock);
1720 if (data->pwm_enable & (1 << (2 * nr)))
1721 /* PWM mode */
1722 val = data->pwm[nr];
1723 else {
1724 /* RPM mode */
1725 val = 255 * fan_from_reg(data->fan_target[nr])
1726 / fan_from_reg(data->fan_full_speed[nr]);
1728 mutex_unlock(&data->update_lock);
1729 return sprintf(buf, "%d\n", val);
1732 static ssize_t store_pwm(struct device *dev,
1733 struct device_attribute *devattr, const char *buf,
1734 size_t count)
1736 struct f71882fg_data *data = dev_get_drvdata(dev);
1737 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1738 long val;
1740 err = kstrtol(buf, 10, &val);
1741 if (err)
1742 return err;
1744 val = SENSORS_LIMIT(val, 0, 255);
1746 mutex_lock(&data->update_lock);
1747 data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
1748 if ((data->type == f8000 && ((data->pwm_enable >> 2 * nr) & 3) != 2) ||
1749 (data->type != f8000 && !((data->pwm_enable >> 2 * nr) & 2))) {
1750 count = -EROFS;
1751 goto leave;
1753 if (data->pwm_enable & (1 << (2 * nr))) {
1754 /* PWM mode */
1755 f71882fg_write8(data, F71882FG_REG_PWM(nr), val);
1756 data->pwm[nr] = val;
1757 } else {
1758 /* RPM mode */
1759 int target, full_speed;
1760 full_speed = f71882fg_read16(data,
1761 F71882FG_REG_FAN_FULL_SPEED(nr));
1762 target = fan_to_reg(val * fan_from_reg(full_speed) / 255);
1763 f71882fg_write16(data, F71882FG_REG_FAN_TARGET(nr), target);
1764 data->fan_target[nr] = target;
1765 data->fan_full_speed[nr] = full_speed;
1767 leave:
1768 mutex_unlock(&data->update_lock);
1770 return count;
1773 static ssize_t show_simple_pwm(struct device *dev,
1774 struct device_attribute *devattr, char *buf)
1776 struct f71882fg_data *data = f71882fg_update_device(dev);
1777 int val, nr = to_sensor_dev_attr_2(devattr)->index;
1779 val = data->pwm[nr];
1780 return sprintf(buf, "%d\n", val);
1783 static ssize_t store_simple_pwm(struct device *dev,
1784 struct device_attribute *devattr,
1785 const char *buf, size_t count)
1787 struct f71882fg_data *data = dev_get_drvdata(dev);
1788 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1789 long val;
1791 err = kstrtol(buf, 10, &val);
1792 if (err)
1793 return err;
1795 val = SENSORS_LIMIT(val, 0, 255);
1797 mutex_lock(&data->update_lock);
1798 f71882fg_write8(data, F71882FG_REG_PWM(nr), val);
1799 data->pwm[nr] = val;
1800 mutex_unlock(&data->update_lock);
1802 return count;
1805 static ssize_t show_pwm_enable(struct device *dev,
1806 struct device_attribute *devattr, char *buf)
1808 int result = 0;
1809 struct f71882fg_data *data = f71882fg_update_device(dev);
1810 int nr = to_sensor_dev_attr_2(devattr)->index;
1812 switch ((data->pwm_enable >> 2 * nr) & 3) {
1813 case 0:
1814 case 1:
1815 result = 2; /* Normal auto mode */
1816 break;
1817 case 2:
1818 result = 1; /* Manual mode */
1819 break;
1820 case 3:
1821 if (data->type == f8000)
1822 result = 3; /* Thermostat mode */
1823 else
1824 result = 1; /* Manual mode */
1825 break;
1828 return sprintf(buf, "%d\n", result);
1831 static ssize_t store_pwm_enable(struct device *dev, struct device_attribute
1832 *devattr, const char *buf, size_t count)
1834 struct f71882fg_data *data = dev_get_drvdata(dev);
1835 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1836 long val;
1838 err = kstrtol(buf, 10, &val);
1839 if (err)
1840 return err;
1842 /* Special case for F8000 pwm channel 3 which only does auto mode */
1843 if (data->type == f8000 && nr == 2 && val != 2)
1844 return -EINVAL;
1846 mutex_lock(&data->update_lock);
1847 data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
1848 /* Special case for F8000 auto PWM mode / Thermostat mode */
1849 if (data->type == f8000 && ((data->pwm_enable >> 2 * nr) & 1)) {
1850 switch (val) {
1851 case 2:
1852 data->pwm_enable &= ~(2 << (2 * nr));
1853 break; /* Normal auto mode */
1854 case 3:
1855 data->pwm_enable |= 2 << (2 * nr);
1856 break; /* Thermostat mode */
1857 default:
1858 count = -EINVAL;
1859 goto leave;
1861 } else {
1862 switch (val) {
1863 case 1:
1864 /* The f71858fg does not support manual RPM mode */
1865 if (data->type == f71858fg &&
1866 ((data->pwm_enable >> (2 * nr)) & 1)) {
1867 count = -EINVAL;
1868 goto leave;
1870 data->pwm_enable |= 2 << (2 * nr);
1871 break; /* Manual */
1872 case 2:
1873 data->pwm_enable &= ~(2 << (2 * nr));
1874 break; /* Normal auto mode */
1875 default:
1876 count = -EINVAL;
1877 goto leave;
1880 f71882fg_write8(data, F71882FG_REG_PWM_ENABLE, data->pwm_enable);
1881 leave:
1882 mutex_unlock(&data->update_lock);
1884 return count;
1887 static ssize_t show_pwm_auto_point_pwm(struct device *dev,
1888 struct device_attribute *devattr,
1889 char *buf)
1891 int result;
1892 struct f71882fg_data *data = f71882fg_update_device(dev);
1893 int pwm = to_sensor_dev_attr_2(devattr)->index;
1894 int point = to_sensor_dev_attr_2(devattr)->nr;
1896 mutex_lock(&data->update_lock);
1897 if (data->pwm_enable & (1 << (2 * pwm))) {
1898 /* PWM mode */
1899 result = data->pwm_auto_point_pwm[pwm][point];
1900 } else {
1901 /* RPM mode */
1902 result = 32 * 255 / (32 + data->pwm_auto_point_pwm[pwm][point]);
1904 mutex_unlock(&data->update_lock);
1906 return sprintf(buf, "%d\n", result);
1909 static ssize_t store_pwm_auto_point_pwm(struct device *dev,
1910 struct device_attribute *devattr,
1911 const char *buf, size_t count)
1913 struct f71882fg_data *data = dev_get_drvdata(dev);
1914 int err, pwm = to_sensor_dev_attr_2(devattr)->index;
1915 int point = to_sensor_dev_attr_2(devattr)->nr;
1916 long val;
1918 err = kstrtol(buf, 10, &val);
1919 if (err)
1920 return err;
1922 val = SENSORS_LIMIT(val, 0, 255);
1924 mutex_lock(&data->update_lock);
1925 data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
1926 if (data->pwm_enable & (1 << (2 * pwm))) {
1927 /* PWM mode */
1928 } else {
1929 /* RPM mode */
1930 if (val < 29) /* Prevent negative numbers */
1931 val = 255;
1932 else
1933 val = (255 - val) * 32 / val;
1935 f71882fg_write8(data, F71882FG_REG_POINT_PWM(pwm, point), val);
1936 data->pwm_auto_point_pwm[pwm][point] = val;
1937 mutex_unlock(&data->update_lock);
1939 return count;
1942 static ssize_t show_pwm_auto_point_temp_hyst(struct device *dev,
1943 struct device_attribute *devattr,
1944 char *buf)
1946 int result = 0;
1947 struct f71882fg_data *data = f71882fg_update_device(dev);
1948 int nr = to_sensor_dev_attr_2(devattr)->index;
1949 int point = to_sensor_dev_attr_2(devattr)->nr;
1951 mutex_lock(&data->update_lock);
1952 if (nr & 1)
1953 result = data->pwm_auto_point_hyst[nr / 2] >> 4;
1954 else
1955 result = data->pwm_auto_point_hyst[nr / 2] & 0x0f;
1956 result = 1000 * (data->pwm_auto_point_temp[nr][point] - result);
1957 mutex_unlock(&data->update_lock);
1959 return sprintf(buf, "%d\n", result);
1962 static ssize_t store_pwm_auto_point_temp_hyst(struct device *dev,
1963 struct device_attribute *devattr,
1964 const char *buf, size_t count)
1966 struct f71882fg_data *data = dev_get_drvdata(dev);
1967 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1968 int point = to_sensor_dev_attr_2(devattr)->nr;
1969 u8 reg;
1970 long val;
1972 err = kstrtol(buf, 10, &val);
1973 if (err)
1974 return err;
1976 val /= 1000;
1978 mutex_lock(&data->update_lock);
1979 data->pwm_auto_point_temp[nr][point] =
1980 f71882fg_read8(data, F71882FG_REG_POINT_TEMP(nr, point));
1981 val = SENSORS_LIMIT(val, data->pwm_auto_point_temp[nr][point] - 15,
1982 data->pwm_auto_point_temp[nr][point]);
1983 val = data->pwm_auto_point_temp[nr][point] - val;
1985 reg = f71882fg_read8(data, F71882FG_REG_FAN_HYST(nr / 2));
1986 if (nr & 1)
1987 reg = (reg & 0x0f) | (val << 4);
1988 else
1989 reg = (reg & 0xf0) | val;
1991 f71882fg_write8(data, F71882FG_REG_FAN_HYST(nr / 2), reg);
1992 data->pwm_auto_point_hyst[nr / 2] = reg;
1993 mutex_unlock(&data->update_lock);
1995 return count;
1998 static ssize_t show_pwm_interpolate(struct device *dev,
1999 struct device_attribute *devattr, char *buf)
2001 int result;
2002 struct f71882fg_data *data = f71882fg_update_device(dev);
2003 int nr = to_sensor_dev_attr_2(devattr)->index;
2005 result = (data->pwm_auto_point_mapping[nr] >> 4) & 1;
2007 return sprintf(buf, "%d\n", result);
2010 static ssize_t store_pwm_interpolate(struct device *dev,
2011 struct device_attribute *devattr,
2012 const char *buf, size_t count)
2014 struct f71882fg_data *data = dev_get_drvdata(dev);
2015 int err, nr = to_sensor_dev_attr_2(devattr)->index;
2016 unsigned long val;
2018 err = kstrtoul(buf, 10, &val);
2019 if (err)
2020 return err;
2022 mutex_lock(&data->update_lock);
2023 data->pwm_auto_point_mapping[nr] =
2024 f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(nr));
2025 if (val)
2026 val = data->pwm_auto_point_mapping[nr] | (1 << 4);
2027 else
2028 val = data->pwm_auto_point_mapping[nr] & (~(1 << 4));
2029 f71882fg_write8(data, F71882FG_REG_POINT_MAPPING(nr), val);
2030 data->pwm_auto_point_mapping[nr] = val;
2031 mutex_unlock(&data->update_lock);
2033 return count;
2036 static ssize_t show_pwm_auto_point_channel(struct device *dev,
2037 struct device_attribute *devattr,
2038 char *buf)
2040 int result;
2041 struct f71882fg_data *data = f71882fg_update_device(dev);
2042 int nr = to_sensor_dev_attr_2(devattr)->index;
2044 result = 1 << ((data->pwm_auto_point_mapping[nr] & 3) -
2045 data->temp_start);
2047 return sprintf(buf, "%d\n", result);
2050 static ssize_t store_pwm_auto_point_channel(struct device *dev,
2051 struct device_attribute *devattr,
2052 const char *buf, size_t count)
2054 struct f71882fg_data *data = dev_get_drvdata(dev);
2055 int err, nr = to_sensor_dev_attr_2(devattr)->index;
2056 long val;
2058 err = kstrtol(buf, 10, &val);
2059 if (err)
2060 return err;
2062 switch (val) {
2063 case 1:
2064 val = 0;
2065 break;
2066 case 2:
2067 val = 1;
2068 break;
2069 case 4:
2070 val = 2;
2071 break;
2072 default:
2073 return -EINVAL;
2075 val += data->temp_start;
2076 mutex_lock(&data->update_lock);
2077 data->pwm_auto_point_mapping[nr] =
2078 f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(nr));
2079 val = (data->pwm_auto_point_mapping[nr] & 0xfc) | val;
2080 f71882fg_write8(data, F71882FG_REG_POINT_MAPPING(nr), val);
2081 data->pwm_auto_point_mapping[nr] = val;
2082 mutex_unlock(&data->update_lock);
2084 return count;
2087 static ssize_t show_pwm_auto_point_temp(struct device *dev,
2088 struct device_attribute *devattr,
2089 char *buf)
2091 int result;
2092 struct f71882fg_data *data = f71882fg_update_device(dev);
2093 int pwm = to_sensor_dev_attr_2(devattr)->index;
2094 int point = to_sensor_dev_attr_2(devattr)->nr;
2096 result = data->pwm_auto_point_temp[pwm][point];
2097 return sprintf(buf, "%d\n", 1000 * result);
2100 static ssize_t store_pwm_auto_point_temp(struct device *dev,
2101 struct device_attribute *devattr,
2102 const char *buf, size_t count)
2104 struct f71882fg_data *data = dev_get_drvdata(dev);
2105 int err, pwm = to_sensor_dev_attr_2(devattr)->index;
2106 int point = to_sensor_dev_attr_2(devattr)->nr;
2107 long val;
2109 err = kstrtol(buf, 10, &val);
2110 if (err)
2111 return err;
2113 val /= 1000;
2115 if (data->auto_point_temp_signed)
2116 val = SENSORS_LIMIT(val, -128, 127);
2117 else
2118 val = SENSORS_LIMIT(val, 0, 127);
2120 mutex_lock(&data->update_lock);
2121 f71882fg_write8(data, F71882FG_REG_POINT_TEMP(pwm, point), val);
2122 data->pwm_auto_point_temp[pwm][point] = val;
2123 mutex_unlock(&data->update_lock);
2125 return count;
2128 static ssize_t show_name(struct device *dev, struct device_attribute *devattr,
2129 char *buf)
2131 struct f71882fg_data *data = dev_get_drvdata(dev);
2132 return sprintf(buf, "%s\n", f71882fg_names[data->type]);
2135 static int __devinit f71882fg_create_sysfs_files(struct platform_device *pdev,
2136 struct sensor_device_attribute_2 *attr, int count)
2138 int err, i;
2140 for (i = 0; i < count; i++) {
2141 err = device_create_file(&pdev->dev, &attr[i].dev_attr);
2142 if (err)
2143 return err;
2145 return 0;
2148 static void f71882fg_remove_sysfs_files(struct platform_device *pdev,
2149 struct sensor_device_attribute_2 *attr, int count)
2151 int i;
2153 for (i = 0; i < count; i++)
2154 device_remove_file(&pdev->dev, &attr[i].dev_attr);
2157 static int __devinit f71882fg_create_fan_sysfs_files(
2158 struct platform_device *pdev, int idx)
2160 struct f71882fg_data *data = platform_get_drvdata(pdev);
2161 int err;
2163 /* Sanity check the pwm setting */
2164 err = 0;
2165 switch (data->type) {
2166 case f71858fg:
2167 if (((data->pwm_enable >> (idx * 2)) & 3) == 3)
2168 err = 1;
2169 break;
2170 case f71862fg:
2171 if (((data->pwm_enable >> (idx * 2)) & 1) != 1)
2172 err = 1;
2173 break;
2174 case f8000:
2175 if (idx == 2)
2176 err = data->pwm_enable & 0x20;
2177 break;
2178 default:
2179 break;
2181 if (err) {
2182 dev_err(&pdev->dev,
2183 "Invalid (reserved) pwm settings: 0x%02x, "
2184 "skipping fan %d\n",
2185 (data->pwm_enable >> (idx * 2)) & 3, idx + 1);
2186 return 0; /* This is a non fatal condition */
2189 err = f71882fg_create_sysfs_files(pdev, &fxxxx_fan_attr[idx][0],
2190 ARRAY_SIZE(fxxxx_fan_attr[0]));
2191 if (err)
2192 return err;
2194 if (f71882fg_fan_has_beep[data->type]) {
2195 err = f71882fg_create_sysfs_files(pdev,
2196 &fxxxx_fan_beep_attr[idx],
2198 if (err)
2199 return err;
2202 dev_info(&pdev->dev, "Fan: %d is in %s mode\n", idx + 1,
2203 (data->pwm_enable & (1 << (2 * idx))) ? "duty-cycle" : "RPM");
2205 /* Check for unsupported auto pwm settings */
2206 switch (data->type) {
2207 case f71808e:
2208 case f71808a:
2209 case f71869:
2210 case f71869a:
2211 case f71889fg:
2212 case f71889ed:
2213 case f71889a:
2214 data->pwm_auto_point_mapping[idx] =
2215 f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(idx));
2216 if ((data->pwm_auto_point_mapping[idx] & 0x80) ||
2217 (data->pwm_auto_point_mapping[idx] & 3) == 0) {
2218 dev_warn(&pdev->dev,
2219 "Auto pwm controlled by raw digital "
2220 "data, disabling pwm auto_point "
2221 "sysfs attributes for fan %d\n", idx + 1);
2222 return 0; /* This is a non fatal condition */
2224 break;
2225 default:
2226 break;
2229 switch (data->type) {
2230 case f71862fg:
2231 err = f71882fg_create_sysfs_files(pdev,
2232 &f71862fg_auto_pwm_attr[idx][0],
2233 ARRAY_SIZE(f71862fg_auto_pwm_attr[0]));
2234 break;
2235 case f71808e:
2236 case f71869:
2237 err = f71882fg_create_sysfs_files(pdev,
2238 &f71869_auto_pwm_attr[idx][0],
2239 ARRAY_SIZE(f71869_auto_pwm_attr[0]));
2240 break;
2241 case f8000:
2242 err = f71882fg_create_sysfs_files(pdev,
2243 &f8000_auto_pwm_attr[idx][0],
2244 ARRAY_SIZE(f8000_auto_pwm_attr[0]));
2245 break;
2246 default:
2247 err = f71882fg_create_sysfs_files(pdev,
2248 &fxxxx_auto_pwm_attr[idx][0],
2249 ARRAY_SIZE(fxxxx_auto_pwm_attr[0]));
2252 return err;
2255 static int __devinit f71882fg_probe(struct platform_device *pdev)
2257 struct f71882fg_data *data;
2258 struct f71882fg_sio_data *sio_data = pdev->dev.platform_data;
2259 int nr_fans = f71882fg_nr_fans[sio_data->type];
2260 int nr_temps = f71882fg_nr_temps[sio_data->type];
2261 int err, i;
2262 u8 start_reg, reg;
2264 data = kzalloc(sizeof(struct f71882fg_data), GFP_KERNEL);
2265 if (!data)
2266 return -ENOMEM;
2268 data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start;
2269 data->type = sio_data->type;
2270 data->temp_start =
2271 (data->type == f71858fg || data->type == f8000) ? 0 : 1;
2272 mutex_init(&data->update_lock);
2273 platform_set_drvdata(pdev, data);
2275 start_reg = f71882fg_read8(data, F71882FG_REG_START);
2276 if (start_reg & 0x04) {
2277 dev_warn(&pdev->dev, "Hardware monitor is powered down\n");
2278 err = -ENODEV;
2279 goto exit_free;
2281 if (!(start_reg & 0x03)) {
2282 dev_warn(&pdev->dev, "Hardware monitoring not activated\n");
2283 err = -ENODEV;
2284 goto exit_free;
2287 /* Register sysfs interface files */
2288 err = device_create_file(&pdev->dev, &dev_attr_name);
2289 if (err)
2290 goto exit_unregister_sysfs;
2292 if (start_reg & 0x01) {
2293 switch (data->type) {
2294 case f71858fg:
2295 data->temp_config =
2296 f71882fg_read8(data, F71882FG_REG_TEMP_CONFIG);
2297 if (data->temp_config & 0x10)
2298 /* The f71858fg temperature alarms behave as
2299 the f8000 alarms in this mode */
2300 err = f71882fg_create_sysfs_files(pdev,
2301 f8000_temp_attr,
2302 ARRAY_SIZE(f8000_temp_attr));
2303 else
2304 err = f71882fg_create_sysfs_files(pdev,
2305 f71858fg_temp_attr,
2306 ARRAY_SIZE(f71858fg_temp_attr));
2307 break;
2308 case f8000:
2309 err = f71882fg_create_sysfs_files(pdev,
2310 f8000_temp_attr,
2311 ARRAY_SIZE(f8000_temp_attr));
2312 break;
2313 default:
2314 err = f71882fg_create_sysfs_files(pdev,
2315 &fxxxx_temp_attr[0][0],
2316 ARRAY_SIZE(fxxxx_temp_attr[0]) * nr_temps);
2318 if (err)
2319 goto exit_unregister_sysfs;
2321 if (f71882fg_temp_has_beep[data->type]) {
2322 err = f71882fg_create_sysfs_files(pdev,
2323 &fxxxx_temp_beep_attr[0][0],
2324 ARRAY_SIZE(fxxxx_temp_beep_attr[0])
2325 * nr_temps);
2326 if (err)
2327 goto exit_unregister_sysfs;
2330 for (i = 0; i < F71882FG_MAX_INS; i++) {
2331 if (f71882fg_has_in[data->type][i]) {
2332 err = device_create_file(&pdev->dev,
2333 &fxxxx_in_attr[i].dev_attr);
2334 if (err)
2335 goto exit_unregister_sysfs;
2338 if (f71882fg_has_in1_alarm[data->type]) {
2339 err = f71882fg_create_sysfs_files(pdev,
2340 fxxxx_in1_alarm_attr,
2341 ARRAY_SIZE(fxxxx_in1_alarm_attr));
2342 if (err)
2343 goto exit_unregister_sysfs;
2347 if (start_reg & 0x02) {
2348 switch (data->type) {
2349 case f71808e:
2350 case f71808a:
2351 case f71869:
2352 case f71869a:
2353 /* These always have signed auto point temps */
2354 data->auto_point_temp_signed = 1;
2355 /* Fall through to select correct fan/pwm reg bank! */
2356 case f71889fg:
2357 case f71889ed:
2358 case f71889a:
2359 reg = f71882fg_read8(data, F71882FG_REG_FAN_FAULT_T);
2360 if (reg & F71882FG_FAN_NEG_TEMP_EN)
2361 data->auto_point_temp_signed = 1;
2362 /* Ensure banked pwm registers point to right bank */
2363 reg &= ~F71882FG_FAN_PROG_SEL;
2364 f71882fg_write8(data, F71882FG_REG_FAN_FAULT_T, reg);
2365 break;
2366 default:
2367 break;
2370 data->pwm_enable =
2371 f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
2373 for (i = 0; i < nr_fans; i++) {
2374 err = f71882fg_create_fan_sysfs_files(pdev, i);
2375 if (err)
2376 goto exit_unregister_sysfs;
2379 /* Some types have 1 extra fan with limited functionality */
2380 switch (data->type) {
2381 case f71808a:
2382 err = f71882fg_create_sysfs_files(pdev,
2383 f71808a_fan3_attr,
2384 ARRAY_SIZE(f71808a_fan3_attr));
2385 break;
2386 case f8000:
2387 err = f71882fg_create_sysfs_files(pdev,
2388 f8000_fan_attr,
2389 ARRAY_SIZE(f8000_fan_attr));
2390 break;
2391 default:
2392 break;
2394 if (err)
2395 goto exit_unregister_sysfs;
2398 data->hwmon_dev = hwmon_device_register(&pdev->dev);
2399 if (IS_ERR(data->hwmon_dev)) {
2400 err = PTR_ERR(data->hwmon_dev);
2401 data->hwmon_dev = NULL;
2402 goto exit_unregister_sysfs;
2405 return 0;
2407 exit_unregister_sysfs:
2408 f71882fg_remove(pdev); /* Will unregister the sysfs files for us */
2409 return err; /* f71882fg_remove() also frees our data */
2410 exit_free:
2411 kfree(data);
2412 return err;
2415 static int f71882fg_remove(struct platform_device *pdev)
2417 struct f71882fg_data *data = platform_get_drvdata(pdev);
2418 int nr_fans = f71882fg_nr_fans[data->type];
2419 int nr_temps = f71882fg_nr_temps[data->type];
2420 int i;
2421 u8 start_reg = f71882fg_read8(data, F71882FG_REG_START);
2423 if (data->hwmon_dev)
2424 hwmon_device_unregister(data->hwmon_dev);
2426 device_remove_file(&pdev->dev, &dev_attr_name);
2428 if (start_reg & 0x01) {
2429 switch (data->type) {
2430 case f71858fg:
2431 if (data->temp_config & 0x10)
2432 f71882fg_remove_sysfs_files(pdev,
2433 f8000_temp_attr,
2434 ARRAY_SIZE(f8000_temp_attr));
2435 else
2436 f71882fg_remove_sysfs_files(pdev,
2437 f71858fg_temp_attr,
2438 ARRAY_SIZE(f71858fg_temp_attr));
2439 break;
2440 case f8000:
2441 f71882fg_remove_sysfs_files(pdev,
2442 f8000_temp_attr,
2443 ARRAY_SIZE(f8000_temp_attr));
2444 break;
2445 default:
2446 f71882fg_remove_sysfs_files(pdev,
2447 &fxxxx_temp_attr[0][0],
2448 ARRAY_SIZE(fxxxx_temp_attr[0]) * nr_temps);
2450 if (f71882fg_temp_has_beep[data->type]) {
2451 f71882fg_remove_sysfs_files(pdev,
2452 &fxxxx_temp_beep_attr[0][0],
2453 ARRAY_SIZE(fxxxx_temp_beep_attr[0]) * nr_temps);
2456 for (i = 0; i < F71882FG_MAX_INS; i++) {
2457 if (f71882fg_has_in[data->type][i]) {
2458 device_remove_file(&pdev->dev,
2459 &fxxxx_in_attr[i].dev_attr);
2462 if (f71882fg_has_in1_alarm[data->type]) {
2463 f71882fg_remove_sysfs_files(pdev,
2464 fxxxx_in1_alarm_attr,
2465 ARRAY_SIZE(fxxxx_in1_alarm_attr));
2469 if (start_reg & 0x02) {
2470 f71882fg_remove_sysfs_files(pdev, &fxxxx_fan_attr[0][0],
2471 ARRAY_SIZE(fxxxx_fan_attr[0]) * nr_fans);
2473 if (f71882fg_fan_has_beep[data->type]) {
2474 f71882fg_remove_sysfs_files(pdev,
2475 fxxxx_fan_beep_attr, nr_fans);
2478 switch (data->type) {
2479 case f71808a:
2480 f71882fg_remove_sysfs_files(pdev,
2481 &fxxxx_auto_pwm_attr[0][0],
2482 ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans);
2483 f71882fg_remove_sysfs_files(pdev,
2484 f71808a_fan3_attr,
2485 ARRAY_SIZE(f71808a_fan3_attr));
2486 break;
2487 case f71862fg:
2488 f71882fg_remove_sysfs_files(pdev,
2489 &f71862fg_auto_pwm_attr[0][0],
2490 ARRAY_SIZE(f71862fg_auto_pwm_attr[0]) *
2491 nr_fans);
2492 break;
2493 case f71808e:
2494 case f71869:
2495 f71882fg_remove_sysfs_files(pdev,
2496 &f71869_auto_pwm_attr[0][0],
2497 ARRAY_SIZE(f71869_auto_pwm_attr[0]) * nr_fans);
2498 break;
2499 case f8000:
2500 f71882fg_remove_sysfs_files(pdev,
2501 f8000_fan_attr,
2502 ARRAY_SIZE(f8000_fan_attr));
2503 f71882fg_remove_sysfs_files(pdev,
2504 &f8000_auto_pwm_attr[0][0],
2505 ARRAY_SIZE(f8000_auto_pwm_attr[0]) * nr_fans);
2506 break;
2507 default:
2508 f71882fg_remove_sysfs_files(pdev,
2509 &fxxxx_auto_pwm_attr[0][0],
2510 ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans);
2514 platform_set_drvdata(pdev, NULL);
2515 kfree(data);
2517 return 0;
2520 static int __init f71882fg_find(int sioaddr, unsigned short *address,
2521 struct f71882fg_sio_data *sio_data)
2523 u16 devid;
2524 int err = superio_enter(sioaddr);
2525 if (err)
2526 return err;
2528 devid = superio_inw(sioaddr, SIO_REG_MANID);
2529 if (devid != SIO_FINTEK_ID) {
2530 pr_debug("Not a Fintek device\n");
2531 err = -ENODEV;
2532 goto exit;
2535 devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID);
2536 switch (devid) {
2537 case SIO_F71808E_ID:
2538 sio_data->type = f71808e;
2539 break;
2540 case SIO_F71808A_ID:
2541 sio_data->type = f71808a;
2542 break;
2543 case SIO_F71858_ID:
2544 sio_data->type = f71858fg;
2545 break;
2546 case SIO_F71862_ID:
2547 sio_data->type = f71862fg;
2548 break;
2549 case SIO_F71869_ID:
2550 sio_data->type = f71869;
2551 break;
2552 case SIO_F71869A_ID:
2553 sio_data->type = f71869a;
2554 break;
2555 case SIO_F71882_ID:
2556 sio_data->type = f71882fg;
2557 break;
2558 case SIO_F71889_ID:
2559 sio_data->type = f71889fg;
2560 break;
2561 case SIO_F71889E_ID:
2562 sio_data->type = f71889ed;
2563 break;
2564 case SIO_F71889A_ID:
2565 sio_data->type = f71889a;
2566 break;
2567 case SIO_F8000_ID:
2568 sio_data->type = f8000;
2569 break;
2570 case SIO_F81865_ID:
2571 sio_data->type = f81865f;
2572 break;
2573 default:
2574 pr_info("Unsupported Fintek device: %04x\n",
2575 (unsigned int)devid);
2576 err = -ENODEV;
2577 goto exit;
2580 if (sio_data->type == f71858fg)
2581 superio_select(sioaddr, SIO_F71858FG_LD_HWM);
2582 else
2583 superio_select(sioaddr, SIO_F71882FG_LD_HWM);
2585 if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) {
2586 pr_warn("Device not activated\n");
2587 err = -ENODEV;
2588 goto exit;
2591 *address = superio_inw(sioaddr, SIO_REG_ADDR);
2592 if (*address == 0) {
2593 pr_warn("Base address not set\n");
2594 err = -ENODEV;
2595 goto exit;
2597 *address &= ~(REGION_LENGTH - 1); /* Ignore 3 LSB */
2599 err = 0;
2600 pr_info("Found %s chip at %#x, revision %d\n",
2601 f71882fg_names[sio_data->type], (unsigned int)*address,
2602 (int)superio_inb(sioaddr, SIO_REG_DEVREV));
2603 exit:
2604 superio_exit(sioaddr);
2605 return err;
2608 static int __init f71882fg_device_add(unsigned short address,
2609 const struct f71882fg_sio_data *sio_data)
2611 struct resource res = {
2612 .start = address,
2613 .end = address + REGION_LENGTH - 1,
2614 .flags = IORESOURCE_IO,
2616 int err;
2618 f71882fg_pdev = platform_device_alloc(DRVNAME, address);
2619 if (!f71882fg_pdev)
2620 return -ENOMEM;
2622 res.name = f71882fg_pdev->name;
2623 err = acpi_check_resource_conflict(&res);
2624 if (err)
2625 goto exit_device_put;
2627 err = platform_device_add_resources(f71882fg_pdev, &res, 1);
2628 if (err) {
2629 pr_err("Device resource addition failed\n");
2630 goto exit_device_put;
2633 err = platform_device_add_data(f71882fg_pdev, sio_data,
2634 sizeof(struct f71882fg_sio_data));
2635 if (err) {
2636 pr_err("Platform data allocation failed\n");
2637 goto exit_device_put;
2640 err = platform_device_add(f71882fg_pdev);
2641 if (err) {
2642 pr_err("Device addition failed\n");
2643 goto exit_device_put;
2646 return 0;
2648 exit_device_put:
2649 platform_device_put(f71882fg_pdev);
2651 return err;
2654 static int __init f71882fg_init(void)
2656 int err = -ENODEV;
2657 unsigned short address;
2658 struct f71882fg_sio_data sio_data;
2660 memset(&sio_data, 0, sizeof(sio_data));
2662 if (f71882fg_find(0x2e, &address, &sio_data) &&
2663 f71882fg_find(0x4e, &address, &sio_data))
2664 goto exit;
2666 err = platform_driver_register(&f71882fg_driver);
2667 if (err)
2668 goto exit;
2670 err = f71882fg_device_add(address, &sio_data);
2671 if (err)
2672 goto exit_driver;
2674 return 0;
2676 exit_driver:
2677 platform_driver_unregister(&f71882fg_driver);
2678 exit:
2679 return err;
2682 static void __exit f71882fg_exit(void)
2684 platform_device_unregister(f71882fg_pdev);
2685 platform_driver_unregister(&f71882fg_driver);
2688 MODULE_DESCRIPTION("F71882FG Hardware Monitoring Driver");
2689 MODULE_AUTHOR("Hans Edgington, Hans de Goede <hdegoede@redhat.com>");
2690 MODULE_LICENSE("GPL");
2692 module_init(f71882fg_init);
2693 module_exit(f71882fg_exit);