Commit 0475169c authored by Andrew Paprocki's avatar Andrew Paprocki Committed by Jean Delvare

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: default avatarAndrew Paprocki <andrew@ishiboo.com>
Signed-off-by: default avatarJean Delvare <khali@linux-fr.org>
parent 116d0486
...@@ -11,7 +11,9 @@ Supported chips: ...@@ -11,7 +11,9 @@ Supported chips:
Prefix: 'it8712' Prefix: 'it8712'
Addresses scanned: from Super I/O config space (8 I/O ports) Addresses scanned: from Super I/O config space (8 I/O ports)
Datasheet: Publicly available at the ITE website Datasheet: Publicly available at the ITE website
http://www.ite.com.tw/ http://www.ite.com.tw/product_info/file/pc/IT8712F_V0.9.1.pdf
http://www.ite.com.tw/product_info/file/pc/Errata%20V0.1%20for%20IT8712F%20V0.9.1.pdf
http://www.ite.com.tw/product_info/file/pc/IT8712F_V0.9.3.pdf
* IT8716F/IT8726F * IT8716F/IT8726F
Prefix: 'it8716' Prefix: 'it8716'
Addresses scanned: from Super I/O config space (8 I/O ports) Addresses scanned: from Super I/O config space (8 I/O ports)
...@@ -90,14 +92,13 @@ upper VID bits share their pins with voltage inputs (in5 and in6) so you ...@@ -90,14 +92,13 @@ upper VID bits share their pins with voltage inputs (in5 and in6) so you
can't have both on a given board. can't have both on a given board.
The IT8716F, IT8718F and later IT8712F revisions have support for The IT8716F, IT8718F and later IT8712F revisions have support for
2 additional fans. They are supported by the driver for the IT8716F and 2 additional fans. The additional fans are supported by the driver.
IT8718F but not for the IT8712F
The IT8716F and IT8718F, and late IT8712F and IT8705F also have optional The IT8716F and IT8718F, and late IT8712F and IT8705F also have optional
16-bit tachometer counters for fans 1 to 3. This is better (no more fan 16-bit tachometer counters for fans 1 to 3. This is better (no more fan
clock divider mess) but not compatible with the older chips and clock divider mess) but not compatible with the older chips and
revisions. For now, the driver only uses the 16-bit mode on the revisions. For now, the driver only uses the 16-bit mode on the
IT8716F and IT8718F. late IT8712F, IT8716F and IT8718F.
The IT8726F is just bit enhanced IT8716F with additional hardware The IT8726F is just bit enhanced IT8716F with additional hardware
for AMD power sequencing. Therefore the chip will appear as IT8716F for AMD power sequencing. Therefore the chip will appear as IT8716F
......
...@@ -151,9 +151,9 @@ static int fix_pwm_polarity; ...@@ -151,9 +151,9 @@ static int fix_pwm_polarity;
/* The IT8718F has the VID value in a different register, in Super-I/O /* The IT8718F has the VID value in a different register, in Super-I/O
configuration space. */ configuration space. */
#define IT87_REG_VID 0x0a #define IT87_REG_VID 0x0a
/* Warning: register 0x0b is used for something completely different in /* The IT8705F and IT8712F earlier than revision 0x08 use register 0x0b
new chips/revisions. I suspect only 16-bit tachometer mode will work for fan divisors. Later IT8712F revisions must use 16-bit tachometer
for these. */ mode. */
#define IT87_REG_FAN_DIV 0x0b #define IT87_REG_FAN_DIV 0x0b
#define IT87_REG_FAN_16BIT 0x0c #define IT87_REG_FAN_16BIT 0x0c
...@@ -234,6 +234,7 @@ static const unsigned int pwm_freq[8] = { ...@@ -234,6 +234,7 @@ static const unsigned int pwm_freq[8] = {
struct it87_sio_data { struct it87_sio_data {
enum chips type; enum chips type;
/* Values read from Super-I/O config space */ /* Values read from Super-I/O config space */
u8 revision;
u8 vid_value; u8 vid_value;
}; };
...@@ -242,6 +243,7 @@ struct it87_sio_data { ...@@ -242,6 +243,7 @@ struct it87_sio_data {
struct it87_data { struct it87_data {
struct device *hwmon_dev; struct device *hwmon_dev;
enum chips type; enum chips type;
u8 revision;
unsigned short addr; unsigned short addr;
const char *name; const char *name;
...@@ -268,6 +270,14 @@ struct it87_data { ...@@ -268,6 +270,14 @@ struct it87_data {
u8 manual_pwm_ctl[3]; /* manual PWM value set by user */ u8 manual_pwm_ctl[3]; /* manual PWM value set by user */
}; };
static inline int has_16bit_fans(const struct it87_data *data)
{
/* IT8712F Datasheet 0.9.1, section 8.3.5 indicates 7h == Version I.
This is the first revision with 16bit tachometer support. */
return (data->type == it8712 && data->revision >= 0x07)
|| data->type == it8716
|| data->type == it8718;
}
static int it87_probe(struct platform_device *pdev); static int it87_probe(struct platform_device *pdev);
static int __devexit it87_remove(struct platform_device *pdev); static int __devexit it87_remove(struct platform_device *pdev);
...@@ -991,8 +1001,9 @@ static int __init it87_find(unsigned short *address, ...@@ -991,8 +1001,9 @@ static int __init it87_find(unsigned short *address,
} }
err = 0; err = 0;
sio_data->revision = superio_inb(DEVREV) & 0x0f;
pr_info("it87: Found IT%04xF chip at 0x%x, revision %d\n", 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) */ /* Read GPIO config and VID value from LDN 7 (GPIO) */
if (chip_type != IT8705F_DEVID) { if (chip_type != IT8705F_DEVID) {
...@@ -1045,6 +1056,7 @@ static int __devinit it87_probe(struct platform_device *pdev) ...@@ -1045,6 +1056,7 @@ static int __devinit it87_probe(struct platform_device *pdev)
data->addr = res->start; data->addr = res->start;
data->type = sio_data->type; data->type = sio_data->type;
data->revision = sio_data->revision;
data->name = names[sio_data->type]; data->name = names[sio_data->type];
/* Now, we do the remaining detection. */ /* Now, we do the remaining detection. */
...@@ -1069,7 +1081,7 @@ static int __devinit it87_probe(struct platform_device *pdev) ...@@ -1069,7 +1081,7 @@ static int __devinit it87_probe(struct platform_device *pdev)
goto ERROR2; goto ERROR2;
/* Do not create fan files for disabled fans */ /* Do not create fan files for disabled fans */
if (data->type == it8716 || data->type == it8718) { if (has_16bit_fans(data)) {
/* 16-bit tachometers */ /* 16-bit tachometers */
if (data->has_fan & (1 << 0)) { if (data->has_fan & (1 << 0)) {
if ((err = device_create_file(dev, if ((err = device_create_file(dev,
...@@ -1350,7 +1362,7 @@ static void __devinit it87_init_device(struct platform_device *pdev) ...@@ -1350,7 +1362,7 @@ static void __devinit it87_init_device(struct platform_device *pdev)
data->has_fan = (data->fan_main_ctrl >> 4) & 0x07; data->has_fan = (data->fan_main_ctrl >> 4) & 0x07;
/* Set tachometers to 16-bit mode if needed */ /* 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); tmp = it87_read_value(data, IT87_REG_FAN_16BIT);
if (~tmp & 0x07 & data->has_fan) { if (~tmp & 0x07 & data->has_fan) {
dev_dbg(&pdev->dev, dev_dbg(&pdev->dev,
...@@ -1426,7 +1438,7 @@ static struct it87_data *it87_update_device(struct device *dev) ...@@ -1426,7 +1438,7 @@ static struct it87_data *it87_update_device(struct device *dev)
data->fan[i] = it87_read_value(data, data->fan[i] = it87_read_value(data,
IT87_REG_FAN[i]); IT87_REG_FAN[i]);
/* Add high byte if in 16-bit mode */ /* 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, data->fan[i] |= it87_read_value(data,
IT87_REG_FANX[i]) << 8; IT87_REG_FANX[i]) << 8;
data->fan_min[i] |= it87_read_value(data, data->fan_min[i] |= it87_read_value(data,
...@@ -1443,8 +1455,7 @@ static struct it87_data *it87_update_device(struct device *dev) ...@@ -1443,8 +1455,7 @@ static struct it87_data *it87_update_device(struct device *dev)
} }
/* Newer chips don't have clock dividers */ /* Newer chips don't have clock dividers */
if ((data->has_fan & 0x07) && data->type != it8716 if ((data->has_fan & 0x07) && !has_16bit_fans(data)) {
&& data->type != it8718) {
i = it87_read_value(data, IT87_REG_FAN_DIV); i = it87_read_value(data, IT87_REG_FAN_DIV);
data->fan_div[0] = i & 0x07; data->fan_div[0] = i & 0x07;
data->fan_div[1] = (i >> 3) & 0x07; data->fan_div[1] = (i >> 3) & 0x07;
...@@ -1460,7 +1471,8 @@ static struct it87_data *it87_update_device(struct device *dev) ...@@ -1460,7 +1471,8 @@ static struct it87_data *it87_update_device(struct device *dev)
data->fan_ctl = it87_read_value(data, IT87_REG_FAN_CTL); data->fan_ctl = it87_read_value(data, IT87_REG_FAN_CTL);
data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE); 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) { if (data->type == it8712 || data->type == it8716) {
data->vid = it87_read_value(data, IT87_REG_VID); data->vid = it87_read_value(data, IT87_REG_VID);
/* The older IT8712F revisions had only 5 VID pins, /* The older IT8712F revisions had only 5 VID pins,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment