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; /* The IT8718F has the VID value in a different register, in Super-I/O configuration space. */ #define IT87_REG_VID 0x0a -/* Warning: register 0x0b is used for something completely different in - new chips/revisions. I suspect only 16-bit tachometer mode will work - for these. */ +/* The IT8705F and IT8712F earlier than revision 0x08 use register 0x0b + for fan divisors. Later IT8712F revisions must use 16-bit tachometer + mode. */ #define IT87_REG_FAN_DIV 0x0b #define IT87_REG_FAN_16BIT 0x0c @@ -234,6 +234,7 @@ static const unsigned int pwm_freq[8] = { struct it87_sio_data { enum chips type; /* Values read from Super-I/O config space */ + u8 revision; u8 vid_value; }; @@ -242,6 +243,7 @@ struct it87_sio_data { struct it87_data { struct device *hwmon_dev; enum chips type; + u8 revision; unsigned short addr; const char *name; @@ -268,6 +270,16 @@ struct it87_data { u8 manual_pwm_ctl[3]; /* manual PWM value set by user */ }; +static inline int has_16bit_fans(const struct it87_data *data) +{ + /* IT8705F Datasheet 0.4.1, 3h == Version G. + IT8712F Datasheet 0.9.1, section 8.3.5 indicates 7h == Version I. + These are the first revisions with 16bit tachometer support. */ + return (data->type == it87 && data->revision >= 0x03) + || (data->type == it8712 && data->revision >= 0x07) + || data->type == it8716 + || data->type == it8718; +} static int it87_probe(struct platform_device *pdev); static int __devexit it87_remove(struct platform_device *pdev); @@ -991,8 +1003,9 @@ static int __init it87_find(unsigned short *address, } err = 0; + sio_data->revision = superio_inb(DEVREV) & 0x0f; pr_info("it87: Found IT%04xF chip at 0x%x, revision %d\n", - chip_type, *address, superio_inb(DEVREV) & 0x0f); + chip_type, *address, sio_data->revision); /* Read GPIO config and VID value from LDN 7 (GPIO) */ if (chip_type != IT8705F_DEVID) { @@ -1045,6 +1058,7 @@ static int __devinit it87_probe(struct platform_device *pdev) data->addr = res->start; data->type = sio_data->type; + data->revision = sio_data->revision; data->name = names[sio_data->type]; /* Now, we do the remaining detection. */ @@ -1069,7 +1083,7 @@ static int __devinit it87_probe(struct platform_device *pdev) goto ERROR2; /* Do not create fan files for disabled fans */ - if (data->type == it8716 || data->type == it8718) { + if (has_16bit_fans(data)) { /* 16-bit tachometers */ if (data->has_fan & (1 << 0)) { if ((err = device_create_file(dev, @@ -1350,7 +1364,7 @@ static void __devinit it87_init_device(struct platform_device *pdev) data->has_fan = (data->fan_main_ctrl >> 4) & 0x07; /* Set tachometers to 16-bit mode if needed */ - if (data->type == it8716 || data->type == it8718) { + if (has_16bit_fans(data)) { tmp = it87_read_value(data, IT87_REG_FAN_16BIT); if (~tmp & 0x07 & data->has_fan) { dev_dbg(&pdev->dev, @@ -1358,10 +1372,13 @@ static void __devinit it87_init_device(struct platform_device *pdev) it87_write_value(data, IT87_REG_FAN_16BIT, tmp | 0x07); } - if (tmp & (1 << 4)) - data->has_fan |= (1 << 3); /* fan4 enabled */ - if (tmp & (1 << 5)) - data->has_fan |= (1 << 4); /* fan5 enabled */ + /* IT8705F only supports three fans. */ + if (data->type != it87) { + if (tmp & (1 << 4)) + data->has_fan |= (1 << 3); /* fan4 enabled */ + if (tmp & (1 << 5)) + data->has_fan |= (1 << 4); /* fan5 enabled */ + } } /* 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) data->fan[i] = it87_read_value(data, IT87_REG_FAN[i]); /* Add high byte if in 16-bit mode */ - if (data->type == it8716 || data->type == it8718) { + if (has_16bit_fans(data)) { data->fan[i] |= it87_read_value(data, IT87_REG_FANX[i]) << 8; data->fan_min[i] |= it87_read_value(data, @@ -1443,8 +1460,7 @@ static struct it87_data *it87_update_device(struct device *dev) } /* Newer chips don't have clock dividers */ - if ((data->has_fan & 0x07) && data->type != it8716 - && data->type != it8718) { + if ((data->has_fan & 0x07) && !has_16bit_fans(data)) { i = it87_read_value(data, IT87_REG_FAN_DIV); data->fan_div[0] = i & 0x07; data->fan_div[1] = (i >> 3) & 0x07; @@ -1460,7 +1476,8 @@ static struct it87_data *it87_update_device(struct device *dev) data->fan_ctl = it87_read_value(data, IT87_REG_FAN_CTL); data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE); - /* The 8705 does not have VID capability */ + /* The 8705 does not have VID capability. + The 8718 does not use IT87_REG_VID for the same purpose. */ if (data->type == it8712 || data->type == it8716) { data->vid = it87_read_value(data, IT87_REG_VID); /* The older IT8712F revisions had only 5 VID pins, |