thp: add debug checks for mapcount related invariants
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / hwmon / f71882fg.c
blob3f49dd376f023e1e6d4a281bc84ae9f05c59288a
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 ***************************************************************************/
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 diasble 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_F71858_ID 0x0507 /* Chipset ID */
51 #define SIO_F71862_ID 0x0601 /* Chipset ID */
52 #define SIO_F71882_ID 0x0541 /* Chipset ID */
53 #define SIO_F71889_ID 0x0723 /* Chipset ID */
54 #define SIO_F8000_ID 0x0581 /* Chipset ID */
56 #define REGION_LENGTH 8
57 #define ADDR_REG_OFFSET 5
58 #define DATA_REG_OFFSET 6
60 #define F71882FG_REG_PECI 0x0A
62 #define F71882FG_REG_IN_STATUS 0x12 /* f71882fg only */
63 #define F71882FG_REG_IN_BEEP 0x13 /* f71882fg only */
64 #define F71882FG_REG_IN(nr) (0x20 + (nr))
65 #define F71882FG_REG_IN1_HIGH 0x32 /* f71882fg only */
67 #define F71882FG_REG_FAN(nr) (0xA0 + (16 * (nr)))
68 #define F71882FG_REG_FAN_TARGET(nr) (0xA2 + (16 * (nr)))
69 #define F71882FG_REG_FAN_FULL_SPEED(nr) (0xA4 + (16 * (nr)))
70 #define F71882FG_REG_FAN_STATUS 0x92
71 #define F71882FG_REG_FAN_BEEP 0x93
73 #define F71882FG_REG_TEMP(nr) (0x70 + 2 * (nr))
74 #define F71882FG_REG_TEMP_OVT(nr) (0x80 + 2 * (nr))
75 #define F71882FG_REG_TEMP_HIGH(nr) (0x81 + 2 * (nr))
76 #define F71882FG_REG_TEMP_STATUS 0x62
77 #define F71882FG_REG_TEMP_BEEP 0x63
78 #define F71882FG_REG_TEMP_CONFIG 0x69
79 #define F71882FG_REG_TEMP_HYST(nr) (0x6C + (nr))
80 #define F71882FG_REG_TEMP_TYPE 0x6B
81 #define F71882FG_REG_TEMP_DIODE_OPEN 0x6F
83 #define F71882FG_REG_PWM(nr) (0xA3 + (16 * (nr)))
84 #define F71882FG_REG_PWM_TYPE 0x94
85 #define F71882FG_REG_PWM_ENABLE 0x96
87 #define F71882FG_REG_FAN_HYST(nr) (0x98 + (nr))
89 #define F71882FG_REG_POINT_PWM(pwm, point) (0xAA + (point) + (16 * (pwm)))
90 #define F71882FG_REG_POINT_TEMP(pwm, point) (0xA6 + (point) + (16 * (pwm)))
91 #define F71882FG_REG_POINT_MAPPING(nr) (0xAF + 16 * (nr))
93 #define F71882FG_REG_START 0x01
95 #define FAN_MIN_DETECT 366 /* Lowest detectable fanspeed */
97 static unsigned short force_id;
98 module_param(force_id, ushort, 0);
99 MODULE_PARM_DESC(force_id, "Override the detected device ID");
101 enum chips { f71858fg, f71862fg, f71882fg, f71889fg, f8000 };
103 static const char *f71882fg_names[] = {
104 "f71858fg",
105 "f71862fg",
106 "f71882fg",
107 "f71889fg",
108 "f8000",
111 static struct platform_device *f71882fg_pdev;
113 /* Super-I/O Function prototypes */
114 static inline int superio_inb(int base, int reg);
115 static inline int superio_inw(int base, int reg);
116 static inline int superio_enter(int base);
117 static inline void superio_select(int base, int ld);
118 static inline void superio_exit(int base);
120 struct f71882fg_sio_data {
121 enum chips type;
124 struct f71882fg_data {
125 unsigned short addr;
126 enum chips type;
127 struct device *hwmon_dev;
129 struct mutex update_lock;
130 int temp_start; /* temp numbering start (0 or 1) */
131 char valid; /* !=0 if following fields are valid */
132 unsigned long last_updated; /* In jiffies */
133 unsigned long last_limits; /* In jiffies */
135 /* Register Values */
136 u8 in[9];
137 u8 in1_max;
138 u8 in_status;
139 u8 in_beep;
140 u16 fan[4];
141 u16 fan_target[4];
142 u16 fan_full_speed[4];
143 u8 fan_status;
144 u8 fan_beep;
145 /* Note: all models have only 3 temperature channels, but on some
146 they are addressed as 0-2 and on others as 1-3, so for coding
147 convenience we reserve space for 4 channels */
148 u16 temp[4];
149 u8 temp_ovt[4];
150 u8 temp_high[4];
151 u8 temp_hyst[2]; /* 2 hysts stored per reg */
152 u8 temp_type[4];
153 u8 temp_status;
154 u8 temp_beep;
155 u8 temp_diode_open;
156 u8 temp_config;
157 u8 pwm[4];
158 u8 pwm_enable;
159 u8 pwm_auto_point_hyst[2];
160 u8 pwm_auto_point_mapping[4];
161 u8 pwm_auto_point_pwm[4][5];
162 s8 pwm_auto_point_temp[4][4];
165 /* Sysfs in */
166 static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
167 char *buf);
168 static ssize_t show_in_max(struct device *dev, struct device_attribute
169 *devattr, char *buf);
170 static ssize_t store_in_max(struct device *dev, struct device_attribute
171 *devattr, const char *buf, size_t count);
172 static ssize_t show_in_beep(struct device *dev, struct device_attribute
173 *devattr, char *buf);
174 static ssize_t store_in_beep(struct device *dev, struct device_attribute
175 *devattr, const char *buf, size_t count);
176 static ssize_t show_in_alarm(struct device *dev, struct device_attribute
177 *devattr, char *buf);
178 /* Sysfs Fan */
179 static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
180 char *buf);
181 static ssize_t show_fan_full_speed(struct device *dev,
182 struct device_attribute *devattr, char *buf);
183 static ssize_t store_fan_full_speed(struct device *dev,
184 struct device_attribute *devattr, const char *buf, size_t count);
185 static ssize_t show_fan_beep(struct device *dev, struct device_attribute
186 *devattr, char *buf);
187 static ssize_t store_fan_beep(struct device *dev, struct device_attribute
188 *devattr, const char *buf, size_t count);
189 static ssize_t show_fan_alarm(struct device *dev, struct device_attribute
190 *devattr, char *buf);
191 /* Sysfs Temp */
192 static ssize_t show_temp(struct device *dev, struct device_attribute
193 *devattr, char *buf);
194 static ssize_t show_temp_max(struct device *dev, struct device_attribute
195 *devattr, char *buf);
196 static ssize_t store_temp_max(struct device *dev, struct device_attribute
197 *devattr, const char *buf, size_t count);
198 static ssize_t show_temp_max_hyst(struct device *dev, struct device_attribute
199 *devattr, char *buf);
200 static ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute
201 *devattr, const char *buf, size_t count);
202 static ssize_t show_temp_crit(struct device *dev, struct device_attribute
203 *devattr, char *buf);
204 static ssize_t store_temp_crit(struct device *dev, struct device_attribute
205 *devattr, const char *buf, size_t count);
206 static ssize_t show_temp_crit_hyst(struct device *dev, struct device_attribute
207 *devattr, char *buf);
208 static ssize_t show_temp_type(struct device *dev, struct device_attribute
209 *devattr, char *buf);
210 static ssize_t show_temp_beep(struct device *dev, struct device_attribute
211 *devattr, char *buf);
212 static ssize_t store_temp_beep(struct device *dev, struct device_attribute
213 *devattr, const char *buf, size_t count);
214 static ssize_t show_temp_alarm(struct device *dev, struct device_attribute
215 *devattr, char *buf);
216 static ssize_t show_temp_fault(struct device *dev, struct device_attribute
217 *devattr, char *buf);
218 /* PWM and Auto point control */
219 static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr,
220 char *buf);
221 static ssize_t store_pwm(struct device *dev, struct device_attribute *devattr,
222 const char *buf, size_t count);
223 static ssize_t show_pwm_enable(struct device *dev,
224 struct device_attribute *devattr, char *buf);
225 static ssize_t store_pwm_enable(struct device *dev,
226 struct device_attribute *devattr, const char *buf, size_t count);
227 static ssize_t show_pwm_interpolate(struct device *dev,
228 struct device_attribute *devattr, char *buf);
229 static ssize_t store_pwm_interpolate(struct device *dev,
230 struct device_attribute *devattr, const char *buf, size_t count);
231 static ssize_t show_pwm_auto_point_channel(struct device *dev,
232 struct device_attribute *devattr, char *buf);
233 static ssize_t store_pwm_auto_point_channel(struct device *dev,
234 struct device_attribute *devattr, const char *buf, size_t count);
235 static ssize_t show_pwm_auto_point_temp_hyst(struct device *dev,
236 struct device_attribute *devattr, char *buf);
237 static ssize_t store_pwm_auto_point_temp_hyst(struct device *dev,
238 struct device_attribute *devattr, const char *buf, size_t count);
239 static ssize_t show_pwm_auto_point_pwm(struct device *dev,
240 struct device_attribute *devattr, char *buf);
241 static ssize_t store_pwm_auto_point_pwm(struct device *dev,
242 struct device_attribute *devattr, const char *buf, size_t count);
243 static ssize_t show_pwm_auto_point_temp(struct device *dev,
244 struct device_attribute *devattr, char *buf);
245 static ssize_t store_pwm_auto_point_temp(struct device *dev,
246 struct device_attribute *devattr, const char *buf, size_t count);
247 /* Sysfs misc */
248 static ssize_t show_name(struct device *dev, struct device_attribute *devattr,
249 char *buf);
251 static int __devinit f71882fg_probe(struct platform_device * pdev);
252 static int f71882fg_remove(struct platform_device *pdev);
254 static struct platform_driver f71882fg_driver = {
255 .driver = {
256 .owner = THIS_MODULE,
257 .name = DRVNAME,
259 .probe = f71882fg_probe,
260 .remove = f71882fg_remove,
263 static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
265 /* Temp and in attr for the f71858fg, the f71858fg is special as it
266 has its temperature indexes start at 0 (the others start at 1) and
267 it only has 3 voltage inputs */
268 static struct sensor_device_attribute_2 f71858fg_in_temp_attr[] = {
269 SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
270 SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
271 SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
272 SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0),
273 SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max,
274 store_temp_max, 0, 0),
275 SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
276 store_temp_max_hyst, 0, 0),
277 SENSOR_ATTR_2(temp1_max_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 0),
278 SENSOR_ATTR_2(temp1_crit, S_IRUGO|S_IWUSR, show_temp_crit,
279 store_temp_crit, 0, 0),
280 SENSOR_ATTR_2(temp1_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
281 0, 0),
282 SENSOR_ATTR_2(temp1_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 4),
283 SENSOR_ATTR_2(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0, 0),
284 SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1),
285 SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_max,
286 store_temp_max, 0, 1),
287 SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
288 store_temp_max_hyst, 0, 1),
289 SENSOR_ATTR_2(temp2_max_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 1),
290 SENSOR_ATTR_2(temp2_crit, S_IRUGO|S_IWUSR, show_temp_crit,
291 store_temp_crit, 0, 1),
292 SENSOR_ATTR_2(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
293 0, 1),
294 SENSOR_ATTR_2(temp2_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5),
295 SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 1),
296 SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 1),
297 SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2),
298 SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max,
299 store_temp_max, 0, 2),
300 SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
301 store_temp_max_hyst, 0, 2),
302 SENSOR_ATTR_2(temp3_max_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 2),
303 SENSOR_ATTR_2(temp3_crit, S_IRUGO|S_IWUSR, show_temp_crit,
304 store_temp_crit, 0, 2),
305 SENSOR_ATTR_2(temp3_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
306 0, 2),
307 SENSOR_ATTR_2(temp3_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6),
308 SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
311 /* Temp and in attr common to the f71862fg, f71882fg and f71889fg */
312 static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = {
313 SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
314 SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
315 SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
316 SENSOR_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 0, 3),
317 SENSOR_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 0, 4),
318 SENSOR_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 0, 5),
319 SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 6),
320 SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 7),
321 SENSOR_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 0, 8),
322 SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 1),
323 SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max,
324 store_temp_max, 0, 1),
325 SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
326 store_temp_max_hyst, 0, 1),
327 /* Should really be temp1_max_alarm, but older versions did not handle
328 the max and crit alarms separately and lm_sensors v2 depends on the
329 presence of temp#_alarm files. The same goes for temp2/3 _alarm. */
330 SENSOR_ATTR_2(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 1),
331 SENSOR_ATTR_2(temp1_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
332 store_temp_beep, 0, 1),
333 SENSOR_ATTR_2(temp1_crit, S_IRUGO|S_IWUSR, show_temp_crit,
334 store_temp_crit, 0, 1),
335 SENSOR_ATTR_2(temp1_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
336 0, 1),
337 SENSOR_ATTR_2(temp1_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5),
338 SENSOR_ATTR_2(temp1_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
339 store_temp_beep, 0, 5),
340 SENSOR_ATTR_2(temp1_type, S_IRUGO, show_temp_type, NULL, 0, 1),
341 SENSOR_ATTR_2(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0, 1),
342 SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 2),
343 SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_max,
344 store_temp_max, 0, 2),
345 SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
346 store_temp_max_hyst, 0, 2),
347 /* Should be temp2_max_alarm, see temp1_alarm note */
348 SENSOR_ATTR_2(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 2),
349 SENSOR_ATTR_2(temp2_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
350 store_temp_beep, 0, 2),
351 SENSOR_ATTR_2(temp2_crit, S_IRUGO|S_IWUSR, show_temp_crit,
352 store_temp_crit, 0, 2),
353 SENSOR_ATTR_2(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
354 0, 2),
355 SENSOR_ATTR_2(temp2_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6),
356 SENSOR_ATTR_2(temp2_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
357 store_temp_beep, 0, 6),
358 SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 2),
359 SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
360 SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 3),
361 SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max,
362 store_temp_max, 0, 3),
363 SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
364 store_temp_max_hyst, 0, 3),
365 /* Should be temp3_max_alarm, see temp1_alarm note */
366 SENSOR_ATTR_2(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 3),
367 SENSOR_ATTR_2(temp3_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
368 store_temp_beep, 0, 3),
369 SENSOR_ATTR_2(temp3_crit, S_IRUGO|S_IWUSR, show_temp_crit,
370 store_temp_crit, 0, 3),
371 SENSOR_ATTR_2(temp3_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
372 0, 3),
373 SENSOR_ATTR_2(temp3_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 7),
374 SENSOR_ATTR_2(temp3_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
375 store_temp_beep, 0, 7),
376 SENSOR_ATTR_2(temp3_type, S_IRUGO, show_temp_type, NULL, 0, 3),
377 SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 3),
380 /* For models with in1 alarm capability */
381 static struct sensor_device_attribute_2 fxxxx_in1_alarm_attr[] = {
382 SENSOR_ATTR_2(in1_max, S_IRUGO|S_IWUSR, show_in_max, store_in_max,
383 0, 1),
384 SENSOR_ATTR_2(in1_beep, S_IRUGO|S_IWUSR, show_in_beep, store_in_beep,
385 0, 1),
386 SENSOR_ATTR_2(in1_alarm, S_IRUGO, show_in_alarm, NULL, 0, 1),
389 /* Temp and in attr for the f8000
390 Note on the f8000 temp_ovt (crit) is used as max, and temp_high (max)
391 is used as hysteresis value to clear alarms
392 Also like the f71858fg its temperature indexes start at 0
394 static struct sensor_device_attribute_2 f8000_in_temp_attr[] = {
395 SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
396 SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
397 SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
398 SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0),
399 SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_crit,
400 store_temp_crit, 0, 0),
401 SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max,
402 store_temp_max, 0, 0),
403 SENSOR_ATTR_2(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 4),
404 SENSOR_ATTR_2(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0, 0),
405 SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1),
406 SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_crit,
407 store_temp_crit, 0, 1),
408 SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max,
409 store_temp_max, 0, 1),
410 SENSOR_ATTR_2(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5),
411 SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 1),
412 SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 1),
413 SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2),
414 SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_crit,
415 store_temp_crit, 0, 2),
416 SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max,
417 store_temp_max, 0, 2),
418 SENSOR_ATTR_2(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6),
419 SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
422 /* Fan / PWM attr common to all models */
423 static struct sensor_device_attribute_2 fxxxx_fan_attr[4][6] = { {
424 SENSOR_ATTR_2(fan1_input, S_IRUGO, show_fan, NULL, 0, 0),
425 SENSOR_ATTR_2(fan1_full_speed, S_IRUGO|S_IWUSR,
426 show_fan_full_speed,
427 store_fan_full_speed, 0, 0),
428 SENSOR_ATTR_2(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 0),
429 SENSOR_ATTR_2(pwm1, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 0),
430 SENSOR_ATTR_2(pwm1_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
431 store_pwm_enable, 0, 0),
432 SENSOR_ATTR_2(pwm1_interpolate, S_IRUGO|S_IWUSR,
433 show_pwm_interpolate, store_pwm_interpolate, 0, 0),
434 }, {
435 SENSOR_ATTR_2(fan2_input, S_IRUGO, show_fan, NULL, 0, 1),
436 SENSOR_ATTR_2(fan2_full_speed, S_IRUGO|S_IWUSR,
437 show_fan_full_speed,
438 store_fan_full_speed, 0, 1),
439 SENSOR_ATTR_2(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 1),
440 SENSOR_ATTR_2(pwm2, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 1),
441 SENSOR_ATTR_2(pwm2_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
442 store_pwm_enable, 0, 1),
443 SENSOR_ATTR_2(pwm2_interpolate, S_IRUGO|S_IWUSR,
444 show_pwm_interpolate, store_pwm_interpolate, 0, 1),
445 }, {
446 SENSOR_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 0, 2),
447 SENSOR_ATTR_2(fan3_full_speed, S_IRUGO|S_IWUSR,
448 show_fan_full_speed,
449 store_fan_full_speed, 0, 2),
450 SENSOR_ATTR_2(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 2),
451 SENSOR_ATTR_2(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 2),
452 SENSOR_ATTR_2(pwm3_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
453 store_pwm_enable, 0, 2),
454 SENSOR_ATTR_2(pwm3_interpolate, S_IRUGO|S_IWUSR,
455 show_pwm_interpolate, store_pwm_interpolate, 0, 2),
456 }, {
457 SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
458 SENSOR_ATTR_2(fan4_full_speed, S_IRUGO|S_IWUSR,
459 show_fan_full_speed,
460 store_fan_full_speed, 0, 3),
461 SENSOR_ATTR_2(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 3),
462 SENSOR_ATTR_2(pwm4, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 3),
463 SENSOR_ATTR_2(pwm4_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
464 store_pwm_enable, 0, 3),
465 SENSOR_ATTR_2(pwm4_interpolate, S_IRUGO|S_IWUSR,
466 show_pwm_interpolate, store_pwm_interpolate, 0, 3),
467 } };
469 /* Attr for models which can beep on Fan alarm */
470 static struct sensor_device_attribute_2 fxxxx_fan_beep_attr[] = {
471 SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep,
472 store_fan_beep, 0, 0),
473 SENSOR_ATTR_2(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep,
474 store_fan_beep, 0, 1),
475 SENSOR_ATTR_2(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep,
476 store_fan_beep, 0, 2),
477 SENSOR_ATTR_2(fan4_beep, S_IRUGO|S_IWUSR, show_fan_beep,
478 store_fan_beep, 0, 3),
481 /* PWM attr for the f71862fg, fewer pwms and fewer zones per pwm than the
482 f71858fg / f71882fg / f71889fg */
483 static struct sensor_device_attribute_2 f71862fg_auto_pwm_attr[] = {
484 SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
485 show_pwm_auto_point_channel,
486 store_pwm_auto_point_channel, 0, 0),
487 SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,
488 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
489 1, 0),
490 SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO|S_IWUSR,
491 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
492 4, 0),
493 SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IRUGO|S_IWUSR,
494 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
495 0, 0),
496 SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IRUGO|S_IWUSR,
497 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
498 3, 0),
499 SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
500 show_pwm_auto_point_temp_hyst,
501 store_pwm_auto_point_temp_hyst,
502 0, 0),
503 SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO,
504 show_pwm_auto_point_temp_hyst, NULL, 3, 0),
506 SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,
507 show_pwm_auto_point_channel,
508 store_pwm_auto_point_channel, 0, 1),
509 SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR,
510 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
511 1, 1),
512 SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO|S_IWUSR,
513 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
514 4, 1),
515 SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IRUGO|S_IWUSR,
516 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
517 0, 1),
518 SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IRUGO|S_IWUSR,
519 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
520 3, 1),
521 SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
522 show_pwm_auto_point_temp_hyst,
523 store_pwm_auto_point_temp_hyst,
524 0, 1),
525 SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO,
526 show_pwm_auto_point_temp_hyst, NULL, 3, 1),
528 SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
529 show_pwm_auto_point_channel,
530 store_pwm_auto_point_channel, 0, 2),
531 SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR,
532 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
533 1, 2),
534 SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO|S_IWUSR,
535 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
536 4, 2),
537 SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IRUGO|S_IWUSR,
538 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
539 0, 2),
540 SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IRUGO|S_IWUSR,
541 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
542 3, 2),
543 SENSOR_ATTR_2(pwm3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
544 show_pwm_auto_point_temp_hyst,
545 store_pwm_auto_point_temp_hyst,
546 0, 2),
547 SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst, S_IRUGO,
548 show_pwm_auto_point_temp_hyst, NULL, 3, 2),
551 /* PWM attr common to the f71858fg, f71882fg and f71889fg */
552 static struct sensor_device_attribute_2 fxxxx_auto_pwm_attr[4][14] = { {
553 SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
554 show_pwm_auto_point_channel,
555 store_pwm_auto_point_channel, 0, 0),
556 SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,
557 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
558 0, 0),
559 SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO|S_IWUSR,
560 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
561 1, 0),
562 SENSOR_ATTR_2(pwm1_auto_point3_pwm, S_IRUGO|S_IWUSR,
563 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
564 2, 0),
565 SENSOR_ATTR_2(pwm1_auto_point4_pwm, S_IRUGO|S_IWUSR,
566 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
567 3, 0),
568 SENSOR_ATTR_2(pwm1_auto_point5_pwm, S_IRUGO|S_IWUSR,
569 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
570 4, 0),
571 SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IRUGO|S_IWUSR,
572 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
573 0, 0),
574 SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IRUGO|S_IWUSR,
575 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
576 1, 0),
577 SENSOR_ATTR_2(pwm1_auto_point3_temp, S_IRUGO|S_IWUSR,
578 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
579 2, 0),
580 SENSOR_ATTR_2(pwm1_auto_point4_temp, S_IRUGO|S_IWUSR,
581 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
582 3, 0),
583 SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
584 show_pwm_auto_point_temp_hyst,
585 store_pwm_auto_point_temp_hyst,
586 0, 0),
587 SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO,
588 show_pwm_auto_point_temp_hyst, NULL, 1, 0),
589 SENSOR_ATTR_2(pwm1_auto_point3_temp_hyst, S_IRUGO,
590 show_pwm_auto_point_temp_hyst, NULL, 2, 0),
591 SENSOR_ATTR_2(pwm1_auto_point4_temp_hyst, S_IRUGO,
592 show_pwm_auto_point_temp_hyst, NULL, 3, 0),
593 }, {
594 SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,
595 show_pwm_auto_point_channel,
596 store_pwm_auto_point_channel, 0, 1),
597 SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR,
598 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
599 0, 1),
600 SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO|S_IWUSR,
601 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
602 1, 1),
603 SENSOR_ATTR_2(pwm2_auto_point3_pwm, S_IRUGO|S_IWUSR,
604 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
605 2, 1),
606 SENSOR_ATTR_2(pwm2_auto_point4_pwm, S_IRUGO|S_IWUSR,
607 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
608 3, 1),
609 SENSOR_ATTR_2(pwm2_auto_point5_pwm, S_IRUGO|S_IWUSR,
610 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
611 4, 1),
612 SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IRUGO|S_IWUSR,
613 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
614 0, 1),
615 SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IRUGO|S_IWUSR,
616 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
617 1, 1),
618 SENSOR_ATTR_2(pwm2_auto_point3_temp, S_IRUGO|S_IWUSR,
619 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
620 2, 1),
621 SENSOR_ATTR_2(pwm2_auto_point4_temp, S_IRUGO|S_IWUSR,
622 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
623 3, 1),
624 SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
625 show_pwm_auto_point_temp_hyst,
626 store_pwm_auto_point_temp_hyst,
627 0, 1),
628 SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO,
629 show_pwm_auto_point_temp_hyst, NULL, 1, 1),
630 SENSOR_ATTR_2(pwm2_auto_point3_temp_hyst, S_IRUGO,
631 show_pwm_auto_point_temp_hyst, NULL, 2, 1),
632 SENSOR_ATTR_2(pwm2_auto_point4_temp_hyst, S_IRUGO,
633 show_pwm_auto_point_temp_hyst, NULL, 3, 1),
634 }, {
635 SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
636 show_pwm_auto_point_channel,
637 store_pwm_auto_point_channel, 0, 2),
638 SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR,
639 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
640 0, 2),
641 SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO|S_IWUSR,
642 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
643 1, 2),
644 SENSOR_ATTR_2(pwm3_auto_point3_pwm, S_IRUGO|S_IWUSR,
645 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
646 2, 2),
647 SENSOR_ATTR_2(pwm3_auto_point4_pwm, S_IRUGO|S_IWUSR,
648 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
649 3, 2),
650 SENSOR_ATTR_2(pwm3_auto_point5_pwm, S_IRUGO|S_IWUSR,
651 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
652 4, 2),
653 SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IRUGO|S_IWUSR,
654 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
655 0, 2),
656 SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IRUGO|S_IWUSR,
657 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
658 1, 2),
659 SENSOR_ATTR_2(pwm3_auto_point3_temp, S_IRUGO|S_IWUSR,
660 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
661 2, 2),
662 SENSOR_ATTR_2(pwm3_auto_point4_temp, S_IRUGO|S_IWUSR,
663 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
664 3, 2),
665 SENSOR_ATTR_2(pwm3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
666 show_pwm_auto_point_temp_hyst,
667 store_pwm_auto_point_temp_hyst,
668 0, 2),
669 SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst, S_IRUGO,
670 show_pwm_auto_point_temp_hyst, NULL, 1, 2),
671 SENSOR_ATTR_2(pwm3_auto_point3_temp_hyst, S_IRUGO,
672 show_pwm_auto_point_temp_hyst, NULL, 2, 2),
673 SENSOR_ATTR_2(pwm3_auto_point4_temp_hyst, S_IRUGO,
674 show_pwm_auto_point_temp_hyst, NULL, 3, 2),
675 }, {
676 SENSOR_ATTR_2(pwm4_auto_channels_temp, S_IRUGO|S_IWUSR,
677 show_pwm_auto_point_channel,
678 store_pwm_auto_point_channel, 0, 3),
679 SENSOR_ATTR_2(pwm4_auto_point1_pwm, S_IRUGO|S_IWUSR,
680 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
681 0, 3),
682 SENSOR_ATTR_2(pwm4_auto_point2_pwm, S_IRUGO|S_IWUSR,
683 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
684 1, 3),
685 SENSOR_ATTR_2(pwm4_auto_point3_pwm, S_IRUGO|S_IWUSR,
686 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
687 2, 3),
688 SENSOR_ATTR_2(pwm4_auto_point4_pwm, S_IRUGO|S_IWUSR,
689 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
690 3, 3),
691 SENSOR_ATTR_2(pwm4_auto_point5_pwm, S_IRUGO|S_IWUSR,
692 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
693 4, 3),
694 SENSOR_ATTR_2(pwm4_auto_point1_temp, S_IRUGO|S_IWUSR,
695 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
696 0, 3),
697 SENSOR_ATTR_2(pwm4_auto_point2_temp, S_IRUGO|S_IWUSR,
698 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
699 1, 3),
700 SENSOR_ATTR_2(pwm4_auto_point3_temp, S_IRUGO|S_IWUSR,
701 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
702 2, 3),
703 SENSOR_ATTR_2(pwm4_auto_point4_temp, S_IRUGO|S_IWUSR,
704 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
705 3, 3),
706 SENSOR_ATTR_2(pwm4_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
707 show_pwm_auto_point_temp_hyst,
708 store_pwm_auto_point_temp_hyst,
709 0, 3),
710 SENSOR_ATTR_2(pwm4_auto_point2_temp_hyst, S_IRUGO,
711 show_pwm_auto_point_temp_hyst, NULL, 1, 3),
712 SENSOR_ATTR_2(pwm4_auto_point3_temp_hyst, S_IRUGO,
713 show_pwm_auto_point_temp_hyst, NULL, 2, 3),
714 SENSOR_ATTR_2(pwm4_auto_point4_temp_hyst, S_IRUGO,
715 show_pwm_auto_point_temp_hyst, NULL, 3, 3),
716 } };
718 /* Fan attr specific to the f8000 (4th fan input can only measure speed) */
719 static struct sensor_device_attribute_2 f8000_fan_attr[] = {
720 SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
723 /* PWM attr for the f8000, zones mapped to temp instead of to pwm!
724 Also the register block at offset A0 maps to TEMP1 (so our temp2, as the
725 F8000 starts counting temps at 0), B0 maps the TEMP2 and C0 maps to TEMP0 */
726 static struct sensor_device_attribute_2 f8000_auto_pwm_attr[] = {
727 SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
728 show_pwm_auto_point_channel,
729 store_pwm_auto_point_channel, 0, 0),
730 SENSOR_ATTR_2(temp1_auto_point1_pwm, S_IRUGO|S_IWUSR,
731 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
732 0, 2),
733 SENSOR_ATTR_2(temp1_auto_point2_pwm, S_IRUGO|S_IWUSR,
734 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
735 1, 2),
736 SENSOR_ATTR_2(temp1_auto_point3_pwm, S_IRUGO|S_IWUSR,
737 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
738 2, 2),
739 SENSOR_ATTR_2(temp1_auto_point4_pwm, S_IRUGO|S_IWUSR,
740 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
741 3, 2),
742 SENSOR_ATTR_2(temp1_auto_point5_pwm, S_IRUGO|S_IWUSR,
743 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
744 4, 2),
745 SENSOR_ATTR_2(temp1_auto_point1_temp, S_IRUGO|S_IWUSR,
746 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
747 0, 2),
748 SENSOR_ATTR_2(temp1_auto_point2_temp, S_IRUGO|S_IWUSR,
749 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
750 1, 2),
751 SENSOR_ATTR_2(temp1_auto_point3_temp, S_IRUGO|S_IWUSR,
752 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
753 2, 2),
754 SENSOR_ATTR_2(temp1_auto_point4_temp, S_IRUGO|S_IWUSR,
755 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
756 3, 2),
757 SENSOR_ATTR_2(temp1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
758 show_pwm_auto_point_temp_hyst,
759 store_pwm_auto_point_temp_hyst,
760 0, 2),
761 SENSOR_ATTR_2(temp1_auto_point2_temp_hyst, S_IRUGO,
762 show_pwm_auto_point_temp_hyst, NULL, 1, 2),
763 SENSOR_ATTR_2(temp1_auto_point3_temp_hyst, S_IRUGO,
764 show_pwm_auto_point_temp_hyst, NULL, 2, 2),
765 SENSOR_ATTR_2(temp1_auto_point4_temp_hyst, S_IRUGO,
766 show_pwm_auto_point_temp_hyst, NULL, 3, 2),
768 SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,
769 show_pwm_auto_point_channel,
770 store_pwm_auto_point_channel, 0, 1),
771 SENSOR_ATTR_2(temp2_auto_point1_pwm, S_IRUGO|S_IWUSR,
772 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
773 0, 0),
774 SENSOR_ATTR_2(temp2_auto_point2_pwm, S_IRUGO|S_IWUSR,
775 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
776 1, 0),
777 SENSOR_ATTR_2(temp2_auto_point3_pwm, S_IRUGO|S_IWUSR,
778 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
779 2, 0),
780 SENSOR_ATTR_2(temp2_auto_point4_pwm, S_IRUGO|S_IWUSR,
781 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
782 3, 0),
783 SENSOR_ATTR_2(temp2_auto_point5_pwm, S_IRUGO|S_IWUSR,
784 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
785 4, 0),
786 SENSOR_ATTR_2(temp2_auto_point1_temp, S_IRUGO|S_IWUSR,
787 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
788 0, 0),
789 SENSOR_ATTR_2(temp2_auto_point2_temp, S_IRUGO|S_IWUSR,
790 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
791 1, 0),
792 SENSOR_ATTR_2(temp2_auto_point3_temp, S_IRUGO|S_IWUSR,
793 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
794 2, 0),
795 SENSOR_ATTR_2(temp2_auto_point4_temp, S_IRUGO|S_IWUSR,
796 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
797 3, 0),
798 SENSOR_ATTR_2(temp2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
799 show_pwm_auto_point_temp_hyst,
800 store_pwm_auto_point_temp_hyst,
801 0, 0),
802 SENSOR_ATTR_2(temp2_auto_point2_temp_hyst, S_IRUGO,
803 show_pwm_auto_point_temp_hyst, NULL, 1, 0),
804 SENSOR_ATTR_2(temp2_auto_point3_temp_hyst, S_IRUGO,
805 show_pwm_auto_point_temp_hyst, NULL, 2, 0),
806 SENSOR_ATTR_2(temp2_auto_point4_temp_hyst, S_IRUGO,
807 show_pwm_auto_point_temp_hyst, NULL, 3, 0),
809 SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
810 show_pwm_auto_point_channel,
811 store_pwm_auto_point_channel, 0, 2),
812 SENSOR_ATTR_2(temp3_auto_point1_pwm, S_IRUGO|S_IWUSR,
813 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
814 0, 1),
815 SENSOR_ATTR_2(temp3_auto_point2_pwm, S_IRUGO|S_IWUSR,
816 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
817 1, 1),
818 SENSOR_ATTR_2(temp3_auto_point3_pwm, S_IRUGO|S_IWUSR,
819 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
820 2, 1),
821 SENSOR_ATTR_2(temp3_auto_point4_pwm, S_IRUGO|S_IWUSR,
822 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
823 3, 1),
824 SENSOR_ATTR_2(temp3_auto_point5_pwm, S_IRUGO|S_IWUSR,
825 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
826 4, 1),
827 SENSOR_ATTR_2(temp3_auto_point1_temp, S_IRUGO|S_IWUSR,
828 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
829 0, 1),
830 SENSOR_ATTR_2(temp3_auto_point2_temp, S_IRUGO|S_IWUSR,
831 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
832 1, 1),
833 SENSOR_ATTR_2(temp3_auto_point3_temp, S_IRUGO|S_IWUSR,
834 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
835 2, 1),
836 SENSOR_ATTR_2(temp3_auto_point4_temp, S_IRUGO|S_IWUSR,
837 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
838 3, 1),
839 SENSOR_ATTR_2(temp3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
840 show_pwm_auto_point_temp_hyst,
841 store_pwm_auto_point_temp_hyst,
842 0, 1),
843 SENSOR_ATTR_2(temp3_auto_point2_temp_hyst, S_IRUGO,
844 show_pwm_auto_point_temp_hyst, NULL, 1, 1),
845 SENSOR_ATTR_2(temp3_auto_point3_temp_hyst, S_IRUGO,
846 show_pwm_auto_point_temp_hyst, NULL, 2, 1),
847 SENSOR_ATTR_2(temp3_auto_point4_temp_hyst, S_IRUGO,
848 show_pwm_auto_point_temp_hyst, NULL, 3, 1),
851 /* Super I/O functions */
852 static inline int superio_inb(int base, int reg)
854 outb(reg, base);
855 return inb(base + 1);
858 static int superio_inw(int base, int reg)
860 int val;
861 val = superio_inb(base, reg) << 8;
862 val |= superio_inb(base, reg + 1);
863 return val;
866 static inline int superio_enter(int base)
868 /* Don't step on other drivers' I/O space by accident */
869 if (!request_muxed_region(base, 2, DRVNAME)) {
870 pr_err("I/O address 0x%04x already in use\n", base);
871 return -EBUSY;
874 /* according to the datasheet the key must be send twice! */
875 outb(SIO_UNLOCK_KEY, base);
876 outb(SIO_UNLOCK_KEY, base);
878 return 0;
881 static inline void superio_select(int base, int ld)
883 outb(SIO_REG_LDSEL, base);
884 outb(ld, base + 1);
887 static inline void superio_exit(int base)
889 outb(SIO_LOCK_KEY, base);
890 release_region(base, 2);
893 static inline int fan_from_reg(u16 reg)
895 return reg ? (1500000 / reg) : 0;
898 static inline u16 fan_to_reg(int fan)
900 return fan ? (1500000 / fan) : 0;
903 static u8 f71882fg_read8(struct f71882fg_data *data, u8 reg)
905 u8 val;
907 outb(reg, data->addr + ADDR_REG_OFFSET);
908 val = inb(data->addr + DATA_REG_OFFSET);
910 return val;
913 static u16 f71882fg_read16(struct f71882fg_data *data, u8 reg)
915 u16 val;
917 val = f71882fg_read8(data, reg) << 8;
918 val |= f71882fg_read8(data, reg + 1);
920 return val;
923 static void f71882fg_write8(struct f71882fg_data *data, u8 reg, u8 val)
925 outb(reg, data->addr + ADDR_REG_OFFSET);
926 outb(val, data->addr + DATA_REG_OFFSET);
929 static void f71882fg_write16(struct f71882fg_data *data, u8 reg, u16 val)
931 f71882fg_write8(data, reg, val >> 8);
932 f71882fg_write8(data, reg + 1, val & 0xff);
935 static u16 f71882fg_read_temp(struct f71882fg_data *data, int nr)
937 if (data->type == f71858fg)
938 return f71882fg_read16(data, F71882FG_REG_TEMP(nr));
939 else
940 return f71882fg_read8(data, F71882FG_REG_TEMP(nr));
943 static struct f71882fg_data *f71882fg_update_device(struct device *dev)
945 struct f71882fg_data *data = dev_get_drvdata(dev);
946 int nr, reg = 0, reg2;
947 int nr_fans = (data->type == f71882fg) ? 4 : 3;
948 int nr_ins = (data->type == f71858fg || data->type == f8000) ? 3 : 9;
950 mutex_lock(&data->update_lock);
952 /* Update once every 60 seconds */
953 if (time_after(jiffies, data->last_limits + 60 * HZ) ||
954 !data->valid) {
955 if (data->type == f71882fg || data->type == f71889fg) {
956 data->in1_max =
957 f71882fg_read8(data, F71882FG_REG_IN1_HIGH);
958 data->in_beep =
959 f71882fg_read8(data, F71882FG_REG_IN_BEEP);
962 /* Get High & boundary temps*/
963 for (nr = data->temp_start; nr < 3 + data->temp_start; nr++) {
964 data->temp_ovt[nr] = f71882fg_read8(data,
965 F71882FG_REG_TEMP_OVT(nr));
966 data->temp_high[nr] = f71882fg_read8(data,
967 F71882FG_REG_TEMP_HIGH(nr));
970 if (data->type != f8000) {
971 data->temp_hyst[0] = f71882fg_read8(data,
972 F71882FG_REG_TEMP_HYST(0));
973 data->temp_hyst[1] = f71882fg_read8(data,
974 F71882FG_REG_TEMP_HYST(1));
977 if (data->type == f71862fg || data->type == f71882fg ||
978 data->type == f71889fg) {
979 data->fan_beep = f71882fg_read8(data,
980 F71882FG_REG_FAN_BEEP);
981 data->temp_beep = f71882fg_read8(data,
982 F71882FG_REG_TEMP_BEEP);
983 /* Have to hardcode type, because temp1 is special */
984 reg = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE);
985 data->temp_type[2] = (reg & 0x04) ? 2 : 4;
986 data->temp_type[3] = (reg & 0x08) ? 2 : 4;
988 /* Determine temp index 1 sensor type */
989 if (data->type == f71889fg) {
990 reg2 = f71882fg_read8(data, F71882FG_REG_START);
991 switch ((reg2 & 0x60) >> 5) {
992 case 0x00: /* BJT / Thermistor */
993 data->temp_type[1] = (reg & 0x02) ? 2 : 4;
994 break;
995 case 0x01: /* AMDSI */
996 data->temp_type[1] = 5;
997 break;
998 case 0x02: /* PECI */
999 case 0x03: /* Ibex Peak ?? Report as PECI for now */
1000 data->temp_type[1] = 6;
1001 break;
1003 } else {
1004 reg2 = f71882fg_read8(data, F71882FG_REG_PECI);
1005 if ((reg2 & 0x03) == 0x01)
1006 data->temp_type[1] = 6; /* PECI */
1007 else if ((reg2 & 0x03) == 0x02)
1008 data->temp_type[1] = 5; /* AMDSI */
1009 else if (data->type == f71862fg ||
1010 data->type == f71882fg)
1011 data->temp_type[1] = (reg & 0x02) ? 2 : 4;
1012 else /* f71858fg and f8000 only support BJT */
1013 data->temp_type[1] = 2;
1016 data->pwm_enable = f71882fg_read8(data,
1017 F71882FG_REG_PWM_ENABLE);
1018 data->pwm_auto_point_hyst[0] =
1019 f71882fg_read8(data, F71882FG_REG_FAN_HYST(0));
1020 data->pwm_auto_point_hyst[1] =
1021 f71882fg_read8(data, F71882FG_REG_FAN_HYST(1));
1023 for (nr = 0; nr < nr_fans; nr++) {
1024 data->pwm_auto_point_mapping[nr] =
1025 f71882fg_read8(data,
1026 F71882FG_REG_POINT_MAPPING(nr));
1028 if (data->type != f71862fg) {
1029 int point;
1030 for (point = 0; point < 5; point++) {
1031 data->pwm_auto_point_pwm[nr][point] =
1032 f71882fg_read8(data,
1033 F71882FG_REG_POINT_PWM
1034 (nr, point));
1036 for (point = 0; point < 4; point++) {
1037 data->pwm_auto_point_temp[nr][point] =
1038 f71882fg_read8(data,
1039 F71882FG_REG_POINT_TEMP
1040 (nr, point));
1042 } else {
1043 data->pwm_auto_point_pwm[nr][1] =
1044 f71882fg_read8(data,
1045 F71882FG_REG_POINT_PWM
1046 (nr, 1));
1047 data->pwm_auto_point_pwm[nr][4] =
1048 f71882fg_read8(data,
1049 F71882FG_REG_POINT_PWM
1050 (nr, 4));
1051 data->pwm_auto_point_temp[nr][0] =
1052 f71882fg_read8(data,
1053 F71882FG_REG_POINT_TEMP
1054 (nr, 0));
1055 data->pwm_auto_point_temp[nr][3] =
1056 f71882fg_read8(data,
1057 F71882FG_REG_POINT_TEMP
1058 (nr, 3));
1061 data->last_limits = jiffies;
1064 /* Update every second */
1065 if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
1066 data->temp_status = f71882fg_read8(data,
1067 F71882FG_REG_TEMP_STATUS);
1068 data->temp_diode_open = f71882fg_read8(data,
1069 F71882FG_REG_TEMP_DIODE_OPEN);
1070 for (nr = data->temp_start; nr < 3 + data->temp_start; nr++)
1071 data->temp[nr] = f71882fg_read_temp(data, nr);
1073 data->fan_status = f71882fg_read8(data,
1074 F71882FG_REG_FAN_STATUS);
1075 for (nr = 0; nr < nr_fans; nr++) {
1076 data->fan[nr] = f71882fg_read16(data,
1077 F71882FG_REG_FAN(nr));
1078 data->fan_target[nr] =
1079 f71882fg_read16(data, F71882FG_REG_FAN_TARGET(nr));
1080 data->fan_full_speed[nr] =
1081 f71882fg_read16(data,
1082 F71882FG_REG_FAN_FULL_SPEED(nr));
1083 data->pwm[nr] =
1084 f71882fg_read8(data, F71882FG_REG_PWM(nr));
1087 /* The f8000 can monitor 1 more fan, but has no pwm for it */
1088 if (data->type == f8000)
1089 data->fan[3] = f71882fg_read16(data,
1090 F71882FG_REG_FAN(3));
1091 if (data->type == f71882fg || data->type == f71889fg)
1092 data->in_status = f71882fg_read8(data,
1093 F71882FG_REG_IN_STATUS);
1094 for (nr = 0; nr < nr_ins; nr++)
1095 data->in[nr] = f71882fg_read8(data,
1096 F71882FG_REG_IN(nr));
1098 data->last_updated = jiffies;
1099 data->valid = 1;
1102 mutex_unlock(&data->update_lock);
1104 return data;
1107 /* Sysfs Interface */
1108 static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
1109 char *buf)
1111 struct f71882fg_data *data = f71882fg_update_device(dev);
1112 int nr = to_sensor_dev_attr_2(devattr)->index;
1113 int speed = fan_from_reg(data->fan[nr]);
1115 if (speed == FAN_MIN_DETECT)
1116 speed = 0;
1118 return sprintf(buf, "%d\n", speed);
1121 static ssize_t show_fan_full_speed(struct device *dev,
1122 struct device_attribute *devattr, char *buf)
1124 struct f71882fg_data *data = f71882fg_update_device(dev);
1125 int nr = to_sensor_dev_attr_2(devattr)->index;
1126 int speed = fan_from_reg(data->fan_full_speed[nr]);
1127 return sprintf(buf, "%d\n", speed);
1130 static ssize_t store_fan_full_speed(struct device *dev,
1131 struct device_attribute *devattr,
1132 const char *buf, size_t count)
1134 struct f71882fg_data *data = dev_get_drvdata(dev);
1135 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1136 long val;
1138 err = strict_strtol(buf, 10, &val);
1139 if (err)
1140 return err;
1142 val = SENSORS_LIMIT(val, 23, 1500000);
1143 val = fan_to_reg(val);
1145 mutex_lock(&data->update_lock);
1146 f71882fg_write16(data, F71882FG_REG_FAN_FULL_SPEED(nr), val);
1147 data->fan_full_speed[nr] = val;
1148 mutex_unlock(&data->update_lock);
1150 return count;
1153 static ssize_t show_fan_beep(struct device *dev, struct device_attribute
1154 *devattr, char *buf)
1156 struct f71882fg_data *data = f71882fg_update_device(dev);
1157 int nr = to_sensor_dev_attr_2(devattr)->index;
1159 if (data->fan_beep & (1 << nr))
1160 return sprintf(buf, "1\n");
1161 else
1162 return sprintf(buf, "0\n");
1165 static ssize_t store_fan_beep(struct device *dev, struct device_attribute
1166 *devattr, const char *buf, size_t count)
1168 struct f71882fg_data *data = dev_get_drvdata(dev);
1169 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1170 unsigned long val;
1172 err = strict_strtoul(buf, 10, &val);
1173 if (err)
1174 return err;
1176 mutex_lock(&data->update_lock);
1177 data->fan_beep = f71882fg_read8(data, F71882FG_REG_FAN_BEEP);
1178 if (val)
1179 data->fan_beep |= 1 << nr;
1180 else
1181 data->fan_beep &= ~(1 << nr);
1183 f71882fg_write8(data, F71882FG_REG_FAN_BEEP, data->fan_beep);
1184 mutex_unlock(&data->update_lock);
1186 return count;
1189 static ssize_t show_fan_alarm(struct device *dev, struct device_attribute
1190 *devattr, char *buf)
1192 struct f71882fg_data *data = f71882fg_update_device(dev);
1193 int nr = to_sensor_dev_attr_2(devattr)->index;
1195 if (data->fan_status & (1 << nr))
1196 return sprintf(buf, "1\n");
1197 else
1198 return sprintf(buf, "0\n");
1201 static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
1202 char *buf)
1204 struct f71882fg_data *data = f71882fg_update_device(dev);
1205 int nr = to_sensor_dev_attr_2(devattr)->index;
1207 return sprintf(buf, "%d\n", data->in[nr] * 8);
1210 static ssize_t show_in_max(struct device *dev, struct device_attribute
1211 *devattr, char *buf)
1213 struct f71882fg_data *data = f71882fg_update_device(dev);
1215 return sprintf(buf, "%d\n", data->in1_max * 8);
1218 static ssize_t store_in_max(struct device *dev, struct device_attribute
1219 *devattr, const char *buf, size_t count)
1221 struct f71882fg_data *data = dev_get_drvdata(dev);
1222 int err;
1223 long val;
1225 err = strict_strtol(buf, 10, &val);
1226 if (err)
1227 return err;
1229 val /= 8;
1230 val = SENSORS_LIMIT(val, 0, 255);
1232 mutex_lock(&data->update_lock);
1233 f71882fg_write8(data, F71882FG_REG_IN1_HIGH, val);
1234 data->in1_max = val;
1235 mutex_unlock(&data->update_lock);
1237 return count;
1240 static ssize_t show_in_beep(struct device *dev, struct device_attribute
1241 *devattr, char *buf)
1243 struct f71882fg_data *data = f71882fg_update_device(dev);
1244 int nr = to_sensor_dev_attr_2(devattr)->index;
1246 if (data->in_beep & (1 << nr))
1247 return sprintf(buf, "1\n");
1248 else
1249 return sprintf(buf, "0\n");
1252 static ssize_t store_in_beep(struct device *dev, struct device_attribute
1253 *devattr, const char *buf, size_t count)
1255 struct f71882fg_data *data = dev_get_drvdata(dev);
1256 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1257 unsigned long val;
1259 err = strict_strtoul(buf, 10, &val);
1260 if (err)
1261 return err;
1263 mutex_lock(&data->update_lock);
1264 data->in_beep = f71882fg_read8(data, F71882FG_REG_IN_BEEP);
1265 if (val)
1266 data->in_beep |= 1 << nr;
1267 else
1268 data->in_beep &= ~(1 << nr);
1270 f71882fg_write8(data, F71882FG_REG_IN_BEEP, data->in_beep);
1271 mutex_unlock(&data->update_lock);
1273 return count;
1276 static ssize_t show_in_alarm(struct device *dev, struct device_attribute
1277 *devattr, char *buf)
1279 struct f71882fg_data *data = f71882fg_update_device(dev);
1280 int nr = to_sensor_dev_attr_2(devattr)->index;
1282 if (data->in_status & (1 << nr))
1283 return sprintf(buf, "1\n");
1284 else
1285 return sprintf(buf, "0\n");
1288 static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
1289 char *buf)
1291 struct f71882fg_data *data = f71882fg_update_device(dev);
1292 int nr = to_sensor_dev_attr_2(devattr)->index;
1293 int sign, temp;
1295 if (data->type == f71858fg) {
1296 /* TEMP_TABLE_SEL 1 or 3 ? */
1297 if (data->temp_config & 1) {
1298 sign = data->temp[nr] & 0x0001;
1299 temp = (data->temp[nr] >> 5) & 0x7ff;
1300 } else {
1301 sign = data->temp[nr] & 0x8000;
1302 temp = (data->temp[nr] >> 5) & 0x3ff;
1304 temp *= 125;
1305 if (sign)
1306 temp -= 128000;
1307 } else
1308 temp = data->temp[nr] * 1000;
1310 return sprintf(buf, "%d\n", temp);
1313 static ssize_t show_temp_max(struct device *dev, struct device_attribute
1314 *devattr, char *buf)
1316 struct f71882fg_data *data = f71882fg_update_device(dev);
1317 int nr = to_sensor_dev_attr_2(devattr)->index;
1319 return sprintf(buf, "%d\n", data->temp_high[nr] * 1000);
1322 static ssize_t store_temp_max(struct device *dev, struct device_attribute
1323 *devattr, const char *buf, size_t count)
1325 struct f71882fg_data *data = dev_get_drvdata(dev);
1326 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1327 long val;
1329 err = strict_strtol(buf, 10, &val);
1330 if (err)
1331 return err;
1333 val /= 1000;
1334 val = SENSORS_LIMIT(val, 0, 255);
1336 mutex_lock(&data->update_lock);
1337 f71882fg_write8(data, F71882FG_REG_TEMP_HIGH(nr), val);
1338 data->temp_high[nr] = val;
1339 mutex_unlock(&data->update_lock);
1341 return count;
1344 static ssize_t show_temp_max_hyst(struct device *dev, struct device_attribute
1345 *devattr, char *buf)
1347 struct f71882fg_data *data = f71882fg_update_device(dev);
1348 int nr = to_sensor_dev_attr_2(devattr)->index;
1349 int temp_max_hyst;
1351 mutex_lock(&data->update_lock);
1352 if (nr & 1)
1353 temp_max_hyst = data->temp_hyst[nr / 2] >> 4;
1354 else
1355 temp_max_hyst = data->temp_hyst[nr / 2] & 0x0f;
1356 temp_max_hyst = (data->temp_high[nr] - temp_max_hyst) * 1000;
1357 mutex_unlock(&data->update_lock);
1359 return sprintf(buf, "%d\n", temp_max_hyst);
1362 static ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute
1363 *devattr, const char *buf, size_t count)
1365 struct f71882fg_data *data = dev_get_drvdata(dev);
1366 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1367 ssize_t ret = count;
1368 u8 reg;
1369 long val;
1371 err = strict_strtol(buf, 10, &val);
1372 if (err)
1373 return err;
1375 val /= 1000;
1377 mutex_lock(&data->update_lock);
1379 /* convert abs to relative and check */
1380 data->temp_high[nr] = f71882fg_read8(data, F71882FG_REG_TEMP_HIGH(nr));
1381 val = SENSORS_LIMIT(val, data->temp_high[nr] - 15,
1382 data->temp_high[nr]);
1383 val = data->temp_high[nr] - val;
1385 /* convert value to register contents */
1386 reg = f71882fg_read8(data, F71882FG_REG_TEMP_HYST(nr / 2));
1387 if (nr & 1)
1388 reg = (reg & 0x0f) | (val << 4);
1389 else
1390 reg = (reg & 0xf0) | val;
1391 f71882fg_write8(data, F71882FG_REG_TEMP_HYST(nr / 2), reg);
1392 data->temp_hyst[nr / 2] = reg;
1394 mutex_unlock(&data->update_lock);
1395 return ret;
1398 static ssize_t show_temp_crit(struct device *dev, struct device_attribute
1399 *devattr, char *buf)
1401 struct f71882fg_data *data = f71882fg_update_device(dev);
1402 int nr = to_sensor_dev_attr_2(devattr)->index;
1404 return sprintf(buf, "%d\n", data->temp_ovt[nr] * 1000);
1407 static ssize_t store_temp_crit(struct device *dev, struct device_attribute
1408 *devattr, const char *buf, size_t count)
1410 struct f71882fg_data *data = dev_get_drvdata(dev);
1411 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1412 long val;
1414 err = strict_strtol(buf, 10, &val);
1415 if (err)
1416 return err;
1418 val /= 1000;
1419 val = SENSORS_LIMIT(val, 0, 255);
1421 mutex_lock(&data->update_lock);
1422 f71882fg_write8(data, F71882FG_REG_TEMP_OVT(nr), val);
1423 data->temp_ovt[nr] = val;
1424 mutex_unlock(&data->update_lock);
1426 return count;
1429 static ssize_t show_temp_crit_hyst(struct device *dev, struct device_attribute
1430 *devattr, char *buf)
1432 struct f71882fg_data *data = f71882fg_update_device(dev);
1433 int nr = to_sensor_dev_attr_2(devattr)->index;
1434 int temp_crit_hyst;
1436 mutex_lock(&data->update_lock);
1437 if (nr & 1)
1438 temp_crit_hyst = data->temp_hyst[nr / 2] >> 4;
1439 else
1440 temp_crit_hyst = data->temp_hyst[nr / 2] & 0x0f;
1441 temp_crit_hyst = (data->temp_ovt[nr] - temp_crit_hyst) * 1000;
1442 mutex_unlock(&data->update_lock);
1444 return sprintf(buf, "%d\n", temp_crit_hyst);
1447 static ssize_t show_temp_type(struct device *dev, struct device_attribute
1448 *devattr, char *buf)
1450 struct f71882fg_data *data = f71882fg_update_device(dev);
1451 int nr = to_sensor_dev_attr_2(devattr)->index;
1453 return sprintf(buf, "%d\n", data->temp_type[nr]);
1456 static ssize_t show_temp_beep(struct device *dev, struct device_attribute
1457 *devattr, char *buf)
1459 struct f71882fg_data *data = f71882fg_update_device(dev);
1460 int nr = to_sensor_dev_attr_2(devattr)->index;
1462 if (data->temp_beep & (1 << nr))
1463 return sprintf(buf, "1\n");
1464 else
1465 return sprintf(buf, "0\n");
1468 static ssize_t store_temp_beep(struct device *dev, struct device_attribute
1469 *devattr, const char *buf, size_t count)
1471 struct f71882fg_data *data = dev_get_drvdata(dev);
1472 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1473 unsigned long val;
1475 err = strict_strtoul(buf, 10, &val);
1476 if (err)
1477 return err;
1479 mutex_lock(&data->update_lock);
1480 data->temp_beep = f71882fg_read8(data, F71882FG_REG_TEMP_BEEP);
1481 if (val)
1482 data->temp_beep |= 1 << nr;
1483 else
1484 data->temp_beep &= ~(1 << nr);
1486 f71882fg_write8(data, F71882FG_REG_TEMP_BEEP, data->temp_beep);
1487 mutex_unlock(&data->update_lock);
1489 return count;
1492 static ssize_t show_temp_alarm(struct device *dev, struct device_attribute
1493 *devattr, char *buf)
1495 struct f71882fg_data *data = f71882fg_update_device(dev);
1496 int nr = to_sensor_dev_attr_2(devattr)->index;
1498 if (data->temp_status & (1 << nr))
1499 return sprintf(buf, "1\n");
1500 else
1501 return sprintf(buf, "0\n");
1504 static ssize_t show_temp_fault(struct device *dev, struct device_attribute
1505 *devattr, char *buf)
1507 struct f71882fg_data *data = f71882fg_update_device(dev);
1508 int nr = to_sensor_dev_attr_2(devattr)->index;
1510 if (data->temp_diode_open & (1 << nr))
1511 return sprintf(buf, "1\n");
1512 else
1513 return sprintf(buf, "0\n");
1516 static ssize_t show_pwm(struct device *dev,
1517 struct device_attribute *devattr, char *buf)
1519 struct f71882fg_data *data = f71882fg_update_device(dev);
1520 int val, nr = to_sensor_dev_attr_2(devattr)->index;
1521 mutex_lock(&data->update_lock);
1522 if (data->pwm_enable & (1 << (2 * nr)))
1523 /* PWM mode */
1524 val = data->pwm[nr];
1525 else {
1526 /* RPM mode */
1527 val = 255 * fan_from_reg(data->fan_target[nr])
1528 / fan_from_reg(data->fan_full_speed[nr]);
1530 mutex_unlock(&data->update_lock);
1531 return sprintf(buf, "%d\n", val);
1534 static ssize_t store_pwm(struct device *dev,
1535 struct device_attribute *devattr, const char *buf,
1536 size_t count)
1538 struct f71882fg_data *data = dev_get_drvdata(dev);
1539 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1540 long val;
1542 err = strict_strtol(buf, 10, &val);
1543 if (err)
1544 return err;
1546 val = SENSORS_LIMIT(val, 0, 255);
1548 mutex_lock(&data->update_lock);
1549 data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
1550 if ((data->type == f8000 && ((data->pwm_enable >> 2 * nr) & 3) != 2) ||
1551 (data->type != f8000 && !((data->pwm_enable >> 2 * nr) & 2))) {
1552 count = -EROFS;
1553 goto leave;
1555 if (data->pwm_enable & (1 << (2 * nr))) {
1556 /* PWM mode */
1557 f71882fg_write8(data, F71882FG_REG_PWM(nr), val);
1558 data->pwm[nr] = val;
1559 } else {
1560 /* RPM mode */
1561 int target, full_speed;
1562 full_speed = f71882fg_read16(data,
1563 F71882FG_REG_FAN_FULL_SPEED(nr));
1564 target = fan_to_reg(val * fan_from_reg(full_speed) / 255);
1565 f71882fg_write16(data, F71882FG_REG_FAN_TARGET(nr), target);
1566 data->fan_target[nr] = target;
1567 data->fan_full_speed[nr] = full_speed;
1569 leave:
1570 mutex_unlock(&data->update_lock);
1572 return count;
1575 static ssize_t show_pwm_enable(struct device *dev,
1576 struct device_attribute *devattr, char *buf)
1578 int result = 0;
1579 struct f71882fg_data *data = f71882fg_update_device(dev);
1580 int nr = to_sensor_dev_attr_2(devattr)->index;
1582 switch ((data->pwm_enable >> 2 * nr) & 3) {
1583 case 0:
1584 case 1:
1585 result = 2; /* Normal auto mode */
1586 break;
1587 case 2:
1588 result = 1; /* Manual mode */
1589 break;
1590 case 3:
1591 if (data->type == f8000)
1592 result = 3; /* Thermostat mode */
1593 else
1594 result = 1; /* Manual mode */
1595 break;
1598 return sprintf(buf, "%d\n", result);
1601 static ssize_t store_pwm_enable(struct device *dev, struct device_attribute
1602 *devattr, const char *buf, size_t count)
1604 struct f71882fg_data *data = dev_get_drvdata(dev);
1605 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1606 long val;
1608 err = strict_strtol(buf, 10, &val);
1609 if (err)
1610 return err;
1612 /* Special case for F8000 pwm channel 3 which only does auto mode */
1613 if (data->type == f8000 && nr == 2 && val != 2)
1614 return -EINVAL;
1616 mutex_lock(&data->update_lock);
1617 data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
1618 /* Special case for F8000 auto PWM mode / Thermostat mode */
1619 if (data->type == f8000 && ((data->pwm_enable >> 2 * nr) & 1)) {
1620 switch (val) {
1621 case 2:
1622 data->pwm_enable &= ~(2 << (2 * nr));
1623 break; /* Normal auto mode */
1624 case 3:
1625 data->pwm_enable |= 2 << (2 * nr);
1626 break; /* Thermostat mode */
1627 default:
1628 count = -EINVAL;
1629 goto leave;
1631 } else {
1632 switch (val) {
1633 case 1:
1634 /* The f71858fg does not support manual RPM mode */
1635 if (data->type == f71858fg &&
1636 ((data->pwm_enable >> (2 * nr)) & 1)) {
1637 count = -EINVAL;
1638 goto leave;
1640 data->pwm_enable |= 2 << (2 * nr);
1641 break; /* Manual */
1642 case 2:
1643 data->pwm_enable &= ~(2 << (2 * nr));
1644 break; /* Normal auto mode */
1645 default:
1646 count = -EINVAL;
1647 goto leave;
1650 f71882fg_write8(data, F71882FG_REG_PWM_ENABLE, data->pwm_enable);
1651 leave:
1652 mutex_unlock(&data->update_lock);
1654 return count;
1657 static ssize_t show_pwm_auto_point_pwm(struct device *dev,
1658 struct device_attribute *devattr,
1659 char *buf)
1661 int result;
1662 struct f71882fg_data *data = f71882fg_update_device(dev);
1663 int pwm = to_sensor_dev_attr_2(devattr)->index;
1664 int point = to_sensor_dev_attr_2(devattr)->nr;
1666 mutex_lock(&data->update_lock);
1667 if (data->pwm_enable & (1 << (2 * pwm))) {
1668 /* PWM mode */
1669 result = data->pwm_auto_point_pwm[pwm][point];
1670 } else {
1671 /* RPM mode */
1672 result = 32 * 255 / (32 + data->pwm_auto_point_pwm[pwm][point]);
1674 mutex_unlock(&data->update_lock);
1676 return sprintf(buf, "%d\n", result);
1679 static ssize_t store_pwm_auto_point_pwm(struct device *dev,
1680 struct device_attribute *devattr,
1681 const char *buf, size_t count)
1683 struct f71882fg_data *data = dev_get_drvdata(dev);
1684 int err, pwm = to_sensor_dev_attr_2(devattr)->index;
1685 int point = to_sensor_dev_attr_2(devattr)->nr;
1686 long val;
1688 err = strict_strtol(buf, 10, &val);
1689 if (err)
1690 return err;
1692 val = SENSORS_LIMIT(val, 0, 255);
1694 mutex_lock(&data->update_lock);
1695 data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
1696 if (data->pwm_enable & (1 << (2 * pwm))) {
1697 /* PWM mode */
1698 } else {
1699 /* RPM mode */
1700 if (val < 29) /* Prevent negative numbers */
1701 val = 255;
1702 else
1703 val = (255 - val) * 32 / val;
1705 f71882fg_write8(data, F71882FG_REG_POINT_PWM(pwm, point), val);
1706 data->pwm_auto_point_pwm[pwm][point] = val;
1707 mutex_unlock(&data->update_lock);
1709 return count;
1712 static ssize_t show_pwm_auto_point_temp_hyst(struct device *dev,
1713 struct device_attribute *devattr,
1714 char *buf)
1716 int result = 0;
1717 struct f71882fg_data *data = f71882fg_update_device(dev);
1718 int nr = to_sensor_dev_attr_2(devattr)->index;
1719 int point = to_sensor_dev_attr_2(devattr)->nr;
1721 mutex_lock(&data->update_lock);
1722 if (nr & 1)
1723 result = data->pwm_auto_point_hyst[nr / 2] >> 4;
1724 else
1725 result = data->pwm_auto_point_hyst[nr / 2] & 0x0f;
1726 result = 1000 * (data->pwm_auto_point_temp[nr][point] - result);
1727 mutex_unlock(&data->update_lock);
1729 return sprintf(buf, "%d\n", result);
1732 static ssize_t store_pwm_auto_point_temp_hyst(struct device *dev,
1733 struct device_attribute *devattr,
1734 const char *buf, size_t count)
1736 struct f71882fg_data *data = dev_get_drvdata(dev);
1737 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1738 int point = to_sensor_dev_attr_2(devattr)->nr;
1739 u8 reg;
1740 long val;
1742 err = strict_strtol(buf, 10, &val);
1743 if (err)
1744 return err;
1746 val /= 1000;
1748 mutex_lock(&data->update_lock);
1749 data->pwm_auto_point_temp[nr][point] =
1750 f71882fg_read8(data, F71882FG_REG_POINT_TEMP(nr, point));
1751 val = SENSORS_LIMIT(val, data->pwm_auto_point_temp[nr][point] - 15,
1752 data->pwm_auto_point_temp[nr][point]);
1753 val = data->pwm_auto_point_temp[nr][point] - val;
1755 reg = f71882fg_read8(data, F71882FG_REG_FAN_HYST(nr / 2));
1756 if (nr & 1)
1757 reg = (reg & 0x0f) | (val << 4);
1758 else
1759 reg = (reg & 0xf0) | val;
1761 f71882fg_write8(data, F71882FG_REG_FAN_HYST(nr / 2), reg);
1762 data->pwm_auto_point_hyst[nr / 2] = reg;
1763 mutex_unlock(&data->update_lock);
1765 return count;
1768 static ssize_t show_pwm_interpolate(struct device *dev,
1769 struct device_attribute *devattr, char *buf)
1771 int result;
1772 struct f71882fg_data *data = f71882fg_update_device(dev);
1773 int nr = to_sensor_dev_attr_2(devattr)->index;
1775 result = (data->pwm_auto_point_mapping[nr] >> 4) & 1;
1777 return sprintf(buf, "%d\n", result);
1780 static ssize_t store_pwm_interpolate(struct device *dev,
1781 struct device_attribute *devattr,
1782 const char *buf, size_t count)
1784 struct f71882fg_data *data = dev_get_drvdata(dev);
1785 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1786 unsigned long val;
1788 err = strict_strtoul(buf, 10, &val);
1789 if (err)
1790 return err;
1792 mutex_lock(&data->update_lock);
1793 data->pwm_auto_point_mapping[nr] =
1794 f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(nr));
1795 if (val)
1796 val = data->pwm_auto_point_mapping[nr] | (1 << 4);
1797 else
1798 val = data->pwm_auto_point_mapping[nr] & (~(1 << 4));
1799 f71882fg_write8(data, F71882FG_REG_POINT_MAPPING(nr), val);
1800 data->pwm_auto_point_mapping[nr] = val;
1801 mutex_unlock(&data->update_lock);
1803 return count;
1806 static ssize_t show_pwm_auto_point_channel(struct device *dev,
1807 struct device_attribute *devattr,
1808 char *buf)
1810 int result;
1811 struct f71882fg_data *data = f71882fg_update_device(dev);
1812 int nr = to_sensor_dev_attr_2(devattr)->index;
1814 result = 1 << ((data->pwm_auto_point_mapping[nr] & 3) -
1815 data->temp_start);
1817 return sprintf(buf, "%d\n", result);
1820 static ssize_t store_pwm_auto_point_channel(struct device *dev,
1821 struct device_attribute *devattr,
1822 const char *buf, size_t count)
1824 struct f71882fg_data *data = dev_get_drvdata(dev);
1825 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1826 long val;
1828 err = strict_strtol(buf, 10, &val);
1829 if (err)
1830 return err;
1832 switch (val) {
1833 case 1:
1834 val = 0;
1835 break;
1836 case 2:
1837 val = 1;
1838 break;
1839 case 4:
1840 val = 2;
1841 break;
1842 default:
1843 return -EINVAL;
1845 val += data->temp_start;
1846 mutex_lock(&data->update_lock);
1847 data->pwm_auto_point_mapping[nr] =
1848 f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(nr));
1849 val = (data->pwm_auto_point_mapping[nr] & 0xfc) | val;
1850 f71882fg_write8(data, F71882FG_REG_POINT_MAPPING(nr), val);
1851 data->pwm_auto_point_mapping[nr] = val;
1852 mutex_unlock(&data->update_lock);
1854 return count;
1857 static ssize_t show_pwm_auto_point_temp(struct device *dev,
1858 struct device_attribute *devattr,
1859 char *buf)
1861 int result;
1862 struct f71882fg_data *data = f71882fg_update_device(dev);
1863 int pwm = to_sensor_dev_attr_2(devattr)->index;
1864 int point = to_sensor_dev_attr_2(devattr)->nr;
1866 result = data->pwm_auto_point_temp[pwm][point];
1867 return sprintf(buf, "%d\n", 1000 * result);
1870 static ssize_t store_pwm_auto_point_temp(struct device *dev,
1871 struct device_attribute *devattr,
1872 const char *buf, size_t count)
1874 struct f71882fg_data *data = dev_get_drvdata(dev);
1875 int err, pwm = to_sensor_dev_attr_2(devattr)->index;
1876 int point = to_sensor_dev_attr_2(devattr)->nr;
1877 long val;
1879 err = strict_strtol(buf, 10, &val);
1880 if (err)
1881 return err;
1883 val /= 1000;
1885 if (data->type == f71889fg)
1886 val = SENSORS_LIMIT(val, -128, 127);
1887 else
1888 val = SENSORS_LIMIT(val, 0, 127);
1890 mutex_lock(&data->update_lock);
1891 f71882fg_write8(data, F71882FG_REG_POINT_TEMP(pwm, point), val);
1892 data->pwm_auto_point_temp[pwm][point] = val;
1893 mutex_unlock(&data->update_lock);
1895 return count;
1898 static ssize_t show_name(struct device *dev, struct device_attribute *devattr,
1899 char *buf)
1901 struct f71882fg_data *data = dev_get_drvdata(dev);
1902 return sprintf(buf, "%s\n", f71882fg_names[data->type]);
1905 static int __devinit f71882fg_create_sysfs_files(struct platform_device *pdev,
1906 struct sensor_device_attribute_2 *attr, int count)
1908 int err, i;
1910 for (i = 0; i < count; i++) {
1911 err = device_create_file(&pdev->dev, &attr[i].dev_attr);
1912 if (err)
1913 return err;
1915 return 0;
1918 static void f71882fg_remove_sysfs_files(struct platform_device *pdev,
1919 struct sensor_device_attribute_2 *attr, int count)
1921 int i;
1923 for (i = 0; i < count; i++)
1924 device_remove_file(&pdev->dev, &attr[i].dev_attr);
1927 static int __devinit f71882fg_probe(struct platform_device *pdev)
1929 struct f71882fg_data *data;
1930 struct f71882fg_sio_data *sio_data = pdev->dev.platform_data;
1931 int err, i, nr_fans = (sio_data->type == f71882fg) ? 4 : 3;
1932 u8 start_reg;
1934 data = kzalloc(sizeof(struct f71882fg_data), GFP_KERNEL);
1935 if (!data)
1936 return -ENOMEM;
1938 data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start;
1939 data->type = sio_data->type;
1940 data->temp_start =
1941 (data->type == f71858fg || data->type == f8000) ? 0 : 1;
1942 mutex_init(&data->update_lock);
1943 platform_set_drvdata(pdev, data);
1945 start_reg = f71882fg_read8(data, F71882FG_REG_START);
1946 if (start_reg & 0x04) {
1947 dev_warn(&pdev->dev, "Hardware monitor is powered down\n");
1948 err = -ENODEV;
1949 goto exit_free;
1951 if (!(start_reg & 0x03)) {
1952 dev_warn(&pdev->dev, "Hardware monitoring not activated\n");
1953 err = -ENODEV;
1954 goto exit_free;
1957 /* Register sysfs interface files */
1958 err = device_create_file(&pdev->dev, &dev_attr_name);
1959 if (err)
1960 goto exit_unregister_sysfs;
1962 if (start_reg & 0x01) {
1963 switch (data->type) {
1964 case f71858fg:
1965 data->temp_config =
1966 f71882fg_read8(data, F71882FG_REG_TEMP_CONFIG);
1967 if (data->temp_config & 0x10)
1968 /* The f71858fg temperature alarms behave as
1969 the f8000 alarms in this mode */
1970 err = f71882fg_create_sysfs_files(pdev,
1971 f8000_in_temp_attr,
1972 ARRAY_SIZE(f8000_in_temp_attr));
1973 else
1974 err = f71882fg_create_sysfs_files(pdev,
1975 f71858fg_in_temp_attr,
1976 ARRAY_SIZE(f71858fg_in_temp_attr));
1977 break;
1978 case f71882fg:
1979 case f71889fg:
1980 err = f71882fg_create_sysfs_files(pdev,
1981 fxxxx_in1_alarm_attr,
1982 ARRAY_SIZE(fxxxx_in1_alarm_attr));
1983 if (err)
1984 goto exit_unregister_sysfs;
1985 /* fall through! */
1986 case f71862fg:
1987 err = f71882fg_create_sysfs_files(pdev,
1988 fxxxx_in_temp_attr,
1989 ARRAY_SIZE(fxxxx_in_temp_attr));
1990 break;
1991 case f8000:
1992 err = f71882fg_create_sysfs_files(pdev,
1993 f8000_in_temp_attr,
1994 ARRAY_SIZE(f8000_in_temp_attr));
1995 break;
1997 if (err)
1998 goto exit_unregister_sysfs;
2001 if (start_reg & 0x02) {
2002 data->pwm_enable =
2003 f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
2005 /* Sanity check the pwm settings */
2006 switch (data->type) {
2007 case f71858fg:
2008 err = 0;
2009 for (i = 0; i < nr_fans; i++)
2010 if (((data->pwm_enable >> (i * 2)) & 3) == 3)
2011 err = 1;
2012 break;
2013 case f71862fg:
2014 err = (data->pwm_enable & 0x15) != 0x15;
2015 break;
2016 case f71882fg:
2017 case f71889fg:
2018 err = 0;
2019 break;
2020 case f8000:
2021 err = data->pwm_enable & 0x20;
2022 break;
2024 if (err) {
2025 dev_err(&pdev->dev,
2026 "Invalid (reserved) pwm settings: 0x%02x\n",
2027 (unsigned int)data->pwm_enable);
2028 err = -ENODEV;
2029 goto exit_unregister_sysfs;
2032 err = f71882fg_create_sysfs_files(pdev, &fxxxx_fan_attr[0][0],
2033 ARRAY_SIZE(fxxxx_fan_attr[0]) * nr_fans);
2034 if (err)
2035 goto exit_unregister_sysfs;
2037 if (data->type == f71862fg || data->type == f71882fg ||
2038 data->type == f71889fg) {
2039 err = f71882fg_create_sysfs_files(pdev,
2040 fxxxx_fan_beep_attr, nr_fans);
2041 if (err)
2042 goto exit_unregister_sysfs;
2045 switch (data->type) {
2046 case f71862fg:
2047 err = f71882fg_create_sysfs_files(pdev,
2048 f71862fg_auto_pwm_attr,
2049 ARRAY_SIZE(f71862fg_auto_pwm_attr));
2050 break;
2051 case f8000:
2052 err = f71882fg_create_sysfs_files(pdev,
2053 f8000_fan_attr,
2054 ARRAY_SIZE(f8000_fan_attr));
2055 if (err)
2056 goto exit_unregister_sysfs;
2057 err = f71882fg_create_sysfs_files(pdev,
2058 f8000_auto_pwm_attr,
2059 ARRAY_SIZE(f8000_auto_pwm_attr));
2060 break;
2061 case f71889fg:
2062 for (i = 0; i < nr_fans; i++) {
2063 data->pwm_auto_point_mapping[i] =
2064 f71882fg_read8(data,
2065 F71882FG_REG_POINT_MAPPING(i));
2066 if (data->pwm_auto_point_mapping[i] & 0x80)
2067 break;
2069 if (i != nr_fans) {
2070 dev_warn(&pdev->dev,
2071 "Auto pwm controlled by raw digital "
2072 "data, disabling pwm auto_point "
2073 "sysfs attributes\n");
2074 break;
2076 /* fall through */
2077 default: /* f71858fg / f71882fg */
2078 err = f71882fg_create_sysfs_files(pdev,
2079 &fxxxx_auto_pwm_attr[0][0],
2080 ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans);
2082 if (err)
2083 goto exit_unregister_sysfs;
2085 for (i = 0; i < nr_fans; i++)
2086 dev_info(&pdev->dev, "Fan: %d is in %s mode\n", i + 1,
2087 (data->pwm_enable & (1 << 2 * i)) ?
2088 "duty-cycle" : "RPM");
2091 data->hwmon_dev = hwmon_device_register(&pdev->dev);
2092 if (IS_ERR(data->hwmon_dev)) {
2093 err = PTR_ERR(data->hwmon_dev);
2094 data->hwmon_dev = NULL;
2095 goto exit_unregister_sysfs;
2098 return 0;
2100 exit_unregister_sysfs:
2101 f71882fg_remove(pdev); /* Will unregister the sysfs files for us */
2102 return err; /* f71882fg_remove() also frees our data */
2103 exit_free:
2104 kfree(data);
2105 return err;
2108 static int f71882fg_remove(struct platform_device *pdev)
2110 struct f71882fg_data *data = platform_get_drvdata(pdev);
2111 int nr_fans = (data->type == f71882fg) ? 4 : 3;
2112 u8 start_reg = f71882fg_read8(data, F71882FG_REG_START);
2114 platform_set_drvdata(pdev, NULL);
2115 if (data->hwmon_dev)
2116 hwmon_device_unregister(data->hwmon_dev);
2118 device_remove_file(&pdev->dev, &dev_attr_name);
2120 if (start_reg & 0x01) {
2121 switch (data->type) {
2122 case f71858fg:
2123 if (data->temp_config & 0x10)
2124 f71882fg_remove_sysfs_files(pdev,
2125 f8000_in_temp_attr,
2126 ARRAY_SIZE(f8000_in_temp_attr));
2127 else
2128 f71882fg_remove_sysfs_files(pdev,
2129 f71858fg_in_temp_attr,
2130 ARRAY_SIZE(f71858fg_in_temp_attr));
2131 break;
2132 case f71882fg:
2133 case f71889fg:
2134 f71882fg_remove_sysfs_files(pdev,
2135 fxxxx_in1_alarm_attr,
2136 ARRAY_SIZE(fxxxx_in1_alarm_attr));
2137 /* fall through! */
2138 case f71862fg:
2139 f71882fg_remove_sysfs_files(pdev,
2140 fxxxx_in_temp_attr,
2141 ARRAY_SIZE(fxxxx_in_temp_attr));
2142 break;
2143 case f8000:
2144 f71882fg_remove_sysfs_files(pdev,
2145 f8000_in_temp_attr,
2146 ARRAY_SIZE(f8000_in_temp_attr));
2147 break;
2151 if (start_reg & 0x02) {
2152 f71882fg_remove_sysfs_files(pdev, &fxxxx_fan_attr[0][0],
2153 ARRAY_SIZE(fxxxx_fan_attr[0]) * nr_fans);
2155 if (data->type == f71862fg || data->type == f71882fg ||
2156 data->type == f71889fg)
2157 f71882fg_remove_sysfs_files(pdev,
2158 fxxxx_fan_beep_attr, nr_fans);
2160 switch (data->type) {
2161 case f71862fg:
2162 f71882fg_remove_sysfs_files(pdev,
2163 f71862fg_auto_pwm_attr,
2164 ARRAY_SIZE(f71862fg_auto_pwm_attr));
2165 break;
2166 case f8000:
2167 f71882fg_remove_sysfs_files(pdev,
2168 f8000_fan_attr,
2169 ARRAY_SIZE(f8000_fan_attr));
2170 f71882fg_remove_sysfs_files(pdev,
2171 f8000_auto_pwm_attr,
2172 ARRAY_SIZE(f8000_auto_pwm_attr));
2173 break;
2174 default: /* f71858fg / f71882fg / f71889fg */
2175 f71882fg_remove_sysfs_files(pdev,
2176 &fxxxx_auto_pwm_attr[0][0],
2177 ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans);
2181 kfree(data);
2183 return 0;
2186 static int __init f71882fg_find(int sioaddr, unsigned short *address,
2187 struct f71882fg_sio_data *sio_data)
2189 u16 devid;
2190 int err = superio_enter(sioaddr);
2191 if (err)
2192 return err;
2194 devid = superio_inw(sioaddr, SIO_REG_MANID);
2195 if (devid != SIO_FINTEK_ID) {
2196 pr_debug("Not a Fintek device\n");
2197 err = -ENODEV;
2198 goto exit;
2201 devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID);
2202 switch (devid) {
2203 case SIO_F71858_ID:
2204 sio_data->type = f71858fg;
2205 break;
2206 case SIO_F71862_ID:
2207 sio_data->type = f71862fg;
2208 break;
2209 case SIO_F71882_ID:
2210 sio_data->type = f71882fg;
2211 break;
2212 case SIO_F71889_ID:
2213 sio_data->type = f71889fg;
2214 break;
2215 case SIO_F8000_ID:
2216 sio_data->type = f8000;
2217 break;
2218 default:
2219 pr_info("Unsupported Fintek device: %04x\n",
2220 (unsigned int)devid);
2221 err = -ENODEV;
2222 goto exit;
2225 if (sio_data->type == f71858fg)
2226 superio_select(sioaddr, SIO_F71858FG_LD_HWM);
2227 else
2228 superio_select(sioaddr, SIO_F71882FG_LD_HWM);
2230 if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) {
2231 pr_warn("Device not activated\n");
2232 err = -ENODEV;
2233 goto exit;
2236 *address = superio_inw(sioaddr, SIO_REG_ADDR);
2237 if (*address == 0) {
2238 pr_warn("Base address not set\n");
2239 err = -ENODEV;
2240 goto exit;
2242 *address &= ~(REGION_LENGTH - 1); /* Ignore 3 LSB */
2244 err = 0;
2245 pr_info("Found %s chip at %#x, revision %d\n",
2246 f71882fg_names[sio_data->type], (unsigned int)*address,
2247 (int)superio_inb(sioaddr, SIO_REG_DEVREV));
2248 exit:
2249 superio_exit(sioaddr);
2250 return err;
2253 static int __init f71882fg_device_add(unsigned short address,
2254 const struct f71882fg_sio_data *sio_data)
2256 struct resource res = {
2257 .start = address,
2258 .end = address + REGION_LENGTH - 1,
2259 .flags = IORESOURCE_IO,
2261 int err;
2263 f71882fg_pdev = platform_device_alloc(DRVNAME, address);
2264 if (!f71882fg_pdev)
2265 return -ENOMEM;
2267 res.name = f71882fg_pdev->name;
2268 err = acpi_check_resource_conflict(&res);
2269 if (err)
2270 goto exit_device_put;
2272 err = platform_device_add_resources(f71882fg_pdev, &res, 1);
2273 if (err) {
2274 pr_err("Device resource addition failed\n");
2275 goto exit_device_put;
2278 err = platform_device_add_data(f71882fg_pdev, sio_data,
2279 sizeof(struct f71882fg_sio_data));
2280 if (err) {
2281 pr_err("Platform data allocation failed\n");
2282 goto exit_device_put;
2285 err = platform_device_add(f71882fg_pdev);
2286 if (err) {
2287 pr_err("Device addition failed\n");
2288 goto exit_device_put;
2291 return 0;
2293 exit_device_put:
2294 platform_device_put(f71882fg_pdev);
2296 return err;
2299 static int __init f71882fg_init(void)
2301 int err = -ENODEV;
2302 unsigned short address;
2303 struct f71882fg_sio_data sio_data;
2305 memset(&sio_data, 0, sizeof(sio_data));
2307 if (f71882fg_find(0x2e, &address, &sio_data) &&
2308 f71882fg_find(0x4e, &address, &sio_data))
2309 goto exit;
2311 err = platform_driver_register(&f71882fg_driver);
2312 if (err)
2313 goto exit;
2315 err = f71882fg_device_add(address, &sio_data);
2316 if (err)
2317 goto exit_driver;
2319 return 0;
2321 exit_driver:
2322 platform_driver_unregister(&f71882fg_driver);
2323 exit:
2324 return err;
2327 static void __exit f71882fg_exit(void)
2329 platform_device_unregister(f71882fg_pdev);
2330 platform_driver_unregister(&f71882fg_driver);
2333 MODULE_DESCRIPTION("F71882FG Hardware Monitoring Driver");
2334 MODULE_AUTHOR("Hans Edgington, Hans de Goede (hdegoede@redhat.com)");
2335 MODULE_LICENSE("GPL");
2337 module_init(f71882fg_init);
2338 module_exit(f71882fg_exit);