aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/it87.c
diff options
context:
space:
mode:
authorAndrew Paprocki <andrew@ishiboo.com>2008-08-06 16:41:06 -0400
committerJean Delvare <khali@mahadeva.delvare>2008-08-06 16:41:06 -0400
commit0475169c13e177e1af5a02f5e9f30fda13dc0b86 (patch)
tree9366e6e093ff39b037011a392c8f97140c3ccad9 /drivers/hwmon/it87.c
parent116d0486bdefc11f71e567cadf0c47f788b4dd06 (diff)
hwmon: (it87) Support for 16-bit fan reading in it8712 >= rev 0x07
The it8712 chip supports 16-bit fan tachometers in revisions >= 0x07. Revisions >= 0x08 dropped support for 8-bit fan divisor registers. The patch enables 16-bit fan readings on all revisions >= 0x07 just like the it8716 and it8718 chips. Signed-off-by: Andrew Paprocki <andrew@ishiboo.com> Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/hwmon/it87.c')
-rw-r--r--drivers/hwmon/it87.c32
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] = {
234struct it87_sio_data { 234struct 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 {
242struct it87_data { 243struct 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
273static 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
272static int it87_probe(struct platform_device *pdev); 282static int it87_probe(struct platform_device *pdev);
273static int __devexit it87_remove(struct platform_device *pdev); 283static 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,