diff options
author | Hans de Goede <hdegoede@redhat.com> | 2011-03-09 14:57:14 -0500 |
---|---|---|
committer | Guenter Roeck <guenter.roeck@ericsson.com> | 2011-03-15 01:39:25 -0400 |
commit | 3cad402281607d4db0d99d88fbd67cabb7c5b9f1 (patch) | |
tree | 81147d3ef8f5a8d6230ae531d00e929a887a77fa | |
parent | e48a7f1a719b258ee8bd2e809205d6d0f9d66aed (diff) |
hwmon/f71882fg: Add support for f71889ed
Note that this patch also makes 2 changes to the code paths for the f71889fg
to keep the code unified between the 2 (for simplicities sake). Both of these
are harmless for then f71889fg:
1) The first change is to always set the FAN_PROG_SEL bit to 0. This influences
accesses to some banked fan / pwm registers. On the f71889fg no registers
which we use are banked. On the f71889ed however some more fan registers
have been banked including one which we use, by making the FAN_PROG_SEL bit
0, address 0x96 will point to the right register.
2) The second change is to see a FANx_TEMP_SEL value of 0 as pointing to
a PECI / AMDSI value, and thus disable our pwm related sysfs attr.
This is correct for the f71889ed and on the f71889fg 0 is a reserved
value, so we should never see it and if we do, disabling the pwm related
sysfs attr is a sane thing to do.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Tested-by: Thomas Greve <tg42@gmx.net>
Tested-by: Sander Eikelenboom <linux@eikelenboom.it>
Signed-off-by: Guenter Roeck <guenter.roeck@ericsson.com>
-rw-r--r-- | Documentation/hwmon/f71882fg | 12 | ||||
-rw-r--r-- | drivers/hwmon/f71882fg.c | 38 |
2 files changed, 35 insertions, 15 deletions
diff --git a/Documentation/hwmon/f71882fg b/Documentation/hwmon/f71882fg index a7952c2bd959..9aa210cae695 100644 --- a/Documentation/hwmon/f71882fg +++ b/Documentation/hwmon/f71882fg | |||
@@ -17,6 +17,10 @@ Supported chips: | |||
17 | * Fintek F71889FG | 17 | * Fintek F71889FG |
18 | Prefix: 'f71889fg' | 18 | Prefix: 'f71889fg' |
19 | Addresses scanned: none, address read from Super I/O config space | 19 | Addresses scanned: none, address read from Super I/O config space |
20 | Datasheet: Available from the Fintek website | ||
21 | * Fintek F71889ED | ||
22 | Prefix: 'f71889ed' | ||
23 | Addresses scanned: none, address read from Super I/O config space | ||
20 | Datasheet: Should become available on the Fintek website soon | 24 | Datasheet: Should become available on the Fintek website soon |
21 | * Fintek F8000 | 25 | * Fintek F8000 |
22 | Prefix: 'f8000' | 26 | Prefix: 'f8000' |
@@ -29,9 +33,9 @@ Author: Hans de Goede <hdegoede@redhat.com> | |||
29 | Description | 33 | Description |
30 | ----------- | 34 | ----------- |
31 | 35 | ||
32 | Fintek F718xxFG/F8000 Super I/O chips include complete hardware monitoring | 36 | Fintek F718xx/F8000 Super I/O chips include complete hardware monitoring |
33 | capabilities. They can monitor up to 9 voltages (3 for the F8000), 4 fans and | 37 | capabilities. They can monitor up to 9 voltages, 4 fans and 3 temperature |
34 | 3 temperature sensors. | 38 | sensors. |
35 | 39 | ||
36 | These chips also have fan controlling features, using either DC or PWM, in | 40 | These chips also have fan controlling features, using either DC or PWM, in |
37 | three different modes (one manual, two automatic). | 41 | three different modes (one manual, two automatic). |
@@ -99,5 +103,5 @@ Writing an unsupported mode will result in an invalid parameter error. | |||
99 | The fan speed is regulated to keep the temp the fan is mapped to between | 103 | The fan speed is regulated to keep the temp the fan is mapped to between |
100 | temp#_auto_point2_temp and temp#_auto_point3_temp. | 104 | temp#_auto_point2_temp and temp#_auto_point3_temp. |
101 | 105 | ||
102 | Both of the automatic modes require that pwm1 corresponds to fan1, pwm2 to | 106 | All of the automatic modes require that pwm1 corresponds to fan1, pwm2 to |
103 | fan2 and pwm3 to fan3. | 107 | fan2 and pwm3 to fan3. |
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c index 4c17f12054a2..49cf19621c0c 100644 --- a/drivers/hwmon/f71882fg.c +++ b/drivers/hwmon/f71882fg.c | |||
@@ -51,16 +51,17 @@ | |||
51 | #define SIO_F71862_ID 0x0601 /* Chipset ID */ | 51 | #define SIO_F71862_ID 0x0601 /* Chipset ID */ |
52 | #define SIO_F71882_ID 0x0541 /* Chipset ID */ | 52 | #define SIO_F71882_ID 0x0541 /* Chipset ID */ |
53 | #define SIO_F71889_ID 0x0723 /* Chipset ID */ | 53 | #define SIO_F71889_ID 0x0723 /* Chipset ID */ |
54 | #define SIO_F71889E_ID 0x0909 /* Chipset ID */ | ||
54 | #define SIO_F8000_ID 0x0581 /* Chipset ID */ | 55 | #define SIO_F8000_ID 0x0581 /* Chipset ID */ |
55 | 56 | ||
56 | #define REGION_LENGTH 8 | 57 | #define REGION_LENGTH 8 |
57 | #define ADDR_REG_OFFSET 5 | 58 | #define ADDR_REG_OFFSET 5 |
58 | #define DATA_REG_OFFSET 6 | 59 | #define DATA_REG_OFFSET 6 |
59 | 60 | ||
60 | #define F71882FG_REG_IN_STATUS 0x12 /* f71882fg only */ | 61 | #define F71882FG_REG_IN_STATUS 0x12 /* f7188x only */ |
61 | #define F71882FG_REG_IN_BEEP 0x13 /* f71882fg only */ | 62 | #define F71882FG_REG_IN_BEEP 0x13 /* f7188x only */ |
62 | #define F71882FG_REG_IN(nr) (0x20 + (nr)) | 63 | #define F71882FG_REG_IN(nr) (0x20 + (nr)) |
63 | #define F71882FG_REG_IN1_HIGH 0x32 /* f71882fg only */ | 64 | #define F71882FG_REG_IN1_HIGH 0x32 /* f7188x only */ |
64 | 65 | ||
65 | #define F71882FG_REG_FAN(nr) (0xA0 + (16 * (nr))) | 66 | #define F71882FG_REG_FAN(nr) (0xA0 + (16 * (nr))) |
66 | #define F71882FG_REG_FAN_TARGET(nr) (0xA2 + (16 * (nr))) | 67 | #define F71882FG_REG_FAN_TARGET(nr) (0xA2 + (16 * (nr))) |
@@ -86,6 +87,7 @@ | |||
86 | 87 | ||
87 | #define F71882FG_REG_FAN_FAULT_T 0x9F | 88 | #define F71882FG_REG_FAN_FAULT_T 0x9F |
88 | #define F71882FG_FAN_NEG_TEMP_EN 0x20 | 89 | #define F71882FG_FAN_NEG_TEMP_EN 0x20 |
90 | #define F71882FG_FAN_PROG_SEL 0x80 | ||
89 | 91 | ||
90 | #define F71882FG_REG_POINT_PWM(pwm, point) (0xAA + (point) + (16 * (pwm))) | 92 | #define F71882FG_REG_POINT_PWM(pwm, point) (0xAA + (point) + (16 * (pwm))) |
91 | #define F71882FG_REG_POINT_TEMP(pwm, point) (0xA6 + (point) + (16 * (pwm))) | 93 | #define F71882FG_REG_POINT_TEMP(pwm, point) (0xA6 + (point) + (16 * (pwm))) |
@@ -101,37 +103,41 @@ static unsigned short force_id; | |||
101 | module_param(force_id, ushort, 0); | 103 | module_param(force_id, ushort, 0); |
102 | MODULE_PARM_DESC(force_id, "Override the detected device ID"); | 104 | MODULE_PARM_DESC(force_id, "Override the detected device ID"); |
103 | 105 | ||
104 | enum chips { f71858fg, f71862fg, f71882fg, f71889fg, f8000 }; | 106 | enum chips { f71858fg, f71862fg, f71882fg, f71889fg, f71889ed, f8000 }; |
105 | 107 | ||
106 | static const char *f71882fg_names[] = { | 108 | static const char *f71882fg_names[] = { |
107 | "f71858fg", | 109 | "f71858fg", |
108 | "f71862fg", | 110 | "f71862fg", |
109 | "f71882fg", | 111 | "f71882fg", |
110 | "f71889fg", | 112 | "f71889fg", |
113 | "f71889ed", | ||
111 | "f8000", | 114 | "f8000", |
112 | }; | 115 | }; |
113 | 116 | ||
114 | static const char f71882fg_has_in[5][F71882FG_MAX_INS] = { | 117 | static const char f71882fg_has_in[6][F71882FG_MAX_INS] = { |
115 | { 1, 1, 1, 0, 0, 0, 0, 0, 0 }, /* f71858fg */ | 118 | { 1, 1, 1, 0, 0, 0, 0, 0, 0 }, /* f71858fg */ |
116 | { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* f71862fg */ | 119 | { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* f71862fg */ |
117 | { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* f71882fg */ | 120 | { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* f71882fg */ |
118 | { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* f71889fg */ | 121 | { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* f71889fg */ |
122 | { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* f71889ed */ | ||
119 | { 1, 1, 1, 0, 0, 0, 0, 0, 0 }, /* f8000 */ | 123 | { 1, 1, 1, 0, 0, 0, 0, 0, 0 }, /* f8000 */ |
120 | }; | 124 | }; |
121 | 125 | ||
122 | static const char f71882fg_has_in1_alarm[5] = { | 126 | static const char f71882fg_has_in1_alarm[6] = { |
123 | 0, /* f71858fg */ | 127 | 0, /* f71858fg */ |
124 | 0, /* f71862fg */ | 128 | 0, /* f71862fg */ |
125 | 1, /* f71882fg */ | 129 | 1, /* f71882fg */ |
126 | 1, /* f71889fg */ | 130 | 1, /* f71889fg */ |
131 | 1, /* f71889ed */ | ||
127 | 0, /* f8000 */ | 132 | 0, /* f8000 */ |
128 | }; | 133 | }; |
129 | 134 | ||
130 | static const char f71882fg_has_beep[5] = { | 135 | static const char f71882fg_has_beep[6] = { |
131 | 0, /* f71858fg */ | 136 | 0, /* f71858fg */ |
132 | 1, /* f71862fg */ | 137 | 1, /* f71862fg */ |
133 | 1, /* f71882fg */ | 138 | 1, /* f71882fg */ |
134 | 1, /* f71889fg */ | 139 | 1, /* f71889fg */ |
140 | 1, /* f71889ed */ | ||
135 | 0, /* f8000 */ | 141 | 0, /* f8000 */ |
136 | }; | 142 | }; |
137 | 143 | ||
@@ -510,7 +516,7 @@ static struct sensor_device_attribute_2 fxxxx_fan_beep_attr[] = { | |||
510 | }; | 516 | }; |
511 | 517 | ||
512 | /* PWM attr for the f71862fg, fewer pwms and fewer zones per pwm than the | 518 | /* PWM attr for the f71862fg, fewer pwms and fewer zones per pwm than the |
513 | f71858fg / f71882fg / f71889fg */ | 519 | standard models */ |
514 | static struct sensor_device_attribute_2 f71862fg_auto_pwm_attr[] = { | 520 | static struct sensor_device_attribute_2 f71862fg_auto_pwm_attr[] = { |
515 | SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR, | 521 | SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR, |
516 | show_pwm_auto_point_channel, | 522 | show_pwm_auto_point_channel, |
@@ -579,7 +585,7 @@ static struct sensor_device_attribute_2 f71862fg_auto_pwm_attr[] = { | |||
579 | show_pwm_auto_point_temp_hyst, NULL, 3, 2), | 585 | show_pwm_auto_point_temp_hyst, NULL, 3, 2), |
580 | }; | 586 | }; |
581 | 587 | ||
582 | /* PWM attr common to the f71858fg, f71882fg and f71889fg */ | 588 | /* PWM attr for the standard models */ |
583 | static struct sensor_device_attribute_2 fxxxx_auto_pwm_attr[4][14] = { { | 589 | static struct sensor_device_attribute_2 fxxxx_auto_pwm_attr[4][14] = { { |
584 | SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR, | 590 | SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR, |
585 | show_pwm_auto_point_channel, | 591 | show_pwm_auto_point_channel, |
@@ -2024,9 +2030,13 @@ static int __devinit f71882fg_probe(struct platform_device *pdev) | |||
2024 | if (start_reg & 0x02) { | 2030 | if (start_reg & 0x02) { |
2025 | switch (data->type) { | 2031 | switch (data->type) { |
2026 | case f71889fg: | 2032 | case f71889fg: |
2033 | case f71889ed: | ||
2027 | reg = f71882fg_read8(data, F71882FG_REG_FAN_FAULT_T); | 2034 | reg = f71882fg_read8(data, F71882FG_REG_FAN_FAULT_T); |
2028 | if (reg & F71882FG_FAN_NEG_TEMP_EN) | 2035 | if (reg & F71882FG_FAN_NEG_TEMP_EN) |
2029 | data->auto_point_temp_signed = 1; | 2036 | data->auto_point_temp_signed = 1; |
2037 | /* Ensure banked pwm registers point to right bank */ | ||
2038 | reg &= ~F71882FG_FAN_PROG_SEL; | ||
2039 | f71882fg_write8(data, F71882FG_REG_FAN_FAULT_T, reg); | ||
2030 | break; | 2040 | break; |
2031 | default: | 2041 | default: |
2032 | break; | 2042 | break; |
@@ -2048,6 +2058,7 @@ static int __devinit f71882fg_probe(struct platform_device *pdev) | |||
2048 | break; | 2058 | break; |
2049 | case f71882fg: | 2059 | case f71882fg: |
2050 | case f71889fg: | 2060 | case f71889fg: |
2061 | case f71889ed: | ||
2051 | err = 0; | 2062 | err = 0; |
2052 | break; | 2063 | break; |
2053 | case f8000: | 2064 | case f8000: |
@@ -2076,11 +2087,13 @@ static int __devinit f71882fg_probe(struct platform_device *pdev) | |||
2076 | 2087 | ||
2077 | switch (data->type) { | 2088 | switch (data->type) { |
2078 | case f71889fg: | 2089 | case f71889fg: |
2090 | case f71889ed: | ||
2079 | for (i = 0; i < nr_fans; i++) { | 2091 | for (i = 0; i < nr_fans; i++) { |
2080 | data->pwm_auto_point_mapping[i] = | 2092 | data->pwm_auto_point_mapping[i] = |
2081 | f71882fg_read8(data, | 2093 | f71882fg_read8(data, |
2082 | F71882FG_REG_POINT_MAPPING(i)); | 2094 | F71882FG_REG_POINT_MAPPING(i)); |
2083 | if (data->pwm_auto_point_mapping[i] & 0x80) | 2095 | if ((data->pwm_auto_point_mapping[i] & 0x80) || |
2096 | (data->pwm_auto_point_mapping[i] & 3) == 0) | ||
2084 | break; | 2097 | break; |
2085 | } | 2098 | } |
2086 | if (i != nr_fans) { | 2099 | if (i != nr_fans) { |
@@ -2219,7 +2232,7 @@ static int f71882fg_remove(struct platform_device *pdev) | |||
2219 | f8000_auto_pwm_attr, | 2232 | f8000_auto_pwm_attr, |
2220 | ARRAY_SIZE(f8000_auto_pwm_attr)); | 2233 | ARRAY_SIZE(f8000_auto_pwm_attr)); |
2221 | break; | 2234 | break; |
2222 | default: /* f71858fg / f71882fg / f71889fg */ | 2235 | default: |
2223 | f71882fg_remove_sysfs_files(pdev, | 2236 | f71882fg_remove_sysfs_files(pdev, |
2224 | &fxxxx_auto_pwm_attr[0][0], | 2237 | &fxxxx_auto_pwm_attr[0][0], |
2225 | ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans); | 2238 | ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans); |
@@ -2261,6 +2274,9 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, | |||
2261 | case SIO_F71889_ID: | 2274 | case SIO_F71889_ID: |
2262 | sio_data->type = f71889fg; | 2275 | sio_data->type = f71889fg; |
2263 | break; | 2276 | break; |
2277 | case SIO_F71889E_ID: | ||
2278 | sio_data->type = f71889ed; | ||
2279 | break; | ||
2264 | case SIO_F8000_ID: | 2280 | case SIO_F8000_ID: |
2265 | sio_data->type = f8000; | 2281 | sio_data->type = f8000; |
2266 | break; | 2282 | break; |