aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2009-06-15 12:39:52 -0400
committerJean Delvare <khali@linux-fr.org>2009-06-15 12:39:52 -0400
commit09475d32e652fe60901fe8c9cd50f3f6db0c4933 (patch)
tree895d7f0d2195e6e6902b6fc8f56cdc4228f0913f
parentb6858bca8d7bf52e2564cba5a5ed87e1019d3fd9 (diff)
hwmon: (f71882fg) Add support for the F71858F
Add support for the hwmon part of the Fintek F71858FG superio IC to the f71882fg driver. Many thanks to Jelle de Jong for lending me a motherboard with this superio on it. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Jean Delvare <khali@linux-fr.org>
-rw-r--r--Documentation/hwmon/f71882fg12
-rw-r--r--drivers/hwmon/Kconfig4
-rw-r--r--drivers/hwmon/f71882fg.c192
3 files changed, 166 insertions, 42 deletions
diff --git a/Documentation/hwmon/f71882fg b/Documentation/hwmon/f71882fg
index a8321267b5b6..bee4c30bc1e2 100644
--- a/Documentation/hwmon/f71882fg
+++ b/Documentation/hwmon/f71882fg
@@ -2,14 +2,18 @@ Kernel driver f71882fg
2====================== 2======================
3 3
4Supported chips: 4Supported chips:
5 * Fintek F71882FG and F71883FG 5 * Fintek F71858FG
6 Prefix: 'f71882fg' 6 Prefix: 'f71858fg'
7 Addresses scanned: none, address read from Super I/O config space 7 Addresses scanned: none, address read from Super I/O config space
8 Datasheet: Available from the Fintek website 8 Datasheet: Available from the Fintek website
9 * Fintek F71862FG and F71863FG 9 * Fintek F71862FG and F71863FG
10 Prefix: 'f71862fg' 10 Prefix: 'f71862fg'
11 Addresses scanned: none, address read from Super I/O config space 11 Addresses scanned: none, address read from Super I/O config space
12 Datasheet: Available from the Fintek website 12 Datasheet: Available from the Fintek website
13 * Fintek F71882FG and F71883FG
14 Prefix: 'f71882fg'
15 Addresses scanned: none, address read from Super I/O config space
16 Datasheet: Available from the Fintek website
13 * Fintek F8000 17 * Fintek F8000
14 Prefix: 'f8000' 18 Prefix: 'f8000'
15 Addresses scanned: none, address read from Super I/O config space 19 Addresses scanned: none, address read from Super I/O config space
@@ -66,13 +70,13 @@ printed when loading the driver.
66 70
67Three different fan control modes are supported; the mode number is written 71Three different fan control modes are supported; the mode number is written
68to the pwm#_enable file. Note that not all modes are supported on all 72to the pwm#_enable file. Note that not all modes are supported on all
69chips, and some modes may only be available in RPM / PWM mode on the F8000. 73chips, and some modes may only be available in RPM / PWM mode.
70Writing an unsupported mode will result in an invalid parameter error. 74Writing an unsupported mode will result in an invalid parameter error.
71 75
72* 1: Manual mode 76* 1: Manual mode
73 You ask for a specific PWM duty cycle / DC voltage or a specific % of 77 You ask for a specific PWM duty cycle / DC voltage or a specific % of
74 fan#_full_speed by writing to the pwm# file. This mode is only 78 fan#_full_speed by writing to the pwm# file. This mode is only
75 available on the F8000 if the fan channel is in RPM mode. 79 available on the F71858FG / F8000 if the fan channel is in RPM mode.
76 80
77* 2: Normal auto mode 81* 2: Normal auto mode
78 You can define a number of temperature/fan speed trip points, which % the 82 You can define a number of temperature/fan speed trip points, which % the
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 79117c3abb41..f8090e137fef 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -306,11 +306,11 @@ config SENSORS_F71805F
306 will be called f71805f. 306 will be called f71805f.
307 307
308config SENSORS_F71882FG 308config SENSORS_F71882FG
309 tristate "Fintek F71862FG, F71882FG and F8000" 309 tristate "Fintek F71858FG, F71862FG, F71882FG and F8000"
310 depends on EXPERIMENTAL 310 depends on EXPERIMENTAL
311 help 311 help
312 If you say yes here you get support for hardware monitoring 312 If you say yes here you get support for hardware monitoring
313 features of the Fintek F71882FG/F71883FG, F71862FG/71863FG 313 features of the Fintek F71858FG, F71862FG/71863FG, F71882FG/F71883FG
314 and F8000 Super-I/O chips. 314 and F8000 Super-I/O chips.
315 315
316 This driver can also be built as a module. If so, the module 316 This driver can also be built as a module. If so, the module
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 7e5b94c19443..4146105f1a57 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -32,6 +32,7 @@
32 32
33#define DRVNAME "f71882fg" 33#define DRVNAME "f71882fg"
34 34
35#define SIO_F71858FG_LD_HWM 0x02 /* Hardware monitor logical device */
35#define SIO_F71882FG_LD_HWM 0x04 /* Hardware monitor logical device */ 36#define SIO_F71882FG_LD_HWM 0x04 /* Hardware monitor logical device */
36#define SIO_UNLOCK_KEY 0x87 /* Key to enable Super-I/O */ 37#define SIO_UNLOCK_KEY 0x87 /* Key to enable Super-I/O */
37#define SIO_LOCK_KEY 0xAA /* Key to diasble Super-I/O */ 38#define SIO_LOCK_KEY 0xAA /* Key to diasble Super-I/O */
@@ -44,6 +45,7 @@
44#define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ 45#define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */
45 46
46#define SIO_FINTEK_ID 0x1934 /* Manufacturers ID */ 47#define SIO_FINTEK_ID 0x1934 /* Manufacturers ID */
48#define SIO_F71858_ID 0x0507 /* Chipset ID */
47#define SIO_F71862_ID 0x0601 /* Chipset ID */ 49#define SIO_F71862_ID 0x0601 /* Chipset ID */
48#define SIO_F71882_ID 0x0541 /* Chipset ID */ 50#define SIO_F71882_ID 0x0541 /* Chipset ID */
49#define SIO_F8000_ID 0x0581 /* Chipset ID */ 51#define SIO_F8000_ID 0x0581 /* Chipset ID */
@@ -70,6 +72,7 @@
70#define F71882FG_REG_TEMP_HIGH(nr) (0x81 + 2 * (nr)) 72#define F71882FG_REG_TEMP_HIGH(nr) (0x81 + 2 * (nr))
71#define F71882FG_REG_TEMP_STATUS 0x62 73#define F71882FG_REG_TEMP_STATUS 0x62
72#define F71882FG_REG_TEMP_BEEP 0x63 74#define F71882FG_REG_TEMP_BEEP 0x63
75#define F71882FG_REG_TEMP_CONFIG 0x69
73#define F71882FG_REG_TEMP_HYST(nr) (0x6C + (nr)) 76#define F71882FG_REG_TEMP_HYST(nr) (0x6C + (nr))
74#define F71882FG_REG_TEMP_TYPE 0x6B 77#define F71882FG_REG_TEMP_TYPE 0x6B
75#define F71882FG_REG_TEMP_DIODE_OPEN 0x6F 78#define F71882FG_REG_TEMP_DIODE_OPEN 0x6F
@@ -92,9 +95,10 @@ static unsigned short force_id;
92module_param(force_id, ushort, 0); 95module_param(force_id, ushort, 0);
93MODULE_PARM_DESC(force_id, "Override the detected device ID"); 96MODULE_PARM_DESC(force_id, "Override the detected device ID");
94 97
95enum chips { f71862fg, f71882fg, f8000 }; 98enum chips { f71858fg, f71862fg, f71882fg, f8000 };
96 99
97static const char *f71882fg_names[] = { 100static const char *f71882fg_names[] = {
101 "f71858fg",
98 "f71862fg", 102 "f71862fg",
99 "f71882fg", 103 "f71882fg",
100 "f8000", 104 "f8000",
@@ -119,6 +123,7 @@ struct f71882fg_data {
119 struct device *hwmon_dev; 123 struct device *hwmon_dev;
120 124
121 struct mutex update_lock; 125 struct mutex update_lock;
126 int temp_start; /* temp numbering start (0 or 1) */
122 char valid; /* !=0 if following fields are valid */ 127 char valid; /* !=0 if following fields are valid */
123 unsigned long last_updated; /* In jiffies */ 128 unsigned long last_updated; /* In jiffies */
124 unsigned long last_limits; /* In jiffies */ 129 unsigned long last_limits; /* In jiffies */
@@ -136,7 +141,7 @@ struct f71882fg_data {
136 /* Note: all models have only 3 temperature channels, but on some 141 /* Note: all models have only 3 temperature channels, but on some
137 they are addressed as 0-2 and on others as 1-3, so for coding 142 they are addressed as 0-2 and on others as 1-3, so for coding
138 convenience we reserve space for 4 channels */ 143 convenience we reserve space for 4 channels */
139 u8 temp[4]; 144 u16 temp[4];
140 u8 temp_ovt[4]; 145 u8 temp_ovt[4];
141 u8 temp_high[4]; 146 u8 temp_high[4];
142 u8 temp_hyst[2]; /* 2 hysts stored per reg */ 147 u8 temp_hyst[2]; /* 2 hysts stored per reg */
@@ -144,6 +149,7 @@ struct f71882fg_data {
144 u8 temp_status; 149 u8 temp_status;
145 u8 temp_beep; 150 u8 temp_beep;
146 u8 temp_diode_open; 151 u8 temp_diode_open;
152 u8 temp_config;
147 u8 pwm[4]; 153 u8 pwm[4];
148 u8 pwm_enable; 154 u8 pwm_enable;
149 u8 pwm_auto_point_hyst[2]; 155 u8 pwm_auto_point_hyst[2];
@@ -252,6 +258,50 @@ static struct platform_driver f71882fg_driver = {
252 258
253static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); 259static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
254 260
261/* Temp and in attr for the f71858fg */
262static struct sensor_device_attribute_2 f71858fg_in_temp_attr[] = {
263 SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
264 SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
265 SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
266 SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0),
267 SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max,
268 store_temp_max, 0, 0),
269 SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
270 store_temp_max_hyst, 0, 0),
271 SENSOR_ATTR_2(temp1_max_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 0),
272 SENSOR_ATTR_2(temp1_crit, S_IRUGO|S_IWUSR, show_temp_crit,
273 store_temp_crit, 0, 0),
274 SENSOR_ATTR_2(temp1_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
275 0, 0),
276 SENSOR_ATTR_2(temp1_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 4),
277 SENSOR_ATTR_2(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0, 0),
278 SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1),
279 SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_max,
280 store_temp_max, 0, 1),
281 SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
282 store_temp_max_hyst, 0, 1),
283 SENSOR_ATTR_2(temp2_max_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 1),
284 SENSOR_ATTR_2(temp2_crit, S_IRUGO|S_IWUSR, show_temp_crit,
285 store_temp_crit, 0, 1),
286 SENSOR_ATTR_2(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
287 0, 1),
288 SENSOR_ATTR_2(temp2_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5),
289 SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 1),
290 SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 1),
291 SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2),
292 SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max,
293 store_temp_max, 0, 2),
294 SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
295 store_temp_max_hyst, 0, 2),
296 SENSOR_ATTR_2(temp3_max_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 2),
297 SENSOR_ATTR_2(temp3_crit, S_IRUGO|S_IWUSR, show_temp_crit,
298 store_temp_crit, 0, 2),
299 SENSOR_ATTR_2(temp3_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
300 0, 2),
301 SENSOR_ATTR_2(temp3_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6),
302 SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
303};
304
255/* Temp and in attr common to both the f71862fg and f71882fg */ 305/* Temp and in attr common to both the f71862fg and f71882fg */
256static struct sensor_device_attribute_2 f718x2fg_in_temp_attr[] = { 306static struct sensor_device_attribute_2 f718x2fg_in_temp_attr[] = {
257 SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0), 307 SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
@@ -476,22 +526,8 @@ static struct sensor_device_attribute_2 f71862fg_fan_attr[] = {
476 show_pwm_auto_point_temp_hyst, NULL, 3, 2), 526 show_pwm_auto_point_temp_hyst, NULL, 3, 2),
477}; 527};
478 528
479/* Fan / PWM attr for the f71882fg */ 529/* Fan / PWM attr common to both the f71882fg and f71858fg */
480static struct sensor_device_attribute_2 f71882fg_fan_attr[] = { 530static struct sensor_device_attribute_2 f71882fg_f71858fg_fan_attr[] = {
481 SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep,
482 store_fan_beep, 0, 0),
483 SENSOR_ATTR_2(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep,
484 store_fan_beep, 0, 1),
485 SENSOR_ATTR_2(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep,
486 store_fan_beep, 0, 2),
487 SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
488 SENSOR_ATTR_2(fan4_full_speed, S_IRUGO|S_IWUSR,
489 show_fan_full_speed,
490 store_fan_full_speed, 0, 3),
491 SENSOR_ATTR_2(fan4_beep, S_IRUGO|S_IWUSR, show_fan_beep,
492 store_fan_beep, 0, 3),
493 SENSOR_ATTR_2(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 3),
494
495 SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR, 531 SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,
496 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 532 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
497 0, 0), 533 0, 0),
@@ -605,6 +641,24 @@ static struct sensor_device_attribute_2 f71882fg_fan_attr[] = {
605 show_pwm_auto_point_temp_hyst, NULL, 2, 2), 641 show_pwm_auto_point_temp_hyst, NULL, 2, 2),
606 SENSOR_ATTR_2(pwm3_auto_point4_temp_hyst, S_IRUGO, 642 SENSOR_ATTR_2(pwm3_auto_point4_temp_hyst, S_IRUGO,
607 show_pwm_auto_point_temp_hyst, NULL, 3, 2), 643 show_pwm_auto_point_temp_hyst, NULL, 3, 2),
644};
645
646/* Fan / PWM attr found on the f71882fg but not on the f71858fg */
647static struct sensor_device_attribute_2 f71882fg_fan_attr[] = {
648 SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep,
649 store_fan_beep, 0, 0),
650 SENSOR_ATTR_2(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep,
651 store_fan_beep, 0, 1),
652 SENSOR_ATTR_2(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep,
653 store_fan_beep, 0, 2),
654
655 SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
656 SENSOR_ATTR_2(fan4_full_speed, S_IRUGO|S_IWUSR,
657 show_fan_full_speed,
658 store_fan_full_speed, 0, 3),
659 SENSOR_ATTR_2(fan4_beep, S_IRUGO|S_IWUSR, show_fan_beep,
660 store_fan_beep, 0, 3),
661 SENSOR_ATTR_2(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 3),
608 662
609 SENSOR_ATTR_2(pwm4, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 3), 663 SENSOR_ATTR_2(pwm4, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 3),
610 SENSOR_ATTR_2(pwm4_enable, S_IRUGO|S_IWUSR, show_pwm_enable, 664 SENSOR_ATTR_2(pwm4_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
@@ -855,13 +909,20 @@ static void f71882fg_write16(struct f71882fg_data *data, u8 reg, u16 val)
855 outb(val & 255, data->addr + DATA_REG_OFFSET); 909 outb(val & 255, data->addr + DATA_REG_OFFSET);
856} 910}
857 911
912static u16 f71882fg_read_temp(struct f71882fg_data *data, int nr)
913{
914 if (data->type == f71858fg)
915 return f71882fg_read16(data, F71882FG_REG_TEMP(nr));
916 else
917 return f71882fg_read8(data, F71882FG_REG_TEMP(nr));
918}
919
858static struct f71882fg_data *f71882fg_update_device(struct device *dev) 920static struct f71882fg_data *f71882fg_update_device(struct device *dev)
859{ 921{
860 struct f71882fg_data *data = dev_get_drvdata(dev); 922 struct f71882fg_data *data = dev_get_drvdata(dev);
861 int nr, reg = 0, reg2; 923 int nr, reg = 0, reg2;
862 int nr_fans = (data->type == f71882fg) ? 4 : 3; 924 int nr_fans = (data->type == f71882fg) ? 4 : 3;
863 int nr_ins = (data->type == f8000) ? 3 : 9; 925 int nr_ins = (data->type == f71858fg || data->type == f8000) ? 3 : 9;
864 int temp_start = (data->type == f8000) ? 0 : 1;
865 926
866 mutex_lock(&data->update_lock); 927 mutex_lock(&data->update_lock);
867 928
@@ -876,7 +937,7 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
876 } 937 }
877 938
878 /* Get High & boundary temps*/ 939 /* Get High & boundary temps*/
879 for (nr = temp_start; nr < 3 + temp_start; nr++) { 940 for (nr = data->temp_start; nr < 3 + data->temp_start; nr++) {
880 data->temp_ovt[nr] = f71882fg_read8(data, 941 data->temp_ovt[nr] = f71882fg_read8(data,
881 F71882FG_REG_TEMP_OVT(nr)); 942 F71882FG_REG_TEMP_OVT(nr));
882 data->temp_high[nr] = f71882fg_read8(data, 943 data->temp_high[nr] = f71882fg_read8(data,
@@ -884,14 +945,17 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
884 } 945 }
885 946
886 if (data->type != f8000) { 947 if (data->type != f8000) {
887 data->fan_beep = f71882fg_read8(data,
888 F71882FG_REG_FAN_BEEP);
889 data->temp_beep = f71882fg_read8(data,
890 F71882FG_REG_TEMP_BEEP);
891 data->temp_hyst[0] = f71882fg_read8(data, 948 data->temp_hyst[0] = f71882fg_read8(data,
892 F71882FG_REG_TEMP_HYST(0)); 949 F71882FG_REG_TEMP_HYST(0));
893 data->temp_hyst[1] = f71882fg_read8(data, 950 data->temp_hyst[1] = f71882fg_read8(data,
894 F71882FG_REG_TEMP_HYST(1)); 951 F71882FG_REG_TEMP_HYST(1));
952 }
953
954 if (data->type == f71862fg || data->type == f71882fg) {
955 data->fan_beep = f71882fg_read8(data,
956 F71882FG_REG_FAN_BEEP);
957 data->temp_beep = f71882fg_read8(data,
958 F71882FG_REG_TEMP_BEEP);
895 /* Have to hardcode type, because temp1 is special */ 959 /* Have to hardcode type, because temp1 is special */
896 reg = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE); 960 reg = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE);
897 data->temp_type[2] = (reg & 0x04) ? 2 : 4; 961 data->temp_type[2] = (reg & 0x04) ? 2 : 4;
@@ -902,10 +966,10 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
902 data->temp_type[1] = 6 /* PECI */; 966 data->temp_type[1] = 6 /* PECI */;
903 else if ((reg2 & 0x03) == 0x02) 967 else if ((reg2 & 0x03) == 0x02)
904 data->temp_type[1] = 5 /* AMDSI */; 968 data->temp_type[1] = 5 /* AMDSI */;
905 else if (data->type != f8000) 969 else if (data->type == f71862fg || data->type == f71882fg)
906 data->temp_type[1] = (reg & 0x02) ? 2 : 4; 970 data->temp_type[1] = (reg & 0x02) ? 2 : 4;
907 else 971 else
908 data->temp_type[1] = 2; /* F8000 only supports BJT */ 972 data->temp_type[1] = 2; /* Only supports BJT */
909 973
910 data->pwm_enable = f71882fg_read8(data, 974 data->pwm_enable = f71882fg_read8(data,
911 F71882FG_REG_PWM_ENABLE); 975 F71882FG_REG_PWM_ENABLE);
@@ -961,9 +1025,8 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
961 F71882FG_REG_TEMP_STATUS); 1025 F71882FG_REG_TEMP_STATUS);
962 data->temp_diode_open = f71882fg_read8(data, 1026 data->temp_diode_open = f71882fg_read8(data,
963 F71882FG_REG_TEMP_DIODE_OPEN); 1027 F71882FG_REG_TEMP_DIODE_OPEN);
964 for (nr = temp_start; nr < 3 + temp_start; nr++) 1028 for (nr = data->temp_start; nr < 3 + data->temp_start; nr++)
965 data->temp[nr] = f71882fg_read8(data, 1029 data->temp[nr] = f71882fg_read_temp(data, nr);
966 F71882FG_REG_TEMP(nr));
967 1030
968 data->fan_status = f71882fg_read8(data, 1031 data->fan_status = f71882fg_read8(data,
969 F71882FG_REG_FAN_STATUS); 1032 F71882FG_REG_FAN_STATUS);
@@ -1166,8 +1229,24 @@ static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
1166{ 1229{
1167 struct f71882fg_data *data = f71882fg_update_device(dev); 1230 struct f71882fg_data *data = f71882fg_update_device(dev);
1168 int nr = to_sensor_dev_attr_2(devattr)->index; 1231 int nr = to_sensor_dev_attr_2(devattr)->index;
1232 int sign, temp;
1233
1234 if (data->type == f71858fg) {
1235 /* TEMP_TABLE_SEL 1 or 3 ? */
1236 if (data->temp_config & 1) {
1237 sign = data->temp[nr] & 0x0001;
1238 temp = (data->temp[nr] >> 5) & 0x7ff;
1239 } else {
1240 sign = data->temp[nr] & 0x8000;
1241 temp = (data->temp[nr] >> 5) & 0x3ff;
1242 }
1243 temp *= 125;
1244 if (sign)
1245 temp -= 128000;
1246 } else
1247 temp = data->temp[nr] * 1000;
1169 1248
1170 return sprintf(buf, "%d\n", data->temp[nr] * 1000); 1249 return sprintf(buf, "%d\n", temp);
1171} 1250}
1172 1251
1173static ssize_t show_temp_max(struct device *dev, struct device_attribute 1252static ssize_t show_temp_max(struct device *dev, struct device_attribute
@@ -1460,6 +1539,12 @@ static ssize_t store_pwm_enable(struct device *dev, struct device_attribute
1460 } else { 1539 } else {
1461 switch (val) { 1540 switch (val) {
1462 case 1: 1541 case 1:
1542 /* The f71858fg does not support manual RPM mode */
1543 if (data->type == f71858fg &&
1544 ((data->pwm_enable >> (2 * nr)) & 1)) {
1545 count = -EINVAL;
1546 goto leave;
1547 }
1463 data->pwm_enable |= 2 << (2 * nr); 1548 data->pwm_enable |= 2 << (2 * nr);
1464 break; /* Manual */ 1549 break; /* Manual */
1465 case 2: 1550 case 2:
@@ -1618,9 +1703,9 @@ static ssize_t show_pwm_auto_point_channel(struct device *dev,
1618 int result; 1703 int result;
1619 struct f71882fg_data *data = f71882fg_update_device(dev); 1704 struct f71882fg_data *data = f71882fg_update_device(dev);
1620 int nr = to_sensor_dev_attr_2(devattr)->index; 1705 int nr = to_sensor_dev_attr_2(devattr)->index;
1621 int temp_start = (data->type == f8000) ? 0 : 1;
1622 1706
1623 result = 1 << ((data->pwm_auto_point_mapping[nr] & 3) - temp_start); 1707 result = 1 << ((data->pwm_auto_point_mapping[nr] & 3) -
1708 data->temp_start);
1624 1709
1625 return sprintf(buf, "%d\n", result); 1710 return sprintf(buf, "%d\n", result);
1626} 1711}
@@ -1631,7 +1716,6 @@ static ssize_t store_pwm_auto_point_channel(struct device *dev,
1631{ 1716{
1632 struct f71882fg_data *data = dev_get_drvdata(dev); 1717 struct f71882fg_data *data = dev_get_drvdata(dev);
1633 int nr = to_sensor_dev_attr_2(devattr)->index; 1718 int nr = to_sensor_dev_attr_2(devattr)->index;
1634 int temp_start = (data->type == f8000) ? 0 : 1;
1635 long val = simple_strtol(buf, NULL, 10); 1719 long val = simple_strtol(buf, NULL, 10);
1636 1720
1637 switch (val) { 1721 switch (val) {
@@ -1647,7 +1731,7 @@ static ssize_t store_pwm_auto_point_channel(struct device *dev,
1647 default: 1731 default:
1648 return -EINVAL; 1732 return -EINVAL;
1649 } 1733 }
1650 val += temp_start; 1734 val += data->temp_start;
1651 mutex_lock(&data->update_lock); 1735 mutex_lock(&data->update_lock);
1652 data->pwm_auto_point_mapping[nr] = 1736 data->pwm_auto_point_mapping[nr] =
1653 f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(nr)); 1737 f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(nr));
@@ -1723,6 +1807,8 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
1723 1807
1724 data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start; 1808 data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start;
1725 data->type = sio_data->type; 1809 data->type = sio_data->type;
1810 data->temp_start =
1811 (data->type == f71858fg || data->type == f8000) ? 0 : 1;
1726 mutex_init(&data->update_lock); 1812 mutex_init(&data->update_lock);
1727 platform_set_drvdata(pdev, data); 1813 platform_set_drvdata(pdev, data);
1728 1814
@@ -1745,6 +1831,20 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
1745 1831
1746 if (start_reg & 0x01) { 1832 if (start_reg & 0x01) {
1747 switch (data->type) { 1833 switch (data->type) {
1834 case f71858fg:
1835 data->temp_config =
1836 f71882fg_read8(data, F71882FG_REG_TEMP_CONFIG);
1837 if (data->temp_config & 0x10)
1838 /* The f71858fg temperature alarms behave as
1839 the f8000 alarms in this mode */
1840 err = f71882fg_create_sysfs_files(pdev,
1841 f8000_in_temp_attr,
1842 ARRAY_SIZE(f8000_in_temp_attr));
1843 else
1844 err = f71882fg_create_sysfs_files(pdev,
1845 f71858fg_in_temp_attr,
1846 ARRAY_SIZE(f71858fg_in_temp_attr));
1847 break;
1748 case f71882fg: 1848 case f71882fg:
1749 err = f71882fg_create_sysfs_files(pdev, 1849 err = f71882fg_create_sysfs_files(pdev,
1750 f71882fg_in_temp_attr, 1850 f71882fg_in_temp_attr,
@@ -1773,6 +1873,12 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
1773 1873
1774 /* Sanity check the pwm settings */ 1874 /* Sanity check the pwm settings */
1775 switch (data->type) { 1875 switch (data->type) {
1876 case f71858fg:
1877 err = 0;
1878 for (i = 0; i < nr_fans; i++)
1879 if (((data->pwm_enable >> (i * 2)) & 3) == 3)
1880 err = 1;
1881 break;
1776 case f71862fg: 1882 case f71862fg:
1777 err = (data->pwm_enable & 0x15) != 0x15; 1883 err = (data->pwm_enable & 0x15) != 0x15;
1778 break; 1884 break;
@@ -1806,6 +1912,13 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
1806 err = f71882fg_create_sysfs_files(pdev, 1912 err = f71882fg_create_sysfs_files(pdev,
1807 f71882fg_fan_attr, 1913 f71882fg_fan_attr,
1808 ARRAY_SIZE(f71882fg_fan_attr)); 1914 ARRAY_SIZE(f71882fg_fan_attr));
1915 if (err)
1916 goto exit_unregister_sysfs;
1917 /* fall through! */
1918 case f71858fg:
1919 err = f71882fg_create_sysfs_files(pdev,
1920 f71882fg_f71858fg_fan_attr,
1921 ARRAY_SIZE(f71882fg_f71858fg_fan_attr));
1809 break; 1922 break;
1810 case f8000: 1923 case f8000:
1811 err = f71882fg_create_sysfs_files(pdev, 1924 err = f71882fg_create_sysfs_files(pdev,
@@ -1890,6 +2003,9 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
1890 2003
1891 devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID); 2004 devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID);
1892 switch (devid) { 2005 switch (devid) {
2006 case SIO_F71858_ID:
2007 sio_data->type = f71858fg;
2008 break;
1893 case SIO_F71862_ID: 2009 case SIO_F71862_ID:
1894 sio_data->type = f71862fg; 2010 sio_data->type = f71862fg;
1895 break; 2011 break;
@@ -1904,7 +2020,11 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
1904 goto exit; 2020 goto exit;
1905 } 2021 }
1906 2022
1907 superio_select(sioaddr, SIO_F71882FG_LD_HWM); 2023 if (sio_data->type == f71858fg)
2024 superio_select(sioaddr, SIO_F71858FG_LD_HWM);
2025 else
2026 superio_select(sioaddr, SIO_F71882FG_LD_HWM);
2027
1908 if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) { 2028 if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) {
1909 printk(KERN_WARNING DRVNAME ": Device not activated\n"); 2029 printk(KERN_WARNING DRVNAME ": Device not activated\n");
1910 goto exit; 2030 goto exit;