Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+5 −4
Original line number Original line Diff line number Diff line
@@ -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
+22 −10
Original line number Original line Diff line number Diff line
@@ -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,