diff options
-rw-r--r-- | Documentation/hwmon/f71882fg | 19 | ||||
-rw-r--r-- | drivers/hwmon/Kconfig | 17 | ||||
-rw-r--r-- | drivers/hwmon/f71882fg.c | 126 |
3 files changed, 117 insertions, 45 deletions
diff --git a/Documentation/hwmon/f71882fg b/Documentation/hwmon/f71882fg index 4d0bc70f1852..df02245d1419 100644 --- a/Documentation/hwmon/f71882fg +++ b/Documentation/hwmon/f71882fg | |||
@@ -2,6 +2,10 @@ Kernel driver f71882fg | |||
2 | ====================== | 2 | ====================== |
3 | 3 | ||
4 | Supported chips: | 4 | Supported chips: |
5 | * Fintek F71808E | ||
6 | Prefix: 'f71808e' | ||
7 | Addresses scanned: none, address read from Super I/O config space | ||
8 | Datasheet: Not public | ||
5 | * Fintek F71858FG | 9 | * Fintek F71858FG |
6 | Prefix: 'f71858fg' | 10 | Prefix: 'f71858fg' |
7 | Addresses scanned: none, address read from Super I/O config space | 11 | Addresses scanned: none, address read from Super I/O config space |
@@ -26,10 +30,25 @@ Supported chips: | |||
26 | Prefix: 'f71889ed' | 30 | Prefix: 'f71889ed' |
27 | Addresses scanned: none, address read from Super I/O config space | 31 | Addresses scanned: none, address read from Super I/O config space |
28 | Datasheet: Should become available on the Fintek website soon | 32 | Datasheet: Should become available on the Fintek website soon |
33 | * Fintek F71889A | ||
34 | Prefix: 'f71889a' | ||
35 | Addresses scanned: none, address read from Super I/O config space | ||
36 | Datasheet: Should become available on the Fintek website soon | ||
29 | * Fintek F8000 | 37 | * Fintek F8000 |
30 | Prefix: 'f8000' | 38 | Prefix: 'f8000' |
31 | Addresses scanned: none, address read from Super I/O config space | 39 | Addresses scanned: none, address read from Super I/O config space |
32 | Datasheet: Not public | 40 | Datasheet: Not public |
41 | * Fintek F81801U | ||
42 | Prefix: 'f71889fg' | ||
43 | Addresses scanned: none, address read from Super I/O config space | ||
44 | Datasheet: Not public | ||
45 | Note: This is the 64-pin variant of the F71889FG, they have the | ||
46 | same device ID and are fully compatible as far as hardware | ||
47 | monitoring is concerned. | ||
48 | * Fintek F81865F | ||
49 | Prefix: 'f81865f' | ||
50 | Addresses scanned: none, address read from Super I/O config space | ||
51 | Datasheet: Available from the Fintek website | ||
33 | 52 | ||
34 | Author: Hans de Goede <hdegoede@redhat.com> | 53 | Author: Hans de Goede <hdegoede@redhat.com> |
35 | 54 | ||
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 81131eda5544..060ef6327876 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -315,11 +315,22 @@ config SENSORS_F71805F | |||
315 | will be called f71805f. | 315 | will be called f71805f. |
316 | 316 | ||
317 | config SENSORS_F71882FG | 317 | config SENSORS_F71882FG |
318 | tristate "Fintek F71858FG, F71862FG, F71882FG, F71889FG and F8000" | 318 | tristate "Fintek F71882FG and compatibles" |
319 | help | 319 | help |
320 | If you say yes here you get support for hardware monitoring | 320 | If you say yes here you get support for hardware monitoring |
321 | features of the Fintek F71858FG, F71862FG/71863FG, F71882FG/F71883FG, | 321 | features of many Fintek Super-I/O (LPC) chips. The currently |
322 | F71889FG and F8000 Super-I/O chips. | 322 | supported chips are: |
323 | F71808E | ||
324 | F71858FG | ||
325 | F71862FG | ||
326 | F71863FG | ||
327 | F71869F/E | ||
328 | F71882FG | ||
329 | F71883FG | ||
330 | F71889FG/ED/A | ||
331 | F8000 | ||
332 | F81801U | ||
333 | F81865F | ||
323 | 334 | ||
324 | This driver can also be built as a module. If so, the module | 335 | This driver can also be built as a module. If so, the module |
325 | will be called f71882fg. | 336 | will be called f71882fg. |
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c index a4d430ee7e20..ca07a32447c2 100644 --- a/drivers/hwmon/f71882fg.c +++ b/drivers/hwmon/f71882fg.c | |||
@@ -54,7 +54,9 @@ | |||
54 | #define SIO_F71882_ID 0x0541 /* Chipset ID */ | 54 | #define SIO_F71882_ID 0x0541 /* Chipset ID */ |
55 | #define SIO_F71889_ID 0x0723 /* Chipset ID */ | 55 | #define SIO_F71889_ID 0x0723 /* Chipset ID */ |
56 | #define SIO_F71889E_ID 0x0909 /* Chipset ID */ | 56 | #define SIO_F71889E_ID 0x0909 /* Chipset ID */ |
57 | #define SIO_F71889A_ID 0x1005 /* Chipset ID */ | ||
57 | #define SIO_F8000_ID 0x0581 /* Chipset ID */ | 58 | #define SIO_F8000_ID 0x0581 /* Chipset ID */ |
59 | #define SIO_F81865_ID 0x0704 /* Chipset ID */ | ||
58 | 60 | ||
59 | #define REGION_LENGTH 8 | 61 | #define REGION_LENGTH 8 |
60 | #define ADDR_REG_OFFSET 5 | 62 | #define ADDR_REG_OFFSET 5 |
@@ -106,7 +108,7 @@ module_param(force_id, ushort, 0); | |||
106 | MODULE_PARM_DESC(force_id, "Override the detected device ID"); | 108 | MODULE_PARM_DESC(force_id, "Override the detected device ID"); |
107 | 109 | ||
108 | enum chips { f71808e, f71858fg, f71862fg, f71869, f71882fg, f71889fg, | 110 | enum chips { f71808e, f71858fg, f71862fg, f71869, f71882fg, f71889fg, |
109 | f71889ed, f8000 }; | 111 | f71889ed, f71889a, f8000, f81865f }; |
110 | 112 | ||
111 | static const char *f71882fg_names[] = { | 113 | static const char *f71882fg_names[] = { |
112 | "f71808e", | 114 | "f71808e", |
@@ -114,42 +116,76 @@ static const char *f71882fg_names[] = { | |||
114 | "f71862fg", | 116 | "f71862fg", |
115 | "f71869", /* Both f71869f and f71869e, reg. compatible and same id */ | 117 | "f71869", /* Both f71869f and f71869e, reg. compatible and same id */ |
116 | "f71882fg", | 118 | "f71882fg", |
117 | "f71889fg", | 119 | "f71889fg", /* f81801u too, same id */ |
118 | "f71889ed", | 120 | "f71889ed", |
121 | "f71889a", | ||
119 | "f8000", | 122 | "f8000", |
123 | "f81865f", | ||
120 | }; | 124 | }; |
121 | 125 | ||
122 | static const char f71882fg_has_in[8][F71882FG_MAX_INS] = { | 126 | static const char f71882fg_has_in[][F71882FG_MAX_INS] = { |
123 | { 1, 1, 1, 1, 1, 1, 0, 1, 1 }, /* f71808e */ | 127 | [f71808e] = { 1, 1, 1, 1, 1, 1, 0, 1, 1 }, |
124 | { 1, 1, 1, 0, 0, 0, 0, 0, 0 }, /* f71858fg */ | 128 | [f71858fg] = { 1, 1, 1, 0, 0, 0, 0, 0, 0 }, |
125 | { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* f71862fg */ | 129 | [f71862fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, |
126 | { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* f71869 */ | 130 | [f71869] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, |
127 | { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* f71882fg */ | 131 | [f71882fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, |
128 | { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* f71889fg */ | 132 | [f71889fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, |
129 | { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* f71889ed */ | 133 | [f71889ed] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, |
130 | { 1, 1, 1, 0, 0, 0, 0, 0, 0 }, /* f8000 */ | 134 | [f71889a] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, |
135 | [f8000] = { 1, 1, 1, 0, 0, 0, 0, 0, 0 }, | ||
136 | [f81865f] = { 1, 1, 1, 1, 1, 1, 1, 0, 0 }, | ||
131 | }; | 137 | }; |
132 | 138 | ||
133 | static const char f71882fg_has_in1_alarm[8] = { | 139 | static const char f71882fg_has_in1_alarm[] = { |
134 | 0, /* f71808e */ | 140 | [f71808e] = 0, |
135 | 0, /* f71858fg */ | 141 | [f71858fg] = 0, |
136 | 0, /* f71862fg */ | 142 | [f71862fg] = 0, |
137 | 0, /* f71869 */ | 143 | [f71869] = 0, |
138 | 1, /* f71882fg */ | 144 | [f71882fg] = 1, |
139 | 1, /* f71889fg */ | 145 | [f71889fg] = 1, |
140 | 1, /* f71889ed */ | 146 | [f71889ed] = 1, |
141 | 0, /* f8000 */ | 147 | [f71889a] = 1, |
148 | [f8000] = 0, | ||
149 | [f81865f] = 1, | ||
142 | }; | 150 | }; |
143 | 151 | ||
144 | static const char f71882fg_has_beep[8] = { | 152 | static const char f71882fg_has_beep[] = { |
145 | 0, /* f71808e */ | 153 | [f71808e] = 0, |
146 | 0, /* f71858fg */ | 154 | [f71858fg] = 0, |
147 | 1, /* f71862fg */ | 155 | [f71862fg] = 1, |
148 | 1, /* f71869 */ | 156 | [f71869] = 1, |
149 | 1, /* f71882fg */ | 157 | [f71882fg] = 1, |
150 | 1, /* f71889fg */ | 158 | [f71889fg] = 1, |
151 | 1, /* f71889ed */ | 159 | [f71889ed] = 1, |
152 | 0, /* f8000 */ | 160 | [f71889a] = 1, |
161 | [f8000] = 0, | ||
162 | [f81865f] = 1, | ||
163 | }; | ||
164 | |||
165 | static const char f71882fg_nr_fans[] = { | ||
166 | [f71808e] = 3, | ||
167 | [f71858fg] = 3, | ||
168 | [f71862fg] = 3, | ||
169 | [f71869] = 3, | ||
170 | [f71882fg] = 4, | ||
171 | [f71889fg] = 3, | ||
172 | [f71889ed] = 3, | ||
173 | [f71889a] = 3, | ||
174 | [f8000] = 3, | ||
175 | [f81865f] = 2, | ||
176 | }; | ||
177 | |||
178 | static const char f71882fg_nr_temps[] = { | ||
179 | [f71808e] = 2, | ||
180 | [f71858fg] = 3, | ||
181 | [f71862fg] = 3, | ||
182 | [f71869] = 3, | ||
183 | [f71882fg] = 3, | ||
184 | [f71889fg] = 3, | ||
185 | [f71889ed] = 3, | ||
186 | [f71889a] = 3, | ||
187 | [f8000] = 3, | ||
188 | [f81865f] = 2, | ||
153 | }; | 189 | }; |
154 | 190 | ||
155 | static struct platform_device *f71882fg_pdev; | 191 | static struct platform_device *f71882fg_pdev; |
@@ -1071,9 +1107,9 @@ static u16 f71882fg_read_temp(struct f71882fg_data *data, int nr) | |||
1071 | static struct f71882fg_data *f71882fg_update_device(struct device *dev) | 1107 | static struct f71882fg_data *f71882fg_update_device(struct device *dev) |
1072 | { | 1108 | { |
1073 | struct f71882fg_data *data = dev_get_drvdata(dev); | 1109 | struct f71882fg_data *data = dev_get_drvdata(dev); |
1110 | int nr_fans = f71882fg_nr_fans[data->type]; | ||
1111 | int nr_temps = f71882fg_nr_temps[data->type]; | ||
1074 | int nr, reg, point; | 1112 | int nr, reg, point; |
1075 | int nr_fans = (data->type == f71882fg) ? 4 : 3; | ||
1076 | int nr_temps = (data->type == f71808e) ? 2 : 3; | ||
1077 | 1113 | ||
1078 | mutex_lock(&data->update_lock); | 1114 | mutex_lock(&data->update_lock); |
1079 | 1115 | ||
@@ -2042,8 +2078,9 @@ static int __devinit f71882fg_probe(struct platform_device *pdev) | |||
2042 | { | 2078 | { |
2043 | struct f71882fg_data *data; | 2079 | struct f71882fg_data *data; |
2044 | struct f71882fg_sio_data *sio_data = pdev->dev.platform_data; | 2080 | struct f71882fg_sio_data *sio_data = pdev->dev.platform_data; |
2045 | int err, i, nr_fans = (sio_data->type == f71882fg) ? 4 : 3; | 2081 | int nr_fans = f71882fg_nr_fans[sio_data->type]; |
2046 | int nr_temps = (sio_data->type == f71808e) ? 2 : 3; | 2082 | int nr_temps = f71882fg_nr_temps[sio_data->type]; |
2083 | int err, i; | ||
2047 | u8 start_reg, reg; | 2084 | u8 start_reg, reg; |
2048 | 2085 | ||
2049 | data = kzalloc(sizeof(struct f71882fg_data), GFP_KERNEL); | 2086 | data = kzalloc(sizeof(struct f71882fg_data), GFP_KERNEL); |
@@ -2138,6 +2175,7 @@ static int __devinit f71882fg_probe(struct platform_device *pdev) | |||
2138 | /* Fall through to select correct fan/pwm reg bank! */ | 2175 | /* Fall through to select correct fan/pwm reg bank! */ |
2139 | case f71889fg: | 2176 | case f71889fg: |
2140 | case f71889ed: | 2177 | case f71889ed: |
2178 | case f71889a: | ||
2141 | reg = f71882fg_read8(data, F71882FG_REG_FAN_FAULT_T); | 2179 | reg = f71882fg_read8(data, F71882FG_REG_FAN_FAULT_T); |
2142 | if (reg & F71882FG_FAN_NEG_TEMP_EN) | 2180 | if (reg & F71882FG_FAN_NEG_TEMP_EN) |
2143 | data->auto_point_temp_signed = 1; | 2181 | data->auto_point_temp_signed = 1; |
@@ -2163,16 +2201,12 @@ static int __devinit f71882fg_probe(struct platform_device *pdev) | |||
2163 | case f71862fg: | 2201 | case f71862fg: |
2164 | err = (data->pwm_enable & 0x15) != 0x15; | 2202 | err = (data->pwm_enable & 0x15) != 0x15; |
2165 | break; | 2203 | break; |
2166 | case f71808e: | ||
2167 | case f71869: | ||
2168 | case f71882fg: | ||
2169 | case f71889fg: | ||
2170 | case f71889ed: | ||
2171 | err = 0; | ||
2172 | break; | ||
2173 | case f8000: | 2204 | case f8000: |
2174 | err = data->pwm_enable & 0x20; | 2205 | err = data->pwm_enable & 0x20; |
2175 | break; | 2206 | break; |
2207 | default: | ||
2208 | err = 0; | ||
2209 | break; | ||
2176 | } | 2210 | } |
2177 | if (err) { | 2211 | if (err) { |
2178 | dev_err(&pdev->dev, | 2212 | dev_err(&pdev->dev, |
@@ -2199,6 +2233,7 @@ static int __devinit f71882fg_probe(struct platform_device *pdev) | |||
2199 | case f71869: | 2233 | case f71869: |
2200 | case f71889fg: | 2234 | case f71889fg: |
2201 | case f71889ed: | 2235 | case f71889ed: |
2236 | case f71889a: | ||
2202 | for (i = 0; i < nr_fans; i++) { | 2237 | for (i = 0; i < nr_fans; i++) { |
2203 | data->pwm_auto_point_mapping[i] = | 2238 | data->pwm_auto_point_mapping[i] = |
2204 | f71882fg_read8(data, | 2239 | f71882fg_read8(data, |
@@ -2276,8 +2311,9 @@ exit_free: | |||
2276 | static int f71882fg_remove(struct platform_device *pdev) | 2311 | static int f71882fg_remove(struct platform_device *pdev) |
2277 | { | 2312 | { |
2278 | struct f71882fg_data *data = platform_get_drvdata(pdev); | 2313 | struct f71882fg_data *data = platform_get_drvdata(pdev); |
2279 | int i, nr_fans = (data->type == f71882fg) ? 4 : 3; | 2314 | int nr_fans = f71882fg_nr_fans[data->type]; |
2280 | int nr_temps = (data->type == f71808e) ? 2 : 3; | 2315 | int nr_temps = f71882fg_nr_temps[data->type]; |
2316 | int i; | ||
2281 | u8 start_reg = f71882fg_read8(data, F71882FG_REG_START); | 2317 | u8 start_reg = f71882fg_read8(data, F71882FG_REG_START); |
2282 | 2318 | ||
2283 | if (data->hwmon_dev) | 2319 | if (data->hwmon_dev) |
@@ -2406,9 +2442,15 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, | |||
2406 | case SIO_F71889E_ID: | 2442 | case SIO_F71889E_ID: |
2407 | sio_data->type = f71889ed; | 2443 | sio_data->type = f71889ed; |
2408 | break; | 2444 | break; |
2445 | case SIO_F71889A_ID: | ||
2446 | sio_data->type = f71889a; | ||
2447 | break; | ||
2409 | case SIO_F8000_ID: | 2448 | case SIO_F8000_ID: |
2410 | sio_data->type = f8000; | 2449 | sio_data->type = f8000; |
2411 | break; | 2450 | break; |
2451 | case SIO_F81865_ID: | ||
2452 | sio_data->type = f81865f; | ||
2453 | break; | ||
2412 | default: | 2454 | default: |
2413 | pr_info("Unsupported Fintek device: %04x\n", | 2455 | pr_info("Unsupported Fintek device: %04x\n", |
2414 | (unsigned int)devid); | 2456 | (unsigned int)devid); |