diff options
Diffstat (limited to 'drivers/hwmon')
-rw-r--r-- | drivers/hwmon/it87.c | 32 |
1 files changed, 22 insertions, 10 deletions
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index e12c132ff83a..2a365681f969 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c | |||
@@ -151,9 +151,9 @@ static int fix_pwm_polarity; | |||
151 | /* The IT8718F has the VID value in a different register, in Super-I/O | 151 | /* The IT8718F has the VID value in a different register, in Super-I/O |
152 | configuration space. */ | 152 | configuration space. */ |
153 | #define IT87_REG_VID 0x0a | 153 | #define IT87_REG_VID 0x0a |
154 | /* Warning: register 0x0b is used for something completely different in | 154 | /* The IT8705F and IT8712F earlier than revision 0x08 use register 0x0b |
155 | new chips/revisions. I suspect only 16-bit tachometer mode will work | 155 | for fan divisors. Later IT8712F revisions must use 16-bit tachometer |
156 | for these. */ | 156 | mode. */ |
157 | #define IT87_REG_FAN_DIV 0x0b | 157 | #define IT87_REG_FAN_DIV 0x0b |
158 | #define IT87_REG_FAN_16BIT 0x0c | 158 | #define IT87_REG_FAN_16BIT 0x0c |
159 | 159 | ||
@@ -234,6 +234,7 @@ static const unsigned int pwm_freq[8] = { | |||
234 | struct it87_sio_data { | 234 | struct it87_sio_data { |
235 | enum chips type; | 235 | enum chips type; |
236 | /* Values read from Super-I/O config space */ | 236 | /* Values read from Super-I/O config space */ |
237 | u8 revision; | ||
237 | u8 vid_value; | 238 | u8 vid_value; |
238 | }; | 239 | }; |
239 | 240 | ||
@@ -242,6 +243,7 @@ struct it87_sio_data { | |||
242 | struct it87_data { | 243 | struct it87_data { |
243 | struct device *hwmon_dev; | 244 | struct device *hwmon_dev; |
244 | enum chips type; | 245 | enum chips type; |
246 | u8 revision; | ||
245 | 247 | ||
246 | unsigned short addr; | 248 | unsigned short addr; |
247 | const char *name; | 249 | const char *name; |
@@ -268,6 +270,14 @@ struct it87_data { | |||
268 | u8 manual_pwm_ctl[3]; /* manual PWM value set by user */ | 270 | u8 manual_pwm_ctl[3]; /* manual PWM value set by user */ |
269 | }; | 271 | }; |
270 | 272 | ||
273 | static inline int has_16bit_fans(const struct it87_data *data) | ||
274 | { | ||
275 | /* IT8712F Datasheet 0.9.1, section 8.3.5 indicates 7h == Version I. | ||
276 | This is the first revision with 16bit tachometer support. */ | ||
277 | return (data->type == it8712 && data->revision >= 0x07) | ||
278 | || data->type == it8716 | ||
279 | || data->type == it8718; | ||
280 | } | ||
271 | 281 | ||
272 | static int it87_probe(struct platform_device *pdev); | 282 | static int it87_probe(struct platform_device *pdev); |
273 | static int __devexit it87_remove(struct platform_device *pdev); | 283 | static int __devexit it87_remove(struct platform_device *pdev); |
@@ -991,8 +1001,9 @@ static int __init it87_find(unsigned short *address, | |||
991 | } | 1001 | } |
992 | 1002 | ||
993 | err = 0; | 1003 | err = 0; |
1004 | sio_data->revision = superio_inb(DEVREV) & 0x0f; | ||
994 | pr_info("it87: Found IT%04xF chip at 0x%x, revision %d\n", | 1005 | pr_info("it87: Found IT%04xF chip at 0x%x, revision %d\n", |
995 | chip_type, *address, superio_inb(DEVREV) & 0x0f); | 1006 | chip_type, *address, sio_data->revision); |
996 | 1007 | ||
997 | /* Read GPIO config and VID value from LDN 7 (GPIO) */ | 1008 | /* Read GPIO config and VID value from LDN 7 (GPIO) */ |
998 | if (chip_type != IT8705F_DEVID) { | 1009 | if (chip_type != IT8705F_DEVID) { |
@@ -1045,6 +1056,7 @@ static int __devinit it87_probe(struct platform_device *pdev) | |||
1045 | 1056 | ||
1046 | data->addr = res->start; | 1057 | data->addr = res->start; |
1047 | data->type = sio_data->type; | 1058 | data->type = sio_data->type; |
1059 | data->revision = sio_data->revision; | ||
1048 | data->name = names[sio_data->type]; | 1060 | data->name = names[sio_data->type]; |
1049 | 1061 | ||
1050 | /* Now, we do the remaining detection. */ | 1062 | /* Now, we do the remaining detection. */ |
@@ -1069,7 +1081,7 @@ static int __devinit it87_probe(struct platform_device *pdev) | |||
1069 | goto ERROR2; | 1081 | goto ERROR2; |
1070 | 1082 | ||
1071 | /* Do not create fan files for disabled fans */ | 1083 | /* Do not create fan files for disabled fans */ |
1072 | if (data->type == it8716 || data->type == it8718) { | 1084 | if (has_16bit_fans(data)) { |
1073 | /* 16-bit tachometers */ | 1085 | /* 16-bit tachometers */ |
1074 | if (data->has_fan & (1 << 0)) { | 1086 | if (data->has_fan & (1 << 0)) { |
1075 | if ((err = device_create_file(dev, | 1087 | if ((err = device_create_file(dev, |
@@ -1350,7 +1362,7 @@ static void __devinit it87_init_device(struct platform_device *pdev) | |||
1350 | data->has_fan = (data->fan_main_ctrl >> 4) & 0x07; | 1362 | data->has_fan = (data->fan_main_ctrl >> 4) & 0x07; |
1351 | 1363 | ||
1352 | /* Set tachometers to 16-bit mode if needed */ | 1364 | /* Set tachometers to 16-bit mode if needed */ |
1353 | if (data->type == it8716 || data->type == it8718) { | 1365 | if (has_16bit_fans(data)) { |
1354 | tmp = it87_read_value(data, IT87_REG_FAN_16BIT); | 1366 | tmp = it87_read_value(data, IT87_REG_FAN_16BIT); |
1355 | if (~tmp & 0x07 & data->has_fan) { | 1367 | if (~tmp & 0x07 & data->has_fan) { |
1356 | dev_dbg(&pdev->dev, | 1368 | dev_dbg(&pdev->dev, |
@@ -1426,7 +1438,7 @@ static struct it87_data *it87_update_device(struct device *dev) | |||
1426 | data->fan[i] = it87_read_value(data, | 1438 | data->fan[i] = it87_read_value(data, |
1427 | IT87_REG_FAN[i]); | 1439 | IT87_REG_FAN[i]); |
1428 | /* Add high byte if in 16-bit mode */ | 1440 | /* Add high byte if in 16-bit mode */ |
1429 | if (data->type == it8716 || data->type == it8718) { | 1441 | if (has_16bit_fans(data)) { |
1430 | data->fan[i] |= it87_read_value(data, | 1442 | data->fan[i] |= it87_read_value(data, |
1431 | IT87_REG_FANX[i]) << 8; | 1443 | IT87_REG_FANX[i]) << 8; |
1432 | data->fan_min[i] |= it87_read_value(data, | 1444 | data->fan_min[i] |= it87_read_value(data, |
@@ -1443,8 +1455,7 @@ static struct it87_data *it87_update_device(struct device *dev) | |||
1443 | } | 1455 | } |
1444 | 1456 | ||
1445 | /* Newer chips don't have clock dividers */ | 1457 | /* Newer chips don't have clock dividers */ |
1446 | if ((data->has_fan & 0x07) && data->type != it8716 | 1458 | if ((data->has_fan & 0x07) && !has_16bit_fans(data)) { |
1447 | && data->type != it8718) { | ||
1448 | i = it87_read_value(data, IT87_REG_FAN_DIV); | 1459 | i = it87_read_value(data, IT87_REG_FAN_DIV); |
1449 | data->fan_div[0] = i & 0x07; | 1460 | data->fan_div[0] = i & 0x07; |
1450 | data->fan_div[1] = (i >> 3) & 0x07; | 1461 | data->fan_div[1] = (i >> 3) & 0x07; |
@@ -1460,7 +1471,8 @@ static struct it87_data *it87_update_device(struct device *dev) | |||
1460 | data->fan_ctl = it87_read_value(data, IT87_REG_FAN_CTL); | 1471 | data->fan_ctl = it87_read_value(data, IT87_REG_FAN_CTL); |
1461 | 1472 | ||
1462 | data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE); | 1473 | data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE); |
1463 | /* The 8705 does not have VID capability */ | 1474 | /* The 8705 does not have VID capability. |
1475 | The 8718 does not use IT87_REG_VID for the same purpose. */ | ||
1464 | if (data->type == it8712 || data->type == it8716) { | 1476 | if (data->type == it8712 || data->type == it8716) { |
1465 | data->vid = it87_read_value(data, IT87_REG_VID); | 1477 | data->vid = it87_read_value(data, IT87_REG_VID); |
1466 | /* The older IT8712F revisions had only 5 VID pins, | 1478 | /* The older IT8712F revisions had only 5 VID pins, |