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>
This commit is contained in:
Andrew Paprocki 2008-08-06 22:41:06 +02:00 committed by Jean Delvare
parent 116d0486bd
commit 0475169c13
2 changed files with 27 additions and 14 deletions

View File

@ -11,7 +11,9 @@ Supported chips:
Prefix: 'it8712'
Addresses scanned: from Super I/O config space (8 I/O ports)
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
Prefix: 'it8716'
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
can't have both on a given board.
The IT8716F, IT8718F and later IT8712F revisions have support for
2 additional fans. They are supported by the driver for the IT8716F and
IT8718F but not for the IT8712F
2 additional fans. The additional fans are supported by the driver.
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
clock divider mess) but not compatible with the older chips and
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
for AMD power sequencing. Therefore the chip will appear as IT8716F

View File

@ -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,14 @@ 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)
{
/* 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 __devexit it87_remove(struct platform_device *pdev);
@ -991,8 +1001,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 +1056,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 +1081,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 +1362,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,
@ -1426,7 +1438,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 +1455,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 +1471,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,