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:
parent
116d0486bd
commit
0475169c13
|
@ -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
|
||||||
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;
|
||||||
/* 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] = {
|
||||||
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 {
|
||||||
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 {
|
||||||
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,
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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)
|
||||||
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,
|
||||||
|
|
Loading…
Reference in New Issue