aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/hwmon/f71882fg10
-rw-r--r--drivers/hwmon/Kconfig6
-rw-r--r--drivers/hwmon/f71882fg.c86
3 files changed, 81 insertions, 21 deletions
diff --git a/Documentation/hwmon/f71882fg b/Documentation/hwmon/f71882fg
index bee4c30bc1e2..a7952c2bd959 100644
--- a/Documentation/hwmon/f71882fg
+++ b/Documentation/hwmon/f71882fg
@@ -14,6 +14,10 @@ Supported chips:
14 Prefix: 'f71882fg' 14 Prefix: 'f71882fg'
15 Addresses scanned: none, address read from Super I/O config space 15 Addresses scanned: none, address read from Super I/O config space
16 Datasheet: Available from the Fintek website 16 Datasheet: Available from the Fintek website
17 * Fintek F71889FG
18 Prefix: 'f71889fg'
19 Addresses scanned: none, address read from Super I/O config space
20 Datasheet: Should become available on the Fintek website soon
17 * Fintek F8000 21 * Fintek F8000
18 Prefix: 'f8000' 22 Prefix: 'f8000'
19 Addresses scanned: none, address read from Super I/O config space 23 Addresses scanned: none, address read from Super I/O config space
@@ -51,6 +55,12 @@ supported. The right one to use depends on external circuitry on the
51motherboard, so the driver assumes that the BIOS set the method 55motherboard, so the driver assumes that the BIOS set the method
52properly. 56properly.
53 57
58Note that the lowest numbered temperature zone trip point corresponds to
59to the border between the highest and one but highest temperature zones, and
60vica versa. So the temperature zone trip points 1-4 (or 1-2) go from high temp
61to low temp! This is how things are implemented in the IC, and the driver
62mimicks this.
63
54There are 2 modes to specify the speed of the fan, PWM duty cycle (or DC 64There are 2 modes to specify the speed of the fan, PWM duty cycle (or DC
55voltage) mode, where 0-100% duty cycle (0-100% of 12V) is specified. And RPM 65voltage) mode, where 0-100% duty cycle (0-100% of 12V) is specified. And RPM
56mode where the actual RPM of the fan (as measured) is controlled and the speed 66mode where the actual RPM of the fan (as measured) is controlled and the speed
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index dd6939370f75..edf8febb5bc4 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -305,12 +305,12 @@ config SENSORS_F71805F
305 will be called f71805f. 305 will be called f71805f.
306 306
307config SENSORS_F71882FG 307config SENSORS_F71882FG
308 tristate "Fintek F71858FG, F71862FG, F71882FG and F8000" 308 tristate "Fintek F71858FG, F71862FG, F71882FG, F71889FG and F8000"
309 depends on EXPERIMENTAL 309 depends on EXPERIMENTAL
310 help 310 help
311 If you say yes here you get support for hardware monitoring 311 If you say yes here you get support for hardware monitoring
312 features of the Fintek F71858FG, F71862FG/71863FG, F71882FG/F71883FG 312 features of the Fintek F71858FG, F71862FG/71863FG, F71882FG/F71883FG,
313 and F8000 Super-I/O chips. 313 F71889FG and F8000 Super-I/O chips.
314 314
315 This driver can also be built as a module. If so, the module 315 This driver can also be built as a module. If so, the module
316 will be called f71882fg. 316 will be called f71882fg.
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 3a695f06905e..a95fa4256caa 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -48,6 +48,7 @@
48#define SIO_F71858_ID 0x0507 /* Chipset ID */ 48#define SIO_F71858_ID 0x0507 /* Chipset ID */
49#define SIO_F71862_ID 0x0601 /* Chipset ID */ 49#define SIO_F71862_ID 0x0601 /* Chipset ID */
50#define SIO_F71882_ID 0x0541 /* Chipset ID */ 50#define SIO_F71882_ID 0x0541 /* Chipset ID */
51#define SIO_F71889_ID 0x0723 /* Chipset ID */
51#define SIO_F8000_ID 0x0581 /* Chipset ID */ 52#define SIO_F8000_ID 0x0581 /* Chipset ID */
52 53
53#define REGION_LENGTH 8 54#define REGION_LENGTH 8
@@ -95,12 +96,13 @@ static unsigned short force_id;
95module_param(force_id, ushort, 0); 96module_param(force_id, ushort, 0);
96MODULE_PARM_DESC(force_id, "Override the detected device ID"); 97MODULE_PARM_DESC(force_id, "Override the detected device ID");
97 98
98enum chips { f71858fg, f71862fg, f71882fg, f8000 }; 99enum chips { f71858fg, f71862fg, f71882fg, f71889fg, f8000 };
99 100
100static const char *f71882fg_names[] = { 101static const char *f71882fg_names[] = {
101 "f71858fg", 102 "f71858fg",
102 "f71862fg", 103 "f71862fg",
103 "f71882fg", 104 "f71882fg",
105 "f71889fg",
104 "f8000", 106 "f8000",
105}; 107};
106 108
@@ -155,7 +157,7 @@ struct f71882fg_data {
155 u8 pwm_auto_point_hyst[2]; 157 u8 pwm_auto_point_hyst[2];
156 u8 pwm_auto_point_mapping[4]; 158 u8 pwm_auto_point_mapping[4];
157 u8 pwm_auto_point_pwm[4][5]; 159 u8 pwm_auto_point_pwm[4][5];
158 u8 pwm_auto_point_temp[4][4]; 160 s8 pwm_auto_point_temp[4][4];
159}; 161};
160 162
161/* Sysfs in */ 163/* Sysfs in */
@@ -945,7 +947,7 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
945 /* Update once every 60 seconds */ 947 /* Update once every 60 seconds */
946 if ( time_after(jiffies, data->last_limits + 60 * HZ ) || 948 if ( time_after(jiffies, data->last_limits + 60 * HZ ) ||
947 !data->valid) { 949 !data->valid) {
948 if (data->type == f71882fg) { 950 if (data->type == f71882fg || data->type == f71889fg) {
949 data->in1_max = 951 data->in1_max =
950 f71882fg_read8(data, F71882FG_REG_IN1_HIGH); 952 f71882fg_read8(data, F71882FG_REG_IN1_HIGH);
951 data->in_beep = 953 data->in_beep =
@@ -967,7 +969,8 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
967 F71882FG_REG_TEMP_HYST(1)); 969 F71882FG_REG_TEMP_HYST(1));
968 } 970 }
969 971
970 if (data->type == f71862fg || data->type == f71882fg) { 972 if (data->type == f71862fg || data->type == f71882fg ||
973 data->type == f71889fg) {
971 data->fan_beep = f71882fg_read8(data, 974 data->fan_beep = f71882fg_read8(data,
972 F71882FG_REG_FAN_BEEP); 975 F71882FG_REG_FAN_BEEP);
973 data->temp_beep = f71882fg_read8(data, 976 data->temp_beep = f71882fg_read8(data,
@@ -977,15 +980,33 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
977 data->temp_type[2] = (reg & 0x04) ? 2 : 4; 980 data->temp_type[2] = (reg & 0x04) ? 2 : 4;
978 data->temp_type[3] = (reg & 0x08) ? 2 : 4; 981 data->temp_type[3] = (reg & 0x08) ? 2 : 4;
979 } 982 }
980 reg2 = f71882fg_read8(data, F71882FG_REG_PECI); 983 /* Determine temp index 1 sensor type */
981 if ((reg2 & 0x03) == 0x01) 984 if (data->type == f71889fg) {
982 data->temp_type[1] = 6 /* PECI */; 985 reg2 = f71882fg_read8(data, F71882FG_REG_START);
983 else if ((reg2 & 0x03) == 0x02) 986 switch ((reg2 & 0x60) >> 5) {
984 data->temp_type[1] = 5 /* AMDSI */; 987 case 0x00: /* BJT / Thermistor */
985 else if (data->type == f71862fg || data->type == f71882fg) 988 data->temp_type[1] = (reg & 0x02) ? 2 : 4;
986 data->temp_type[1] = (reg & 0x02) ? 2 : 4; 989 break;
987 else 990 case 0x01: /* AMDSI */
988 data->temp_type[1] = 2; /* Only supports BJT */ 991 data->temp_type[1] = 5;
992 break;
993 case 0x02: /* PECI */
994 case 0x03: /* Ibex Peak ?? Report as PECI for now */
995 data->temp_type[1] = 6;
996 break;
997 }
998 } else {
999 reg2 = f71882fg_read8(data, F71882FG_REG_PECI);
1000 if ((reg2 & 0x03) == 0x01)
1001 data->temp_type[1] = 6; /* PECI */
1002 else if ((reg2 & 0x03) == 0x02)
1003 data->temp_type[1] = 5; /* AMDSI */
1004 else if (data->type == f71862fg ||
1005 data->type == f71882fg)
1006 data->temp_type[1] = (reg & 0x02) ? 2 : 4;
1007 else /* f71858fg and f8000 only support BJT */
1008 data->temp_type[1] = 2;
1009 }
989 1010
990 data->pwm_enable = f71882fg_read8(data, 1011 data->pwm_enable = f71882fg_read8(data,
991 F71882FG_REG_PWM_ENABLE); 1012 F71882FG_REG_PWM_ENABLE);
@@ -1062,7 +1083,7 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
1062 if (data->type == f8000) 1083 if (data->type == f8000)
1063 data->fan[3] = f71882fg_read16(data, 1084 data->fan[3] = f71882fg_read16(data,
1064 F71882FG_REG_FAN(3)); 1085 F71882FG_REG_FAN(3));
1065 if (data->type == f71882fg) 1086 if (data->type == f71882fg || data->type == f71889fg)
1066 data->in_status = f71882fg_read8(data, 1087 data->in_status = f71882fg_read8(data,
1067 F71882FG_REG_IN_STATUS); 1088 F71882FG_REG_IN_STATUS);
1068 for (nr = 0; nr < nr_ins; nr++) 1089 for (nr = 0; nr < nr_ins; nr++)
@@ -1780,7 +1801,11 @@ static ssize_t store_pwm_auto_point_temp(struct device *dev,
1780 int pwm = to_sensor_dev_attr_2(devattr)->index; 1801 int pwm = to_sensor_dev_attr_2(devattr)->index;
1781 int point = to_sensor_dev_attr_2(devattr)->nr; 1802 int point = to_sensor_dev_attr_2(devattr)->nr;
1782 long val = simple_strtol(buf, NULL, 10) / 1000; 1803 long val = simple_strtol(buf, NULL, 10) / 1000;
1783 val = SENSORS_LIMIT(val, 0, 255); 1804
1805 if (data->type == f71889fg)
1806 val = SENSORS_LIMIT(val, -128, 127);
1807 else
1808 val = SENSORS_LIMIT(val, 0, 127);
1784 1809
1785 mutex_lock(&data->update_lock); 1810 mutex_lock(&data->update_lock);
1786 f71882fg_write8(data, F71882FG_REG_POINT_TEMP(pwm, point), val); 1811 f71882fg_write8(data, F71882FG_REG_POINT_TEMP(pwm, point), val);
@@ -1871,6 +1896,7 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
1871 ARRAY_SIZE(f71858fg_in_temp_attr)); 1896 ARRAY_SIZE(f71858fg_in_temp_attr));
1872 break; 1897 break;
1873 case f71882fg: 1898 case f71882fg:
1899 case f71889fg:
1874 err = f71882fg_create_sysfs_files(pdev, 1900 err = f71882fg_create_sysfs_files(pdev,
1875 fxxxx_in1_alarm_attr, 1901 fxxxx_in1_alarm_attr,
1876 ARRAY_SIZE(fxxxx_in1_alarm_attr)); 1902 ARRAY_SIZE(fxxxx_in1_alarm_attr));
@@ -1908,6 +1934,7 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
1908 err = (data->pwm_enable & 0x15) != 0x15; 1934 err = (data->pwm_enable & 0x15) != 0x15;
1909 break; 1935 break;
1910 case f71882fg: 1936 case f71882fg:
1937 case f71889fg:
1911 err = 0; 1938 err = 0;
1912 break; 1939 break;
1913 case f8000: 1940 case f8000:
@@ -1927,7 +1954,8 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
1927 if (err) 1954 if (err)
1928 goto exit_unregister_sysfs; 1955 goto exit_unregister_sysfs;
1929 1956
1930 if (data->type == f71862fg || data->type == f71882fg) { 1957 if (data->type == f71862fg || data->type == f71882fg ||
1958 data->type == f71889fg) {
1931 err = f71882fg_create_sysfs_files(pdev, 1959 err = f71882fg_create_sysfs_files(pdev,
1932 fxxxx_fan_beep_attr, nr_fans); 1960 fxxxx_fan_beep_attr, nr_fans);
1933 if (err) 1961 if (err)
@@ -1950,6 +1978,22 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
1950 f8000_auto_pwm_attr, 1978 f8000_auto_pwm_attr,
1951 ARRAY_SIZE(f8000_auto_pwm_attr)); 1979 ARRAY_SIZE(f8000_auto_pwm_attr));
1952 break; 1980 break;
1981 case f71889fg:
1982 for (i = 0; i < nr_fans; i++) {
1983 data->pwm_auto_point_mapping[i] =
1984 f71882fg_read8(data,
1985 F71882FG_REG_POINT_MAPPING(i));
1986 if (data->pwm_auto_point_mapping[i] & 0x80)
1987 break;
1988 }
1989 if (i != nr_fans) {
1990 dev_warn(&pdev->dev,
1991 "Auto pwm controlled by raw digital "
1992 "data, disabling pwm auto_point "
1993 "sysfs attributes\n");
1994 break;
1995 }
1996 /* fall through */
1953 default: /* f71858fg / f71882fg */ 1997 default: /* f71858fg / f71882fg */
1954 err = f71882fg_create_sysfs_files(pdev, 1998 err = f71882fg_create_sysfs_files(pdev,
1955 &fxxxx_auto_pwm_attr[0][0], 1999 &fxxxx_auto_pwm_attr[0][0],
@@ -2006,6 +2050,7 @@ static int f71882fg_remove(struct platform_device *pdev)
2006 ARRAY_SIZE(f71858fg_in_temp_attr)); 2050 ARRAY_SIZE(f71858fg_in_temp_attr));
2007 break; 2051 break;
2008 case f71882fg: 2052 case f71882fg:
2053 case f71889fg:
2009 f71882fg_remove_sysfs_files(pdev, 2054 f71882fg_remove_sysfs_files(pdev,
2010 fxxxx_in1_alarm_attr, 2055 fxxxx_in1_alarm_attr,
2011 ARRAY_SIZE(fxxxx_in1_alarm_attr)); 2056 ARRAY_SIZE(fxxxx_in1_alarm_attr));
@@ -2027,7 +2072,8 @@ static int f71882fg_remove(struct platform_device *pdev)
2027 f71882fg_remove_sysfs_files(pdev, &fxxxx_fan_attr[0][0], 2072 f71882fg_remove_sysfs_files(pdev, &fxxxx_fan_attr[0][0],
2028 ARRAY_SIZE(fxxxx_fan_attr[0]) * nr_fans); 2073 ARRAY_SIZE(fxxxx_fan_attr[0]) * nr_fans);
2029 2074
2030 if (data->type == f71862fg || data->type == f71882fg) 2075 if (data->type == f71862fg || data->type == f71882fg ||
2076 data->type == f71889fg)
2031 f71882fg_remove_sysfs_files(pdev, 2077 f71882fg_remove_sysfs_files(pdev,
2032 fxxxx_fan_beep_attr, nr_fans); 2078 fxxxx_fan_beep_attr, nr_fans);
2033 2079
@@ -2082,11 +2128,15 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
2082 case SIO_F71882_ID: 2128 case SIO_F71882_ID:
2083 sio_data->type = f71882fg; 2129 sio_data->type = f71882fg;
2084 break; 2130 break;
2131 case SIO_F71889_ID:
2132 sio_data->type = f71889fg;
2133 break;
2085 case SIO_F8000_ID: 2134 case SIO_F8000_ID:
2086 sio_data->type = f8000; 2135 sio_data->type = f8000;
2087 break; 2136 break;
2088 default: 2137 default:
2089 printk(KERN_INFO DRVNAME ": Unsupported Fintek device\n"); 2138 printk(KERN_INFO DRVNAME ": Unsupported Fintek device: %04x\n",
2139 (unsigned int)devid);
2090 goto exit; 2140 goto exit;
2091 } 2141 }
2092 2142