aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/f71882fg.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/f71882fg.c')
-rw-r--r--drivers/hwmon/f71882fg.c522
1 files changed, 358 insertions, 164 deletions
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 6e06019015a5..a4d430ee7e20 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -1,6 +1,6 @@
1/*************************************************************************** 1/***************************************************************************
2 * Copyright (C) 2006 by Hans Edgington <hans@edgington.nl> * 2 * Copyright (C) 2006 by Hans Edgington <hans@edgington.nl> *
3 * Copyright (C) 2007-2009 Hans de Goede <hdegoede@redhat.com> * 3 * Copyright (C) 2007-2011 Hans de Goede <hdegoede@redhat.com> *
4 * * 4 * *
5 * This program is free software; you can redistribute it and/or modify * 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 * 6 * it under the terms of the GNU General Public License as published by *
@@ -47,22 +47,23 @@
47#define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ 47#define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */
48 48
49#define SIO_FINTEK_ID 0x1934 /* Manufacturers ID */ 49#define SIO_FINTEK_ID 0x1934 /* Manufacturers ID */
50#define SIO_F71808E_ID 0x0901 /* Chipset ID */
50#define SIO_F71858_ID 0x0507 /* Chipset ID */ 51#define SIO_F71858_ID 0x0507 /* Chipset ID */
51#define SIO_F71862_ID 0x0601 /* Chipset ID */ 52#define SIO_F71862_ID 0x0601 /* Chipset ID */
53#define SIO_F71869_ID 0x0814 /* Chipset ID */
52#define SIO_F71882_ID 0x0541 /* Chipset ID */ 54#define SIO_F71882_ID 0x0541 /* Chipset ID */
53#define SIO_F71889_ID 0x0723 /* Chipset ID */ 55#define SIO_F71889_ID 0x0723 /* Chipset ID */
56#define SIO_F71889E_ID 0x0909 /* Chipset ID */
54#define SIO_F8000_ID 0x0581 /* Chipset ID */ 57#define SIO_F8000_ID 0x0581 /* Chipset ID */
55 58
56#define REGION_LENGTH 8 59#define REGION_LENGTH 8
57#define ADDR_REG_OFFSET 5 60#define ADDR_REG_OFFSET 5
58#define DATA_REG_OFFSET 6 61#define DATA_REG_OFFSET 6
59 62
60#define F71882FG_REG_PECI 0x0A 63#define F71882FG_REG_IN_STATUS 0x12 /* f7188x only */
61 64#define F71882FG_REG_IN_BEEP 0x13 /* f7188x only */
62#define F71882FG_REG_IN_STATUS 0x12 /* f71882fg only */
63#define F71882FG_REG_IN_BEEP 0x13 /* f71882fg only */
64#define F71882FG_REG_IN(nr) (0x20 + (nr)) 65#define F71882FG_REG_IN(nr) (0x20 + (nr))
65#define F71882FG_REG_IN1_HIGH 0x32 /* f71882fg only */ 66#define F71882FG_REG_IN1_HIGH 0x32 /* f7188x only */
66 67
67#define F71882FG_REG_FAN(nr) (0xA0 + (16 * (nr))) 68#define F71882FG_REG_FAN(nr) (0xA0 + (16 * (nr)))
68#define F71882FG_REG_FAN_TARGET(nr) (0xA2 + (16 * (nr))) 69#define F71882FG_REG_FAN_TARGET(nr) (0xA2 + (16 * (nr)))
@@ -86,28 +87,71 @@
86 87
87#define F71882FG_REG_FAN_HYST(nr) (0x98 + (nr)) 88#define F71882FG_REG_FAN_HYST(nr) (0x98 + (nr))
88 89
90#define F71882FG_REG_FAN_FAULT_T 0x9F
91#define F71882FG_FAN_NEG_TEMP_EN 0x20
92#define F71882FG_FAN_PROG_SEL 0x80
93
89#define F71882FG_REG_POINT_PWM(pwm, point) (0xAA + (point) + (16 * (pwm))) 94#define F71882FG_REG_POINT_PWM(pwm, point) (0xAA + (point) + (16 * (pwm)))
90#define F71882FG_REG_POINT_TEMP(pwm, point) (0xA6 + (point) + (16 * (pwm))) 95#define F71882FG_REG_POINT_TEMP(pwm, point) (0xA6 + (point) + (16 * (pwm)))
91#define F71882FG_REG_POINT_MAPPING(nr) (0xAF + 16 * (nr)) 96#define F71882FG_REG_POINT_MAPPING(nr) (0xAF + 16 * (nr))
92 97
93#define F71882FG_REG_START 0x01 98#define F71882FG_REG_START 0x01
94 99
100#define F71882FG_MAX_INS 9
101
95#define FAN_MIN_DETECT 366 /* Lowest detectable fanspeed */ 102#define FAN_MIN_DETECT 366 /* Lowest detectable fanspeed */
96 103
97static unsigned short force_id; 104static unsigned short force_id;
98module_param(force_id, ushort, 0); 105module_param(force_id, ushort, 0);
99MODULE_PARM_DESC(force_id, "Override the detected device ID"); 106MODULE_PARM_DESC(force_id, "Override the detected device ID");
100 107
101enum chips { f71858fg, f71862fg, f71882fg, f71889fg, f8000 }; 108enum chips { f71808e, f71858fg, f71862fg, f71869, f71882fg, f71889fg,
109 f71889ed, f8000 };
102 110
103static const char *f71882fg_names[] = { 111static const char *f71882fg_names[] = {
112 "f71808e",
104 "f71858fg", 113 "f71858fg",
105 "f71862fg", 114 "f71862fg",
115 "f71869", /* Both f71869f and f71869e, reg. compatible and same id */
106 "f71882fg", 116 "f71882fg",
107 "f71889fg", 117 "f71889fg",
118 "f71889ed",
108 "f8000", 119 "f8000",
109}; 120};
110 121
122static const char f71882fg_has_in[8][F71882FG_MAX_INS] = {
123 { 1, 1, 1, 1, 1, 1, 0, 1, 1 }, /* f71808e */
124 { 1, 1, 1, 0, 0, 0, 0, 0, 0 }, /* f71858fg */
125 { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* f71862fg */
126 { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* f71869 */
127 { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* f71882fg */
128 { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* f71889fg */
129 { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* f71889ed */
130 { 1, 1, 1, 0, 0, 0, 0, 0, 0 }, /* f8000 */
131};
132
133static const char f71882fg_has_in1_alarm[8] = {
134 0, /* f71808e */
135 0, /* f71858fg */
136 0, /* f71862fg */
137 0, /* f71869 */
138 1, /* f71882fg */
139 1, /* f71889fg */
140 1, /* f71889ed */
141 0, /* f8000 */
142};
143
144static const char f71882fg_has_beep[8] = {
145 0, /* f71808e */
146 0, /* f71858fg */
147 1, /* f71862fg */
148 1, /* f71869 */
149 1, /* f71882fg */
150 1, /* f71889fg */
151 1, /* f71889ed */
152 0, /* f8000 */
153};
154
111static struct platform_device *f71882fg_pdev; 155static struct platform_device *f71882fg_pdev;
112 156
113/* Super-I/O Function prototypes */ 157/* Super-I/O Function prototypes */
@@ -129,11 +173,12 @@ struct f71882fg_data {
129 struct mutex update_lock; 173 struct mutex update_lock;
130 int temp_start; /* temp numbering start (0 or 1) */ 174 int temp_start; /* temp numbering start (0 or 1) */
131 char valid; /* !=0 if following fields are valid */ 175 char valid; /* !=0 if following fields are valid */
176 char auto_point_temp_signed;
132 unsigned long last_updated; /* In jiffies */ 177 unsigned long last_updated; /* In jiffies */
133 unsigned long last_limits; /* In jiffies */ 178 unsigned long last_limits; /* In jiffies */
134 179
135 /* Register Values */ 180 /* Register Values */
136 u8 in[9]; 181 u8 in[F71882FG_MAX_INS];
137 u8 in1_max; 182 u8 in1_max;
138 u8 in_status; 183 u8 in_status;
139 u8 in_beep; 184 u8 in_beep;
@@ -142,7 +187,7 @@ struct f71882fg_data {
142 u16 fan_full_speed[4]; 187 u16 fan_full_speed[4];
143 u8 fan_status; 188 u8 fan_status;
144 u8 fan_beep; 189 u8 fan_beep;
145 /* Note: all models have only 3 temperature channels, but on some 190 /* Note: all models have max 3 temperature channels, but on some
146 they are addressed as 0-2 and on others as 1-3, so for coding 191 they are addressed as 0-2 and on others as 1-3, so for coding
147 convenience we reserve space for 4 channels */ 192 convenience we reserve space for 4 channels */
148 u16 temp[4]; 193 u16 temp[4];
@@ -262,13 +307,9 @@ static struct platform_driver f71882fg_driver = {
262 307
263static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); 308static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
264 309
265/* Temp and in attr for the f71858fg, the f71858fg is special as it 310/* Temp attr for the f71858fg, the f71858fg is special as it has its
266 has its temperature indexes start at 0 (the others start at 1) and 311 temperature indexes start at 0 (the others start at 1) */
267 it only has 3 voltage inputs */ 312static struct sensor_device_attribute_2 f71858fg_temp_attr[] = {
268static struct sensor_device_attribute_2 f71858fg_in_temp_attr[] = {
269 SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
270 SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
271 SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
272 SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0), 313 SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0),
273 SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max, 314 SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max,
274 store_temp_max, 0, 0), 315 store_temp_max, 0, 0),
@@ -292,7 +333,6 @@ static struct sensor_device_attribute_2 f71858fg_in_temp_attr[] = {
292 SENSOR_ATTR_2(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 333 SENSOR_ATTR_2(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
293 0, 1), 334 0, 1),
294 SENSOR_ATTR_2(temp2_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5), 335 SENSOR_ATTR_2(temp2_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5),
295 SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 1),
296 SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 1), 336 SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 1),
297 SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2), 337 SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2),
298 SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max, 338 SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max,
@@ -308,17 +348,8 @@ static struct sensor_device_attribute_2 f71858fg_in_temp_attr[] = {
308 SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2), 348 SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
309}; 349};
310 350
311/* Temp and in attr common to the f71862fg, f71882fg and f71889fg */ 351/* Temp attr for the standard models */
312static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = { 352static struct sensor_device_attribute_2 fxxxx_temp_attr[3][9] = { {
313 SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
314 SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
315 SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
316 SENSOR_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 0, 3),
317 SENSOR_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 0, 4),
318 SENSOR_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 0, 5),
319 SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 6),
320 SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 7),
321 SENSOR_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 0, 8),
322 SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 1), 353 SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 1),
323 SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max, 354 SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max,
324 store_temp_max, 0, 1), 355 store_temp_max, 0, 1),
@@ -328,17 +359,14 @@ static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = {
328 the max and crit alarms separately and lm_sensors v2 depends on the 359 the max and crit alarms separately and lm_sensors v2 depends on the
329 presence of temp#_alarm files. The same goes for temp2/3 _alarm. */ 360 presence of temp#_alarm files. The same goes for temp2/3 _alarm. */
330 SENSOR_ATTR_2(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 1), 361 SENSOR_ATTR_2(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 1),
331 SENSOR_ATTR_2(temp1_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
332 store_temp_beep, 0, 1),
333 SENSOR_ATTR_2(temp1_crit, S_IRUGO|S_IWUSR, show_temp_crit, 362 SENSOR_ATTR_2(temp1_crit, S_IRUGO|S_IWUSR, show_temp_crit,
334 store_temp_crit, 0, 1), 363 store_temp_crit, 0, 1),
335 SENSOR_ATTR_2(temp1_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 364 SENSOR_ATTR_2(temp1_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
336 0, 1), 365 0, 1),
337 SENSOR_ATTR_2(temp1_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5), 366 SENSOR_ATTR_2(temp1_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5),
338 SENSOR_ATTR_2(temp1_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
339 store_temp_beep, 0, 5),
340 SENSOR_ATTR_2(temp1_type, S_IRUGO, show_temp_type, NULL, 0, 1), 367 SENSOR_ATTR_2(temp1_type, S_IRUGO, show_temp_type, NULL, 0, 1),
341 SENSOR_ATTR_2(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0, 1), 368 SENSOR_ATTR_2(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0, 1),
369}, {
342 SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 2), 370 SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 2),
343 SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_max, 371 SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_max,
344 store_temp_max, 0, 2), 372 store_temp_max, 0, 2),
@@ -346,17 +374,14 @@ static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = {
346 store_temp_max_hyst, 0, 2), 374 store_temp_max_hyst, 0, 2),
347 /* Should be temp2_max_alarm, see temp1_alarm note */ 375 /* Should be temp2_max_alarm, see temp1_alarm note */
348 SENSOR_ATTR_2(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 2), 376 SENSOR_ATTR_2(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 2),
349 SENSOR_ATTR_2(temp2_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
350 store_temp_beep, 0, 2),
351 SENSOR_ATTR_2(temp2_crit, S_IRUGO|S_IWUSR, show_temp_crit, 377 SENSOR_ATTR_2(temp2_crit, S_IRUGO|S_IWUSR, show_temp_crit,
352 store_temp_crit, 0, 2), 378 store_temp_crit, 0, 2),
353 SENSOR_ATTR_2(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 379 SENSOR_ATTR_2(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
354 0, 2), 380 0, 2),
355 SENSOR_ATTR_2(temp2_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6), 381 SENSOR_ATTR_2(temp2_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6),
356 SENSOR_ATTR_2(temp2_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
357 store_temp_beep, 0, 6),
358 SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 2), 382 SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 2),
359 SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 2), 383 SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
384}, {
360 SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 3), 385 SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 3),
361 SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max, 386 SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max,
362 store_temp_max, 0, 3), 387 store_temp_max, 0, 3),
@@ -364,37 +389,39 @@ static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = {
364 store_temp_max_hyst, 0, 3), 389 store_temp_max_hyst, 0, 3),
365 /* Should be temp3_max_alarm, see temp1_alarm note */ 390 /* Should be temp3_max_alarm, see temp1_alarm note */
366 SENSOR_ATTR_2(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 3), 391 SENSOR_ATTR_2(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 3),
367 SENSOR_ATTR_2(temp3_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
368 store_temp_beep, 0, 3),
369 SENSOR_ATTR_2(temp3_crit, S_IRUGO|S_IWUSR, show_temp_crit, 392 SENSOR_ATTR_2(temp3_crit, S_IRUGO|S_IWUSR, show_temp_crit,
370 store_temp_crit, 0, 3), 393 store_temp_crit, 0, 3),
371 SENSOR_ATTR_2(temp3_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 394 SENSOR_ATTR_2(temp3_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
372 0, 3), 395 0, 3),
373 SENSOR_ATTR_2(temp3_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 7), 396 SENSOR_ATTR_2(temp3_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 7),
374 SENSOR_ATTR_2(temp3_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
375 store_temp_beep, 0, 7),
376 SENSOR_ATTR_2(temp3_type, S_IRUGO, show_temp_type, NULL, 0, 3), 397 SENSOR_ATTR_2(temp3_type, S_IRUGO, show_temp_type, NULL, 0, 3),
377 SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 3), 398 SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 3),
378}; 399} };
379 400
380/* For models with in1 alarm capability */ 401/* Temp attr for models which can beep on temp alarm */
381static struct sensor_device_attribute_2 fxxxx_in1_alarm_attr[] = { 402static struct sensor_device_attribute_2 fxxxx_temp_beep_attr[3][2] = { {
382 SENSOR_ATTR_2(in1_max, S_IRUGO|S_IWUSR, show_in_max, store_in_max, 403 SENSOR_ATTR_2(temp1_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
383 0, 1), 404 store_temp_beep, 0, 1),
384 SENSOR_ATTR_2(in1_beep, S_IRUGO|S_IWUSR, show_in_beep, store_in_beep, 405 SENSOR_ATTR_2(temp1_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
385 0, 1), 406 store_temp_beep, 0, 5),
386 SENSOR_ATTR_2(in1_alarm, S_IRUGO, show_in_alarm, NULL, 0, 1), 407}, {
387}; 408 SENSOR_ATTR_2(temp2_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
409 store_temp_beep, 0, 2),
410 SENSOR_ATTR_2(temp2_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
411 store_temp_beep, 0, 6),
412}, {
413 SENSOR_ATTR_2(temp3_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
414 store_temp_beep, 0, 3),
415 SENSOR_ATTR_2(temp3_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
416 store_temp_beep, 0, 7),
417} };
388 418
389/* Temp and in attr for the f8000 419/* Temp attr for the f8000
390 Note on the f8000 temp_ovt (crit) is used as max, and temp_high (max) 420 Note on the f8000 temp_ovt (crit) is used as max, and temp_high (max)
391 is used as hysteresis value to clear alarms 421 is used as hysteresis value to clear alarms
392 Also like the f71858fg its temperature indexes start at 0 422 Also like the f71858fg its temperature indexes start at 0
393 */ 423 */
394static struct sensor_device_attribute_2 f8000_in_temp_attr[] = { 424static struct sensor_device_attribute_2 f8000_temp_attr[] = {
395 SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
396 SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
397 SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
398 SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0), 425 SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0),
399 SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_crit, 426 SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_crit,
400 store_temp_crit, 0, 0), 427 store_temp_crit, 0, 0),
@@ -408,7 +435,6 @@ static struct sensor_device_attribute_2 f8000_in_temp_attr[] = {
408 SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max, 435 SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max,
409 store_temp_max, 0, 1), 436 store_temp_max, 0, 1),
410 SENSOR_ATTR_2(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5), 437 SENSOR_ATTR_2(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5),
411 SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 1),
412 SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 1), 438 SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 1),
413 SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2), 439 SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2),
414 SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_crit, 440 SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_crit,
@@ -419,6 +445,28 @@ static struct sensor_device_attribute_2 f8000_in_temp_attr[] = {
419 SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2), 445 SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
420}; 446};
421 447
448/* in attr for all models */
449static struct sensor_device_attribute_2 fxxxx_in_attr[] = {
450 SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
451 SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
452 SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
453 SENSOR_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 0, 3),
454 SENSOR_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 0, 4),
455 SENSOR_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 0, 5),
456 SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 6),
457 SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 7),
458 SENSOR_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 0, 8),
459};
460
461/* For models with in1 alarm capability */
462static struct sensor_device_attribute_2 fxxxx_in1_alarm_attr[] = {
463 SENSOR_ATTR_2(in1_max, S_IRUGO|S_IWUSR, show_in_max, store_in_max,
464 0, 1),
465 SENSOR_ATTR_2(in1_beep, S_IRUGO|S_IWUSR, show_in_beep, store_in_beep,
466 0, 1),
467 SENSOR_ATTR_2(in1_alarm, S_IRUGO, show_in_alarm, NULL, 0, 1),
468};
469
422/* Fan / PWM attr common to all models */ 470/* Fan / PWM attr common to all models */
423static struct sensor_device_attribute_2 fxxxx_fan_attr[4][6] = { { 471static struct sensor_device_attribute_2 fxxxx_fan_attr[4][6] = { {
424 SENSOR_ATTR_2(fan1_input, S_IRUGO, show_fan, NULL, 0, 0), 472 SENSOR_ATTR_2(fan1_input, S_IRUGO, show_fan, NULL, 0, 0),
@@ -479,7 +527,7 @@ static struct sensor_device_attribute_2 fxxxx_fan_beep_attr[] = {
479}; 527};
480 528
481/* PWM attr for the f71862fg, fewer pwms and fewer zones per pwm than the 529/* PWM attr for the f71862fg, fewer pwms and fewer zones per pwm than the
482 f71858fg / f71882fg / f71889fg */ 530 standard models */
483static struct sensor_device_attribute_2 f71862fg_auto_pwm_attr[] = { 531static struct sensor_device_attribute_2 f71862fg_auto_pwm_attr[] = {
484 SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR, 532 SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
485 show_pwm_auto_point_channel, 533 show_pwm_auto_point_channel,
@@ -548,7 +596,87 @@ static struct sensor_device_attribute_2 f71862fg_auto_pwm_attr[] = {
548 show_pwm_auto_point_temp_hyst, NULL, 3, 2), 596 show_pwm_auto_point_temp_hyst, NULL, 3, 2),
549}; 597};
550 598
551/* PWM attr common to the f71858fg, f71882fg and f71889fg */ 599/* PWM attr for the f71808e/f71869, almost identical to the f71862fg, but the
600 pwm setting when the temperature is above the pwmX_auto_point1_temp can be
601 programmed instead of being hardcoded to 0xff */
602static struct sensor_device_attribute_2 f71869_auto_pwm_attr[] = {
603 SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
604 show_pwm_auto_point_channel,
605 store_pwm_auto_point_channel, 0, 0),
606 SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,
607 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
608 0, 0),
609 SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO|S_IWUSR,
610 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
611 1, 0),
612 SENSOR_ATTR_2(pwm1_auto_point3_pwm, S_IRUGO|S_IWUSR,
613 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
614 4, 0),
615 SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IRUGO|S_IWUSR,
616 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
617 0, 0),
618 SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IRUGO|S_IWUSR,
619 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
620 3, 0),
621 SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
622 show_pwm_auto_point_temp_hyst,
623 store_pwm_auto_point_temp_hyst,
624 0, 0),
625 SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO,
626 show_pwm_auto_point_temp_hyst, NULL, 3, 0),
627
628 SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,
629 show_pwm_auto_point_channel,
630 store_pwm_auto_point_channel, 0, 1),
631 SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR,
632 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
633 0, 1),
634 SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO|S_IWUSR,
635 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
636 1, 1),
637 SENSOR_ATTR_2(pwm2_auto_point3_pwm, S_IRUGO|S_IWUSR,
638 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
639 4, 1),
640 SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IRUGO|S_IWUSR,
641 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
642 0, 1),
643 SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IRUGO|S_IWUSR,
644 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
645 3, 1),
646 SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
647 show_pwm_auto_point_temp_hyst,
648 store_pwm_auto_point_temp_hyst,
649 0, 1),
650 SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO,
651 show_pwm_auto_point_temp_hyst, NULL, 3, 1),
652
653 SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
654 show_pwm_auto_point_channel,
655 store_pwm_auto_point_channel, 0, 2),
656 SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR,
657 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
658 0, 2),
659 SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO|S_IWUSR,
660 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
661 1, 2),
662 SENSOR_ATTR_2(pwm3_auto_point3_pwm, S_IRUGO|S_IWUSR,
663 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
664 4, 2),
665 SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IRUGO|S_IWUSR,
666 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
667 0, 2),
668 SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IRUGO|S_IWUSR,
669 show_pwm_auto_point_temp, store_pwm_auto_point_temp,
670 3, 2),
671 SENSOR_ATTR_2(pwm3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
672 show_pwm_auto_point_temp_hyst,
673 store_pwm_auto_point_temp_hyst,
674 0, 2),
675 SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst, S_IRUGO,
676 show_pwm_auto_point_temp_hyst, NULL, 3, 2),
677};
678
679/* PWM attr for the standard models */
552static struct sensor_device_attribute_2 fxxxx_auto_pwm_attr[4][14] = { { 680static struct sensor_device_attribute_2 fxxxx_auto_pwm_attr[4][14] = { {
553 SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR, 681 SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
554 show_pwm_auto_point_channel, 682 show_pwm_auto_point_channel,
@@ -943,16 +1071,16 @@ static u16 f71882fg_read_temp(struct f71882fg_data *data, int nr)
943static struct f71882fg_data *f71882fg_update_device(struct device *dev) 1071static struct f71882fg_data *f71882fg_update_device(struct device *dev)
944{ 1072{
945 struct f71882fg_data *data = dev_get_drvdata(dev); 1073 struct f71882fg_data *data = dev_get_drvdata(dev);
946 int nr, reg = 0, reg2; 1074 int nr, reg, point;
947 int nr_fans = (data->type == f71882fg) ? 4 : 3; 1075 int nr_fans = (data->type == f71882fg) ? 4 : 3;
948 int nr_ins = (data->type == f71858fg || data->type == f8000) ? 3 : 9; 1076 int nr_temps = (data->type == f71808e) ? 2 : 3;
949 1077
950 mutex_lock(&data->update_lock); 1078 mutex_lock(&data->update_lock);
951 1079
952 /* Update once every 60 seconds */ 1080 /* Update once every 60 seconds */
953 if (time_after(jiffies, data->last_limits + 60 * HZ) || 1081 if (time_after(jiffies, data->last_limits + 60 * HZ) ||
954 !data->valid) { 1082 !data->valid) {
955 if (data->type == f71882fg || data->type == f71889fg) { 1083 if (f71882fg_has_in1_alarm[data->type]) {
956 data->in1_max = 1084 data->in1_max =
957 f71882fg_read8(data, F71882FG_REG_IN1_HIGH); 1085 f71882fg_read8(data, F71882FG_REG_IN1_HIGH);
958 data->in_beep = 1086 data->in_beep =
@@ -960,7 +1088,8 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
960 } 1088 }
961 1089
962 /* Get High & boundary temps*/ 1090 /* Get High & boundary temps*/
963 for (nr = data->temp_start; nr < 3 + data->temp_start; nr++) { 1091 for (nr = data->temp_start; nr < nr_temps + data->temp_start;
1092 nr++) {
964 data->temp_ovt[nr] = f71882fg_read8(data, 1093 data->temp_ovt[nr] = f71882fg_read8(data,
965 F71882FG_REG_TEMP_OVT(nr)); 1094 F71882FG_REG_TEMP_OVT(nr));
966 data->temp_high[nr] = f71882fg_read8(data, 1095 data->temp_high[nr] = f71882fg_read8(data,
@@ -973,44 +1102,19 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
973 data->temp_hyst[1] = f71882fg_read8(data, 1102 data->temp_hyst[1] = f71882fg_read8(data,
974 F71882FG_REG_TEMP_HYST(1)); 1103 F71882FG_REG_TEMP_HYST(1));
975 } 1104 }
1105 /* All but the f71858fg / f8000 have this register */
1106 if ((data->type != f71858fg) && (data->type != f8000)) {
1107 reg = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE);
1108 data->temp_type[1] = (reg & 0x02) ? 2 : 4;
1109 data->temp_type[2] = (reg & 0x04) ? 2 : 4;
1110 data->temp_type[3] = (reg & 0x08) ? 2 : 4;
1111 }
976 1112
977 if (data->type == f71862fg || data->type == f71882fg || 1113 if (f71882fg_has_beep[data->type]) {
978 data->type == f71889fg) {
979 data->fan_beep = f71882fg_read8(data, 1114 data->fan_beep = f71882fg_read8(data,
980 F71882FG_REG_FAN_BEEP); 1115 F71882FG_REG_FAN_BEEP);
981 data->temp_beep = f71882fg_read8(data, 1116 data->temp_beep = f71882fg_read8(data,
982 F71882FG_REG_TEMP_BEEP); 1117 F71882FG_REG_TEMP_BEEP);
983 /* Have to hardcode type, because temp1 is special */
984 reg = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE);
985 data->temp_type[2] = (reg & 0x04) ? 2 : 4;
986 data->temp_type[3] = (reg & 0x08) ? 2 : 4;
987 }
988 /* Determine temp index 1 sensor type */
989 if (data->type == f71889fg) {
990 reg2 = f71882fg_read8(data, F71882FG_REG_START);
991 switch ((reg2 & 0x60) >> 5) {
992 case 0x00: /* BJT / Thermistor */
993 data->temp_type[1] = (reg & 0x02) ? 2 : 4;
994 break;
995 case 0x01: /* AMDSI */
996 data->temp_type[1] = 5;
997 break;
998 case 0x02: /* PECI */
999 case 0x03: /* Ibex Peak ?? Report as PECI for now */
1000 data->temp_type[1] = 6;
1001 break;
1002 }
1003 } else {
1004 reg2 = f71882fg_read8(data, F71882FG_REG_PECI);
1005 if ((reg2 & 0x03) == 0x01)
1006 data->temp_type[1] = 6; /* PECI */
1007 else if ((reg2 & 0x03) == 0x02)
1008 data->temp_type[1] = 5; /* AMDSI */
1009 else if (data->type == f71862fg ||
1010 data->type == f71882fg)
1011 data->temp_type[1] = (reg & 0x02) ? 2 : 4;
1012 else /* f71858fg and f8000 only support BJT */
1013 data->temp_type[1] = 2;
1014 } 1118 }
1015 1119
1016 data->pwm_enable = f71882fg_read8(data, 1120 data->pwm_enable = f71882fg_read8(data,
@@ -1025,8 +1129,8 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
1025 f71882fg_read8(data, 1129 f71882fg_read8(data,
1026 F71882FG_REG_POINT_MAPPING(nr)); 1130 F71882FG_REG_POINT_MAPPING(nr));
1027 1131
1028 if (data->type != f71862fg) { 1132 switch (data->type) {
1029 int point; 1133 default:
1030 for (point = 0; point < 5; point++) { 1134 for (point = 0; point < 5; point++) {
1031 data->pwm_auto_point_pwm[nr][point] = 1135 data->pwm_auto_point_pwm[nr][point] =
1032 f71882fg_read8(data, 1136 f71882fg_read8(data,
@@ -1039,7 +1143,14 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
1039 F71882FG_REG_POINT_TEMP 1143 F71882FG_REG_POINT_TEMP
1040 (nr, point)); 1144 (nr, point));
1041 } 1145 }
1042 } else { 1146 break;
1147 case f71808e:
1148 case f71869:
1149 data->pwm_auto_point_pwm[nr][0] =
1150 f71882fg_read8(data,
1151 F71882FG_REG_POINT_PWM(nr, 0));
1152 /* Fall through */
1153 case f71862fg:
1043 data->pwm_auto_point_pwm[nr][1] = 1154 data->pwm_auto_point_pwm[nr][1] =
1044 f71882fg_read8(data, 1155 f71882fg_read8(data,
1045 F71882FG_REG_POINT_PWM 1156 F71882FG_REG_POINT_PWM
@@ -1056,6 +1167,7 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
1056 f71882fg_read8(data, 1167 f71882fg_read8(data,
1057 F71882FG_REG_POINT_TEMP 1168 F71882FG_REG_POINT_TEMP
1058 (nr, 3)); 1169 (nr, 3));
1170 break;
1059 } 1171 }
1060 } 1172 }
1061 data->last_limits = jiffies; 1173 data->last_limits = jiffies;
@@ -1067,7 +1179,8 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
1067 F71882FG_REG_TEMP_STATUS); 1179 F71882FG_REG_TEMP_STATUS);
1068 data->temp_diode_open = f71882fg_read8(data, 1180 data->temp_diode_open = f71882fg_read8(data,
1069 F71882FG_REG_TEMP_DIODE_OPEN); 1181 F71882FG_REG_TEMP_DIODE_OPEN);
1070 for (nr = data->temp_start; nr < 3 + data->temp_start; nr++) 1182 for (nr = data->temp_start; nr < nr_temps + data->temp_start;
1183 nr++)
1071 data->temp[nr] = f71882fg_read_temp(data, nr); 1184 data->temp[nr] = f71882fg_read_temp(data, nr);
1072 1185
1073 data->fan_status = f71882fg_read8(data, 1186 data->fan_status = f71882fg_read8(data,
@@ -1083,17 +1196,18 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
1083 data->pwm[nr] = 1196 data->pwm[nr] =
1084 f71882fg_read8(data, F71882FG_REG_PWM(nr)); 1197 f71882fg_read8(data, F71882FG_REG_PWM(nr));
1085 } 1198 }
1086
1087 /* The f8000 can monitor 1 more fan, but has no pwm for it */ 1199 /* The f8000 can monitor 1 more fan, but has no pwm for it */
1088 if (data->type == f8000) 1200 if (data->type == f8000)
1089 data->fan[3] = f71882fg_read16(data, 1201 data->fan[3] = f71882fg_read16(data,
1090 F71882FG_REG_FAN(3)); 1202 F71882FG_REG_FAN(3));
1091 if (data->type == f71882fg || data->type == f71889fg) 1203
1204 if (f71882fg_has_in1_alarm[data->type])
1092 data->in_status = f71882fg_read8(data, 1205 data->in_status = f71882fg_read8(data,
1093 F71882FG_REG_IN_STATUS); 1206 F71882FG_REG_IN_STATUS);
1094 for (nr = 0; nr < nr_ins; nr++) 1207 for (nr = 0; nr < F71882FG_MAX_INS; nr++)
1095 data->in[nr] = f71882fg_read8(data, 1208 if (f71882fg_has_in[data->type][nr])
1096 F71882FG_REG_IN(nr)); 1209 data->in[nr] = f71882fg_read8(data,
1210 F71882FG_REG_IN(nr));
1097 1211
1098 data->last_updated = jiffies; 1212 data->last_updated = jiffies;
1099 data->valid = 1; 1213 data->valid = 1;
@@ -1882,7 +1996,7 @@ static ssize_t store_pwm_auto_point_temp(struct device *dev,
1882 1996
1883 val /= 1000; 1997 val /= 1000;
1884 1998
1885 if (data->type == f71889fg) 1999 if (data->auto_point_temp_signed)
1886 val = SENSORS_LIMIT(val, -128, 127); 2000 val = SENSORS_LIMIT(val, -128, 127);
1887 else 2001 else
1888 val = SENSORS_LIMIT(val, 0, 127); 2002 val = SENSORS_LIMIT(val, 0, 127);
@@ -1929,7 +2043,8 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
1929 struct f71882fg_data *data; 2043 struct f71882fg_data *data;
1930 struct f71882fg_sio_data *sio_data = pdev->dev.platform_data; 2044 struct f71882fg_sio_data *sio_data = pdev->dev.platform_data;
1931 int err, i, nr_fans = (sio_data->type == f71882fg) ? 4 : 3; 2045 int err, i, nr_fans = (sio_data->type == f71882fg) ? 4 : 3;
1932 u8 start_reg; 2046 int nr_temps = (sio_data->type == f71808e) ? 2 : 3;
2047 u8 start_reg, reg;
1933 2048
1934 data = kzalloc(sizeof(struct f71882fg_data), GFP_KERNEL); 2049 data = kzalloc(sizeof(struct f71882fg_data), GFP_KERNEL);
1935 if (!data) 2050 if (!data)
@@ -1968,37 +2083,72 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
1968 /* The f71858fg temperature alarms behave as 2083 /* The f71858fg temperature alarms behave as
1969 the f8000 alarms in this mode */ 2084 the f8000 alarms in this mode */
1970 err = f71882fg_create_sysfs_files(pdev, 2085 err = f71882fg_create_sysfs_files(pdev,
1971 f8000_in_temp_attr, 2086 f8000_temp_attr,
1972 ARRAY_SIZE(f8000_in_temp_attr)); 2087 ARRAY_SIZE(f8000_temp_attr));
1973 else 2088 else
1974 err = f71882fg_create_sysfs_files(pdev, 2089 err = f71882fg_create_sysfs_files(pdev,
1975 f71858fg_in_temp_attr, 2090 f71858fg_temp_attr,
1976 ARRAY_SIZE(f71858fg_in_temp_attr)); 2091 ARRAY_SIZE(f71858fg_temp_attr));
1977 break;
1978 case f71882fg:
1979 case f71889fg:
1980 err = f71882fg_create_sysfs_files(pdev,
1981 fxxxx_in1_alarm_attr,
1982 ARRAY_SIZE(fxxxx_in1_alarm_attr));
1983 if (err)
1984 goto exit_unregister_sysfs;
1985 /* fall through! */
1986 case f71862fg:
1987 err = f71882fg_create_sysfs_files(pdev,
1988 fxxxx_in_temp_attr,
1989 ARRAY_SIZE(fxxxx_in_temp_attr));
1990 break; 2092 break;
1991 case f8000: 2093 case f8000:
1992 err = f71882fg_create_sysfs_files(pdev, 2094 err = f71882fg_create_sysfs_files(pdev,
1993 f8000_in_temp_attr, 2095 f8000_temp_attr,
1994 ARRAY_SIZE(f8000_in_temp_attr)); 2096 ARRAY_SIZE(f8000_temp_attr));
1995 break; 2097 break;
2098 default:
2099 err = f71882fg_create_sysfs_files(pdev,
2100 &fxxxx_temp_attr[0][0],
2101 ARRAY_SIZE(fxxxx_temp_attr[0]) * nr_temps);
1996 } 2102 }
1997 if (err) 2103 if (err)
1998 goto exit_unregister_sysfs; 2104 goto exit_unregister_sysfs;
2105
2106 if (f71882fg_has_beep[data->type]) {
2107 err = f71882fg_create_sysfs_files(pdev,
2108 &fxxxx_temp_beep_attr[0][0],
2109 ARRAY_SIZE(fxxxx_temp_beep_attr[0])
2110 * nr_temps);
2111 if (err)
2112 goto exit_unregister_sysfs;
2113 }
2114
2115 for (i = 0; i < F71882FG_MAX_INS; i++) {
2116 if (f71882fg_has_in[data->type][i]) {
2117 err = device_create_file(&pdev->dev,
2118 &fxxxx_in_attr[i].dev_attr);
2119 if (err)
2120 goto exit_unregister_sysfs;
2121 }
2122 }
2123 if (f71882fg_has_in1_alarm[data->type]) {
2124 err = f71882fg_create_sysfs_files(pdev,
2125 fxxxx_in1_alarm_attr,
2126 ARRAY_SIZE(fxxxx_in1_alarm_attr));
2127 if (err)
2128 goto exit_unregister_sysfs;
2129 }
1999 } 2130 }
2000 2131
2001 if (start_reg & 0x02) { 2132 if (start_reg & 0x02) {
2133 switch (data->type) {
2134 case f71808e:
2135 case f71869:
2136 /* These always have signed auto point temps */
2137 data->auto_point_temp_signed = 1;
2138 /* Fall through to select correct fan/pwm reg bank! */
2139 case f71889fg:
2140 case f71889ed:
2141 reg = f71882fg_read8(data, F71882FG_REG_FAN_FAULT_T);
2142 if (reg & F71882FG_FAN_NEG_TEMP_EN)
2143 data->auto_point_temp_signed = 1;
2144 /* Ensure banked pwm registers point to right bank */
2145 reg &= ~F71882FG_FAN_PROG_SEL;
2146 f71882fg_write8(data, F71882FG_REG_FAN_FAULT_T, reg);
2147 break;
2148 default:
2149 break;
2150 }
2151
2002 data->pwm_enable = 2152 data->pwm_enable =
2003 f71882fg_read8(data, F71882FG_REG_PWM_ENABLE); 2153 f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
2004 2154
@@ -2013,8 +2163,11 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
2013 case f71862fg: 2163 case f71862fg:
2014 err = (data->pwm_enable & 0x15) != 0x15; 2164 err = (data->pwm_enable & 0x15) != 0x15;
2015 break; 2165 break;
2166 case f71808e:
2167 case f71869:
2016 case f71882fg: 2168 case f71882fg:
2017 case f71889fg: 2169 case f71889fg:
2170 case f71889ed:
2018 err = 0; 2171 err = 0;
2019 break; 2172 break;
2020 case f8000: 2173 case f8000:
@@ -2034,8 +2187,7 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
2034 if (err) 2187 if (err)
2035 goto exit_unregister_sysfs; 2188 goto exit_unregister_sysfs;
2036 2189
2037 if (data->type == f71862fg || data->type == f71882fg || 2190 if (f71882fg_has_beep[data->type]) {
2038 data->type == f71889fg) {
2039 err = f71882fg_create_sysfs_files(pdev, 2191 err = f71882fg_create_sysfs_files(pdev,
2040 fxxxx_fan_beep_attr, nr_fans); 2192 fxxxx_fan_beep_attr, nr_fans);
2041 if (err) 2193 if (err)
@@ -2043,11 +2195,42 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
2043 } 2195 }
2044 2196
2045 switch (data->type) { 2197 switch (data->type) {
2198 case f71808e:
2199 case f71869:
2200 case f71889fg:
2201 case f71889ed:
2202 for (i = 0; i < nr_fans; i++) {
2203 data->pwm_auto_point_mapping[i] =
2204 f71882fg_read8(data,
2205 F71882FG_REG_POINT_MAPPING(i));
2206 if ((data->pwm_auto_point_mapping[i] & 0x80) ||
2207 (data->pwm_auto_point_mapping[i] & 3) == 0)
2208 break;
2209 }
2210 if (i != nr_fans) {
2211 dev_warn(&pdev->dev,
2212 "Auto pwm controlled by raw digital "
2213 "data, disabling pwm auto_point "
2214 "sysfs attributes\n");
2215 goto no_pwm_auto_point;
2216 }
2217 break;
2218 default:
2219 break;
2220 }
2221
2222 switch (data->type) {
2046 case f71862fg: 2223 case f71862fg:
2047 err = f71882fg_create_sysfs_files(pdev, 2224 err = f71882fg_create_sysfs_files(pdev,
2048 f71862fg_auto_pwm_attr, 2225 f71862fg_auto_pwm_attr,
2049 ARRAY_SIZE(f71862fg_auto_pwm_attr)); 2226 ARRAY_SIZE(f71862fg_auto_pwm_attr));
2050 break; 2227 break;
2228 case f71808e:
2229 case f71869:
2230 err = f71882fg_create_sysfs_files(pdev,
2231 f71869_auto_pwm_attr,
2232 ARRAY_SIZE(f71869_auto_pwm_attr));
2233 break;
2051 case f8000: 2234 case f8000:
2052 err = f71882fg_create_sysfs_files(pdev, 2235 err = f71882fg_create_sysfs_files(pdev,
2053 f8000_fan_attr, 2236 f8000_fan_attr,
@@ -2058,23 +2241,7 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
2058 f8000_auto_pwm_attr, 2241 f8000_auto_pwm_attr,
2059 ARRAY_SIZE(f8000_auto_pwm_attr)); 2242 ARRAY_SIZE(f8000_auto_pwm_attr));
2060 break; 2243 break;
2061 case f71889fg: 2244 default:
2062 for (i = 0; i < nr_fans; i++) {
2063 data->pwm_auto_point_mapping[i] =
2064 f71882fg_read8(data,
2065 F71882FG_REG_POINT_MAPPING(i));
2066 if (data->pwm_auto_point_mapping[i] & 0x80)
2067 break;
2068 }
2069 if (i != nr_fans) {
2070 dev_warn(&pdev->dev,
2071 "Auto pwm controlled by raw digital "
2072 "data, disabling pwm auto_point "
2073 "sysfs attributes\n");
2074 break;
2075 }
2076 /* fall through */
2077 default: /* f71858fg / f71882fg */
2078 err = f71882fg_create_sysfs_files(pdev, 2245 err = f71882fg_create_sysfs_files(pdev,
2079 &fxxxx_auto_pwm_attr[0][0], 2246 &fxxxx_auto_pwm_attr[0][0],
2080 ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans); 2247 ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans);
@@ -2082,6 +2249,7 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
2082 if (err) 2249 if (err)
2083 goto exit_unregister_sysfs; 2250 goto exit_unregister_sysfs;
2084 2251
2252no_pwm_auto_point:
2085 for (i = 0; i < nr_fans; i++) 2253 for (i = 0; i < nr_fans; i++)
2086 dev_info(&pdev->dev, "Fan: %d is in %s mode\n", i + 1, 2254 dev_info(&pdev->dev, "Fan: %d is in %s mode\n", i + 1,
2087 (data->pwm_enable & (1 << 2 * i)) ? 2255 (data->pwm_enable & (1 << 2 * i)) ?
@@ -2108,7 +2276,8 @@ exit_free:
2108static int f71882fg_remove(struct platform_device *pdev) 2276static int f71882fg_remove(struct platform_device *pdev)
2109{ 2277{
2110 struct f71882fg_data *data = platform_get_drvdata(pdev); 2278 struct f71882fg_data *data = platform_get_drvdata(pdev);
2111 int nr_fans = (data->type == f71882fg) ? 4 : 3; 2279 int i, nr_fans = (data->type == f71882fg) ? 4 : 3;
2280 int nr_temps = (data->type == f71808e) ? 2 : 3;
2112 u8 start_reg = f71882fg_read8(data, F71882FG_REG_START); 2281 u8 start_reg = f71882fg_read8(data, F71882FG_REG_START);
2113 2282
2114 if (data->hwmon_dev) 2283 if (data->hwmon_dev)
@@ -2121,29 +2290,39 @@ static int f71882fg_remove(struct platform_device *pdev)
2121 case f71858fg: 2290 case f71858fg:
2122 if (data->temp_config & 0x10) 2291 if (data->temp_config & 0x10)
2123 f71882fg_remove_sysfs_files(pdev, 2292 f71882fg_remove_sysfs_files(pdev,
2124 f8000_in_temp_attr, 2293 f8000_temp_attr,
2125 ARRAY_SIZE(f8000_in_temp_attr)); 2294 ARRAY_SIZE(f8000_temp_attr));
2126 else 2295 else
2127 f71882fg_remove_sysfs_files(pdev, 2296 f71882fg_remove_sysfs_files(pdev,
2128 f71858fg_in_temp_attr, 2297 f71858fg_temp_attr,
2129 ARRAY_SIZE(f71858fg_in_temp_attr)); 2298 ARRAY_SIZE(f71858fg_temp_attr));
2130 break;
2131 case f71882fg:
2132 case f71889fg:
2133 f71882fg_remove_sysfs_files(pdev,
2134 fxxxx_in1_alarm_attr,
2135 ARRAY_SIZE(fxxxx_in1_alarm_attr));
2136 /* fall through! */
2137 case f71862fg:
2138 f71882fg_remove_sysfs_files(pdev,
2139 fxxxx_in_temp_attr,
2140 ARRAY_SIZE(fxxxx_in_temp_attr));
2141 break; 2299 break;
2142 case f8000: 2300 case f8000:
2143 f71882fg_remove_sysfs_files(pdev, 2301 f71882fg_remove_sysfs_files(pdev,
2144 f8000_in_temp_attr, 2302 f8000_temp_attr,
2145 ARRAY_SIZE(f8000_in_temp_attr)); 2303 ARRAY_SIZE(f8000_temp_attr));
2146 break; 2304 break;
2305 default:
2306 f71882fg_remove_sysfs_files(pdev,
2307 &fxxxx_temp_attr[0][0],
2308 ARRAY_SIZE(fxxxx_temp_attr[0]) * nr_temps);
2309 }
2310 if (f71882fg_has_beep[data->type]) {
2311 f71882fg_remove_sysfs_files(pdev,
2312 &fxxxx_temp_beep_attr[0][0],
2313 ARRAY_SIZE(fxxxx_temp_beep_attr[0]) * nr_temps);
2314 }
2315
2316 for (i = 0; i < F71882FG_MAX_INS; i++) {
2317 if (f71882fg_has_in[data->type][i]) {
2318 device_remove_file(&pdev->dev,
2319 &fxxxx_in_attr[i].dev_attr);
2320 }
2321 }
2322 if (f71882fg_has_in1_alarm[data->type]) {
2323 f71882fg_remove_sysfs_files(pdev,
2324 fxxxx_in1_alarm_attr,
2325 ARRAY_SIZE(fxxxx_in1_alarm_attr));
2147 } 2326 }
2148 } 2327 }
2149 2328
@@ -2151,10 +2330,10 @@ static int f71882fg_remove(struct platform_device *pdev)
2151 f71882fg_remove_sysfs_files(pdev, &fxxxx_fan_attr[0][0], 2330 f71882fg_remove_sysfs_files(pdev, &fxxxx_fan_attr[0][0],
2152 ARRAY_SIZE(fxxxx_fan_attr[0]) * nr_fans); 2331 ARRAY_SIZE(fxxxx_fan_attr[0]) * nr_fans);
2153 2332
2154 if (data->type == f71862fg || data->type == f71882fg || 2333 if (f71882fg_has_beep[data->type]) {
2155 data->type == f71889fg)
2156 f71882fg_remove_sysfs_files(pdev, 2334 f71882fg_remove_sysfs_files(pdev,
2157 fxxxx_fan_beep_attr, nr_fans); 2335 fxxxx_fan_beep_attr, nr_fans);
2336 }
2158 2337
2159 switch (data->type) { 2338 switch (data->type) {
2160 case f71862fg: 2339 case f71862fg:
@@ -2162,6 +2341,12 @@ static int f71882fg_remove(struct platform_device *pdev)
2162 f71862fg_auto_pwm_attr, 2341 f71862fg_auto_pwm_attr,
2163 ARRAY_SIZE(f71862fg_auto_pwm_attr)); 2342 ARRAY_SIZE(f71862fg_auto_pwm_attr));
2164 break; 2343 break;
2344 case f71808e:
2345 case f71869:
2346 f71882fg_remove_sysfs_files(pdev,
2347 f71869_auto_pwm_attr,
2348 ARRAY_SIZE(f71869_auto_pwm_attr));
2349 break;
2165 case f8000: 2350 case f8000:
2166 f71882fg_remove_sysfs_files(pdev, 2351 f71882fg_remove_sysfs_files(pdev,
2167 f8000_fan_attr, 2352 f8000_fan_attr,
@@ -2170,7 +2355,7 @@ static int f71882fg_remove(struct platform_device *pdev)
2170 f8000_auto_pwm_attr, 2355 f8000_auto_pwm_attr,
2171 ARRAY_SIZE(f8000_auto_pwm_attr)); 2356 ARRAY_SIZE(f8000_auto_pwm_attr));
2172 break; 2357 break;
2173 default: /* f71858fg / f71882fg / f71889fg */ 2358 default:
2174 f71882fg_remove_sysfs_files(pdev, 2359 f71882fg_remove_sysfs_files(pdev,
2175 &fxxxx_auto_pwm_attr[0][0], 2360 &fxxxx_auto_pwm_attr[0][0],
2176 ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans); 2361 ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans);
@@ -2200,18 +2385,27 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
2200 2385
2201 devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID); 2386 devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID);
2202 switch (devid) { 2387 switch (devid) {
2388 case SIO_F71808E_ID:
2389 sio_data->type = f71808e;
2390 break;
2203 case SIO_F71858_ID: 2391 case SIO_F71858_ID:
2204 sio_data->type = f71858fg; 2392 sio_data->type = f71858fg;
2205 break; 2393 break;
2206 case SIO_F71862_ID: 2394 case SIO_F71862_ID:
2207 sio_data->type = f71862fg; 2395 sio_data->type = f71862fg;
2208 break; 2396 break;
2397 case SIO_F71869_ID:
2398 sio_data->type = f71869;
2399 break;
2209 case SIO_F71882_ID: 2400 case SIO_F71882_ID:
2210 sio_data->type = f71882fg; 2401 sio_data->type = f71882fg;
2211 break; 2402 break;
2212 case SIO_F71889_ID: 2403 case SIO_F71889_ID:
2213 sio_data->type = f71889fg; 2404 sio_data->type = f71889fg;
2214 break; 2405 break;
2406 case SIO_F71889E_ID:
2407 sio_data->type = f71889ed;
2408 break;
2215 case SIO_F8000_ID: 2409 case SIO_F8000_ID:
2216 sio_data->type = f8000; 2410 sio_data->type = f8000;
2217 break; 2411 break;