diff options
Diffstat (limited to 'drivers/hwmon/it87.c')
-rw-r--r-- | drivers/hwmon/it87.c | 45 |
1 files changed, 31 insertions, 14 deletions
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index e12c132ff83a..30cdb0956779 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,16 @@ 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 | /* IT8705F Datasheet 0.4.1, 3h == Version G. | ||
276 | IT8712F Datasheet 0.9.1, section 8.3.5 indicates 7h == Version I. | ||
277 | These are the first revisions with 16bit tachometer support. */ | ||
278 | return (data->type == it87 && data->revision >= 0x03) | ||
279 | || (data->type == it8712 && data->revision >= 0x07) | ||
280 | || data->type == it8716 | ||
281 | || data->type == it8718; | ||
282 | } | ||
271 | 283 | ||
272 | static int it87_probe(struct platform_device *pdev); | 284 | static int it87_probe(struct platform_device *pdev); |
273 | static int __devexit it87_remove(struct platform_device *pdev); | 285 | static int __devexit it87_remove(struct platform_device *pdev); |
@@ -991,8 +1003,9 @@ static int __init it87_find(unsigned short *address, | |||
991 | } | 1003 | } |
992 | 1004 | ||
993 | err = 0; | 1005 | err = 0; |
1006 | sio_data->revision = superio_inb(DEVREV) & 0x0f; | ||
994 | pr_info("it87: Found IT%04xF chip at 0x%x, revision %d\n", | 1007 | pr_info("it87: Found IT%04xF chip at 0x%x, revision %d\n", |
995 | chip_type, *address, superio_inb(DEVREV) & 0x0f); | 1008 | chip_type, *address, sio_data->revision); |
996 | 1009 | ||
997 | /* Read GPIO config and VID value from LDN 7 (GPIO) */ | 1010 | /* Read GPIO config and VID value from LDN 7 (GPIO) */ |
998 | if (chip_type != IT8705F_DEVID) { | 1011 | if (chip_type != IT8705F_DEVID) { |
@@ -1045,6 +1058,7 @@ static int __devinit it87_probe(struct platform_device *pdev) | |||
1045 | 1058 | ||
1046 | data->addr = res->start; | 1059 | data->addr = res->start; |
1047 | data->type = sio_data->type; | 1060 | data->type = sio_data->type; |
1061 | data->revision = sio_data->revision; | ||
1048 | data->name = names[sio_data->type]; | 1062 | data->name = names[sio_data->type]; |
1049 | 1063 | ||
1050 | /* Now, we do the remaining detection. */ | 1064 | /* Now, we do the remaining detection. */ |
@@ -1069,7 +1083,7 @@ static int __devinit it87_probe(struct platform_device *pdev) | |||
1069 | goto ERROR2; | 1083 | goto ERROR2; |
1070 | 1084 | ||
1071 | /* Do not create fan files for disabled fans */ | 1085 | /* Do not create fan files for disabled fans */ |
1072 | if (data->type == it8716 || data->type == it8718) { | 1086 | if (has_16bit_fans(data)) { |
1073 | /* 16-bit tachometers */ | 1087 | /* 16-bit tachometers */ |
1074 | if (data->has_fan & (1 << 0)) { | 1088 | if (data->has_fan & (1 << 0)) { |
1075 | if ((err = device_create_file(dev, | 1089 | if ((err = device_create_file(dev, |
@@ -1350,7 +1364,7 @@ static void __devinit it87_init_device(struct platform_device *pdev) | |||
1350 | data->has_fan = (data->fan_main_ctrl >> 4) & 0x07; | 1364 | data->has_fan = (data->fan_main_ctrl >> 4) & 0x07; |
1351 | 1365 | ||
1352 | /* Set tachometers to 16-bit mode if needed */ | 1366 | /* Set tachometers to 16-bit mode if needed */ |
1353 | if (data->type == it8716 || data->type == it8718) { | 1367 | if (has_16bit_fans(data)) { |
1354 | tmp = it87_read_value(data, IT87_REG_FAN_16BIT); | 1368 | tmp = it87_read_value(data, IT87_REG_FAN_16BIT); |
1355 | if (~tmp & 0x07 & data->has_fan) { | 1369 | if (~tmp & 0x07 & data->has_fan) { |
1356 | dev_dbg(&pdev->dev, | 1370 | dev_dbg(&pdev->dev, |
@@ -1358,10 +1372,13 @@ static void __devinit it87_init_device(struct platform_device *pdev) | |||
1358 | it87_write_value(data, IT87_REG_FAN_16BIT, | 1372 | it87_write_value(data, IT87_REG_FAN_16BIT, |
1359 | tmp | 0x07); | 1373 | tmp | 0x07); |
1360 | } | 1374 | } |
1361 | if (tmp & (1 << 4)) | 1375 | /* IT8705F only supports three fans. */ |
1362 | data->has_fan |= (1 << 3); /* fan4 enabled */ | 1376 | if (data->type != it87) { |
1363 | if (tmp & (1 << 5)) | 1377 | if (tmp & (1 << 4)) |
1364 | data->has_fan |= (1 << 4); /* fan5 enabled */ | 1378 | data->has_fan |= (1 << 3); /* fan4 enabled */ |
1379 | if (tmp & (1 << 5)) | ||
1380 | data->has_fan |= (1 << 4); /* fan5 enabled */ | ||
1381 | } | ||
1365 | } | 1382 | } |
1366 | 1383 | ||
1367 | /* Set current fan mode registers and the default settings for the | 1384 | /* Set current fan mode registers and the default settings for the |
@@ -1426,7 +1443,7 @@ static struct it87_data *it87_update_device(struct device *dev) | |||
1426 | data->fan[i] = it87_read_value(data, | 1443 | data->fan[i] = it87_read_value(data, |
1427 | IT87_REG_FAN[i]); | 1444 | IT87_REG_FAN[i]); |
1428 | /* Add high byte if in 16-bit mode */ | 1445 | /* Add high byte if in 16-bit mode */ |
1429 | if (data->type == it8716 || data->type == it8718) { | 1446 | if (has_16bit_fans(data)) { |
1430 | data->fan[i] |= it87_read_value(data, | 1447 | data->fan[i] |= it87_read_value(data, |
1431 | IT87_REG_FANX[i]) << 8; | 1448 | IT87_REG_FANX[i]) << 8; |
1432 | data->fan_min[i] |= it87_read_value(data, | 1449 | data->fan_min[i] |= it87_read_value(data, |
@@ -1443,8 +1460,7 @@ static struct it87_data *it87_update_device(struct device *dev) | |||
1443 | } | 1460 | } |
1444 | 1461 | ||
1445 | /* Newer chips don't have clock dividers */ | 1462 | /* Newer chips don't have clock dividers */ |
1446 | if ((data->has_fan & 0x07) && data->type != it8716 | 1463 | if ((data->has_fan & 0x07) && !has_16bit_fans(data)) { |
1447 | && data->type != it8718) { | ||
1448 | i = it87_read_value(data, IT87_REG_FAN_DIV); | 1464 | i = it87_read_value(data, IT87_REG_FAN_DIV); |
1449 | data->fan_div[0] = i & 0x07; | 1465 | data->fan_div[0] = i & 0x07; |
1450 | data->fan_div[1] = (i >> 3) & 0x07; | 1466 | data->fan_div[1] = (i >> 3) & 0x07; |
@@ -1460,7 +1476,8 @@ static struct it87_data *it87_update_device(struct device *dev) | |||
1460 | data->fan_ctl = it87_read_value(data, IT87_REG_FAN_CTL); | 1476 | data->fan_ctl = it87_read_value(data, IT87_REG_FAN_CTL); |
1461 | 1477 | ||
1462 | data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE); | 1478 | data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE); |
1463 | /* The 8705 does not have VID capability */ | 1479 | /* The 8705 does not have VID capability. |
1480 | The 8718 does not use IT87_REG_VID for the same purpose. */ | ||
1464 | if (data->type == it8712 || data->type == it8716) { | 1481 | if (data->type == it8712 || data->type == it8716) { |
1465 | data->vid = it87_read_value(data, IT87_REG_VID); | 1482 | data->vid = it87_read_value(data, IT87_REG_VID); |
1466 | /* The older IT8712F revisions had only 5 VID pins, | 1483 | /* The older IT8712F revisions had only 5 VID pins, |