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