aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/hwmon/f71882fg19
-rw-r--r--drivers/hwmon/Kconfig17
-rw-r--r--drivers/hwmon/f71882fg.c126
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
4Supported chips: 4Supported 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
34Author: Hans de Goede <hdegoede@redhat.com> 53Author: 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
317config SENSORS_F71882FG 317config 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);
106MODULE_PARM_DESC(force_id, "Override the detected device ID"); 108MODULE_PARM_DESC(force_id, "Override the detected device ID");
107 109
108enum chips { f71808e, f71858fg, f71862fg, f71869, f71882fg, f71889fg, 110enum chips { f71808e, f71858fg, f71862fg, f71869, f71882fg, f71889fg,
109 f71889ed, f8000 }; 111 f71889ed, f71889a, f8000, f81865f };
110 112
111static const char *f71882fg_names[] = { 113static 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
122static const char f71882fg_has_in[8][F71882FG_MAX_INS] = { 126static 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
133static const char f71882fg_has_in1_alarm[8] = { 139static 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
144static const char f71882fg_has_beep[8] = { 152static 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
165static 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
178static 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
155static struct platform_device *f71882fg_pdev; 191static struct platform_device *f71882fg_pdev;
@@ -1071,9 +1107,9 @@ static u16 f71882fg_read_temp(struct f71882fg_data *data, int nr)
1071static struct f71882fg_data *f71882fg_update_device(struct device *dev) 1107static 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:
2276static int f71882fg_remove(struct platform_device *pdev) 2311static 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);