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) (0x72 + 2 * (nr))
67 #define F71882FG_REG_TEMP_OVT(nr) (0x82 + 2 * (nr))
68 #define F71882FG_REG_TEMP_HIGH(nr) (0x83 + 2 * (nr))
69 #define F71882FG_REG_TEMP_STATUS 0x62
70 #define F71882FG_REG_TEMP_BEEP 0x63
71 #define F71882FG_REG_TEMP_HYST1 0x6C
72 #define F71882FG_REG_TEMP_HYST23 0x6D
73 #define F71882FG_REG_TEMP_TYPE 0x6B
74 #define F71882FG_REG_TEMP_DIODE_OPEN 0x6F
76 #define F71882FG_REG_PWM(nr) (0xA3 + (16 * (nr)))
77 #define F71882FG_REG_PWM_TYPE 0x94
78 #define F71882FG_REG_PWM_ENABLE 0x96
80 #define F71882FG_REG_FAN_HYST0 0x98
81 #define F71882FG_REG_FAN_HYST1 0x99
83 #define F71882FG_REG_POINT_PWM(pwm, point) (0xAA + (point) + (16 * (pwm)))
84 #define F71882FG_REG_POINT_TEMP(pwm, point) (0xA6 + (point) + (16 * (pwm)))
85 #define F71882FG_REG_POINT_MAPPING(nr) (0xAF + 16 * (nr))
87 #define F71882FG_REG_START 0x01
89 #define FAN_MIN_DETECT 366 /* Lowest detectable fanspeed */
91 static unsigned short force_id
;
92 module_param(force_id
, ushort
, 0);
93 MODULE_PARM_DESC(force_id
, "Override the detected device ID");
95 static int fan_mode
[4] = { 0, 0, 0, 0 };
96 module_param_array(fan_mode
, int, NULL
, 0644);
97 MODULE_PARM_DESC(fan_mode
, "List of fan control modes (f71882fg only) "
98 "(0=don't change, 1=pwm, 2=rpm)\n"
99 "Note: this needs a write to pwm#_enable to take effect");
101 enum chips
{ f71862fg
, f71882fg
};
103 static const char *f71882fg_names
[] = {
108 static struct platform_device
*f71882fg_pdev
;
110 /* Super-I/O Function prototypes */
111 static inline int superio_inb(int base
, int reg
);
112 static inline int superio_inw(int base
, int reg
);
113 static inline void superio_enter(int base
);
114 static inline void superio_select(int base
, int ld
);
115 static inline void superio_exit(int base
);
117 struct f71882fg_sio_data
{
121 struct f71882fg_data
{
124 struct device
*hwmon_dev
;
126 struct mutex update_lock
;
127 char valid
; /* !=0 if following fields are valid */
128 unsigned long last_updated
; /* In jiffies */
129 unsigned long last_limits
; /* In jiffies */
131 /* Register Values */
138 u16 fan_full_speed
[4];
151 u8 pwm_auto_point_hyst
[2];
152 u8 pwm_auto_point_mapping
[4];
153 u8 pwm_auto_point_pwm
[4][5];
154 u8 pwm_auto_point_temp
[4][4];
158 static ssize_t
show_in(struct device
*dev
, struct device_attribute
*devattr
,
160 static ssize_t
show_in_max(struct device
*dev
, struct device_attribute
161 *devattr
, char *buf
);
162 static ssize_t
store_in_max(struct device
*dev
, struct device_attribute
163 *devattr
, const char *buf
, size_t count
);
164 static ssize_t
show_in_beep(struct device
*dev
, struct device_attribute
165 *devattr
, char *buf
);
166 static ssize_t
store_in_beep(struct device
*dev
, struct device_attribute
167 *devattr
, const char *buf
, size_t count
);
168 static ssize_t
show_in_alarm(struct device
*dev
, struct device_attribute
169 *devattr
, char *buf
);
171 static ssize_t
show_fan(struct device
*dev
, struct device_attribute
*devattr
,
173 static ssize_t
show_fan_full_speed(struct device
*dev
,
174 struct device_attribute
*devattr
, char *buf
);
175 static ssize_t
store_fan_full_speed(struct device
*dev
,
176 struct device_attribute
*devattr
, const char *buf
, size_t count
);
177 static ssize_t
show_fan_beep(struct device
*dev
, struct device_attribute
178 *devattr
, char *buf
);
179 static ssize_t
store_fan_beep(struct device
*dev
, struct device_attribute
180 *devattr
, const char *buf
, size_t count
);
181 static ssize_t
show_fan_alarm(struct device
*dev
, struct device_attribute
182 *devattr
, char *buf
);
184 static ssize_t
show_temp(struct device
*dev
, struct device_attribute
185 *devattr
, char *buf
);
186 static ssize_t
show_temp_max(struct device
*dev
, struct device_attribute
187 *devattr
, char *buf
);
188 static ssize_t
store_temp_max(struct device
*dev
, struct device_attribute
189 *devattr
, const char *buf
, size_t count
);
190 static ssize_t
show_temp_max_hyst(struct device
*dev
, struct device_attribute
191 *devattr
, char *buf
);
192 static ssize_t
store_temp_max_hyst(struct device
*dev
, struct device_attribute
193 *devattr
, const char *buf
, size_t count
);
194 static ssize_t
show_temp_crit(struct device
*dev
, struct device_attribute
195 *devattr
, char *buf
);
196 static ssize_t
store_temp_crit(struct device
*dev
, struct device_attribute
197 *devattr
, const char *buf
, size_t count
);
198 static ssize_t
show_temp_crit_hyst(struct device
*dev
, struct device_attribute
199 *devattr
, char *buf
);
200 static ssize_t
show_temp_type(struct device
*dev
, struct device_attribute
201 *devattr
, char *buf
);
202 static ssize_t
show_temp_beep(struct device
*dev
, struct device_attribute
203 *devattr
, char *buf
);
204 static ssize_t
store_temp_beep(struct device
*dev
, struct device_attribute
205 *devattr
, const char *buf
, size_t count
);
206 static ssize_t
show_temp_alarm(struct device
*dev
, struct device_attribute
207 *devattr
, char *buf
);
208 static ssize_t
show_temp_fault(struct device
*dev
, struct device_attribute
209 *devattr
, char *buf
);
210 /* PWM and Auto point control */
211 static ssize_t
show_pwm(struct device
*dev
, struct device_attribute
*devattr
,
213 static ssize_t
store_pwm(struct device
*dev
, struct device_attribute
*devattr
,
214 const char *buf
, size_t count
);
215 static ssize_t
show_pwm_enable(struct device
*dev
,
216 struct device_attribute
*devattr
, char *buf
);
217 static ssize_t
store_pwm_enable(struct device
*dev
,
218 struct device_attribute
*devattr
, const char *buf
, size_t count
);
219 static ssize_t
show_pwm_interpolate(struct device
*dev
,
220 struct device_attribute
*devattr
, char *buf
);
221 static ssize_t
store_pwm_interpolate(struct device
*dev
,
222 struct device_attribute
*devattr
, const char *buf
, size_t count
);
223 static ssize_t
show_pwm_auto_point_channel(struct device
*dev
,
224 struct device_attribute
*devattr
, char *buf
);
225 static ssize_t
store_pwm_auto_point_channel(struct device
*dev
,
226 struct device_attribute
*devattr
, const char *buf
, size_t count
);
227 static ssize_t
show_pwm_auto_point_temp_hyst(struct device
*dev
,
228 struct device_attribute
*devattr
, char *buf
);
229 static ssize_t
store_pwm_auto_point_temp_hyst(struct device
*dev
,
230 struct device_attribute
*devattr
, const char *buf
, size_t count
);
231 static ssize_t
show_pwm_auto_point_pwm(struct device
*dev
,
232 struct device_attribute
*devattr
, char *buf
);
233 static ssize_t
store_pwm_auto_point_pwm(struct device
*dev
,
234 struct device_attribute
*devattr
, const char *buf
, size_t count
);
235 static ssize_t
show_pwm_auto_point_temp(struct device
*dev
,
236 struct device_attribute
*devattr
, char *buf
);
237 static ssize_t
store_pwm_auto_point_temp(struct device
*dev
,
238 struct device_attribute
*devattr
, const char *buf
, size_t count
);
240 static ssize_t
show_name(struct device
*dev
, struct device_attribute
*devattr
,
243 static int __devinit
f71882fg_probe(struct platform_device
* pdev
);
244 static int f71882fg_remove(struct platform_device
*pdev
);
246 static struct platform_driver f71882fg_driver
= {
248 .owner
= THIS_MODULE
,
251 .probe
= f71882fg_probe
,
252 .remove
= __devexit_p(f71882fg_remove
),
255 static DEVICE_ATTR(name
, S_IRUGO
, show_name
, NULL
);
257 static struct sensor_device_attribute_2 f718x2fg_in_temp_attr
[] = {
258 SENSOR_ATTR_2(in0_input
, S_IRUGO
, show_in
, NULL
, 0, 0),
259 SENSOR_ATTR_2(in1_input
, S_IRUGO
, show_in
, NULL
, 0, 1),
260 SENSOR_ATTR_2(in2_input
, S_IRUGO
, show_in
, NULL
, 0, 2),
261 SENSOR_ATTR_2(in3_input
, S_IRUGO
, show_in
, NULL
, 0, 3),
262 SENSOR_ATTR_2(in4_input
, S_IRUGO
, show_in
, NULL
, 0, 4),
263 SENSOR_ATTR_2(in5_input
, S_IRUGO
, show_in
, NULL
, 0, 5),
264 SENSOR_ATTR_2(in6_input
, S_IRUGO
, show_in
, NULL
, 0, 6),
265 SENSOR_ATTR_2(in7_input
, S_IRUGO
, show_in
, NULL
, 0, 7),
266 SENSOR_ATTR_2(in8_input
, S_IRUGO
, show_in
, NULL
, 0, 8),
267 SENSOR_ATTR_2(temp1_input
, S_IRUGO
, show_temp
, NULL
, 0, 0),
268 SENSOR_ATTR_2(temp1_max
, S_IRUGO
|S_IWUSR
, show_temp_max
,
269 store_temp_max
, 0, 0),
270 SENSOR_ATTR_2(temp1_max_hyst
, S_IRUGO
|S_IWUSR
, show_temp_max_hyst
,
271 store_temp_max_hyst
, 0, 0),
272 SENSOR_ATTR_2(temp1_crit
, S_IRUGO
|S_IWUSR
, show_temp_crit
,
273 store_temp_crit
, 0, 0),
274 SENSOR_ATTR_2(temp1_crit_hyst
, S_IRUGO
, show_temp_crit_hyst
, NULL
,
276 SENSOR_ATTR_2(temp1_type
, S_IRUGO
, show_temp_type
, NULL
, 0, 0),
277 SENSOR_ATTR_2(temp1_beep
, S_IRUGO
|S_IWUSR
, show_temp_beep
,
278 store_temp_beep
, 0, 0),
279 SENSOR_ATTR_2(temp1_alarm
, S_IRUGO
, show_temp_alarm
, NULL
, 0, 0),
280 SENSOR_ATTR_2(temp1_fault
, S_IRUGO
, show_temp_fault
, NULL
, 0, 0),
281 SENSOR_ATTR_2(temp2_input
, S_IRUGO
, show_temp
, NULL
, 0, 1),
282 SENSOR_ATTR_2(temp2_max
, S_IRUGO
|S_IWUSR
, show_temp_max
,
283 store_temp_max
, 0, 1),
284 SENSOR_ATTR_2(temp2_max_hyst
, S_IRUGO
|S_IWUSR
, show_temp_max_hyst
,
285 store_temp_max_hyst
, 0, 1),
286 SENSOR_ATTR_2(temp2_crit
, S_IRUGO
|S_IWUSR
, show_temp_crit
,
287 store_temp_crit
, 0, 1),
288 SENSOR_ATTR_2(temp2_crit_hyst
, S_IRUGO
, show_temp_crit_hyst
, NULL
,
290 SENSOR_ATTR_2(temp2_type
, S_IRUGO
, show_temp_type
, NULL
, 0, 1),
291 SENSOR_ATTR_2(temp2_beep
, S_IRUGO
|S_IWUSR
, show_temp_beep
,
292 store_temp_beep
, 0, 1),
293 SENSOR_ATTR_2(temp2_alarm
, S_IRUGO
, show_temp_alarm
, NULL
, 0, 1),
294 SENSOR_ATTR_2(temp2_fault
, S_IRUGO
, show_temp_fault
, NULL
, 0, 1),
295 SENSOR_ATTR_2(temp3_input
, S_IRUGO
, show_temp
, NULL
, 0, 2),
296 SENSOR_ATTR_2(temp3_max
, S_IRUGO
|S_IWUSR
, show_temp_max
,
297 store_temp_max
, 0, 2),
298 SENSOR_ATTR_2(temp3_max_hyst
, S_IRUGO
|S_IWUSR
, show_temp_max_hyst
,
299 store_temp_max_hyst
, 0, 2),
300 SENSOR_ATTR_2(temp3_crit
, S_IRUGO
|S_IWUSR
, show_temp_crit
,
301 store_temp_crit
, 0, 2),
302 SENSOR_ATTR_2(temp3_crit_hyst
, S_IRUGO
, show_temp_crit_hyst
, NULL
,
304 SENSOR_ATTR_2(temp3_type
, S_IRUGO
, show_temp_type
, NULL
, 0, 2),
305 SENSOR_ATTR_2(temp3_beep
, S_IRUGO
|S_IWUSR
, show_temp_beep
,
306 store_temp_beep
, 0, 2),
307 SENSOR_ATTR_2(temp3_alarm
, S_IRUGO
, show_temp_alarm
, NULL
, 0, 2),
308 SENSOR_ATTR_2(temp3_fault
, S_IRUGO
, show_temp_fault
, NULL
, 0, 2),
311 static struct sensor_device_attribute_2 f71882fg_in_temp_attr
[] = {
312 SENSOR_ATTR_2(in1_max
, S_IRUGO
|S_IWUSR
, show_in_max
, store_in_max
,
314 SENSOR_ATTR_2(in1_beep
, S_IRUGO
|S_IWUSR
, show_in_beep
, store_in_beep
,
316 SENSOR_ATTR_2(in1_alarm
, S_IRUGO
, show_in_alarm
, NULL
, 0, 1),
319 static struct sensor_device_attribute_2 f718x2fg_fan_attr
[] = {
320 SENSOR_ATTR_2(fan1_input
, S_IRUGO
, show_fan
, NULL
, 0, 0),
321 SENSOR_ATTR_2(fan1_full_speed
, S_IRUGO
|S_IWUSR
,
323 store_fan_full_speed
, 0, 0),
324 SENSOR_ATTR_2(fan1_beep
, S_IRUGO
|S_IWUSR
, show_fan_beep
,
325 store_fan_beep
, 0, 0),
326 SENSOR_ATTR_2(fan1_alarm
, S_IRUGO
, show_fan_alarm
, NULL
, 0, 0),
327 SENSOR_ATTR_2(fan2_input
, S_IRUGO
, show_fan
, NULL
, 0, 1),
328 SENSOR_ATTR_2(fan2_full_speed
, S_IRUGO
|S_IWUSR
,
330 store_fan_full_speed
, 0, 1),
331 SENSOR_ATTR_2(fan2_beep
, S_IRUGO
|S_IWUSR
, show_fan_beep
,
332 store_fan_beep
, 0, 1),
333 SENSOR_ATTR_2(fan2_alarm
, S_IRUGO
, show_fan_alarm
, NULL
, 0, 1),
334 SENSOR_ATTR_2(fan3_input
, S_IRUGO
, show_fan
, NULL
, 0, 2),
335 SENSOR_ATTR_2(fan3_full_speed
, S_IRUGO
|S_IWUSR
,
337 store_fan_full_speed
, 0, 2),
338 SENSOR_ATTR_2(fan3_beep
, S_IRUGO
|S_IWUSR
, show_fan_beep
,
339 store_fan_beep
, 0, 2),
340 SENSOR_ATTR_2(fan3_alarm
, S_IRUGO
, show_fan_alarm
, NULL
, 0, 2),
342 SENSOR_ATTR_2(pwm1
, S_IRUGO
|S_IWUSR
, show_pwm
, store_pwm
, 0, 0),
343 SENSOR_ATTR_2(pwm1_enable
, S_IRUGO
|S_IWUSR
, show_pwm_enable
,
344 store_pwm_enable
, 0, 0),
345 SENSOR_ATTR_2(pwm1_interpolate
, S_IRUGO
|S_IWUSR
,
346 show_pwm_interpolate
, store_pwm_interpolate
, 0, 0),
347 SENSOR_ATTR_2(pwm1_auto_channels_temp
, S_IRUGO
|S_IWUSR
,
348 show_pwm_auto_point_channel
,
349 store_pwm_auto_point_channel
, 0, 0),
351 SENSOR_ATTR_2(pwm2
, S_IRUGO
|S_IWUSR
, show_pwm
, store_pwm
, 0, 1),
352 SENSOR_ATTR_2(pwm2_enable
, S_IRUGO
|S_IWUSR
, show_pwm_enable
,
353 store_pwm_enable
, 0, 1),
354 SENSOR_ATTR_2(pwm2_interpolate
, S_IRUGO
|S_IWUSR
,
355 show_pwm_interpolate
, store_pwm_interpolate
, 0, 1),
356 SENSOR_ATTR_2(pwm2_auto_channels_temp
, S_IRUGO
|S_IWUSR
,
357 show_pwm_auto_point_channel
,
358 store_pwm_auto_point_channel
, 0, 1),
360 SENSOR_ATTR_2(pwm3
, S_IRUGO
|S_IWUSR
, show_pwm
, store_pwm
, 0, 2),
361 SENSOR_ATTR_2(pwm3_enable
, S_IRUGO
|S_IWUSR
, show_pwm_enable
,
362 store_pwm_enable
, 0, 2),
363 SENSOR_ATTR_2(pwm3_interpolate
, S_IRUGO
|S_IWUSR
,
364 show_pwm_interpolate
, store_pwm_interpolate
, 0, 2),
365 SENSOR_ATTR_2(pwm3_auto_channels_temp
, S_IRUGO
|S_IWUSR
,
366 show_pwm_auto_point_channel
,
367 store_pwm_auto_point_channel
, 0, 2),
370 static struct sensor_device_attribute_2 f71862fg_fan_attr
[] = {
371 SENSOR_ATTR_2(pwm1_auto_point1_pwm
, S_IRUGO
|S_IWUSR
,
372 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
374 SENSOR_ATTR_2(pwm1_auto_point2_pwm
, S_IRUGO
|S_IWUSR
,
375 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
377 SENSOR_ATTR_2(pwm1_auto_point1_temp
, S_IRUGO
|S_IWUSR
,
378 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
380 SENSOR_ATTR_2(pwm1_auto_point2_temp
, S_IRUGO
|S_IWUSR
,
381 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
383 SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst
, S_IRUGO
|S_IWUSR
,
384 show_pwm_auto_point_temp_hyst
,
385 store_pwm_auto_point_temp_hyst
,
387 SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst
, S_IRUGO
,
388 show_pwm_auto_point_temp_hyst
, NULL
, 3, 0),
390 SENSOR_ATTR_2(pwm2_auto_point1_pwm
, S_IRUGO
|S_IWUSR
,
391 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
393 SENSOR_ATTR_2(pwm2_auto_point2_pwm
, S_IRUGO
|S_IWUSR
,
394 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
396 SENSOR_ATTR_2(pwm2_auto_point1_temp
, S_IRUGO
|S_IWUSR
,
397 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
399 SENSOR_ATTR_2(pwm2_auto_point2_temp
, S_IRUGO
|S_IWUSR
,
400 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
402 SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst
, S_IRUGO
|S_IWUSR
,
403 show_pwm_auto_point_temp_hyst
,
404 store_pwm_auto_point_temp_hyst
,
406 SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst
, S_IRUGO
,
407 show_pwm_auto_point_temp_hyst
, NULL
, 3, 1),
410 static struct sensor_device_attribute_2 f71882fg_fan_attr
[] = {
411 SENSOR_ATTR_2(fan4_input
, S_IRUGO
, show_fan
, NULL
, 0, 3),
412 SENSOR_ATTR_2(fan4_full_speed
, S_IRUGO
|S_IWUSR
,
414 store_fan_full_speed
, 0, 3),
415 SENSOR_ATTR_2(fan4_beep
, S_IRUGO
|S_IWUSR
, show_fan_beep
,
416 store_fan_beep
, 0, 3),
417 SENSOR_ATTR_2(fan4_alarm
, S_IRUGO
, show_fan_alarm
, NULL
, 0, 3),
419 SENSOR_ATTR_2(pwm1_auto_point1_pwm
, S_IRUGO
|S_IWUSR
,
420 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
422 SENSOR_ATTR_2(pwm1_auto_point2_pwm
, S_IRUGO
|S_IWUSR
,
423 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
425 SENSOR_ATTR_2(pwm1_auto_point3_pwm
, S_IRUGO
|S_IWUSR
,
426 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
428 SENSOR_ATTR_2(pwm1_auto_point4_pwm
, S_IRUGO
|S_IWUSR
,
429 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
431 SENSOR_ATTR_2(pwm1_auto_point5_pwm
, S_IRUGO
|S_IWUSR
,
432 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
434 SENSOR_ATTR_2(pwm1_auto_point1_temp
, S_IRUGO
|S_IWUSR
,
435 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
437 SENSOR_ATTR_2(pwm1_auto_point2_temp
, S_IRUGO
|S_IWUSR
,
438 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
440 SENSOR_ATTR_2(pwm1_auto_point3_temp
, S_IRUGO
|S_IWUSR
,
441 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
443 SENSOR_ATTR_2(pwm1_auto_point4_temp
, S_IRUGO
|S_IWUSR
,
444 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
446 SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst
, S_IRUGO
|S_IWUSR
,
447 show_pwm_auto_point_temp_hyst
,
448 store_pwm_auto_point_temp_hyst
,
450 SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst
, S_IRUGO
,
451 show_pwm_auto_point_temp_hyst
, NULL
, 1, 0),
452 SENSOR_ATTR_2(pwm1_auto_point3_temp_hyst
, S_IRUGO
,
453 show_pwm_auto_point_temp_hyst
, NULL
, 2, 0),
454 SENSOR_ATTR_2(pwm1_auto_point4_temp_hyst
, S_IRUGO
,
455 show_pwm_auto_point_temp_hyst
, NULL
, 3, 0),
457 SENSOR_ATTR_2(pwm2_auto_point1_pwm
, S_IRUGO
|S_IWUSR
,
458 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
460 SENSOR_ATTR_2(pwm2_auto_point2_pwm
, S_IRUGO
|S_IWUSR
,
461 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
463 SENSOR_ATTR_2(pwm2_auto_point3_pwm
, S_IRUGO
|S_IWUSR
,
464 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
466 SENSOR_ATTR_2(pwm2_auto_point4_pwm
, S_IRUGO
|S_IWUSR
,
467 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
469 SENSOR_ATTR_2(pwm2_auto_point5_pwm
, S_IRUGO
|S_IWUSR
,
470 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
472 SENSOR_ATTR_2(pwm2_auto_point1_temp
, S_IRUGO
|S_IWUSR
,
473 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
475 SENSOR_ATTR_2(pwm2_auto_point2_temp
, S_IRUGO
|S_IWUSR
,
476 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
478 SENSOR_ATTR_2(pwm2_auto_point3_temp
, S_IRUGO
|S_IWUSR
,
479 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
481 SENSOR_ATTR_2(pwm2_auto_point4_temp
, S_IRUGO
|S_IWUSR
,
482 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
484 SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst
, S_IRUGO
|S_IWUSR
,
485 show_pwm_auto_point_temp_hyst
,
486 store_pwm_auto_point_temp_hyst
,
488 SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst
, S_IRUGO
,
489 show_pwm_auto_point_temp_hyst
, NULL
, 1, 1),
490 SENSOR_ATTR_2(pwm2_auto_point3_temp_hyst
, S_IRUGO
,
491 show_pwm_auto_point_temp_hyst
, NULL
, 2, 1),
492 SENSOR_ATTR_2(pwm2_auto_point4_temp_hyst
, S_IRUGO
,
493 show_pwm_auto_point_temp_hyst
, NULL
, 3, 1),
495 SENSOR_ATTR_2(pwm3_auto_point1_pwm
, S_IRUGO
|S_IWUSR
,
496 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
498 SENSOR_ATTR_2(pwm3_auto_point2_pwm
, S_IRUGO
|S_IWUSR
,
499 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
501 SENSOR_ATTR_2(pwm3_auto_point3_pwm
, S_IRUGO
|S_IWUSR
,
502 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
504 SENSOR_ATTR_2(pwm3_auto_point4_pwm
, S_IRUGO
|S_IWUSR
,
505 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
507 SENSOR_ATTR_2(pwm3_auto_point5_pwm
, S_IRUGO
|S_IWUSR
,
508 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
510 SENSOR_ATTR_2(pwm3_auto_point1_temp
, S_IRUGO
|S_IWUSR
,
511 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
513 SENSOR_ATTR_2(pwm3_auto_point2_temp
, S_IRUGO
|S_IWUSR
,
514 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
516 SENSOR_ATTR_2(pwm3_auto_point3_temp
, S_IRUGO
|S_IWUSR
,
517 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
519 SENSOR_ATTR_2(pwm3_auto_point4_temp
, S_IRUGO
|S_IWUSR
,
520 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
522 SENSOR_ATTR_2(pwm3_auto_point1_temp_hyst
, S_IRUGO
|S_IWUSR
,
523 show_pwm_auto_point_temp_hyst
,
524 store_pwm_auto_point_temp_hyst
,
526 SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst
, S_IRUGO
,
527 show_pwm_auto_point_temp_hyst
, NULL
, 1, 2),
528 SENSOR_ATTR_2(pwm3_auto_point3_temp_hyst
, S_IRUGO
,
529 show_pwm_auto_point_temp_hyst
, NULL
, 2, 2),
530 SENSOR_ATTR_2(pwm3_auto_point4_temp_hyst
, S_IRUGO
,
531 show_pwm_auto_point_temp_hyst
, NULL
, 3, 2),
533 SENSOR_ATTR_2(pwm4
, S_IRUGO
|S_IWUSR
, show_pwm
, store_pwm
, 0, 3),
534 SENSOR_ATTR_2(pwm4_enable
, S_IRUGO
|S_IWUSR
, show_pwm_enable
,
535 store_pwm_enable
, 0, 3),
536 SENSOR_ATTR_2(pwm4_interpolate
, S_IRUGO
|S_IWUSR
,
537 show_pwm_interpolate
, store_pwm_interpolate
, 0, 3),
538 SENSOR_ATTR_2(pwm4_auto_channels_temp
, S_IRUGO
|S_IWUSR
,
539 show_pwm_auto_point_channel
,
540 store_pwm_auto_point_channel
, 0, 3),
541 SENSOR_ATTR_2(pwm4_auto_point1_pwm
, S_IRUGO
|S_IWUSR
,
542 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
544 SENSOR_ATTR_2(pwm4_auto_point2_pwm
, S_IRUGO
|S_IWUSR
,
545 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
547 SENSOR_ATTR_2(pwm4_auto_point3_pwm
, S_IRUGO
|S_IWUSR
,
548 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
550 SENSOR_ATTR_2(pwm4_auto_point4_pwm
, S_IRUGO
|S_IWUSR
,
551 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
553 SENSOR_ATTR_2(pwm4_auto_point5_pwm
, S_IRUGO
|S_IWUSR
,
554 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
556 SENSOR_ATTR_2(pwm4_auto_point1_temp
, S_IRUGO
|S_IWUSR
,
557 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
559 SENSOR_ATTR_2(pwm4_auto_point2_temp
, S_IRUGO
|S_IWUSR
,
560 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
562 SENSOR_ATTR_2(pwm4_auto_point3_temp
, S_IRUGO
|S_IWUSR
,
563 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
565 SENSOR_ATTR_2(pwm4_auto_point4_temp
, S_IRUGO
|S_IWUSR
,
566 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
568 SENSOR_ATTR_2(pwm4_auto_point1_temp_hyst
, S_IRUGO
|S_IWUSR
,
569 show_pwm_auto_point_temp_hyst
,
570 store_pwm_auto_point_temp_hyst
,
572 SENSOR_ATTR_2(pwm4_auto_point2_temp_hyst
, S_IRUGO
,
573 show_pwm_auto_point_temp_hyst
, NULL
, 1, 3),
574 SENSOR_ATTR_2(pwm4_auto_point3_temp_hyst
, S_IRUGO
,
575 show_pwm_auto_point_temp_hyst
, NULL
, 2, 3),
576 SENSOR_ATTR_2(pwm4_auto_point4_temp_hyst
, S_IRUGO
,
577 show_pwm_auto_point_temp_hyst
, NULL
, 3, 3),
581 /* Super I/O functions */
582 static inline int superio_inb(int base
, int reg
)
585 return inb(base
+ 1);
588 static int superio_inw(int base
, int reg
)
592 val
= inb(base
+ 1) << 8;
594 val
|= inb(base
+ 1);
598 static inline void superio_enter(int base
)
600 /* according to the datasheet the key must be send twice! */
601 outb( SIO_UNLOCK_KEY
, base
);
602 outb( SIO_UNLOCK_KEY
, base
);
605 static inline void superio_select( int base
, int ld
)
607 outb(SIO_REG_LDSEL
, base
);
611 static inline void superio_exit(int base
)
613 outb(SIO_LOCK_KEY
, base
);
616 static inline u16
fan_from_reg(u16 reg
)
618 return reg
? (1500000 / reg
) : 0;
621 static inline u16
fan_to_reg(u16 fan
)
623 return fan
? (1500000 / fan
) : 0;
626 static u8
f71882fg_read8(struct f71882fg_data
*data
, u8 reg
)
630 outb(reg
, data
->addr
+ ADDR_REG_OFFSET
);
631 val
= inb(data
->addr
+ DATA_REG_OFFSET
);
636 static u16
f71882fg_read16(struct f71882fg_data
*data
, u8 reg
)
640 outb(reg
++, data
->addr
+ ADDR_REG_OFFSET
);
641 val
= inb(data
->addr
+ DATA_REG_OFFSET
) << 8;
642 outb(reg
, data
->addr
+ ADDR_REG_OFFSET
);
643 val
|= inb(data
->addr
+ DATA_REG_OFFSET
);
648 static void f71882fg_write8(struct f71882fg_data
*data
, u8 reg
, u8 val
)
650 outb(reg
, data
->addr
+ ADDR_REG_OFFSET
);
651 outb(val
, data
->addr
+ DATA_REG_OFFSET
);
654 static void f71882fg_write16(struct f71882fg_data
*data
, u8 reg
, u16 val
)
656 outb(reg
++, data
->addr
+ ADDR_REG_OFFSET
);
657 outb(val
>> 8, data
->addr
+ DATA_REG_OFFSET
);
658 outb(reg
, data
->addr
+ ADDR_REG_OFFSET
);
659 outb(val
& 255, data
->addr
+ DATA_REG_OFFSET
);
662 static struct f71882fg_data
*f71882fg_update_device(struct device
*dev
)
664 struct f71882fg_data
*data
= dev_get_drvdata(dev
);
666 int nr_fans
= (data
->type
== f71862fg
) ? 3 : 4;
668 mutex_lock(&data
->update_lock
);
670 /* Update once every 60 seconds */
671 if ( time_after(jiffies
, data
->last_limits
+ 60 * HZ
) ||
673 if (data
->type
== f71882fg
) {
675 f71882fg_read8(data
, F71882FG_REG_IN1_HIGH
);
677 f71882fg_read8(data
, F71882FG_REG_IN_BEEP
);
680 /* Get High & boundary temps*/
681 for (nr
= 0; nr
< 3; nr
++) {
682 data
->temp_ovt
[nr
] = f71882fg_read8(data
,
683 F71882FG_REG_TEMP_OVT(nr
));
684 data
->temp_high
[nr
] = f71882fg_read8(data
,
685 F71882FG_REG_TEMP_HIGH(nr
));
688 /* Have to hardcode hyst*/
689 data
->temp_hyst
[0] = f71882fg_read8(data
,
690 F71882FG_REG_TEMP_HYST1
) >> 4;
691 /* Hyst temps 2 & 3 stored in same register */
692 reg
= f71882fg_read8(data
, F71882FG_REG_TEMP_HYST23
);
693 data
->temp_hyst
[1] = reg
& 0x0F;
694 data
->temp_hyst
[2] = reg
>> 4;
696 /* Have to hardcode type, because temp1 is special */
697 reg
= f71882fg_read8(data
, F71882FG_REG_TEMP_TYPE
);
698 reg2
= f71882fg_read8(data
, F71882FG_REG_PECI
);
699 if ((reg2
& 0x03) == 0x01)
700 data
->temp_type
[0] = 6 /* PECI */;
701 else if ((reg2
& 0x03) == 0x02)
702 data
->temp_type
[0] = 5 /* AMDSI */;
704 data
->temp_type
[0] = (reg
& 0x02) ? 2 : 4;
706 data
->temp_type
[1] = (reg
& 0x04) ? 2 : 4;
707 data
->temp_type
[2] = (reg
& 0x08) ? 2 : 4;
709 data
->temp_beep
= f71882fg_read8(data
, F71882FG_REG_TEMP_BEEP
);
711 data
->fan_beep
= f71882fg_read8(data
, F71882FG_REG_FAN_BEEP
);
713 data
->pwm_enable
= f71882fg_read8(data
,
714 F71882FG_REG_PWM_ENABLE
);
715 data
->pwm_auto_point_hyst
[0] = f71882fg_read8(data
,
716 F71882FG_REG_FAN_HYST0
);
717 data
->pwm_auto_point_hyst
[1] = f71882fg_read8(data
,
718 F71882FG_REG_FAN_HYST1
);
719 for (nr
= 0; nr
< nr_fans
; nr
++) {
720 data
->pwm_auto_point_mapping
[nr
] =
722 F71882FG_REG_POINT_MAPPING(nr
));
724 if (data
->type
== f71882fg
) {
726 for (point
= 0; point
< 5; point
++) {
727 data
->pwm_auto_point_pwm
[nr
][point
] =
729 F71882FG_REG_POINT_PWM
732 for (point
= 0; point
< 4; point
++) {
733 data
->pwm_auto_point_temp
[nr
][point
] =
735 F71882FG_REG_POINT_TEMP
739 data
->pwm_auto_point_pwm
[nr
][1] =
741 F71882FG_REG_POINT_PWM
743 data
->pwm_auto_point_pwm
[nr
][4] =
745 F71882FG_REG_POINT_PWM
747 data
->pwm_auto_point_temp
[nr
][0] =
749 F71882FG_REG_POINT_TEMP
751 data
->pwm_auto_point_temp
[nr
][3] =
753 F71882FG_REG_POINT_TEMP
757 data
->last_limits
= jiffies
;
760 /* Update every second */
761 if (time_after(jiffies
, data
->last_updated
+ HZ
) || !data
->valid
) {
762 data
->temp_status
= f71882fg_read8(data
,
763 F71882FG_REG_TEMP_STATUS
);
764 data
->temp_diode_open
= f71882fg_read8(data
,
765 F71882FG_REG_TEMP_DIODE_OPEN
);
766 for (nr
= 0; nr
< 3; nr
++)
767 data
->temp
[nr
] = f71882fg_read8(data
,
768 F71882FG_REG_TEMP(nr
));
770 data
->fan_status
= f71882fg_read8(data
,
771 F71882FG_REG_FAN_STATUS
);
772 for (nr
= 0; nr
< nr_fans
; nr
++) {
773 data
->fan
[nr
] = f71882fg_read16(data
,
774 F71882FG_REG_FAN(nr
));
775 data
->fan_target
[nr
] =
776 f71882fg_read16(data
, F71882FG_REG_FAN_TARGET(nr
));
777 data
->fan_full_speed
[nr
] =
778 f71882fg_read16(data
,
779 F71882FG_REG_FAN_FULL_SPEED(nr
));
781 f71882fg_read8(data
, F71882FG_REG_PWM(nr
));
784 if (data
->type
== f71882fg
)
785 data
->in_status
= f71882fg_read8(data
,
786 F71882FG_REG_IN_STATUS
);
787 for (nr
= 0; nr
< 9; nr
++)
788 data
->in
[nr
] = f71882fg_read8(data
,
789 F71882FG_REG_IN(nr
));
791 data
->last_updated
= jiffies
;
795 mutex_unlock(&data
->update_lock
);
800 /* Sysfs Interface */
801 static ssize_t
show_fan(struct device
*dev
, struct device_attribute
*devattr
,
804 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
805 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
806 int speed
= fan_from_reg(data
->fan
[nr
]);
808 if (speed
== FAN_MIN_DETECT
)
811 return sprintf(buf
, "%d\n", speed
);
814 static ssize_t
show_fan_full_speed(struct device
*dev
,
815 struct device_attribute
*devattr
, char *buf
)
817 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
818 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
819 int speed
= fan_from_reg(data
->fan_full_speed
[nr
]);
820 return sprintf(buf
, "%d\n", speed
);
823 static ssize_t
store_fan_full_speed(struct device
*dev
,
824 struct device_attribute
*devattr
,
825 const char *buf
, size_t count
)
827 struct f71882fg_data
*data
= dev_get_drvdata(dev
);
828 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
829 long val
= simple_strtol(buf
, NULL
, 10);
831 val
= SENSORS_LIMIT(val
, 23, 1500000);
832 val
= fan_to_reg(val
);
834 mutex_lock(&data
->update_lock
);
835 if (data
->pwm_enable
& (1 << (2 * nr
)))
840 f71882fg_write16(data
, F71882FG_REG_FAN_FULL_SPEED(nr
), val
);
841 data
->fan_full_speed
[nr
] = val
;
843 mutex_unlock(&data
->update_lock
);
848 static ssize_t
show_fan_beep(struct device
*dev
, struct device_attribute
851 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
852 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
854 if (data
->fan_beep
& (1 << nr
))
855 return sprintf(buf
, "1\n");
857 return sprintf(buf
, "0\n");
860 static ssize_t
store_fan_beep(struct device
*dev
, struct device_attribute
861 *devattr
, const char *buf
, size_t count
)
863 struct f71882fg_data
*data
= dev_get_drvdata(dev
);
864 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
865 int val
= simple_strtoul(buf
, NULL
, 10);
867 mutex_lock(&data
->update_lock
);
869 data
->fan_beep
|= 1 << nr
;
871 data
->fan_beep
&= ~(1 << nr
);
873 f71882fg_write8(data
, F71882FG_REG_FAN_BEEP
, data
->fan_beep
);
874 mutex_unlock(&data
->update_lock
);
879 static ssize_t
show_fan_alarm(struct device
*dev
, struct device_attribute
882 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
883 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
885 if (data
->fan_status
& (1 << nr
))
886 return sprintf(buf
, "1\n");
888 return sprintf(buf
, "0\n");
891 static ssize_t
show_in(struct device
*dev
, struct device_attribute
*devattr
,
894 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
895 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
897 return sprintf(buf
, "%d\n", data
->in
[nr
] * 8);
900 static ssize_t
show_in_max(struct device
*dev
, struct device_attribute
903 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
905 return sprintf(buf
, "%d\n", data
->in1_max
* 8);
908 static ssize_t
store_in_max(struct device
*dev
, struct device_attribute
909 *devattr
, const char *buf
, size_t count
)
911 struct f71882fg_data
*data
= dev_get_drvdata(dev
);
912 int val
= simple_strtoul(buf
, NULL
, 10) / 8;
917 mutex_lock(&data
->update_lock
);
918 f71882fg_write8(data
, F71882FG_REG_IN1_HIGH
, val
);
920 mutex_unlock(&data
->update_lock
);
925 static ssize_t
show_in_beep(struct device
*dev
, struct device_attribute
928 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
929 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
931 if (data
->in_beep
& (1 << nr
))
932 return sprintf(buf
, "1\n");
934 return sprintf(buf
, "0\n");
937 static ssize_t
store_in_beep(struct device
*dev
, struct device_attribute
938 *devattr
, const char *buf
, size_t count
)
940 struct f71882fg_data
*data
= dev_get_drvdata(dev
);
941 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
942 int val
= simple_strtoul(buf
, NULL
, 10);
944 mutex_lock(&data
->update_lock
);
946 data
->in_beep
|= 1 << nr
;
948 data
->in_beep
&= ~(1 << nr
);
950 f71882fg_write8(data
, F71882FG_REG_IN_BEEP
, data
->in_beep
);
951 mutex_unlock(&data
->update_lock
);
956 static ssize_t
show_in_alarm(struct device
*dev
, struct device_attribute
959 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
960 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
962 if (data
->in_status
& (1 << nr
))
963 return sprintf(buf
, "1\n");
965 return sprintf(buf
, "0\n");
968 static ssize_t
show_temp(struct device
*dev
, struct device_attribute
*devattr
,
971 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
972 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
974 return sprintf(buf
, "%d\n", data
->temp
[nr
] * 1000);
977 static ssize_t
show_temp_max(struct device
*dev
, struct device_attribute
980 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
981 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
983 return sprintf(buf
, "%d\n", data
->temp_high
[nr
] * 1000);
986 static ssize_t
store_temp_max(struct device
*dev
, struct device_attribute
987 *devattr
, const char *buf
, size_t count
)
989 struct f71882fg_data
*data
= dev_get_drvdata(dev
);
990 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
991 int val
= simple_strtoul(buf
, NULL
, 10) / 1000;
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
;
1010 return sprintf(buf
, "%d\n",
1011 (data
->temp_high
[nr
] - data
->temp_hyst
[nr
]) * 1000);
1014 static ssize_t
store_temp_max_hyst(struct device
*dev
, struct device_attribute
1015 *devattr
, const char *buf
, size_t count
)
1017 struct f71882fg_data
*data
= dev_get_drvdata(dev
);
1018 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1019 int val
= simple_strtoul(buf
, NULL
, 10) / 1000;
1020 ssize_t ret
= count
;
1022 mutex_lock(&data
->update_lock
);
1024 /* convert abs to relative and check */
1025 val
= data
->temp_high
[nr
] - val
;
1026 if (val
< 0 || val
> 15) {
1028 goto store_temp_max_hyst_exit
;
1031 data
->temp_hyst
[nr
] = val
;
1033 /* convert value to register contents */
1039 val
= val
| (data
->temp_hyst
[2] << 4);
1042 val
= data
->temp_hyst
[1] | (val
<< 4);
1046 f71882fg_write8(data
, nr
? F71882FG_REG_TEMP_HYST23
:
1047 F71882FG_REG_TEMP_HYST1
, val
);
1049 store_temp_max_hyst_exit
:
1050 mutex_unlock(&data
->update_lock
);
1054 static ssize_t
show_temp_crit(struct device
*dev
, struct device_attribute
1055 *devattr
, char *buf
)
1057 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1058 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1060 return sprintf(buf
, "%d\n", data
->temp_ovt
[nr
] * 1000);
1063 static ssize_t
store_temp_crit(struct device
*dev
, struct device_attribute
1064 *devattr
, const char *buf
, size_t count
)
1066 struct f71882fg_data
*data
= dev_get_drvdata(dev
);
1067 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1068 int val
= simple_strtoul(buf
, NULL
, 10) / 1000;
1073 mutex_lock(&data
->update_lock
);
1074 f71882fg_write8(data
, F71882FG_REG_TEMP_OVT(nr
), val
);
1075 data
->temp_ovt
[nr
] = val
;
1076 mutex_unlock(&data
->update_lock
);
1081 static ssize_t
show_temp_crit_hyst(struct device
*dev
, struct device_attribute
1082 *devattr
, char *buf
)
1084 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1085 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1087 return sprintf(buf
, "%d\n",
1088 (data
->temp_ovt
[nr
] - data
->temp_hyst
[nr
]) * 1000);
1091 static ssize_t
show_temp_type(struct device
*dev
, struct device_attribute
1092 *devattr
, char *buf
)
1094 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1095 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1097 return sprintf(buf
, "%d\n", data
->temp_type
[nr
]);
1100 static ssize_t
show_temp_beep(struct device
*dev
, struct device_attribute
1101 *devattr
, char *buf
)
1103 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1104 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1106 if (data
->temp_beep
& (1 << (nr
+ 1)))
1107 return sprintf(buf
, "1\n");
1109 return sprintf(buf
, "0\n");
1112 static ssize_t
store_temp_beep(struct device
*dev
, struct device_attribute
1113 *devattr
, const char *buf
, size_t count
)
1115 struct f71882fg_data
*data
= dev_get_drvdata(dev
);
1116 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1117 int val
= simple_strtoul(buf
, NULL
, 10);
1119 mutex_lock(&data
->update_lock
);
1121 data
->temp_beep
|= 1 << (nr
+ 1);
1123 data
->temp_beep
&= ~(1 << (nr
+ 1));
1125 f71882fg_write8(data
, F71882FG_REG_TEMP_BEEP
, data
->temp_beep
);
1126 mutex_unlock(&data
->update_lock
);
1131 static ssize_t
show_temp_alarm(struct device
*dev
, struct device_attribute
1132 *devattr
, char *buf
)
1134 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1135 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1137 if (data
->temp_status
& (1 << (nr
+ 1)))
1138 return sprintf(buf
, "1\n");
1140 return sprintf(buf
, "0\n");
1143 static ssize_t
show_temp_fault(struct device
*dev
, struct device_attribute
1144 *devattr
, char *buf
)
1146 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1147 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1149 if (data
->temp_diode_open
& (1 << (nr
+ 1)))
1150 return sprintf(buf
, "1\n");
1152 return sprintf(buf
, "0\n");
1155 static ssize_t
show_pwm(struct device
*dev
,
1156 struct device_attribute
*devattr
, char *buf
)
1158 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1159 int val
, nr
= to_sensor_dev_attr_2(devattr
)->index
;
1160 if (data
->pwm_enable
& (1 << (2 * nr
)))
1162 val
= data
->pwm
[nr
];
1165 mutex_lock(&data
->update_lock
);
1166 val
= 255 * fan_from_reg(data
->fan_target
[nr
])
1167 / fan_from_reg(data
->fan_full_speed
[nr
]);
1168 mutex_unlock(&data
->update_lock
);
1170 return sprintf(buf
, "%d\n", val
);
1173 static ssize_t
store_pwm(struct device
*dev
,
1174 struct device_attribute
*devattr
, const char *buf
,
1177 /* struct f71882fg_data *data = dev_get_drvdata(dev); */
1178 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1179 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1180 long val
= simple_strtol(buf
, NULL
, 10);
1181 val
= SENSORS_LIMIT(val
, 0, 255);
1183 mutex_lock(&data
->update_lock
);
1184 if (data
->pwm_enable
& (1 << (2 * nr
))) {
1186 f71882fg_write8(data
, F71882FG_REG_PWM(nr
), val
);
1187 data
->pwm
[nr
] = val
;
1190 int target
= val
* fan_from_reg(data
->fan_full_speed
[nr
]) / 255;
1191 f71882fg_write16(data
, F71882FG_REG_FAN_TARGET(nr
),
1192 fan_to_reg(target
));
1193 data
->fan_target
[nr
] = fan_to_reg(target
);
1195 mutex_unlock(&data
->update_lock
);
1200 static ssize_t
show_pwm_enable(struct device
*dev
,
1201 struct device_attribute
*devattr
, char *buf
)
1204 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1205 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1207 if (data
->pwm_enable
& (2 << (2 * nr
)))
1212 return sprintf(buf
, "%d\n", result
);
1215 static ssize_t
store_pwm_enable(struct device
*dev
, struct device_attribute
1216 *devattr
, const char *buf
, size_t count
)
1218 struct f71882fg_data
*data
= dev_get_drvdata(dev
);
1219 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1220 long val
= simple_strtol(buf
, NULL
, 10);
1221 if (val
< 1 || val
> 2)
1224 mutex_lock(&data
->update_lock
);
1227 data
->pwm_enable
|= 2 << (2 * nr
);
1230 data
->pwm_enable
&= ~(2 << (2 * nr
));
1231 break; /* Temperature ctrl */
1233 if (data
->type
== f71882fg
) {
1234 switch (fan_mode
[nr
]) {
1236 data
->pwm_enable
|= 1 << (2 * nr
);
1237 break; /* Duty cycle mode */
1239 data
->pwm_enable
&= ~(1 << (2 * nr
));
1240 break; /* RPM mode */
1243 f71882fg_write8(data
, F71882FG_REG_PWM_ENABLE
, data
->pwm_enable
);
1244 mutex_unlock(&data
->update_lock
);
1249 static ssize_t
show_pwm_auto_point_pwm(struct device
*dev
,
1250 struct device_attribute
*devattr
,
1254 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1255 int pwm
= to_sensor_dev_attr_2(devattr
)->index
;
1256 int point
= to_sensor_dev_attr_2(devattr
)->nr
;
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
]);
1266 return sprintf(buf
, "%d\n", result
);
1269 static ssize_t
store_pwm_auto_point_pwm(struct device
*dev
,
1270 struct device_attribute
*devattr
,
1271 const char *buf
, size_t count
)
1273 /* struct f71882fg_data *data = dev_get_drvdata(dev); */
1274 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1275 int pwm
= to_sensor_dev_attr_2(devattr
)->index
;
1276 int point
= to_sensor_dev_attr_2(devattr
)->nr
;
1277 int val
= simple_strtoul(buf
, NULL
, 10);
1278 val
= SENSORS_LIMIT(val
, 0, 255);
1280 mutex_lock(&data
->update_lock
);
1281 if (data
->pwm_enable
& (1 << (2 * pwm
))) {
1285 if (val
< 29) /* Prevent negative numbers */
1288 val
= (255 - val
) * 32 / val
;
1290 f71882fg_write8(data
, F71882FG_REG_POINT_PWM(pwm
, point
), val
);
1291 data
->pwm_auto_point_pwm
[pwm
][point
] = val
;
1292 mutex_unlock(&data
->update_lock
);
1297 static ssize_t
show_pwm_auto_point_temp_hyst(struct device
*dev
,
1298 struct device_attribute
*devattr
,
1302 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1303 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1304 int point
= to_sensor_dev_attr_2(devattr
)->nr
;
1306 mutex_lock(&data
->update_lock
);
1309 result
= data
->pwm_auto_point_hyst
[0] & 0x0f;
1312 result
= data
->pwm_auto_point_hyst
[0] >> 4;
1315 result
= data
->pwm_auto_point_hyst
[1] & 0x0f;
1318 result
= data
->pwm_auto_point_hyst
[1] >> 4;
1321 result
= 1000 * (data
->pwm_auto_point_temp
[nr
][point
] - result
);
1322 mutex_unlock(&data
->update_lock
);
1324 return sprintf(buf
, "%d\n", result
);
1327 static ssize_t
store_pwm_auto_point_temp_hyst(struct device
*dev
,
1328 struct device_attribute
*devattr
,
1329 const char *buf
, size_t count
)
1331 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1332 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1333 int point
= to_sensor_dev_attr_2(devattr
)->nr
;
1334 long val
= simple_strtol(buf
, NULL
, 10) / 1000;
1336 mutex_lock(&data
->update_lock
);
1337 val
= SENSORS_LIMIT(val
, data
->pwm_auto_point_temp
[nr
][point
] - 15,
1338 data
->pwm_auto_point_temp
[nr
][point
]);
1339 val
= data
->pwm_auto_point_temp
[nr
][point
] - val
;
1343 val
= (data
->pwm_auto_point_hyst
[0] & 0xf0) | val
;
1346 val
= (data
->pwm_auto_point_hyst
[0] & 0x0f) | (val
<< 4);
1349 val
= (data
->pwm_auto_point_hyst
[1] & 0xf0) | val
;
1352 val
= (data
->pwm_auto_point_hyst
[1] & 0x0f) | (val
<< 4);
1355 if (nr
== 0 || nr
== 1) {
1356 f71882fg_write8(data
, F71882FG_REG_FAN_HYST0
, val
);
1357 data
->pwm_auto_point_hyst
[0] = val
;
1359 f71882fg_write8(data
, F71882FG_REG_FAN_HYST1
, val
);
1360 data
->pwm_auto_point_hyst
[1] = val
;
1362 mutex_unlock(&data
->update_lock
);
1367 static ssize_t
show_pwm_interpolate(struct device
*dev
,
1368 struct device_attribute
*devattr
, char *buf
)
1371 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1372 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1374 result
= (data
->pwm_auto_point_mapping
[nr
] >> 4) & 1;
1376 return sprintf(buf
, "%d\n", result
);
1379 static ssize_t
store_pwm_interpolate(struct device
*dev
,
1380 struct device_attribute
*devattr
,
1381 const char *buf
, size_t count
)
1383 /* struct f71882fg_data *data = dev_get_drvdata(dev); */
1384 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1385 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1386 int val
= simple_strtoul(buf
, NULL
, 10);
1387 mutex_lock(&data
->update_lock
);
1389 val
= data
->pwm_auto_point_mapping
[nr
] | (1 << 4);
1391 val
= data
->pwm_auto_point_mapping
[nr
] & (~(1 << 4));
1392 f71882fg_write8(data
, F71882FG_REG_POINT_MAPPING(nr
), val
);
1393 data
->pwm_auto_point_mapping
[nr
] = val
;
1394 mutex_unlock(&data
->update_lock
);
1399 static ssize_t
show_pwm_auto_point_channel(struct device
*dev
,
1400 struct device_attribute
*devattr
,
1404 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1405 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1407 result
= 1 << ((data
->pwm_auto_point_mapping
[nr
] & 3) - 1);
1409 return sprintf(buf
, "%d\n", result
);
1412 static ssize_t
store_pwm_auto_point_channel(struct device
*dev
,
1413 struct device_attribute
*devattr
,
1414 const char *buf
, size_t count
)
1416 /* struct f71882fg_data *data = dev_get_drvdata(dev); */
1417 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1418 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1419 long val
= simple_strtol(buf
, NULL
, 10);
1433 mutex_lock(&data
->update_lock
);
1434 val
= (data
->pwm_auto_point_mapping
[nr
] & 0xfc) | val
;
1435 f71882fg_write8(data
, F71882FG_REG_POINT_MAPPING(nr
), val
);
1436 data
->pwm_auto_point_mapping
[nr
] = val
;
1437 mutex_unlock(&data
->update_lock
);
1442 static ssize_t
show_pwm_auto_point_temp(struct device
*dev
,
1443 struct device_attribute
*devattr
,
1447 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1448 int pwm
= to_sensor_dev_attr_2(devattr
)->index
;
1449 int point
= to_sensor_dev_attr_2(devattr
)->nr
;
1451 result
= data
->pwm_auto_point_temp
[pwm
][point
];
1452 return sprintf(buf
, "%d\n", 1000 * result
);
1455 static ssize_t
store_pwm_auto_point_temp(struct device
*dev
,
1456 struct device_attribute
*devattr
,
1457 const char *buf
, size_t count
)
1459 /* struct f71882fg_data *data = dev_get_drvdata(dev); */
1460 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1461 int pwm
= to_sensor_dev_attr_2(devattr
)->index
;
1462 int point
= to_sensor_dev_attr_2(devattr
)->nr
;
1463 long val
= simple_strtol(buf
, NULL
, 10) / 1000;
1464 val
= SENSORS_LIMIT(val
, 0, 255);
1466 mutex_lock(&data
->update_lock
);
1467 f71882fg_write8(data
, F71882FG_REG_POINT_TEMP(pwm
, point
), val
);
1468 data
->pwm_auto_point_temp
[pwm
][point
] = val
;
1469 mutex_unlock(&data
->update_lock
);
1474 static ssize_t
show_name(struct device
*dev
, struct device_attribute
*devattr
,
1477 struct f71882fg_data
*data
= dev_get_drvdata(dev
);
1478 return sprintf(buf
, "%s\n", f71882fg_names
[data
->type
]);
1481 static int __devinit
f71882fg_create_sysfs_files(struct platform_device
*pdev
,
1482 struct sensor_device_attribute_2
*attr
, int count
)
1486 for (i
= 0; i
< count
; i
++) {
1487 err
= device_create_file(&pdev
->dev
, &attr
[i
].dev_attr
);
1494 static int __devinit
f71882fg_probe(struct platform_device
*pdev
)
1496 struct f71882fg_data
*data
;
1497 struct f71882fg_sio_data
*sio_data
= pdev
->dev
.platform_data
;
1501 data
= kzalloc(sizeof(struct f71882fg_data
), GFP_KERNEL
);
1505 data
->addr
= platform_get_resource(pdev
, IORESOURCE_IO
, 0)->start
;
1506 data
->type
= sio_data
->type
;
1507 mutex_init(&data
->update_lock
);
1508 platform_set_drvdata(pdev
, data
);
1510 start_reg
= f71882fg_read8(data
, F71882FG_REG_START
);
1511 if (!(start_reg
& 0x03)) {
1512 dev_warn(&pdev
->dev
, "Hardware monitoring not activated\n");
1517 /* If it is a 71862 and the fan / pwm part is enabled sanity check
1519 if (data
->type
== f71862fg
&& (start_reg
& 0x02)) {
1520 u8 reg
= f71882fg_read8(data
, F71882FG_REG_PWM_ENABLE
);
1521 if ((reg
& 0x15) != 0x15) {
1523 "Invalid (reserved) pwm settings: 0x%02x\n",
1530 /* Register sysfs interface files */
1531 err
= device_create_file(&pdev
->dev
, &dev_attr_name
);
1533 goto exit_unregister_sysfs
;
1535 if (start_reg
& 0x01) {
1536 err
= f71882fg_create_sysfs_files(pdev
, f718x2fg_in_temp_attr
,
1537 ARRAY_SIZE(f718x2fg_in_temp_attr
));
1539 goto exit_unregister_sysfs
;
1541 if (data
->type
== f71882fg
) {
1542 err
= f71882fg_create_sysfs_files(pdev
,
1543 f71882fg_in_temp_attr
,
1544 ARRAY_SIZE(f71882fg_in_temp_attr
));
1546 goto exit_unregister_sysfs
;
1550 if (start_reg
& 0x02) {
1551 err
= f71882fg_create_sysfs_files(pdev
, f718x2fg_fan_attr
,
1552 ARRAY_SIZE(f718x2fg_fan_attr
));
1554 goto exit_unregister_sysfs
;
1556 if (data
->type
== f71862fg
) {
1557 err
= f71882fg_create_sysfs_files(pdev
,
1559 ARRAY_SIZE(f71862fg_fan_attr
));
1561 err
= f71882fg_create_sysfs_files(pdev
,
1563 ARRAY_SIZE(f71882fg_fan_attr
));
1566 goto exit_unregister_sysfs
;
1569 data
->hwmon_dev
= hwmon_device_register(&pdev
->dev
);
1570 if (IS_ERR(data
->hwmon_dev
)) {
1571 err
= PTR_ERR(data
->hwmon_dev
);
1572 data
->hwmon_dev
= NULL
;
1573 goto exit_unregister_sysfs
;
1578 exit_unregister_sysfs
:
1579 f71882fg_remove(pdev
); /* Will unregister the sysfs files for us */
1580 return err
; /* f71882fg_remove() also frees our data */
1586 static int f71882fg_remove(struct platform_device
*pdev
)
1589 struct f71882fg_data
*data
= platform_get_drvdata(pdev
);
1591 platform_set_drvdata(pdev
, NULL
);
1592 if (data
->hwmon_dev
)
1593 hwmon_device_unregister(data
->hwmon_dev
);
1595 device_remove_file(&pdev
->dev
, &dev_attr_name
);
1597 for (i
= 0; i
< ARRAY_SIZE(f718x2fg_in_temp_attr
); i
++)
1598 device_remove_file(&pdev
->dev
,
1599 &f718x2fg_in_temp_attr
[i
].dev_attr
);
1601 for (i
= 0; i
< ARRAY_SIZE(f71882fg_in_temp_attr
); i
++)
1602 device_remove_file(&pdev
->dev
,
1603 &f71882fg_in_temp_attr
[i
].dev_attr
);
1605 for (i
= 0; i
< ARRAY_SIZE(f718x2fg_fan_attr
); i
++)
1606 device_remove_file(&pdev
->dev
, &f718x2fg_fan_attr
[i
].dev_attr
);
1608 for (i
= 0; i
< ARRAY_SIZE(f71862fg_fan_attr
); i
++)
1609 device_remove_file(&pdev
->dev
, &f71862fg_fan_attr
[i
].dev_attr
);
1611 for (i
= 0; i
< ARRAY_SIZE(f71882fg_fan_attr
); i
++)
1612 device_remove_file(&pdev
->dev
, &f71882fg_fan_attr
[i
].dev_attr
);
1619 static int __init
f71882fg_find(int sioaddr
, unsigned short *address
,
1620 struct f71882fg_sio_data
*sio_data
)
1625 superio_enter(sioaddr
);
1627 devid
= superio_inw(sioaddr
, SIO_REG_MANID
);
1628 if (devid
!= SIO_FINTEK_ID
) {
1629 printk(KERN_INFO DRVNAME
": Not a Fintek device\n");
1633 devid
= force_id
? force_id
: superio_inw(sioaddr
, SIO_REG_DEVID
);
1636 sio_data
->type
= f71862fg
;
1639 sio_data
->type
= f71882fg
;
1642 printk(KERN_INFO DRVNAME
": Unsupported Fintek device\n");
1646 superio_select(sioaddr
, SIO_F71882FG_LD_HWM
);
1647 if (!(superio_inb(sioaddr
, SIO_REG_ENABLE
) & 0x01)) {
1648 printk(KERN_WARNING DRVNAME
": Device not activated\n");
1652 *address
= superio_inw(sioaddr
, SIO_REG_ADDR
);
1655 printk(KERN_WARNING DRVNAME
": Base address not set\n");
1658 *address
&= ~(REGION_LENGTH
- 1); /* Ignore 3 LSB */
1661 printk(KERN_INFO DRVNAME
": Found %s chip at %#x, revision %d\n",
1662 f71882fg_names
[sio_data
->type
], (unsigned int)*address
,
1663 (int)superio_inb(sioaddr
, SIO_REG_DEVREV
));
1665 superio_exit(sioaddr
);
1669 static int __init
f71882fg_device_add(unsigned short address
,
1670 const struct f71882fg_sio_data
*sio_data
)
1672 struct resource res
= {
1674 .end
= address
+ REGION_LENGTH
- 1,
1675 .flags
= IORESOURCE_IO
,
1679 f71882fg_pdev
= platform_device_alloc(DRVNAME
, address
);
1683 res
.name
= f71882fg_pdev
->name
;
1684 err
= platform_device_add_resources(f71882fg_pdev
, &res
, 1);
1686 printk(KERN_ERR DRVNAME
": Device resource addition failed\n");
1687 goto exit_device_put
;
1690 err
= platform_device_add_data(f71882fg_pdev
, sio_data
,
1691 sizeof(struct f71882fg_sio_data
));
1693 printk(KERN_ERR DRVNAME
": Platform data allocation failed\n");
1694 goto exit_device_put
;
1697 err
= platform_device_add(f71882fg_pdev
);
1699 printk(KERN_ERR DRVNAME
": Device addition failed\n");
1700 goto exit_device_put
;
1706 platform_device_put(f71882fg_pdev
);
1711 static int __init
f71882fg_init(void)
1714 unsigned short address
;
1715 struct f71882fg_sio_data sio_data
;
1717 memset(&sio_data
, 0, sizeof(sio_data
));
1719 if (f71882fg_find(0x2e, &address
, &sio_data
) &&
1720 f71882fg_find(0x4e, &address
, &sio_data
))
1723 err
= platform_driver_register(&f71882fg_driver
);
1727 err
= f71882fg_device_add(address
, &sio_data
);
1734 platform_driver_unregister(&f71882fg_driver
);
1739 static void __exit
f71882fg_exit(void)
1741 platform_device_unregister(f71882fg_pdev
);
1742 platform_driver_unregister(&f71882fg_driver
);
1745 MODULE_DESCRIPTION("F71882FG Hardware Monitoring Driver");
1746 MODULE_AUTHOR("Hans Edgington, Hans de Goede (hdegoede@redhat.com)");
1747 MODULE_LICENSE("GPL");
1749 module_init(f71882fg_init
);
1750 module_exit(f71882fg_exit
);