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_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];
141 /* Note: all models have only 3 temperature channels, but on some
142 they are addressed as 0-2 and on others as 1-3, so for coding
143 convenience we reserve space for 4 channels */
154 u8 pwm_auto_point_hyst
[2];
155 u8 pwm_auto_point_mapping
[4];
156 u8 pwm_auto_point_pwm
[4][5];
157 u8 pwm_auto_point_temp
[4][4];
161 static ssize_t
show_in(struct device
*dev
, struct device_attribute
*devattr
,
163 static ssize_t
show_in_max(struct device
*dev
, struct device_attribute
164 *devattr
, char *buf
);
165 static ssize_t
store_in_max(struct device
*dev
, struct device_attribute
166 *devattr
, const char *buf
, size_t count
);
167 static ssize_t
show_in_beep(struct device
*dev
, struct device_attribute
168 *devattr
, char *buf
);
169 static ssize_t
store_in_beep(struct device
*dev
, struct device_attribute
170 *devattr
, const char *buf
, size_t count
);
171 static ssize_t
show_in_alarm(struct device
*dev
, struct device_attribute
172 *devattr
, char *buf
);
174 static ssize_t
show_fan(struct device
*dev
, struct device_attribute
*devattr
,
176 static ssize_t
show_fan_full_speed(struct device
*dev
,
177 struct device_attribute
*devattr
, char *buf
);
178 static ssize_t
store_fan_full_speed(struct device
*dev
,
179 struct device_attribute
*devattr
, const char *buf
, size_t count
);
180 static ssize_t
show_fan_beep(struct device
*dev
, struct device_attribute
181 *devattr
, char *buf
);
182 static ssize_t
store_fan_beep(struct device
*dev
, struct device_attribute
183 *devattr
, const char *buf
, size_t count
);
184 static ssize_t
show_fan_alarm(struct device
*dev
, struct device_attribute
185 *devattr
, char *buf
);
187 static ssize_t
show_temp(struct device
*dev
, struct device_attribute
188 *devattr
, char *buf
);
189 static ssize_t
show_temp_max(struct device
*dev
, struct device_attribute
190 *devattr
, char *buf
);
191 static ssize_t
store_temp_max(struct device
*dev
, struct device_attribute
192 *devattr
, const char *buf
, size_t count
);
193 static ssize_t
show_temp_max_hyst(struct device
*dev
, struct device_attribute
194 *devattr
, char *buf
);
195 static ssize_t
store_temp_max_hyst(struct device
*dev
, struct device_attribute
196 *devattr
, const char *buf
, size_t count
);
197 static ssize_t
show_temp_crit(struct device
*dev
, struct device_attribute
198 *devattr
, char *buf
);
199 static ssize_t
store_temp_crit(struct device
*dev
, struct device_attribute
200 *devattr
, const char *buf
, size_t count
);
201 static ssize_t
show_temp_crit_hyst(struct device
*dev
, struct device_attribute
202 *devattr
, char *buf
);
203 static ssize_t
show_temp_type(struct device
*dev
, struct device_attribute
204 *devattr
, char *buf
);
205 static ssize_t
show_temp_beep(struct device
*dev
, struct device_attribute
206 *devattr
, char *buf
);
207 static ssize_t
store_temp_beep(struct device
*dev
, struct device_attribute
208 *devattr
, const char *buf
, size_t count
);
209 static ssize_t
show_temp_alarm(struct device
*dev
, struct device_attribute
210 *devattr
, char *buf
);
211 static ssize_t
show_temp_fault(struct device
*dev
, struct device_attribute
212 *devattr
, char *buf
);
213 /* PWM and Auto point control */
214 static ssize_t
show_pwm(struct device
*dev
, struct device_attribute
*devattr
,
216 static ssize_t
store_pwm(struct device
*dev
, struct device_attribute
*devattr
,
217 const char *buf
, size_t count
);
218 static ssize_t
show_pwm_enable(struct device
*dev
,
219 struct device_attribute
*devattr
, char *buf
);
220 static ssize_t
store_pwm_enable(struct device
*dev
,
221 struct device_attribute
*devattr
, const char *buf
, size_t count
);
222 static ssize_t
show_pwm_interpolate(struct device
*dev
,
223 struct device_attribute
*devattr
, char *buf
);
224 static ssize_t
store_pwm_interpolate(struct device
*dev
,
225 struct device_attribute
*devattr
, const char *buf
, size_t count
);
226 static ssize_t
show_pwm_auto_point_channel(struct device
*dev
,
227 struct device_attribute
*devattr
, char *buf
);
228 static ssize_t
store_pwm_auto_point_channel(struct device
*dev
,
229 struct device_attribute
*devattr
, const char *buf
, size_t count
);
230 static ssize_t
show_pwm_auto_point_temp_hyst(struct device
*dev
,
231 struct device_attribute
*devattr
, char *buf
);
232 static ssize_t
store_pwm_auto_point_temp_hyst(struct device
*dev
,
233 struct device_attribute
*devattr
, const char *buf
, size_t count
);
234 static ssize_t
show_pwm_auto_point_pwm(struct device
*dev
,
235 struct device_attribute
*devattr
, char *buf
);
236 static ssize_t
store_pwm_auto_point_pwm(struct device
*dev
,
237 struct device_attribute
*devattr
, const char *buf
, size_t count
);
238 static ssize_t
show_pwm_auto_point_temp(struct device
*dev
,
239 struct device_attribute
*devattr
, char *buf
);
240 static ssize_t
store_pwm_auto_point_temp(struct device
*dev
,
241 struct device_attribute
*devattr
, const char *buf
, size_t count
);
243 static ssize_t
show_name(struct device
*dev
, struct device_attribute
*devattr
,
246 static int __devinit
f71882fg_probe(struct platform_device
* pdev
);
247 static int f71882fg_remove(struct platform_device
*pdev
);
249 static struct platform_driver f71882fg_driver
= {
251 .owner
= THIS_MODULE
,
254 .probe
= f71882fg_probe
,
255 .remove
= __devexit_p(f71882fg_remove
),
258 static DEVICE_ATTR(name
, S_IRUGO
, show_name
, NULL
);
260 static struct sensor_device_attribute_2 f718x2fg_in_temp_attr
[] = {
261 SENSOR_ATTR_2(in0_input
, S_IRUGO
, show_in
, NULL
, 0, 0),
262 SENSOR_ATTR_2(in1_input
, S_IRUGO
, show_in
, NULL
, 0, 1),
263 SENSOR_ATTR_2(in2_input
, S_IRUGO
, show_in
, NULL
, 0, 2),
264 SENSOR_ATTR_2(in3_input
, S_IRUGO
, show_in
, NULL
, 0, 3),
265 SENSOR_ATTR_2(in4_input
, S_IRUGO
, show_in
, NULL
, 0, 4),
266 SENSOR_ATTR_2(in5_input
, S_IRUGO
, show_in
, NULL
, 0, 5),
267 SENSOR_ATTR_2(in6_input
, S_IRUGO
, show_in
, NULL
, 0, 6),
268 SENSOR_ATTR_2(in7_input
, S_IRUGO
, show_in
, NULL
, 0, 7),
269 SENSOR_ATTR_2(in8_input
, S_IRUGO
, show_in
, NULL
, 0, 8),
270 SENSOR_ATTR_2(temp1_input
, S_IRUGO
, show_temp
, NULL
, 0, 1),
271 SENSOR_ATTR_2(temp1_max
, S_IRUGO
|S_IWUSR
, show_temp_max
,
272 store_temp_max
, 0, 1),
273 SENSOR_ATTR_2(temp1_max_hyst
, S_IRUGO
|S_IWUSR
, show_temp_max_hyst
,
274 store_temp_max_hyst
, 0, 1),
275 SENSOR_ATTR_2(temp1_crit
, S_IRUGO
|S_IWUSR
, show_temp_crit
,
276 store_temp_crit
, 0, 1),
277 SENSOR_ATTR_2(temp1_crit_hyst
, S_IRUGO
, show_temp_crit_hyst
, NULL
,
279 SENSOR_ATTR_2(temp1_type
, S_IRUGO
, show_temp_type
, NULL
, 0, 1),
280 SENSOR_ATTR_2(temp1_beep
, S_IRUGO
|S_IWUSR
, show_temp_beep
,
281 store_temp_beep
, 0, 1),
282 SENSOR_ATTR_2(temp1_alarm
, S_IRUGO
, show_temp_alarm
, NULL
, 0, 1),
283 SENSOR_ATTR_2(temp1_fault
, S_IRUGO
, show_temp_fault
, NULL
, 0, 1),
284 SENSOR_ATTR_2(temp2_input
, S_IRUGO
, show_temp
, NULL
, 0, 2),
285 SENSOR_ATTR_2(temp2_max
, S_IRUGO
|S_IWUSR
, show_temp_max
,
286 store_temp_max
, 0, 2),
287 SENSOR_ATTR_2(temp2_max_hyst
, S_IRUGO
|S_IWUSR
, show_temp_max_hyst
,
288 store_temp_max_hyst
, 0, 2),
289 SENSOR_ATTR_2(temp2_crit
, S_IRUGO
|S_IWUSR
, show_temp_crit
,
290 store_temp_crit
, 0, 2),
291 SENSOR_ATTR_2(temp2_crit_hyst
, S_IRUGO
, show_temp_crit_hyst
, NULL
,
293 SENSOR_ATTR_2(temp2_type
, S_IRUGO
, show_temp_type
, NULL
, 0, 2),
294 SENSOR_ATTR_2(temp2_beep
, S_IRUGO
|S_IWUSR
, show_temp_beep
,
295 store_temp_beep
, 0, 2),
296 SENSOR_ATTR_2(temp2_alarm
, S_IRUGO
, show_temp_alarm
, NULL
, 0, 2),
297 SENSOR_ATTR_2(temp2_fault
, S_IRUGO
, show_temp_fault
, NULL
, 0, 2),
298 SENSOR_ATTR_2(temp3_input
, S_IRUGO
, show_temp
, NULL
, 0, 3),
299 SENSOR_ATTR_2(temp3_max
, S_IRUGO
|S_IWUSR
, show_temp_max
,
300 store_temp_max
, 0, 3),
301 SENSOR_ATTR_2(temp3_max_hyst
, S_IRUGO
|S_IWUSR
, show_temp_max_hyst
,
302 store_temp_max_hyst
, 0, 3),
303 SENSOR_ATTR_2(temp3_crit
, S_IRUGO
|S_IWUSR
, show_temp_crit
,
304 store_temp_crit
, 0, 3),
305 SENSOR_ATTR_2(temp3_crit_hyst
, S_IRUGO
, show_temp_crit_hyst
, NULL
,
307 SENSOR_ATTR_2(temp3_type
, S_IRUGO
, show_temp_type
, NULL
, 0, 3),
308 SENSOR_ATTR_2(temp3_beep
, S_IRUGO
|S_IWUSR
, show_temp_beep
,
309 store_temp_beep
, 0, 3),
310 SENSOR_ATTR_2(temp3_alarm
, S_IRUGO
, show_temp_alarm
, NULL
, 0, 3),
311 SENSOR_ATTR_2(temp3_fault
, S_IRUGO
, show_temp_fault
, NULL
, 0, 3),
314 static struct sensor_device_attribute_2 f71882fg_in_temp_attr
[] = {
315 SENSOR_ATTR_2(in1_max
, S_IRUGO
|S_IWUSR
, show_in_max
, store_in_max
,
317 SENSOR_ATTR_2(in1_beep
, S_IRUGO
|S_IWUSR
, show_in_beep
, store_in_beep
,
319 SENSOR_ATTR_2(in1_alarm
, S_IRUGO
, show_in_alarm
, NULL
, 0, 1),
322 static struct sensor_device_attribute_2 f718x2fg_fan_attr
[] = {
323 SENSOR_ATTR_2(fan1_input
, S_IRUGO
, show_fan
, NULL
, 0, 0),
324 SENSOR_ATTR_2(fan1_full_speed
, S_IRUGO
|S_IWUSR
,
326 store_fan_full_speed
, 0, 0),
327 SENSOR_ATTR_2(fan1_beep
, S_IRUGO
|S_IWUSR
, show_fan_beep
,
328 store_fan_beep
, 0, 0),
329 SENSOR_ATTR_2(fan1_alarm
, S_IRUGO
, show_fan_alarm
, NULL
, 0, 0),
330 SENSOR_ATTR_2(fan2_input
, S_IRUGO
, show_fan
, NULL
, 0, 1),
331 SENSOR_ATTR_2(fan2_full_speed
, S_IRUGO
|S_IWUSR
,
333 store_fan_full_speed
, 0, 1),
334 SENSOR_ATTR_2(fan2_beep
, S_IRUGO
|S_IWUSR
, show_fan_beep
,
335 store_fan_beep
, 0, 1),
336 SENSOR_ATTR_2(fan2_alarm
, S_IRUGO
, show_fan_alarm
, NULL
, 0, 1),
337 SENSOR_ATTR_2(fan3_input
, S_IRUGO
, show_fan
, NULL
, 0, 2),
338 SENSOR_ATTR_2(fan3_full_speed
, S_IRUGO
|S_IWUSR
,
340 store_fan_full_speed
, 0, 2),
341 SENSOR_ATTR_2(fan3_beep
, S_IRUGO
|S_IWUSR
, show_fan_beep
,
342 store_fan_beep
, 0, 2),
343 SENSOR_ATTR_2(fan3_alarm
, S_IRUGO
, show_fan_alarm
, NULL
, 0, 2),
345 SENSOR_ATTR_2(pwm1
, S_IRUGO
|S_IWUSR
, show_pwm
, store_pwm
, 0, 0),
346 SENSOR_ATTR_2(pwm1_enable
, S_IRUGO
|S_IWUSR
, show_pwm_enable
,
347 store_pwm_enable
, 0, 0),
348 SENSOR_ATTR_2(pwm1_interpolate
, S_IRUGO
|S_IWUSR
,
349 show_pwm_interpolate
, store_pwm_interpolate
, 0, 0),
350 SENSOR_ATTR_2(pwm1_auto_channels_temp
, S_IRUGO
|S_IWUSR
,
351 show_pwm_auto_point_channel
,
352 store_pwm_auto_point_channel
, 0, 0),
354 SENSOR_ATTR_2(pwm2
, S_IRUGO
|S_IWUSR
, show_pwm
, store_pwm
, 0, 1),
355 SENSOR_ATTR_2(pwm2_enable
, S_IRUGO
|S_IWUSR
, show_pwm_enable
,
356 store_pwm_enable
, 0, 1),
357 SENSOR_ATTR_2(pwm2_interpolate
, S_IRUGO
|S_IWUSR
,
358 show_pwm_interpolate
, store_pwm_interpolate
, 0, 1),
359 SENSOR_ATTR_2(pwm2_auto_channels_temp
, S_IRUGO
|S_IWUSR
,
360 show_pwm_auto_point_channel
,
361 store_pwm_auto_point_channel
, 0, 1),
363 SENSOR_ATTR_2(pwm3
, S_IRUGO
|S_IWUSR
, show_pwm
, store_pwm
, 0, 2),
364 SENSOR_ATTR_2(pwm3_enable
, S_IRUGO
|S_IWUSR
, show_pwm_enable
,
365 store_pwm_enable
, 0, 2),
366 SENSOR_ATTR_2(pwm3_interpolate
, S_IRUGO
|S_IWUSR
,
367 show_pwm_interpolate
, store_pwm_interpolate
, 0, 2),
368 SENSOR_ATTR_2(pwm3_auto_channels_temp
, S_IRUGO
|S_IWUSR
,
369 show_pwm_auto_point_channel
,
370 store_pwm_auto_point_channel
, 0, 2),
373 static struct sensor_device_attribute_2 f71862fg_fan_attr
[] = {
374 SENSOR_ATTR_2(pwm1_auto_point1_pwm
, S_IRUGO
|S_IWUSR
,
375 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
377 SENSOR_ATTR_2(pwm1_auto_point2_pwm
, S_IRUGO
|S_IWUSR
,
378 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
380 SENSOR_ATTR_2(pwm1_auto_point1_temp
, S_IRUGO
|S_IWUSR
,
381 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
383 SENSOR_ATTR_2(pwm1_auto_point2_temp
, S_IRUGO
|S_IWUSR
,
384 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
386 SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst
, S_IRUGO
|S_IWUSR
,
387 show_pwm_auto_point_temp_hyst
,
388 store_pwm_auto_point_temp_hyst
,
390 SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst
, S_IRUGO
,
391 show_pwm_auto_point_temp_hyst
, NULL
, 3, 0),
393 SENSOR_ATTR_2(pwm2_auto_point1_pwm
, S_IRUGO
|S_IWUSR
,
394 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
396 SENSOR_ATTR_2(pwm2_auto_point2_pwm
, S_IRUGO
|S_IWUSR
,
397 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
399 SENSOR_ATTR_2(pwm2_auto_point1_temp
, S_IRUGO
|S_IWUSR
,
400 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
402 SENSOR_ATTR_2(pwm2_auto_point2_temp
, S_IRUGO
|S_IWUSR
,
403 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
405 SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst
, S_IRUGO
|S_IWUSR
,
406 show_pwm_auto_point_temp_hyst
,
407 store_pwm_auto_point_temp_hyst
,
409 SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst
, S_IRUGO
,
410 show_pwm_auto_point_temp_hyst
, NULL
, 3, 1),
413 static struct sensor_device_attribute_2 f71882fg_fan_attr
[] = {
414 SENSOR_ATTR_2(fan4_input
, S_IRUGO
, show_fan
, NULL
, 0, 3),
415 SENSOR_ATTR_2(fan4_full_speed
, S_IRUGO
|S_IWUSR
,
417 store_fan_full_speed
, 0, 3),
418 SENSOR_ATTR_2(fan4_beep
, S_IRUGO
|S_IWUSR
, show_fan_beep
,
419 store_fan_beep
, 0, 3),
420 SENSOR_ATTR_2(fan4_alarm
, S_IRUGO
, show_fan_alarm
, NULL
, 0, 3),
422 SENSOR_ATTR_2(pwm1_auto_point1_pwm
, S_IRUGO
|S_IWUSR
,
423 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
425 SENSOR_ATTR_2(pwm1_auto_point2_pwm
, S_IRUGO
|S_IWUSR
,
426 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
428 SENSOR_ATTR_2(pwm1_auto_point3_pwm
, S_IRUGO
|S_IWUSR
,
429 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
431 SENSOR_ATTR_2(pwm1_auto_point4_pwm
, S_IRUGO
|S_IWUSR
,
432 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
434 SENSOR_ATTR_2(pwm1_auto_point5_pwm
, S_IRUGO
|S_IWUSR
,
435 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
437 SENSOR_ATTR_2(pwm1_auto_point1_temp
, S_IRUGO
|S_IWUSR
,
438 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
440 SENSOR_ATTR_2(pwm1_auto_point2_temp
, S_IRUGO
|S_IWUSR
,
441 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
443 SENSOR_ATTR_2(pwm1_auto_point3_temp
, S_IRUGO
|S_IWUSR
,
444 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
446 SENSOR_ATTR_2(pwm1_auto_point4_temp
, S_IRUGO
|S_IWUSR
,
447 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
449 SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst
, S_IRUGO
|S_IWUSR
,
450 show_pwm_auto_point_temp_hyst
,
451 store_pwm_auto_point_temp_hyst
,
453 SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst
, S_IRUGO
,
454 show_pwm_auto_point_temp_hyst
, NULL
, 1, 0),
455 SENSOR_ATTR_2(pwm1_auto_point3_temp_hyst
, S_IRUGO
,
456 show_pwm_auto_point_temp_hyst
, NULL
, 2, 0),
457 SENSOR_ATTR_2(pwm1_auto_point4_temp_hyst
, S_IRUGO
,
458 show_pwm_auto_point_temp_hyst
, NULL
, 3, 0),
460 SENSOR_ATTR_2(pwm2_auto_point1_pwm
, S_IRUGO
|S_IWUSR
,
461 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
463 SENSOR_ATTR_2(pwm2_auto_point2_pwm
, S_IRUGO
|S_IWUSR
,
464 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
466 SENSOR_ATTR_2(pwm2_auto_point3_pwm
, S_IRUGO
|S_IWUSR
,
467 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
469 SENSOR_ATTR_2(pwm2_auto_point4_pwm
, S_IRUGO
|S_IWUSR
,
470 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
472 SENSOR_ATTR_2(pwm2_auto_point5_pwm
, S_IRUGO
|S_IWUSR
,
473 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
475 SENSOR_ATTR_2(pwm2_auto_point1_temp
, S_IRUGO
|S_IWUSR
,
476 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
478 SENSOR_ATTR_2(pwm2_auto_point2_temp
, S_IRUGO
|S_IWUSR
,
479 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
481 SENSOR_ATTR_2(pwm2_auto_point3_temp
, S_IRUGO
|S_IWUSR
,
482 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
484 SENSOR_ATTR_2(pwm2_auto_point4_temp
, S_IRUGO
|S_IWUSR
,
485 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
487 SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst
, S_IRUGO
|S_IWUSR
,
488 show_pwm_auto_point_temp_hyst
,
489 store_pwm_auto_point_temp_hyst
,
491 SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst
, S_IRUGO
,
492 show_pwm_auto_point_temp_hyst
, NULL
, 1, 1),
493 SENSOR_ATTR_2(pwm2_auto_point3_temp_hyst
, S_IRUGO
,
494 show_pwm_auto_point_temp_hyst
, NULL
, 2, 1),
495 SENSOR_ATTR_2(pwm2_auto_point4_temp_hyst
, S_IRUGO
,
496 show_pwm_auto_point_temp_hyst
, NULL
, 3, 1),
498 SENSOR_ATTR_2(pwm3_auto_point1_pwm
, S_IRUGO
|S_IWUSR
,
499 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
501 SENSOR_ATTR_2(pwm3_auto_point2_pwm
, S_IRUGO
|S_IWUSR
,
502 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
504 SENSOR_ATTR_2(pwm3_auto_point3_pwm
, S_IRUGO
|S_IWUSR
,
505 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
507 SENSOR_ATTR_2(pwm3_auto_point4_pwm
, S_IRUGO
|S_IWUSR
,
508 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
510 SENSOR_ATTR_2(pwm3_auto_point5_pwm
, S_IRUGO
|S_IWUSR
,
511 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
513 SENSOR_ATTR_2(pwm3_auto_point1_temp
, S_IRUGO
|S_IWUSR
,
514 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
516 SENSOR_ATTR_2(pwm3_auto_point2_temp
, S_IRUGO
|S_IWUSR
,
517 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
519 SENSOR_ATTR_2(pwm3_auto_point3_temp
, S_IRUGO
|S_IWUSR
,
520 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
522 SENSOR_ATTR_2(pwm3_auto_point4_temp
, S_IRUGO
|S_IWUSR
,
523 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
525 SENSOR_ATTR_2(pwm3_auto_point1_temp_hyst
, S_IRUGO
|S_IWUSR
,
526 show_pwm_auto_point_temp_hyst
,
527 store_pwm_auto_point_temp_hyst
,
529 SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst
, S_IRUGO
,
530 show_pwm_auto_point_temp_hyst
, NULL
, 1, 2),
531 SENSOR_ATTR_2(pwm3_auto_point3_temp_hyst
, S_IRUGO
,
532 show_pwm_auto_point_temp_hyst
, NULL
, 2, 2),
533 SENSOR_ATTR_2(pwm3_auto_point4_temp_hyst
, S_IRUGO
,
534 show_pwm_auto_point_temp_hyst
, NULL
, 3, 2),
536 SENSOR_ATTR_2(pwm4
, S_IRUGO
|S_IWUSR
, show_pwm
, store_pwm
, 0, 3),
537 SENSOR_ATTR_2(pwm4_enable
, S_IRUGO
|S_IWUSR
, show_pwm_enable
,
538 store_pwm_enable
, 0, 3),
539 SENSOR_ATTR_2(pwm4_interpolate
, S_IRUGO
|S_IWUSR
,
540 show_pwm_interpolate
, store_pwm_interpolate
, 0, 3),
541 SENSOR_ATTR_2(pwm4_auto_channels_temp
, S_IRUGO
|S_IWUSR
,
542 show_pwm_auto_point_channel
,
543 store_pwm_auto_point_channel
, 0, 3),
544 SENSOR_ATTR_2(pwm4_auto_point1_pwm
, S_IRUGO
|S_IWUSR
,
545 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
547 SENSOR_ATTR_2(pwm4_auto_point2_pwm
, S_IRUGO
|S_IWUSR
,
548 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
550 SENSOR_ATTR_2(pwm4_auto_point3_pwm
, S_IRUGO
|S_IWUSR
,
551 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
553 SENSOR_ATTR_2(pwm4_auto_point4_pwm
, S_IRUGO
|S_IWUSR
,
554 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
556 SENSOR_ATTR_2(pwm4_auto_point5_pwm
, S_IRUGO
|S_IWUSR
,
557 show_pwm_auto_point_pwm
, store_pwm_auto_point_pwm
,
559 SENSOR_ATTR_2(pwm4_auto_point1_temp
, S_IRUGO
|S_IWUSR
,
560 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
562 SENSOR_ATTR_2(pwm4_auto_point2_temp
, S_IRUGO
|S_IWUSR
,
563 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
565 SENSOR_ATTR_2(pwm4_auto_point3_temp
, S_IRUGO
|S_IWUSR
,
566 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
568 SENSOR_ATTR_2(pwm4_auto_point4_temp
, S_IRUGO
|S_IWUSR
,
569 show_pwm_auto_point_temp
, store_pwm_auto_point_temp
,
571 SENSOR_ATTR_2(pwm4_auto_point1_temp_hyst
, S_IRUGO
|S_IWUSR
,
572 show_pwm_auto_point_temp_hyst
,
573 store_pwm_auto_point_temp_hyst
,
575 SENSOR_ATTR_2(pwm4_auto_point2_temp_hyst
, S_IRUGO
,
576 show_pwm_auto_point_temp_hyst
, NULL
, 1, 3),
577 SENSOR_ATTR_2(pwm4_auto_point3_temp_hyst
, S_IRUGO
,
578 show_pwm_auto_point_temp_hyst
, NULL
, 2, 3),
579 SENSOR_ATTR_2(pwm4_auto_point4_temp_hyst
, S_IRUGO
,
580 show_pwm_auto_point_temp_hyst
, NULL
, 3, 3),
584 /* Super I/O functions */
585 static inline int superio_inb(int base
, int reg
)
588 return inb(base
+ 1);
591 static int superio_inw(int base
, int reg
)
595 val
= inb(base
+ 1) << 8;
597 val
|= inb(base
+ 1);
601 static inline void superio_enter(int base
)
603 /* according to the datasheet the key must be send twice! */
604 outb( SIO_UNLOCK_KEY
, base
);
605 outb( SIO_UNLOCK_KEY
, base
);
608 static inline void superio_select( int base
, int ld
)
610 outb(SIO_REG_LDSEL
, base
);
614 static inline void superio_exit(int base
)
616 outb(SIO_LOCK_KEY
, base
);
619 static inline u16
fan_from_reg(u16 reg
)
621 return reg
? (1500000 / reg
) : 0;
624 static inline u16
fan_to_reg(u16 fan
)
626 return fan
? (1500000 / fan
) : 0;
629 static u8
f71882fg_read8(struct f71882fg_data
*data
, u8 reg
)
633 outb(reg
, data
->addr
+ ADDR_REG_OFFSET
);
634 val
= inb(data
->addr
+ DATA_REG_OFFSET
);
639 static u16
f71882fg_read16(struct f71882fg_data
*data
, u8 reg
)
643 outb(reg
++, data
->addr
+ ADDR_REG_OFFSET
);
644 val
= inb(data
->addr
+ DATA_REG_OFFSET
) << 8;
645 outb(reg
, data
->addr
+ ADDR_REG_OFFSET
);
646 val
|= inb(data
->addr
+ DATA_REG_OFFSET
);
651 static void f71882fg_write8(struct f71882fg_data
*data
, u8 reg
, u8 val
)
653 outb(reg
, data
->addr
+ ADDR_REG_OFFSET
);
654 outb(val
, data
->addr
+ DATA_REG_OFFSET
);
657 static void f71882fg_write16(struct f71882fg_data
*data
, u8 reg
, u16 val
)
659 outb(reg
++, data
->addr
+ ADDR_REG_OFFSET
);
660 outb(val
>> 8, data
->addr
+ DATA_REG_OFFSET
);
661 outb(reg
, data
->addr
+ ADDR_REG_OFFSET
);
662 outb(val
& 255, data
->addr
+ DATA_REG_OFFSET
);
665 static struct f71882fg_data
*f71882fg_update_device(struct device
*dev
)
667 struct f71882fg_data
*data
= dev_get_drvdata(dev
);
669 int nr_fans
= (data
->type
== f71862fg
) ? 3 : 4;
671 mutex_lock(&data
->update_lock
);
673 /* Update once every 60 seconds */
674 if ( time_after(jiffies
, data
->last_limits
+ 60 * HZ
) ||
676 if (data
->type
== f71882fg
) {
678 f71882fg_read8(data
, F71882FG_REG_IN1_HIGH
);
680 f71882fg_read8(data
, F71882FG_REG_IN_BEEP
);
683 /* Get High & boundary temps*/
684 for (nr
= 1; nr
< 4; nr
++) {
685 data
->temp_ovt
[nr
] = f71882fg_read8(data
,
686 F71882FG_REG_TEMP_OVT(nr
));
687 data
->temp_high
[nr
] = f71882fg_read8(data
,
688 F71882FG_REG_TEMP_HIGH(nr
));
691 /* Have to hardcode hyst*/
692 data
->temp_hyst
[1] = f71882fg_read8(data
,
693 F71882FG_REG_TEMP_HYST1
) >> 4;
694 /* Hyst temps 2 & 3 stored in same register */
695 reg
= f71882fg_read8(data
, F71882FG_REG_TEMP_HYST23
);
696 data
->temp_hyst
[2] = reg
& 0x0F;
697 data
->temp_hyst
[3] = reg
>> 4;
699 /* Have to hardcode type, because temp1 is special */
700 reg
= f71882fg_read8(data
, F71882FG_REG_TEMP_TYPE
);
701 reg2
= f71882fg_read8(data
, F71882FG_REG_PECI
);
702 if ((reg2
& 0x03) == 0x01)
703 data
->temp_type
[1] = 6 /* PECI */;
704 else if ((reg2
& 0x03) == 0x02)
705 data
->temp_type
[1] = 5 /* AMDSI */;
707 data
->temp_type
[1] = (reg
& 0x02) ? 2 : 4;
709 data
->temp_type
[2] = (reg
& 0x04) ? 2 : 4;
710 data
->temp_type
[3] = (reg
& 0x08) ? 2 : 4;
712 data
->temp_beep
= f71882fg_read8(data
, F71882FG_REG_TEMP_BEEP
);
714 data
->fan_beep
= f71882fg_read8(data
, F71882FG_REG_FAN_BEEP
);
716 data
->pwm_enable
= f71882fg_read8(data
,
717 F71882FG_REG_PWM_ENABLE
);
718 data
->pwm_auto_point_hyst
[0] = f71882fg_read8(data
,
719 F71882FG_REG_FAN_HYST0
);
720 data
->pwm_auto_point_hyst
[1] = f71882fg_read8(data
,
721 F71882FG_REG_FAN_HYST1
);
722 for (nr
= 0; nr
< nr_fans
; nr
++) {
723 data
->pwm_auto_point_mapping
[nr
] =
725 F71882FG_REG_POINT_MAPPING(nr
));
727 if (data
->type
== f71882fg
) {
729 for (point
= 0; point
< 5; point
++) {
730 data
->pwm_auto_point_pwm
[nr
][point
] =
732 F71882FG_REG_POINT_PWM
735 for (point
= 0; point
< 4; point
++) {
736 data
->pwm_auto_point_temp
[nr
][point
] =
738 F71882FG_REG_POINT_TEMP
742 data
->pwm_auto_point_pwm
[nr
][1] =
744 F71882FG_REG_POINT_PWM
746 data
->pwm_auto_point_pwm
[nr
][4] =
748 F71882FG_REG_POINT_PWM
750 data
->pwm_auto_point_temp
[nr
][0] =
752 F71882FG_REG_POINT_TEMP
754 data
->pwm_auto_point_temp
[nr
][3] =
756 F71882FG_REG_POINT_TEMP
760 data
->last_limits
= jiffies
;
763 /* Update every second */
764 if (time_after(jiffies
, data
->last_updated
+ HZ
) || !data
->valid
) {
765 data
->temp_status
= f71882fg_read8(data
,
766 F71882FG_REG_TEMP_STATUS
);
767 data
->temp_diode_open
= f71882fg_read8(data
,
768 F71882FG_REG_TEMP_DIODE_OPEN
);
769 for (nr
= 1; nr
< 4; nr
++)
770 data
->temp
[nr
] = f71882fg_read8(data
,
771 F71882FG_REG_TEMP(nr
));
773 data
->fan_status
= f71882fg_read8(data
,
774 F71882FG_REG_FAN_STATUS
);
775 for (nr
= 0; nr
< nr_fans
; nr
++) {
776 data
->fan
[nr
] = f71882fg_read16(data
,
777 F71882FG_REG_FAN(nr
));
778 data
->fan_target
[nr
] =
779 f71882fg_read16(data
, F71882FG_REG_FAN_TARGET(nr
));
780 data
->fan_full_speed
[nr
] =
781 f71882fg_read16(data
,
782 F71882FG_REG_FAN_FULL_SPEED(nr
));
784 f71882fg_read8(data
, F71882FG_REG_PWM(nr
));
787 if (data
->type
== f71882fg
)
788 data
->in_status
= f71882fg_read8(data
,
789 F71882FG_REG_IN_STATUS
);
790 for (nr
= 0; nr
< 9; nr
++)
791 data
->in
[nr
] = f71882fg_read8(data
,
792 F71882FG_REG_IN(nr
));
794 data
->last_updated
= jiffies
;
798 mutex_unlock(&data
->update_lock
);
803 /* Sysfs Interface */
804 static ssize_t
show_fan(struct device
*dev
, struct device_attribute
*devattr
,
807 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
808 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
809 int speed
= fan_from_reg(data
->fan
[nr
]);
811 if (speed
== FAN_MIN_DETECT
)
814 return sprintf(buf
, "%d\n", speed
);
817 static ssize_t
show_fan_full_speed(struct device
*dev
,
818 struct device_attribute
*devattr
, char *buf
)
820 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
821 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
822 int speed
= fan_from_reg(data
->fan_full_speed
[nr
]);
823 return sprintf(buf
, "%d\n", speed
);
826 static ssize_t
store_fan_full_speed(struct device
*dev
,
827 struct device_attribute
*devattr
,
828 const char *buf
, size_t count
)
830 struct f71882fg_data
*data
= dev_get_drvdata(dev
);
831 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
832 long val
= simple_strtol(buf
, NULL
, 10);
834 val
= SENSORS_LIMIT(val
, 23, 1500000);
835 val
= fan_to_reg(val
);
837 mutex_lock(&data
->update_lock
);
838 if (data
->pwm_enable
& (1 << (2 * nr
)))
843 f71882fg_write16(data
, F71882FG_REG_FAN_FULL_SPEED(nr
), val
);
844 data
->fan_full_speed
[nr
] = val
;
846 mutex_unlock(&data
->update_lock
);
851 static ssize_t
show_fan_beep(struct device
*dev
, struct device_attribute
854 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
855 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
857 if (data
->fan_beep
& (1 << nr
))
858 return sprintf(buf
, "1\n");
860 return sprintf(buf
, "0\n");
863 static ssize_t
store_fan_beep(struct device
*dev
, struct device_attribute
864 *devattr
, const char *buf
, size_t count
)
866 struct f71882fg_data
*data
= dev_get_drvdata(dev
);
867 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
868 int val
= simple_strtoul(buf
, NULL
, 10);
870 mutex_lock(&data
->update_lock
);
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 int val
= simple_strtoul(buf
, NULL
, 10) / 8;
920 mutex_lock(&data
->update_lock
);
921 f71882fg_write8(data
, F71882FG_REG_IN1_HIGH
, val
);
923 mutex_unlock(&data
->update_lock
);
928 static ssize_t
show_in_beep(struct device
*dev
, struct device_attribute
931 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
932 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
934 if (data
->in_beep
& (1 << nr
))
935 return sprintf(buf
, "1\n");
937 return sprintf(buf
, "0\n");
940 static ssize_t
store_in_beep(struct device
*dev
, struct device_attribute
941 *devattr
, const char *buf
, size_t count
)
943 struct f71882fg_data
*data
= dev_get_drvdata(dev
);
944 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
945 int val
= simple_strtoul(buf
, NULL
, 10);
947 mutex_lock(&data
->update_lock
);
949 data
->in_beep
|= 1 << nr
;
951 data
->in_beep
&= ~(1 << nr
);
953 f71882fg_write8(data
, F71882FG_REG_IN_BEEP
, data
->in_beep
);
954 mutex_unlock(&data
->update_lock
);
959 static ssize_t
show_in_alarm(struct device
*dev
, struct device_attribute
962 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
963 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
965 if (data
->in_status
& (1 << nr
))
966 return sprintf(buf
, "1\n");
968 return sprintf(buf
, "0\n");
971 static ssize_t
show_temp(struct device
*dev
, struct device_attribute
*devattr
,
974 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
975 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
977 return sprintf(buf
, "%d\n", data
->temp
[nr
] * 1000);
980 static ssize_t
show_temp_max(struct device
*dev
, struct device_attribute
983 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
984 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
986 return sprintf(buf
, "%d\n", data
->temp_high
[nr
] * 1000);
989 static ssize_t
store_temp_max(struct device
*dev
, struct device_attribute
990 *devattr
, const char *buf
, size_t count
)
992 struct f71882fg_data
*data
= dev_get_drvdata(dev
);
993 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
994 int val
= simple_strtoul(buf
, NULL
, 10) / 1000;
999 mutex_lock(&data
->update_lock
);
1000 f71882fg_write8(data
, F71882FG_REG_TEMP_HIGH(nr
), val
);
1001 data
->temp_high
[nr
] = val
;
1002 mutex_unlock(&data
->update_lock
);
1007 static ssize_t
show_temp_max_hyst(struct device
*dev
, struct device_attribute
1008 *devattr
, char *buf
)
1010 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1011 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1013 return sprintf(buf
, "%d\n",
1014 (data
->temp_high
[nr
] - data
->temp_hyst
[nr
]) * 1000);
1017 static ssize_t
store_temp_max_hyst(struct device
*dev
, struct device_attribute
1018 *devattr
, const char *buf
, size_t count
)
1020 struct f71882fg_data
*data
= dev_get_drvdata(dev
);
1021 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1022 int val
= simple_strtoul(buf
, NULL
, 10) / 1000;
1023 ssize_t ret
= count
;
1025 mutex_lock(&data
->update_lock
);
1027 /* convert abs to relative and check */
1028 val
= data
->temp_high
[nr
] - val
;
1029 if (val
< 0 || val
> 15) {
1031 goto store_temp_max_hyst_exit
;
1034 data
->temp_hyst
[nr
] = val
;
1036 /* convert value to register contents */
1042 val
= val
| (data
->temp_hyst
[3] << 4);
1045 val
= data
->temp_hyst
[2] | (val
<< 4);
1049 f71882fg_write8(data
, (nr
<= 1) ? F71882FG_REG_TEMP_HYST1
:
1050 F71882FG_REG_TEMP_HYST23
, val
);
1052 store_temp_max_hyst_exit
:
1053 mutex_unlock(&data
->update_lock
);
1057 static ssize_t
show_temp_crit(struct device
*dev
, struct device_attribute
1058 *devattr
, char *buf
)
1060 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1061 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1063 return sprintf(buf
, "%d\n", data
->temp_ovt
[nr
] * 1000);
1066 static ssize_t
store_temp_crit(struct device
*dev
, struct device_attribute
1067 *devattr
, const char *buf
, size_t count
)
1069 struct f71882fg_data
*data
= dev_get_drvdata(dev
);
1070 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1071 int val
= simple_strtoul(buf
, NULL
, 10) / 1000;
1076 mutex_lock(&data
->update_lock
);
1077 f71882fg_write8(data
, F71882FG_REG_TEMP_OVT(nr
), val
);
1078 data
->temp_ovt
[nr
] = val
;
1079 mutex_unlock(&data
->update_lock
);
1084 static ssize_t
show_temp_crit_hyst(struct device
*dev
, struct device_attribute
1085 *devattr
, char *buf
)
1087 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1088 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1090 return sprintf(buf
, "%d\n",
1091 (data
->temp_ovt
[nr
] - data
->temp_hyst
[nr
]) * 1000);
1094 static ssize_t
show_temp_type(struct device
*dev
, struct device_attribute
1095 *devattr
, char *buf
)
1097 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1098 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1100 return sprintf(buf
, "%d\n", data
->temp_type
[nr
]);
1103 static ssize_t
show_temp_beep(struct device
*dev
, struct device_attribute
1104 *devattr
, char *buf
)
1106 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1107 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1109 if (data
->temp_beep
& (1 << nr
))
1110 return sprintf(buf
, "1\n");
1112 return sprintf(buf
, "0\n");
1115 static ssize_t
store_temp_beep(struct device
*dev
, struct device_attribute
1116 *devattr
, const char *buf
, size_t count
)
1118 struct f71882fg_data
*data
= dev_get_drvdata(dev
);
1119 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1120 int val
= simple_strtoul(buf
, NULL
, 10);
1122 mutex_lock(&data
->update_lock
);
1124 data
->temp_beep
|= 1 << nr
;
1126 data
->temp_beep
&= ~(1 << nr
);
1128 f71882fg_write8(data
, F71882FG_REG_TEMP_BEEP
, data
->temp_beep
);
1129 mutex_unlock(&data
->update_lock
);
1134 static ssize_t
show_temp_alarm(struct device
*dev
, struct device_attribute
1135 *devattr
, char *buf
)
1137 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1138 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1140 if (data
->temp_status
& (1 << nr
))
1141 return sprintf(buf
, "1\n");
1143 return sprintf(buf
, "0\n");
1146 static ssize_t
show_temp_fault(struct device
*dev
, struct device_attribute
1147 *devattr
, char *buf
)
1149 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1150 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1152 if (data
->temp_diode_open
& (1 << nr
))
1153 return sprintf(buf
, "1\n");
1155 return sprintf(buf
, "0\n");
1158 static ssize_t
show_pwm(struct device
*dev
,
1159 struct device_attribute
*devattr
, char *buf
)
1161 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1162 int val
, nr
= to_sensor_dev_attr_2(devattr
)->index
;
1163 if (data
->pwm_enable
& (1 << (2 * nr
)))
1165 val
= data
->pwm
[nr
];
1168 mutex_lock(&data
->update_lock
);
1169 val
= 255 * fan_from_reg(data
->fan_target
[nr
])
1170 / fan_from_reg(data
->fan_full_speed
[nr
]);
1171 mutex_unlock(&data
->update_lock
);
1173 return sprintf(buf
, "%d\n", val
);
1176 static ssize_t
store_pwm(struct device
*dev
,
1177 struct device_attribute
*devattr
, const char *buf
,
1180 /* struct f71882fg_data *data = dev_get_drvdata(dev); */
1181 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1182 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1183 long val
= simple_strtol(buf
, NULL
, 10);
1184 val
= SENSORS_LIMIT(val
, 0, 255);
1186 mutex_lock(&data
->update_lock
);
1187 if (data
->pwm_enable
& (1 << (2 * nr
))) {
1189 f71882fg_write8(data
, F71882FG_REG_PWM(nr
), val
);
1190 data
->pwm
[nr
] = val
;
1193 int target
= val
* fan_from_reg(data
->fan_full_speed
[nr
]) / 255;
1194 f71882fg_write16(data
, F71882FG_REG_FAN_TARGET(nr
),
1195 fan_to_reg(target
));
1196 data
->fan_target
[nr
] = fan_to_reg(target
);
1198 mutex_unlock(&data
->update_lock
);
1203 static ssize_t
show_pwm_enable(struct device
*dev
,
1204 struct device_attribute
*devattr
, char *buf
)
1207 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1208 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1210 if (data
->pwm_enable
& (2 << (2 * nr
)))
1215 return sprintf(buf
, "%d\n", result
);
1218 static ssize_t
store_pwm_enable(struct device
*dev
, struct device_attribute
1219 *devattr
, const char *buf
, size_t count
)
1221 struct f71882fg_data
*data
= dev_get_drvdata(dev
);
1222 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1223 long val
= simple_strtol(buf
, NULL
, 10);
1224 if (val
< 1 || val
> 2)
1227 mutex_lock(&data
->update_lock
);
1230 data
->pwm_enable
|= 2 << (2 * nr
);
1233 data
->pwm_enable
&= ~(2 << (2 * nr
));
1234 break; /* Temperature ctrl */
1236 if (data
->type
== f71882fg
) {
1237 switch (fan_mode
[nr
]) {
1239 data
->pwm_enable
|= 1 << (2 * nr
);
1240 break; /* Duty cycle mode */
1242 data
->pwm_enable
&= ~(1 << (2 * nr
));
1243 break; /* RPM mode */
1246 f71882fg_write8(data
, F71882FG_REG_PWM_ENABLE
, data
->pwm_enable
);
1247 mutex_unlock(&data
->update_lock
);
1252 static ssize_t
show_pwm_auto_point_pwm(struct device
*dev
,
1253 struct device_attribute
*devattr
,
1257 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1258 int pwm
= to_sensor_dev_attr_2(devattr
)->index
;
1259 int point
= to_sensor_dev_attr_2(devattr
)->nr
;
1261 if (data
->pwm_enable
& (1 << (2 * pwm
))) {
1263 result
= data
->pwm_auto_point_pwm
[pwm
][point
];
1266 result
= 32 * 255 / (32 + data
->pwm_auto_point_pwm
[pwm
][point
]);
1269 return sprintf(buf
, "%d\n", result
);
1272 static ssize_t
store_pwm_auto_point_pwm(struct device
*dev
,
1273 struct device_attribute
*devattr
,
1274 const char *buf
, size_t count
)
1276 /* struct f71882fg_data *data = dev_get_drvdata(dev); */
1277 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1278 int pwm
= to_sensor_dev_attr_2(devattr
)->index
;
1279 int point
= to_sensor_dev_attr_2(devattr
)->nr
;
1280 int val
= simple_strtoul(buf
, NULL
, 10);
1281 val
= SENSORS_LIMIT(val
, 0, 255);
1283 mutex_lock(&data
->update_lock
);
1284 if (data
->pwm_enable
& (1 << (2 * pwm
))) {
1288 if (val
< 29) /* Prevent negative numbers */
1291 val
= (255 - val
) * 32 / val
;
1293 f71882fg_write8(data
, F71882FG_REG_POINT_PWM(pwm
, point
), val
);
1294 data
->pwm_auto_point_pwm
[pwm
][point
] = val
;
1295 mutex_unlock(&data
->update_lock
);
1300 static ssize_t
show_pwm_auto_point_temp_hyst(struct device
*dev
,
1301 struct device_attribute
*devattr
,
1305 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1306 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1307 int point
= to_sensor_dev_attr_2(devattr
)->nr
;
1309 mutex_lock(&data
->update_lock
);
1312 result
= data
->pwm_auto_point_hyst
[0] & 0x0f;
1315 result
= data
->pwm_auto_point_hyst
[0] >> 4;
1318 result
= data
->pwm_auto_point_hyst
[1] & 0x0f;
1321 result
= data
->pwm_auto_point_hyst
[1] >> 4;
1324 result
= 1000 * (data
->pwm_auto_point_temp
[nr
][point
] - result
);
1325 mutex_unlock(&data
->update_lock
);
1327 return sprintf(buf
, "%d\n", result
);
1330 static ssize_t
store_pwm_auto_point_temp_hyst(struct device
*dev
,
1331 struct device_attribute
*devattr
,
1332 const char *buf
, size_t count
)
1334 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1335 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1336 int point
= to_sensor_dev_attr_2(devattr
)->nr
;
1337 long val
= simple_strtol(buf
, NULL
, 10) / 1000;
1339 mutex_lock(&data
->update_lock
);
1340 val
= SENSORS_LIMIT(val
, data
->pwm_auto_point_temp
[nr
][point
] - 15,
1341 data
->pwm_auto_point_temp
[nr
][point
]);
1342 val
= data
->pwm_auto_point_temp
[nr
][point
] - val
;
1346 val
= (data
->pwm_auto_point_hyst
[0] & 0xf0) | val
;
1349 val
= (data
->pwm_auto_point_hyst
[0] & 0x0f) | (val
<< 4);
1352 val
= (data
->pwm_auto_point_hyst
[1] & 0xf0) | val
;
1355 val
= (data
->pwm_auto_point_hyst
[1] & 0x0f) | (val
<< 4);
1358 if (nr
== 0 || nr
== 1) {
1359 f71882fg_write8(data
, F71882FG_REG_FAN_HYST0
, val
);
1360 data
->pwm_auto_point_hyst
[0] = val
;
1362 f71882fg_write8(data
, F71882FG_REG_FAN_HYST1
, val
);
1363 data
->pwm_auto_point_hyst
[1] = val
;
1365 mutex_unlock(&data
->update_lock
);
1370 static ssize_t
show_pwm_interpolate(struct device
*dev
,
1371 struct device_attribute
*devattr
, char *buf
)
1374 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1375 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1377 result
= (data
->pwm_auto_point_mapping
[nr
] >> 4) & 1;
1379 return sprintf(buf
, "%d\n", result
);
1382 static ssize_t
store_pwm_interpolate(struct device
*dev
,
1383 struct device_attribute
*devattr
,
1384 const char *buf
, size_t count
)
1386 /* struct f71882fg_data *data = dev_get_drvdata(dev); */
1387 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1388 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1389 int val
= simple_strtoul(buf
, NULL
, 10);
1390 mutex_lock(&data
->update_lock
);
1392 val
= data
->pwm_auto_point_mapping
[nr
] | (1 << 4);
1394 val
= data
->pwm_auto_point_mapping
[nr
] & (~(1 << 4));
1395 f71882fg_write8(data
, F71882FG_REG_POINT_MAPPING(nr
), val
);
1396 data
->pwm_auto_point_mapping
[nr
] = val
;
1397 mutex_unlock(&data
->update_lock
);
1402 static ssize_t
show_pwm_auto_point_channel(struct device
*dev
,
1403 struct device_attribute
*devattr
,
1407 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1408 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1410 result
= 1 << ((data
->pwm_auto_point_mapping
[nr
] & 3) - 1);
1412 return sprintf(buf
, "%d\n", result
);
1415 static ssize_t
store_pwm_auto_point_channel(struct device
*dev
,
1416 struct device_attribute
*devattr
,
1417 const char *buf
, size_t count
)
1419 /* struct f71882fg_data *data = dev_get_drvdata(dev); */
1420 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1421 int nr
= to_sensor_dev_attr_2(devattr
)->index
;
1422 long val
= simple_strtol(buf
, NULL
, 10);
1436 mutex_lock(&data
->update_lock
);
1437 val
= (data
->pwm_auto_point_mapping
[nr
] & 0xfc) | val
;
1438 f71882fg_write8(data
, F71882FG_REG_POINT_MAPPING(nr
), val
);
1439 data
->pwm_auto_point_mapping
[nr
] = val
;
1440 mutex_unlock(&data
->update_lock
);
1445 static ssize_t
show_pwm_auto_point_temp(struct device
*dev
,
1446 struct device_attribute
*devattr
,
1450 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1451 int pwm
= to_sensor_dev_attr_2(devattr
)->index
;
1452 int point
= to_sensor_dev_attr_2(devattr
)->nr
;
1454 result
= data
->pwm_auto_point_temp
[pwm
][point
];
1455 return sprintf(buf
, "%d\n", 1000 * result
);
1458 static ssize_t
store_pwm_auto_point_temp(struct device
*dev
,
1459 struct device_attribute
*devattr
,
1460 const char *buf
, size_t count
)
1462 /* struct f71882fg_data *data = dev_get_drvdata(dev); */
1463 struct f71882fg_data
*data
= f71882fg_update_device(dev
);
1464 int pwm
= to_sensor_dev_attr_2(devattr
)->index
;
1465 int point
= to_sensor_dev_attr_2(devattr
)->nr
;
1466 long val
= simple_strtol(buf
, NULL
, 10) / 1000;
1467 val
= SENSORS_LIMIT(val
, 0, 255);
1469 mutex_lock(&data
->update_lock
);
1470 f71882fg_write8(data
, F71882FG_REG_POINT_TEMP(pwm
, point
), val
);
1471 data
->pwm_auto_point_temp
[pwm
][point
] = val
;
1472 mutex_unlock(&data
->update_lock
);
1477 static ssize_t
show_name(struct device
*dev
, struct device_attribute
*devattr
,
1480 struct f71882fg_data
*data
= dev_get_drvdata(dev
);
1481 return sprintf(buf
, "%s\n", f71882fg_names
[data
->type
]);
1484 static int __devinit
f71882fg_create_sysfs_files(struct platform_device
*pdev
,
1485 struct sensor_device_attribute_2
*attr
, int count
)
1489 for (i
= 0; i
< count
; i
++) {
1490 err
= device_create_file(&pdev
->dev
, &attr
[i
].dev_attr
);
1497 static int __devinit
f71882fg_probe(struct platform_device
*pdev
)
1499 struct f71882fg_data
*data
;
1500 struct f71882fg_sio_data
*sio_data
= pdev
->dev
.platform_data
;
1504 data
= kzalloc(sizeof(struct f71882fg_data
), GFP_KERNEL
);
1508 data
->addr
= platform_get_resource(pdev
, IORESOURCE_IO
, 0)->start
;
1509 data
->type
= sio_data
->type
;
1510 mutex_init(&data
->update_lock
);
1511 platform_set_drvdata(pdev
, data
);
1513 start_reg
= f71882fg_read8(data
, F71882FG_REG_START
);
1514 if (!(start_reg
& 0x03)) {
1515 dev_warn(&pdev
->dev
, "Hardware monitoring not activated\n");
1520 /* If it is a 71862 and the fan / pwm part is enabled sanity check
1522 if (data
->type
== f71862fg
&& (start_reg
& 0x02)) {
1523 u8 reg
= f71882fg_read8(data
, F71882FG_REG_PWM_ENABLE
);
1524 if ((reg
& 0x15) != 0x15) {
1526 "Invalid (reserved) pwm settings: 0x%02x\n",
1533 /* Register sysfs interface files */
1534 err
= device_create_file(&pdev
->dev
, &dev_attr_name
);
1536 goto exit_unregister_sysfs
;
1538 if (start_reg
& 0x01) {
1539 err
= f71882fg_create_sysfs_files(pdev
, f718x2fg_in_temp_attr
,
1540 ARRAY_SIZE(f718x2fg_in_temp_attr
));
1542 goto exit_unregister_sysfs
;
1544 if (data
->type
== f71882fg
) {
1545 err
= f71882fg_create_sysfs_files(pdev
,
1546 f71882fg_in_temp_attr
,
1547 ARRAY_SIZE(f71882fg_in_temp_attr
));
1549 goto exit_unregister_sysfs
;
1553 if (start_reg
& 0x02) {
1554 err
= f71882fg_create_sysfs_files(pdev
, f718x2fg_fan_attr
,
1555 ARRAY_SIZE(f718x2fg_fan_attr
));
1557 goto exit_unregister_sysfs
;
1559 if (data
->type
== f71862fg
) {
1560 err
= f71882fg_create_sysfs_files(pdev
,
1562 ARRAY_SIZE(f71862fg_fan_attr
));
1564 err
= f71882fg_create_sysfs_files(pdev
,
1566 ARRAY_SIZE(f71882fg_fan_attr
));
1569 goto exit_unregister_sysfs
;
1572 data
->hwmon_dev
= hwmon_device_register(&pdev
->dev
);
1573 if (IS_ERR(data
->hwmon_dev
)) {
1574 err
= PTR_ERR(data
->hwmon_dev
);
1575 data
->hwmon_dev
= NULL
;
1576 goto exit_unregister_sysfs
;
1581 exit_unregister_sysfs
:
1582 f71882fg_remove(pdev
); /* Will unregister the sysfs files for us */
1583 return err
; /* f71882fg_remove() also frees our data */
1589 static int f71882fg_remove(struct platform_device
*pdev
)
1592 struct f71882fg_data
*data
= platform_get_drvdata(pdev
);
1594 platform_set_drvdata(pdev
, NULL
);
1595 if (data
->hwmon_dev
)
1596 hwmon_device_unregister(data
->hwmon_dev
);
1598 device_remove_file(&pdev
->dev
, &dev_attr_name
);
1600 for (i
= 0; i
< ARRAY_SIZE(f718x2fg_in_temp_attr
); i
++)
1601 device_remove_file(&pdev
->dev
,
1602 &f718x2fg_in_temp_attr
[i
].dev_attr
);
1604 for (i
= 0; i
< ARRAY_SIZE(f71882fg_in_temp_attr
); i
++)
1605 device_remove_file(&pdev
->dev
,
1606 &f71882fg_in_temp_attr
[i
].dev_attr
);
1608 for (i
= 0; i
< ARRAY_SIZE(f718x2fg_fan_attr
); i
++)
1609 device_remove_file(&pdev
->dev
, &f718x2fg_fan_attr
[i
].dev_attr
);
1611 for (i
= 0; i
< ARRAY_SIZE(f71862fg_fan_attr
); i
++)
1612 device_remove_file(&pdev
->dev
, &f71862fg_fan_attr
[i
].dev_attr
);
1614 for (i
= 0; i
< ARRAY_SIZE(f71882fg_fan_attr
); i
++)
1615 device_remove_file(&pdev
->dev
, &f71882fg_fan_attr
[i
].dev_attr
);
1622 static int __init
f71882fg_find(int sioaddr
, unsigned short *address
,
1623 struct f71882fg_sio_data
*sio_data
)
1628 superio_enter(sioaddr
);
1630 devid
= superio_inw(sioaddr
, SIO_REG_MANID
);
1631 if (devid
!= SIO_FINTEK_ID
) {
1632 printk(KERN_INFO DRVNAME
": Not a Fintek device\n");
1636 devid
= force_id
? force_id
: superio_inw(sioaddr
, SIO_REG_DEVID
);
1639 sio_data
->type
= f71862fg
;
1642 sio_data
->type
= f71882fg
;
1645 printk(KERN_INFO DRVNAME
": Unsupported Fintek device\n");
1649 superio_select(sioaddr
, SIO_F71882FG_LD_HWM
);
1650 if (!(superio_inb(sioaddr
, SIO_REG_ENABLE
) & 0x01)) {
1651 printk(KERN_WARNING DRVNAME
": Device not activated\n");
1655 *address
= superio_inw(sioaddr
, SIO_REG_ADDR
);
1658 printk(KERN_WARNING DRVNAME
": Base address not set\n");
1661 *address
&= ~(REGION_LENGTH
- 1); /* Ignore 3 LSB */
1664 printk(KERN_INFO DRVNAME
": Found %s chip at %#x, revision %d\n",
1665 f71882fg_names
[sio_data
->type
], (unsigned int)*address
,
1666 (int)superio_inb(sioaddr
, SIO_REG_DEVREV
));
1668 superio_exit(sioaddr
);
1672 static int __init
f71882fg_device_add(unsigned short address
,
1673 const struct f71882fg_sio_data
*sio_data
)
1675 struct resource res
= {
1677 .end
= address
+ REGION_LENGTH
- 1,
1678 .flags
= IORESOURCE_IO
,
1682 f71882fg_pdev
= platform_device_alloc(DRVNAME
, address
);
1686 res
.name
= f71882fg_pdev
->name
;
1687 err
= platform_device_add_resources(f71882fg_pdev
, &res
, 1);
1689 printk(KERN_ERR DRVNAME
": Device resource addition failed\n");
1690 goto exit_device_put
;
1693 err
= platform_device_add_data(f71882fg_pdev
, sio_data
,
1694 sizeof(struct f71882fg_sio_data
));
1696 printk(KERN_ERR DRVNAME
": Platform data allocation failed\n");
1697 goto exit_device_put
;
1700 err
= platform_device_add(f71882fg_pdev
);
1702 printk(KERN_ERR DRVNAME
": Device addition failed\n");
1703 goto exit_device_put
;
1709 platform_device_put(f71882fg_pdev
);
1714 static int __init
f71882fg_init(void)
1717 unsigned short address
;
1718 struct f71882fg_sio_data sio_data
;
1720 memset(&sio_data
, 0, sizeof(sio_data
));
1722 if (f71882fg_find(0x2e, &address
, &sio_data
) &&
1723 f71882fg_find(0x4e, &address
, &sio_data
))
1726 err
= platform_driver_register(&f71882fg_driver
);
1730 err
= f71882fg_device_add(address
, &sio_data
);
1737 platform_driver_unregister(&f71882fg_driver
);
1742 static void __exit
f71882fg_exit(void)
1744 platform_device_unregister(f71882fg_pdev
);
1745 platform_driver_unregister(&f71882fg_driver
);
1748 MODULE_DESCRIPTION("F71882FG Hardware Monitoring Driver");
1749 MODULE_AUTHOR("Hans Edgington, Hans de Goede (hdegoede@redhat.com)");
1750 MODULE_LICENSE("GPL");
1752 module_init(f71882fg_init
);
1753 module_exit(f71882fg_exit
);