1 /***************************************************************************
2 * Copyright (C) 2006 by Hans Edgington <hans@edgington.nl> *
3 * Copyright (C) 2007,2008 by Hans de Goede <hdegoede@redhat.com> *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
21 #include <linux/module.h>
22 #include <linux/init.h>
23 #include <linux/slab.h>
24 #include <linux/jiffies.h>
25 #include <linux/platform_device.h>
26 #include <linux/hwmon.h>
27 #include <linux/hwmon-sysfs.h>
28 #include <linux/err.h>
29 #include <linux/mutex.h>
32 #define DRVNAME "f71882fg"
34 #define SIO_F71882FG_LD_HWM 0x04 /* Hardware monitor logical device */
35 #define SIO_UNLOCK_KEY 0x87 /* Key to enable Super-I/O */
36 #define SIO_LOCK_KEY 0xAA /* Key to diasble Super-I/O */
38 #define SIO_REG_LDSEL 0x07 /* Logical device select */
39 #define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */
40 #define SIO_REG_DEVREV 0x22 /* Device revision */
41 #define SIO_REG_MANID 0x23 /* Fintek ID (2 bytes) */
42 #define SIO_REG_ENABLE 0x30 /* Logical device enable */
43 #define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */
45 #define SIO_FINTEK_ID 0x1934 /* Manufacturers ID */
46 #define SIO_F71862_ID 0x0601 /* Chipset ID */
47 #define SIO_F71882_ID 0x0541 /* Chipset ID */
49 #define REGION_LENGTH 8
50 #define ADDR_REG_OFFSET 5
51 #define DATA_REG_OFFSET 6
53 #define F71882FG_REG_PECI 0x0A
55 #define F71882FG_REG_IN_STATUS 0x12 /* f71882fg only */
56 #define F71882FG_REG_IN_BEEP 0x13 /* f71882fg only */
57 #define F71882FG_REG_IN(nr) (0x20 + (nr))
58 #define F71882FG_REG_IN1_HIGH 0x32 /* f71882fg only */
60 #define F71882FG_REG_FAN(nr) (0xA0 + (16 * (nr)))
61 #define F71882FG_REG_FAN_TARGET(nr) (0xA2 + (16 * (nr)))
62 #define F71882FG_REG_FAN_FULL_SPEED(nr) (0xA4 + (16 * (nr)))
63 #define F71882FG_REG_FAN_STATUS 0x92
64 #define F71882FG_REG_FAN_BEEP 0x93
66 #define F71882FG_REG_TEMP(nr) (0x70 + 2 * (nr))
67 #define F71882FG_REG_TEMP_OVT(nr) (0x80 + 2 * (nr))
68 #define F71882FG_REG_TEMP_HIGH(nr) (0x81 + 2 * (nr))
69 #define F71882FG_REG_TEMP_STATUS 0x62
70 #define F71882FG_REG_TEMP_BEEP 0x63
71 #define F71882FG_REG_TEMP_HYST(nr) (0x6C + (nr))
72 #define F71882FG_REG_TEMP_TYPE 0x6B
73 #define F71882FG_REG_TEMP_DIODE_OPEN 0x6F
75 #define F71882FG_REG_PWM(nr) (0xA3 + (16 * (nr)))
76 #define F71882FG_REG_PWM_TYPE 0x94
77 #define F71882FG_REG_PWM_ENABLE 0x96
79 #define F71882FG_REG_FAN_HYST(nr) (0x98 + (nr))
81 #define F71882FG_REG_POINT_PWM(pwm, point) (0xAA + (point) + (16 * (pwm)))
82 #define F71882FG_REG_POINT_TEMP(pwm, point) (0xA6 + (point) + (16 * (pwm)))
83 #define F71882FG_REG_POINT_MAPPING(nr) (0xAF + 16 * (nr))
85 #define F71882FG_REG_START 0x01
87 #define FAN_MIN_DETECT 366 /* Lowest detectable fanspeed */
89 static unsigned short force_id
;
90 module_param(force_id
, ushort
, 0);
91 MODULE_PARM_DESC(force_id
, "Override the detected device ID");
93 enum chips
{ f71862fg
, f71882fg
};
95 static const char *f71882fg_names
[] = {
100 static struct platform_device
*f71882fg_pdev
;
102 /* Super-I/O Function prototypes */
103 static inline int superio_inb(int base
, int reg
);
104 static inline int superio_inw(int base
, int reg
);
105 static inline void superio_enter(int base
);
106 static inline void superio_select(int base
, int ld
);
107 static inline void superio_exit(int base
);
109 struct f71882fg_sio_data
{
113 struct f71882fg_data
{
116 struct device
*hwmon_dev
;
118 struct mutex update_lock
;
119 char valid
; /* !=0 if following fields are valid */
120 unsigned long last_updated
; /* In jiffies */
121 unsigned long last_limits
; /* In jiffies */
123 /* Register Values */
130 u16 fan_full_speed
[4];
133 /* Note: all models have only 3 temperature channels, but on some
134 they are addressed as 0-2 and on others as 1-3, so for coding
135 convenience we reserve space for 4 channels */
139 u8 temp_hyst
[2]; /* 2 hysts stored per reg */
146 u8 pwm_auto_point_hyst
[2];
147 u8 pwm_auto_point_mapping
[4];
148 u8 pwm_auto_point_pwm
[4][5];
149 u8 pwm_auto_point_temp
[4][4];
153 static ssize_t
show_in(struct device
*dev
, struct device_attribute
*devattr
,
155 static ssize_t
show_in_max(struct device
*dev
, struct device_attribute
156 *devattr
, char *buf
);
157 static ssize_t
store_in_max(struct device
*dev
, struct device_attribute
158 *devattr
, const char *buf
, size_t count
);
159 static ssize_t
show_in_beep(struct device
*dev
, struct device_attribute
160 *devattr
, char *buf
);
161 static ssize_t
store_in_beep(struct device
*dev
, struct device_attribute
162 *devattr
, const char *buf
, size_t count
);
163 static ssize_t
show_in_alarm(struct device
*dev
, struct device_attribute
164 *devattr
, char *buf
);
166 static ssize_t
show_fan(struct device
*dev
, struct device_attribute
*devattr
,
168 static ssize_t
show_fan_full_speed(struct device
*dev
,
169 struct device_attribute
*devattr
, char *buf
);
170 static ssize_t
store_fan_full_speed(struct device
*dev
,
171 struct device_attribute
*devattr
, const char *buf
, size_t count
);
172 static ssize_t
show_fan_beep(struct device
*dev
, struct device_attribute
173 *devattr
, char *buf
);
174 static ssize_t
store_fan_beep(struct device
*dev
, struct device_attribute
175 *devattr
, const char *buf
, size_t count
);
176 static ssize_t
show_fan_alarm(struct device
*dev
, struct device_attribute
177 *devattr
, char *buf
);
179 static ssize_t
show_temp(struct device
*dev
, struct device_attribute
180 *devattr
, char *buf
);
181 static ssize_t
show_temp_max(struct device
*dev
, struct device_attribute
182 *devattr
, char *buf
);
183 static ssize_t
store_temp_max(struct device
*dev
, struct device_attribute
184 *devattr
, const char *buf
, size_t count
);
185 static ssize_t
show_temp_max_hyst(struct device
*dev
, struct device_attribute
186 *devattr
, char *buf
);
187 static ssize_t
store_temp_max_hyst(struct device
*dev
, struct device_attribute
188 *devattr
, const char *buf
, size_t count
);
189 static ssize_t
show_temp_crit(struct device
*dev
, struct device_attribute
190 *devattr
, char *buf
);
191 static ssize_t
store_temp_crit(struct device
*dev
, struct device_attribute
192 *devattr
, const char *buf
, size_t count
);
193 static ssize_t
show_temp_crit_hyst(struct device
*dev
, struct device_attribute
194 *devattr
, char *buf
);
195 static ssize_t
show_temp_type(struct device
*dev
, struct device_attribute
196 *devattr
, char *buf
);
197 static ssize_t
show_temp_beep(struct device
*dev
, struct device_attribute
198 *devattr
, char *buf
);
199 static ssize_t
store_temp_beep(struct device
*dev
, struct device_attribute
200 *devattr
, const char *buf
, size_t count
);
201 static ssize_t
show_temp_alarm(struct device
*dev
, struct device_attribute
202 *devattr
, char *buf
);
203 static ssize_t
show_temp_fault(struct device
*dev
, struct device_attribute
204 *devattr
, char *buf
);
205 /* PWM and Auto point control */
206 static ssize_t
show_pwm(struct device
*dev
, struct device_attribute
*devattr
,
208 static ssize_t
store_pwm(struct device
*dev
, struct device_attribute
*devattr
,
209 const char *buf
, size_t count
);
210 static ssize_t
show_pwm_enable(struct device
*dev
,
211 struct device_attribute
*devattr
, char *buf
);
212 static ssize_t
store_pwm_enable(struct device
*dev
,
213 struct device_attribute
*devattr
, const char *buf
, size_t count
);
214 static ssize_t
show_pwm_interpolate(struct device
*dev
,
215 struct device_attribute
*devattr
, char *buf
);
216 static ssize_t
store_pwm_interpolate(struct device
*dev
,
217 struct device_attribute
*devattr
, const char *buf
, size_t count
);
218 static ssize_t
show_pwm_auto_point_channel(struct device
*dev
,
219 struct device_attribute
*devattr
, char *buf
);
220 static ssize_t
store_pwm_auto_point_channel(struct device
*dev
,
221 struct device_attribute
*devattr
, const char *buf
, size_t count
);
222 static ssize_t
show_pwm_auto_point_temp_hyst(struct device
*dev
,
223 struct device_attribute
*devattr
, char *buf
);
224 static ssize_t
store_pwm_auto_point_temp_hyst(struct device
*dev
,
225 struct device_attribute
*devattr
, const char *buf
, size_t count
);
226 static ssize_t
show_pwm_auto_point_pwm(struct device
*dev
,
227 struct device_attribute
*devattr
, char *buf
);
228 static ssize_t
store_pwm_auto_point_pwm(struct device
*dev
,
229 struct device_attribute
*devattr
, const char *buf
, size_t count
);
230 static ssize_t
show_pwm_auto_point_temp(struct device
*dev
,
231 struct device_attribute
*devattr
, char *buf
);
232 static ssize_t
store_pwm_auto_point_temp(struct device
*dev
,
233 struct device_attribute
*devattr
, const char *buf
, size_t count
);
235 static ssize_t
show_name(struct device
*dev
, struct device_attribute
*devattr
,
238 static int __devinit
f71882fg_probe(struct platform_device
* pdev
);
239 static int f71882fg_remove(struct platform_device
*pdev
);
241 static struct platform_driver f71882fg_driver
= {
243 .owner
= THIS_MODULE
,
246 .probe
= f71882fg_probe
,
247 .remove
= __devexit_p(f71882fg_remove
),
250 static DEVICE_ATTR(name
, S_IRUGO
, show_name
, NULL
);
252 static struct sensor_device_attribute_2 f718x2fg_in_temp_attr
[] = {
253 SENSOR_ATTR_2(in0_input
, S_IRUGO
, show_in
, NULL
, 0, 0),
254 SENSOR_ATTR_2(in1_input
, S_IRUGO
, show_in
, NULL
, 0, 1),
255 SENSOR_ATTR_2(in2_input
, S_IRUGO
, show_in
, NULL
, 0, 2),
256 SENSOR_ATTR_2(in3_input
, S_IRUGO
, show_in
, NULL
, 0, 3),
257 SENSOR_ATTR_2(in4_input
, S_IRUGO
, show_in
, NULL
, 0, 4),
258 SENSOR_ATTR_2(in5_input
, S_IRUGO
, show_in
, NULL
, 0, 5),
259 SENSOR_ATTR_2(in6_input
, S_IRUGO
, show_in
, NULL
, 0, 6),
260 SENSOR_ATTR_2(in7_input
, S_IRUGO
, show_in
, NULL
, 0, 7),
261 SENSOR_ATTR_2(in8_input
, S_IRUGO
, show_in
, NULL
, 0, 8),
262 SENSOR_ATTR_2(temp1_input
, S_IRUGO
, show_temp
, NULL
, 0, 1),
263 SENSOR_ATTR_2(temp1_max
, S_IRUGO
|S_IWUSR
, show_temp_max
,
264 store_temp_max
, 0, 1),
265 SENSOR_ATTR_2(temp1_max_hyst
, S_IRUGO
|S_IWUSR
, show_temp_max_hyst
,
266 store_temp_max_hyst
, 0, 1),
267 /* Should really be temp1_max_alarm, but older versions did not handle
268 the max and crit alarms separately and lm_sensors v2 depends on the
269 presence of temp#_alarm files. The same goes for temp2/3 _alarm. */
270 SENSOR_ATTR_2(temp1_alarm
, S_IRUGO
, show_temp_alarm
, NULL
, 0, 1),
271 SENSOR_ATTR_2(temp1_max_beep
, S_IRUGO
|S_IWUSR
, show_temp_beep
,
272 store_temp_beep
, 0, 1),
273 SENSOR_ATTR_2(temp1_crit
, S_IRUGO
|S_IWUSR
, show_temp_crit
,
274 store_temp_crit
, 0, 1),
275 SENSOR_ATTR_2(temp1_crit_hyst
, S_IRUGO
, show_temp_crit_hyst
, NULL
,
277 SENSOR_ATTR_2(temp1_crit_alarm
, S_IRUGO
, show_temp_alarm
, NULL
, 0, 5),
278 SENSOR_ATTR_2(temp1_crit_beep
, S_IRUGO
|S_IWUSR
, show_temp_beep
,
279 store_temp_beep
, 0, 5),
280 SENSOR_ATTR_2(temp1_type
, S_IRUGO
, show_temp_type
, NULL
, 0, 1),
281 SENSOR_ATTR_2(temp1_fault
, S_IRUGO
, show_temp_fault
, NULL
, 0, 1),
282 SENSOR_ATTR_2(temp2_input
, S_IRUGO
, show_temp
, NULL
, 0, 2),
283 SENSOR_ATTR_2(temp2_max
, S_IRUGO
|S_IWUSR
, show_temp_max
,
284 store_temp_max
, 0, 2),
285 SENSOR_ATTR_2(temp2_max_hyst
, S_IRUGO
|S_IWUSR
, show_temp_max_hyst
,
286 store_temp_max_hyst
, 0, 2),
287 /* Should be temp2_max_alarm, see temp1_alarm note */
288 SENSOR_ATTR_2(temp2_alarm
, S_IRUGO
, show_temp_alarm
, NULL
, 0, 2),
289 SENSOR_ATTR_2(temp2_max_beep
, S_IRUGO
|S_IWUSR
, show_temp_beep
,
290 store_temp_beep
, 0, 2),
291 SENSOR_ATTR_2(temp2_crit
, S_IRUGO
|S_IWUSR
, show_temp_crit
,
292 store_temp_crit
, 0, 2),
293 SENSOR_ATTR_2(temp2_crit_hyst
, S_IRUGO
, show_temp_crit_hyst
, NULL
,
295 SENSOR_ATTR_2(temp2_crit_alarm
, S_IRUGO
, show_temp_alarm
, NULL
, 0, 6),
296 SENSOR_ATTR_2(temp2_crit_beep
, S_IRUGO
|S_IWUSR
, show_temp_beep
,
297 store_temp_beep
, 0, 6),
298 SENSOR_ATTR_2(temp2_type
, S_IRUGO
, show_temp_type
, NULL
, 0, 2),
299 SENSOR_ATTR_2(temp2_fault
, S_IRUGO
, show_temp_fault
, NULL
, 0, 2),
300 SENSOR_ATTR_2(temp3_input
, S_IRUGO
, show_temp
, NULL
, 0, 3),
301 SENSOR_ATTR_2(temp3_max
, S_IRUGO
|S_IWUSR
, show_temp_max
,
302 store_temp_max
, 0, 3),
303 SENSOR_ATTR_2(temp3_max_hyst
, S_IRUGO
|S_IWUSR
, show_temp_max_hyst
,
304 store_temp_max_hyst
, 0, 3),
305 /* Should be temp3_max_alarm, see temp1_alarm note */
306 SENSOR_ATTR_2(temp3_alarm
, S_IRUGO
, show_temp_alarm
, NULL
, 0, 3),
307 SENSOR_ATTR_2(temp3_max_beep
, S_IRUGO
|S_IWUSR
, show_temp_beep
,
308 store_temp_beep
, 0, 3),
309 SENSOR_ATTR_2(temp3_crit
, S_IRUGO
|S_IWUSR
, show_temp_crit
,
310 store_temp_crit
, 0, 3),
311 SENSOR_ATTR_2(temp3_crit_hyst
, S_IRUGO
, show_temp_crit_hyst
, NULL
,
313 SENSOR_ATTR_2(temp3_crit_alarm
, S_IRUGO
, show_temp_alarm
, NULL
, 0, 7),
314 SENSOR_ATTR_2(temp3_crit_beep
, S_IRUGO
|S_IWUSR
, show_temp_beep
,
315 store_temp_beep
, 0, 7),
316 SENSOR_ATTR_2(temp3_type
, S_IRUGO
, show_temp_type
, NULL
, 0, 3),
317 SENSOR_ATTR_2(temp3_fault
, S_IRUGO
, show_temp_fault
, NULL
, 0, 3),
320 static struct sensor_device_attribute_2 f71882fg_in_temp_attr
[] = {
321 SENSOR_ATTR_2(in1_max
, S_IRUGO
|S_IWUSR
, show_in_max
, store_in_max
,
323 SENSOR_ATTR_2(in1_beep
, S_IRUGO
|S_IWUSR
, show_in_beep
, store_in_beep
,
325 SENSOR_ATTR_2(in1_alarm
, S_IRUGO
, show_in_alarm
, NULL
, 0, 1),
328 static struct sensor_device_attribute_2 f718x2fg_fan_attr
[] = {
329 SENSOR_ATTR_2(fan1_input
, S_IRUGO
, show_fan
, NULL
, 0, 0),
330 SENSOR_ATTR_2(fan1_full_speed
, S_IRUGO
|S_IWUSR
,
332 store_fan_full_speed
, 0, 0),
333 SENSOR_ATTR_2(fan1_beep
, S_IRUGO
|S_IWUSR
, show_fan_beep
,
334 store_fan_beep
, 0, 0),
335 SENSOR_ATTR_2(fan1_alarm
, S_IRUGO
, show_fan_alarm
, NULL
, 0, 0),
336 SENSOR_ATTR_2(fan2_input
, S_IRUGO
, show_fan
, NULL
, 0, 1),
337 SENSOR_ATTR_2(fan2_full_speed
, S_IRUGO
|S_IWUSR
,
339 store_fan_full_speed
, 0, 1),
340 SENSOR_ATTR_2(fan2_beep
, S_IRUGO
|S_IWUSR
, show_fan_beep
,
341 store_fan_beep
, 0, 1),
342 SENSOR_ATTR_2(fan2_alarm
, S_IRUGO
, show_fan_alarm
, NULL
, 0, 1),
343 SENSOR_ATTR_2(fan3_input
, S_IRUGO
, show_fan
, NULL
, 0, 2),
344 SENSOR_ATTR_2(fan3_full_speed
, S_IRUGO
|S_IWUSR
,
346 store_fan_full_speed
, 0, 2),
347 SENSOR_ATTR_2(fan3_beep
, S_IRUGO
|S_IWUSR
, show_fan_beep
,
348 store_fan_beep
, 0, 2),
349 SENSOR_ATTR_2(fan3_alarm
, S_IRUGO
, show_fan_alarm
, NULL
, 0, 2),
351 SENSOR_ATTR_2(pwm1
, S_IRUGO
|S_IWUSR
, show_pwm
, store_pwm
, 0, 0),
352 SENSOR_ATTR_2(pwm1_enable
, S_IRUGO
|S_IWUSR
, show_pwm_enable
,
353 store_pwm_enable
, 0, 0),
354 SENSOR_ATTR_2(pwm1_interpolate
, S_IRUGO
|S_IWUSR
,
355 show_pwm_interpolate
, store_pwm_interpolate
, 0, 0),
356 SENSOR_ATTR_2(pwm1_auto_channels_temp
, S_IRUGO
|S_IWUSR
,
357 show_pwm_auto_point_channel
,
358 store_pwm_auto_point_channel
, 0, 0),
360 SENSOR_ATTR_2(pwm2
, S_IRUGO
|S_IWUSR
, show_pwm
, store_pwm
, 0, 1),
361 SENSOR_ATTR_2(pwm2_enable
, S_IRUGO
|S_IWUSR
, show_pwm_enable
,
362 store_pwm_enable
, 0, 1),
363 SENSOR_ATTR_2(pwm2_interpolate
, S_IRUGO
|S_IWUSR
,
364 show_pwm_interpolate
, store_pwm_interpolate
, 0, 1),
365 SENSOR_ATTR_2(pwm2_auto_channels_temp
, S_IRUGO
|S_IWUSR
,
366 show_pwm_auto_point_channel
,
367 store_pwm_auto_point_channel
, 0, 1),
369 SENSOR_ATTR_2(pwm3
, S_IRUGO
|S_IWUSR
, show_pwm
, store_pwm
, 0, 2),
370 SENSOR_ATTR_2(pwm3_enable
, S_IRUGO
|S_IWUSR
, show_pwm_enable
,
371 store_pwm_enable
, 0, 2),
372 SENSOR_ATTR_2(pwm3_interpolate
, S_IRUGO
|S_IWUSR
,
373 show_pwm_interpolate
, store_pwm_interpolate
, 0, 2),
374 SENSOR_ATTR_2(pwm3_auto_channels_temp
, S_IRUGO
|S_IWUSR
,
375 show_pwm_auto_point_channel
,
376 store_pwm_auto_point_channel
, 0, 2),
379 static struct sensor_device_attribute_2 f71862fg_fan_attr
[] = {
380 SENSOR_ATTR_2(pwm1_auto_point1_pwm
, S_IRUGO
|S_IWUSR
,
381 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
383 SENSOR_ATTR_2(pwm1_auto_point2_pwm
, S_IRUGO
|S_IWUSR
,
384 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
386 SENSOR_ATTR_2(pwm1_auto_point1_temp
, S_IRUGO
|S_IWUSR
,
387 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
389 SENSOR_ATTR_2(pwm1_auto_point2_temp
, S_IRUGO
|S_IWUSR
,
390 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
392 SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst
, S_IRUGO
|S_IWUSR
,
393 show_pwm_auto_point_temp_hyst
,
394 store_pwm_auto_point_temp_hyst
,
396 SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst
, S_IRUGO
,
397 show_pwm_auto_point_temp_hyst
, NULL
, 3, 0),
399 SENSOR_ATTR_2(pwm2_auto_point1_pwm
, S_IRUGO
|S_IWUSR
,
400 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
402 SENSOR_ATTR_2(pwm2_auto_point2_pwm
, S_IRUGO
|S_IWUSR
,
403 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
405 SENSOR_ATTR_2(pwm2_auto_point1_temp
, S_IRUGO
|S_IWUSR
,
406 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
408 SENSOR_ATTR_2(pwm2_auto_point2_temp
, S_IRUGO
|S_IWUSR
,
409 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
411 SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst
, S_IRUGO
|S_IWUSR
,
412 show_pwm_auto_point_temp_hyst
,
413 store_pwm_auto_point_temp_hyst
,
415 SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst
, S_IRUGO
,
416 show_pwm_auto_point_temp_hyst
, NULL
, 3, 1),
419 static struct sensor_device_attribute_2 f71882fg_fan_attr
[] = {
420 SENSOR_ATTR_2(fan4_input
, S_IRUGO
, show_fan
, NULL
, 0, 3),
421 SENSOR_ATTR_2(fan4_full_speed
, S_IRUGO
|S_IWUSR
,
423 store_fan_full_speed
, 0, 3),
424 SENSOR_ATTR_2(fan4_beep
, S_IRUGO
|S_IWUSR
, show_fan_beep
,
425 store_fan_beep
, 0, 3),
426 SENSOR_ATTR_2(fan4_alarm
, S_IRUGO
, show_fan_alarm
, NULL
, 0, 3),
428 SENSOR_ATTR_2(pwm1_auto_point1_pwm
, S_IRUGO
|S_IWUSR
,
429 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
431 SENSOR_ATTR_2(pwm1_auto_point2_pwm
, S_IRUGO
|S_IWUSR
,
432 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
434 SENSOR_ATTR_2(pwm1_auto_point3_pwm
, S_IRUGO
|S_IWUSR
,
435 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
437 SENSOR_ATTR_2(pwm1_auto_point4_pwm
, S_IRUGO
|S_IWUSR
,
438 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
440 SENSOR_ATTR_2(pwm1_auto_point5_pwm
, S_IRUGO
|S_IWUSR
,
441 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
443 SENSOR_ATTR_2(pwm1_auto_point1_temp
, S_IRUGO
|S_IWUSR
,
444 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
446 SENSOR_ATTR_2(pwm1_auto_point2_temp
, S_IRUGO
|S_IWUSR
,
447 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
449 SENSOR_ATTR_2(pwm1_auto_point3_temp
, S_IRUGO
|S_IWUSR
,
450 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
452 SENSOR_ATTR_2(pwm1_auto_point4_temp
, S_IRUGO
|S_IWUSR
,
453 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
455 SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst
, S_IRUGO
|S_IWUSR
,
456 show_pwm_auto_point_temp_hyst
,
457 store_pwm_auto_point_temp_hyst
,
459 SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst
, S_IRUGO
,
460 show_pwm_auto_point_temp_hyst
, NULL
, 1, 0),
461 SENSOR_ATTR_2(pwm1_auto_point3_temp_hyst
, S_IRUGO
,
462 show_pwm_auto_point_temp_hyst
, NULL
, 2, 0),
463 SENSOR_ATTR_2(pwm1_auto_point4_temp_hyst
, S_IRUGO
,
464 show_pwm_auto_point_temp_hyst
, NULL
, 3, 0),
466 SENSOR_ATTR_2(pwm2_auto_point1_pwm
, S_IRUGO
|S_IWUSR
,
467 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
469 SENSOR_ATTR_2(pwm2_auto_point2_pwm
, S_IRUGO
|S_IWUSR
,
470 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
472 SENSOR_ATTR_2(pwm2_auto_point3_pwm
, S_IRUGO
|S_IWUSR
,
473 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
475 SENSOR_ATTR_2(pwm2_auto_point4_pwm
, S_IRUGO
|S_IWUSR
,
476 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
478 SENSOR_ATTR_2(pwm2_auto_point5_pwm
, S_IRUGO
|S_IWUSR
,
479 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
481 SENSOR_ATTR_2(pwm2_auto_point1_temp
, S_IRUGO
|S_IWUSR
,
482 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
484 SENSOR_ATTR_2(pwm2_auto_point2_temp
, S_IRUGO
|S_IWUSR
,
485 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
487 SENSOR_ATTR_2(pwm2_auto_point3_temp
, S_IRUGO
|S_IWUSR
,
488 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
490 SENSOR_ATTR_2(pwm2_auto_point4_temp
, S_IRUGO
|S_IWUSR
,
491 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
493 SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst
, S_IRUGO
|S_IWUSR
,
494 show_pwm_auto_point_temp_hyst
,
495 store_pwm_auto_point_temp_hyst
,
497 SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst
, S_IRUGO
,
498 show_pwm_auto_point_temp_hyst
, NULL
, 1, 1),
499 SENSOR_ATTR_2(pwm2_auto_point3_temp_hyst
, S_IRUGO
,
500 show_pwm_auto_point_temp_hyst
, NULL
, 2, 1),
501 SENSOR_ATTR_2(pwm2_auto_point4_temp_hyst
, S_IRUGO
,
502 show_pwm_auto_point_temp_hyst
, NULL
, 3, 1),
504 SENSOR_ATTR_2(pwm3_auto_point1_pwm
, S_IRUGO
|S_IWUSR
,
505 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
507 SENSOR_ATTR_2(pwm3_auto_point2_pwm
, S_IRUGO
|S_IWUSR
,
508 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
510 SENSOR_ATTR_2(pwm3_auto_point3_pwm
, S_IRUGO
|S_IWUSR
,
511 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
513 SENSOR_ATTR_2(pwm3_auto_point4_pwm
, S_IRUGO
|S_IWUSR
,
514 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
516 SENSOR_ATTR_2(pwm3_auto_point5_pwm
, S_IRUGO
|S_IWUSR
,
517 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
519 SENSOR_ATTR_2(pwm3_auto_point1_temp
, S_IRUGO
|S_IWUSR
,
520 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
522 SENSOR_ATTR_2(pwm3_auto_point2_temp
, S_IRUGO
|S_IWUSR
,
523 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
525 SENSOR_ATTR_2(pwm3_auto_point3_temp
, S_IRUGO
|S_IWUSR
,
526 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
528 SENSOR_ATTR_2(pwm3_auto_point4_temp
, S_IRUGO
|S_IWUSR
,
529 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
531 SENSOR_ATTR_2(pwm3_auto_point1_temp_hyst
, S_IRUGO
|S_IWUSR
,
532 show_pwm_auto_point_temp_hyst
,
533 store_pwm_auto_point_temp_hyst
,
535 SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst
, S_IRUGO
,
536 show_pwm_auto_point_temp_hyst
, NULL
, 1, 2),
537 SENSOR_ATTR_2(pwm3_auto_point3_temp_hyst
, S_IRUGO
,
538 show_pwm_auto_point_temp_hyst
, NULL
, 2, 2),
539 SENSOR_ATTR_2(pwm3_auto_point4_temp_hyst
, S_IRUGO
,
540 show_pwm_auto_point_temp_hyst
, NULL
, 3, 2),
542 SENSOR_ATTR_2(pwm4
, S_IRUGO
|S_IWUSR
, show_pwm
, store_pwm
, 0, 3),
543 SENSOR_ATTR_2(pwm4_enable
, S_IRUGO
|S_IWUSR
, show_pwm_enable
,
544 store_pwm_enable
, 0, 3),
545 SENSOR_ATTR_2(pwm4_interpolate
, S_IRUGO
|S_IWUSR
,
546 show_pwm_interpolate
, store_pwm_interpolate
, 0, 3),
547 SENSOR_ATTR_2(pwm4_auto_channels_temp
, S_IRUGO
|S_IWUSR
,
548 show_pwm_auto_point_channel
,
549 store_pwm_auto_point_channel
, 0, 3),
550 SENSOR_ATTR_2(pwm4_auto_point1_pwm
, S_IRUGO
|S_IWUSR
,
551 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
553 SENSOR_ATTR_2(pwm4_auto_point2_pwm
, S_IRUGO
|S_IWUSR
,
554 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
556 SENSOR_ATTR_2(pwm4_auto_point3_pwm
, S_IRUGO
|S_IWUSR
,
557 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
559 SENSOR_ATTR_2(pwm4_auto_point4_pwm
, S_IRUGO
|S_IWUSR
,
560 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
562 SENSOR_ATTR_2(pwm4_auto_point5_pwm
, S_IRUGO
|S_IWUSR
,
563 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
565 SENSOR_ATTR_2(pwm4_auto_point1_temp
, S_IRUGO
|S_IWUSR
,
566 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
568 SENSOR_ATTR_2(pwm4_auto_point2_temp
, S_IRUGO
|S_IWUSR
,
569 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
571 SENSOR_ATTR_2(pwm4_auto_point3_temp
, S_IRUGO
|S_IWUSR
,
572 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
574 SENSOR_ATTR_2(pwm4_auto_point4_temp
, S_IRUGO
|S_IWUSR
,
575 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
577 SENSOR_ATTR_2(pwm4_auto_point1_temp_hyst
, S_IRUGO
|S_IWUSR
,
578 show_pwm_auto_point_temp_hyst
,
579 store_pwm_auto_point_temp_hyst
,
581 SENSOR_ATTR_2(pwm4_auto_point2_temp_hyst
, S_IRUGO
,
582 show_pwm_auto_point_temp_hyst
, NULL
, 1, 3),
583 SENSOR_ATTR_2(pwm4_auto_point3_temp_hyst
, S_IRUGO
,
584 show_pwm_auto_point_temp_hyst
, NULL
, 2, 3),
585 SENSOR_ATTR_2(pwm4_auto_point4_temp_hyst
, S_IRUGO
,
586 show_pwm_auto_point_temp_hyst
, NULL
, 3, 3),
590 /* Super I/O functions */
591 static inline int superio_inb(int base
, int reg
)
594 return inb(base
+ 1);
597 static int superio_inw(int base
, int reg
)
601 val
= inb(base
+ 1) << 8;
603 val
|= inb(base
+ 1);
607 static inline void superio_enter(int base
)
609 /* according to the datasheet the key must be send twice! */
610 outb( SIO_UNLOCK_KEY
, base
);
611 outb( SIO_UNLOCK_KEY
, base
);
614 static inline void superio_select( int base
, int ld
)
616 outb(SIO_REG_LDSEL
, base
);
620 static inline void superio_exit(int base
)
622 outb(SIO_LOCK_KEY
, base
);
625 static inline u16
fan_from_reg(u16 reg
)
627 return reg
? (1500000 / reg
) : 0;
630 static inline u16
fan_to_reg(u16 fan
)
632 return fan
? (1500000 / fan
) : 0;
635 static u8
f71882fg_read8(struct f71882fg_data
*data
, u8 reg
)
639 outb(reg
, data
->addr
+ ADDR_REG_OFFSET
);
640 val
= inb(data
->addr
+ DATA_REG_OFFSET
);
645 static u16
f71882fg_read16(struct f71882fg_data
*data
, u8 reg
)
649 outb(reg
++, data
->addr
+ ADDR_REG_OFFSET
);
650 val
= inb(data
->addr
+ DATA_REG_OFFSET
) << 8;
651 outb(reg
, data
->addr
+ ADDR_REG_OFFSET
);
652 val
|= inb(data
->addr
+ DATA_REG_OFFSET
);
657 static void f71882fg_write8(struct f71882fg_data
*data
, u8 reg
, u8 val
)
659 outb(reg
, data
->addr
+ ADDR_REG_OFFSET
);
660 outb(val
, data
->addr
+ DATA_REG_OFFSET
);
663 static void f71882fg_write16(struct f71882fg_data
*data
, u8 reg
, u16 val
)
665 outb(reg
++, data
->addr
+ ADDR_REG_OFFSET
);
666 outb(val
>> 8, data
->addr
+ DATA_REG_OFFSET
);
667 outb(reg
, data
->addr
+ ADDR_REG_OFFSET
);
668 outb(val
& 255, data
->addr
+ DATA_REG_OFFSET
);
671 static struct f71882fg_data
*f71882fg_update_device(struct device
*dev
)
673 struct f71882fg_data
*data
= dev_get_drvdata(dev
);
675 int nr_fans
= (data
->type
== f71862fg
) ? 3 : 4;
677 mutex_lock(&data
->update_lock
);
679 /* Update once every 60 seconds */
680 if ( time_after(jiffies
, data
->last_limits
+ 60 * HZ
) ||
682 if (data
->type
== f71882fg
) {
684 f71882fg_read8(data
, F71882FG_REG_IN1_HIGH
);
686 f71882fg_read8(data
, F71882FG_REG_IN_BEEP
);
689 /* Get High & boundary temps*/
690 for (nr
= 1; nr
< 4; nr
++) {
691 data
->temp_ovt
[nr
] = f71882fg_read8(data
,
692 F71882FG_REG_TEMP_OVT(nr
));
693 data
->temp_high
[nr
] = f71882fg_read8(data
,
694 F71882FG_REG_TEMP_HIGH(nr
));
699 f71882fg_read8(data
, F71882FG_REG_TEMP_HYST(0));
701 f71882fg_read8(data
, F71882FG_REG_TEMP_HYST(1));
703 /* Have to hardcode type, because temp1 is special */
704 reg
= f71882fg_read8(data
, F71882FG_REG_TEMP_TYPE
);
705 reg2
= f71882fg_read8(data
, F71882FG_REG_PECI
);
706 if ((reg2
& 0x03) == 0x01)
707 data
->temp_type
[1] = 6 /* PECI */;
708 else if ((reg2
& 0x03) == 0x02)
709 data
->temp_type
[1] = 5 /* AMDSI */;
711 data
->temp_type
[1] = (reg
& 0x02) ? 2 : 4;
713 data
->temp_type
[2] = (reg
& 0x04) ? 2 : 4;
714 data
->temp_type
[3] = (reg
& 0x08) ? 2 : 4;
716 data
->temp_beep
= f71882fg_read8(data
, F71882FG_REG_TEMP_BEEP
);
718 data
->fan_beep
= f71882fg_read8(data
, F71882FG_REG_FAN_BEEP
);
720 data
->pwm_enable
= f71882fg_read8(data
,
721 F71882FG_REG_PWM_ENABLE
);
722 data
->pwm_auto_point_hyst
[0] =
723 f71882fg_read8(data
, F71882FG_REG_FAN_HYST(0));
724 data
->pwm_auto_point_hyst
[1] =
725 f71882fg_read8(data
, F71882FG_REG_FAN_HYST(1));
727 for (nr
= 0; nr
< nr_fans
; nr
++) {
728 data
->pwm_auto_point_mapping
[nr
] =
730 F71882FG_REG_POINT_MAPPING(nr
));
732 if (data
->type
== f71882fg
) {
734 for (point
= 0; point
< 5; point
++) {
735 data
->pwm_auto_point_pwm
[nr
][point
] =
737 F71882FG_REG_POINT_PWM
740 for (point
= 0; point
< 4; point
++) {
741 data
->pwm_auto_point_temp
[nr
][point
] =
743 F71882FG_REG_POINT_TEMP
747 data
->pwm_auto_point_pwm
[nr
][1] =
749 F71882FG_REG_POINT_PWM
751 data
->pwm_auto_point_pwm
[nr
][4] =
753 F71882FG_REG_POINT_PWM
755 data
->pwm_auto_point_temp
[nr
][0] =
757 F71882FG_REG_POINT_TEMP
759 data
->pwm_auto_point_temp
[nr
][3] =
761 F71882FG_REG_POINT_TEMP
765 data
->last_limits
= jiffies
;
768 /* Update every second */
769 if (time_after(jiffies
, data
->last_updated
+ HZ
) || !data
->valid
) {
770 data
->temp_status
= f71882fg_read8(data
,
771 F71882FG_REG_TEMP_STATUS
);
772 data
->temp_diode_open
= f71882fg_read8(data
,
773 F71882FG_REG_TEMP_DIODE_OPEN
);
774 for (nr
= 1; nr
< 4; nr
++)
775 data
->temp
[nr
] = f71882fg_read8(data
,
776 F71882FG_REG_TEMP(nr
));
778 data
->fan_status
= f71882fg_read8(data
,
779 F71882FG_REG_FAN_STATUS
);
780 for (nr
= 0; nr
< nr_fans
; nr
++) {
781 data
->fan
[nr
] = f71882fg_read16(data
,
782 F71882FG_REG_FAN(nr
));
783 data
->fan_target
[nr
] =
784 f71882fg_read16(data
, F71882FG_REG_FAN_TARGET(nr
));
785 data
->fan_full_speed
[nr
] =
786 f71882fg_read16(data
,
787 F71882FG_REG_FAN_FULL_SPEED(nr
));
789 f71882fg_read8(data
, F71882FG_REG_PWM(nr
));
792 if (data
->type
== f71882fg
)
793 data
->in_status
= f71882fg_read8(data
,
794 F71882FG_REG_IN_STATUS
);
795 for (nr
= 0; nr
< 9; nr
++)
796 data
->in
[nr
] = f71882fg_read8(data
,
797 F71882FG_REG_IN(nr
));
799 data
->last_updated
= jiffies
;
803 mutex_unlock(&data
->update_lock
);
808 /* Sysfs Interface */
809 static ssize_t
show_fan(struct device
*dev
, struct device_attribute
*devattr
,
812 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
813 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
814 int speed
= fan_from_reg(data
->fan
[nr
]);
816 if (speed
== FAN_MIN_DETECT
)
819 return sprintf(buf
, "%d\n", speed
);
822 static ssize_t
show_fan_full_speed(struct device
*dev
,
823 struct device_attribute
*devattr
, char *buf
)
825 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
826 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
827 int speed
= fan_from_reg(data
->fan_full_speed
[nr
]);
828 return sprintf(buf
, "%d\n", speed
);
831 static ssize_t
store_fan_full_speed(struct device
*dev
,
832 struct device_attribute
*devattr
,
833 const char *buf
, size_t count
)
835 struct f71882fg_data
*data
= dev_get_drvdata(dev
);
836 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
837 long val
= simple_strtol(buf
, NULL
, 10);
839 val
= SENSORS_LIMIT(val
, 23, 1500000);
840 val
= fan_to_reg(val
);
842 mutex_lock(&data
->update_lock
);
843 f71882fg_write16(data
, F71882FG_REG_FAN_FULL_SPEED(nr
), val
);
844 data
->fan_full_speed
[nr
] = val
;
845 mutex_unlock(&data
->update_lock
);
850 static ssize_t
show_fan_beep(struct device
*dev
, struct device_attribute
853 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
854 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
856 if (data
->fan_beep
& (1 << nr
))
857 return sprintf(buf
, "1\n");
859 return sprintf(buf
, "0\n");
862 static ssize_t
store_fan_beep(struct device
*dev
, struct device_attribute
863 *devattr
, const char *buf
, size_t count
)
865 struct f71882fg_data
*data
= dev_get_drvdata(dev
);
866 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
867 unsigned long val
= simple_strtoul(buf
, NULL
, 10);
869 mutex_lock(&data
->update_lock
);
870 data
->fan_beep
= f71882fg_read8(data
, F71882FG_REG_FAN_BEEP
);
872 data
->fan_beep
|= 1 << nr
;
874 data
->fan_beep
&= ~(1 << nr
);
876 f71882fg_write8(data
, F71882FG_REG_FAN_BEEP
, data
->fan_beep
);
877 mutex_unlock(&data
->update_lock
);
882 static ssize_t
show_fan_alarm(struct device
*dev
, struct device_attribute
885 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
886 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
888 if (data
->fan_status
& (1 << nr
))
889 return sprintf(buf
, "1\n");
891 return sprintf(buf
, "0\n");
894 static ssize_t
show_in(struct device
*dev
, struct device_attribute
*devattr
,
897 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
898 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
900 return sprintf(buf
, "%d\n", data
->in
[nr
] * 8);
903 static ssize_t
show_in_max(struct device
*dev
, struct device_attribute
906 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
908 return sprintf(buf
, "%d\n", data
->in1_max
* 8);
911 static ssize_t
store_in_max(struct device
*dev
, struct device_attribute
912 *devattr
, const char *buf
, size_t count
)
914 struct f71882fg_data
*data
= dev_get_drvdata(dev
);
915 long val
= simple_strtol(buf
, NULL
, 10) / 8;
916 val
= SENSORS_LIMIT(val
, 0, 255);
918 mutex_lock(&data
->update_lock
);
919 f71882fg_write8(data
, F71882FG_REG_IN1_HIGH
, val
);
921 mutex_unlock(&data
->update_lock
);
926 static ssize_t
show_in_beep(struct device
*dev
, struct device_attribute
929 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
930 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
932 if (data
->in_beep
& (1 << nr
))
933 return sprintf(buf
, "1\n");
935 return sprintf(buf
, "0\n");
938 static ssize_t
store_in_beep(struct device
*dev
, struct device_attribute
939 *devattr
, const char *buf
, size_t count
)
941 struct f71882fg_data
*data
= dev_get_drvdata(dev
);
942 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
943 unsigned long val
= simple_strtoul(buf
, NULL
, 10);
945 mutex_lock(&data
->update_lock
);
946 data
->in_beep
= f71882fg_read8(data
, F71882FG_REG_IN_BEEP
);
948 data
->in_beep
|= 1 << nr
;
950 data
->in_beep
&= ~(1 << nr
);
952 f71882fg_write8(data
, F71882FG_REG_IN_BEEP
, data
->in_beep
);
953 mutex_unlock(&data
->update_lock
);
958 static ssize_t
show_in_alarm(struct device
*dev
, struct device_attribute
961 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
962 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
964 if (data
->in_status
& (1 << nr
))
965 return sprintf(buf
, "1\n");
967 return sprintf(buf
, "0\n");
970 static ssize_t
show_temp(struct device
*dev
, struct device_attribute
*devattr
,
973 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
974 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
976 return sprintf(buf
, "%d\n", data
->temp
[nr
] * 1000);
979 static ssize_t
show_temp_max(struct device
*dev
, struct device_attribute
982 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
983 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
985 return sprintf(buf
, "%d\n", data
->temp_high
[nr
] * 1000);
988 static ssize_t
store_temp_max(struct device
*dev
, struct device_attribute
989 *devattr
, const char *buf
, size_t count
)
991 struct f71882fg_data
*data
= dev_get_drvdata(dev
);
992 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
993 long val
= simple_strtol(buf
, NULL
, 10) / 1000;
994 val
= SENSORS_LIMIT(val
, 0, 255);
996 mutex_lock(&data
->update_lock
);
997 f71882fg_write8(data
, F71882FG_REG_TEMP_HIGH(nr
), val
);
998 data
->temp_high
[nr
] = val
;
999 mutex_unlock(&data
->update_lock
);
1004 static ssize_t
show_temp_max_hyst(struct device
*dev
, struct device_attribute
1005 *devattr
, char *buf
)
1007 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1008 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1011 mutex_lock(&data
->update_lock
);
1013 temp_max_hyst
= data
->temp_hyst
[nr
/ 2] >> 4;
1015 temp_max_hyst
= data
->temp_hyst
[nr
/ 2] & 0x0f;
1016 temp_max_hyst
= (data
->temp_high
[nr
] - temp_max_hyst
) * 1000;
1017 mutex_unlock(&data
->update_lock
);
1019 return sprintf(buf
, "%d\n", temp_max_hyst
);
1022 static ssize_t
store_temp_max_hyst(struct device
*dev
, struct device_attribute
1023 *devattr
, const char *buf
, size_t count
)
1025 struct f71882fg_data
*data
= dev_get_drvdata(dev
);
1026 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1027 long val
= simple_strtol(buf
, NULL
, 10) / 1000;
1028 ssize_t ret
= count
;
1031 mutex_lock(&data
->update_lock
);
1033 /* convert abs to relative and check */
1034 data
->temp_high
[nr
] = f71882fg_read8(data
, F71882FG_REG_TEMP_HIGH(nr
));
1035 val
= SENSORS_LIMIT(val
, data
->temp_high
[nr
] - 15,
1036 data
->temp_high
[nr
]);
1037 val
= data
->temp_high
[nr
] - val
;
1039 /* convert value to register contents */
1040 reg
= f71882fg_read8(data
, F71882FG_REG_TEMP_HYST(nr
/ 2));
1042 reg
= (reg
& 0x0f) | (val
<< 4);
1044 reg
= (reg
& 0xf0) | val
;
1045 f71882fg_write8(data
, F71882FG_REG_TEMP_HYST(nr
/ 2), reg
);
1046 data
->temp_hyst
[nr
/ 2] = reg
;
1048 mutex_unlock(&data
->update_lock
);
1052 static ssize_t
show_temp_crit(struct device
*dev
, struct device_attribute
1053 *devattr
, char *buf
)
1055 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1056 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1058 return sprintf(buf
, "%d\n", data
->temp_ovt
[nr
] * 1000);
1061 static ssize_t
store_temp_crit(struct device
*dev
, struct device_attribute
1062 *devattr
, const char *buf
, size_t count
)
1064 struct f71882fg_data
*data
= dev_get_drvdata(dev
);
1065 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1066 long val
= simple_strtol(buf
, NULL
, 10) / 1000;
1067 val
= SENSORS_LIMIT(val
, 0, 255);
1069 mutex_lock(&data
->update_lock
);
1070 f71882fg_write8(data
, F71882FG_REG_TEMP_OVT(nr
), val
);
1071 data
->temp_ovt
[nr
] = val
;
1072 mutex_unlock(&data
->update_lock
);
1077 static ssize_t
show_temp_crit_hyst(struct device
*dev
, struct device_attribute
1078 *devattr
, char *buf
)
1080 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1081 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1084 mutex_lock(&data
->update_lock
);
1086 temp_crit_hyst
= data
->temp_hyst
[nr
/ 2] >> 4;
1088 temp_crit_hyst
= data
->temp_hyst
[nr
/ 2] & 0x0f;
1089 temp_crit_hyst
= (data
->temp_ovt
[nr
] - temp_crit_hyst
) * 1000;
1090 mutex_unlock(&data
->update_lock
);
1092 return sprintf(buf
, "%d\n", temp_crit_hyst
);
1095 static ssize_t
show_temp_type(struct device
*dev
, struct device_attribute
1096 *devattr
, char *buf
)
1098 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1099 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1101 return sprintf(buf
, "%d\n", data
->temp_type
[nr
]);
1104 static ssize_t
show_temp_beep(struct device
*dev
, struct device_attribute
1105 *devattr
, char *buf
)
1107 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1108 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1110 if (data
->temp_beep
& (1 << nr
))
1111 return sprintf(buf
, "1\n");
1113 return sprintf(buf
, "0\n");
1116 static ssize_t
store_temp_beep(struct device
*dev
, struct device_attribute
1117 *devattr
, const char *buf
, size_t count
)
1119 struct f71882fg_data
*data
= dev_get_drvdata(dev
);
1120 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1121 unsigned long val
= simple_strtoul(buf
, NULL
, 10);
1123 mutex_lock(&data
->update_lock
);
1124 data
->temp_beep
= f71882fg_read8(data
, F71882FG_REG_TEMP_BEEP
);
1126 data
->temp_beep
|= 1 << nr
;
1128 data
->temp_beep
&= ~(1 << nr
);
1130 f71882fg_write8(data
, F71882FG_REG_TEMP_BEEP
, data
->temp_beep
);
1131 mutex_unlock(&data
->update_lock
);
1136 static ssize_t
show_temp_alarm(struct device
*dev
, struct device_attribute
1137 *devattr
, char *buf
)
1139 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1140 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1142 if (data
->temp_status
& (1 << nr
))
1143 return sprintf(buf
, "1\n");
1145 return sprintf(buf
, "0\n");
1148 static ssize_t
show_temp_fault(struct device
*dev
, struct device_attribute
1149 *devattr
, char *buf
)
1151 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1152 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1154 if (data
->temp_diode_open
& (1 << nr
))
1155 return sprintf(buf
, "1\n");
1157 return sprintf(buf
, "0\n");
1160 static ssize_t
show_pwm(struct device
*dev
,
1161 struct device_attribute
*devattr
, char *buf
)
1163 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1164 int val
, nr
= to_sensor_dev_attr_2(devattr
)->index
;
1165 mutex_lock(&data
->update_lock
);
1166 if (data
->pwm_enable
& (1 << (2 * nr
)))
1168 val
= data
->pwm
[nr
];
1171 val
= 255 * fan_from_reg(data
->fan_target
[nr
])
1172 / fan_from_reg(data
->fan_full_speed
[nr
]);
1174 mutex_unlock(&data
->update_lock
);
1175 return sprintf(buf
, "%d\n", val
);
1178 static ssize_t
store_pwm(struct device
*dev
,
1179 struct device_attribute
*devattr
, const char *buf
,
1182 struct f71882fg_data
*data
= dev_get_drvdata(dev
);
1183 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1184 long val
= simple_strtol(buf
, NULL
, 10);
1185 val
= SENSORS_LIMIT(val
, 0, 255);
1187 mutex_lock(&data
->update_lock
);
1188 data
->pwm_enable
= f71882fg_read8(data
, F71882FG_REG_PWM_ENABLE
);
1189 if (data
->pwm_enable
& (1 << (2 * nr
))) {
1191 f71882fg_write8(data
, F71882FG_REG_PWM(nr
), val
);
1192 data
->pwm
[nr
] = val
;
1195 int target
, full_speed
;
1196 full_speed
= f71882fg_read16(data
,
1197 F71882FG_REG_FAN_FULL_SPEED(nr
));
1198 target
= fan_to_reg(val
* fan_from_reg(full_speed
) / 255);
1199 f71882fg_write16(data
, F71882FG_REG_FAN_TARGET(nr
), target
);
1200 data
->fan_target
[nr
] = target
;
1201 data
->fan_full_speed
[nr
] = full_speed
;
1203 mutex_unlock(&data
->update_lock
);
1208 static ssize_t
show_pwm_enable(struct device
*dev
,
1209 struct device_attribute
*devattr
, char *buf
)
1212 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1213 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1215 if (data
->pwm_enable
& (2 << (2 * nr
)))
1220 return sprintf(buf
, "%d\n", result
);
1223 static ssize_t
store_pwm_enable(struct device
*dev
, struct device_attribute
1224 *devattr
, const char *buf
, size_t count
)
1226 struct f71882fg_data
*data
= dev_get_drvdata(dev
);
1227 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1228 long val
= simple_strtol(buf
, NULL
, 10);
1229 if (val
< 1 || val
> 2)
1232 mutex_lock(&data
->update_lock
);
1233 data
->pwm_enable
= f71882fg_read8(data
, F71882FG_REG_PWM_ENABLE
);
1236 data
->pwm_enable
|= 2 << (2 * nr
);
1239 data
->pwm_enable
&= ~(2 << (2 * nr
));
1240 break; /* Temperature ctrl */
1242 f71882fg_write8(data
, F71882FG_REG_PWM_ENABLE
, data
->pwm_enable
);
1243 mutex_unlock(&data
->update_lock
);
1248 static ssize_t
show_pwm_auto_point_pwm(struct device
*dev
,
1249 struct device_attribute
*devattr
,
1253 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1254 int pwm
= to_sensor_dev_attr_2(devattr
)->index
;
1255 int point
= to_sensor_dev_attr_2(devattr
)->nr
;
1257 mutex_lock(&data
->update_lock
);
1258 if (data
->pwm_enable
& (1 << (2 * pwm
))) {
1260 result
= data
->pwm_auto_point_pwm
[pwm
][point
];
1263 result
= 32 * 255 / (32 + data
->pwm_auto_point_pwm
[pwm
][point
]);
1265 mutex_unlock(&data
->update_lock
);
1267 return sprintf(buf
, "%d\n", result
);
1270 static ssize_t
store_pwm_auto_point_pwm(struct device
*dev
,
1271 struct device_attribute
*devattr
,
1272 const char *buf
, size_t count
)
1274 struct f71882fg_data
*data
= dev_get_drvdata(dev
);
1275 int pwm
= to_sensor_dev_attr_2(devattr
)->index
;
1276 int point
= to_sensor_dev_attr_2(devattr
)->nr
;
1277 long val
= simple_strtol(buf
, NULL
, 10);
1278 val
= SENSORS_LIMIT(val
, 0, 255);
1280 mutex_lock(&data
->update_lock
);
1281 data
->pwm_enable
= f71882fg_read8(data
, F71882FG_REG_PWM_ENABLE
);
1282 if (data
->pwm_enable
& (1 << (2 * pwm
))) {
1286 if (val
< 29) /* Prevent negative numbers */
1289 val
= (255 - val
) * 32 / val
;
1291 f71882fg_write8(data
, F71882FG_REG_POINT_PWM(pwm
, point
), val
);
1292 data
->pwm_auto_point_pwm
[pwm
][point
] = val
;
1293 mutex_unlock(&data
->update_lock
);
1298 static ssize_t
show_pwm_auto_point_temp_hyst(struct device
*dev
,
1299 struct device_attribute
*devattr
,
1303 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1304 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1305 int point
= to_sensor_dev_attr_2(devattr
)->nr
;
1307 mutex_lock(&data
->update_lock
);
1309 result
= data
->pwm_auto_point_hyst
[nr
/ 2] >> 4;
1311 result
= data
->pwm_auto_point_hyst
[nr
/ 2] & 0x0f;
1312 result
= 1000 * (data
->pwm_auto_point_temp
[nr
][point
] - result
);
1313 mutex_unlock(&data
->update_lock
);
1315 return sprintf(buf
, "%d\n", result
);
1318 static ssize_t
store_pwm_auto_point_temp_hyst(struct device
*dev
,
1319 struct device_attribute
*devattr
,
1320 const char *buf
, size_t count
)
1322 struct f71882fg_data
*data
= dev_get_drvdata(dev
);
1323 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1324 int point
= to_sensor_dev_attr_2(devattr
)->nr
;
1325 long val
= simple_strtol(buf
, NULL
, 10) / 1000;
1328 mutex_lock(&data
->update_lock
);
1329 data
->pwm_auto_point_temp
[nr
][point
] =
1330 f71882fg_read8(data
, F71882FG_REG_POINT_TEMP(nr
, point
));
1331 val
= SENSORS_LIMIT(val
, data
->pwm_auto_point_temp
[nr
][point
] - 15,
1332 data
->pwm_auto_point_temp
[nr
][point
]);
1333 val
= data
->pwm_auto_point_temp
[nr
][point
] - val
;
1335 reg
= f71882fg_read8(data
, F71882FG_REG_FAN_HYST(nr
/ 2));
1337 reg
= (reg
& 0x0f) | (val
<< 4);
1339 reg
= (reg
& 0xf0) | val
;
1341 f71882fg_write8(data
, F71882FG_REG_FAN_HYST(nr
/ 2), reg
);
1342 data
->pwm_auto_point_hyst
[nr
/ 2] = reg
;
1343 mutex_unlock(&data
->update_lock
);
1348 static ssize_t
show_pwm_interpolate(struct device
*dev
,
1349 struct device_attribute
*devattr
, char *buf
)
1352 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1353 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1355 result
= (data
->pwm_auto_point_mapping
[nr
] >> 4) & 1;
1357 return sprintf(buf
, "%d\n", result
);
1360 static ssize_t
store_pwm_interpolate(struct device
*dev
,
1361 struct device_attribute
*devattr
,
1362 const char *buf
, size_t count
)
1364 struct f71882fg_data
*data
= dev_get_drvdata(dev
);
1365 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1366 unsigned long val
= simple_strtoul(buf
, NULL
, 10);
1368 mutex_lock(&data
->update_lock
);
1369 data
->pwm_auto_point_mapping
[nr
] =
1370 f71882fg_read8(data
, F71882FG_REG_POINT_MAPPING(nr
));
1372 val
= data
->pwm_auto_point_mapping
[nr
] | (1 << 4);
1374 val
= data
->pwm_auto_point_mapping
[nr
] & (~(1 << 4));
1375 f71882fg_write8(data
, F71882FG_REG_POINT_MAPPING(nr
), val
);
1376 data
->pwm_auto_point_mapping
[nr
] = val
;
1377 mutex_unlock(&data
->update_lock
);
1382 static ssize_t
show_pwm_auto_point_channel(struct device
*dev
,
1383 struct device_attribute
*devattr
,
1387 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1388 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1390 result
= 1 << ((data
->pwm_auto_point_mapping
[nr
] & 3) - 1);
1392 return sprintf(buf
, "%d\n", result
);
1395 static ssize_t
store_pwm_auto_point_channel(struct device
*dev
,
1396 struct device_attribute
*devattr
,
1397 const char *buf
, size_t count
)
1399 struct f71882fg_data
*data
= dev_get_drvdata(dev
);
1400 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1401 long val
= simple_strtol(buf
, NULL
, 10);
1415 mutex_lock(&data
->update_lock
);
1416 data
->pwm_auto_point_mapping
[nr
] =
1417 f71882fg_read8(data
, F71882FG_REG_POINT_MAPPING(nr
));
1418 val
= (data
->pwm_auto_point_mapping
[nr
] & 0xfc) | val
;
1419 f71882fg_write8(data
, F71882FG_REG_POINT_MAPPING(nr
), val
);
1420 data
->pwm_auto_point_mapping
[nr
] = val
;
1421 mutex_unlock(&data
->update_lock
);
1426 static ssize_t
show_pwm_auto_point_temp(struct device
*dev
,
1427 struct device_attribute
*devattr
,
1431 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1432 int pwm
= to_sensor_dev_attr_2(devattr
)->index
;
1433 int point
= to_sensor_dev_attr_2(devattr
)->nr
;
1435 result
= data
->pwm_auto_point_temp
[pwm
][point
];
1436 return sprintf(buf
, "%d\n", 1000 * result
);
1439 static ssize_t
store_pwm_auto_point_temp(struct device
*dev
,
1440 struct device_attribute
*devattr
,
1441 const char *buf
, size_t count
)
1443 struct f71882fg_data
*data
= dev_get_drvdata(dev
);
1444 int pwm
= to_sensor_dev_attr_2(devattr
)->index
;
1445 int point
= to_sensor_dev_attr_2(devattr
)->nr
;
1446 long val
= simple_strtol(buf
, NULL
, 10) / 1000;
1447 val
= SENSORS_LIMIT(val
, 0, 255);
1449 mutex_lock(&data
->update_lock
);
1450 f71882fg_write8(data
, F71882FG_REG_POINT_TEMP(pwm
, point
), val
);
1451 data
->pwm_auto_point_temp
[pwm
][point
] = val
;
1452 mutex_unlock(&data
->update_lock
);
1457 static ssize_t
show_name(struct device
*dev
, struct device_attribute
*devattr
,
1460 struct f71882fg_data
*data
= dev_get_drvdata(dev
);
1461 return sprintf(buf
, "%s\n", f71882fg_names
[data
->type
]);
1464 static int __devinit
f71882fg_create_sysfs_files(struct platform_device
*pdev
,
1465 struct sensor_device_attribute_2
*attr
, int count
)
1469 for (i
= 0; i
< count
; i
++) {
1470 err
= device_create_file(&pdev
->dev
, &attr
[i
].dev_attr
);
1477 static int __devinit
f71882fg_probe(struct platform_device
*pdev
)
1479 struct f71882fg_data
*data
;
1480 struct f71882fg_sio_data
*sio_data
= pdev
->dev
.platform_data
;
1484 data
= kzalloc(sizeof(struct f71882fg_data
), GFP_KERNEL
);
1488 data
->addr
= platform_get_resource(pdev
, IORESOURCE_IO
, 0)->start
;
1489 data
->type
= sio_data
->type
;
1490 mutex_init(&data
->update_lock
);
1491 platform_set_drvdata(pdev
, data
);
1493 start_reg
= f71882fg_read8(data
, F71882FG_REG_START
);
1494 if (start_reg
& 0x04) {
1495 dev_warn(&pdev
->dev
, "Hardware monitor is powered down\n");
1499 if (!(start_reg
& 0x03)) {
1500 dev_warn(&pdev
->dev
, "Hardware monitoring not activated\n");
1505 /* If it is a 71862 and the fan / pwm part is enabled sanity check
1507 if (data
->type
== f71862fg
&& (start_reg
& 0x02)) {
1508 u8 reg
= f71882fg_read8(data
, F71882FG_REG_PWM_ENABLE
);
1509 if ((reg
& 0x15) != 0x15) {
1511 "Invalid (reserved) pwm settings: 0x%02x\n",
1518 /* Register sysfs interface files */
1519 err
= device_create_file(&pdev
->dev
, &dev_attr_name
);
1521 goto exit_unregister_sysfs
;
1523 if (start_reg
& 0x01) {
1524 err
= f71882fg_create_sysfs_files(pdev
, f718x2fg_in_temp_attr
,
1525 ARRAY_SIZE(f718x2fg_in_temp_attr
));
1527 goto exit_unregister_sysfs
;
1529 if (data
->type
== f71882fg
) {
1530 err
= f71882fg_create_sysfs_files(pdev
,
1531 f71882fg_in_temp_attr
,
1532 ARRAY_SIZE(f71882fg_in_temp_attr
));
1534 goto exit_unregister_sysfs
;
1538 if (start_reg
& 0x02) {
1539 err
= f71882fg_create_sysfs_files(pdev
, f718x2fg_fan_attr
,
1540 ARRAY_SIZE(f718x2fg_fan_attr
));
1542 goto exit_unregister_sysfs
;
1544 if (data
->type
== f71862fg
) {
1545 err
= f71882fg_create_sysfs_files(pdev
,
1547 ARRAY_SIZE(f71862fg_fan_attr
));
1549 err
= f71882fg_create_sysfs_files(pdev
,
1551 ARRAY_SIZE(f71882fg_fan_attr
));
1554 goto exit_unregister_sysfs
;
1557 data
->hwmon_dev
= hwmon_device_register(&pdev
->dev
);
1558 if (IS_ERR(data
->hwmon_dev
)) {
1559 err
= PTR_ERR(data
->hwmon_dev
);
1560 data
->hwmon_dev
= NULL
;
1561 goto exit_unregister_sysfs
;
1566 exit_unregister_sysfs
:
1567 f71882fg_remove(pdev
); /* Will unregister the sysfs files for us */
1568 return err
; /* f71882fg_remove() also frees our data */
1574 static int f71882fg_remove(struct platform_device
*pdev
)
1577 struct f71882fg_data
*data
= platform_get_drvdata(pdev
);
1579 platform_set_drvdata(pdev
, NULL
);
1580 if (data
->hwmon_dev
)
1581 hwmon_device_unregister(data
->hwmon_dev
);
1583 device_remove_file(&pdev
->dev
, &dev_attr_name
);
1585 for (i
= 0; i
< ARRAY_SIZE(f718x2fg_in_temp_attr
); i
++)
1586 device_remove_file(&pdev
->dev
,
1587 &f718x2fg_in_temp_attr
[i
].dev_attr
);
1589 for (i
= 0; i
< ARRAY_SIZE(f71882fg_in_temp_attr
); i
++)
1590 device_remove_file(&pdev
->dev
,
1591 &f71882fg_in_temp_attr
[i
].dev_attr
);
1593 for (i
= 0; i
< ARRAY_SIZE(f718x2fg_fan_attr
); i
++)
1594 device_remove_file(&pdev
->dev
, &f718x2fg_fan_attr
[i
].dev_attr
);
1596 for (i
= 0; i
< ARRAY_SIZE(f71862fg_fan_attr
); i
++)
1597 device_remove_file(&pdev
->dev
, &f71862fg_fan_attr
[i
].dev_attr
);
1599 for (i
= 0; i
< ARRAY_SIZE(f71882fg_fan_attr
); i
++)
1600 device_remove_file(&pdev
->dev
, &f71882fg_fan_attr
[i
].dev_attr
);
1607 static int __init
f71882fg_find(int sioaddr
, unsigned short *address
,
1608 struct f71882fg_sio_data
*sio_data
)
1613 superio_enter(sioaddr
);
1615 devid
= superio_inw(sioaddr
, SIO_REG_MANID
);
1616 if (devid
!= SIO_FINTEK_ID
) {
1617 printk(KERN_INFO DRVNAME
": Not a Fintek device\n");
1621 devid
= force_id
? force_id
: superio_inw(sioaddr
, SIO_REG_DEVID
);
1624 sio_data
->type
= f71862fg
;
1627 sio_data
->type
= f71882fg
;
1630 printk(KERN_INFO DRVNAME
": Unsupported Fintek device\n");
1634 superio_select(sioaddr
, SIO_F71882FG_LD_HWM
);
1635 if (!(superio_inb(sioaddr
, SIO_REG_ENABLE
) & 0x01)) {
1636 printk(KERN_WARNING DRVNAME
": Device not activated\n");
1640 *address
= superio_inw(sioaddr
, SIO_REG_ADDR
);
1643 printk(KERN_WARNING DRVNAME
": Base address not set\n");
1646 *address
&= ~(REGION_LENGTH
- 1); /* Ignore 3 LSB */
1649 printk(KERN_INFO DRVNAME
": Found %s chip at %#x, revision %d\n",
1650 f71882fg_names
[sio_data
->type
], (unsigned int)*address
,
1651 (int)superio_inb(sioaddr
, SIO_REG_DEVREV
));
1653 superio_exit(sioaddr
);
1657 static int __init
f71882fg_device_add(unsigned short address
,
1658 const struct f71882fg_sio_data
*sio_data
)
1660 struct resource res
= {
1662 .end
= address
+ REGION_LENGTH
- 1,
1663 .flags
= IORESOURCE_IO
,
1667 f71882fg_pdev
= platform_device_alloc(DRVNAME
, address
);
1671 res
.name
= f71882fg_pdev
->name
;
1672 err
= platform_device_add_resources(f71882fg_pdev
, &res
, 1);
1674 printk(KERN_ERR DRVNAME
": Device resource addition failed\n");
1675 goto exit_device_put
;
1678 err
= platform_device_add_data(f71882fg_pdev
, sio_data
,
1679 sizeof(struct f71882fg_sio_data
));
1681 printk(KERN_ERR DRVNAME
": Platform data allocation failed\n");
1682 goto exit_device_put
;
1685 err
= platform_device_add(f71882fg_pdev
);
1687 printk(KERN_ERR DRVNAME
": Device addition failed\n");
1688 goto exit_device_put
;
1694 platform_device_put(f71882fg_pdev
);
1699 static int __init
f71882fg_init(void)
1702 unsigned short address
;
1703 struct f71882fg_sio_data sio_data
;
1705 memset(&sio_data
, 0, sizeof(sio_data
));
1707 if (f71882fg_find(0x2e, &address
, &sio_data
) &&
1708 f71882fg_find(0x4e, &address
, &sio_data
))
1711 err
= platform_driver_register(&f71882fg_driver
);
1715 err
= f71882fg_device_add(address
, &sio_data
);
1722 platform_driver_unregister(&f71882fg_driver
);
1727 static void __exit
f71882fg_exit(void)
1729 platform_device_unregister(f71882fg_pdev
);
1730 platform_driver_unregister(&f71882fg_driver
);
1733 MODULE_DESCRIPTION("F71882FG Hardware Monitoring Driver");
1734 MODULE_AUTHOR("Hans Edgington, Hans de Goede (hdegoede@redhat.com)");
1735 MODULE_LICENSE("GPL");
1737 module_init(f71882fg_init
);
1738 module_exit(f71882fg_exit
);