Files
it87/it87-roeck.patch
2019-01-27 15:23:29 +01:00

9071 lines
302 KiB
Diff

From 5072a0c75856746adee6b559b283e1acb2003682 Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Wed, 28 Dec 2016 20:45:31 -0800
Subject: [PATCH 01/61] Experimental support for IT8607E
Assume for now that in5 and in6 are supported, and that fan control
is standard (unlike IT8603E).
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index f8499cb..ccab431 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -11,6 +11,7 @@
* similar parts. The other devices are supported by different drivers.
*
* Supports: IT8603E Super I/O chip w/LPC interface
+ * IT8607E Super I/O chip w/LPC interface
* IT8620E Super I/O chip w/LPC interface
* IT8622E Super I/O chip w/LPC interface
* IT8623E Super I/O chip w/LPC interface
@@ -72,7 +73,7 @@
enum chips { it87, it8712, it8716, it8718, it8720, it8721, it8728, it8732,
it8771, it8772, it8781, it8782, it8783, it8786, it8790,
- it8792, it8603, it8620, it8622, it8628 };
+ it8792, it8603, it8607, it8620, it8622, it8628 };
static unsigned short force_id;
module_param(force_id, ushort, 0);
@@ -162,6 +163,7 @@ static inline void superio_exit(int ioreg)
#define IT8786E_DEVID 0x8786
#define IT8790E_DEVID 0x8790
#define IT8603E_DEVID 0x8603
+#define IT8607E_DEVID 0x8607
#define IT8620E_DEVID 0x8620
#define IT8622E_DEVID 0x8622
#define IT8623E_DEVID 0x8623
@@ -442,6 +444,14 @@ static const struct it87_devices it87_devices[] = {
| FEAT_AVCC3 | FEAT_PWM_FREQ2,
.peci_mask = 0x07,
},
+ [it8607] = {
+ .name = "it8607",
+ .suffix = "E",
+ .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
+ | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
+ | FEAT_AVCC3 | FEAT_PWM_FREQ2,
+ .peci_mask = 0x07,
+ },
[it8620] = {
.name = "it8620",
.suffix = "E",
@@ -2462,6 +2472,9 @@ static int __init it87_find(int sioaddr, unsigned short *address,
case IT8623E_DEVID:
sio_data->type = it8603;
break;
+ case IT8607E_DEVID:
+ sio_data->type = it8607;
+ break;
case IT8620E_DEVID:
sio_data->type = it8620;
break;
@@ -2594,7 +2607,7 @@ static int __init it87_find(int sioaddr, unsigned short *address,
sio_data->beep_pin = superio_inb(sioaddr,
IT87_SIO_BEEP_PIN_REG) & 0x3f;
- } else if (sio_data->type == it8603) {
+ } else if (sio_data->type == it8603 || sio_data->type == it8607) {
int reg27, reg29;
superio_select(sioaddr, GPIO);
@@ -2614,8 +2627,10 @@ static int __init it87_find(int sioaddr, unsigned short *address,
if (reg29 & BIT(2))
sio_data->skip_fan |= BIT(1);
- sio_data->skip_in |= BIT(5); /* No VIN5 */
- sio_data->skip_in |= BIT(6); /* No VIN6 */
+ if (sio_data->type == it8603) {
+ sio_data->skip_in |= BIT(5); /* No VIN5 */
+ sio_data->skip_in |= BIT(6); /* No VIN6 */
+ }
sio_data->beep_pin = superio_inb(sioaddr,
IT87_SIO_BEEP_PIN_REG) & 0x3f;
--
2.20.1
From 4b38d375f8241c52bdea4b22057cf3f727ba3a76 Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Fri, 10 Mar 2017 09:06:17 -0800
Subject: [PATCH 02/61] Fix feature mask for IT8792E (IT8733E)
The chip features match those of IT8790E. Most important is the
ADC resolution, which is 12 mV, not 10.9 mV.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index ccab431..7af7eea 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -430,11 +430,10 @@ static const struct it87_devices it87_devices[] = {
[it8792] = {
.name = "it8792",
.suffix = "E",
- .features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS
- | FEAT_TEMP_OFFSET | FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI
- | FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL,
+ .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
+ | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
+ | FEAT_PWM_FREQ2,
.peci_mask = 0x07,
- .old_peci_mask = 0x02, /* Actually reports PCH */
},
[it8603] = {
.name = "it8603",
--
2.20.1
From 8915dcbee61d14bd2243ccbe8d2639004ec72416 Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Sat, 11 Mar 2017 08:39:40 -0800
Subject: [PATCH 03/61] Add 4th fan control and measurement for IT8732E
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 49 insertions(+), 12 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 7af7eea..24945fb 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -304,6 +304,8 @@ struct it87_devices {
#define FEAT_PWM_FREQ2 BIT(16) /* Separate pwm freq 2 */
#define FEAT_SIX_TEMP BIT(17) /* Up to 6 temp sensors */
#define FEAT_VIN3_5V BIT(18) /* VIN3 connected to +5V */
+#define FEAT_FOUR_FANS BIT(19) /* Supports four fans */
+#define FEAT_FOUR_PWM BIT(20) /* Supports four fan controls */
static const struct it87_devices it87_devices[] = {
[it87] = {
@@ -362,7 +364,8 @@ static const struct it87_devices it87_devices[] = {
.suffix = "F",
.features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS
| FEAT_TEMP_OFFSET | FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI
- | FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL,
+ | FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_FOUR_FANS
+ | FEAT_FOUR_PWM,
.peci_mask = 0x07,
.old_peci_mask = 0x02, /* Actually reports PCH */
},
@@ -504,6 +507,12 @@ static const struct it87_devices it87_devices[] = {
#define has_pwm_freq2(data) ((data)->features & FEAT_PWM_FREQ2)
#define has_six_temp(data) ((data)->features & FEAT_SIX_TEMP)
#define has_vin3_5v(data) ((data)->features & FEAT_VIN3_5V)
+#define has_four_fans(data) ((data)->features & (FEAT_FOUR_FANS | \
+ FEAT_FIVE_FANS | \
+ FEAT_SIX_FANS))
+#define has_four_pwm(data) ((data)->features & (FEAT_FOUR_PWM | \
+ FEAT_FIVE_PWM \
+ | FEAT_SIX_PWM))
struct it87_sio_data {
int sioaddr;
@@ -2524,8 +2533,10 @@ static int __init it87_find(int sioaddr, unsigned short *address,
else
sio_data->skip_in |= BIT(9);
- if (!has_five_pwm(config))
+ if (!has_four_pwm(config))
sio_data->skip_pwm |= BIT(3) | BIT(4) | BIT(5);
+ else if (!has_five_pwm(config))
+ sio_data->skip_pwm |= BIT(4) | BIT(5);
else if (!has_six_pwm(config))
sio_data->skip_pwm |= BIT(5);
@@ -2718,6 +2729,34 @@ static int __init it87_find(int sioaddr, unsigned short *address,
if (!(reg & BIT(0)))
sio_data->skip_in |= BIT(9);
+ sio_data->beep_pin = superio_inb(sioaddr,
+ IT87_SIO_BEEP_PIN_REG) & 0x3f;
+ } else if (sio_data->type == it8732) {
+ int reg;
+
+ superio_select(sioaddr, GPIO);
+
+ /* Check for pwm2, fan2 */
+ reg = superio_inb(sioaddr, IT87_SIO_GPIO5_REG);
+ if (reg & BIT(1))
+ sio_data->skip_pwm |= BIT(1);
+ if (reg & BIT(2))
+ sio_data->skip_fan |= BIT(1);
+
+ /* Check for pwm3, fan3, fan4 */
+ reg = superio_inb(sioaddr, IT87_SIO_GPIO3_REG);
+ if (reg & BIT(6))
+ sio_data->skip_pwm |= BIT(2);
+ if (reg & BIT(7))
+ sio_data->skip_fan |= BIT(2);
+ if (reg & BIT(5))
+ sio_data->skip_fan |= BIT(3);
+
+ /* Check if AVCC is on VIN3 */
+ reg = superio_inb(sioaddr, IT87_SIO_PINX2_REG);
+ if (reg & BIT(0))
+ sio_data->internal |= BIT(0);
+
sio_data->beep_pin = superio_inb(sioaddr,
IT87_SIO_BEEP_PIN_REG) & 0x3f;
} else {
@@ -2971,16 +3010,14 @@ static void it87_init_device(struct platform_device *pdev)
it87_check_tachometers_16bit_mode(pdev);
/* Check for additional fans */
- if (has_five_fans(data)) {
- tmp = it87_read_value(data, IT87_REG_FAN_16BIT);
-
- if (tmp & BIT(4))
- data->has_fan |= BIT(3); /* fan4 enabled */
- if (tmp & BIT(5))
- data->has_fan |= BIT(4); /* fan5 enabled */
- if (has_six_fans(data) && (tmp & BIT(2)))
- data->has_fan |= BIT(5); /* fan6 enabled */
- }
+ tmp = it87_read_value(data, IT87_REG_FAN_16BIT);
+
+ if (has_four_fans(data) && (tmp & BIT(4)))
+ data->has_fan |= BIT(3); /* fan4 enabled */
+ if (has_five_fans(data) && (tmp & BIT(5)))
+ data->has_fan |= BIT(4); /* fan5 enabled */
+ if (!has_fan16_config(data) && has_six_fans(data) && (tmp & BIT(2)))
+ data->has_fan |= BIT(5); /* fan6 enabled */
/* Fan input pins may be used for alternative functions */
data->has_fan &= ~sio_data->skip_fan;
--
2.20.1
From 85589c2f498a3df0bf76778ddd0d6d6a91ac0b0d Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Tue, 14 Mar 2017 09:33:52 -0700
Subject: [PATCH 04/61] Force chip ID only if a chip has been found
If the reported chip ID is 0xffff, there is no chip, and forcing the chip
type does not add value.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 24945fb..2f5af83 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -2424,7 +2424,12 @@ static int __init it87_find(int sioaddr, unsigned short *address,
return err;
err = -ENODEV;
- chip_type = force_id ? force_id : superio_inw(sioaddr, DEVID);
+ chip_type = superio_inw(sioaddr, DEVID);
+ if (chip_type == 0xffff)
+ goto exit;
+
+ if (force_id)
+ chip_type = force_id;
switch (chip_type) {
case IT8705F_DEVID:
--
2.20.1
From 58166ed61f7974dac5b8dd5e07dc591993c0bc1b Mon Sep 17 00:00:00 2001
From: Hannes Haberl <hannes.haberl@student.tugraz.at>
Date: Mon, 27 Aug 2018 00:34:23 +0200
Subject: [PATCH 05/61] Add multi-bank support
Some IT87 chips have more registers that can be accessed using
bank switching.
Signed-off-by: Hannes Haberl <hannes.haberl@student.tugraz.at>
---
it87.c | 43 +++++++++++++++++++++++++++++++++++++------
1 file changed, 37 insertions(+), 6 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 2f5af83..91d691f 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -212,6 +212,8 @@ static bool fix_pwm_polarity;
#define IT87_REG_ALARM2 0x02
#define IT87_REG_ALARM3 0x03
+#define IT87_REG_BANK 0x06
+
/*
* The IT8718F and IT8720F have the VID value in a different register, in
* Super-I/O configuration space.
@@ -306,6 +308,7 @@ struct it87_devices {
#define FEAT_VIN3_5V BIT(18) /* VIN3 connected to +5V */
#define FEAT_FOUR_FANS BIT(19) /* Supports four fans */
#define FEAT_FOUR_PWM BIT(20) /* Supports four fan controls */
+#define FEAT_BANK_SEL BIT(21) /* Chip has multi-bank support */
static const struct it87_devices it87_devices[] = {
[it87] = {
@@ -513,6 +516,7 @@ static const struct it87_devices it87_devices[] = {
#define has_four_pwm(data) ((data)->features & (FEAT_FOUR_PWM | \
FEAT_FIVE_PWM \
| FEAT_SIX_PWM))
+#define has_bank_sel(data) ((data)->features & FEAT_BANK_SEL)
struct it87_sio_data {
int sioaddr;
@@ -540,6 +544,7 @@ struct it87_data {
int sioaddr;
enum chips type;
u32 features;
+ u8 bank;
u8 peci_mask;
u8 old_peci_mask;
@@ -689,15 +694,39 @@ static const unsigned int pwm_freq[8] = {
750000,
};
+static int _it87_read_value(struct it87_data *data, u8 reg)
+{
+ outb_p(reg, data->addr + IT87_ADDR_REG_OFFSET);
+ return inb_p(data->addr + IT87_DATA_REG_OFFSET);
+}
+
+static void _it87_write_value(struct it87_data *data, u8 reg, u8 value)
+{
+ outb_p(reg, data->addr + IT87_ADDR_REG_OFFSET);
+ outb_p(value, data->addr + IT87_DATA_REG_OFFSET);
+}
+
+static void it87_set_bank(struct it87_data *data, u8 bank)
+{
+ if (has_bank_sel(data) && bank != data->bank) {
+ u8 breg = _it87_read_value(data, IT87_REG_BANK);
+
+ breg &= 0x1f;
+ breg |= (bank << 5);
+ data->bank = bank;
+ _it87_write_value(data, IT87_REG_BANK, breg);
+ }
+}
+
/*
* Must be called with data->update_lock held, except during initialization.
* We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks,
* would slow down the IT87 access and should not be necessary.
*/
-static int it87_read_value(struct it87_data *data, u8 reg)
+static int it87_read_value(struct it87_data *data, u16 reg)
{
- outb_p(reg, data->addr + IT87_ADDR_REG_OFFSET);
- return inb_p(data->addr + IT87_DATA_REG_OFFSET);
+ it87_set_bank(data, reg >> 8);
+ return _it87_read_value(data, reg & 0xff);
}
/*
@@ -705,10 +734,10 @@ static int it87_read_value(struct it87_data *data, u8 reg)
* We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks,
* would slow down the IT87 access and should not be necessary.
*/
-static void it87_write_value(struct it87_data *data, u8 reg, u8 value)
+static void it87_write_value(struct it87_data *data, u16 reg, u8 value)
{
- outb_p(reg, data->addr + IT87_ADDR_REG_OFFSET);
- outb_p(value, data->addr + IT87_DATA_REG_OFFSET);
+ it87_set_bank(data, reg >> 8);
+ _it87_write_value(data, reg & 0xff, value);
}
static void it87_update_pwm_ctrl(struct it87_data *data, int nr)
@@ -3124,6 +3153,8 @@ static int it87_probe(struct platform_device *pdev)
data->features = it87_devices[sio_data->type].features;
data->peci_mask = it87_devices[sio_data->type].peci_mask;
data->old_peci_mask = it87_devices[sio_data->type].old_peci_mask;
+ data->bank = 0xff;
+
/*
* IT8705F Datasheet 0.4.1, 3h == Version G.
* IT8712F Datasheet 0.9.1, section 8.3.5 indicates 8h == Version J.
--
2.20.1
From 09168c88904df2a22c480032ac82bd11eb098d75 Mon Sep 17 00:00:00 2001
From: Hannes Haberl <hannes.haberl@student.tugraz.at>
Date: Mon, 27 Aug 2018 00:48:25 +0200
Subject: [PATCH 06/61] Add preliminary support for IT8686E
The IT8686 is similar to the IT8620 and IT8628 but offers
temperature limits for every temperature channel.
Signed-off-by: Hannes Haberl <hannes.haberl@student.tugraz.at>
---
it87.c | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 91d691f..a443e4d 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -16,6 +16,7 @@
* IT8622E Super I/O chip w/LPC interface
* IT8623E Super I/O chip w/LPC interface
* IT8628E Super I/O chip w/LPC interface
+ * IT8686E Super I/O chip w/LPC interface
* IT8705F Super I/O chip w/LPC interface
* IT8712F Super I/O chip w/LPC interface
* IT8716F Super I/O chip w/LPC interface
@@ -73,7 +74,7 @@
enum chips { it87, it8712, it8716, it8718, it8720, it8721, it8728, it8732,
it8771, it8772, it8781, it8782, it8783, it8786, it8790,
- it8792, it8603, it8607, it8620, it8622, it8628 };
+ it8792, it8603, it8607, it8620, it8622, it8628, it8686 };
static unsigned short force_id;
module_param(force_id, ushort, 0);
@@ -168,6 +169,7 @@ static inline void superio_exit(int ioreg)
#define IT8622E_DEVID 0x8622
#define IT8623E_DEVID 0x8623
#define IT8628E_DEVID 0x8628
+#define IT8686E_DEVID 0x8686
#define IT87_ACT_REG 0x30
#define IT87_BASE_REG 0x60
@@ -484,6 +486,15 @@ static const struct it87_devices it87_devices[] = {
| FEAT_SIX_TEMP | FEAT_VIN3_5V,
.peci_mask = 0x07,
},
+ [it8686] = {
+ .name = "it8686",
+ .suffix = "E",
+ .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
+ | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_SIX_FANS
+ | FEAT_IN7_INTERNAL | FEAT_SIX_PWM | FEAT_PWM_FREQ2
+ | FEAT_SIX_TEMP | FEAT_BANK_SEL,
+ .peci_mask = 0x07,
+ },
};
#define has_16bit_fans(data) ((data)->features & FEAT_16BIT_FANS)
@@ -2526,6 +2537,9 @@ static int __init it87_find(int sioaddr, unsigned short *address,
case IT8628E_DEVID:
sio_data->type = it8628;
break;
+ case IT8686E_DEVID:
+ sio_data->type = it8686;
+ break;
case 0xffff: /* No device at all */
goto exit;
default:
@@ -2678,7 +2692,8 @@ static int __init it87_find(int sioaddr, unsigned short *address,
sio_data->beep_pin = superio_inb(sioaddr,
IT87_SIO_BEEP_PIN_REG) & 0x3f;
- } else if (sio_data->type == it8620 || sio_data->type == it8628) {
+ } else if (sio_data->type == it8620 || sio_data->type == it8628 ||
+ sio_data->type == it8686) {
int reg;
superio_select(sioaddr, GPIO);
--
2.20.1
From 66d4ab6ecc7ba68ff0ed2de907a6f45c8fffb011 Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Mon, 20 Mar 2017 17:43:03 -0700
Subject: [PATCH 07/61] Separate internal scaling from 12mV ADC
Some chips have internal voltage scaling but 10.9mV ADC,
so we can no longer associate the 12mV ADC with internal scaling
but need a different flag to distinguish scaling support.
Also fix ADC resolution for IT8790E and IT8792E.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 36 +++++++++++++++++++-----------------
1 file changed, 19 insertions(+), 17 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index a443e4d..d645b7c 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -311,6 +311,7 @@ struct it87_devices {
#define FEAT_FOUR_FANS BIT(19) /* Supports four fans */
#define FEAT_FOUR_PWM BIT(20) /* Supports four fan controls */
#define FEAT_BANK_SEL BIT(21) /* Chip has multi-bank support */
+#define FEAT_SCALING BIT(22) /* Internal voltage scaling */
static const struct it87_devices it87_devices[] = {
[it87] = {
@@ -352,7 +353,7 @@ static const struct it87_devices it87_devices[] = {
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_OFFSET | FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI
| FEAT_FAN16_CONFIG | FEAT_FIVE_FANS | FEAT_IN7_INTERNAL
- | FEAT_PWM_FREQ2,
+ | FEAT_PWM_FREQ2 | FEAT_SCALING,
.peci_mask = 0x05,
.old_peci_mask = 0x02, /* Actually reports PCH */
},
@@ -361,7 +362,7 @@ static const struct it87_devices it87_devices[] = {
.suffix = "F",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_FIVE_FANS
- | FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2,
+ | FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2 | FEAT_SCALING,
.peci_mask = 0x07,
},
[it8732] = {
@@ -379,7 +380,7 @@ static const struct it87_devices it87_devices[] = {
.suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
- | FEAT_PWM_FREQ2,
+ | FEAT_PWM_FREQ2 | FEAT_SCALING,
/* PECI: guesswork */
/* 12mV ADC (OHM) */
/* 16 bit fans (OHM) */
@@ -391,7 +392,7 @@ static const struct it87_devices it87_devices[] = {
.suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
- | FEAT_PWM_FREQ2,
+ | FEAT_PWM_FREQ2 | FEAT_SCALING,
/* PECI (coreboot) */
/* 12mV ADC (HWSensors4, OHM) */
/* 16 bit fans (HWSensors4, OHM) */
@@ -430,17 +431,17 @@ static const struct it87_devices it87_devices[] = {
[it8790] = {
.name = "it8790",
.suffix = "E",
- .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
- | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
- | FEAT_PWM_FREQ2,
+ .features = FEAT_NEWER_AUTOPWM | FEAT_10_9MV_ADC | FEAT_SCALING
+ | FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI
+ | FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2,
.peci_mask = 0x07,
},
[it8792] = {
.name = "it8792",
.suffix = "E",
- .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
- | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
- | FEAT_PWM_FREQ2,
+ .features = FEAT_NEWER_AUTOPWM | FEAT_10_9MV_ADC | FEAT_SCALING
+ | FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI
+ | FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2,
.peci_mask = 0x07,
},
[it8603] = {
@@ -448,7 +449,7 @@ static const struct it87_devices it87_devices[] = {
.suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
- | FEAT_AVCC3 | FEAT_PWM_FREQ2,
+ | FEAT_AVCC3 | FEAT_PWM_FREQ2 | FEAT_SCALING,
.peci_mask = 0x07,
},
[it8607] = {
@@ -456,7 +457,7 @@ static const struct it87_devices it87_devices[] = {
.suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
- | FEAT_AVCC3 | FEAT_PWM_FREQ2,
+ | FEAT_AVCC3 | FEAT_PWM_FREQ2 | FEAT_SCALING,
.peci_mask = 0x07,
},
[it8620] = {
@@ -465,7 +466,7 @@ static const struct it87_devices it87_devices[] = {
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_SIX_FANS
| FEAT_IN7_INTERNAL | FEAT_SIX_PWM | FEAT_PWM_FREQ2
- | FEAT_SIX_TEMP | FEAT_VIN3_5V,
+ | FEAT_SIX_TEMP | FEAT_VIN3_5V | FEAT_SCALING,
.peci_mask = 0x07,
},
[it8622] = {
@@ -474,7 +475,7 @@ static const struct it87_devices it87_devices[] = {
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_FIVE_FANS
| FEAT_FIVE_PWM | FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2
- | FEAT_AVCC3 | FEAT_VIN3_5V,
+ | FEAT_AVCC3 | FEAT_VIN3_5V | FEAT_SCALING,
.peci_mask = 0x07,
},
[it8628] = {
@@ -483,7 +484,7 @@ static const struct it87_devices it87_devices[] = {
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_SIX_FANS
| FEAT_IN7_INTERNAL | FEAT_SIX_PWM | FEAT_PWM_FREQ2
- | FEAT_SIX_TEMP | FEAT_VIN3_5V,
+ | FEAT_SIX_TEMP | FEAT_VIN3_5V | FEAT_SCALING,
.peci_mask = 0x07,
},
[it8686] = {
@@ -492,7 +493,7 @@ static const struct it87_devices it87_devices[] = {
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_SIX_FANS
| FEAT_IN7_INTERNAL | FEAT_SIX_PWM | FEAT_PWM_FREQ2
- | FEAT_SIX_TEMP | FEAT_BANK_SEL,
+ | FEAT_SIX_TEMP | FEAT_BANK_SEL | FEAT_SCALING,
.peci_mask = 0x07,
},
};
@@ -528,6 +529,7 @@ static const struct it87_devices it87_devices[] = {
FEAT_FIVE_PWM \
| FEAT_SIX_PWM))
#define has_bank_sel(data) ((data)->features & FEAT_BANK_SEL)
+#define has_scaling(data) ((data)->features & FEAT_SCALING)
struct it87_sio_data {
int sioaddr;
@@ -3209,7 +3211,7 @@ static int it87_probe(struct platform_device *pdev)
"Detected broken BIOS defaults, disabling PWM interface\n");
/* Starting with IT8721F, we handle scaling of internal voltages */
- if (has_12mv_adc(data)) {
+ if (has_scaling(data)) {
if (sio_data->internal & BIT(0))
data->in_scaled |= BIT(3); /* in3 is AVCC */
if (sio_data->internal & BIT(1))
--
2.20.1
From 79459ac2cd4b6965f925fc154bc5a24cca650933 Mon Sep 17 00:00:00 2001
From: Drew <linux@mcraes.org>
Date: Thu, 16 Mar 2017 22:31:54 -0400
Subject: [PATCH 08/61] Added preliminary support for IT8665E
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 88 insertions(+), 10 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index d645b7c..7da047c 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -16,6 +16,7 @@
* IT8622E Super I/O chip w/LPC interface
* IT8623E Super I/O chip w/LPC interface
* IT8628E Super I/O chip w/LPC interface
+ * IT8665E Super I/O chip w/LPC interface
* IT8686E Super I/O chip w/LPC interface
* IT8705F Super I/O chip w/LPC interface
* IT8712F Super I/O chip w/LPC interface
@@ -74,7 +75,8 @@
enum chips { it87, it8712, it8716, it8718, it8720, it8721, it8728, it8732,
it8771, it8772, it8781, it8782, it8783, it8786, it8790,
- it8792, it8603, it8607, it8620, it8622, it8628, it8686 };
+ it8792, it8603, it8607, it8620, it8622, it8628, it8665,
+ it8686 };
static unsigned short force_id;
module_param(force_id, ushort, 0);
@@ -169,6 +171,7 @@ static inline void superio_exit(int ioreg)
#define IT8622E_DEVID 0x8622
#define IT8623E_DEVID 0x8623
#define IT8628E_DEVID 0x8628
+#define IT8665E_DEVID 0x8665
#define IT8686E_DEVID 0x8686
#define IT87_ACT_REG 0x30
#define IT87_BASE_REG 0x60
@@ -179,8 +182,10 @@ static inline void superio_exit(int ioreg)
#define IT87_SIO_GPIO3_REG 0x27
#define IT87_SIO_GPIO4_REG 0x28
#define IT87_SIO_GPIO5_REG 0x29
+#define IT87_SIO_GPIO9_REG 0xd3
#define IT87_SIO_PINX1_REG 0x2a /* Pin selection */
#define IT87_SIO_PINX2_REG 0x2c /* Pin selection */
+#define IT87_SIO_PINX4_REG 0x2d /* Pin selection */
#define IT87_SIO_SPI_REG 0xef /* SPI function pin select */
#define IT87_SIO_VID_REG 0xfc /* VID value */
#define IT87_SIO_BEEP_PIN_REG 0xf6 /* Beep pin mapping */
@@ -487,6 +492,15 @@ static const struct it87_devices it87_devices[] = {
| FEAT_SIX_TEMP | FEAT_VIN3_5V | FEAT_SCALING,
.peci_mask = 0x07,
},
+ [it8665] = {
+ .name = "it8665",
+ .suffix = "E",
+ .features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS
+ | FEAT_TEMP_OFFSET | FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI
+ | FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_SIX_FANS
+ | FEAT_SIX_PWM | FEAT_BANK_SEL,
+ .peci_mask = 0x07,
+ },
[it8686] = {
.name = "it8686",
.suffix = "E",
@@ -2539,6 +2553,9 @@ static int __init it87_find(int sioaddr, unsigned short *address,
case IT8628E_DEVID:
sio_data->type = it8628;
break;
+ case IT8665E_DEVID:
+ sio_data->type = it8665;
+ break;
case IT8686E_DEVID:
sio_data->type = it8686;
break;
@@ -2808,6 +2825,48 @@ static int __init it87_find(int sioaddr, unsigned short *address,
if (reg & BIT(0))
sio_data->internal |= BIT(0);
+ sio_data->beep_pin = superio_inb(sioaddr,
+ IT87_SIO_BEEP_PIN_REG) & 0x3f;
+ } else if (sio_data->type == it8665) {
+ int reg;
+
+ superio_select(sioaddr, GPIO);
+
+ /* Check for pwm2 */
+ reg = superio_inb(sioaddr, IT87_SIO_GPIO5_REG);
+ if (reg & BIT(1))
+ sio_data->skip_pwm |= BIT(1);
+
+ /* Check for fan2 */
+ reg = superio_inb(sioaddr, IT87_SIO_PINX4_REG);
+ if (reg & BIT(4))
+ sio_data->skip_fan |= BIT(1);
+
+ /* Check for pwm3, fan3 */
+ reg = superio_inb(sioaddr, IT87_SIO_GPIO3_REG);
+ if (reg & BIT(6))
+ sio_data->skip_pwm |= BIT(2);
+ if (reg & BIT(7))
+ sio_data->skip_fan |= BIT(2);
+
+ /* Check for pwm5, fan5 */
+ reg = superio_inb(sioaddr, IT87_SIO_GPIO2_REG);
+ if (reg & BIT(5))
+ sio_data->skip_pwm |= BIT(4);
+ if (!(reg & BIT(4)))
+ sio_data->skip_fan |= BIT(4);
+
+ /* Check for pwm4, fan4, pwm6, fan6 */
+ reg = superio_inb(sioaddr, IT87_SIO_GPIO9_REG);
+ if (reg & BIT(2))
+ sio_data->skip_pwm |= BIT(3);
+ if (reg & BIT(3))
+ sio_data->skip_fan |= BIT(3);
+ if (reg & BIT(0))
+ sio_data->skip_pwm |= BIT(5);
+ if (reg & BIT(1))
+ sio_data->skip_fan |= BIT(5);
+
sio_data->beep_pin = superio_inb(sioaddr,
IT87_SIO_BEEP_PIN_REG) & 0x3f;
} else {
@@ -3067,20 +3126,39 @@ static void it87_init_device(struct platform_device *pdev)
data->has_fan |= BIT(3); /* fan4 enabled */
if (has_five_fans(data) && (tmp & BIT(5)))
data->has_fan |= BIT(4); /* fan5 enabled */
- if (!has_fan16_config(data) && has_six_fans(data) && (tmp & BIT(2)))
- data->has_fan |= BIT(5); /* fan6 enabled */
+ if (has_six_fans(data)) {
+ switch (data->type) {
+ case it8620:
+ case it8628:
+ case it8686:
+ if (tmp & BIT(2))
+ data->has_fan |= BIT(5); /* fan6 enabled */
+ break;
+ case it8665:
+ tmp = it87_read_value(data, IT87_REG_FAN_DIV);
+ if (tmp & BIT(3))
+ data->has_fan |= BIT(5); /* fan6 enabled */
+ break;
+ default:
+ break;
+ }
+ }
/* Fan input pins may be used for alternative functions */
data->has_fan &= ~sio_data->skip_fan;
- /* Check if pwm5, pwm6 are enabled */
+ /* Check if pwm6 is enabled */
if (has_six_pwm(data)) {
- /* The following code may be IT8620E specific */
- tmp = it87_read_value(data, IT87_REG_FAN_DIV);
- if ((tmp & 0xc0) == 0xc0)
- sio_data->skip_pwm |= BIT(4);
- if (!(tmp & BIT(3)))
- sio_data->skip_pwm |= BIT(5);
+ switch (data->type) {
+ case it8620:
+ case it8686:
+ tmp = it87_read_value(data, IT87_REG_FAN_DIV);
+ if (!(tmp & BIT(3)))
+ sio_data->skip_pwm |= BIT(5);
+ break;
+ default:
+ break;
+ }
}
it87_start_monitoring(data);
--
2.20.1
From 51ffa2a8c19e419cd2099161ae93a493a4569a98 Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Sun, 19 Mar 2017 00:57:24 -0700
Subject: [PATCH 09/61] Add support for chip specific register sets
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 85 +++++++++++++++++++++++++++++++++++++++++++---------------
1 file changed, 64 insertions(+), 21 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 7da047c..da093be 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -241,16 +241,27 @@ static bool fix_pwm_polarity;
* - up to 6 fan (1 to 6)
*/
-static const u8 IT87_REG_FAN[] = { 0x0d, 0x0e, 0x0f, 0x80, 0x82, 0x4c };
-static const u8 IT87_REG_FAN_MIN[] = { 0x10, 0x11, 0x12, 0x84, 0x86, 0x4e };
-static const u8 IT87_REG_FANX[] = { 0x18, 0x19, 0x1a, 0x81, 0x83, 0x4d };
-static const u8 IT87_REG_FANX_MIN[] = { 0x1b, 0x1c, 0x1d, 0x85, 0x87, 0x4f };
+static const u8 IT87_REG_FAN[] = { 0x0d, 0x0e, 0x0f, 0x80, 0x82, 0x4c };
+static const u8 IT87_REG_FAN_MIN[] = { 0x10, 0x11, 0x12, 0x84, 0x86, 0x4e };
+static const u8 IT87_REG_FANX[] = { 0x18, 0x19, 0x1a, 0x81, 0x83, 0x4d };
+static const u8 IT87_REG_FANX_MIN[] = { 0x1b, 0x1c, 0x1d, 0x85, 0x87, 0x4f };
+
+static const u8 IT87_REG_FAN_8665[] = { 0x0d, 0x0e, 0x0f, 0x80, 0x82, 0x93 };
+static const u8 IT87_REG_FAN_MIN_8665[] =
+ { 0x10, 0x11, 0x12, 0x84, 0x86, 0xb2 };
+static const u8 IT87_REG_FANX_8665[] = { 0x18, 0x19, 0x1a, 0x81, 0x83, 0x94 };
+static const u8 IT87_REG_FANX_MIN_8665[] =
+ { 0x1b, 0x1c, 0x1d, 0x85, 0x87, 0xb3 };
+
static const u8 IT87_REG_TEMP_OFFSET[] = { 0x56, 0x57, 0x59 };
#define IT87_REG_FAN_MAIN_CTRL 0x13
#define IT87_REG_FAN_CTL 0x14
-static const u8 IT87_REG_PWM[] = { 0x15, 0x16, 0x17, 0x7f, 0xa7, 0xaf };
-static const u8 IT87_REG_PWM_DUTY[] = { 0x63, 0x6b, 0x73, 0x7b, 0xa3, 0xab };
+
+static const u8 IT87_REG_PWM[] = { 0x15, 0x16, 0x17, 0x7f, 0xa7, 0xaf };
+static const u8 IT87_REG_PWM_8665[] = { 0x15, 0x16, 0x17, 0x1e, 0x1f, 0x92 };
+
+static const u8 IT87_REG_PWM_DUTY[] = { 0x63, 0x6b, 0x73, 0x7b, 0xa3, 0xab };
static const u8 IT87_REG_VIN[] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
0x27, 0x28, 0x2f, 0x2c, 0x2d, 0x2e };
@@ -575,6 +586,13 @@ struct it87_data {
u8 peci_mask;
u8 old_peci_mask;
+ const u8 *REG_FAN;
+ const u8 *REG_FANX;
+ const u8 *REG_FAN_MIN;
+ const u8 *REG_FANX_MIN;
+
+ const u8 *REG_PWM;
+
unsigned short addr;
const char *name;
struct mutex update_lock;
@@ -769,7 +787,7 @@ static void it87_write_value(struct it87_data *data, u16 reg, u8 value)
static void it87_update_pwm_ctrl(struct it87_data *data, int nr)
{
- data->pwm_ctrl[nr] = it87_read_value(data, IT87_REG_PWM[nr]);
+ data->pwm_ctrl[nr] = it87_read_value(data, data->REG_PWM[nr]);
if (has_newer_autopwm(data)) {
data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03;
data->pwm_duty[nr] = it87_read_value(data,
@@ -857,15 +875,15 @@ static struct it87_data *it87_update_device(struct device *dev)
continue;
data->fan[i][1] =
- it87_read_value(data, IT87_REG_FAN_MIN[i]);
+ it87_read_value(data, data->REG_FAN_MIN[i]);
data->fan[i][0] = it87_read_value(data,
- IT87_REG_FAN[i]);
+ data->REG_FAN[i]);
/* Add high byte if in 16-bit mode */
if (has_16bit_fans(data)) {
data->fan[i][0] |= it87_read_value(data,
- IT87_REG_FANX[i]) << 8;
+ data->REG_FANX[i]) << 8;
data->fan[i][1] |= it87_read_value(data,
- IT87_REG_FANX_MIN[i]) << 8;
+ data->REG_FANX_MIN[i]) << 8;
}
}
for (i = 0; i < NUM_TEMP; i++) {
@@ -1273,9 +1291,9 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *attr,
if (has_16bit_fans(data)) {
data->fan[nr][index] = FAN16_TO_REG(val);
- it87_write_value(data, IT87_REG_FAN_MIN[nr],
+ it87_write_value(data, data->REG_FAN_MIN[nr],
data->fan[nr][index] & 0xff);
- it87_write_value(data, IT87_REG_FANX_MIN[nr],
+ it87_write_value(data, data->REG_FANX_MIN[nr],
data->fan[nr][index] >> 8);
} else {
reg = it87_read_value(data, IT87_REG_FAN_DIV);
@@ -1292,7 +1310,7 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *attr,
}
data->fan[nr][index] =
FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
- it87_write_value(data, IT87_REG_FAN_MIN[nr],
+ it87_write_value(data, data->REG_FAN_MIN[nr],
data->fan[nr][index]);
}
@@ -1339,7 +1357,7 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
/* Restore fan min limit */
data->fan[nr][1] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
- it87_write_value(data, IT87_REG_FAN_MIN[nr], data->fan[nr][1]);
+ it87_write_value(data, data->REG_FAN_MIN[nr], data->fan[nr][1]);
mutex_unlock(&data->update_lock);
return count;
@@ -1419,7 +1437,7 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr,
ctrl = data->pwm_duty[nr];
}
data->pwm_ctrl[nr] = ctrl;
- it87_write_value(data, IT87_REG_PWM[nr], ctrl);
+ it87_write_value(data, data->REG_PWM[nr], ctrl);
}
} else {
u8 ctrl;
@@ -1433,7 +1451,7 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr,
ctrl = (val == 1 ? data->pwm_duty[nr] : 0x80);
}
data->pwm_ctrl[nr] = ctrl;
- it87_write_value(data, IT87_REG_PWM[nr], ctrl);
+ it87_write_value(data, data->REG_PWM[nr], ctrl);
if (data->type != it8603 && nr < 3) {
/* set SmartGuardian mode */
@@ -1480,7 +1498,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
*/
if (!(data->pwm_ctrl[nr] & 0x80)) {
data->pwm_ctrl[nr] = data->pwm_duty[nr];
- it87_write_value(data, IT87_REG_PWM[nr],
+ it87_write_value(data, data->REG_PWM[nr],
data->pwm_ctrl[nr]);
}
}
@@ -1581,7 +1599,7 @@ static ssize_t set_pwm_temp_map(struct device *dev,
if (data->pwm_ctrl[nr] & 0x80) {
data->pwm_ctrl[nr] = (data->pwm_ctrl[nr] & 0xfc) |
data->pwm_temp_map[nr];
- it87_write_value(data, IT87_REG_PWM[nr], data->pwm_ctrl[nr]);
+ it87_write_value(data, data->REG_PWM[nr], data->pwm_ctrl[nr]);
}
mutex_unlock(&data->update_lock);
return count;
@@ -3082,6 +3100,31 @@ static void it87_init_device(struct platform_device *pdev)
struct it87_data *data = platform_get_drvdata(pdev);
int tmp, i;
+ /* Initialize chip specific register pointers */
+ switch (data->type) {
+ case it8665:
+ data->REG_FAN = IT87_REG_FAN_8665;
+ data->REG_FANX = IT87_REG_FANX_8665;
+ data->REG_FAN_MIN = IT87_REG_FAN_MIN_8665;
+ data->REG_FANX_MIN = IT87_REG_FANX_MIN_8665;
+ data->REG_PWM = IT87_REG_PWM_8665;
+ break;
+ case it8622:
+ data->REG_FAN = IT87_REG_FAN;
+ data->REG_FANX = IT87_REG_FANX;
+ data->REG_FAN_MIN = IT87_REG_FAN_MIN;
+ data->REG_FANX_MIN = IT87_REG_FANX_MIN;
+ data->REG_PWM = IT87_REG_PWM_8665;
+ break;
+ default:
+ data->REG_FAN = IT87_REG_FAN;
+ data->REG_FANX = IT87_REG_FANX;
+ data->REG_FAN_MIN = IT87_REG_FAN_MIN;
+ data->REG_FANX_MIN = IT87_REG_FANX_MIN;
+ data->REG_PWM = IT87_REG_PWM;
+ break;
+ }
+
/*
* For each PWM channel:
* - If it is in automatic mode, setting to manual mode should set
@@ -3187,7 +3230,7 @@ static int it87_check_pwm(struct device *dev)
for (i = 0; i < ARRAY_SIZE(pwm); i++)
pwm[i] = it87_read_value(data,
- IT87_REG_PWM[i]);
+ data->REG_PWM[i]);
/*
* If any fan is in automatic pwm mode, the polarity
@@ -3202,7 +3245,7 @@ static int it87_check_pwm(struct device *dev)
tmp | 0x87);
for (i = 0; i < 3; i++)
it87_write_value(data,
- IT87_REG_PWM[i],
+ data->REG_PWM[i],
0x7f & ~pwm[i]);
return 1;
}
--
2.20.1
From 763dca5d5b2bd337f03e6bbf7f4c4be7b8e6a642 Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Wed, 22 Mar 2017 00:54:35 -0700
Subject: [PATCH 10/61] Preliminary support for IT8655E
Assume it is similar to IT8665E with three instead of six fans.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 42 ++++++++++++++++++++++++++++++++++++++++--
1 file changed, 40 insertions(+), 2 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index da093be..c6d560c 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -16,6 +16,7 @@
* IT8622E Super I/O chip w/LPC interface
* IT8623E Super I/O chip w/LPC interface
* IT8628E Super I/O chip w/LPC interface
+ * IT8655E Super I/O chip w/LPC interface
* IT8665E Super I/O chip w/LPC interface
* IT8686E Super I/O chip w/LPC interface
* IT8705F Super I/O chip w/LPC interface
@@ -75,7 +76,7 @@
enum chips { it87, it8712, it8716, it8718, it8720, it8721, it8728, it8732,
it8771, it8772, it8781, it8782, it8783, it8786, it8790,
- it8792, it8603, it8607, it8620, it8622, it8628, it8665,
+ it8792, it8603, it8607, it8620, it8622, it8628, it8655, it8665,
it8686 };
static unsigned short force_id;
@@ -171,6 +172,7 @@ static inline void superio_exit(int ioreg)
#define IT8622E_DEVID 0x8622
#define IT8623E_DEVID 0x8623
#define IT8628E_DEVID 0x8628
+#define IT8655E_DEVID 0x8655
#define IT8665E_DEVID 0x8665
#define IT8686E_DEVID 0x8686
#define IT87_ACT_REG 0x30
@@ -503,11 +505,19 @@ static const struct it87_devices it87_devices[] = {
| FEAT_SIX_TEMP | FEAT_VIN3_5V | FEAT_SCALING,
.peci_mask = 0x07,
},
+ [it8655] = {
+ .name = "it8655",
+ .suffix = "E",
+ .features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS
+ | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI
+ | FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_BANK_SEL,
+ .peci_mask = 0x07,
+ },
[it8665] = {
.name = "it8665",
.suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS
- | FEAT_TEMP_OFFSET | FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI
+ | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI
| FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_SIX_FANS
| FEAT_SIX_PWM | FEAT_BANK_SEL,
.peci_mask = 0x07,
@@ -2571,6 +2581,9 @@ static int __init it87_find(int sioaddr, unsigned short *address,
case IT8628E_DEVID:
sio_data->type = it8628;
break;
+ case IT8655E_DEVID:
+ sio_data->type = it8655;
+ break;
case IT8665E_DEVID:
sio_data->type = it8665;
break;
@@ -2843,6 +2856,30 @@ static int __init it87_find(int sioaddr, unsigned short *address,
if (reg & BIT(0))
sio_data->internal |= BIT(0);
+ sio_data->beep_pin = superio_inb(sioaddr,
+ IT87_SIO_BEEP_PIN_REG) & 0x3f;
+ } else if (sio_data->type == it8655) {
+ int reg;
+
+ superio_select(sioaddr, GPIO);
+
+ /* Check for pwm2 */
+ reg = superio_inb(sioaddr, IT87_SIO_GPIO5_REG);
+ if (reg & BIT(1))
+ sio_data->skip_pwm |= BIT(1);
+
+ /* Check for fan2 */
+ reg = superio_inb(sioaddr, IT87_SIO_PINX4_REG);
+ if (reg & BIT(4))
+ sio_data->skip_fan |= BIT(1);
+
+ /* Check for pwm3, fan3 */
+ reg = superio_inb(sioaddr, IT87_SIO_GPIO3_REG);
+ if (reg & BIT(6))
+ sio_data->skip_pwm |= BIT(2);
+ if (reg & BIT(7))
+ sio_data->skip_fan |= BIT(2);
+
sio_data->beep_pin = superio_inb(sioaddr,
IT87_SIO_BEEP_PIN_REG) & 0x3f;
} else if (sio_data->type == it8665) {
@@ -3102,6 +3139,7 @@ static void it87_init_device(struct platform_device *pdev)
/* Initialize chip specific register pointers */
switch (data->type) {
+ case it8655:
case it8665:
data->REG_FAN = IT87_REG_FAN_8665;
data->REG_FANX = IT87_REG_FANX_8665;
--
2.20.1
From d7b376bbd16309819dafe9b48dde0de9b2ee594a Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Sat, 25 Mar 2017 07:05:41 -0700
Subject: [PATCH 11/61] Improve AVCC3 support
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 26 +++++++++++++++-----------
1 file changed, 15 insertions(+), 11 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index c6d560c..3a94dd2 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -502,14 +502,14 @@ static const struct it87_devices it87_devices[] = {
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_SIX_FANS
| FEAT_IN7_INTERNAL | FEAT_SIX_PWM | FEAT_PWM_FREQ2
- | FEAT_SIX_TEMP | FEAT_VIN3_5V | FEAT_SCALING,
+ | FEAT_SIX_TEMP | FEAT_VIN3_5V | FEAT_SCALING | FEAT_AVCC3,
.peci_mask = 0x07,
},
[it8655] = {
.name = "it8655",
.suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS
- | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI
+ | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_AVCC3
| FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_BANK_SEL,
.peci_mask = 0x07,
},
@@ -517,7 +517,7 @@ static const struct it87_devices it87_devices[] = {
.name = "it8665",
.suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS
- | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI
+ | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_AVCC3
| FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_SIX_FANS
| FEAT_SIX_PWM | FEAT_BANK_SEL,
.peci_mask = 0x07,
@@ -528,7 +528,7 @@ static const struct it87_devices it87_devices[] = {
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_SIX_FANS
| FEAT_IN7_INTERNAL | FEAT_SIX_PWM | FEAT_PWM_FREQ2
- | FEAT_SIX_TEMP | FEAT_BANK_SEL | FEAT_SCALING,
+ | FEAT_SIX_TEMP | FEAT_BANK_SEL | FEAT_SCALING | FEAT_AVCC3,
.peci_mask = 0x07,
},
};
@@ -2161,10 +2161,10 @@ static struct attribute *it87_attributes_in[] = {
&sensor_dev_attr_in7_beep.dev_attr.attr, /* 39 */
&sensor_dev_attr_in8_input.dev_attr.attr, /* 40 */
- &sensor_dev_attr_in9_input.dev_attr.attr,
- &sensor_dev_attr_in10_input.dev_attr.attr,
- &sensor_dev_attr_in11_input.dev_attr.attr,
- &sensor_dev_attr_in12_input.dev_attr.attr,
+ &sensor_dev_attr_in9_input.dev_attr.attr, /* 41 */
+ &sensor_dev_attr_in10_input.dev_attr.attr, /* 42 */
+ &sensor_dev_attr_in11_input.dev_attr.attr, /* 43 */
+ &sensor_dev_attr_in12_input.dev_attr.attr, /* 44 */
NULL
};
@@ -2786,10 +2786,14 @@ static int __init it87_find(int sioaddr, unsigned short *address,
/* Check if AVCC is on VIN3 */
reg = superio_inb(sioaddr, IT87_SIO_PINX2_REG);
- if (reg & BIT(0))
- sio_data->internal |= BIT(0);
- else
+ if (reg & BIT(0)) {
+ /* For it8686, the bit just enables AVCC3 */
+ if (sio_data->type != it8686)
+ sio_data->internal |= BIT(0);
+ } else {
+ sio_data->internal &= ~BIT(3);
sio_data->skip_in |= BIT(9);
+ }
sio_data->beep_pin = superio_inb(sioaddr,
IT87_SIO_BEEP_PIN_REG) & 0x3f;
--
2.20.1
From 76607759b05e6d47cc483faf6f69776182f5d5e7 Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Tue, 28 Mar 2017 06:26:19 -0700
Subject: [PATCH 12/61] Add feature flag FEAT_FANCTL_ONOFF
Several recent chips don't support configuration bits to turn fan control
off entirely for the first three fans. Handle all of them with a
configuration flag.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 58 +++++++++++++++++++++++++++++++++++-----------------------
1 file changed, 35 insertions(+), 23 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 3a94dd2..fa2ed33 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -330,31 +330,34 @@ struct it87_devices {
#define FEAT_FOUR_PWM BIT(20) /* Supports four fan controls */
#define FEAT_BANK_SEL BIT(21) /* Chip has multi-bank support */
#define FEAT_SCALING BIT(22) /* Internal voltage scaling */
+#define FEAT_FANCTL_ONOFF BIT(23) /* chip has FAN_CTL ON/OFF */
static const struct it87_devices it87_devices[] = {
[it87] = {
.name = "it87",
.suffix = "F",
- .features = FEAT_OLD_AUTOPWM, /* may need to overwrite */
+ .features = FEAT_OLD_AUTOPWM | FEAT_FANCTL_ONOFF,
+ /* may need to overwrite */
},
[it8712] = {
.name = "it8712",
.suffix = "F",
- .features = FEAT_OLD_AUTOPWM | FEAT_VID,
+ .features = FEAT_OLD_AUTOPWM | FEAT_VID | FEAT_FANCTL_ONOFF,
/* may need to overwrite */
},
[it8716] = {
.name = "it8716",
.suffix = "F",
.features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_VID
- | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS | FEAT_PWM_FREQ2,
+ | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS | FEAT_PWM_FREQ2
+ | FEAT_FANCTL_ONOFF,
},
[it8718] = {
.name = "it8718",
.suffix = "F",
.features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_VID
| FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS
- | FEAT_PWM_FREQ2,
+ | FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF,
.old_peci_mask = 0x4,
},
[it8720] = {
@@ -362,7 +365,7 @@ static const struct it87_devices it87_devices[] = {
.suffix = "F",
.features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_VID
| FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS
- | FEAT_PWM_FREQ2,
+ | FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF,
.old_peci_mask = 0x4,
},
[it8721] = {
@@ -371,7 +374,7 @@ static const struct it87_devices it87_devices[] = {
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_OFFSET | FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI
| FEAT_FAN16_CONFIG | FEAT_FIVE_FANS | FEAT_IN7_INTERNAL
- | FEAT_PWM_FREQ2 | FEAT_SCALING,
+ | FEAT_PWM_FREQ2 | FEAT_SCALING | FEAT_FANCTL_ONOFF,
.peci_mask = 0x05,
.old_peci_mask = 0x02, /* Actually reports PCH */
},
@@ -380,7 +383,8 @@ static const struct it87_devices it87_devices[] = {
.suffix = "F",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_FIVE_FANS
- | FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2 | FEAT_SCALING,
+ | FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2 | FEAT_SCALING
+ | FEAT_FANCTL_ONOFF,
.peci_mask = 0x07,
},
[it8732] = {
@@ -389,7 +393,7 @@ static const struct it87_devices it87_devices[] = {
.features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS
| FEAT_TEMP_OFFSET | FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI
| FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_FOUR_FANS
- | FEAT_FOUR_PWM,
+ | FEAT_FOUR_PWM | FEAT_FANCTL_ONOFF,
.peci_mask = 0x07,
.old_peci_mask = 0x02, /* Actually reports PCH */
},
@@ -398,7 +402,7 @@ static const struct it87_devices it87_devices[] = {
.suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
- | FEAT_PWM_FREQ2 | FEAT_SCALING,
+ | FEAT_PWM_FREQ2 | FEAT_SCALING | FEAT_FANCTL_ONOFF,
/* PECI: guesswork */
/* 12mV ADC (OHM) */
/* 16 bit fans (OHM) */
@@ -410,7 +414,7 @@ static const struct it87_devices it87_devices[] = {
.suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
- | FEAT_PWM_FREQ2 | FEAT_SCALING,
+ | FEAT_PWM_FREQ2 | FEAT_SCALING | FEAT_FANCTL_ONOFF,
/* PECI (coreboot) */
/* 12mV ADC (HWSensors4, OHM) */
/* 16 bit fans (HWSensors4, OHM) */
@@ -421,21 +425,24 @@ static const struct it87_devices it87_devices[] = {
.name = "it8781",
.suffix = "F",
.features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET
- | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_PWM_FREQ2,
+ | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_PWM_FREQ2
+ | FEAT_FANCTL_ONOFF,
.old_peci_mask = 0x4,
},
[it8782] = {
.name = "it8782",
.suffix = "F",
.features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET
- | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_PWM_FREQ2,
+ | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_PWM_FREQ2
+ | FEAT_FANCTL_ONOFF,
.old_peci_mask = 0x4,
},
[it8783] = {
.name = "it8783",
.suffix = "E/F",
.features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET
- | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_PWM_FREQ2,
+ | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_PWM_FREQ2
+ | FEAT_FANCTL_ONOFF,
.old_peci_mask = 0x4,
},
[it8786] = {
@@ -443,7 +450,7 @@ static const struct it87_devices it87_devices[] = {
.suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
- | FEAT_PWM_FREQ2,
+ | FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF,
.peci_mask = 0x07,
},
[it8790] = {
@@ -451,7 +458,7 @@ static const struct it87_devices it87_devices[] = {
.suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_10_9MV_ADC | FEAT_SCALING
| FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI
- | FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2,
+ | FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF,
.peci_mask = 0x07,
},
[it8792] = {
@@ -459,7 +466,7 @@ static const struct it87_devices it87_devices[] = {
.suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_10_9MV_ADC | FEAT_SCALING
| FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI
- | FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2,
+ | FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF,
.peci_mask = 0x07,
},
[it8603] = {
@@ -475,7 +482,8 @@ static const struct it87_devices it87_devices[] = {
.suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
- | FEAT_AVCC3 | FEAT_PWM_FREQ2 | FEAT_SCALING,
+ | FEAT_AVCC3 | FEAT_PWM_FREQ2 | FEAT_SCALING
+ | FEAT_FANCTL_ONOFF,
.peci_mask = 0x07,
},
[it8620] = {
@@ -484,7 +492,8 @@ static const struct it87_devices it87_devices[] = {
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_SIX_FANS
| FEAT_IN7_INTERNAL | FEAT_SIX_PWM | FEAT_PWM_FREQ2
- | FEAT_SIX_TEMP | FEAT_VIN3_5V | FEAT_SCALING,
+ | FEAT_SIX_TEMP | FEAT_VIN3_5V | FEAT_SCALING
+ | FEAT_FANCTL_ONOFF,
.peci_mask = 0x07,
},
[it8622] = {
@@ -502,7 +511,8 @@ static const struct it87_devices it87_devices[] = {
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_SIX_FANS
| FEAT_IN7_INTERNAL | FEAT_SIX_PWM | FEAT_PWM_FREQ2
- | FEAT_SIX_TEMP | FEAT_VIN3_5V | FEAT_SCALING | FEAT_AVCC3,
+ | FEAT_SIX_TEMP | FEAT_VIN3_5V | FEAT_SCALING | FEAT_AVCC3
+ | FEAT_FANCTL_ONOFF,
.peci_mask = 0x07,
},
[it8655] = {
@@ -565,6 +575,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_SIX_PWM))
#define has_bank_sel(data) ((data)->features & FEAT_BANK_SEL)
#define has_scaling(data) ((data)->features & FEAT_SCALING)
+#define has_fanctl_onoff(data) ((data)->features & FEAT_FANCTL_ONOFF)
struct it87_sio_data {
int sioaddr;
@@ -1206,11 +1217,12 @@ static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO | S_IWUSR, show_temp_type,
static int pwm_mode(const struct it87_data *data, int nr)
{
- if (data->type != it8603 && nr < 3 && !(data->fan_main_ctrl & BIT(nr)))
+ if (has_fanctl_onoff(data) && nr < 3 &&
+ !(data->fan_main_ctrl & BIT(nr)))
return 0; /* Full speed */
if (data->pwm_ctrl[nr] & 0x80)
return 2; /* Automatic mode */
- if ((data->type == it8603 || nr >= 3) &&
+ if ((!has_fanctl_onoff(data) || nr >= 3) &&
data->pwm_duty[nr] == pwm_to_reg(data, 0xff))
return 0; /* Full speed */
@@ -1423,7 +1435,7 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr,
mutex_lock(&data->update_lock);
if (val == 0) {
- if (nr < 3 && data->type != it8603) {
+ if (nr < 3 && has_fanctl_onoff(data)) {
int tmp;
/* make sure the fan is on when in on/off mode */
tmp = it87_read_value(data, IT87_REG_FAN_CTL);
@@ -1463,7 +1475,7 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr,
data->pwm_ctrl[nr] = ctrl;
it87_write_value(data, data->REG_PWM[nr], ctrl);
- if (data->type != it8603 && nr < 3) {
+ if (has_fanctl_onoff(data) && nr < 3) {
/* set SmartGuardian mode */
data->fan_main_ctrl |= BIT(nr);
it87_write_value(data, IT87_REG_FAN_MAIN_CTRL,
--
2.20.1
From 6236638afe3ce6c26154bca478bc26551d535289 Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Tue, 11 Apr 2017 06:47:37 -0700
Subject: [PATCH 13/61] Add limit support for temp 4-6
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 93 insertions(+), 21 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index fa2ed33..85d2479 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -255,7 +255,7 @@ static const u8 IT87_REG_FANX_8665[] = { 0x18, 0x19, 0x1a, 0x81, 0x83, 0x94 };
static const u8 IT87_REG_FANX_MIN_8665[] =
{ 0x1b, 0x1c, 0x1d, 0x85, 0x87, 0xb3 };
-static const u8 IT87_REG_TEMP_OFFSET[] = { 0x56, 0x57, 0x59 };
+static const u8 IT87_REG_TEMP_OFFSET[] = { 0x56, 0x57, 0x59, 0x5a, 0x91, 0x90 };
#define IT87_REG_FAN_MAIN_CTRL 0x13
#define IT87_REG_FAN_CTL 0x14
@@ -272,8 +272,9 @@ static const u8 IT87_REG_VIN[] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
#define IT87_REG_VIN_MAX(nr) (0x30 + (nr) * 2)
#define IT87_REG_VIN_MIN(nr) (0x31 + (nr) * 2)
-#define IT87_REG_TEMP_HIGH(nr) (0x40 + (nr) * 2)
-#define IT87_REG_TEMP_LOW(nr) (0x41 + (nr) * 2)
+
+static const u8 IT87_REG_TEMP_HIGH[] = { 0x40, 0x42, 0x44, 0x46, 0xb4, 0xb6 };
+static const u8 IT87_REG_TEMP_LOW[] = { 0x41, 0x43, 0x45, 0x47, 0xb5, 0xb7 };
#define IT87_REG_VIN_ENABLE 0x50
#define IT87_REG_TEMP_ENABLE 0x51
@@ -292,8 +293,6 @@ static const u8 IT87_REG_AUTO_BASE[] = { 0x60, 0x68, 0x70, 0x78, 0xa0, 0xa8 };
#define NUM_VIN ARRAY_SIZE(IT87_REG_VIN)
#define NUM_VIN_LIMIT 8
#define NUM_TEMP 6
-#define NUM_TEMP_OFFSET ARRAY_SIZE(IT87_REG_TEMP_OFFSET)
-#define NUM_TEMP_LIMIT 3
#define NUM_FAN ARRAY_SIZE(IT87_REG_FAN)
#define NUM_FAN_DIV 3
#define NUM_PWM ARRAY_SIZE(IT87_REG_PWM)
@@ -303,6 +302,7 @@ struct it87_devices {
const char *name;
const char * const suffix;
u32 features;
+ u8 num_temp_limit;
u8 peci_mask;
u8 old_peci_mask;
};
@@ -338,12 +338,14 @@ static const struct it87_devices it87_devices[] = {
.suffix = "F",
.features = FEAT_OLD_AUTOPWM | FEAT_FANCTL_ONOFF,
/* may need to overwrite */
+ .num_temp_limit = 3,
},
[it8712] = {
.name = "it8712",
.suffix = "F",
.features = FEAT_OLD_AUTOPWM | FEAT_VID | FEAT_FANCTL_ONOFF,
/* may need to overwrite */
+ .num_temp_limit = 3,
},
[it8716] = {
.name = "it8716",
@@ -351,6 +353,7 @@ static const struct it87_devices it87_devices[] = {
.features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_VID
| FEAT_FAN16_CONFIG | FEAT_FIVE_FANS | FEAT_PWM_FREQ2
| FEAT_FANCTL_ONOFF,
+ .num_temp_limit = 3,
},
[it8718] = {
.name = "it8718",
@@ -358,6 +361,7 @@ static const struct it87_devices it87_devices[] = {
.features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_VID
| FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS
| FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF,
+ .num_temp_limit = 3,
.old_peci_mask = 0x4,
},
[it8720] = {
@@ -366,6 +370,7 @@ static const struct it87_devices it87_devices[] = {
.features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_VID
| FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS
| FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF,
+ .num_temp_limit = 3,
.old_peci_mask = 0x4,
},
[it8721] = {
@@ -375,6 +380,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_TEMP_OFFSET | FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI
| FEAT_FAN16_CONFIG | FEAT_FIVE_FANS | FEAT_IN7_INTERNAL
| FEAT_PWM_FREQ2 | FEAT_SCALING | FEAT_FANCTL_ONOFF,
+ .num_temp_limit = 3,
.peci_mask = 0x05,
.old_peci_mask = 0x02, /* Actually reports PCH */
},
@@ -385,6 +391,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_FIVE_FANS
| FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2 | FEAT_SCALING
| FEAT_FANCTL_ONOFF,
+ .num_temp_limit = 3,
.peci_mask = 0x07,
},
[it8732] = {
@@ -394,6 +401,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_TEMP_OFFSET | FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI
| FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_FOUR_FANS
| FEAT_FOUR_PWM | FEAT_FANCTL_ONOFF,
+ .num_temp_limit = 3,
.peci_mask = 0x07,
.old_peci_mask = 0x02, /* Actually reports PCH */
},
@@ -407,6 +415,7 @@ static const struct it87_devices it87_devices[] = {
/* 12mV ADC (OHM) */
/* 16 bit fans (OHM) */
/* three fans, always 16 bit (guesswork) */
+ .num_temp_limit = 3,
.peci_mask = 0x07,
},
[it8772] = {
@@ -419,6 +428,7 @@ static const struct it87_devices it87_devices[] = {
/* 12mV ADC (HWSensors4, OHM) */
/* 16 bit fans (HWSensors4, OHM) */
/* three fans, always 16 bit (datasheet) */
+ .num_temp_limit = 3,
.peci_mask = 0x07,
},
[it8781] = {
@@ -427,6 +437,7 @@ static const struct it87_devices it87_devices[] = {
.features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET
| FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_PWM_FREQ2
| FEAT_FANCTL_ONOFF,
+ .num_temp_limit = 3,
.old_peci_mask = 0x4,
},
[it8782] = {
@@ -435,6 +446,7 @@ static const struct it87_devices it87_devices[] = {
.features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET
| FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_PWM_FREQ2
| FEAT_FANCTL_ONOFF,
+ .num_temp_limit = 3,
.old_peci_mask = 0x4,
},
[it8783] = {
@@ -443,6 +455,7 @@ static const struct it87_devices it87_devices[] = {
.features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET
| FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_PWM_FREQ2
| FEAT_FANCTL_ONOFF,
+ .num_temp_limit = 3,
.old_peci_mask = 0x4,
},
[it8786] = {
@@ -451,6 +464,7 @@ static const struct it87_devices it87_devices[] = {
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
| FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF,
+ .num_temp_limit = 3,
.peci_mask = 0x07,
},
[it8790] = {
@@ -459,6 +473,7 @@ static const struct it87_devices it87_devices[] = {
.features = FEAT_NEWER_AUTOPWM | FEAT_10_9MV_ADC | FEAT_SCALING
| FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI
| FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF,
+ .num_temp_limit = 3,
.peci_mask = 0x07,
},
[it8792] = {
@@ -467,6 +482,7 @@ static const struct it87_devices it87_devices[] = {
.features = FEAT_NEWER_AUTOPWM | FEAT_10_9MV_ADC | FEAT_SCALING
| FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI
| FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF,
+ .num_temp_limit = 3,
.peci_mask = 0x07,
},
[it8603] = {
@@ -475,6 +491,7 @@ static const struct it87_devices it87_devices[] = {
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
| FEAT_AVCC3 | FEAT_PWM_FREQ2 | FEAT_SCALING,
+ .num_temp_limit = 3,
.peci_mask = 0x07,
},
[it8607] = {
@@ -484,6 +501,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
| FEAT_AVCC3 | FEAT_PWM_FREQ2 | FEAT_SCALING
| FEAT_FANCTL_ONOFF,
+ .num_temp_limit = 3,
.peci_mask = 0x07,
},
[it8620] = {
@@ -494,6 +512,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_IN7_INTERNAL | FEAT_SIX_PWM | FEAT_PWM_FREQ2
| FEAT_SIX_TEMP | FEAT_VIN3_5V | FEAT_SCALING
| FEAT_FANCTL_ONOFF,
+ .num_temp_limit = 3,
.peci_mask = 0x07,
},
[it8622] = {
@@ -503,6 +522,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_FIVE_FANS
| FEAT_FIVE_PWM | FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2
| FEAT_AVCC3 | FEAT_VIN3_5V | FEAT_SCALING,
+ .num_temp_limit = 3,
.peci_mask = 0x07,
},
[it8628] = {
@@ -513,6 +533,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_IN7_INTERNAL | FEAT_SIX_PWM | FEAT_PWM_FREQ2
| FEAT_SIX_TEMP | FEAT_VIN3_5V | FEAT_SCALING | FEAT_AVCC3
| FEAT_FANCTL_ONOFF,
+ .num_temp_limit = 3,
.peci_mask = 0x07,
},
[it8655] = {
@@ -521,6 +542,7 @@ static const struct it87_devices it87_devices[] = {
.features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_AVCC3
| FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_BANK_SEL,
+ .num_temp_limit = 6,
.peci_mask = 0x07,
},
[it8665] = {
@@ -530,6 +552,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_AVCC3
| FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_SIX_FANS
| FEAT_SIX_PWM | FEAT_BANK_SEL,
+ .num_temp_limit = 6,
.peci_mask = 0x07,
},
[it8686] = {
@@ -539,6 +562,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_SIX_FANS
| FEAT_IN7_INTERNAL | FEAT_SIX_PWM | FEAT_PWM_FREQ2
| FEAT_SIX_TEMP | FEAT_BANK_SEL | FEAT_SCALING | FEAT_AVCC3,
+ .num_temp_limit = 6,
.peci_mask = 0x07,
},
};
@@ -629,6 +653,7 @@ struct it87_data {
u16 fan[NUM_FAN][2]; /* Register values, [nr][0]=fan, [1]=min */
u8 has_temp; /* Bitfield, temp sensors enabled */
s8 temp[NUM_TEMP][4]; /* [nr][0]=temp, [1]=min, [2]=max, [3]=offset */
+ u8 num_temp_limit; /* Number of temp limit/offset registers */
u8 sensor; /* Register value (IT87_REG_TEMP_ENABLE) */
u8 extra; /* Register value (IT87_REG_TEMP_EXTRA) */
u8 fan_div[NUM_FAN_DIV];/* Register encoding, shifted right */
@@ -913,18 +938,18 @@ static struct it87_data *it87_update_device(struct device *dev)
data->temp[i][0] =
it87_read_value(data, IT87_REG_TEMP(i));
- if (has_temp_offset(data) && i < NUM_TEMP_OFFSET)
+ if (i >= data->num_temp_limit)
+ continue;
+
+ if (has_temp_offset(data))
data->temp[i][3] =
it87_read_value(data,
IT87_REG_TEMP_OFFSET[i]);
- if (i >= NUM_TEMP_LIMIT)
- continue;
-
data->temp[i][1] =
- it87_read_value(data, IT87_REG_TEMP_LOW(i));
+ it87_read_value(data, IT87_REG_TEMP_LOW[i]);
data->temp[i][2] =
- it87_read_value(data, IT87_REG_TEMP_HIGH(i));
+ it87_read_value(data, IT87_REG_TEMP_HIGH[i]);
}
/* Newer chips don't have clock dividers */
@@ -1091,10 +1116,10 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr,
switch (index) {
default:
case 1:
- reg = IT87_REG_TEMP_LOW(nr);
+ reg = IT87_REG_TEMP_LOW[nr];
break;
case 2:
- reg = IT87_REG_TEMP_HIGH(nr);
+ reg = IT87_REG_TEMP_HIGH[nr];
break;
case 3:
regval = it87_read_value(data, IT87_REG_BEEP_ENABLE);
@@ -1135,8 +1160,26 @@ static SENSOR_DEVICE_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
static SENSOR_DEVICE_ATTR_2(temp3_offset, S_IRUGO | S_IWUSR, show_temp,
set_temp, 2, 3);
static SENSOR_DEVICE_ATTR_2(temp4_input, S_IRUGO, show_temp, NULL, 3, 0);
+static SENSOR_DEVICE_ATTR_2(temp4_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
+ 3, 1);
+static SENSOR_DEVICE_ATTR_2(temp4_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
+ 3, 2);
+static SENSOR_DEVICE_ATTR_2(temp4_offset, S_IRUGO | S_IWUSR, show_temp,
+ set_temp, 3, 3);
static SENSOR_DEVICE_ATTR_2(temp5_input, S_IRUGO, show_temp, NULL, 4, 0);
+static SENSOR_DEVICE_ATTR_2(temp5_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
+ 4, 1);
+static SENSOR_DEVICE_ATTR_2(temp5_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
+ 4, 2);
+static SENSOR_DEVICE_ATTR_2(temp5_offset, S_IRUGO | S_IWUSR, show_temp,
+ set_temp, 4, 3);
static SENSOR_DEVICE_ATTR_2(temp6_input, S_IRUGO, show_temp, NULL, 5, 0);
+static SENSOR_DEVICE_ATTR_2(temp6_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
+ 5, 1);
+static SENSOR_DEVICE_ATTR_2(temp6_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
+ 5, 2);
+static SENSOR_DEVICE_ATTR_2(temp6_offset, S_IRUGO | S_IWUSR, show_temp,
+ set_temp, 5, 3);
static ssize_t show_temp_type(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -1212,6 +1255,12 @@ static SENSOR_DEVICE_ATTR(temp2_type, S_IRUGO | S_IWUSR, show_temp_type,
set_temp_type, 1);
static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO | S_IWUSR, show_temp_type,
set_temp_type, 2);
+static SENSOR_DEVICE_ATTR(temp4_type, S_IRUGO | S_IWUSR, show_temp_type,
+ set_temp_type, 3);
+static SENSOR_DEVICE_ATTR(temp5_type, S_IRUGO | S_IWUSR, show_temp_type,
+ set_temp_type, 4);
+static SENSOR_DEVICE_ATTR(temp6_type, S_IRUGO | S_IWUSR, show_temp_type,
+ set_temp_type, 5);
/* 6 Fans */
@@ -1981,6 +2030,9 @@ static SENSOR_DEVICE_ATTR(fan6_alarm, S_IRUGO, show_alarm, NULL, 7);
static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 16);
static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 17);
static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 18);
+static SENSOR_DEVICE_ATTR(temp4_alarm, S_IRUGO, show_alarm, NULL, 19);
+static SENSOR_DEVICE_ATTR(temp5_alarm, S_IRUGO, show_alarm, NULL, 20);
+static SENSOR_DEVICE_ATTR(temp6_alarm, S_IRUGO, show_alarm, NULL, 21);
static SENSOR_DEVICE_ATTR(intrusion0_alarm, S_IRUGO | S_IWUSR,
show_alarm, clear_intrusion, 4);
@@ -2034,6 +2086,9 @@ static SENSOR_DEVICE_ATTR(temp1_beep, S_IRUGO | S_IWUSR,
show_beep, set_beep, 2);
static SENSOR_DEVICE_ATTR(temp2_beep, S_IRUGO, show_beep, NULL, 2);
static SENSOR_DEVICE_ATTR(temp3_beep, S_IRUGO, show_beep, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp4_beep, S_IRUGO, show_beep, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp5_beep, S_IRUGO, show_beep, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp6_beep, S_IRUGO, show_beep, NULL, 2);
static ssize_t vrm_show(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -2193,14 +2248,12 @@ static umode_t it87_temp_is_visible(struct kobject *kobj,
int i = index / 7; /* temperature index */
int a = index % 7; /* attribute index */
- if (index >= 21) {
- i = index - 21 + 3;
- a = 0;
- }
-
if (!(data->has_temp & BIT(i)))
return 0;
+ if (a && i >= data->num_temp_limit)
+ return 0;
+
if (a == 5 && !has_temp_offset(data))
return 0;
@@ -2236,8 +2289,26 @@ static struct attribute *it87_attributes_temp[] = {
&sensor_dev_attr_temp3_beep.dev_attr.attr,
&sensor_dev_attr_temp4_input.dev_attr.attr, /* 21 */
+ &sensor_dev_attr_temp4_max.dev_attr.attr,
+ &sensor_dev_attr_temp4_min.dev_attr.attr,
+ &sensor_dev_attr_temp4_type.dev_attr.attr,
+ &sensor_dev_attr_temp4_alarm.dev_attr.attr,
+ &sensor_dev_attr_temp4_offset.dev_attr.attr,
+ &sensor_dev_attr_temp4_beep.dev_attr.attr,
&sensor_dev_attr_temp5_input.dev_attr.attr,
+ &sensor_dev_attr_temp5_max.dev_attr.attr,
+ &sensor_dev_attr_temp5_min.dev_attr.attr,
+ &sensor_dev_attr_temp5_type.dev_attr.attr,
+ &sensor_dev_attr_temp5_alarm.dev_attr.attr,
+ &sensor_dev_attr_temp5_offset.dev_attr.attr,
+ &sensor_dev_attr_temp5_beep.dev_attr.attr,
&sensor_dev_attr_temp6_input.dev_attr.attr,
+ &sensor_dev_attr_temp6_max.dev_attr.attr,
+ &sensor_dev_attr_temp6_min.dev_attr.attr,
+ &sensor_dev_attr_temp6_type.dev_attr.attr,
+ &sensor_dev_attr_temp6_alarm.dev_attr.attr,
+ &sensor_dev_attr_temp6_offset.dev_attr.attr,
+ &sensor_dev_attr_temp6_beep.dev_attr.attr,
NULL
};
@@ -3085,10 +3156,10 @@ static void it87_check_limit_regs(struct it87_data *data)
if (reg == 0xff)
it87_write_value(data, IT87_REG_VIN_MIN(i), 0);
}
- for (i = 0; i < NUM_TEMP_LIMIT; i++) {
- reg = it87_read_value(data, IT87_REG_TEMP_HIGH(i));
+ for (i = 0; i < data->num_temp_limit; i++) {
+ reg = it87_read_value(data, IT87_REG_TEMP_HIGH[i]);
if (reg == 0xff)
- it87_write_value(data, IT87_REG_TEMP_HIGH(i), 127);
+ it87_write_value(data, IT87_REG_TEMP_HIGH[i], 127);
}
}
@@ -3343,6 +3414,7 @@ static int it87_probe(struct platform_device *pdev)
data->sioaddr = sio_data->sioaddr;
data->type = sio_data->type;
data->features = it87_devices[sio_data->type].features;
+ data->num_temp_limit = it87_devices[sio_data->type].num_temp_limit;
data->peci_mask = it87_devices[sio_data->type].peci_mask;
data->old_peci_mask = it87_devices[sio_data->type].old_peci_mask;
data->bank = 0xff;
--
2.20.1
From d76e3343a9de023380c7f5cdfe6033e29b77143d Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Wed, 12 Apr 2017 06:15:24 -0700
Subject: [PATCH 14/61] Various improvements NEEDS SPLITTING
- Acquire acpi mutex (not supported in upstream kernel)
- Try to handle 0x4e access failures on Gigabyte boards
- Improve temperature register / limit / type support for recent chips
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 320 +++++++++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 265 insertions(+), 55 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 85d2479..b4441ff 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -74,6 +74,9 @@
#define DRVNAME "it87"
+/* Necessary API not (yet) exported in upstream kernel */
+/* #define __IT87_USE_ACPI_MUTEX */
+
enum chips { it87, it8712, it8716, it8718, it8720, it8721, it8728, it8732,
it8771, it8772, it8781, it8782, it8783, it8786, it8790,
it8792, it8603, it8607, it8620, it8622, it8628, it8655, it8665,
@@ -84,6 +87,11 @@ module_param(force_id, ushort, 0);
MODULE_PARM_DESC(force_id, "Override the detected device ID");
static struct platform_device *it87_pdev[2];
+static bool it87_sio4e_broken;
+#ifdef __IT87_USE_ACPI_MUTEX
+static acpi_handle it87_acpi_sio_handle;
+static char *it87_acpi_sio_mutex;
+#endif
#define REG_2E 0x2e /* The register to read/write */
#define REG_4E 0x4e /* Secondary register to read/write */
@@ -97,10 +105,28 @@ static struct platform_device *it87_pdev[2];
#define DEVID 0x20 /* Register: Device ID */
#define DEVREV 0x22 /* Register: Device Revision */
+static inline void __superio_enter(int ioreg)
+{
+ outb(0x87, ioreg);
+ outb(0x01, ioreg);
+ outb(0x55, ioreg);
+ outb(ioreg == REG_4E ? 0xaa : 0x55, ioreg);
+}
+
static inline int superio_inb(int ioreg, int reg)
{
+ int val;
+
outb(reg, ioreg);
- return inb(ioreg + 1);
+ val = inb(ioreg + 1);
+ if (it87_sio4e_broken && ioreg == 0x4e && val == 0xff) {
+ __superio_enter(ioreg);
+ outb(reg, ioreg);
+ val = inb(ioreg + 1);
+ pr_warn("Retry access 0x4e:0x%x -> 0x%x\n", reg, val);
+ }
+
+ return val;
}
static inline void superio_outb(int ioreg, int reg, int val)
@@ -111,13 +137,7 @@ static inline void superio_outb(int ioreg, int reg, int val)
static int superio_inw(int ioreg, int reg)
{
- int val;
-
- outb(reg++, ioreg);
- val = inb(ioreg + 1) << 8;
- outb(reg, ioreg);
- val |= inb(ioreg + 1);
- return val;
+ return (superio_inb(ioreg, reg) << 8) | superio_inb(ioreg, reg + 1);
}
static inline void superio_select(int ioreg, int ldn)
@@ -128,24 +148,45 @@ static inline void superio_select(int ioreg, int ldn)
static inline int superio_enter(int ioreg)
{
+#ifdef __IT87_USE_ACPI_MUTEX
+ if (it87_acpi_sio_mutex) {
+ acpi_status status;
+
+ status = acpi_acquire_mutex(NULL, it87_acpi_sio_mutex, 0x10);
+ if (ACPI_FAILURE(status)) {
+ pr_err("Failed to acquire ACPI mutex\n");
+ return -EBUSY;
+ }
+ }
+#endif
/*
* Try to reserve ioreg and ioreg + 1 for exclusive access.
*/
if (!request_muxed_region(ioreg, 2, DRVNAME))
- return -EBUSY;
+ goto error;
- outb(0x87, ioreg);
- outb(0x01, ioreg);
- outb(0x55, ioreg);
- outb(ioreg == REG_4E ? 0xaa : 0x55, ioreg);
+ __superio_enter(ioreg);
return 0;
+
+error:
+#ifdef __IT87_USE_ACPI_MUTEX
+ if (it87_acpi_sio_mutex)
+ acpi_release_mutex(it87_acpi_sio_handle, NULL);
+#endif
+ return -EBUSY;
}
static inline void superio_exit(int ioreg)
{
- outb(0x02, ioreg);
- outb(0x02, ioreg + 1);
+ if (!it87_sio4e_broken || ioreg != 0x4e) {
+ outb(0x02, ioreg);
+ outb(0x02, ioreg + 1);
+ }
release_region(ioreg, 2);
+#ifdef __IT87_USE_ACPI_MUTEX
+ if (it87_acpi_sio_mutex)
+ acpi_release_mutex(it87_acpi_sio_handle, NULL);
+#endif
}
/* Logical device 4 registers */
@@ -257,6 +298,8 @@ static const u8 IT87_REG_FANX_MIN_8665[] =
static const u8 IT87_REG_TEMP_OFFSET[] = { 0x56, 0x57, 0x59, 0x5a, 0x91, 0x90 };
+static const u8 IT87_REG_TEMP_OFFSET_8686[] = { 0x56, 0x57, 0x59, 0x92, 0x91, 0x90 };
+
#define IT87_REG_FAN_MAIN_CTRL 0x13
#define IT87_REG_FAN_CTL 0x14
@@ -276,6 +319,11 @@ static const u8 IT87_REG_VIN[] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
static const u8 IT87_REG_TEMP_HIGH[] = { 0x40, 0x42, 0x44, 0x46, 0xb4, 0xb6 };
static const u8 IT87_REG_TEMP_LOW[] = { 0x41, 0x43, 0x45, 0x47, 0xb5, 0xb7 };
+static const u8 IT87_REG_TEMP_HIGH_8686[] =
+ { 0x40, 0x42, 0x44, 0xb4, 0xb6, 0xb8 };
+static const u8 IT87_REG_TEMP_LOW_8686[] =
+ { 0x41, 0x43, 0x45, 0xb5, 0xb7, 0xb9 };
+
#define IT87_REG_VIN_ENABLE 0x50
#define IT87_REG_TEMP_ENABLE 0x51
#define IT87_REG_TEMP_EXTRA 0x55
@@ -290,6 +338,9 @@ static const u8 IT87_REG_AUTO_BASE[] = { 0x60, 0x68, 0x70, 0x78, 0xa0, 0xa8 };
#define IT87_REG_TEMP456_ENABLE 0x77
+static const u16 IT87_REG_TEMP_SRC1[] = { 0x21d, 0x21e, 0x21f };
+#define IT87_REG_TEMP_SRC2 0x23d
+
#define NUM_VIN ARRAY_SIZE(IT87_REG_VIN)
#define NUM_VIN_LIMIT 8
#define NUM_TEMP 6
@@ -638,6 +689,10 @@ struct it87_data {
const u8 *REG_PWM;
+ const u8 *REG_TEMP_OFFSET;
+ const u8 *REG_TEMP_LOW;
+ const u8 *REG_TEMP_HIGH;
+
unsigned short addr;
const char *name;
struct mutex update_lock;
@@ -944,12 +999,12 @@ static struct it87_data *it87_update_device(struct device *dev)
if (has_temp_offset(data))
data->temp[i][3] =
it87_read_value(data,
- IT87_REG_TEMP_OFFSET[i]);
+ data->REG_TEMP_OFFSET[i]);
data->temp[i][1] =
- it87_read_value(data, IT87_REG_TEMP_LOW[i]);
+ it87_read_value(data, data->REG_TEMP_LOW[i]);
data->temp[i][2] =
- it87_read_value(data, IT87_REG_TEMP_HIGH[i]);
+ it87_read_value(data, data->REG_TEMP_HIGH[i]);
}
/* Newer chips don't have clock dividers */
@@ -1116,10 +1171,10 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr,
switch (index) {
default:
case 1:
- reg = IT87_REG_TEMP_LOW[nr];
+ reg = data->REG_TEMP_LOW[nr];
break;
case 2:
- reg = IT87_REG_TEMP_HIGH[nr];
+ reg = data->REG_TEMP_HIGH[nr];
break;
case 3:
regval = it87_read_value(data, IT87_REG_BEEP_ENABLE);
@@ -1128,7 +1183,7 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr,
it87_write_value(data, IT87_REG_BEEP_ENABLE, regval);
}
data->valid = 0;
- reg = IT87_REG_TEMP_OFFSET[nr];
+ reg = data->REG_TEMP_OFFSET[nr];
break;
}
@@ -1181,23 +1236,87 @@ static SENSOR_DEVICE_ATTR_2(temp6_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
static SENSOR_DEVICE_ATTR_2(temp6_offset, S_IRUGO | S_IWUSR, show_temp,
set_temp, 5, 3);
+static int get_temp_type(struct it87_data *data, int index)
+{
+ u8 reg, extra;
+ int type = 0;
+
+ if (has_bank_sel(data)) {
+ int s1reg = IT87_REG_TEMP_SRC1[index/2] >> ((index % 2) * 4);
+ u8 src1, src2;
+
+ src1 = (it87_read_value(data, s1reg) >> ((index % 2) * 4)) & 0x0f;
+ src2 = it87_read_value(data, IT87_REG_TEMP_SRC2);
+
+ switch (data->type) {
+ case it8686:
+ switch (src1) {
+ case 0:
+ if (index >= 3)
+ return 4;
+ break;
+ case 1:
+ if (index == 1 || index == 2 ||
+ index == 4 || index == 5)
+ return 6;
+ break;
+ case 2:
+ if (index == 2 || index == 6)
+ return 5;
+ break;
+ default:
+ break;
+ }
+ break;
+ case it8655:
+ case it8665:
+ if (src1 < 3) {
+ index = src1;
+ break;
+ }
+ switch (src1) {
+ case 3:
+ type = (src2 & BIT(index)) ? 6 : 5;
+ break;
+ case 4 ... 8:
+ type = (src2 & BIT(index)) ? 4 : 6;
+ break;
+ case 9:
+ type = (src2 & BIT(index)) ? 5 : 0;
+ break;
+ default:
+ break;
+ }
+ return type;
+ default:
+ return 0;
+ }
+ }
+ if (index >= 3)
+ return 0;
+
+ reg = it87_read_value(data, IT87_REG_TEMP_ENABLE);
+ extra = it87_read_value(data, IT87_REG_TEMP_EXTRA);
+
+ if ((has_temp_peci(data, index) && (reg >> 6 == index + 1)) ||
+ (has_temp_old_peci(data, index) && (extra & 0x80)))
+ type = 6; /* Intel PECI */
+ if (reg & BIT(index))
+ type = 3; /* thermal diode */
+ else if (reg & BIT(index + 3))
+ type = 4; /* thermistor */
+
+ return type;
+}
+
static ssize_t show_temp_type(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
- int nr = sensor_attr->index;
struct it87_data *data = it87_update_device(dev);
- u8 reg = data->sensor; /* In case value is updated while used */
- u8 extra = data->extra;
+ int type = get_temp_type(data, sensor_attr->index);
- if ((has_temp_peci(data, nr) && (reg >> 6 == nr + 1)) ||
- (has_temp_old_peci(data, nr) && (extra & 0x80)))
- return sprintf(buf, "6\n"); /* Intel PECI */
- if (reg & (1 << nr))
- return sprintf(buf, "3\n"); /* thermal diode */
- if (reg & (8 << nr))
- return sprintf(buf, "4\n"); /* thermistor */
- return sprintf(buf, "0\n"); /* disabled */
+ return sprintf(buf, "%d\n", type);
}
static ssize_t set_temp_type(struct device *dev, struct device_attribute *attr,
@@ -2254,6 +2373,16 @@ static umode_t it87_temp_is_visible(struct kobject *kobj,
if (a && i >= data->num_temp_limit)
return 0;
+ if (a == 3) {
+ int type = get_temp_type(data, i);
+
+ if (type == 0)
+ return 0;
+ if (has_bank_sel(data))
+ return 0444;
+ return attr->mode;
+ }
+
if (a == 5 && !has_temp_offset(data))
return 0;
@@ -2267,7 +2396,7 @@ static struct attribute *it87_attributes_temp[] = {
&sensor_dev_attr_temp1_input.dev_attr.attr,
&sensor_dev_attr_temp1_max.dev_attr.attr,
&sensor_dev_attr_temp1_min.dev_attr.attr,
- &sensor_dev_attr_temp1_type.dev_attr.attr,
+ &sensor_dev_attr_temp1_type.dev_attr.attr, /* 3 */
&sensor_dev_attr_temp1_alarm.dev_attr.attr,
&sensor_dev_attr_temp1_offset.dev_attr.attr, /* 5 */
&sensor_dev_attr_temp1_beep.dev_attr.attr, /* 6 */
@@ -2295,6 +2424,7 @@ static struct attribute *it87_attributes_temp[] = {
&sensor_dev_attr_temp4_alarm.dev_attr.attr,
&sensor_dev_attr_temp4_offset.dev_attr.attr,
&sensor_dev_attr_temp4_beep.dev_attr.attr,
+
&sensor_dev_attr_temp5_input.dev_attr.attr,
&sensor_dev_attr_temp5_max.dev_attr.attr,
&sensor_dev_attr_temp5_min.dev_attr.attr,
@@ -2302,6 +2432,7 @@ static struct attribute *it87_attributes_temp[] = {
&sensor_dev_attr_temp5_alarm.dev_attr.attr,
&sensor_dev_attr_temp5_offset.dev_attr.attr,
&sensor_dev_attr_temp5_beep.dev_attr.attr,
+
&sensor_dev_attr_temp6_input.dev_attr.attr,
&sensor_dev_attr_temp6_max.dev_attr.attr,
&sensor_dev_attr_temp6_min.dev_attr.attr,
@@ -2583,7 +2714,6 @@ static int __init it87_find(int sioaddr, unsigned short *address,
{
int err;
u16 chip_type;
- const char *board_vendor, *board_name;
const struct it87_devices *config;
err = superio_enter(sioaddr);
@@ -3116,25 +3246,6 @@ static int __init it87_find(int sioaddr, unsigned short *address,
if (sio_data->beep_pin)
pr_info("Beeping is supported\n");
- /* Disable specific features based on DMI strings */
- board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
- board_name = dmi_get_system_info(DMI_BOARD_NAME);
- if (board_vendor && board_name) {
- if (strcmp(board_vendor, "nVIDIA") == 0 &&
- strcmp(board_name, "FN68PT") == 0) {
- /*
- * On the Shuttle SN68PT, FAN_CTL2 is apparently not
- * connected to a fan, but to something else. One user
- * has reported instant system power-off when changing
- * the PWM2 duty cycle, so we disable it.
- * I use the board name string as the trigger in case
- * the same board is ever used in other systems.
- */
- pr_info("Disabling pwm2 due to hardware constraints\n");
- sio_data->skip_pwm = BIT(1);
- }
- }
-
exit:
superio_exit(sioaddr);
return err;
@@ -3157,9 +3268,9 @@ static void it87_check_limit_regs(struct it87_data *data)
it87_write_value(data, IT87_REG_VIN_MIN(i), 0);
}
for (i = 0; i < data->num_temp_limit; i++) {
- reg = it87_read_value(data, IT87_REG_TEMP_HIGH[i]);
+ reg = it87_read_value(data, data->REG_TEMP_HIGH[i]);
if (reg == 0xff)
- it87_write_value(data, IT87_REG_TEMP_HIGH[i], 127);
+ it87_write_value(data, data->REG_TEMP_HIGH[i], 127);
}
}
@@ -3226,6 +3337,16 @@ static void it87_init_device(struct platform_device *pdev)
/* Initialize chip specific register pointers */
switch (data->type) {
+ case it8686:
+ data->REG_FAN = IT87_REG_FAN;
+ data->REG_FANX = IT87_REG_FANX;
+ data->REG_FAN_MIN = IT87_REG_FAN_MIN;
+ data->REG_FANX_MIN = IT87_REG_FANX_MIN;
+ data->REG_PWM = IT87_REG_PWM;
+ data->REG_TEMP_OFFSET = IT87_REG_TEMP_OFFSET_8686;
+ data->REG_TEMP_LOW = IT87_REG_TEMP_LOW_8686;
+ data->REG_TEMP_HIGH = IT87_REG_TEMP_HIGH_8686;
+ break;
case it8655:
case it8665:
data->REG_FAN = IT87_REG_FAN_8665;
@@ -3233,6 +3354,9 @@ static void it87_init_device(struct platform_device *pdev)
data->REG_FAN_MIN = IT87_REG_FAN_MIN_8665;
data->REG_FANX_MIN = IT87_REG_FANX_MIN_8665;
data->REG_PWM = IT87_REG_PWM_8665;
+ data->REG_TEMP_OFFSET = IT87_REG_TEMP_OFFSET;
+ data->REG_TEMP_LOW = IT87_REG_TEMP_LOW;
+ data->REG_TEMP_HIGH = IT87_REG_TEMP_HIGH;
break;
case it8622:
data->REG_FAN = IT87_REG_FAN;
@@ -3240,6 +3364,9 @@ static void it87_init_device(struct platform_device *pdev)
data->REG_FAN_MIN = IT87_REG_FAN_MIN;
data->REG_FANX_MIN = IT87_REG_FANX_MIN;
data->REG_PWM = IT87_REG_PWM_8665;
+ data->REG_TEMP_OFFSET = IT87_REG_TEMP_OFFSET;
+ data->REG_TEMP_LOW = IT87_REG_TEMP_LOW;
+ data->REG_TEMP_HIGH = IT87_REG_TEMP_HIGH;
break;
default:
data->REG_FAN = IT87_REG_FAN;
@@ -3247,6 +3374,9 @@ static void it87_init_device(struct platform_device *pdev)
data->REG_FAN_MIN = IT87_REG_FAN_MIN;
data->REG_FANX_MIN = IT87_REG_FANX_MIN;
data->REG_PWM = IT87_REG_PWM;
+ data->REG_TEMP_OFFSET = IT87_REG_TEMP_OFFSET;
+ data->REG_TEMP_LOW = IT87_REG_TEMP_LOW;
+ data->REG_TEMP_HIGH = IT87_REG_TEMP_HIGH;
break;
}
@@ -3655,14 +3785,92 @@ exit_device_put:
return err;
}
+struct it87_dmi_data {
+ bool sio4e_broken; /* SIO accesses @ 0x4e are broken */
+ char *sio_mutex; /* SIO ACPI mutex */
+ u8 skip_pwm; /* pwm channels to skip for this board */
+};
+
+/*
+ * On Gigabyte AB350 boards, accesses to the Super-IO chip
+ * at address 0x4e/0x4f can result in a system hang.
+ * Accesses to address 0x2e/0x2f need to be mutex protected.
+ */
+static struct it87_dmi_data gigabyte_ab350_gaming = {
+ .sio4e_broken = true,
+ .sio_mutex = "\\_SB.PCI0.SBRG.SIO1.MUT0",
+};
+
+/*
+ * On the Shuttle SN68PT, FAN_CTL2 is apparently not
+ * connected to a fan, but to something else. One user
+ * has reported instant system power-off when changing
+ * the PWM2 duty cycle, so we disable it.
+ * I use the board name string as the trigger in case
+ * the same board is ever used in other systems.
+ */
+static struct it87_dmi_data nvidia_fn68pt = {
+ .skip_pwm = BIT(1),
+};
+
+static const struct dmi_system_id it87_dmi_table[] __initconst = {
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Gigabyte Technology Co., Ltd."),
+ DMI_MATCH(DMI_BOARD_NAME, "AB350-Gaming-CF"),
+ },
+ .driver_data = &gigabyte_ab350_gaming,
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Gigabyte Technology Co., Ltd."),
+ DMI_MATCH(DMI_BOARD_NAME, "AB350-Gaming 3-CF"),
+ },
+ .driver_data = &gigabyte_ab350_gaming,
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "nVIDIA"),
+ DMI_MATCH(DMI_BOARD_NAME, "FN68PT"),
+ },
+ .driver_data = &nvidia_fn68pt,
+ },
+ { }
+};
+
static int __init sm_it87_init(void)
{
+ const struct dmi_system_id *dmi = dmi_first_match(it87_dmi_table);
+ struct it87_dmi_data *dmi_data = NULL;
int sioaddr[2] = { REG_2E, REG_4E };
struct it87_sio_data sio_data;
unsigned short isa_address[2];
bool found = false;
int i, err;
+ if (dmi)
+ dmi_data = dmi->driver_data;
+
+ if (dmi_data) {
+ it87_sio4e_broken = dmi_data->sio4e_broken;
+#ifdef __IT87_USE_ACPI_MUTEX
+ if (dmi_data->sio_mutex) {
+ static acpi_status status;
+
+ status = acpi_get_handle(NULL, dmi_data->sio_mutex,
+ &it87_acpi_sio_handle);
+ if (ACPI_SUCCESS(status)) {
+ it87_acpi_sio_mutex = dmi_data->sio_mutex;
+ pr_debug("Found ACPI SIO mutex %s\n",
+ dmi_data->sio_mutex);
+ } else {
+ pr_warn("ACPI SIO mutex %s not found\n",
+ dmi_data->sio_mutex);
+ }
+ }
+#endif /* __IT87_USE_ACPI_MUTEX */
+ }
+
err = platform_driver_register(&it87_driver);
if (err)
return err;
@@ -3680,6 +3888,8 @@ static int __init sm_it87_init(void)
if (i && isa_address[i] == isa_address[0])
break;
+ if (dmi_data)
+ sio_data.skip_pwm |= dmi_data->skip_pwm;
err = it87_device_add(i, isa_address[i], &sio_data);
if (err)
goto exit_dev_unregister;
--
2.20.1
From a700444d088baf0a5157120664e22cc39c1ed7c7 Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Wed, 12 Apr 2017 06:32:49 -0700
Subject: [PATCH 15/61] Fix up temp offset register addresses
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index b4441ff..53466e5 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -296,9 +296,9 @@ static const u8 IT87_REG_FANX_8665[] = { 0x18, 0x19, 0x1a, 0x81, 0x83, 0x94 };
static const u8 IT87_REG_FANX_MIN_8665[] =
{ 0x1b, 0x1c, 0x1d, 0x85, 0x87, 0xb3 };
-static const u8 IT87_REG_TEMP_OFFSET[] = { 0x56, 0x57, 0x59, 0x5a, 0x91, 0x90 };
+static const u8 IT87_REG_TEMP_OFFSET[] = { 0x56, 0x57, 0x59, 0x5a, 0x90, 0x91 };
-static const u8 IT87_REG_TEMP_OFFSET_8686[] = { 0x56, 0x57, 0x59, 0x92, 0x91, 0x90 };
+static const u8 IT87_REG_TEMP_OFFSET_8686[] = { 0x56, 0x57, 0x59, 0x90, 0x91, 0x92 };
#define IT87_REG_FAN_MAIN_CTRL 0x13
#define IT87_REG_FAN_CTL 0x14
--
2.20.1
From b012e5a9900f3ce0963b5bfcba51570a20bdc14f Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Thu, 13 Apr 2017 06:02:32 -0700
Subject: [PATCH 16/61] Add support for 11mV ADC
The ADC LSB on some newer chips such as IT8613E and IT8625E is
officially 11mV, not 10.9mV. Add support for it.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 53466e5..cebf8c9 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -382,6 +382,7 @@ struct it87_devices {
#define FEAT_BANK_SEL BIT(21) /* Chip has multi-bank support */
#define FEAT_SCALING BIT(22) /* Internal voltage scaling */
#define FEAT_FANCTL_ONOFF BIT(23) /* chip has FAN_CTL ON/OFF */
+#define FEAT_11MV_ADC BIT(24)
static const struct it87_devices it87_devices[] = {
[it87] = {
@@ -651,6 +652,7 @@ static const struct it87_devices it87_devices[] = {
#define has_bank_sel(data) ((data)->features & FEAT_BANK_SEL)
#define has_scaling(data) ((data)->features & FEAT_SCALING)
#define has_fanctl_onoff(data) ((data)->features & FEAT_FANCTL_ONOFF)
+#define has_11mv_adc(data) ((data)->features & FEAT_11MV_ADC)
struct it87_sio_data {
int sioaddr;
@@ -749,6 +751,8 @@ static int adc_lsb(const struct it87_data *data, int nr)
lsb = 120;
else if (has_10_9mv_adc(data))
lsb = 109;
+ else if (has_11mv_adc(data))
+ lsb = 110;
else
lsb = 160;
if (data->in_scaled & BIT(nr))
@@ -2262,7 +2266,8 @@ static ssize_t show_label(struct device *dev, struct device_attribute *attr,
if (has_vin3_5v(data) && nr == 0)
label = labels[0];
- else if (has_12mv_adc(data) || has_10_9mv_adc(data))
+ else if (has_12mv_adc(data) || has_10_9mv_adc(data) ||
+ has_11mv_adc(data))
label = labels_it8721[nr];
else
label = labels[nr];
--
2.20.1
From 8fc4443d07bbe5a38cd6edd9a62857553d03fe6a Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Thu, 13 Apr 2017 07:05:13 -0700
Subject: [PATCH 17/61] FEAT_TEMP_PECI does not apply to multi-bank chips.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index cebf8c9..2b0d164 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -592,30 +592,27 @@ static const struct it87_devices it87_devices[] = {
.name = "it8655",
.suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS
- | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_AVCC3
+ | FEAT_TEMP_OFFSET | FEAT_AVCC3
| FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_BANK_SEL,
.num_temp_limit = 6,
- .peci_mask = 0x07,
},
[it8665] = {
.name = "it8665",
.suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS
- | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_AVCC3
+ | FEAT_TEMP_OFFSET | FEAT_AVCC3
| FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_SIX_FANS
| FEAT_SIX_PWM | FEAT_BANK_SEL,
.num_temp_limit = 6,
- .peci_mask = 0x07,
},
[it8686] = {
.name = "it8686",
.suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
- | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_SIX_FANS
+ | FEAT_TEMP_OFFSET | FEAT_SIX_FANS
| FEAT_IN7_INTERNAL | FEAT_SIX_PWM | FEAT_PWM_FREQ2
| FEAT_SIX_TEMP | FEAT_BANK_SEL | FEAT_SCALING | FEAT_AVCC3,
.num_temp_limit = 6,
- .peci_mask = 0x07,
},
};
--
2.20.1
From 5a92d28da3cbbfdca35fdd24f7765e10fc80f997 Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Tue, 18 Apr 2017 10:00:31 -0700
Subject: [PATCH 18/61] Disable access to 2nd Super-IO chip
It is known to be broken.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 2b0d164..b5828e4 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -3878,6 +3878,12 @@ static int __init sm_it87_init(void)
return err;
for (i = 0; i < ARRAY_SIZE(sioaddr); i++) {
+ /*
+ * Accessing the second Super-IO chi can result in board
+ * hangs. Disable until we figure out what is going on.
+ */
+ if (it87_sio4e_broken && sioaddr[i] == 0x4e)
+ continue;
memset(&sio_data, 0, sizeof(struct it87_sio_data));
isa_address[i] = 0;
err = it87_find(sioaddr[i], &isa_address[i], &sio_data);
--
2.20.1
From 961f13295c0dec3f933bf08a3bd462fd6cfde0f9 Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Tue, 18 Apr 2017 14:49:22 -0700
Subject: [PATCH 19/61] Blacklist IT8792E on AX370-Gaming K7
Accessing it may result in a system hang.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index b5828e4..7f11e6d 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -3794,7 +3794,7 @@ struct it87_dmi_data {
};
/*
- * On Gigabyte AB350 boards, accesses to the Super-IO chip
+ * On Gigabyte AB350 and AX370 boards, accesses to the Super-IO chip
* at address 0x4e/0x4f can result in a system hang.
* Accesses to address 0x2e/0x2f need to be mutex protected.
*/
@@ -3830,6 +3830,13 @@ static const struct dmi_system_id it87_dmi_table[] __initconst = {
},
.driver_data = &gigabyte_ab350_gaming,
},
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Gigabyte Technology Co., Ltd."),
+ DMI_MATCH(DMI_BOARD_NAME, "AX370-Gaming K7"),
+ },
+ .driver_data = &gigabyte_ab350_gaming,
+ },
{
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "nVIDIA"),
--
2.20.1
From 7232fe7d8f07082ff1479a34f940486c9232ffd8 Mon Sep 17 00:00:00 2001
From: andreychernyshev <atchernyshev@hotmail.com>
Date: Sat, 15 Apr 2017 15:07:44 +0300
Subject: [PATCH 20/61] Add support for IT8613E
[groeck: Fix README]
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 96 insertions(+), 8 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 7f11e6d..72cee49 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -12,6 +12,7 @@
*
* Supports: IT8603E Super I/O chip w/LPC interface
* IT8607E Super I/O chip w/LPC interface
+ * IT8613E Super I/O chip w/LPC interface
* IT8620E Super I/O chip w/LPC interface
* IT8622E Super I/O chip w/LPC interface
* IT8623E Super I/O chip w/LPC interface
@@ -79,8 +80,8 @@
enum chips { it87, it8712, it8716, it8718, it8720, it8721, it8728, it8732,
it8771, it8772, it8781, it8782, it8783, it8786, it8790,
- it8792, it8603, it8607, it8620, it8622, it8628, it8655, it8665,
- it8686 };
+ it8792, it8603, it8607, it8613, it8620, it8622, it8628, it8655,
+ it8665, it8686 };
static unsigned short force_id;
module_param(force_id, ushort, 0);
@@ -209,6 +210,7 @@ static inline void superio_exit(int ioreg)
#define IT8790E_DEVID 0x8790
#define IT8603E_DEVID 0x8603
#define IT8607E_DEVID 0x8607
+#define IT8613E_DEVID 0x8613
#define IT8620E_DEVID 0x8620
#define IT8622E_DEVID 0x8622
#define IT8623E_DEVID 0x8623
@@ -556,6 +558,16 @@ static const struct it87_devices it87_devices[] = {
.num_temp_limit = 3,
.peci_mask = 0x07,
},
+ [it8613] = {
+ .name = "it8613",
+ .suffix = "E",
+ .features = FEAT_NEWER_AUTOPWM | FEAT_11MV_ADC | FEAT_16BIT_FANS
+ | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_FIVE_FANS
+ | FEAT_FIVE_PWM | FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2
+ | FEAT_AVCC3 | FEAT_SCALING,
+ .num_temp_limit = 6,
+ .peci_mask = 0x07,
+ },
[it8620] = {
.name = "it8620",
.suffix = "E",
@@ -891,7 +903,10 @@ static void it87_update_pwm_ctrl(struct it87_data *data, int nr)
{
data->pwm_ctrl[nr] = it87_read_value(data, data->REG_PWM[nr]);
if (has_newer_autopwm(data)) {
- data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03;
+ if (data->type == it8613)
+ data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x38;
+ else
+ data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03;
data->pwm_duty[nr] = it87_read_value(data,
IT87_REG_PWM_DUTY[nr]);
} else {
@@ -1742,10 +1757,16 @@ static ssize_t show_pwm_temp_map(struct device *dev,
int map;
map = data->pwm_temp_map[nr];
- if (map >= 3)
- map = 0; /* Should never happen */
- if (nr >= 3) /* pwm channels 3..6 map to temp4..6 */
- map += 3;
+ if (data->type == it8613) {
+ map >>= 3;
+ if (map >= 7)
+ map = 0; /* Should never happen */
+ } else {
+ if (map >= 3)
+ map = 0; /* Should never happen */
+ if (nr >= 3) /* pwm channels 3..6 map to temp4..6 */
+ map += 3;
+ }
return sprintf(buf, "%d\n", (int)BIT(map));
}
@@ -1763,7 +1784,7 @@ static ssize_t set_pwm_temp_map(struct device *dev,
if (kstrtol(buf, 10, &val) < 0)
return -EINVAL;
- if (nr >= 3)
+ if (nr >= 3 && data->type != it8613)
val -= 3;
switch (val) {
@@ -1776,10 +1797,27 @@ static ssize_t set_pwm_temp_map(struct device *dev,
case BIT(2):
reg = 0x02;
break;
+ case BIT(3):
+ reg = 0x03;
+ break;
+ case BIT(4):
+ reg = 0x04;
+ break;
+ case BIT(5):
+ reg = 0x05;
+ break;
+ case BIT(5) | BIT(6):
+ reg = 0x06;
+ break;
default:
return -EINVAL;
}
+ if (data->type == it8613)
+ reg <<= 3;
+ else if (reg > 0x02)
+ return -EINVAL;
+
mutex_lock(&data->update_lock);
it87_update_pwm_ctrl(data, nr);
data->pwm_temp_map[nr] = reg;
@@ -2787,6 +2825,9 @@ static int __init it87_find(int sioaddr, unsigned short *address,
case IT8607E_DEVID:
sio_data->type = it8607;
break;
+ case IT8613E_DEVID:
+ sio_data->type = it8613;
+ break;
case IT8620E_DEVID:
sio_data->type = it8620;
break;
@@ -2955,6 +2996,43 @@ static int __init it87_find(int sioaddr, unsigned short *address,
sio_data->skip_in |= BIT(6); /* No VIN6 */
}
+ sio_data->beep_pin = superio_inb(sioaddr,
+ IT87_SIO_BEEP_PIN_REG) & 0x3f;
+ } else if (sio_data->type == it8613) {
+ int reg27, reg29, reg2a;
+
+ superio_select(sioaddr, GPIO);
+
+ /* Check for pwm3, fan3, pwm5, fan5 */
+ reg27 = superio_inb(sioaddr, IT87_SIO_GPIO3_REG);
+ if (reg27 & BIT(1))
+ sio_data->skip_fan |= BIT(4);
+ if (reg27 & BIT(3))
+ sio_data->skip_pwm |= BIT(4);
+ if (reg27 & BIT(6))
+ sio_data->skip_pwm |= BIT(2);
+ if (reg27 & BIT(7))
+ sio_data->skip_fan |= BIT(2);
+
+ /* Check for pwm2, fan2 */
+ reg29 = superio_inb(sioaddr, IT87_SIO_GPIO5_REG);
+ if (reg29 & BIT(1))
+ sio_data->skip_pwm |= BIT(1);
+ if (reg29 & BIT(2))
+ sio_data->skip_fan |= BIT(1);
+
+ /* Check for pwm4, fan4 */
+ reg2a = superio_inb(sioaddr, IT87_SIO_PINX1_REG);
+ if (!(reg2a & BIT(0)) || (reg29 & BIT(7))) {
+ sio_data->skip_fan |= BIT(3);
+ sio_data->skip_pwm |= BIT(3);
+ }
+
+ sio_data->skip_pwm |= BIT(0); /* No pwm1 */
+ sio_data->skip_fan |= BIT(0); /* No fan1 */
+ sio_data->skip_in |= BIT(3); /* No VIN3 */
+ sio_data->skip_in |= BIT(6); /* No VIN6 */
+
sio_data->beep_pin = superio_inb(sioaddr,
IT87_SIO_BEEP_PIN_REG) & 0x3f;
} else if (sio_data->type == it8620 || sio_data->type == it8628 ||
@@ -3370,6 +3448,16 @@ static void it87_init_device(struct platform_device *pdev)
data->REG_TEMP_LOW = IT87_REG_TEMP_LOW;
data->REG_TEMP_HIGH = IT87_REG_TEMP_HIGH;
break;
+ case it8613:
+ data->REG_FAN = IT87_REG_FAN;
+ data->REG_FANX = IT87_REG_FANX;
+ data->REG_FAN_MIN = IT87_REG_FAN_MIN;
+ data->REG_FANX_MIN = IT87_REG_FANX_MIN;
+ data->REG_PWM = IT87_REG_PWM_8665;
+ data->REG_TEMP_OFFSET = IT87_REG_TEMP_OFFSET;
+ data->REG_TEMP_LOW = IT87_REG_TEMP_LOW;
+ data->REG_TEMP_HIGH = IT87_REG_TEMP_HIGH;
+ break;
default:
data->REG_FAN = IT87_REG_FAN;
data->REG_FANX = IT87_REG_FANX;
--
2.20.1
From 5833165e8f027b58f59c5f60fcfcf05df420dd72 Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Tue, 18 Apr 2017 21:57:08 -0700
Subject: [PATCH 21/61] Introduce FEAT_NEW_TEMPMAP
Several recent chips have a different register definition for
temperature to pwm assignment. Introduce FEAT_NEW_TEMPMAP to reflect
this and assign to affected chips.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 26 +++++++++++++++-----------
1 file changed, 15 insertions(+), 11 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 72cee49..fc3d96e 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -385,6 +385,7 @@ struct it87_devices {
#define FEAT_SCALING BIT(22) /* Internal voltage scaling */
#define FEAT_FANCTL_ONOFF BIT(23) /* chip has FAN_CTL ON/OFF */
#define FEAT_11MV_ADC BIT(24)
+#define FEAT_NEW_TEMPMAP BIT(25) /* new temp input selection */
static const struct it87_devices it87_devices[] = {
[it87] = {
@@ -564,7 +565,7 @@ static const struct it87_devices it87_devices[] = {
.features = FEAT_NEWER_AUTOPWM | FEAT_11MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_FIVE_FANS
| FEAT_FIVE_PWM | FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2
- | FEAT_AVCC3 | FEAT_SCALING,
+ | FEAT_AVCC3 | FEAT_SCALING | FEAT_NEW_TEMPMAP,
.num_temp_limit = 6,
.peci_mask = 0x07,
},
@@ -604,7 +605,7 @@ static const struct it87_devices it87_devices[] = {
.name = "it8655",
.suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS
- | FEAT_TEMP_OFFSET | FEAT_AVCC3
+ | FEAT_TEMP_OFFSET | FEAT_AVCC3 | FEAT_NEW_TEMPMAP
| FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_BANK_SEL,
.num_temp_limit = 6,
},
@@ -612,7 +613,7 @@ static const struct it87_devices it87_devices[] = {
.name = "it8665",
.suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS
- | FEAT_TEMP_OFFSET | FEAT_AVCC3
+ | FEAT_TEMP_OFFSET | FEAT_AVCC3 | FEAT_NEW_TEMPMAP
| FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_SIX_FANS
| FEAT_SIX_PWM | FEAT_BANK_SEL,
.num_temp_limit = 6,
@@ -621,7 +622,7 @@ static const struct it87_devices it87_devices[] = {
.name = "it8686",
.suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
- | FEAT_TEMP_OFFSET | FEAT_SIX_FANS
+ | FEAT_TEMP_OFFSET | FEAT_SIX_FANS | FEAT_NEW_TEMPMAP
| FEAT_IN7_INTERNAL | FEAT_SIX_PWM | FEAT_PWM_FREQ2
| FEAT_SIX_TEMP | FEAT_BANK_SEL | FEAT_SCALING | FEAT_AVCC3,
.num_temp_limit = 6,
@@ -662,6 +663,7 @@ static const struct it87_devices it87_devices[] = {
#define has_scaling(data) ((data)->features & FEAT_SCALING)
#define has_fanctl_onoff(data) ((data)->features & FEAT_FANCTL_ONOFF)
#define has_11mv_adc(data) ((data)->features & FEAT_11MV_ADC)
+#define has_new_tempmap(data) ((data)->features & FEAT_NEW_TEMPMAP)
struct it87_sio_data {
int sioaddr;
@@ -903,7 +905,7 @@ static void it87_update_pwm_ctrl(struct it87_data *data, int nr)
{
data->pwm_ctrl[nr] = it87_read_value(data, data->REG_PWM[nr]);
if (has_newer_autopwm(data)) {
- if (data->type == it8613)
+ if (has_new_tempmap(data))
data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x38;
else
data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03;
@@ -1757,9 +1759,9 @@ static ssize_t show_pwm_temp_map(struct device *dev,
int map;
map = data->pwm_temp_map[nr];
- if (data->type == it8613) {
+ if (has_new_tempmap(data)) {
map >>= 3;
- if (map >= 7)
+ if (map >= 6)
map = 0; /* Should never happen */
} else {
if (map >= 3)
@@ -1784,7 +1786,7 @@ static ssize_t set_pwm_temp_map(struct device *dev,
if (kstrtol(buf, 10, &val) < 0)
return -EINVAL;
- if (nr >= 3 && data->type != it8613)
+ if (nr >= 3 && !has_new_tempmap(data))
val -= 3;
switch (val) {
@@ -1806,14 +1808,14 @@ static ssize_t set_pwm_temp_map(struct device *dev,
case BIT(5):
reg = 0x05;
break;
- case BIT(5) | BIT(6):
+ case BIT(6):
reg = 0x06;
break;
default:
return -EINVAL;
}
- if (data->type == it8613)
+ if (has_new_tempmap(data))
reg <<= 3;
else if (reg > 0x02)
return -EINVAL;
@@ -1826,7 +1828,9 @@ static ssize_t set_pwm_temp_map(struct device *dev,
* otherwise, just store it for later use.
*/
if (data->pwm_ctrl[nr] & 0x80) {
- data->pwm_ctrl[nr] = (data->pwm_ctrl[nr] & 0xfc) |
+ u8 mask = has_new_tempmap(data) ? 0xc7 : 0xfc;
+
+ data->pwm_ctrl[nr] = (data->pwm_ctrl[nr] & mask) |
data->pwm_temp_map[nr];
it87_write_value(data, data->REG_PWM[nr], data->pwm_ctrl[nr]);
}
--
2.20.1
From d24ae0a766c0c451c7f09bfa48dd9b5a3718919a Mon Sep 17 00:00:00 2001
From: koji54 <koji.kabuto@free.fr>
Date: Sun, 23 Apr 2017 09:32:30 +0200
Subject: [PATCH 22/61] Add Gigabyte AX370-Gaming 5 to IT8792E blacklist
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index fc3d96e..2d8904f 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -3929,6 +3929,13 @@ static const struct dmi_system_id it87_dmi_table[] __initconst = {
},
.driver_data = &gigabyte_ab350_gaming,
},
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Gigabyte Technology Co., Ltd."),
+ DMI_MATCH(DMI_BOARD_NAME, "AX370-Gaming 5"),
+ },
+ .driver_data = &gigabyte_ab350_gaming,
+ },
{
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "nVIDIA"),
--
2.20.1
From 6bd5339176ab8cdd8103f90d8e35651d60f18c2b Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Wed, 26 Apr 2017 14:28:27 -0700
Subject: [PATCH 23/61] Initialize register pointers before using them
Register pointers have to be initialized before they can be used in
it87_check_pwm().
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 34 +++++++++++++++++++++-------------
1 file changed, 21 insertions(+), 13 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 2d8904f..acadef3 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -3412,12 +3412,9 @@ static void it87_start_monitoring(struct it87_data *data)
| (update_vbat ? 0x41 : 0x01));
}
-/* Called when we have found a new IT87. */
-static void it87_init_device(struct platform_device *pdev)
+static void it87_init_regs(struct platform_device *pdev)
{
- struct it87_sio_data *sio_data = dev_get_platdata(&pdev->dev);
struct it87_data *data = platform_get_drvdata(pdev);
- int tmp, i;
/* Initialize chip specific register pointers */
switch (data->type) {
@@ -3453,15 +3450,15 @@ static void it87_init_device(struct platform_device *pdev)
data->REG_TEMP_HIGH = IT87_REG_TEMP_HIGH;
break;
case it8613:
- data->REG_FAN = IT87_REG_FAN;
- data->REG_FANX = IT87_REG_FANX;
- data->REG_FAN_MIN = IT87_REG_FAN_MIN;
- data->REG_FANX_MIN = IT87_REG_FANX_MIN;
- data->REG_PWM = IT87_REG_PWM_8665;
- data->REG_TEMP_OFFSET = IT87_REG_TEMP_OFFSET;
- data->REG_TEMP_LOW = IT87_REG_TEMP_LOW;
- data->REG_TEMP_HIGH = IT87_REG_TEMP_HIGH;
- break;
+ data->REG_FAN = IT87_REG_FAN;
+ data->REG_FANX = IT87_REG_FANX;
+ data->REG_FAN_MIN = IT87_REG_FAN_MIN;
+ data->REG_FANX_MIN = IT87_REG_FANX_MIN;
+ data->REG_PWM = IT87_REG_PWM_8665;
+ data->REG_TEMP_OFFSET = IT87_REG_TEMP_OFFSET;
+ data->REG_TEMP_LOW = IT87_REG_TEMP_LOW;
+ data->REG_TEMP_HIGH = IT87_REG_TEMP_HIGH;
+ break;
default:
data->REG_FAN = IT87_REG_FAN;
data->REG_FANX = IT87_REG_FANX;
@@ -3473,6 +3470,14 @@ static void it87_init_device(struct platform_device *pdev)
data->REG_TEMP_HIGH = IT87_REG_TEMP_HIGH;
break;
}
+}
+
+/* Called when we have found a new IT87. */
+static void it87_init_device(struct platform_device *pdev)
+{
+ struct it87_sio_data *sio_data = dev_get_platdata(&pdev->dev);
+ struct it87_data *data = platform_get_drvdata(pdev);
+ int tmp, i;
/*
* For each PWM channel:
@@ -3675,6 +3680,9 @@ static int it87_probe(struct platform_device *pdev)
mutex_init(&data->update_lock);
+ /* Initialize register pointers */
+ it87_init_regs(pdev);
+
/* Check PWM configuration */
enable_pwm_interface = it87_check_pwm(dev);
if (!enable_pwm_interface)
--
2.20.1
From 64fd4dc3146788db5cf924b3143cf392a5d32afc Mon Sep 17 00:00:00 2001
From: Justin Maggard <jmaggard@netgear.com>
Date: Tue, 2 May 2017 11:59:26 -0700
Subject: [PATCH 24/61] Add support for IT8625E
This is mostly identical to IT8665E, with the exception of the
configuration bits for fans 4 and 5.
Signed-off-by: Justin Maggard <jmaggard@netgear.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 88 +++++++++++++++++++++++++++++++++++++++-------------------
1 file changed, 60 insertions(+), 28 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index acadef3..d1e1bff 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -16,6 +16,7 @@
* IT8620E Super I/O chip w/LPC interface
* IT8622E Super I/O chip w/LPC interface
* IT8623E Super I/O chip w/LPC interface
+ * IT8625E Super I/O chip w/LPC interface
* IT8628E Super I/O chip w/LPC interface
* IT8655E Super I/O chip w/LPC interface
* IT8665E Super I/O chip w/LPC interface
@@ -80,8 +81,8 @@
enum chips { it87, it8712, it8716, it8718, it8720, it8721, it8728, it8732,
it8771, it8772, it8781, it8782, it8783, it8786, it8790,
- it8792, it8603, it8607, it8613, it8620, it8622, it8628, it8655,
- it8665, it8686 };
+ it8792, it8603, it8607, it8613, it8620, it8622, it8625, it8628,
+ it8655, it8665, it8686 };
static unsigned short force_id;
module_param(force_id, ushort, 0);
@@ -214,6 +215,7 @@ static inline void superio_exit(int ioreg)
#define IT8620E_DEVID 0x8620
#define IT8622E_DEVID 0x8622
#define IT8623E_DEVID 0x8623
+#define IT8625E_DEVID 0x8625
#define IT8628E_DEVID 0x8628
#define IT8655E_DEVID 0x8655
#define IT8665E_DEVID 0x8665
@@ -590,6 +592,15 @@ static const struct it87_devices it87_devices[] = {
.num_temp_limit = 3,
.peci_mask = 0x07,
},
+ [it8625] = {
+ .name = "it8625",
+ .suffix = "E",
+ .features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS
+ | FEAT_TEMP_OFFSET | FEAT_AVCC3 | FEAT_NEW_TEMPMAP
+ | FEAT_11MV_ADC | FEAT_IN7_INTERNAL | FEAT_SIX_FANS
+ | FEAT_SIX_PWM | FEAT_BANK_SEL | FEAT_SCALING,
+ .num_temp_limit = 6,
+ },
[it8628] = {
.name = "it8628",
.suffix = "E",
@@ -1286,6 +1297,9 @@ static int get_temp_type(struct it87_data *data, int index)
break;
}
break;
+ case it8625:
+ if (index < 3)
+ break;
case it8655:
case it8665:
if (src1 < 3) {
@@ -2838,6 +2852,9 @@ static int __init it87_find(int sioaddr, unsigned short *address,
case IT8622E_DEVID:
sio_data->type = it8622;
break;
+ case IT8625E_DEVID:
+ sio_data->type = it8625;
+ break;
case IT8628E_DEVID:
sio_data->type = it8628;
break;
@@ -3183,44 +3200,57 @@ static int __init it87_find(int sioaddr, unsigned short *address,
sio_data->beep_pin = superio_inb(sioaddr,
IT87_SIO_BEEP_PIN_REG) & 0x3f;
- } else if (sio_data->type == it8665) {
- int reg;
+ } else if (sio_data->type == it8665 || sio_data->type == it8625) {
+ int reg27, reg29, reg2d, regd3;
superio_select(sioaddr, GPIO);
- /* Check for pwm2 */
- reg = superio_inb(sioaddr, IT87_SIO_GPIO5_REG);
- if (reg & BIT(1))
- sio_data->skip_pwm |= BIT(1);
+ reg27 = superio_inb(sioaddr, IT87_SIO_GPIO3_REG);
+ reg29 = superio_inb(sioaddr, IT87_SIO_GPIO5_REG);
+ reg2d = superio_inb(sioaddr, IT87_SIO_PINX4_REG);
+ regd3 = superio_inb(sioaddr, IT87_SIO_GPIO9_REG);
- /* Check for fan2 */
- reg = superio_inb(sioaddr, IT87_SIO_PINX4_REG);
- if (reg & BIT(4))
+ /* Check for pwm2, fan2 */
+ if (reg29 & BIT(1))
+ sio_data->skip_pwm |= BIT(1);
+ if (reg2d & BIT(4))
sio_data->skip_fan |= BIT(1);
/* Check for pwm3, fan3 */
- reg = superio_inb(sioaddr, IT87_SIO_GPIO3_REG);
- if (reg & BIT(6))
+ if (reg27 & BIT(6))
sio_data->skip_pwm |= BIT(2);
- if (reg & BIT(7))
+ if (reg27 & BIT(7))
sio_data->skip_fan |= BIT(2);
- /* Check for pwm5, fan5 */
- reg = superio_inb(sioaddr, IT87_SIO_GPIO2_REG);
- if (reg & BIT(5))
- sio_data->skip_pwm |= BIT(4);
- if (!(reg & BIT(4)))
- sio_data->skip_fan |= BIT(4);
+ /* Check for pwm4, fan4, pwm5, fan5 */
+ if (sio_data->type == it8625) {
+ int reg25 = superio_inb(sioaddr, IT87_SIO_GPIO1_REG);
+
+ if (reg25 & BIT(6))
+ sio_data->skip_fan |= BIT(3);
+ if (reg25 & BIT(5))
+ sio_data->skip_pwm |= BIT(3);
+ if (reg27 & BIT(3))
+ sio_data->skip_pwm |= BIT(4);
+ if (reg27 & BIT(1))
+ sio_data->skip_fan |= BIT(4);
+ } else {
+ int reg26 = superio_inb(sioaddr, IT87_SIO_GPIO2_REG);
+
+ if (regd3 & BIT(2))
+ sio_data->skip_pwm |= BIT(3);
+ if (regd3 & BIT(3))
+ sio_data->skip_fan |= BIT(3);
+ if (reg26 & BIT(5))
+ sio_data->skip_pwm |= BIT(4);
+ if (!(reg26 & BIT(4)))
+ sio_data->skip_fan |= BIT(4);
+ }
- /* Check for pwm4, fan4, pwm6, fan6 */
- reg = superio_inb(sioaddr, IT87_SIO_GPIO9_REG);
- if (reg & BIT(2))
- sio_data->skip_pwm |= BIT(3);
- if (reg & BIT(3))
- sio_data->skip_fan |= BIT(3);
- if (reg & BIT(0))
+ /* Check for pwm6, fan6 */
+ if (regd3 & BIT(0))
sio_data->skip_pwm |= BIT(5);
- if (reg & BIT(1))
+ if (regd3 & BIT(1))
sio_data->skip_fan |= BIT(5);
sio_data->beep_pin = superio_inb(sioaddr,
@@ -3428,6 +3458,7 @@ static void it87_init_regs(struct platform_device *pdev)
data->REG_TEMP_LOW = IT87_REG_TEMP_LOW_8686;
data->REG_TEMP_HIGH = IT87_REG_TEMP_HIGH_8686;
break;
+ case it8625:
case it8655:
case it8665:
data->REG_FAN = IT87_REG_FAN_8665;
@@ -3531,6 +3562,7 @@ static void it87_init_device(struct platform_device *pdev)
if (tmp & BIT(2))
data->has_fan |= BIT(5); /* fan6 enabled */
break;
+ case it8625:
case it8665:
tmp = it87_read_value(data, IT87_REG_FAN_DIV);
if (tmp & BIT(3))
--
2.20.1
From c5b42b5ee5fb4b9da9348d2085bf7dc07fd1581c Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Mon, 15 May 2017 21:15:55 -0700
Subject: [PATCH 25/61] Mark 2nd Super-IO chip on AB350M-D3H as broken
Configuration register access of the second Super-IO chip on AB350M-D3H
is just as broken as the others and can result in the known system hang-up.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index d1e1bff..fa95505 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -3962,6 +3962,13 @@ static const struct dmi_system_id it87_dmi_table[] __initconst = {
},
.driver_data = &gigabyte_ab350_gaming,
},
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Gigabyte Technology Co., Ltd."),
+ DMI_MATCH(DMI_BOARD_NAME, "AB350M-D3H-CF"),
+ },
+ .driver_data = &gigabyte_ab350_gaming,
+ },
{
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Gigabyte Technology Co., Ltd."),
--
2.20.1
From 837ea8bb7153a0f0aa64d8509f87b15bf8dbb5eb Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Tue, 23 May 2017 06:05:29 -0700
Subject: [PATCH 26/61] Provide blacklist module parameter to override
blacklist.
Load module with blacklist=0 to override blacklist.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index fa95505..2dad41a 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -88,6 +88,11 @@ static unsigned short force_id;
module_param(force_id, ushort, 0);
MODULE_PARM_DESC(force_id, "Override the detected device ID");
+static unsigned short blacklist = 1;
+module_param(blacklist, ushort, 0);
+MODULE_PARM_DESC(blacklist,
+ "Enable/disable blacklist (1=enable, 0=disable, default 1)");
+
static struct platform_device *it87_pdev[2];
static bool it87_sio4e_broken;
#ifdef __IT87_USE_ACPI_MUTEX
@@ -4032,10 +4037,10 @@ static int __init sm_it87_init(void)
for (i = 0; i < ARRAY_SIZE(sioaddr); i++) {
/*
- * Accessing the second Super-IO chi can result in board
+ * Accessing the second Super-IO chip can result in board
* hangs. Disable until we figure out what is going on.
*/
- if (it87_sio4e_broken && sioaddr[i] == 0x4e)
+ if (blacklist && it87_sio4e_broken && sioaddr[i] == 0x4e)
continue;
memset(&sio_data, 0, sizeof(struct it87_sio_data));
isa_address[i] = 0;
--
2.20.1
From d9135a1a4c084f3584af23dbde5fa2f710ba7007 Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Wed, 7 Jun 2017 16:56:31 -0700
Subject: [PATCH 27/61] Add support for 6 temperature limit registers on
IT8628E
IT8628E has 6 temperature limit registers, overlayed with VIN7..VIN9
limit registers, but only 3 temperature offset registers. Given that,
introduce separate variables for the number of temperature limit
registers and the number of temperature offset registers.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 40 +++++++++++++++++++++++++++++++++++-----
1 file changed, 35 insertions(+), 5 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 2dad41a..2693df4 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -363,6 +363,7 @@ struct it87_devices {
const char * const suffix;
u32 features;
u8 num_temp_limit;
+ u8 num_temp_offset;
u8 peci_mask;
u8 old_peci_mask;
};
@@ -401,6 +402,7 @@ static const struct it87_devices it87_devices[] = {
.features = FEAT_OLD_AUTOPWM | FEAT_FANCTL_ONOFF,
/* may need to overwrite */
.num_temp_limit = 3,
+ .num_temp_offset = 0,
},
[it8712] = {
.name = "it8712",
@@ -408,6 +410,7 @@ static const struct it87_devices it87_devices[] = {
.features = FEAT_OLD_AUTOPWM | FEAT_VID | FEAT_FANCTL_ONOFF,
/* may need to overwrite */
.num_temp_limit = 3,
+ .num_temp_offset = 0,
},
[it8716] = {
.name = "it8716",
@@ -416,6 +419,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_FAN16_CONFIG | FEAT_FIVE_FANS | FEAT_PWM_FREQ2
| FEAT_FANCTL_ONOFF,
.num_temp_limit = 3,
+ .num_temp_offset = 3,
},
[it8718] = {
.name = "it8718",
@@ -424,6 +428,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS
| FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF,
.num_temp_limit = 3,
+ .num_temp_offset = 3,
.old_peci_mask = 0x4,
},
[it8720] = {
@@ -433,6 +438,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS
| FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF,
.num_temp_limit = 3,
+ .num_temp_offset = 3,
.old_peci_mask = 0x4,
},
[it8721] = {
@@ -443,6 +449,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_FAN16_CONFIG | FEAT_FIVE_FANS | FEAT_IN7_INTERNAL
| FEAT_PWM_FREQ2 | FEAT_SCALING | FEAT_FANCTL_ONOFF,
.num_temp_limit = 3,
+ .num_temp_offset = 3,
.peci_mask = 0x05,
.old_peci_mask = 0x02, /* Actually reports PCH */
},
@@ -453,7 +460,8 @@ static const struct it87_devices it87_devices[] = {
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_FIVE_FANS
| FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2 | FEAT_SCALING
| FEAT_FANCTL_ONOFF,
- .num_temp_limit = 3,
+ .num_temp_limit = 6,
+ .num_temp_offset = 3,
.peci_mask = 0x07,
},
[it8732] = {
@@ -464,6 +472,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_FOUR_FANS
| FEAT_FOUR_PWM | FEAT_FANCTL_ONOFF,
.num_temp_limit = 3,
+ .num_temp_offset = 3,
.peci_mask = 0x07,
.old_peci_mask = 0x02, /* Actually reports PCH */
},
@@ -478,6 +487,7 @@ static const struct it87_devices it87_devices[] = {
/* 16 bit fans (OHM) */
/* three fans, always 16 bit (guesswork) */
.num_temp_limit = 3,
+ .num_temp_offset = 3,
.peci_mask = 0x07,
},
[it8772] = {
@@ -491,6 +501,7 @@ static const struct it87_devices it87_devices[] = {
/* 16 bit fans (HWSensors4, OHM) */
/* three fans, always 16 bit (datasheet) */
.num_temp_limit = 3,
+ .num_temp_offset = 3,
.peci_mask = 0x07,
},
[it8781] = {
@@ -500,6 +511,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_PWM_FREQ2
| FEAT_FANCTL_ONOFF,
.num_temp_limit = 3,
+ .num_temp_offset = 3,
.old_peci_mask = 0x4,
},
[it8782] = {
@@ -509,6 +521,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_PWM_FREQ2
| FEAT_FANCTL_ONOFF,
.num_temp_limit = 3,
+ .num_temp_offset = 3,
.old_peci_mask = 0x4,
},
[it8783] = {
@@ -518,6 +531,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_PWM_FREQ2
| FEAT_FANCTL_ONOFF,
.num_temp_limit = 3,
+ .num_temp_offset = 3,
.old_peci_mask = 0x4,
},
[it8786] = {
@@ -527,6 +541,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
| FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF,
.num_temp_limit = 3,
+ .num_temp_offset = 3,
.peci_mask = 0x07,
},
[it8790] = {
@@ -536,6 +551,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI
| FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF,
.num_temp_limit = 3,
+ .num_temp_offset = 3,
.peci_mask = 0x07,
},
[it8792] = {
@@ -545,6 +561,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI
| FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF,
.num_temp_limit = 3,
+ .num_temp_offset = 3,
.peci_mask = 0x07,
},
[it8603] = {
@@ -554,6 +571,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
| FEAT_AVCC3 | FEAT_PWM_FREQ2 | FEAT_SCALING,
.num_temp_limit = 3,
+ .num_temp_offset = 3,
.peci_mask = 0x07,
},
[it8607] = {
@@ -564,6 +582,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_AVCC3 | FEAT_PWM_FREQ2 | FEAT_SCALING
| FEAT_FANCTL_ONOFF,
.num_temp_limit = 3,
+ .num_temp_offset = 3,
.peci_mask = 0x07,
},
[it8613] = {
@@ -574,6 +593,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_FIVE_PWM | FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2
| FEAT_AVCC3 | FEAT_SCALING | FEAT_NEW_TEMPMAP,
.num_temp_limit = 6,
+ .num_temp_offset = 6,
.peci_mask = 0x07,
},
[it8620] = {
@@ -585,6 +605,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_SIX_TEMP | FEAT_VIN3_5V | FEAT_SCALING
| FEAT_FANCTL_ONOFF,
.num_temp_limit = 3,
+ .num_temp_offset = 3,
.peci_mask = 0x07,
},
[it8622] = {
@@ -595,6 +616,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_FIVE_PWM | FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2
| FEAT_AVCC3 | FEAT_VIN3_5V | FEAT_SCALING,
.num_temp_limit = 3,
+ .num_temp_offset = 3,
.peci_mask = 0x07,
},
[it8625] = {
@@ -605,6 +627,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_11MV_ADC | FEAT_IN7_INTERNAL | FEAT_SIX_FANS
| FEAT_SIX_PWM | FEAT_BANK_SEL | FEAT_SCALING,
.num_temp_limit = 6,
+ .num_temp_offset = 6,
},
[it8628] = {
.name = "it8628",
@@ -614,7 +637,8 @@ static const struct it87_devices it87_devices[] = {
| FEAT_IN7_INTERNAL | FEAT_SIX_PWM | FEAT_PWM_FREQ2
| FEAT_SIX_TEMP | FEAT_VIN3_5V | FEAT_SCALING | FEAT_AVCC3
| FEAT_FANCTL_ONOFF,
- .num_temp_limit = 3,
+ .num_temp_limit = 6,
+ .num_temp_offset = 3,
.peci_mask = 0x07,
},
[it8655] = {
@@ -624,6 +648,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_TEMP_OFFSET | FEAT_AVCC3 | FEAT_NEW_TEMPMAP
| FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_BANK_SEL,
.num_temp_limit = 6,
+ .num_temp_offset = 6,
},
[it8665] = {
.name = "it8665",
@@ -633,6 +658,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_SIX_FANS
| FEAT_SIX_PWM | FEAT_BANK_SEL,
.num_temp_limit = 6,
+ .num_temp_offset = 6,
},
[it8686] = {
.name = "it8686",
@@ -642,6 +668,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_IN7_INTERNAL | FEAT_SIX_PWM | FEAT_PWM_FREQ2
| FEAT_SIX_TEMP | FEAT_BANK_SEL | FEAT_SCALING | FEAT_AVCC3,
.num_temp_limit = 6,
+ .num_temp_offset = 6,
},
};
@@ -737,7 +764,8 @@ struct it87_data {
u16 fan[NUM_FAN][2]; /* Register values, [nr][0]=fan, [1]=min */
u8 has_temp; /* Bitfield, temp sensors enabled */
s8 temp[NUM_TEMP][4]; /* [nr][0]=temp, [1]=min, [2]=max, [3]=offset */
- u8 num_temp_limit; /* Number of temp limit/offset registers */
+ u8 num_temp_limit; /* Number of temperature limit registers */
+ u8 num_temp_offset; /* Number of temperature offset registers */
u8 sensor; /* Register value (IT87_REG_TEMP_ENABLE) */
u8 extra; /* Register value (IT87_REG_TEMP_EXTRA) */
u8 fan_div[NUM_FAN_DIV];/* Register encoding, shifted right */
@@ -1030,7 +1058,7 @@ static struct it87_data *it87_update_device(struct device *dev)
if (i >= data->num_temp_limit)
continue;
- if (has_temp_offset(data))
+ if (has_temp_offset(data) && i < data->num_temp_offset)
data->temp[i][3] =
it87_read_value(data,
data->REG_TEMP_OFFSET[i]);
@@ -2446,7 +2474,7 @@ static umode_t it87_temp_is_visible(struct kobject *kobj,
return attr->mode;
}
- if (a == 5 && !has_temp_offset(data))
+ if (a == 5 && (!has_temp_offset(data) || i >= data->num_temp_offset))
return 0;
if (a == 6 && !data->has_beep)
@@ -3453,6 +3481,7 @@ static void it87_init_regs(struct platform_device *pdev)
/* Initialize chip specific register pointers */
switch (data->type) {
+ case it8628:
case it8686:
data->REG_FAN = IT87_REG_FAN;
data->REG_FANX = IT87_REG_FANX;
@@ -3681,6 +3710,7 @@ static int it87_probe(struct platform_device *pdev)
data->type = sio_data->type;
data->features = it87_devices[sio_data->type].features;
data->num_temp_limit = it87_devices[sio_data->type].num_temp_limit;
+ data->num_temp_offset = it87_devices[sio_data->type].num_temp_offset;
data->peci_mask = it87_devices[sio_data->type].peci_mask;
data->old_peci_mask = it87_devices[sio_data->type].old_peci_mask;
data->bank = 0xff;
--
2.20.1
From 2804a0a27a8e2f1b29cf7eda74688cd1bcd89077 Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Wed, 7 Jun 2017 17:19:15 -0700
Subject: [PATCH 28/61] Drop FEAT_TEMP_OFFSET
Since we now count the number of temperature offset registers directly,
there is no need for the temperature offset feature flag anymore.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 54 ++++++++++++++++++++++++++----------------------------
1 file changed, 26 insertions(+), 28 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 2693df4..e530110 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -372,7 +372,6 @@ struct it87_devices {
#define FEAT_NEWER_AUTOPWM BIT(1)
#define FEAT_OLD_AUTOPWM BIT(2)
#define FEAT_16BIT_FANS BIT(3)
-#define FEAT_TEMP_OFFSET BIT(4)
#define FEAT_TEMP_PECI BIT(5)
#define FEAT_TEMP_OLD_PECI BIT(6)
#define FEAT_FAN16_CONFIG BIT(7) /* Need to enable 16-bit fans */
@@ -415,7 +414,7 @@ static const struct it87_devices it87_devices[] = {
[it8716] = {
.name = "it8716",
.suffix = "F",
- .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_VID
+ .features = FEAT_16BIT_FANS | FEAT_VID
| FEAT_FAN16_CONFIG | FEAT_FIVE_FANS | FEAT_PWM_FREQ2
| FEAT_FANCTL_ONOFF,
.num_temp_limit = 3,
@@ -424,7 +423,7 @@ static const struct it87_devices it87_devices[] = {
[it8718] = {
.name = "it8718",
.suffix = "F",
- .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_VID
+ .features = FEAT_16BIT_FANS | FEAT_VID
| FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS
| FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF,
.num_temp_limit = 3,
@@ -434,7 +433,7 @@ static const struct it87_devices it87_devices[] = {
[it8720] = {
.name = "it8720",
.suffix = "F",
- .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_VID
+ .features = FEAT_16BIT_FANS | FEAT_VID
| FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS
| FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF,
.num_temp_limit = 3,
@@ -445,7 +444,7 @@ static const struct it87_devices it87_devices[] = {
.name = "it8721",
.suffix = "F",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
- | FEAT_TEMP_OFFSET | FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI
+ | FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI
| FEAT_FAN16_CONFIG | FEAT_FIVE_FANS | FEAT_IN7_INTERNAL
| FEAT_PWM_FREQ2 | FEAT_SCALING | FEAT_FANCTL_ONOFF,
.num_temp_limit = 3,
@@ -457,7 +456,7 @@ static const struct it87_devices it87_devices[] = {
.name = "it8728",
.suffix = "F",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
- | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_FIVE_FANS
+ | FEAT_TEMP_PECI | FEAT_FIVE_FANS
| FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2 | FEAT_SCALING
| FEAT_FANCTL_ONOFF,
.num_temp_limit = 6,
@@ -468,7 +467,7 @@ static const struct it87_devices it87_devices[] = {
.name = "it8732",
.suffix = "F",
.features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS
- | FEAT_TEMP_OFFSET | FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI
+ | FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI
| FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_FOUR_FANS
| FEAT_FOUR_PWM | FEAT_FANCTL_ONOFF,
.num_temp_limit = 3,
@@ -480,7 +479,7 @@ static const struct it87_devices it87_devices[] = {
.name = "it8771",
.suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
- | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
+ | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
| FEAT_PWM_FREQ2 | FEAT_SCALING | FEAT_FANCTL_ONOFF,
/* PECI: guesswork */
/* 12mV ADC (OHM) */
@@ -494,7 +493,7 @@ static const struct it87_devices it87_devices[] = {
.name = "it8772",
.suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
- | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
+ | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
| FEAT_PWM_FREQ2 | FEAT_SCALING | FEAT_FANCTL_ONOFF,
/* PECI (coreboot) */
/* 12mV ADC (HWSensors4, OHM) */
@@ -507,7 +506,7 @@ static const struct it87_devices it87_devices[] = {
[it8781] = {
.name = "it8781",
.suffix = "F",
- .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET
+ .features = FEAT_16BIT_FANS
| FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_PWM_FREQ2
| FEAT_FANCTL_ONOFF,
.num_temp_limit = 3,
@@ -517,7 +516,7 @@ static const struct it87_devices it87_devices[] = {
[it8782] = {
.name = "it8782",
.suffix = "F",
- .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET
+ .features = FEAT_16BIT_FANS
| FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_PWM_FREQ2
| FEAT_FANCTL_ONOFF,
.num_temp_limit = 3,
@@ -527,7 +526,7 @@ static const struct it87_devices it87_devices[] = {
[it8783] = {
.name = "it8783",
.suffix = "E/F",
- .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET
+ .features = FEAT_16BIT_FANS
| FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_PWM_FREQ2
| FEAT_FANCTL_ONOFF,
.num_temp_limit = 3,
@@ -538,7 +537,7 @@ static const struct it87_devices it87_devices[] = {
.name = "it8786",
.suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
- | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
+ | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
| FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF,
.num_temp_limit = 3,
.num_temp_offset = 3,
@@ -548,7 +547,7 @@ static const struct it87_devices it87_devices[] = {
.name = "it8790",
.suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_10_9MV_ADC | FEAT_SCALING
- | FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI
+ | FEAT_16BIT_FANS | FEAT_TEMP_PECI
| FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF,
.num_temp_limit = 3,
.num_temp_offset = 3,
@@ -558,7 +557,7 @@ static const struct it87_devices it87_devices[] = {
.name = "it8792",
.suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_10_9MV_ADC | FEAT_SCALING
- | FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI
+ | FEAT_16BIT_FANS | FEAT_TEMP_PECI
| FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF,
.num_temp_limit = 3,
.num_temp_offset = 3,
@@ -568,7 +567,7 @@ static const struct it87_devices it87_devices[] = {
.name = "it8603",
.suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
- | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
+ | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
| FEAT_AVCC3 | FEAT_PWM_FREQ2 | FEAT_SCALING,
.num_temp_limit = 3,
.num_temp_offset = 3,
@@ -578,7 +577,7 @@ static const struct it87_devices it87_devices[] = {
.name = "it8607",
.suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
- | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
+ | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
| FEAT_AVCC3 | FEAT_PWM_FREQ2 | FEAT_SCALING
| FEAT_FANCTL_ONOFF,
.num_temp_limit = 3,
@@ -589,7 +588,7 @@ static const struct it87_devices it87_devices[] = {
.name = "it8613",
.suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_11MV_ADC | FEAT_16BIT_FANS
- | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_FIVE_FANS
+ | FEAT_TEMP_PECI | FEAT_FIVE_FANS
| FEAT_FIVE_PWM | FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2
| FEAT_AVCC3 | FEAT_SCALING | FEAT_NEW_TEMPMAP,
.num_temp_limit = 6,
@@ -600,7 +599,7 @@ static const struct it87_devices it87_devices[] = {
.name = "it8620",
.suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
- | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_SIX_FANS
+ | FEAT_TEMP_PECI | FEAT_SIX_FANS
| FEAT_IN7_INTERNAL | FEAT_SIX_PWM | FEAT_PWM_FREQ2
| FEAT_SIX_TEMP | FEAT_VIN3_5V | FEAT_SCALING
| FEAT_FANCTL_ONOFF,
@@ -612,7 +611,7 @@ static const struct it87_devices it87_devices[] = {
.name = "it8622",
.suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
- | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_FIVE_FANS
+ | FEAT_TEMP_PECI | FEAT_FIVE_FANS
| FEAT_FIVE_PWM | FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2
| FEAT_AVCC3 | FEAT_VIN3_5V | FEAT_SCALING,
.num_temp_limit = 3,
@@ -623,7 +622,7 @@ static const struct it87_devices it87_devices[] = {
.name = "it8625",
.suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS
- | FEAT_TEMP_OFFSET | FEAT_AVCC3 | FEAT_NEW_TEMPMAP
+ | FEAT_AVCC3 | FEAT_NEW_TEMPMAP
| FEAT_11MV_ADC | FEAT_IN7_INTERNAL | FEAT_SIX_FANS
| FEAT_SIX_PWM | FEAT_BANK_SEL | FEAT_SCALING,
.num_temp_limit = 6,
@@ -633,7 +632,7 @@ static const struct it87_devices it87_devices[] = {
.name = "it8628",
.suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
- | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_SIX_FANS
+ | FEAT_TEMP_PECI | FEAT_SIX_FANS
| FEAT_IN7_INTERNAL | FEAT_SIX_PWM | FEAT_PWM_FREQ2
| FEAT_SIX_TEMP | FEAT_VIN3_5V | FEAT_SCALING | FEAT_AVCC3
| FEAT_FANCTL_ONOFF,
@@ -645,7 +644,7 @@ static const struct it87_devices it87_devices[] = {
.name = "it8655",
.suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS
- | FEAT_TEMP_OFFSET | FEAT_AVCC3 | FEAT_NEW_TEMPMAP
+ | FEAT_AVCC3 | FEAT_NEW_TEMPMAP
| FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_BANK_SEL,
.num_temp_limit = 6,
.num_temp_offset = 6,
@@ -654,7 +653,7 @@ static const struct it87_devices it87_devices[] = {
.name = "it8665",
.suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS
- | FEAT_TEMP_OFFSET | FEAT_AVCC3 | FEAT_NEW_TEMPMAP
+ | FEAT_AVCC3 | FEAT_NEW_TEMPMAP
| FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_SIX_FANS
| FEAT_SIX_PWM | FEAT_BANK_SEL,
.num_temp_limit = 6,
@@ -664,7 +663,7 @@ static const struct it87_devices it87_devices[] = {
.name = "it8686",
.suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
- | FEAT_TEMP_OFFSET | FEAT_SIX_FANS | FEAT_NEW_TEMPMAP
+ | FEAT_SIX_FANS | FEAT_NEW_TEMPMAP
| FEAT_IN7_INTERNAL | FEAT_SIX_PWM | FEAT_PWM_FREQ2
| FEAT_SIX_TEMP | FEAT_BANK_SEL | FEAT_SCALING | FEAT_AVCC3,
.num_temp_limit = 6,
@@ -677,7 +676,6 @@ static const struct it87_devices it87_devices[] = {
#define has_10_9mv_adc(data) ((data)->features & FEAT_10_9MV_ADC)
#define has_newer_autopwm(data) ((data)->features & FEAT_NEWER_AUTOPWM)
#define has_old_autopwm(data) ((data)->features & FEAT_OLD_AUTOPWM)
-#define has_temp_offset(data) ((data)->features & FEAT_TEMP_OFFSET)
#define has_temp_peci(data, nr) (((data)->features & FEAT_TEMP_PECI) && \
((data)->peci_mask & BIT(nr)))
#define has_temp_old_peci(data, nr) \
@@ -1058,7 +1056,7 @@ static struct it87_data *it87_update_device(struct device *dev)
if (i >= data->num_temp_limit)
continue;
- if (has_temp_offset(data) && i < data->num_temp_offset)
+ if (i < data->num_temp_offset)
data->temp[i][3] =
it87_read_value(data,
data->REG_TEMP_OFFSET[i]);
@@ -2474,7 +2472,7 @@ static umode_t it87_temp_is_visible(struct kobject *kobj,
return attr->mode;
}
- if (a == 5 && (!has_temp_offset(data) || i >= data->num_temp_offset))
+ if (a == 5 && i >= data->num_temp_offset)
return 0;
if (a == 6 && !data->has_beep)
--
2.20.1
From d8946f799dffd1afef1702d7bb524b11a1e4870a Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Sun, 23 Jul 2017 07:29:38 -0700
Subject: [PATCH 29/61] IT8607 does not support the 1st fan, only fan2-3
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index e530110..7dcb589 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -3043,9 +3043,16 @@ static int __init it87_find(int sioaddr, unsigned short *address,
if (reg29 & BIT(2))
sio_data->skip_fan |= BIT(1);
- if (sio_data->type == it8603) {
+ switch (sio_data->type) {
+ case it8603:
sio_data->skip_in |= BIT(5); /* No VIN5 */
sio_data->skip_in |= BIT(6); /* No VIN6 */
+ break;
+ case it8607:
+ sio_data->skip_pwm |= BIT(0);/* No fan1 */
+ sio_data->skip_fan |= BIT(0);
+ default:
+ break;
}
sio_data->beep_pin = superio_inb(sioaddr,
--
2.20.1
From 95990b21cba07386575d3929c9fd6cc3bad73f03 Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Sat, 5 Aug 2017 12:48:49 -0700
Subject: [PATCH 30/61] Fix accesses to IT8792E
If IT8792E or a compatible chip such as IT8795 (which has the same chip ID,
0x8733) resides at SIO address 0x4e/0x4f, and another Super-IO chip is at
SIO address 0x2e/0x2f, the IT8792E causes a cycle decode problem when exiting
its configuration mode. This can result in access errors for both chips, and
may result in system hangs.
Never exit configuration mode for IT8792E to avoid the problem.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 45 ++++++++++++++++-----------------------------
1 file changed, 16 insertions(+), 29 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 7dcb589..a6001b7 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -88,13 +88,7 @@ static unsigned short force_id;
module_param(force_id, ushort, 0);
MODULE_PARM_DESC(force_id, "Override the detected device ID");
-static unsigned short blacklist = 1;
-module_param(blacklist, ushort, 0);
-MODULE_PARM_DESC(blacklist,
- "Enable/disable blacklist (1=enable, 0=disable, default 1)");
-
static struct platform_device *it87_pdev[2];
-static bool it87_sio4e_broken;
#ifdef __IT87_USE_ACPI_MUTEX
static acpi_handle it87_acpi_sio_handle;
static char *it87_acpi_sio_mutex;
@@ -126,12 +120,6 @@ static inline int superio_inb(int ioreg, int reg)
outb(reg, ioreg);
val = inb(ioreg + 1);
- if (it87_sio4e_broken && ioreg == 0x4e && val == 0xff) {
- __superio_enter(ioreg);
- outb(reg, ioreg);
- val = inb(ioreg + 1);
- pr_warn("Retry access 0x4e:0x%x -> 0x%x\n", reg, val);
- }
return val;
}
@@ -183,9 +171,9 @@ error:
return -EBUSY;
}
-static inline void superio_exit(int ioreg)
+static inline void superio_exit(int ioreg, bool doexit)
{
- if (!it87_sio4e_broken || ioreg != 0x4e) {
+ if (doexit) {
outb(0x02, ioreg);
outb(0x02, ioreg + 1);
}
@@ -2801,9 +2789,10 @@ static const struct attribute_group it87_group_auto_pwm = {
static int __init it87_find(int sioaddr, unsigned short *address,
struct it87_sio_data *sio_data)
{
- int err;
- u16 chip_type;
const struct it87_devices *config;
+ bool doexit = true;
+ u16 chip_type;
+ int err;
err = superio_enter(sioaddr);
if (err)
@@ -2845,6 +2834,13 @@ static int __init it87_find(int sioaddr, unsigned short *address,
break;
case IT8792E_DEVID:
sio_data->type = it8792;
+ /*
+ * Disabling configuration mode on IT8792E can result in system
+ * hang-ups and access failures to the Super-IO chip at the
+ * second SIO address. Never exit configuration mode on this
+ * chip to avoid the problem.
+ */
+ doexit = false;
break;
case IT8771E_DEVID:
sio_data->type = it8771;
@@ -3399,7 +3395,7 @@ static int __init it87_find(int sioaddr, unsigned short *address,
pr_info("Beeping is supported\n");
exit:
- superio_exit(sioaddr);
+ superio_exit(sioaddr, doexit);
return err;
}
@@ -3872,7 +3868,8 @@ static void __maybe_unused it87_resume_sio(struct platform_device *pdev)
reg2c);
}
- superio_exit(data->sioaddr);
+ /* Don't exit configuration mode for IT8792E */
+ superio_exit(data->sioaddr, data->type != it8792);
}
static int __maybe_unused it87_resume(struct device *dev)
@@ -3960,18 +3957,15 @@ exit_device_put:
}
struct it87_dmi_data {
- bool sio4e_broken; /* SIO accesses @ 0x4e are broken */
char *sio_mutex; /* SIO ACPI mutex */
u8 skip_pwm; /* pwm channels to skip for this board */
};
/*
* On Gigabyte AB350 and AX370 boards, accesses to the Super-IO chip
- * at address 0x4e/0x4f can result in a system hang.
- * Accesses to address 0x2e/0x2f need to be mutex protected.
+ * at address 0x2e/0x2f need to be mutex protected.
*/
static struct it87_dmi_data gigabyte_ab350_gaming = {
- .sio4e_broken = true,
.sio_mutex = "\\_SB.PCI0.SBRG.SIO1.MUT0",
};
@@ -4047,7 +4041,6 @@ static int __init sm_it87_init(void)
dmi_data = dmi->driver_data;
if (dmi_data) {
- it87_sio4e_broken = dmi_data->sio4e_broken;
#ifdef __IT87_USE_ACPI_MUTEX
if (dmi_data->sio_mutex) {
static acpi_status status;
@@ -4071,12 +4064,6 @@ static int __init sm_it87_init(void)
return err;
for (i = 0; i < ARRAY_SIZE(sioaddr); i++) {
- /*
- * Accessing the second Super-IO chip can result in board
- * hangs. Disable until we figure out what is going on.
- */
- if (blacklist && it87_sio4e_broken && sioaddr[i] == 0x4e)
- continue;
memset(&sio_data, 0, sizeof(struct it87_sio_data));
isa_address[i] = 0;
err = it87_find(sioaddr[i], &isa_address[i], &sio_data);
--
2.20.1
From 8998c62d51eb122f12f3007b7c44ee1b70c85772 Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Sun, 6 Aug 2017 14:06:29 -0700
Subject: [PATCH 31/61] Drop ACPI mutex code SPLIT,SQUASH
The observed problems with IT8792E were after all not caused by ACPI
mutex problems, so drop that code for now.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 89 ----------------------------------------------------------
1 file changed, 89 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index a6001b7..215286d 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -76,9 +76,6 @@
#define DRVNAME "it87"
-/* Necessary API not (yet) exported in upstream kernel */
-/* #define __IT87_USE_ACPI_MUTEX */
-
enum chips { it87, it8712, it8716, it8718, it8720, it8721, it8728, it8732,
it8771, it8772, it8781, it8782, it8783, it8786, it8790,
it8792, it8603, it8607, it8613, it8620, it8622, it8625, it8628,
@@ -89,10 +86,6 @@ module_param(force_id, ushort, 0);
MODULE_PARM_DESC(force_id, "Override the detected device ID");
static struct platform_device *it87_pdev[2];
-#ifdef __IT87_USE_ACPI_MUTEX
-static acpi_handle it87_acpi_sio_handle;
-static char *it87_acpi_sio_mutex;
-#endif
#define REG_2E 0x2e /* The register to read/write */
#define REG_4E 0x4e /* Secondary register to read/write */
@@ -143,17 +136,6 @@ static inline void superio_select(int ioreg, int ldn)
static inline int superio_enter(int ioreg)
{
-#ifdef __IT87_USE_ACPI_MUTEX
- if (it87_acpi_sio_mutex) {
- acpi_status status;
-
- status = acpi_acquire_mutex(NULL, it87_acpi_sio_mutex, 0x10);
- if (ACPI_FAILURE(status)) {
- pr_err("Failed to acquire ACPI mutex\n");
- return -EBUSY;
- }
- }
-#endif
/*
* Try to reserve ioreg and ioreg + 1 for exclusive access.
*/
@@ -164,10 +146,6 @@ static inline int superio_enter(int ioreg)
return 0;
error:
-#ifdef __IT87_USE_ACPI_MUTEX
- if (it87_acpi_sio_mutex)
- acpi_release_mutex(it87_acpi_sio_handle, NULL);
-#endif
return -EBUSY;
}
@@ -178,10 +156,6 @@ static inline void superio_exit(int ioreg, bool doexit)
outb(0x02, ioreg + 1);
}
release_region(ioreg, 2);
-#ifdef __IT87_USE_ACPI_MUTEX
- if (it87_acpi_sio_mutex)
- acpi_release_mutex(it87_acpi_sio_handle, NULL);
-#endif
}
/* Logical device 4 registers */
@@ -3957,18 +3931,9 @@ exit_device_put:
}
struct it87_dmi_data {
- char *sio_mutex; /* SIO ACPI mutex */
u8 skip_pwm; /* pwm channels to skip for this board */
};
-/*
- * On Gigabyte AB350 and AX370 boards, accesses to the Super-IO chip
- * at address 0x2e/0x2f need to be mutex protected.
- */
-static struct it87_dmi_data gigabyte_ab350_gaming = {
- .sio_mutex = "\\_SB.PCI0.SBRG.SIO1.MUT0",
-};
-
/*
* On the Shuttle SN68PT, FAN_CTL2 is apparently not
* connected to a fan, but to something else. One user
@@ -3982,41 +3947,6 @@ static struct it87_dmi_data nvidia_fn68pt = {
};
static const struct dmi_system_id it87_dmi_table[] __initconst = {
- {
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Gigabyte Technology Co., Ltd."),
- DMI_MATCH(DMI_BOARD_NAME, "AB350-Gaming-CF"),
- },
- .driver_data = &gigabyte_ab350_gaming,
- },
- {
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Gigabyte Technology Co., Ltd."),
- DMI_MATCH(DMI_BOARD_NAME, "AB350-Gaming 3-CF"),
- },
- .driver_data = &gigabyte_ab350_gaming,
- },
- {
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Gigabyte Technology Co., Ltd."),
- DMI_MATCH(DMI_BOARD_NAME, "AB350M-D3H-CF"),
- },
- .driver_data = &gigabyte_ab350_gaming,
- },
- {
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Gigabyte Technology Co., Ltd."),
- DMI_MATCH(DMI_BOARD_NAME, "AX370-Gaming K7"),
- },
- .driver_data = &gigabyte_ab350_gaming,
- },
- {
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Gigabyte Technology Co., Ltd."),
- DMI_MATCH(DMI_BOARD_NAME, "AX370-Gaming 5"),
- },
- .driver_data = &gigabyte_ab350_gaming,
- },
{
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "nVIDIA"),
@@ -4040,25 +3970,6 @@ static int __init sm_it87_init(void)
if (dmi)
dmi_data = dmi->driver_data;
- if (dmi_data) {
-#ifdef __IT87_USE_ACPI_MUTEX
- if (dmi_data->sio_mutex) {
- static acpi_status status;
-
- status = acpi_get_handle(NULL, dmi_data->sio_mutex,
- &it87_acpi_sio_handle);
- if (ACPI_SUCCESS(status)) {
- it87_acpi_sio_mutex = dmi_data->sio_mutex;
- pr_debug("Found ACPI SIO mutex %s\n",
- dmi_data->sio_mutex);
- } else {
- pr_warn("ACPI SIO mutex %s not found\n",
- dmi_data->sio_mutex);
- }
- }
-#endif /* __IT87_USE_ACPI_MUTEX */
- }
-
err = platform_driver_register(&it87_driver);
if (err)
return err;
--
2.20.1
From 703b6e2b3ff9a148cbe66b9117c7a0fb16b81317 Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Sun, 6 Aug 2017 15:00:33 -0700
Subject: [PATCH 32/61] Force IT8790E and IT8792E into configuration mode
IT8790E and IT8792E need to be in configuration mode to avoid LPC bus errors.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 215286d..6f011b7 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -2836,6 +2836,7 @@ static int __init it87_find(int sioaddr, unsigned short *address,
break;
case IT8790E_DEVID:
sio_data->type = it8790;
+ doexit = false; /* See IT8792E comment above */
break;
case IT8603E_DEVID:
case IT8623E_DEVID:
@@ -3931,9 +3932,28 @@ exit_device_put:
}
struct it87_dmi_data {
+ bool sio2_force_config; /* force sio2 into configuration mode */
u8 skip_pwm; /* pwm channels to skip for this board */
};
+/*
+ * On various Gigabyte AM4 boards (AB350, AX370), the second Super-IO chip
+ * (IT8792E) needs to be in configuration mode before accessing the first
+ * due to a bug in IT8792E which otherwise results in LPC bus access errors.
+ * This needs to be done before accessing the first Super-IO chip since
+ * the second chip may have been accessed prior to loading this driver.
+ *
+ * The problem is also reported to affect IT8795E, which is used on X299 boards
+ * and has the same chip ID as IT9792E (0x8733). It also appears to affect
+ * systems with IT8790E, which is used on some Z97X-Gaming boards as well as
+ * Z87X-OC.
+ * DMI entries for those systems will be added as they become available and
+ * as the problem is confirmed to affect those boards.
+ */
+static struct it87_dmi_data gigabyte_sio2_force = {
+ .sio2_force_config = true,
+};
+
/*
* On the Shuttle SN68PT, FAN_CTL2 is apparently not
* connected to a fan, but to something else. One user
@@ -3947,6 +3967,27 @@ static struct it87_dmi_data nvidia_fn68pt = {
};
static const struct dmi_system_id it87_dmi_table[] __initconst = {
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Gigabyte Technology Co., Ltd."),
+ DMI_MATCH(DMI_BOARD_NAME, "AB350"),
+ },
+ .driver_data = &gigabyte_sio2_force,
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Gigabyte Technology Co., Ltd."),
+ DMI_MATCH(DMI_BOARD_NAME, "AX370"),
+ },
+ .driver_data = &gigabyte_sio2_force,
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Gigabyte Technology Co., Ltd."),
+ DMI_MATCH(DMI_BOARD_NAME, "Z97X-Gaming G1"),
+ },
+ .driver_data = &gigabyte_sio2_force,
+ },
{
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "nVIDIA"),
@@ -3974,6 +4015,9 @@ static int __init sm_it87_init(void)
if (err)
return err;
+ if (dmi_data && dmi_data->sio2_force_config)
+ __superio_enter(REG_4E);
+
for (i = 0; i < ARRAY_SIZE(sioaddr); i++) {
memset(&sio_data, 0, sizeof(struct it87_sio_data));
isa_address[i] = 0;
--
2.20.1
From 923c3e01f145b960cef40e784f53e538883717a0 Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Tue, 8 Aug 2017 06:35:46 -0700
Subject: [PATCH 33/61] IT8655E and IT8665E both support internal register
scaling SQUASH
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 6f011b7..a1fd12b 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -606,7 +606,7 @@ static const struct it87_devices it87_devices[] = {
.name = "it8655",
.suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS
- | FEAT_AVCC3 | FEAT_NEW_TEMPMAP
+ | FEAT_AVCC3 | FEAT_NEW_TEMPMAP | FEAT_SCALING
| FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_BANK_SEL,
.num_temp_limit = 6,
.num_temp_offset = 6,
@@ -615,7 +615,7 @@ static const struct it87_devices it87_devices[] = {
.name = "it8665",
.suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS
- | FEAT_AVCC3 | FEAT_NEW_TEMPMAP
+ | FEAT_AVCC3 | FEAT_NEW_TEMPMAP | FEAT_SCALING
| FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_SIX_FANS
| FEAT_SIX_PWM | FEAT_BANK_SEL,
.num_temp_limit = 6,
--
2.20.1
From 5b164e9ed9a6d309f2a5984226ca5f85378dfb02 Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Sun, 3 Sep 2017 13:58:47 -0700
Subject: [PATCH 34/61] Update pwm cached control registers before writing pwm
enable
If pwmX_enable is written prior to displaying any attributes,
t87_update_pwm_ctrl() is never called, and the cached pwm registers
are never read before written. This results in bad values written
into various registers, and can result in operational failures.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index a1fd12b..3aaf9b7 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -1626,6 +1626,7 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr,
}
mutex_lock(&data->update_lock);
+ it87_update_pwm_ctrl(data, nr);
if (val == 0) {
if (nr < 3 && has_fanctl_onoff(data)) {
--
2.20.1
From 5a77719e7cea35d09d6b003c198752aaaccc2d78 Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Mon, 4 Sep 2017 08:27:19 -0700
Subject: [PATCH 35/61] Rework pwm temperature mapping
Various chips have different numbers of valid values for pwm temperature
mapping. Rework the code to take this into account.
No longer keep map as bitmap, but maintain it as number 1..X. Do not try to
define a separate mapping entry for pwm4..6 on chips where the temperature
map for those pwm controls is taken from a different temperature input.
Introduce helpers to convert the control register contents to a map and
vice versa.
Reflect that IT8607 uses the new temperature map in bit 3..5 of the pwm
control register.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 154 +++++++++++++++++++++++++++++++--------------------------
1 file changed, 85 insertions(+), 69 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 3aaf9b7..fc0583f 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -326,6 +326,7 @@ struct it87_devices {
u32 features;
u8 num_temp_limit;
u8 num_temp_offset;
+ u8 num_temp_map; /* Number of temperature sources for pwm */
u8 peci_mask;
u8 old_peci_mask;
};
@@ -364,6 +365,7 @@ static const struct it87_devices it87_devices[] = {
/* may need to overwrite */
.num_temp_limit = 3,
.num_temp_offset = 0,
+ .num_temp_map = 3,
},
[it8712] = {
.name = "it8712",
@@ -372,6 +374,7 @@ static const struct it87_devices it87_devices[] = {
/* may need to overwrite */
.num_temp_limit = 3,
.num_temp_offset = 0,
+ .num_temp_map = 3,
},
[it8716] = {
.name = "it8716",
@@ -381,6 +384,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_FANCTL_ONOFF,
.num_temp_limit = 3,
.num_temp_offset = 3,
+ .num_temp_map = 3,
},
[it8718] = {
.name = "it8718",
@@ -390,6 +394,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF,
.num_temp_limit = 3,
.num_temp_offset = 3,
+ .num_temp_map = 3,
.old_peci_mask = 0x4,
},
[it8720] = {
@@ -400,6 +405,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF,
.num_temp_limit = 3,
.num_temp_offset = 3,
+ .num_temp_map = 3,
.old_peci_mask = 0x4,
},
[it8721] = {
@@ -411,6 +417,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_PWM_FREQ2 | FEAT_SCALING | FEAT_FANCTL_ONOFF,
.num_temp_limit = 3,
.num_temp_offset = 3,
+ .num_temp_map = 3,
.peci_mask = 0x05,
.old_peci_mask = 0x02, /* Actually reports PCH */
},
@@ -423,6 +430,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_FANCTL_ONOFF,
.num_temp_limit = 6,
.num_temp_offset = 3,
+ .num_temp_map = 3,
.peci_mask = 0x07,
},
[it8732] = {
@@ -434,6 +442,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_FOUR_PWM | FEAT_FANCTL_ONOFF,
.num_temp_limit = 3,
.num_temp_offset = 3,
+ .num_temp_map = 3,
.peci_mask = 0x07,
.old_peci_mask = 0x02, /* Actually reports PCH */
},
@@ -449,6 +458,7 @@ static const struct it87_devices it87_devices[] = {
/* three fans, always 16 bit (guesswork) */
.num_temp_limit = 3,
.num_temp_offset = 3,
+ .num_temp_map = 3,
.peci_mask = 0x07,
},
[it8772] = {
@@ -463,6 +473,7 @@ static const struct it87_devices it87_devices[] = {
/* three fans, always 16 bit (datasheet) */
.num_temp_limit = 3,
.num_temp_offset = 3,
+ .num_temp_map = 3,
.peci_mask = 0x07,
},
[it8781] = {
@@ -473,6 +484,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_FANCTL_ONOFF,
.num_temp_limit = 3,
.num_temp_offset = 3,
+ .num_temp_map = 3,
.old_peci_mask = 0x4,
},
[it8782] = {
@@ -483,6 +495,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_FANCTL_ONOFF,
.num_temp_limit = 3,
.num_temp_offset = 3,
+ .num_temp_map = 3,
.old_peci_mask = 0x4,
},
[it8783] = {
@@ -493,6 +506,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_FANCTL_ONOFF,
.num_temp_limit = 3,
.num_temp_offset = 3,
+ .num_temp_map = 3,
.old_peci_mask = 0x4,
},
[it8786] = {
@@ -503,6 +517,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF,
.num_temp_limit = 3,
.num_temp_offset = 3,
+ .num_temp_map = 3,
.peci_mask = 0x07,
},
[it8790] = {
@@ -513,6 +528,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF,
.num_temp_limit = 3,
.num_temp_offset = 3,
+ .num_temp_map = 3,
.peci_mask = 0x07,
},
[it8792] = {
@@ -523,6 +539,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF,
.num_temp_limit = 3,
.num_temp_offset = 3,
+ .num_temp_map = 3,
.peci_mask = 0x07,
},
[it8603] = {
@@ -533,17 +550,19 @@ static const struct it87_devices it87_devices[] = {
| FEAT_AVCC3 | FEAT_PWM_FREQ2 | FEAT_SCALING,
.num_temp_limit = 3,
.num_temp_offset = 3,
+ .num_temp_map = 4,
.peci_mask = 0x07,
},
[it8607] = {
.name = "it8607",
.suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
- | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
+ | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL | FEAT_NEW_TEMPMAP
| FEAT_AVCC3 | FEAT_PWM_FREQ2 | FEAT_SCALING
| FEAT_FANCTL_ONOFF,
.num_temp_limit = 3,
.num_temp_offset = 3,
+ .num_temp_map = 6,
.peci_mask = 0x07,
},
[it8613] = {
@@ -555,6 +574,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_AVCC3 | FEAT_SCALING | FEAT_NEW_TEMPMAP,
.num_temp_limit = 6,
.num_temp_offset = 6,
+ .num_temp_map = 6,
.peci_mask = 0x07,
},
[it8620] = {
@@ -567,6 +587,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_FANCTL_ONOFF,
.num_temp_limit = 3,
.num_temp_offset = 3,
+ .num_temp_map = 3,
.peci_mask = 0x07,
},
[it8622] = {
@@ -578,6 +599,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_AVCC3 | FEAT_VIN3_5V | FEAT_SCALING,
.num_temp_limit = 3,
.num_temp_offset = 3,
+ .num_temp_map = 4,
.peci_mask = 0x07,
},
[it8625] = {
@@ -589,6 +611,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_SIX_PWM | FEAT_BANK_SEL | FEAT_SCALING,
.num_temp_limit = 6,
.num_temp_offset = 6,
+ .num_temp_map = 6,
},
[it8628] = {
.name = "it8628",
@@ -600,6 +623,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_FANCTL_ONOFF,
.num_temp_limit = 6,
.num_temp_offset = 3,
+ .num_temp_map = 3,
.peci_mask = 0x07,
},
[it8655] = {
@@ -610,6 +634,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_BANK_SEL,
.num_temp_limit = 6,
.num_temp_offset = 6,
+ .num_temp_map = 6,
},
[it8665] = {
.name = "it8665",
@@ -620,6 +645,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_SIX_PWM | FEAT_BANK_SEL,
.num_temp_limit = 6,
.num_temp_offset = 6,
+ .num_temp_map = 6,
},
[it8686] = {
.name = "it8686",
@@ -630,6 +656,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_SIX_TEMP | FEAT_BANK_SEL | FEAT_SCALING | FEAT_AVCC3,
.num_temp_limit = 6,
.num_temp_offset = 6,
+ .num_temp_map = 7,
},
};
@@ -752,6 +779,9 @@ struct it87_data {
u8 pwm_ctrl[NUM_PWM]; /* Register value */
u8 pwm_duty[NUM_PWM]; /* Manual PWM value set by user */
u8 pwm_temp_map[NUM_PWM];/* PWM to temp. chan. mapping (bits 1-0) */
+ u8 pwm_temp_map_mask; /* 0x03 for old, 0x07 for new temp map */
+ u8 pwm_temp_map_shift; /* 0 for old, 3 for new temp map */
+ u8 pwm_num_temp_map; /* from config data, 3..7 depending on chip */
/* Automatic fan speed control registers */
u8 auto_pwm[NUM_AUTO_PWM][4]; /* [nr][3] is hard-coded */
@@ -838,6 +868,25 @@ static int DIV_TO_REG(int val)
#define DIV_FROM_REG(val) BIT(val)
+static u8 temp_map_from_reg(const struct it87_data *data, u8 reg)
+{
+ u8 map;
+
+ map = (reg >> data->pwm_temp_map_shift) & data->pwm_temp_map_mask;
+ if (map >= data->pwm_num_temp_map) /* map is 0-based */
+ map = 0;
+
+ return map;
+}
+
+static u8 temp_map_to_reg(const struct it87_data *data, int nr, u8 map)
+{
+ u8 ctrl = data->pwm_ctrl[nr];
+
+ return (ctrl & ~(data->pwm_temp_map_mask << data->pwm_temp_map_shift)) |
+ (map << data->pwm_temp_map_shift);
+}
+
/*
* PWM base frequencies. The frequency has to be divided by either 128 or 256,
* depending on the chip type, to calculate the actual PWM frequency.
@@ -907,19 +956,19 @@ static void it87_write_value(struct it87_data *data, u16 reg, u8 value)
static void it87_update_pwm_ctrl(struct it87_data *data, int nr)
{
- data->pwm_ctrl[nr] = it87_read_value(data, data->REG_PWM[nr]);
+ u8 ctrl;
+
+ ctrl = it87_read_value(data, data->REG_PWM[nr]);
+ data->pwm_ctrl[nr] = ctrl;
if (has_newer_autopwm(data)) {
- if (has_new_tempmap(data))
- data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x38;
- else
- data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03;
+ data->pwm_temp_map[nr] = temp_map_from_reg(data, ctrl);
data->pwm_duty[nr] = it87_read_value(data,
IT87_REG_PWM_DUTY[nr]);
} else {
- if (data->pwm_ctrl[nr] & 0x80) /* Automatic mode */
- data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03;
+ if (ctrl & 0x80) /* Automatic mode */
+ data->pwm_temp_map[nr] = temp_map_from_reg(data, ctrl);
else /* Manual mode */
- data->pwm_duty[nr] = data->pwm_ctrl[nr] & 0x7f;
+ data->pwm_duty[nr] = ctrl & 0x7f;
}
if (has_old_autopwm(data)) {
@@ -1647,8 +1696,9 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr,
data->pwm_duty[nr]);
/* and set manual mode */
if (has_newer_autopwm(data)) {
- ctrl = (data->pwm_ctrl[nr] & 0x7c) |
- data->pwm_temp_map[nr];
+ ctrl = temp_map_to_reg(data, nr,
+ data->pwm_temp_map[nr]);
+ ctrl &= 0x7f;
} else {
ctrl = data->pwm_duty[nr];
}
@@ -1659,9 +1709,11 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr,
u8 ctrl;
if (has_newer_autopwm(data)) {
- ctrl = (data->pwm_ctrl[nr] & 0x7c) |
- data->pwm_temp_map[nr];
- if (val != 1)
+ ctrl = temp_map_to_reg(data, nr,
+ data->pwm_temp_map[nr]);
+ if (val == 1)
+ ctrl &= 0x7f;
+ else
ctrl |= 0x80;
} else {
ctrl = (val == 1 ? data->pwm_duty[nr] : 0x80);
@@ -1764,21 +1816,8 @@ static ssize_t show_pwm_temp_map(struct device *dev,
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
struct it87_data *data = it87_update_device(dev);
int nr = sensor_attr->index;
- int map;
- map = data->pwm_temp_map[nr];
- if (has_new_tempmap(data)) {
- map >>= 3;
- if (map >= 6)
- map = 0; /* Should never happen */
- } else {
- if (map >= 3)
- map = 0; /* Should never happen */
- if (nr >= 3) /* pwm channels 3..6 map to temp4..6 */
- map += 3;
- }
-
- return sprintf(buf, "%d\n", (int)BIT(map));
+ return sprintf(buf, "%d\n", data->pwm_temp_map[nr] + 1);
}
static ssize_t set_pwm_temp_map(struct device *dev,
@@ -1788,58 +1827,26 @@ static ssize_t set_pwm_temp_map(struct device *dev,
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
struct it87_data *data = dev_get_drvdata(dev);
int nr = sensor_attr->index;
- long val;
- u8 reg;
+ unsigned long val;
+ u8 map;
- if (kstrtol(buf, 10, &val) < 0)
+ if (kstrtoul(buf, 10, &val) < 0)
return -EINVAL;
- if (nr >= 3 && !has_new_tempmap(data))
- val -= 3;
-
- switch (val) {
- case BIT(0):
- reg = 0x00;
- break;
- case BIT(1):
- reg = 0x01;
- break;
- case BIT(2):
- reg = 0x02;
- break;
- case BIT(3):
- reg = 0x03;
- break;
- case BIT(4):
- reg = 0x04;
- break;
- case BIT(5):
- reg = 0x05;
- break;
- case BIT(6):
- reg = 0x06;
- break;
- default:
+ if (!val || val > data->pwm_num_temp_map)
return -EINVAL;
- }
- if (has_new_tempmap(data))
- reg <<= 3;
- else if (reg > 0x02)
- return -EINVAL;
+ map = val - 1;
mutex_lock(&data->update_lock);
it87_update_pwm_ctrl(data, nr);
- data->pwm_temp_map[nr] = reg;
+ data->pwm_temp_map[nr] = map;
/*
* If we are in automatic mode, write the temp mapping immediately;
* otherwise, just store it for later use.
*/
if (data->pwm_ctrl[nr] & 0x80) {
- u8 mask = has_new_tempmap(data) ? 0xc7 : 0xfc;
-
- data->pwm_ctrl[nr] = (data->pwm_ctrl[nr] & mask) |
- data->pwm_temp_map[nr];
+ data->pwm_ctrl[nr] = temp_map_to_reg(data, nr, map);
it87_write_value(data, data->REG_PWM[nr], data->pwm_ctrl[nr]);
}
mutex_unlock(&data->update_lock);
@@ -3521,13 +3528,21 @@ static void it87_init_device(struct platform_device *pdev)
struct it87_data *data = platform_get_drvdata(pdev);
int tmp, i;
+ if (has_new_tempmap(data)) {
+ data->pwm_temp_map_shift = 3;
+ data->pwm_temp_map_mask = 0x07;
+ } else {
+ data->pwm_temp_map_shift = 0;
+ data->pwm_temp_map_mask = 0x03;
+ }
+
/*
* For each PWM channel:
* - If it is in automatic mode, setting to manual mode should set
* the fan to full speed by default.
* - If it is in manual mode, we need a mapping to temperature
* channels to use when later setting to automatic mode later.
- * Use a 1:1 mapping by default (we are clueless.)
+ * Map to the first sensor by default (we are clueless.)
* In both cases, the value can (and should) be changed by the user
* prior to switching to a different mode.
* Note that this is no longer needed for the IT8721F and later, as
@@ -3535,7 +3550,7 @@ static void it87_init_device(struct platform_device *pdev)
* manual duty cycle.
*/
for (i = 0; i < NUM_AUTO_PWM; i++) {
- data->pwm_temp_map[i] = i;
+ data->pwm_temp_map[i] = 0;
data->pwm_duty[i] = 0x7f; /* Full speed */
data->auto_pwm[i][3] = 0x7f; /* Full speed, hard-coded */
}
@@ -3688,6 +3703,7 @@ static int it87_probe(struct platform_device *pdev)
data->features = it87_devices[sio_data->type].features;
data->num_temp_limit = it87_devices[sio_data->type].num_temp_limit;
data->num_temp_offset = it87_devices[sio_data->type].num_temp_offset;
+ data->pwm_num_temp_map = it87_devices[sio_data->type].num_temp_map;
data->peci_mask = it87_devices[sio_data->type].peci_mask;
data->old_peci_mask = it87_devices[sio_data->type].old_peci_mask;
data->bank = 0xff;
--
2.20.1
From 582d8d1ce66115fc36f95ad73cfbb6bfdeca9dc6 Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Wed, 20 Sep 2017 15:19:33 -0700
Subject: [PATCH 36/61] Add 'ignore_resource_conflict' error
It appears that some BIOSes reserve ACPI resources without using them,
and acpi_enable_resources=lax seems to result in failures to load
certain drivers.
Introduce a 'ignore_resource_conflict' module parameter as alternate
means to ignore ACPI resource conflicts.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index fc0583f..5ac74cd 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -85,6 +85,10 @@ static unsigned short force_id;
module_param(force_id, ushort, 0);
MODULE_PARM_DESC(force_id, "Override the detected device ID");
+static bool ignore_resource_conflict;
+module_param(ignore_resource_conflict, bool, 0);
+MODULE_PARM_DESC(ignore_resource_conflict, "Ignore ACPI resource conflict");
+
static struct platform_device *it87_pdev[2];
#define REG_2E 0x2e /* The register to read/write */
@@ -3914,8 +3918,10 @@ static int __init it87_device_add(int index, unsigned short address,
int err;
err = acpi_check_resource_conflict(&res);
- if (err)
- return err;
+ if (err) {
+ if (!ignore_resource_conflict)
+ return err;
+ }
pdev = platform_device_alloc(DRVNAME, address);
if (!pdev)
--
2.20.1
From 25ab2bab3c57390d635f4ebe48e0002fb74d1540 Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Thu, 21 Sep 2017 15:19:05 -0700
Subject: [PATCH 37/61] Improve temperature sensor type detection for IT8686
EDIT/SPLIT
Introduce two new type values, 7 for 'virtual' and 8 for 'other'.
This will need to be added to the ABI once approved.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 36 +++++++++++++++---------------------
1 file changed, 15 insertions(+), 21 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 5ac74cd..ffdbe77 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -1311,6 +1311,15 @@ static SENSOR_DEVICE_ATTR_2(temp6_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
static SENSOR_DEVICE_ATTR_2(temp6_offset, S_IRUGO | S_IWUSR, show_temp,
set_temp, 5, 3);
+static const u8 temp_types_8686[NUM_TEMP][9] = {
+ { 0, 8, 8, 8, 8, 8, 8, 8, 7 },
+ { 0, 6, 8, 8, 6, 0, 0, 0, 7 },
+ { 0, 6, 5, 8, 6, 0, 0, 0, 7 },
+ { 4, 8, 8, 8, 8, 8, 8, 8, 7 },
+ { 4, 6, 8, 8, 6, 0, 0, 0, 7 },
+ { 4, 6, 5, 8, 6, 0, 0, 0, 7 },
+};
+
static int get_temp_type(struct it87_data *data, int index)
{
u8 reg, extra;
@@ -1321,27 +1330,11 @@ static int get_temp_type(struct it87_data *data, int index)
u8 src1, src2;
src1 = (it87_read_value(data, s1reg) >> ((index % 2) * 4)) & 0x0f;
- src2 = it87_read_value(data, IT87_REG_TEMP_SRC2);
switch (data->type) {
case it8686:
- switch (src1) {
- case 0:
- if (index >= 3)
- return 4;
- break;
- case 1:
- if (index == 1 || index == 2 ||
- index == 4 || index == 5)
- return 6;
- break;
- case 2:
- if (index == 2 || index == 6)
- return 5;
- break;
- default:
- break;
- }
+ if (src1 < 9)
+ type = temp_types_8686[index][src1];
break;
case it8625:
if (index < 3)
@@ -1352,6 +1345,7 @@ static int get_temp_type(struct it87_data *data, int index)
index = src1;
break;
}
+ src2 = it87_read_value(data, IT87_REG_TEMP_SRC2);
switch (src1) {
case 3:
type = (src2 & BIT(index)) ? 6 : 5;
@@ -1370,8 +1364,8 @@ static int get_temp_type(struct it87_data *data, int index)
return 0;
}
}
- if (index >= 3)
- return 0;
+ if (type || index >= 3)
+ return type;
reg = it87_read_value(data, IT87_REG_TEMP_ENABLE);
extra = it87_read_value(data, IT87_REG_TEMP_EXTRA);
@@ -3967,7 +3961,7 @@ struct it87_dmi_data {
* the second chip may have been accessed prior to loading this driver.
*
* The problem is also reported to affect IT8795E, which is used on X299 boards
- * and has the same chip ID as IT9792E (0x8733). It also appears to affect
+ * and has the same chip ID as IT8792E (0x8733). It also appears to affect
* systems with IT8790E, which is used on some Z97X-Gaming boards as well as
* Z87X-OC.
* DMI entries for those systems will be added as they become available and
--
2.20.1
From fd392f142cb088e0900622335da1b304bb1fdbe2 Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Thu, 21 Sep 2017 15:26:02 -0700
Subject: [PATCH 38/61] Always restore previous bank register after
reading/writing data
There is some indication that other entities (BIOS ? EC ?) may access
the chip asynchronously. Restore the bank selection after read/write
operations to limit any potenial impact.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 34 +++++++++++++++++++++++-----------
1 file changed, 23 insertions(+), 11 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index ffdbe77..fa8acff 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -725,7 +725,6 @@ struct it87_data {
int sioaddr;
enum chips type;
u32 features;
- u8 bank;
u8 peci_mask;
u8 old_peci_mask;
@@ -924,16 +923,21 @@ static void _it87_write_value(struct it87_data *data, u8 reg, u8 value)
outb_p(value, data->addr + IT87_DATA_REG_OFFSET);
}
-static void it87_set_bank(struct it87_data *data, u8 bank)
+static u8 it87_set_bank(struct it87_data *data, u8 bank)
{
- if (has_bank_sel(data) && bank != data->bank) {
+ u8 _bank = bank;
+
+ if (has_bank_sel(data)) {
u8 breg = _it87_read_value(data, IT87_REG_BANK);
- breg &= 0x1f;
- breg |= (bank << 5);
- data->bank = bank;
- _it87_write_value(data, IT87_REG_BANK, breg);
+ _bank = breg >> 5;
+ if (bank != _bank) {
+ breg &= 0x1f;
+ breg |= (bank << 5);
+ _it87_write_value(data, IT87_REG_BANK, breg);
+ }
}
+ return _bank;
}
/*
@@ -943,8 +947,14 @@ static void it87_set_bank(struct it87_data *data, u8 bank)
*/
static int it87_read_value(struct it87_data *data, u16 reg)
{
- it87_set_bank(data, reg >> 8);
- return _it87_read_value(data, reg & 0xff);
+ u8 bank;
+ int val;
+
+ bank = it87_set_bank(data, reg >> 8);
+ val = _it87_read_value(data, reg & 0xff);
+ it87_set_bank(data, bank);
+
+ return val;
}
/*
@@ -954,8 +964,11 @@ static int it87_read_value(struct it87_data *data, u16 reg)
*/
static void it87_write_value(struct it87_data *data, u16 reg, u8 value)
{
- it87_set_bank(data, reg >> 8);
+ u8 bank;
+
+ bank = it87_set_bank(data, reg >> 8);
_it87_write_value(data, reg & 0xff, value);
+ it87_set_bank(data, bank);
}
static void it87_update_pwm_ctrl(struct it87_data *data, int nr)
@@ -3704,7 +3717,6 @@ static int it87_probe(struct platform_device *pdev)
data->pwm_num_temp_map = it87_devices[sio_data->type].num_temp_map;
data->peci_mask = it87_devices[sio_data->type].peci_mask;
data->old_peci_mask = it87_devices[sio_data->type].old_peci_mask;
- data->bank = 0xff;
/*
* IT8705F Datasheet 0.4.1, 3h == Version G.
--
2.20.1
From 99551ed445dd37310548589ebf6151baed39cb6b Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Thu, 21 Sep 2017 16:17:53 -0700
Subject: [PATCH 39/61] Simplify and fix temperature sensor type detection EDIT
Temperature sensor types won't change, so we only need to read it once.
Also fix temperature register calculation.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index fa8acff..67774ff 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -756,6 +756,7 @@ struct it87_data {
s8 temp[NUM_TEMP][4]; /* [nr][0]=temp, [1]=min, [2]=max, [3]=offset */
u8 num_temp_limit; /* Number of temperature limit registers */
u8 num_temp_offset; /* Number of temperature offset registers */
+ u8 temp_src[4]; /* Up to 4 temperature source registers */
u8 sensor; /* Register value (IT87_REG_TEMP_ENABLE) */
u8 extra; /* Register value (IT87_REG_TEMP_EXTRA) */
u8 fan_div[NUM_FAN_DIV];/* Register encoding, shifted right */
@@ -1339,10 +1340,9 @@ static int get_temp_type(struct it87_data *data, int index)
int type = 0;
if (has_bank_sel(data)) {
- int s1reg = IT87_REG_TEMP_SRC1[index/2] >> ((index % 2) * 4);
u8 src1, src2;
- src1 = (it87_read_value(data, s1reg) >> ((index % 2) * 4)) & 0x0f;
+ src1 = (data->temp_src[index / 2] >> ((index % 2) * 4)) & 0x0f;
switch (data->type) {
case it8686:
@@ -1358,7 +1358,7 @@ static int get_temp_type(struct it87_data *data, int index)
index = src1;
break;
}
- src2 = it87_read_value(data, IT87_REG_TEMP_SRC2);
+ src2 = data->temp_src[3];
switch (src1) {
case 3:
type = (src2 & BIT(index)) ? 6 : 5;
@@ -3465,6 +3465,14 @@ static void it87_check_tachometers_16bit_mode(struct platform_device *pdev)
static void it87_start_monitoring(struct it87_data *data)
{
+ if (has_bank_sel(data)) {
+ int i;
+ for (i = 0; i < 3; i++)
+ data->temp_src[i] =
+ it87_read_value(data, IT87_REG_TEMP_SRC1[i]);
+ data->temp_src[3] = it87_read_value(data, IT87_REG_TEMP_SRC2);
+ }
+
it87_write_value(data, IT87_REG_CONFIG,
(it87_read_value(data, IT87_REG_CONFIG) & 0x3e)
| (update_vbat ? 0x41 : 0x01));
--
2.20.1
From b4be6f3b2b92b2e88ee56395ad7032635b299692 Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Sun, 24 Sep 2017 08:10:16 -0700
Subject: [PATCH 40/61] Fix FAN_TAC5 detection for IT8665E
FAN_TAC5 is connected if 26h[4]=0.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 67774ff..e719eb5 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -3241,6 +3241,10 @@ static int __init it87_find(int sioaddr, unsigned short *address,
/* Check for pwm2, fan2 */
if (reg29 & BIT(1))
sio_data->skip_pwm |= BIT(1);
+ /*
+ * Note: Table 6-1 in datasheet claims that FAN_TAC2
+ * would be enabled with 29h[2]=0.
+ */
if (reg2d & BIT(4))
sio_data->skip_fan |= BIT(1);
@@ -3271,7 +3275,7 @@ static int __init it87_find(int sioaddr, unsigned short *address,
sio_data->skip_fan |= BIT(3);
if (reg26 & BIT(5))
sio_data->skip_pwm |= BIT(4);
- if (!(reg26 & BIT(4)))
+ if (reg26 & BIT(4))
sio_data->skip_fan |= BIT(4);
}
--
2.20.1
From 40b3dbe8f32b23fb21898564655adf08cfabbee1 Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Fri, 29 Sep 2017 21:52:09 -0700
Subject: [PATCH 41/61] Disable SMBus access while accessing Enviromnental
Controller registers EDIT/FIX
Some chips support Environmental Controller access through SMBus.
On those chips, it is possible that an Embedded Controller accesses
Environmental Controller chip registers at any time. There is no real
means for synchronization. On banked chips, this can and will result in
access errors with unpredictable result.
Disable SMBus access while reading or writing environmental controller
registers to work around the problem.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 320 +++++++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 254 insertions(+), 66 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index e719eb5..ea218e3 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -144,13 +144,10 @@ static inline int superio_enter(int ioreg)
* Try to reserve ioreg and ioreg + 1 for exclusive access.
*/
if (!request_muxed_region(ioreg, 2, DRVNAME))
- goto error;
+ return -EBUSY;
__superio_enter(ioreg);
return 0;
-
-error:
- return -EBUSY;
}
static inline void superio_exit(int ioreg, bool doexit)
@@ -191,10 +188,13 @@ static inline void superio_exit(int ioreg, bool doexit)
#define IT8655E_DEVID 0x8655
#define IT8665E_DEVID 0x8665
#define IT8686E_DEVID 0x8686
-#define IT87_ACT_REG 0x30
-#define IT87_BASE_REG 0x60
-/* Logical device 7 registers (IT8712F and later) */
+/* Logical device 4 (Environmental Monitor) registers */
+#define IT87_ACT_REG 0x30
+#define IT87_BASE_REG 0x60
+#define IT87_SPECIAL_CFG_REG 0xf3 /* special configuration register */
+
+/* Logical device 7 (GPIO) registers (IT8712F and later) */
#define IT87_SIO_GPIO1_REG 0x25
#define IT87_SIO_GPIO2_REG 0x26
#define IT87_SIO_GPIO3_REG 0x27
@@ -333,6 +333,8 @@ struct it87_devices {
u8 num_temp_map; /* Number of temperature sources for pwm */
u8 peci_mask;
u8 old_peci_mask;
+ u8 smbus_bitmap; /* SMBus enable bits in extra config register */
+ u8 ec_special_config;
};
#define FEAT_12MV_ADC BIT(0)
@@ -616,6 +618,7 @@ static const struct it87_devices it87_devices[] = {
.num_temp_limit = 6,
.num_temp_offset = 6,
.num_temp_map = 6,
+ .smbus_bitmap = BIT(1) | BIT(2),
},
[it8628] = {
.name = "it8628",
@@ -639,6 +642,7 @@ static const struct it87_devices it87_devices[] = {
.num_temp_limit = 6,
.num_temp_offset = 6,
.num_temp_map = 6,
+ .smbus_bitmap = BIT(2),
},
[it8665] = {
.name = "it8665",
@@ -650,6 +654,7 @@ static const struct it87_devices it87_devices[] = {
.num_temp_limit = 6,
.num_temp_offset = 6,
.num_temp_map = 6,
+ .smbus_bitmap = BIT(2),
},
[it8686] = {
.name = "it8686",
@@ -661,6 +666,7 @@ static const struct it87_devices it87_devices[] = {
.num_temp_limit = 6,
.num_temp_offset = 6,
.num_temp_map = 7,
+ .smbus_bitmap = BIT(1) | BIT(2),
},
};
@@ -700,8 +706,9 @@ static const struct it87_devices it87_devices[] = {
#define has_new_tempmap(data) ((data)->features & FEAT_NEW_TEMPMAP)
struct it87_sio_data {
- int sioaddr;
+ u8 sioaddr;
enum chips type;
+ u8 doexit;
/* Values read from Super-I/O config space */
u8 revision;
u8 vid_value;
@@ -714,6 +721,8 @@ struct it87_sio_data {
u8 skip_fan;
u8 skip_pwm;
u8 skip_temp;
+ u8 smbus_bitmap;
+ u8 ec_special_config;
};
/*
@@ -722,12 +731,16 @@ struct it87_sio_data {
*/
struct it87_data {
const struct attribute_group *groups[7];
- int sioaddr;
enum chips type;
u32 features;
u8 peci_mask;
u8 old_peci_mask;
+ u8 smbus_bitmap; /* !=0 if SMBus needs to be disabled */
+ u8 ec_special_config; /* EC special config register restore value */
+ u8 sioaddr; /* SIO port address */
+ bool doexit; /* true if exit from sio config is ok */
+
const u8 *REG_FAN;
const u8 *REG_FANX;
const u8 *REG_FAN_MIN;
@@ -912,6 +925,39 @@ static const unsigned int pwm_freq[8] = {
750000,
};
+static int smbus_disable(struct it87_data *data)
+{
+ int err;
+
+ if (data->smbus_bitmap) {
+ err = superio_enter(data->sioaddr);
+ if (err)
+ return err;
+ superio_select(data->sioaddr, PME);
+ superio_outb(data->sioaddr, IT87_SPECIAL_CFG_REG,
+ data->ec_special_config & ~data->smbus_bitmap);
+ superio_exit(data->sioaddr, data->doexit);
+ }
+ return 0;
+}
+
+static int smbus_enable(struct it87_data *data)
+{
+ int err;
+
+ if (data->smbus_bitmap) {
+ err = superio_enter(data->sioaddr);
+ if (err)
+ return err;
+
+ superio_select(data->sioaddr, PME);
+ superio_outb(data->sioaddr, IT87_SPECIAL_CFG_REG,
+ data->ec_special_config);
+ superio_exit(data->sioaddr, data->doexit);
+ }
+ return 0;
+}
+
static int _it87_read_value(struct it87_data *data, u8 reg)
{
outb_p(reg, data->addr + IT87_ADDR_REG_OFFSET);
@@ -943,6 +989,7 @@ static u8 it87_set_bank(struct it87_data *data, u8 bank)
/*
* Must be called with data->update_lock held, except during initialization.
+ * Must be called with SMBus accesses disabled.
* We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks,
* would slow down the IT87 access and should not be necessary.
*/
@@ -960,6 +1007,7 @@ static int it87_read_value(struct it87_data *data, u16 reg)
/*
* Must be called with data->update_lock held, except during initialization.
+ * Must be called with SMBus accesses disabled
* We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks,
* would slow down the IT87 access and should not be necessary.
*/
@@ -1025,12 +1073,32 @@ static void it87_update_pwm_ctrl(struct it87_data *data, int nr)
}
}
+static int it87_lock(struct it87_data *data)
+{
+ int err;
+
+ mutex_lock(&data->update_lock);
+ err = smbus_disable(data);
+ if (err)
+ mutex_unlock(&data->update_lock);
+ return err;
+}
+
+static void it87_unlock(struct it87_data *data)
+{
+ smbus_enable(data);
+ mutex_unlock(&data->update_lock);
+}
+
static struct it87_data *it87_update_device(struct device *dev)
{
struct it87_data *data = dev_get_drvdata(dev);
+ int err;
int i;
- mutex_lock(&data->update_lock);
+ err = it87_lock(data);
+ if (err)
+ return ERR_PTR(err);
if (time_after(jiffies, data->last_updated + HZ + HZ / 2) ||
!data->valid) {
@@ -1137,9 +1205,7 @@ static struct it87_data *it87_update_device(struct device *dev)
data->last_updated = jiffies;
data->valid = 1;
}
-
- mutex_unlock(&data->update_lock);
-
+ it87_unlock(data);
return data;
}
@@ -1151,6 +1217,9 @@ static ssize_t show_in(struct device *dev, struct device_attribute *attr,
int index = sattr->index;
int nr = sattr->nr;
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+
return sprintf(buf, "%d\n", in_from_reg(data, nr, data->in[nr][index]));
}
@@ -1162,17 +1231,21 @@ static ssize_t set_in(struct device *dev, struct device_attribute *attr,
int index = sattr->index;
int nr = sattr->nr;
unsigned long val;
+ int err;
if (kstrtoul(buf, 10, &val) < 0)
return -EINVAL;
- mutex_lock(&data->update_lock);
+ err = it87_lock(data);
+ if (err)
+ return err;
+
data->in[nr][index] = in_to_reg(data, nr, val);
it87_write_value(data,
index == 1 ? IT87_REG_VIN_MIN(nr)
: IT87_REG_VIN_MAX(nr),
data->in[nr][index]);
- mutex_unlock(&data->update_lock);
+ it87_unlock(data);
return count;
}
@@ -1239,6 +1312,9 @@ static ssize_t show_temp(struct device *dev, struct device_attribute *attr,
int index = sattr->index;
struct it87_data *data = it87_update_device(dev);
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+
return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[nr][index]));
}
@@ -1251,11 +1327,14 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr,
struct it87_data *data = dev_get_drvdata(dev);
long val;
u8 reg, regval;
+ int err;
if (kstrtol(buf, 10, &val) < 0)
return -EINVAL;
- mutex_lock(&data->update_lock);
+ err = it87_lock(data);
+ if (err)
+ return err;
switch (index) {
default:
@@ -1278,7 +1357,7 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr,
data->temp[nr][index] = TEMP_TO_REG(val);
it87_write_value(data, reg, data->temp[nr][index]);
- mutex_unlock(&data->update_lock);
+ it87_unlock(data);
return count;
}
@@ -1399,8 +1478,12 @@ static ssize_t show_temp_type(struct device *dev, struct device_attribute *attr,
{
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
struct it87_data *data = it87_update_device(dev);
- int type = get_temp_type(data, sensor_attr->index);
+ int type;
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+
+ type = get_temp_type(data, sensor_attr->index);
return sprintf(buf, "%d\n", type);
}
@@ -1413,10 +1496,15 @@ static ssize_t set_temp_type(struct device *dev, struct device_attribute *attr,
struct it87_data *data = dev_get_drvdata(dev);
long val;
u8 reg, extra;
+ int err;
if (kstrtol(buf, 10, &val) < 0)
return -EINVAL;
+ err = it87_lock(data);
+ if (err)
+ return err;
+
reg = it87_read_value(data, IT87_REG_TEMP_ENABLE);
reg &= ~(1 << nr);
reg &= ~(8 << nr);
@@ -1439,17 +1527,19 @@ static ssize_t set_temp_type(struct device *dev, struct device_attribute *attr,
reg |= (nr + 1) << 6;
else if (has_temp_old_peci(data, nr) && val == 6)
extra |= 0x80;
- else if (val != 0)
- return -EINVAL;
+ else if (val != 0) {
+ count = -EINVAL;
+ goto unlock;
+ }
- mutex_lock(&data->update_lock);
data->sensor = reg;
data->extra = extra;
it87_write_value(data, IT87_REG_TEMP_ENABLE, data->sensor);
if (has_temp_old_peci(data, nr))
it87_write_value(data, IT87_REG_TEMP_EXTRA, data->extra);
data->valid = 0; /* Force cache refresh */
- mutex_unlock(&data->update_lock);
+unlock:
+ it87_unlock(data);
return count;
}
@@ -1491,6 +1581,9 @@ static ssize_t show_fan(struct device *dev, struct device_attribute *attr,
int speed;
struct it87_data *data = it87_update_device(dev);
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+
speed = has_16bit_fans(data) ?
FAN16_FROM_REG(data->fan[nr][index]) :
FAN_FROM_REG(data->fan[nr][index],
@@ -1505,6 +1598,9 @@ static ssize_t show_fan_div(struct device *dev, struct device_attribute *attr,
struct it87_data *data = it87_update_device(dev);
int nr = sensor_attr->index;
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+
return sprintf(buf, "%lu\n", DIV_FROM_REG(data->fan_div[nr]));
}
@@ -1515,6 +1611,9 @@ static ssize_t show_pwm_enable(struct device *dev,
struct it87_data *data = it87_update_device(dev);
int nr = sensor_attr->index;
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+
return sprintf(buf, "%d\n", pwm_mode(data, nr));
}
@@ -1525,6 +1624,9 @@ static ssize_t show_pwm(struct device *dev, struct device_attribute *attr,
struct it87_data *data = it87_update_device(dev);
int nr = sensor_attr->index;
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+
return sprintf(buf, "%d\n",
pwm_from_reg(data, data->pwm_duty[nr]));
}
@@ -1538,6 +1640,9 @@ static ssize_t show_pwm_freq(struct device *dev, struct device_attribute *attr,
unsigned int freq;
int index;
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+
if (has_pwm_freq2(data) && nr == 1)
index = (data->extra >> 4) & 0x07;
else
@@ -1557,12 +1662,15 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *attr,
struct it87_data *data = dev_get_drvdata(dev);
long val;
+ int err;
u8 reg;
if (kstrtol(buf, 10, &val) < 0)
return -EINVAL;
- mutex_lock(&data->update_lock);
+ err = it87_lock(data);
+ if (err)
+ return err;
if (has_16bit_fans(data)) {
data->fan[nr][index] = FAN16_TO_REG(val);
@@ -1588,8 +1696,7 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *attr,
it87_write_value(data, data->REG_FAN_MIN[nr],
data->fan[nr][index]);
}
-
- mutex_unlock(&data->update_lock);
+ it87_unlock(data);
return count;
}
@@ -1600,13 +1707,16 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
struct it87_data *data = dev_get_drvdata(dev);
int nr = sensor_attr->index;
unsigned long val;
- int min;
+ int min, err;
u8 old;
if (kstrtoul(buf, 10, &val) < 0)
return -EINVAL;
- mutex_lock(&data->update_lock);
+ err = it87_lock(data);
+ if (err)
+ return err;
+
old = it87_read_value(data, IT87_REG_FAN_DIV);
/* Save fan min limit */
@@ -1633,8 +1743,7 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
/* Restore fan min limit */
data->fan[nr][1] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
it87_write_value(data, data->REG_FAN_MIN[nr], data->fan[nr][1]);
-
- mutex_unlock(&data->update_lock);
+ it87_unlock(data);
return count;
}
@@ -1675,6 +1784,7 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr,
struct it87_data *data = dev_get_drvdata(dev);
int nr = sensor_attr->index;
long val;
+ int err;
if (kstrtol(buf, 10, &val) < 0 || val < 0 || val > 2)
return -EINVAL;
@@ -1685,7 +1795,10 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr,
return -EINVAL;
}
- mutex_lock(&data->update_lock);
+ err = it87_lock(data);
+ if (err)
+ return err;
+
it87_update_pwm_ctrl(data, nr);
if (val == 0) {
@@ -1739,8 +1852,7 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr,
data->fan_main_ctrl);
}
}
-
- mutex_unlock(&data->update_lock);
+ it87_unlock(data);
return count;
}
@@ -1751,11 +1863,15 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
struct it87_data *data = dev_get_drvdata(dev);
int nr = sensor_attr->index;
long val;
+ int err;
if (kstrtol(buf, 10, &val) < 0 || val < 0 || val > 255)
return -EINVAL;
- mutex_lock(&data->update_lock);
+ err = it87_lock(data);
+ if (err)
+ return err;
+
it87_update_pwm_ctrl(data, nr);
if (has_newer_autopwm(data)) {
/*
@@ -1763,8 +1879,8 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
* is read-only so we can't write the value.
*/
if (data->pwm_ctrl[nr] & 0x80) {
- mutex_unlock(&data->update_lock);
- return -EBUSY;
+ count = -EBUSY;
+ goto unlock;
}
data->pwm_duty[nr] = pwm_to_reg(data, val);
it87_write_value(data, IT87_REG_PWM_DUTY[nr],
@@ -1781,7 +1897,8 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
data->pwm_ctrl[nr]);
}
}
- mutex_unlock(&data->update_lock);
+unlock:
+ it87_unlock(data);
return count;
}
@@ -1792,6 +1909,7 @@ static ssize_t set_pwm_freq(struct device *dev, struct device_attribute *attr,
struct it87_data *data = dev_get_drvdata(dev);
int nr = sensor_attr->index;
unsigned long val;
+ int err;
int i;
if (kstrtoul(buf, 10, &val) < 0)
@@ -1806,7 +1924,10 @@ static ssize_t set_pwm_freq(struct device *dev, struct device_attribute *attr,
break;
}
- mutex_lock(&data->update_lock);
+ err = it87_lock(data);
+ if (err)
+ return err;
+
if (nr == 0) {
data->fan_ctl = it87_read_value(data, IT87_REG_FAN_CTL) & 0x8f;
data->fan_ctl |= i << 4;
@@ -1816,8 +1937,7 @@ static ssize_t set_pwm_freq(struct device *dev, struct device_attribute *attr,
data->extra |= i << 4;
it87_write_value(data, IT87_REG_TEMP_EXTRA, data->extra);
}
- mutex_unlock(&data->update_lock);
-
+ it87_unlock(data);
return count;
}
@@ -1828,6 +1948,9 @@ static ssize_t show_pwm_temp_map(struct device *dev,
struct it87_data *data = it87_update_device(dev);
int nr = sensor_attr->index;
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+
return sprintf(buf, "%d\n", data->pwm_temp_map[nr] + 1);
}
@@ -1839,6 +1962,7 @@ static ssize_t set_pwm_temp_map(struct device *dev,
struct it87_data *data = dev_get_drvdata(dev);
int nr = sensor_attr->index;
unsigned long val;
+ int err;
u8 map;
if (kstrtoul(buf, 10, &val) < 0)
@@ -1849,7 +1973,10 @@ static ssize_t set_pwm_temp_map(struct device *dev,
map = val - 1;
- mutex_lock(&data->update_lock);
+ err = it87_lock(data);
+ if (err)
+ return err;
+
it87_update_pwm_ctrl(data, nr);
data->pwm_temp_map[nr] = map;
/*
@@ -1860,7 +1987,7 @@ static ssize_t set_pwm_temp_map(struct device *dev,
data->pwm_ctrl[nr] = temp_map_to_reg(data, nr, map);
it87_write_value(data, data->REG_PWM[nr], data->pwm_ctrl[nr]);
}
- mutex_unlock(&data->update_lock);
+ it87_unlock(data);
return count;
}
@@ -1873,6 +2000,9 @@ static ssize_t show_auto_pwm(struct device *dev, struct device_attribute *attr,
int nr = sensor_attr->nr;
int point = sensor_attr->index;
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+
return sprintf(buf, "%d\n",
pwm_from_reg(data, data->auto_pwm[nr][point]));
}
@@ -1887,18 +2017,22 @@ static ssize_t set_auto_pwm(struct device *dev, struct device_attribute *attr,
int point = sensor_attr->index;
int regaddr;
long val;
+ int err;
if (kstrtol(buf, 10, &val) < 0 || val < 0 || val > 255)
return -EINVAL;
- mutex_lock(&data->update_lock);
+ err = it87_lock(data);
+ if (err)
+ return err;
+
data->auto_pwm[nr][point] = pwm_to_reg(data, val);
if (has_newer_autopwm(data))
regaddr = IT87_REG_AUTO_TEMP(nr, 3);
else
regaddr = IT87_REG_AUTO_PWM(nr, point);
it87_write_value(data, regaddr, data->auto_pwm[nr][point]);
- mutex_unlock(&data->update_lock);
+ it87_unlock(data);
return count;
}
@@ -1909,6 +2043,9 @@ static ssize_t show_auto_pwm_slope(struct device *dev,
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
int nr = sensor_attr->index;
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+
return sprintf(buf, "%d\n", data->auto_pwm[nr][1] & 0x7f);
}
@@ -1920,15 +2057,19 @@ static ssize_t set_auto_pwm_slope(struct device *dev,
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
int nr = sensor_attr->index;
unsigned long val;
+ int err;
if (kstrtoul(buf, 10, &val) < 0 || val > 127)
return -EINVAL;
- mutex_lock(&data->update_lock);
+ err = it87_lock(data);
+ if (err)
+ return err;
+
data->auto_pwm[nr][1] = (data->auto_pwm[nr][1] & 0x80) | val;
it87_write_value(data, IT87_REG_AUTO_TEMP(nr, 4),
data->auto_pwm[nr][1]);
- mutex_unlock(&data->update_lock);
+ it87_unlock(data);
return count;
}
@@ -1942,6 +2083,9 @@ static ssize_t show_auto_temp(struct device *dev, struct device_attribute *attr,
int point = sensor_attr->index;
int reg;
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+
if (has_old_autopwm(data) || point)
reg = data->auto_temp[nr][point];
else
@@ -1960,11 +2104,15 @@ static ssize_t set_auto_temp(struct device *dev, struct device_attribute *attr,
int point = sensor_attr->index;
long val;
int reg;
+ int err;
if (kstrtol(buf, 10, &val) < 0 || val < -128000 || val > 127000)
return -EINVAL;
- mutex_lock(&data->update_lock);
+ err = it87_lock(data);
+ if (err)
+ return err;
+
if (has_newer_autopwm(data) && !point) {
reg = data->auto_temp[nr][1] - TEMP_TO_REG(val);
reg = clamp_val(reg, 0, 0x1f) | (data->auto_temp[nr][0] & 0xe0);
@@ -1977,7 +2125,7 @@ static ssize_t set_auto_temp(struct device *dev, struct device_attribute *attr,
point--;
it87_write_value(data, IT87_REG_AUTO_TEMP(nr, point), reg);
}
- mutex_unlock(&data->update_lock);
+ it87_unlock(data);
return count;
}
@@ -2162,6 +2310,9 @@ static ssize_t alarms_show(struct device *dev, struct device_attribute *attr,
{
struct it87_data *data = it87_update_device(dev);
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+
return sprintf(buf, "%u\n", data->alarms);
}
static DEVICE_ATTR_RO(alarms);
@@ -2172,6 +2323,9 @@ static ssize_t show_alarm(struct device *dev, struct device_attribute *attr,
struct it87_data *data = it87_update_device(dev);
int bitnr = to_sensor_dev_attr(attr)->index;
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+
return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1);
}
@@ -2180,24 +2334,22 @@ static ssize_t clear_intrusion(struct device *dev,
size_t count)
{
struct it87_data *data = dev_get_drvdata(dev);
- int config;
+ int err, config;
long val;
if (kstrtol(buf, 10, &val) < 0 || val != 0)
return -EINVAL;
- mutex_lock(&data->update_lock);
- config = it87_read_value(data, IT87_REG_CONFIG);
- if (config < 0) {
- count = config;
- } else {
- config |= BIT(5);
- it87_write_value(data, IT87_REG_CONFIG, config);
- /* Invalidate cache to force re-read */
- data->valid = 0;
- }
- mutex_unlock(&data->update_lock);
+ err = it87_lock(data);
+ if (err)
+ return err;
+ config = it87_read_value(data, IT87_REG_CONFIG);
+ config |= BIT(5);
+ it87_write_value(data, IT87_REG_CONFIG, config);
+ /* Invalidate cache to force re-read */
+ data->valid = 0;
+ it87_unlock(data);
return count;
}
@@ -2230,6 +2382,9 @@ static ssize_t show_beep(struct device *dev, struct device_attribute *attr,
struct it87_data *data = it87_update_device(dev);
int bitnr = to_sensor_dev_attr(attr)->index;
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+
return sprintf(buf, "%u\n", (data->beeps >> bitnr) & 1);
}
@@ -2239,18 +2394,22 @@ static ssize_t set_beep(struct device *dev, struct device_attribute *attr,
int bitnr = to_sensor_dev_attr(attr)->index;
struct it87_data *data = dev_get_drvdata(dev);
long val;
+ int err;
if (kstrtol(buf, 10, &val) < 0 || (val != 0 && val != 1))
return -EINVAL;
- mutex_lock(&data->update_lock);
+ err = it87_lock(data);
+ if (err)
+ return err;
+
data->beeps = it87_read_value(data, IT87_REG_BEEP_ENABLE);
if (val)
data->beeps |= BIT(bitnr);
else
data->beeps &= ~BIT(bitnr);
it87_write_value(data, IT87_REG_BEEP_ENABLE, data->beeps);
- mutex_unlock(&data->update_lock);
+ it87_unlock(data);
return count;
}
@@ -2306,6 +2465,9 @@ static ssize_t cpu0_vid_show(struct device *dev,
{
struct it87_data *data = it87_update_device(dev);
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+
return sprintf(buf, "%ld\n", (long)vid_from_reg(data->vid, data->vrm));
}
static DEVICE_ATTR_RO(cpu0_vid);
@@ -2791,6 +2953,8 @@ static int __init it87_find(int sioaddr, unsigned short *address,
if (err)
return err;
+ sio_data->sioaddr = sioaddr;
+
err = -ENODEV;
chip_type = superio_inw(sioaddr, DEVID);
if (chip_type == 0xffff)
@@ -2907,6 +3071,8 @@ static int __init it87_find(int sioaddr, unsigned short *address,
goto exit;
}
+ sio_data->doexit = doexit;
+
err = 0;
sio_data->sioaddr = sioaddr;
sio_data->revision = superio_inb(sioaddr, DEVREV) & 0x0f;
@@ -3392,6 +3558,15 @@ static int __init it87_find(int sioaddr, unsigned short *address,
if (sio_data->beep_pin)
pr_info("Beeping is supported\n");
+ if (config->smbus_bitmap) {
+ u8 reg;
+
+ superio_select(sioaddr, PME);
+ reg = superio_inb(sioaddr, IT87_SPECIAL_CFG_REG);
+ sio_data->ec_special_config = reg;
+ sio_data->smbus_bitmap = reg & config->smbus_bitmap;
+ }
+
exit:
superio_exit(sioaddr, doexit);
return err;
@@ -3706,6 +3881,7 @@ static int it87_probe(struct platform_device *pdev)
struct it87_sio_data *sio_data = dev_get_platdata(dev);
int enable_pwm_interface;
struct device *hwmon_dev;
+ int err;
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
if (!devm_request_region(&pdev->dev, res->start, IT87_EC_EXTENT,
@@ -3723,6 +3899,10 @@ static int it87_probe(struct platform_device *pdev)
data->addr = res->start;
data->sioaddr = sio_data->sioaddr;
data->type = sio_data->type;
+ data->sioaddr = sio_data->sioaddr;
+ data->smbus_bitmap = sio_data->smbus_bitmap;
+ data->ec_special_config = sio_data->ec_special_config;
+ data->doexit = sio_data->doexit;
data->features = it87_devices[sio_data->type].features;
data->num_temp_limit = it87_devices[sio_data->type].num_temp_limit;
data->num_temp_offset = it87_devices[sio_data->type].num_temp_offset;
@@ -3753,11 +3933,6 @@ static int it87_probe(struct platform_device *pdev)
break;
}
- /* Now, we do the remaining detection. */
- if ((it87_read_value(data, IT87_REG_CONFIG) & 0x80) ||
- it87_read_value(data, IT87_REG_CHIPID) != 0x90)
- return -ENODEV;
-
platform_set_drvdata(pdev, data);
mutex_init(&data->update_lock);
@@ -3765,6 +3940,17 @@ static int it87_probe(struct platform_device *pdev)
/* Initialize register pointers */
it87_init_regs(pdev);
+ err = smbus_disable(data);
+ if (err)
+ return err;
+
+ /* Now, we do the remaining detection. */
+ if ((it87_read_value(data, IT87_REG_CONFIG) & 0x80) ||
+ it87_read_value(data, IT87_REG_CHIPID) != 0x90) {
+ smbus_enable(data);
+ return -ENODEV;
+ }
+
/* Check PWM configuration */
enable_pwm_interface = it87_check_pwm(dev);
if (!enable_pwm_interface)
@@ -3825,6 +4011,8 @@ static int it87_probe(struct platform_device *pdev)
/* Initialize the IT87 chip */
it87_init_device(pdev);
+ smbus_enable(data);
+
if (!sio_data->skip_vid) {
data->has_vid = true;
data->vrm = vid_which_vrm();
--
2.20.1
From e3bbb5408cbf496c804f01ad4cd30c14e706561b Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Sat, 30 Sep 2017 23:50:09 -0700
Subject: [PATCH 42/61] Add MMIO support CHECK/DOCUMENT
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 360 ++++++++++++++++++++++++++++++++-------------------------
1 file changed, 205 insertions(+), 155 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index ea218e3..9ccce1b 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -89,6 +89,10 @@ static bool ignore_resource_conflict;
module_param(ignore_resource_conflict, bool, 0);
MODULE_PARM_DESC(ignore_resource_conflict, "Ignore ACPI resource conflict");
+static bool mmio;
+module_param(mmio, bool, 0);
+MODULE_PARM_DESC(mmio, "Use MMIO if available");
+
static struct platform_device *it87_pdev[2];
#define REG_2E 0x2e /* The register to read/write */
@@ -194,7 +198,8 @@ static inline void superio_exit(int ioreg, bool doexit)
#define IT87_BASE_REG 0x60
#define IT87_SPECIAL_CFG_REG 0xf3 /* special configuration register */
-/* Logical device 7 (GPIO) registers (IT8712F and later) */
+/* Global configuration registers (IT8712F and later) */
+#define IT87_EC_HWM_MIO_REG 0x24 /* MMIO configuration register */
#define IT87_SIO_GPIO1_REG 0x25
#define IT87_SIO_GPIO2_REG 0x26
#define IT87_SIO_GPIO3_REG 0x27
@@ -204,6 +209,8 @@ static inline void superio_exit(int ioreg, bool doexit)
#define IT87_SIO_PINX1_REG 0x2a /* Pin selection */
#define IT87_SIO_PINX2_REG 0x2c /* Pin selection */
#define IT87_SIO_PINX4_REG 0x2d /* Pin selection */
+
+/* Logical device 7 (GPIO) registers (IT8712F and later) */
#define IT87_SIO_SPI_REG 0xef /* SPI function pin select */
#define IT87_SIO_VID_REG 0xfc /* VID value */
#define IT87_SIO_BEEP_PIN_REG 0xf6 /* Beep pin mapping */
@@ -362,6 +369,7 @@ struct it87_devices {
#define FEAT_FANCTL_ONOFF BIT(23) /* chip has FAN_CTL ON/OFF */
#define FEAT_11MV_ADC BIT(24)
#define FEAT_NEW_TEMPMAP BIT(25) /* new temp input selection */
+#define FEAT_MMIO BIT(26) /* Chip supports MMIO */
static const struct it87_devices it87_devices[] = {
[it87] = {
@@ -650,7 +658,7 @@ static const struct it87_devices it87_devices[] = {
.features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS
| FEAT_AVCC3 | FEAT_NEW_TEMPMAP | FEAT_SCALING
| FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_SIX_FANS
- | FEAT_SIX_PWM | FEAT_BANK_SEL,
+ | FEAT_SIX_PWM | FEAT_BANK_SEL | FEAT_MMIO,
.num_temp_limit = 6,
.num_temp_offset = 6,
.num_temp_map = 6,
@@ -704,6 +712,7 @@ static const struct it87_devices it87_devices[] = {
#define has_fanctl_onoff(data) ((data)->features & FEAT_FANCTL_ONOFF)
#define has_11mv_adc(data) ((data)->features & FEAT_11MV_ADC)
#define has_new_tempmap(data) ((data)->features & FEAT_NEW_TEMPMAP)
+#define has_mmio(data) ((data)->features & FEAT_MMIO)
struct it87_sio_data {
u8 sioaddr;
@@ -741,6 +750,10 @@ struct it87_data {
u8 sioaddr; /* SIO port address */
bool doexit; /* true if exit from sio config is ok */
+ void __iomem *mmio; /* Remapped MMIO address if available */
+ int (*read)(struct it87_data *, u16);
+ void (*write)(struct it87_data *, u16, u8);
+
const u8 *REG_FAN;
const u8 *REG_FANX;
const u8 *REG_FAN_MIN;
@@ -958,30 +971,30 @@ static int smbus_enable(struct it87_data *data)
return 0;
}
-static int _it87_read_value(struct it87_data *data, u8 reg)
+static int _it87_io_read(struct it87_data *data, u16 reg)
{
outb_p(reg, data->addr + IT87_ADDR_REG_OFFSET);
return inb_p(data->addr + IT87_DATA_REG_OFFSET);
}
-static void _it87_write_value(struct it87_data *data, u8 reg, u8 value)
+static void _it87_io_write(struct it87_data *data, u16 reg, u8 value)
{
outb_p(reg, data->addr + IT87_ADDR_REG_OFFSET);
outb_p(value, data->addr + IT87_DATA_REG_OFFSET);
}
-static u8 it87_set_bank(struct it87_data *data, u8 bank)
+static u8 it87_io_set_bank(struct it87_data *data, u8 bank)
{
u8 _bank = bank;
if (has_bank_sel(data)) {
- u8 breg = _it87_read_value(data, IT87_REG_BANK);
+ u8 breg = _it87_io_read(data, IT87_REG_BANK);
_bank = breg >> 5;
if (bank != _bank) {
breg &= 0x1f;
breg |= (bank << 5);
- _it87_write_value(data, IT87_REG_BANK, breg);
+ _it87_io_write(data, IT87_REG_BANK, breg);
}
}
return _bank;
@@ -993,14 +1006,14 @@ static u8 it87_set_bank(struct it87_data *data, u8 bank)
* We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks,
* would slow down the IT87 access and should not be necessary.
*/
-static int it87_read_value(struct it87_data *data, u16 reg)
+static int it87_io_read(struct it87_data *data, u16 reg)
{
u8 bank;
int val;
- bank = it87_set_bank(data, reg >> 8);
- val = _it87_read_value(data, reg & 0xff);
- it87_set_bank(data, bank);
+ bank = it87_io_set_bank(data, reg >> 8);
+ val = _it87_io_read(data, reg & 0xff);
+ it87_io_set_bank(data, bank);
return val;
}
@@ -1011,25 +1024,34 @@ static int it87_read_value(struct it87_data *data, u16 reg)
* We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks,
* would slow down the IT87 access and should not be necessary.
*/
-static void it87_write_value(struct it87_data *data, u16 reg, u8 value)
+static void it87_io_write(struct it87_data *data, u16 reg, u8 value)
{
u8 bank;
- bank = it87_set_bank(data, reg >> 8);
- _it87_write_value(data, reg & 0xff, value);
- it87_set_bank(data, bank);
+ bank = it87_io_set_bank(data, reg >> 8);
+ _it87_io_write(data, reg & 0xff, value);
+ it87_io_set_bank(data, bank);
+}
+
+static int it87_mmio_read(struct it87_data *data, u16 reg)
+{
+ return readb(data->mmio + reg);
+}
+
+static void it87_mmio_write(struct it87_data *data, u16 reg, u8 value)
+{
+ writeb(value, data->mmio + reg);
}
static void it87_update_pwm_ctrl(struct it87_data *data, int nr)
{
u8 ctrl;
- ctrl = it87_read_value(data, data->REG_PWM[nr]);
+ ctrl = data->read(data, data->REG_PWM[nr]);
data->pwm_ctrl[nr] = ctrl;
if (has_newer_autopwm(data)) {
data->pwm_temp_map[nr] = temp_map_from_reg(data, ctrl);
- data->pwm_duty[nr] = it87_read_value(data,
- IT87_REG_PWM_DUTY[nr]);
+ data->pwm_duty[nr] = data->read(data, IT87_REG_PWM_DUTY[nr]);
} else {
if (ctrl & 0x80) /* Automatic mode */
data->pwm_temp_map[nr] = temp_map_from_reg(data, ctrl);
@@ -1041,10 +1063,10 @@ static void it87_update_pwm_ctrl(struct it87_data *data, int nr)
int i;
for (i = 0; i < 5 ; i++)
- data->auto_temp[nr][i] = it87_read_value(data,
+ data->auto_temp[nr][i] = data->read(data,
IT87_REG_AUTO_TEMP(nr, i));
for (i = 0; i < 3 ; i++)
- data->auto_pwm[nr][i] = it87_read_value(data,
+ data->auto_pwm[nr][i] = data->read(data,
IT87_REG_AUTO_PWM(nr, i));
} else if (has_newer_autopwm(data)) {
int i;
@@ -1056,20 +1078,19 @@ static void it87_update_pwm_ctrl(struct it87_data *data, int nr)
* 3: fan max temperature (base + 2)
*/
data->auto_temp[nr][0] =
- it87_read_value(data, IT87_REG_AUTO_TEMP(nr, 5));
+ data->read(data, IT87_REG_AUTO_TEMP(nr, 5));
for (i = 0; i < 3 ; i++)
data->auto_temp[nr][i + 1] =
- it87_read_value(data,
- IT87_REG_AUTO_TEMP(nr, i));
+ data->read(data, IT87_REG_AUTO_TEMP(nr, i));
/*
* 0: start pwm value (base + 3)
* 1: pwm slope (base + 4, 1/8th pwm)
*/
data->auto_pwm[nr][0] =
- it87_read_value(data, IT87_REG_AUTO_TEMP(nr, 3));
+ data->read(data, IT87_REG_AUTO_TEMP(nr, 3));
data->auto_pwm[nr][1] =
- it87_read_value(data, IT87_REG_AUTO_TEMP(nr, 4));
+ data->read(data, IT87_REG_AUTO_TEMP(nr, 4));
}
}
@@ -1107,24 +1128,21 @@ static struct it87_data *it87_update_device(struct device *dev)
* Cleared after each update, so reenable. Value
* returned by this read will be previous value
*/
- it87_write_value(data, IT87_REG_CONFIG,
- it87_read_value(data, IT87_REG_CONFIG) | 0x40);
+ data->write(data, IT87_REG_CONFIG,
+ data->read(data, IT87_REG_CONFIG) | 0x40);
}
for (i = 0; i < NUM_VIN; i++) {
if (!(data->has_in & BIT(i)))
continue;
- data->in[i][0] =
- it87_read_value(data, IT87_REG_VIN[i]);
+ data->in[i][0] = data->read(data, IT87_REG_VIN[i]);
/* VBAT and AVCC don't have limit registers */
if (i >= NUM_VIN_LIMIT)
continue;
- data->in[i][1] =
- it87_read_value(data, IT87_REG_VIN_MIN(i));
- data->in[i][2] =
- it87_read_value(data, IT87_REG_VIN_MAX(i));
+ data->in[i][1] = data->read(data, IT87_REG_VIN_MIN(i));
+ data->in[i][2] = data->read(data, IT87_REG_VIN_MAX(i));
}
for (i = 0; i < NUM_FAN; i++) {
@@ -1132,15 +1150,13 @@ static struct it87_data *it87_update_device(struct device *dev)
if (!(data->has_fan & BIT(i)))
continue;
- data->fan[i][1] =
- it87_read_value(data, data->REG_FAN_MIN[i]);
- data->fan[i][0] = it87_read_value(data,
- data->REG_FAN[i]);
+ data->fan[i][1] = data->read(data, data->REG_FAN_MIN[i]);
+ data->fan[i][0] = data->read(data, data->REG_FAN[i]);
/* Add high byte if in 16-bit mode */
if (has_16bit_fans(data)) {
- data->fan[i][0] |= it87_read_value(data,
+ data->fan[i][0] |= data->read(data,
data->REG_FANX[i]) << 8;
- data->fan[i][1] |= it87_read_value(data,
+ data->fan[i][1] |= data->read(data,
data->REG_FANX_MIN[i]) << 8;
}
}
@@ -1148,54 +1164,52 @@ static struct it87_data *it87_update_device(struct device *dev)
if (!(data->has_temp & BIT(i)))
continue;
data->temp[i][0] =
- it87_read_value(data, IT87_REG_TEMP(i));
+ data->read(data, IT87_REG_TEMP(i));
if (i >= data->num_temp_limit)
continue;
if (i < data->num_temp_offset)
data->temp[i][3] =
- it87_read_value(data,
- data->REG_TEMP_OFFSET[i]);
+ data->read(data, data->REG_TEMP_OFFSET[i]);
data->temp[i][1] =
- it87_read_value(data, data->REG_TEMP_LOW[i]);
+ data->read(data, data->REG_TEMP_LOW[i]);
data->temp[i][2] =
- it87_read_value(data, data->REG_TEMP_HIGH[i]);
+ data->read(data, data->REG_TEMP_HIGH[i]);
}
/* Newer chips don't have clock dividers */
if ((data->has_fan & 0x07) && !has_16bit_fans(data)) {
- i = it87_read_value(data, IT87_REG_FAN_DIV);
+ i = data->read(data, IT87_REG_FAN_DIV);
data->fan_div[0] = i & 0x07;
data->fan_div[1] = (i >> 3) & 0x07;
data->fan_div[2] = (i & 0x40) ? 3 : 1;
}
data->alarms =
- it87_read_value(data, IT87_REG_ALARM1) |
- (it87_read_value(data, IT87_REG_ALARM2) << 8) |
- (it87_read_value(data, IT87_REG_ALARM3) << 16);
- data->beeps = it87_read_value(data, IT87_REG_BEEP_ENABLE);
-
- data->fan_main_ctrl = it87_read_value(data,
- IT87_REG_FAN_MAIN_CTRL);
- data->fan_ctl = it87_read_value(data, IT87_REG_FAN_CTL);
+ data->read(data, IT87_REG_ALARM1) |
+ (data->read(data, IT87_REG_ALARM2) << 8) |
+ (data->read(data, IT87_REG_ALARM3) << 16);
+ data->beeps = data->read(data, IT87_REG_BEEP_ENABLE);
+
+ data->fan_main_ctrl = data->read(data, IT87_REG_FAN_MAIN_CTRL);
+ data->fan_ctl = data->read(data, IT87_REG_FAN_CTL);
for (i = 0; i < NUM_PWM; i++) {
if (!(data->has_pwm & BIT(i)))
continue;
it87_update_pwm_ctrl(data, i);
}
- data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE);
- data->extra = it87_read_value(data, IT87_REG_TEMP_EXTRA);
+ data->sensor = data->read(data, IT87_REG_TEMP_ENABLE);
+ data->extra = data->read(data, IT87_REG_TEMP_EXTRA);
/*
* The IT8705F does not have VID capability.
* The IT8718F and later don't use IT87_REG_VID for the
* same purpose.
*/
if (data->type == it8712 || data->type == it8716) {
- data->vid = it87_read_value(data, IT87_REG_VID);
+ data->vid = data->read(data, IT87_REG_VID);
/*
* The older IT8712F revisions had only 5 VID pins,
* but we assume it is always safe to read 6 bits.
@@ -1241,10 +1255,9 @@ static ssize_t set_in(struct device *dev, struct device_attribute *attr,
return err;
data->in[nr][index] = in_to_reg(data, nr, val);
- it87_write_value(data,
- index == 1 ? IT87_REG_VIN_MIN(nr)
- : IT87_REG_VIN_MAX(nr),
- data->in[nr][index]);
+ data->write(data, index == 1 ? IT87_REG_VIN_MIN(nr)
+ : IT87_REG_VIN_MAX(nr),
+ data->in[nr][index]);
it87_unlock(data);
return count;
}
@@ -1345,10 +1358,10 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr,
reg = data->REG_TEMP_HIGH[nr];
break;
case 3:
- regval = it87_read_value(data, IT87_REG_BEEP_ENABLE);
+ regval = data->read(data, IT87_REG_BEEP_ENABLE);
if (!(regval & 0x80)) {
regval |= 0x80;
- it87_write_value(data, IT87_REG_BEEP_ENABLE, regval);
+ data->write(data, IT87_REG_BEEP_ENABLE, regval);
}
data->valid = 0;
reg = data->REG_TEMP_OFFSET[nr];
@@ -1356,7 +1369,7 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr,
}
data->temp[nr][index] = TEMP_TO_REG(val);
- it87_write_value(data, reg, data->temp[nr][index]);
+ data->write(data, reg, data->temp[nr][index]);
it87_unlock(data);
return count;
}
@@ -1459,8 +1472,8 @@ static int get_temp_type(struct it87_data *data, int index)
if (type || index >= 3)
return type;
- reg = it87_read_value(data, IT87_REG_TEMP_ENABLE);
- extra = it87_read_value(data, IT87_REG_TEMP_EXTRA);
+ reg = data->read(data, IT87_REG_TEMP_ENABLE);
+ extra = data->read(data, IT87_REG_TEMP_EXTRA);
if ((has_temp_peci(data, index) && (reg >> 6 == index + 1)) ||
(has_temp_old_peci(data, index) && (extra & 0x80)))
@@ -1505,12 +1518,12 @@ static ssize_t set_temp_type(struct device *dev, struct device_attribute *attr,
if (err)
return err;
- reg = it87_read_value(data, IT87_REG_TEMP_ENABLE);
+ reg = data->read(data, IT87_REG_TEMP_ENABLE);
reg &= ~(1 << nr);
reg &= ~(8 << nr);
if (has_temp_peci(data, nr) && (reg >> 6 == nr + 1 || val == 6))
reg &= 0x3f;
- extra = it87_read_value(data, IT87_REG_TEMP_EXTRA);
+ extra = data->read(data, IT87_REG_TEMP_EXTRA);
if (has_temp_old_peci(data, nr) && ((extra & 0x80) || val == 6))
extra &= 0x7f;
if (val == 2) { /* backwards compatibility */
@@ -1534,9 +1547,9 @@ static ssize_t set_temp_type(struct device *dev, struct device_attribute *attr,
data->sensor = reg;
data->extra = extra;
- it87_write_value(data, IT87_REG_TEMP_ENABLE, data->sensor);
+ data->write(data, IT87_REG_TEMP_ENABLE, data->sensor);
if (has_temp_old_peci(data, nr))
- it87_write_value(data, IT87_REG_TEMP_EXTRA, data->extra);
+ data->write(data, IT87_REG_TEMP_EXTRA, data->extra);
data->valid = 0; /* Force cache refresh */
unlock:
it87_unlock(data);
@@ -1674,12 +1687,12 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *attr,
if (has_16bit_fans(data)) {
data->fan[nr][index] = FAN16_TO_REG(val);
- it87_write_value(data, data->REG_FAN_MIN[nr],
- data->fan[nr][index] & 0xff);
- it87_write_value(data, data->REG_FANX_MIN[nr],
- data->fan[nr][index] >> 8);
+ data->write(data, data->REG_FAN_MIN[nr],
+ data->fan[nr][index] & 0xff);
+ data->write(data, data->REG_FANX_MIN[nr],
+ data->fan[nr][index] >> 8);
} else {
- reg = it87_read_value(data, IT87_REG_FAN_DIV);
+ reg = data->read(data, IT87_REG_FAN_DIV);
switch (nr) {
case 0:
data->fan_div[nr] = reg & 0x07;
@@ -1693,8 +1706,7 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *attr,
}
data->fan[nr][index] =
FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
- it87_write_value(data, data->REG_FAN_MIN[nr],
- data->fan[nr][index]);
+ data->write(data, data->REG_FAN_MIN[nr], data->fan[nr][index]);
}
it87_unlock(data);
return count;
@@ -1717,7 +1729,7 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
if (err)
return err;
- old = it87_read_value(data, IT87_REG_FAN_DIV);
+ old = data->read(data, IT87_REG_FAN_DIV);
/* Save fan min limit */
min = FAN_FROM_REG(data->fan[nr][1], DIV_FROM_REG(data->fan_div[nr]));
@@ -1738,11 +1750,11 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
val |= (data->fan_div[1] & 0x07) << 3;
if (data->fan_div[2] == 3)
val |= 0x1 << 6;
- it87_write_value(data, IT87_REG_FAN_DIV, val);
+ data->write(data, IT87_REG_FAN_DIV, val);
/* Restore fan min limit */
data->fan[nr][1] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
- it87_write_value(data, data->REG_FAN_MIN[nr], data->fan[nr][1]);
+ data->write(data, data->REG_FAN_MIN[nr], data->fan[nr][1]);
it87_unlock(data);
return count;
}
@@ -1805,19 +1817,19 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr,
if (nr < 3 && has_fanctl_onoff(data)) {
int tmp;
/* make sure the fan is on when in on/off mode */
- tmp = it87_read_value(data, IT87_REG_FAN_CTL);
- it87_write_value(data, IT87_REG_FAN_CTL, tmp | BIT(nr));
+ tmp = data->read(data, IT87_REG_FAN_CTL);
+ data->write(data, IT87_REG_FAN_CTL, tmp | BIT(nr));
/* set on/off mode */
data->fan_main_ctrl &= ~BIT(nr);
- it87_write_value(data, IT87_REG_FAN_MAIN_CTRL,
- data->fan_main_ctrl);
+ data->write(data, IT87_REG_FAN_MAIN_CTRL,
+ data->fan_main_ctrl);
} else {
u8 ctrl;
/* No on/off mode, set maximum pwm value */
data->pwm_duty[nr] = pwm_to_reg(data, 0xff);
- it87_write_value(data, IT87_REG_PWM_DUTY[nr],
- data->pwm_duty[nr]);
+ data->write(data, IT87_REG_PWM_DUTY[nr],
+ data->pwm_duty[nr]);
/* and set manual mode */
if (has_newer_autopwm(data)) {
ctrl = temp_map_to_reg(data, nr,
@@ -1827,7 +1839,7 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr,
ctrl = data->pwm_duty[nr];
}
data->pwm_ctrl[nr] = ctrl;
- it87_write_value(data, data->REG_PWM[nr], ctrl);
+ data->write(data, data->REG_PWM[nr], ctrl);
}
} else {
u8 ctrl;
@@ -1843,13 +1855,13 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr,
ctrl = (val == 1 ? data->pwm_duty[nr] : 0x80);
}
data->pwm_ctrl[nr] = ctrl;
- it87_write_value(data, data->REG_PWM[nr], ctrl);
+ data->write(data, data->REG_PWM[nr], ctrl);
if (has_fanctl_onoff(data) && nr < 3) {
/* set SmartGuardian mode */
data->fan_main_ctrl |= BIT(nr);
- it87_write_value(data, IT87_REG_FAN_MAIN_CTRL,
- data->fan_main_ctrl);
+ data->write(data, IT87_REG_FAN_MAIN_CTRL,
+ data->fan_main_ctrl);
}
}
it87_unlock(data);
@@ -1883,8 +1895,8 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
goto unlock;
}
data->pwm_duty[nr] = pwm_to_reg(data, val);
- it87_write_value(data, IT87_REG_PWM_DUTY[nr],
- data->pwm_duty[nr]);
+ data->write(data, IT87_REG_PWM_DUTY[nr],
+ data->pwm_duty[nr]);
} else {
data->pwm_duty[nr] = pwm_to_reg(data, val);
/*
@@ -1893,8 +1905,8 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
*/
if (!(data->pwm_ctrl[nr] & 0x80)) {
data->pwm_ctrl[nr] = data->pwm_duty[nr];
- it87_write_value(data, data->REG_PWM[nr],
- data->pwm_ctrl[nr]);
+ data->write(data, data->REG_PWM[nr],
+ data->pwm_ctrl[nr]);
}
}
unlock:
@@ -1929,13 +1941,13 @@ static ssize_t set_pwm_freq(struct device *dev, struct device_attribute *attr,
return err;
if (nr == 0) {
- data->fan_ctl = it87_read_value(data, IT87_REG_FAN_CTL) & 0x8f;
+ data->fan_ctl = data->read(data, IT87_REG_FAN_CTL) & 0x8f;
data->fan_ctl |= i << 4;
- it87_write_value(data, IT87_REG_FAN_CTL, data->fan_ctl);
+ data->write(data, IT87_REG_FAN_CTL, data->fan_ctl);
} else {
- data->extra = it87_read_value(data, IT87_REG_TEMP_EXTRA) & 0x8f;
+ data->extra = data->read(data, IT87_REG_TEMP_EXTRA) & 0x8f;
data->extra |= i << 4;
- it87_write_value(data, IT87_REG_TEMP_EXTRA, data->extra);
+ data->write(data, IT87_REG_TEMP_EXTRA, data->extra);
}
it87_unlock(data);
return count;
@@ -1985,7 +1997,7 @@ static ssize_t set_pwm_temp_map(struct device *dev,
*/
if (data->pwm_ctrl[nr] & 0x80) {
data->pwm_ctrl[nr] = temp_map_to_reg(data, nr, map);
- it87_write_value(data, data->REG_PWM[nr], data->pwm_ctrl[nr]);
+ data->write(data, data->REG_PWM[nr], data->pwm_ctrl[nr]);
}
it87_unlock(data);
return count;
@@ -2031,7 +2043,7 @@ static ssize_t set_auto_pwm(struct device *dev, struct device_attribute *attr,
regaddr = IT87_REG_AUTO_TEMP(nr, 3);
else
regaddr = IT87_REG_AUTO_PWM(nr, point);
- it87_write_value(data, regaddr, data->auto_pwm[nr][point]);
+ data->write(data, regaddr, data->auto_pwm[nr][point]);
it87_unlock(data);
return count;
}
@@ -2067,8 +2079,7 @@ static ssize_t set_auto_pwm_slope(struct device *dev,
return err;
data->auto_pwm[nr][1] = (data->auto_pwm[nr][1] & 0x80) | val;
- it87_write_value(data, IT87_REG_AUTO_TEMP(nr, 4),
- data->auto_pwm[nr][1]);
+ data->write(data, IT87_REG_AUTO_TEMP(nr, 4), data->auto_pwm[nr][1]);
it87_unlock(data);
return count;
}
@@ -2117,13 +2128,13 @@ static ssize_t set_auto_temp(struct device *dev, struct device_attribute *attr,
reg = data->auto_temp[nr][1] - TEMP_TO_REG(val);
reg = clamp_val(reg, 0, 0x1f) | (data->auto_temp[nr][0] & 0xe0);
data->auto_temp[nr][0] = reg;
- it87_write_value(data, IT87_REG_AUTO_TEMP(nr, 5), reg);
+ data->write(data, IT87_REG_AUTO_TEMP(nr, 5), reg);
} else {
reg = TEMP_TO_REG(val);
data->auto_temp[nr][point] = reg;
if (has_newer_autopwm(data))
point--;
- it87_write_value(data, IT87_REG_AUTO_TEMP(nr, point), reg);
+ data->write(data, IT87_REG_AUTO_TEMP(nr, point), reg);
}
it87_unlock(data);
return count;
@@ -2344,9 +2355,9 @@ static ssize_t clear_intrusion(struct device *dev,
if (err)
return err;
- config = it87_read_value(data, IT87_REG_CONFIG);
+ config = data->read(data, IT87_REG_CONFIG);
config |= BIT(5);
- it87_write_value(data, IT87_REG_CONFIG, config);
+ data->write(data, IT87_REG_CONFIG, config);
/* Invalidate cache to force re-read */
data->valid = 0;
it87_unlock(data);
@@ -2403,12 +2414,12 @@ static ssize_t set_beep(struct device *dev, struct device_attribute *attr,
if (err)
return err;
- data->beeps = it87_read_value(data, IT87_REG_BEEP_ENABLE);
+ data->beeps = data->read(data, IT87_REG_BEEP_ENABLE);
if (val)
data->beeps |= BIT(bitnr);
else
data->beeps &= ~BIT(bitnr);
- it87_write_value(data, IT87_REG_BEEP_ENABLE, data->beeps);
+ data->write(data, IT87_REG_BEEP_ENABLE, data->beeps);
it87_unlock(data);
return count;
}
@@ -2942,9 +2953,10 @@ static const struct attribute_group it87_group_auto_pwm = {
/* SuperIO detection - will change isa_address if a chip is found */
static int __init it87_find(int sioaddr, unsigned short *address,
- struct it87_sio_data *sio_data)
+ phys_addr_t *mmio_address, struct it87_sio_data *sio_data)
{
const struct it87_devices *config;
+ phys_addr_t base = 0;
bool doexit = true;
u16 chip_type;
int err;
@@ -3082,6 +3094,17 @@ static int __init it87_find(int sioaddr, unsigned short *address,
config = &it87_devices[sio_data->type];
+ if (has_mmio(config) && mmio) {
+ u8 reg;
+
+ reg = superio_inb(sioaddr, IT87_EC_HWM_MIO_REG);
+ if (reg & BIT(5)) {
+ base = 0xf0000000 + ((reg & 0x0f) << 24);
+ base += (reg & 0xc0) << 14;
+ }
+ }
+ *mmio_address = base;
+
/* in7 (VSB or VCCH5V) is always internal on some chips */
if (has_in7_internal(config))
sio_data->internal |= BIT(1);
@@ -3558,7 +3581,7 @@ static int __init it87_find(int sioaddr, unsigned short *address,
if (sio_data->beep_pin)
pr_info("Beeping is supported\n");
- if (config->smbus_bitmap) {
+ if (config->smbus_bitmap && !base) {
u8 reg;
superio_select(sioaddr, PME);
@@ -3584,14 +3607,14 @@ static void it87_check_limit_regs(struct it87_data *data)
int i, reg;
for (i = 0; i < NUM_VIN_LIMIT; i++) {
- reg = it87_read_value(data, IT87_REG_VIN_MIN(i));
+ reg = data->read(data, IT87_REG_VIN_MIN(i));
if (reg == 0xff)
- it87_write_value(data, IT87_REG_VIN_MIN(i), 0);
+ data->write(data, IT87_REG_VIN_MIN(i), 0);
}
for (i = 0; i < data->num_temp_limit; i++) {
- reg = it87_read_value(data, data->REG_TEMP_HIGH[i]);
+ reg = data->read(data, data->REG_TEMP_HIGH[i]);
if (reg == 0xff)
- it87_write_value(data, data->REG_TEMP_HIGH[i], 127);
+ data->write(data, data->REG_TEMP_HIGH[i], 127);
}
}
@@ -3600,10 +3623,10 @@ static void it87_check_voltage_monitors_reset(struct it87_data *data)
{
int reg;
- reg = it87_read_value(data, IT87_REG_VIN_ENABLE);
+ reg = data->read(data, IT87_REG_VIN_ENABLE);
if ((reg & 0xff) == 0) {
/* Enable all voltage monitors */
- it87_write_value(data, IT87_REG_VIN_ENABLE, 0xff);
+ data->write(data, IT87_REG_VIN_ENABLE, 0xff);
}
}
@@ -3615,11 +3638,11 @@ static void it87_check_tachometers_reset(struct platform_device *pdev)
u8 mask, fan_main_ctrl;
mask = 0x70 & ~(sio_data->skip_fan << 4);
- fan_main_ctrl = it87_read_value(data, IT87_REG_FAN_MAIN_CTRL);
+ fan_main_ctrl = data->read(data, IT87_REG_FAN_MAIN_CTRL);
if ((fan_main_ctrl & mask) == 0) {
/* Enable all fan tachometers */
fan_main_ctrl |= mask;
- it87_write_value(data, IT87_REG_FAN_MAIN_CTRL,
+ data->write(data, IT87_REG_FAN_MAIN_CTRL,
fan_main_ctrl);
}
}
@@ -3633,11 +3656,11 @@ static void it87_check_tachometers_16bit_mode(struct platform_device *pdev)
if (!has_fan16_config(data))
return;
- reg = it87_read_value(data, IT87_REG_FAN_16BIT);
+ reg = data->read(data, IT87_REG_FAN_16BIT);
if (~reg & 0x07 & data->has_fan) {
dev_dbg(&pdev->dev,
"Setting fan1-3 to 16-bit mode\n");
- it87_write_value(data, IT87_REG_FAN_16BIT,
+ data->write(data, IT87_REG_FAN_16BIT,
reg | 0x07);
}
}
@@ -3648,12 +3671,12 @@ static void it87_start_monitoring(struct it87_data *data)
int i;
for (i = 0; i < 3; i++)
data->temp_src[i] =
- it87_read_value(data, IT87_REG_TEMP_SRC1[i]);
- data->temp_src[3] = it87_read_value(data, IT87_REG_TEMP_SRC2);
+ data->read(data, IT87_REG_TEMP_SRC1[i]);
+ data->temp_src[3] = data->read(data, IT87_REG_TEMP_SRC2);
}
- it87_write_value(data, IT87_REG_CONFIG,
- (it87_read_value(data, IT87_REG_CONFIG) & 0x3e)
+ data->write(data, IT87_REG_CONFIG,
+ (data->read(data, IT87_REG_CONFIG) & 0x3e)
| (update_vbat ? 0x41 : 0x01));
}
@@ -3717,6 +3740,17 @@ static void it87_init_regs(struct platform_device *pdev)
data->REG_TEMP_HIGH = IT87_REG_TEMP_HIGH;
break;
}
+
+ if (data->mmio) {
+ data->read = it87_mmio_read;
+ data->write = it87_mmio_write;
+ } else if (has_bank_sel(data)) {
+ data->read = it87_io_read;
+ data->write = it87_io_write;
+ } else {
+ data->read = _it87_io_read;
+ data->write = _it87_io_write;
+ }
}
/* Called when we have found a new IT87. */
@@ -3766,13 +3800,13 @@ static void it87_init_device(struct platform_device *pdev)
it87_check_tachometers_reset(pdev);
- data->fan_main_ctrl = it87_read_value(data, IT87_REG_FAN_MAIN_CTRL);
+ data->fan_main_ctrl = data->read(data, IT87_REG_FAN_MAIN_CTRL);
data->has_fan = (data->fan_main_ctrl >> 4) & 0x07;
it87_check_tachometers_16bit_mode(pdev);
/* Check for additional fans */
- tmp = it87_read_value(data, IT87_REG_FAN_16BIT);
+ tmp = data->read(data, IT87_REG_FAN_16BIT);
if (has_four_fans(data) && (tmp & BIT(4)))
data->has_fan |= BIT(3); /* fan4 enabled */
@@ -3788,7 +3822,7 @@ static void it87_init_device(struct platform_device *pdev)
break;
case it8625:
case it8665:
- tmp = it87_read_value(data, IT87_REG_FAN_DIV);
+ tmp = data->read(data, IT87_REG_FAN_DIV);
if (tmp & BIT(3))
data->has_fan |= BIT(5); /* fan6 enabled */
break;
@@ -3805,7 +3839,7 @@ static void it87_init_device(struct platform_device *pdev)
switch (data->type) {
case it8620:
case it8686:
- tmp = it87_read_value(data, IT87_REG_FAN_DIV);
+ tmp = data->read(data, IT87_REG_FAN_DIV);
if (!(tmp & BIT(3)))
sio_data->skip_pwm |= BIT(5);
break;
@@ -3826,7 +3860,7 @@ static int it87_check_pwm(struct device *dev)
* and polarity set to active low is sign that this is the case so we
* disable pwm control to protect the user.
*/
- int tmp = it87_read_value(data, IT87_REG_FAN_CTL);
+ int tmp = data->read(data, IT87_REG_FAN_CTL);
if ((tmp & 0x87) == 0) {
if (fix_pwm_polarity) {
@@ -3839,7 +3873,7 @@ static int it87_check_pwm(struct device *dev)
u8 pwm[3];
for (i = 0; i < ARRAY_SIZE(pwm); i++)
- pwm[i] = it87_read_value(data,
+ pwm[i] = data->read(data,
data->REG_PWM[i]);
/*
@@ -3851,12 +3885,10 @@ static int it87_check_pwm(struct device *dev)
if (!((pwm[0] | pwm[1] | pwm[2]) & 0x80)) {
dev_info(dev,
"Reconfiguring PWM to active high polarity\n");
- it87_write_value(data, IT87_REG_FAN_CTL,
- tmp | 0x87);
+ data->write(data, IT87_REG_FAN_CTL, tmp | 0x87);
for (i = 0; i < 3; i++)
- it87_write_value(data,
- data->REG_PWM[i],
- 0x7f & ~pwm[i]);
+ data->write(data, data->REG_PWM[i],
+ 0x7f & ~pwm[i]);
return 1;
}
@@ -3883,19 +3915,25 @@ static int it87_probe(struct platform_device *pdev)
struct device *hwmon_dev;
int err;
- res = platform_get_resource(pdev, IORESOURCE_IO, 0);
- if (!devm_request_region(&pdev->dev, res->start, IT87_EC_EXTENT,
- DRVNAME)) {
- dev_err(dev, "Failed to request region 0x%lx-0x%lx\n",
- (unsigned long)res->start,
- (unsigned long)(res->start + IT87_EC_EXTENT - 1));
- return -EBUSY;
- }
-
- data = devm_kzalloc(&pdev->dev, sizeof(struct it87_data), GFP_KERNEL);
+ data = devm_kzalloc(dev, sizeof(struct it87_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
+ res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ if (!res)
+ return -EINVAL;
+ if (res->flags & IORESOURCE_IO) {
+ if (!devm_request_region(dev, res->start, IT87_EC_EXTENT,
+ DRVNAME)) {
+ dev_err(dev, "Failed to request region %pR\n", res);
+ return -EBUSY;
+ }
+ } else {
+ data->mmio = devm_ioremap_resource(dev, res);
+ if (IS_ERR(data->mmio))
+ return PTR_ERR(data->mmio);
+ }
+
data->addr = res->start;
data->sioaddr = sio_data->sioaddr;
data->type = sio_data->type;
@@ -3945,8 +3983,8 @@ static int it87_probe(struct platform_device *pdev)
return err;
/* Now, we do the remaining detection. */
- if ((it87_read_value(data, IT87_REG_CONFIG) & 0x80) ||
- it87_read_value(data, IT87_REG_CHIPID) != 0x90) {
+ if ((data->read(data, IT87_REG_CONFIG) & 0x80) ||
+ data->read(data, IT87_REG_CHIPID) != 0x90) {
smbus_enable(data);
return -ENODEV;
}
@@ -3978,7 +4016,7 @@ static int it87_probe(struct platform_device *pdev)
data->has_temp = 0x07;
if (sio_data->skip_temp & BIT(2)) {
if (sio_data->type == it8782 &&
- !(it87_read_value(data, IT87_REG_TEMP_EXTRA) & 0x80))
+ !(data->read(data, IT87_REG_TEMP_EXTRA) & 0x80))
data->has_temp &= ~BIT(2);
}
@@ -3987,7 +4025,7 @@ static int it87_probe(struct platform_device *pdev)
data->has_in = 0x3ff & ~sio_data->skip_in;
if (has_six_temp(data)) {
- u8 reg = it87_read_value(data, IT87_REG_TEMP456_ENABLE);
+ u8 reg = data->read(data, IT87_REG_TEMP456_ENABLE);
/* Check for additional temperature sensors */
if ((reg & 0x03) >= 0x02)
@@ -4111,25 +4149,33 @@ static struct platform_driver it87_driver = {
.probe = it87_probe,
};
-static int __init it87_device_add(int index, unsigned short address,
+static int __init it87_device_add(int index, unsigned short sio_address,
+ phys_addr_t mmio_address,
const struct it87_sio_data *sio_data)
{
struct platform_device *pdev;
struct resource res = {
- .start = address + IT87_EC_OFFSET,
- .end = address + IT87_EC_OFFSET + IT87_EC_EXTENT - 1,
.name = DRVNAME,
- .flags = IORESOURCE_IO,
};
int err;
+ if (mmio_address) {
+ res.start = mmio_address;
+ res.end = mmio_address + 0x400 - 1;
+ res.flags = IORESOURCE_MEM;
+ } else {
+ res.start = sio_address + IT87_EC_OFFSET;
+ res.end = sio_address + IT87_EC_OFFSET + IT87_EC_EXTENT - 1;
+ res.flags = IORESOURCE_IO;
+ }
+
err = acpi_check_resource_conflict(&res);
if (err) {
if (!ignore_resource_conflict)
return err;
}
- pdev = platform_device_alloc(DRVNAME, address);
+ pdev = platform_device_alloc(DRVNAME, sio_address);
if (!pdev)
return -ENOMEM;
@@ -4234,6 +4280,7 @@ static int __init sm_it87_init(void)
int sioaddr[2] = { REG_2E, REG_4E };
struct it87_sio_data sio_data;
unsigned short isa_address[2];
+ phys_addr_t mmio_address;
bool found = false;
int i, err;
@@ -4250,7 +4297,9 @@ static int __init sm_it87_init(void)
for (i = 0; i < ARRAY_SIZE(sioaddr); i++) {
memset(&sio_data, 0, sizeof(struct it87_sio_data));
isa_address[i] = 0;
- err = it87_find(sioaddr[i], &isa_address[i], &sio_data);
+ mmio_address = 0;
+ err = it87_find(sioaddr[i], &isa_address[i],
+ &mmio_address, &sio_data);
if (err || isa_address[i] == 0)
continue;
/*
@@ -4262,7 +4311,8 @@ static int __init sm_it87_init(void)
if (dmi_data)
sio_data.skip_pwm |= dmi_data->skip_pwm;
- err = it87_device_add(i, isa_address[i], &sio_data);
+ err = it87_device_add(i, isa_address[i], mmio_address,
+ &sio_data);
if (err)
goto exit_dev_unregister;
--
2.20.1
From 2a3cdf1d39b4068b69984264e92977d7133beb63 Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Sun, 1 Oct 2017 13:02:59 -0700
Subject: [PATCH 43/61] Print MMIO address into kernel log
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 9ccce1b..99eb59a 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -2958,6 +2958,7 @@ static int __init it87_find(int sioaddr, unsigned short *address,
const struct it87_devices *config;
phys_addr_t base = 0;
bool doexit = true;
+ char mmio_str[32];
u16 chip_type;
int err;
@@ -3088,9 +3089,6 @@ static int __init it87_find(int sioaddr, unsigned short *address,
err = 0;
sio_data->sioaddr = sioaddr;
sio_data->revision = superio_inb(sioaddr, DEVREV) & 0x0f;
- pr_info("Found IT%04x%s chip at 0x%x, revision %d\n", chip_type,
- it87_devices[sio_data->type].suffix,
- *address, sio_data->revision);
config = &it87_devices[sio_data->type];
@@ -3105,6 +3103,14 @@ static int __init it87_find(int sioaddr, unsigned short *address,
}
*mmio_address = base;
+ mmio_str[0] = '\0';
+ if (base)
+ snprintf(mmio_str, sizeof(mmio_str), " [MMIO at %pa]", &base);
+
+ pr_info("Found IT%04x%s chip at 0x%x%s, revision %d\n", chip_type,
+ it87_devices[sio_data->type].suffix,
+ *address, mmio_str, sio_data->revision);
+
/* in7 (VSB or VCCH5V) is always internal on some chips */
if (has_in7_internal(config))
sio_data->internal |= BIT(1);
--
2.20.1
From 8e0d4d62cf390538776c941f4ed984588629201b Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Sun, 1 Oct 2017 13:40:18 -0700
Subject: [PATCH 44/61] Fix mmio resource request
We have to request a memory resource with IORESOURCE_MEM.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 99eb59a..c4f24f0 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -3926,15 +3926,14 @@ static int it87_probe(struct platform_device *pdev)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
- if (!res)
- return -EINVAL;
- if (res->flags & IORESOURCE_IO) {
+ if (res) {
if (!devm_request_region(dev, res->start, IT87_EC_EXTENT,
DRVNAME)) {
dev_err(dev, "Failed to request region %pR\n", res);
return -EBUSY;
}
} else {
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
data->mmio = devm_ioremap_resource(dev, res);
if (IS_ERR(data->mmio))
return PTR_ERR(data->mmio);
--
2.20.1
From 1376ff402872c5ce44da02487d2390239000b0f4 Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Sun, 1 Oct 2017 15:28:24 -0700
Subject: [PATCH 45/61] Add SMBus bitmap for IT8622
IT8622 supports two external SMBus channels. Add bitmask to disable them
while accessing the chip.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index c4f24f0..7811a30 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -615,6 +615,7 @@ static const struct it87_devices it87_devices[] = {
.num_temp_offset = 3,
.num_temp_map = 4,
.peci_mask = 0x07,
+ .smbus_bitmap = BIT(1) | BIT(2),
},
[it8625] = {
.name = "it8625",
--
2.20.1
From 1d8515188dc238d6ef57144efbe8c1aa1c39ec4e Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Sun, 1 Oct 2017 16:39:31 -0700
Subject: [PATCH 46/61] Improve AMDTSI temp type detection, and temp 4 type
detection on IT8622
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 30 ++++++++++++++++++++++++++----
1 file changed, 26 insertions(+), 4 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 7811a30..bedadd3 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -614,7 +614,7 @@ static const struct it87_devices it87_devices[] = {
.num_temp_limit = 3,
.num_temp_offset = 3,
.num_temp_map = 4,
- .peci_mask = 0x07,
+ .peci_mask = 0x0f,
.smbus_bitmap = BIT(1) | BIT(2),
},
[it8625] = {
@@ -1430,7 +1430,7 @@ static const u8 temp_types_8686[NUM_TEMP][9] = {
static int get_temp_type(struct it87_data *data, int index)
{
u8 reg, extra;
- int type = 0;
+ int ttype, type = 0;
if (has_bank_sel(data)) {
u8 src1, src2;
@@ -1470,15 +1470,37 @@ static int get_temp_type(struct it87_data *data, int index)
return 0;
}
}
- if (type || index >= 3)
+ if (type)
return type;
+ /* Dectect PECI vs. AMDTSI if possible */
+ ttype = 6;
+ if ((has_temp_peci(data, index)) && data->type != it8721) {
+ extra = data->read(data, 0x98); /* PCH/AMDTSI host status */
+ if (extra & BIT(6))
+ ttype = 5;
+ }
+
reg = data->read(data, IT87_REG_TEMP_ENABLE);
+
+ /* Per chip special detection */
+ switch (data->type) {
+ case it8622:
+ if (!(reg & 0xc0) && index == 3)
+ type = ttype;
+ break;
+ default:
+ break;
+ }
+
+ if (type || index >= 3)
+ return type;
+
extra = data->read(data, IT87_REG_TEMP_EXTRA);
if ((has_temp_peci(data, index) && (reg >> 6 == index + 1)) ||
(has_temp_old_peci(data, index) && (extra & 0x80)))
- type = 6; /* Intel PECI */
+ type = ttype; /* Intel PECI or AMDTSI */
if (reg & BIT(index))
type = 3; /* thermal diode */
else if (reg & BIT(index + 3))
--
2.20.1
From 632b30964076e4db17b06a105e9c407b00ab5307 Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Sun, 1 Oct 2017 16:47:43 -0700
Subject: [PATCH 47/61] Add support for 4th temperature sensor on IT8622
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index bedadd3..d1bdedd 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -370,6 +370,7 @@ struct it87_devices {
#define FEAT_11MV_ADC BIT(24)
#define FEAT_NEW_TEMPMAP BIT(25) /* new temp input selection */
#define FEAT_MMIO BIT(26) /* Chip supports MMIO */
+#define FEAT_FOUR_TEMP BIT(27)
static const struct it87_devices it87_devices[] = {
[it87] = {
@@ -608,7 +609,7 @@ static const struct it87_devices it87_devices[] = {
.name = "it8622",
.suffix = "E",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
- | FEAT_TEMP_PECI | FEAT_FIVE_FANS
+ | FEAT_TEMP_PECI | FEAT_FIVE_FANS | FEAT_FOUR_TEMP
| FEAT_FIVE_PWM | FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2
| FEAT_AVCC3 | FEAT_VIN3_5V | FEAT_SCALING,
.num_temp_limit = 3,
@@ -714,6 +715,7 @@ static const struct it87_devices it87_devices[] = {
#define has_11mv_adc(data) ((data)->features & FEAT_11MV_ADC)
#define has_new_tempmap(data) ((data)->features & FEAT_NEW_TEMPMAP)
#define has_mmio(data) ((data)->features & FEAT_MMIO)
+#define has_four_temp(data) ((data)->features & FEAT_FOUR_TEMP)
struct it87_sio_data {
u8 sioaddr;
@@ -4052,7 +4054,9 @@ static int it87_probe(struct platform_device *pdev)
data->need_in7_reroute = sio_data->need_in7_reroute;
data->has_in = 0x3ff & ~sio_data->skip_in;
- if (has_six_temp(data)) {
+ if (has_four_temp(data)) {
+ data->has_temp |= BIT(3);
+ } else if (has_six_temp(data)) {
u8 reg = data->read(data, IT87_REG_TEMP456_ENABLE);
/* Check for additional temperature sensors */
--
2.20.1
From 12a4ace0cf8099d79c57b2902d33e4bc73eaa669 Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Mon, 2 Oct 2017 07:51:19 -0700
Subject: [PATCH 48/61] Checkpatch cleanup: Use octal permissions for module
parameters BLAME,SQUASH
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index d1bdedd..5cddec3 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -82,15 +82,15 @@ enum chips { it87, it8712, it8716, it8718, it8720, it8721, it8728, it8732,
it8655, it8665, it8686 };
static unsigned short force_id;
-module_param(force_id, ushort, 0);
+module_param(force_id, ushort, 0000);
MODULE_PARM_DESC(force_id, "Override the detected device ID");
static bool ignore_resource_conflict;
-module_param(ignore_resource_conflict, bool, 0);
+module_param(ignore_resource_conflict, bool, 0000);
MODULE_PARM_DESC(ignore_resource_conflict, "Ignore ACPI resource conflict");
static bool mmio;
-module_param(mmio, bool, 0);
+module_param(mmio, bool, 0000);
MODULE_PARM_DESC(mmio, "Use MMIO if available");
static struct platform_device *it87_pdev[2];
@@ -4382,9 +4382,9 @@ static void __exit sm_it87_exit(void)
MODULE_AUTHOR("Chris Gauthron, Jean Delvare <jdelvare@suse.de>");
MODULE_DESCRIPTION("IT8705F/IT871xF/IT872xF hardware monitoring driver");
-module_param(update_vbat, bool, 0);
+module_param(update_vbat, bool, 0000);
MODULE_PARM_DESC(update_vbat, "Update vbat if set else return powerup value");
-module_param(fix_pwm_polarity, bool, 0);
+module_param(fix_pwm_polarity, bool, 0000);
MODULE_PARM_DESC(fix_pwm_polarity,
"Force PWM polarity to active high (DANGEROUS)");
MODULE_LICENSE("GPL");
--
2.20.1
From 768191f12d5f0ed83831d71f13dee4aead70c1cf Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Mon, 2 Oct 2017 07:56:47 -0700
Subject: [PATCH 49/61] Checkpatch cleanup: Use octal file permissions
BLAME,SQUASH
Symbolic file permissions ran out of favor and result in a checkpatch
warning. Use octal permissions instead.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 472 ++++++++++++++++++++++++++-------------------------------
1 file changed, 211 insertions(+), 261 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 5cddec3..a43da8c 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -1265,59 +1265,43 @@ static ssize_t set_in(struct device *dev, struct device_attribute *attr,
return count;
}
-static SENSOR_DEVICE_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0);
-static SENSOR_DEVICE_ATTR_2(in0_min, S_IRUGO | S_IWUSR, show_in, set_in,
- 0, 1);
-static SENSOR_DEVICE_ATTR_2(in0_max, S_IRUGO | S_IWUSR, show_in, set_in,
- 0, 2);
-
-static SENSOR_DEVICE_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 1, 0);
-static SENSOR_DEVICE_ATTR_2(in1_min, S_IRUGO | S_IWUSR, show_in, set_in,
- 1, 1);
-static SENSOR_DEVICE_ATTR_2(in1_max, S_IRUGO | S_IWUSR, show_in, set_in,
- 1, 2);
-
-static SENSOR_DEVICE_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 2, 0);
-static SENSOR_DEVICE_ATTR_2(in2_min, S_IRUGO | S_IWUSR, show_in, set_in,
- 2, 1);
-static SENSOR_DEVICE_ATTR_2(in2_max, S_IRUGO | S_IWUSR, show_in, set_in,
- 2, 2);
-
-static SENSOR_DEVICE_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 3, 0);
-static SENSOR_DEVICE_ATTR_2(in3_min, S_IRUGO | S_IWUSR, show_in, set_in,
- 3, 1);
-static SENSOR_DEVICE_ATTR_2(in3_max, S_IRUGO | S_IWUSR, show_in, set_in,
- 3, 2);
-
-static SENSOR_DEVICE_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 4, 0);
-static SENSOR_DEVICE_ATTR_2(in4_min, S_IRUGO | S_IWUSR, show_in, set_in,
- 4, 1);
-static SENSOR_DEVICE_ATTR_2(in4_max, S_IRUGO | S_IWUSR, show_in, set_in,
- 4, 2);
-
-static SENSOR_DEVICE_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 5, 0);
-static SENSOR_DEVICE_ATTR_2(in5_min, S_IRUGO | S_IWUSR, show_in, set_in,
- 5, 1);
-static SENSOR_DEVICE_ATTR_2(in5_max, S_IRUGO | S_IWUSR, show_in, set_in,
- 5, 2);
-
-static SENSOR_DEVICE_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 6, 0);
-static SENSOR_DEVICE_ATTR_2(in6_min, S_IRUGO | S_IWUSR, show_in, set_in,
- 6, 1);
-static SENSOR_DEVICE_ATTR_2(in6_max, S_IRUGO | S_IWUSR, show_in, set_in,
- 6, 2);
-
-static SENSOR_DEVICE_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 7, 0);
-static SENSOR_DEVICE_ATTR_2(in7_min, S_IRUGO | S_IWUSR, show_in, set_in,
- 7, 1);
-static SENSOR_DEVICE_ATTR_2(in7_max, S_IRUGO | S_IWUSR, show_in, set_in,
- 7, 2);
-
-static SENSOR_DEVICE_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 8, 0);
-static SENSOR_DEVICE_ATTR_2(in9_input, S_IRUGO, show_in, NULL, 9, 0);
-static SENSOR_DEVICE_ATTR_2(in10_input, S_IRUGO, show_in, NULL, 10, 0);
-static SENSOR_DEVICE_ATTR_2(in11_input, S_IRUGO, show_in, NULL, 11, 0);
-static SENSOR_DEVICE_ATTR_2(in12_input, S_IRUGO, show_in, NULL, 12, 0);
+static SENSOR_DEVICE_ATTR_2(in0_input, 0444, show_in, NULL, 0, 0);
+static SENSOR_DEVICE_ATTR_2(in0_min, 0644, show_in, set_in, 0, 1);
+static SENSOR_DEVICE_ATTR_2(in0_max, 0644, show_in, set_in, 0, 2);
+
+static SENSOR_DEVICE_ATTR_2(in1_input, 0444, show_in, NULL, 1, 0);
+static SENSOR_DEVICE_ATTR_2(in1_min, 0644, show_in, set_in, 1, 1);
+static SENSOR_DEVICE_ATTR_2(in1_max, 0644, show_in, set_in, 1, 2);
+
+static SENSOR_DEVICE_ATTR_2(in2_input, 0444, show_in, NULL, 2, 0);
+static SENSOR_DEVICE_ATTR_2(in2_min, 0644, show_in, set_in, 2, 1);
+static SENSOR_DEVICE_ATTR_2(in2_max, 0644, show_in, set_in, 2, 2);
+
+static SENSOR_DEVICE_ATTR_2(in3_input, 0444, show_in, NULL, 3, 0);
+static SENSOR_DEVICE_ATTR_2(in3_min, 0644, show_in, set_in, 3, 1);
+static SENSOR_DEVICE_ATTR_2(in3_max, 0644, show_in, set_in, 3, 2);
+
+static SENSOR_DEVICE_ATTR_2(in4_input, 0444, show_in, NULL, 4, 0);
+static SENSOR_DEVICE_ATTR_2(in4_min, 0644, show_in, set_in, 4, 1);
+static SENSOR_DEVICE_ATTR_2(in4_max, 0644, show_in, set_in, 4, 2);
+
+static SENSOR_DEVICE_ATTR_2(in5_input, 0444, show_in, NULL, 5, 0);
+static SENSOR_DEVICE_ATTR_2(in5_min, 0644, show_in, set_in, 5, 1);
+static SENSOR_DEVICE_ATTR_2(in5_max, 0644, show_in, set_in, 5, 2);
+
+static SENSOR_DEVICE_ATTR_2(in6_input, 0444, show_in, NULL, 6, 0);
+static SENSOR_DEVICE_ATTR_2(in6_min, 0644, show_in, set_in, 6, 1);
+static SENSOR_DEVICE_ATTR_2(in6_max, 0644, show_in, set_in, 6, 2);
+
+static SENSOR_DEVICE_ATTR_2(in7_input, 0444, show_in, NULL, 7, 0);
+static SENSOR_DEVICE_ATTR_2(in7_min, 0644, show_in, set_in, 7, 1);
+static SENSOR_DEVICE_ATTR_2(in7_max, 0644, show_in, set_in, 7, 2);
+
+static SENSOR_DEVICE_ATTR_2(in8_input, 0444, show_in, NULL, 8, 0);
+static SENSOR_DEVICE_ATTR_2(in9_input, 0444, show_in, NULL, 9, 0);
+static SENSOR_DEVICE_ATTR_2(in10_input, 0444, show_in, NULL, 10, 0);
+static SENSOR_DEVICE_ATTR_2(in11_input, 0444, show_in, NULL, 11, 0);
+static SENSOR_DEVICE_ATTR_2(in12_input, 0444, show_in, NULL, 12, 0);
/* Up to 6 temperatures */
static ssize_t show_temp(struct device *dev, struct device_attribute *attr,
@@ -1377,48 +1361,30 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr,
return count;
}
-static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0);
-static SENSOR_DEVICE_ATTR_2(temp1_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
- 0, 1);
-static SENSOR_DEVICE_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
- 0, 2);
-static SENSOR_DEVICE_ATTR_2(temp1_offset, S_IRUGO | S_IWUSR, show_temp,
- set_temp, 0, 3);
-static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 1, 0);
-static SENSOR_DEVICE_ATTR_2(temp2_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
- 1, 1);
-static SENSOR_DEVICE_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
- 1, 2);
-static SENSOR_DEVICE_ATTR_2(temp2_offset, S_IRUGO | S_IWUSR, show_temp,
- set_temp, 1, 3);
-static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 2, 0);
-static SENSOR_DEVICE_ATTR_2(temp3_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
- 2, 1);
-static SENSOR_DEVICE_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
- 2, 2);
-static SENSOR_DEVICE_ATTR_2(temp3_offset, S_IRUGO | S_IWUSR, show_temp,
- set_temp, 2, 3);
-static SENSOR_DEVICE_ATTR_2(temp4_input, S_IRUGO, show_temp, NULL, 3, 0);
-static SENSOR_DEVICE_ATTR_2(temp4_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
- 3, 1);
-static SENSOR_DEVICE_ATTR_2(temp4_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
- 3, 2);
-static SENSOR_DEVICE_ATTR_2(temp4_offset, S_IRUGO | S_IWUSR, show_temp,
- set_temp, 3, 3);
-static SENSOR_DEVICE_ATTR_2(temp5_input, S_IRUGO, show_temp, NULL, 4, 0);
-static SENSOR_DEVICE_ATTR_2(temp5_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
- 4, 1);
-static SENSOR_DEVICE_ATTR_2(temp5_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
- 4, 2);
-static SENSOR_DEVICE_ATTR_2(temp5_offset, S_IRUGO | S_IWUSR, show_temp,
- set_temp, 4, 3);
-static SENSOR_DEVICE_ATTR_2(temp6_input, S_IRUGO, show_temp, NULL, 5, 0);
-static SENSOR_DEVICE_ATTR_2(temp6_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
- 5, 1);
-static SENSOR_DEVICE_ATTR_2(temp6_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
- 5, 2);
-static SENSOR_DEVICE_ATTR_2(temp6_offset, S_IRUGO | S_IWUSR, show_temp,
- set_temp, 5, 3);
+static SENSOR_DEVICE_ATTR_2(temp1_input, 0444, show_temp, NULL, 0, 0);
+static SENSOR_DEVICE_ATTR_2(temp1_min, 0644, show_temp, set_temp, 0, 1);
+static SENSOR_DEVICE_ATTR_2(temp1_max, 0644, show_temp, set_temp, 0, 2);
+static SENSOR_DEVICE_ATTR_2(temp1_offset, 0644, show_temp, set_temp, 0, 3);
+static SENSOR_DEVICE_ATTR_2(temp2_input, 0444, show_temp, NULL, 1, 0);
+static SENSOR_DEVICE_ATTR_2(temp2_min, 0644, show_temp, set_temp, 1, 1);
+static SENSOR_DEVICE_ATTR_2(temp2_max, 0644, show_temp, set_temp, 1, 2);
+static SENSOR_DEVICE_ATTR_2(temp2_offset, 0644, show_temp, set_temp, 1, 3);
+static SENSOR_DEVICE_ATTR_2(temp3_input, 0444, show_temp, NULL, 2, 0);
+static SENSOR_DEVICE_ATTR_2(temp3_min, 0644, show_temp, set_temp, 2, 1);
+static SENSOR_DEVICE_ATTR_2(temp3_max, 0644, show_temp, set_temp, 2, 2);
+static SENSOR_DEVICE_ATTR_2(temp3_offset, 0644, show_temp, set_temp, 2, 3);
+static SENSOR_DEVICE_ATTR_2(temp4_input, 0444, show_temp, NULL, 3, 0);
+static SENSOR_DEVICE_ATTR_2(temp4_min, 0644, show_temp, set_temp, 3, 1);
+static SENSOR_DEVICE_ATTR_2(temp4_max, 0644, show_temp, set_temp, 3, 2);
+static SENSOR_DEVICE_ATTR_2(temp4_offset, 0644, show_temp, set_temp, 3, 3);
+static SENSOR_DEVICE_ATTR_2(temp5_input, 0444, show_temp, NULL, 4, 0);
+static SENSOR_DEVICE_ATTR_2(temp5_min, 0644, show_temp, set_temp, 4, 1);
+static SENSOR_DEVICE_ATTR_2(temp5_max, 0644, show_temp, set_temp, 4, 2);
+static SENSOR_DEVICE_ATTR_2(temp5_offset, 0644, show_temp, set_temp, 4, 3);
+static SENSOR_DEVICE_ATTR_2(temp6_input, 0444, show_temp, NULL, 5, 0);
+static SENSOR_DEVICE_ATTR_2(temp6_min, 0644, show_temp, set_temp, 5, 1);
+static SENSOR_DEVICE_ATTR_2(temp6_max, 0644, show_temp, set_temp, 5, 2);
+static SENSOR_DEVICE_ATTR_2(temp6_offset, 0644, show_temp, set_temp, 5, 3);
static const u8 temp_types_8686[NUM_TEMP][9] = {
{ 0, 8, 8, 8, 8, 8, 8, 8, 7 },
@@ -1581,18 +1547,12 @@ unlock:
return count;
}
-static SENSOR_DEVICE_ATTR(temp1_type, S_IRUGO | S_IWUSR, show_temp_type,
- set_temp_type, 0);
-static SENSOR_DEVICE_ATTR(temp2_type, S_IRUGO | S_IWUSR, show_temp_type,
- set_temp_type, 1);
-static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO | S_IWUSR, show_temp_type,
- set_temp_type, 2);
-static SENSOR_DEVICE_ATTR(temp4_type, S_IRUGO | S_IWUSR, show_temp_type,
- set_temp_type, 3);
-static SENSOR_DEVICE_ATTR(temp5_type, S_IRUGO | S_IWUSR, show_temp_type,
- set_temp_type, 4);
-static SENSOR_DEVICE_ATTR(temp6_type, S_IRUGO | S_IWUSR, show_temp_type,
- set_temp_type, 5);
+static SENSOR_DEVICE_ATTR(temp1_type, 0644, show_temp_type, set_temp_type, 0);
+static SENSOR_DEVICE_ATTR(temp2_type, 0644, show_temp_type, set_temp_type, 1);
+static SENSOR_DEVICE_ATTR(temp3_type, 0644, show_temp_type, set_temp_type, 2);
+static SENSOR_DEVICE_ATTR(temp4_type, 0644, show_temp_type, set_temp_type, 3);
+static SENSOR_DEVICE_ATTR(temp5_type, 0644, show_temp_type, set_temp_type, 4);
+static SENSOR_DEVICE_ATTR(temp6_type, 0644, show_temp_type, set_temp_type, 5);
/* 6 Fans */
@@ -2165,179 +2125,169 @@ static ssize_t set_auto_temp(struct device *dev, struct device_attribute *attr,
return count;
}
-static SENSOR_DEVICE_ATTR_2(fan1_input, S_IRUGO, show_fan, NULL, 0, 0);
-static SENSOR_DEVICE_ATTR_2(fan1_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
- 0, 1);
-static SENSOR_DEVICE_ATTR(fan1_div, S_IRUGO | S_IWUSR, show_fan_div,
- set_fan_div, 0);
-
-static SENSOR_DEVICE_ATTR_2(fan2_input, S_IRUGO, show_fan, NULL, 1, 0);
-static SENSOR_DEVICE_ATTR_2(fan2_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
- 1, 1);
-static SENSOR_DEVICE_ATTR(fan2_div, S_IRUGO | S_IWUSR, show_fan_div,
- set_fan_div, 1);
-
-static SENSOR_DEVICE_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 2, 0);
-static SENSOR_DEVICE_ATTR_2(fan3_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
- 2, 1);
-static SENSOR_DEVICE_ATTR(fan3_div, S_IRUGO | S_IWUSR, show_fan_div,
- set_fan_div, 2);
-
-static SENSOR_DEVICE_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 3, 0);
-static SENSOR_DEVICE_ATTR_2(fan4_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
- 3, 1);
-
-static SENSOR_DEVICE_ATTR_2(fan5_input, S_IRUGO, show_fan, NULL, 4, 0);
-static SENSOR_DEVICE_ATTR_2(fan5_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
- 4, 1);
-
-static SENSOR_DEVICE_ATTR_2(fan6_input, S_IRUGO, show_fan, NULL, 5, 0);
-static SENSOR_DEVICE_ATTR_2(fan6_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
- 5, 1);
-
-static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(fan1_input, 0444, show_fan, NULL, 0, 0);
+static SENSOR_DEVICE_ATTR_2(fan1_min, 0644, show_fan, set_fan, 0, 1);
+static SENSOR_DEVICE_ATTR(fan1_div, 0644, show_fan_div, set_fan_div, 0);
+
+static SENSOR_DEVICE_ATTR_2(fan2_input, 0444, show_fan, NULL, 1, 0);
+static SENSOR_DEVICE_ATTR_2(fan2_min, 0644, show_fan, set_fan, 1, 1);
+static SENSOR_DEVICE_ATTR(fan2_div, 0644, show_fan_div, set_fan_div, 1);
+
+static SENSOR_DEVICE_ATTR_2(fan3_input, 0444, show_fan, NULL, 2, 0);
+static SENSOR_DEVICE_ATTR_2(fan3_min, 0644, show_fan, set_fan, 2, 1);
+static SENSOR_DEVICE_ATTR(fan3_div, 0644, show_fan_div, set_fan_div, 2);
+
+static SENSOR_DEVICE_ATTR_2(fan4_input, 0444, show_fan, NULL, 3, 0);
+static SENSOR_DEVICE_ATTR_2(fan4_min, 0644, show_fan, set_fan, 3, 1);
+
+static SENSOR_DEVICE_ATTR_2(fan5_input, 0444, show_fan, NULL, 4, 0);
+static SENSOR_DEVICE_ATTR_2(fan5_min, 0644, show_fan, set_fan, 4, 1);
+
+static SENSOR_DEVICE_ATTR_2(fan6_input, 0444, show_fan, NULL, 5, 0);
+static SENSOR_DEVICE_ATTR_2(fan6_min, 0644, show_fan, set_fan, 5, 1);
+
+static SENSOR_DEVICE_ATTR(pwm1_enable, 0644,
show_pwm_enable, set_pwm_enable, 0);
-static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 0);
-static SENSOR_DEVICE_ATTR(pwm1_freq, S_IRUGO | S_IWUSR, show_pwm_freq,
- set_pwm_freq, 0);
-static SENSOR_DEVICE_ATTR(pwm1_auto_channels_temp, S_IRUGO,
+static SENSOR_DEVICE_ATTR(pwm1, 0644, show_pwm, set_pwm, 0);
+static SENSOR_DEVICE_ATTR(pwm1_freq, 0644, show_pwm_freq, set_pwm_freq, 0);
+static SENSOR_DEVICE_ATTR(pwm1_auto_channels_temp, 0444,
show_pwm_temp_map, set_pwm_temp_map, 0);
-static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_pwm, 0644,
show_auto_pwm, set_auto_pwm, 0, 0);
-static SENSOR_DEVICE_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm1_auto_point2_pwm, 0644,
show_auto_pwm, set_auto_pwm, 0, 1);
-static SENSOR_DEVICE_ATTR_2(pwm1_auto_point3_pwm, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm1_auto_point3_pwm, 0644,
show_auto_pwm, set_auto_pwm, 0, 2);
-static SENSOR_DEVICE_ATTR_2(pwm1_auto_point4_pwm, S_IRUGO,
+static SENSOR_DEVICE_ATTR_2(pwm1_auto_point4_pwm, 0444,
show_auto_pwm, NULL, 0, 3);
-static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_temp, 0644,
show_auto_temp, set_auto_temp, 0, 1);
-static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_temp_hyst, 0644,
show_auto_temp, set_auto_temp, 0, 0);
-static SENSOR_DEVICE_ATTR_2(pwm1_auto_point2_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm1_auto_point2_temp, 0644,
show_auto_temp, set_auto_temp, 0, 2);
-static SENSOR_DEVICE_ATTR_2(pwm1_auto_point3_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm1_auto_point3_temp, 0644,
show_auto_temp, set_auto_temp, 0, 3);
-static SENSOR_DEVICE_ATTR_2(pwm1_auto_point4_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm1_auto_point4_temp, 0644,
show_auto_temp, set_auto_temp, 0, 4);
-static SENSOR_DEVICE_ATTR_2(pwm1_auto_start, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm1_auto_start, 0644,
show_auto_pwm, set_auto_pwm, 0, 0);
-static SENSOR_DEVICE_ATTR(pwm1_auto_slope, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm1_auto_slope, 0644,
show_auto_pwm_slope, set_auto_pwm_slope, 0);
-static SENSOR_DEVICE_ATTR(pwm2_enable, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm2_enable, 0644,
show_pwm_enable, set_pwm_enable, 1);
-static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 1);
-static SENSOR_DEVICE_ATTR(pwm2_freq, S_IRUGO, show_pwm_freq, set_pwm_freq, 1);
-static SENSOR_DEVICE_ATTR(pwm2_auto_channels_temp, S_IRUGO,
+static SENSOR_DEVICE_ATTR(pwm2, 0644, show_pwm, set_pwm, 1);
+static SENSOR_DEVICE_ATTR(pwm2_freq, 0444, show_pwm_freq, set_pwm_freq, 1);
+static SENSOR_DEVICE_ATTR(pwm2_auto_channels_temp, 0444,
show_pwm_temp_map, set_pwm_temp_map, 1);
-static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_pwm, 0644,
show_auto_pwm, set_auto_pwm, 1, 0);
-static SENSOR_DEVICE_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm2_auto_point2_pwm, 0644,
show_auto_pwm, set_auto_pwm, 1, 1);
-static SENSOR_DEVICE_ATTR_2(pwm2_auto_point3_pwm, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm2_auto_point3_pwm, 0644,
show_auto_pwm, set_auto_pwm, 1, 2);
-static SENSOR_DEVICE_ATTR_2(pwm2_auto_point4_pwm, S_IRUGO,
+static SENSOR_DEVICE_ATTR_2(pwm2_auto_point4_pwm, 0444,
show_auto_pwm, NULL, 1, 3);
-static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_temp, 0644,
show_auto_temp, set_auto_temp, 1, 1);
-static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_temp_hyst, 0644,
show_auto_temp, set_auto_temp, 1, 0);
-static SENSOR_DEVICE_ATTR_2(pwm2_auto_point2_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm2_auto_point2_temp, 0644,
show_auto_temp, set_auto_temp, 1, 2);
-static SENSOR_DEVICE_ATTR_2(pwm2_auto_point3_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm2_auto_point3_temp, 0644,
show_auto_temp, set_auto_temp, 1, 3);
-static SENSOR_DEVICE_ATTR_2(pwm2_auto_point4_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm2_auto_point4_temp, 0644,
show_auto_temp, set_auto_temp, 1, 4);
-static SENSOR_DEVICE_ATTR_2(pwm2_auto_start, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm2_auto_start, 0644,
show_auto_pwm, set_auto_pwm, 1, 0);
-static SENSOR_DEVICE_ATTR(pwm2_auto_slope, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm2_auto_slope, 0644,
show_auto_pwm_slope, set_auto_pwm_slope, 1);
-static SENSOR_DEVICE_ATTR(pwm3_enable, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm3_enable, 0644,
show_pwm_enable, set_pwm_enable, 2);
-static SENSOR_DEVICE_ATTR(pwm3, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 2);
-static SENSOR_DEVICE_ATTR(pwm3_freq, S_IRUGO, show_pwm_freq, NULL, 2);
-static SENSOR_DEVICE_ATTR(pwm3_auto_channels_temp, S_IRUGO,
+static SENSOR_DEVICE_ATTR(pwm3, 0644, show_pwm, set_pwm, 2);
+static SENSOR_DEVICE_ATTR(pwm3_freq, 0444, show_pwm_freq, NULL, 2);
+static SENSOR_DEVICE_ATTR(pwm3_auto_channels_temp, 0444,
show_pwm_temp_map, set_pwm_temp_map, 2);
-static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_pwm, 0644,
show_auto_pwm, set_auto_pwm, 2, 0);
-static SENSOR_DEVICE_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm3_auto_point2_pwm, 0644,
show_auto_pwm, set_auto_pwm, 2, 1);
-static SENSOR_DEVICE_ATTR_2(pwm3_auto_point3_pwm, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm3_auto_point3_pwm, 0644,
show_auto_pwm, set_auto_pwm, 2, 2);
-static SENSOR_DEVICE_ATTR_2(pwm3_auto_point4_pwm, S_IRUGO,
+static SENSOR_DEVICE_ATTR_2(pwm3_auto_point4_pwm, 0444,
show_auto_pwm, NULL, 2, 3);
-static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_temp, 0644,
show_auto_temp, set_auto_temp, 2, 1);
-static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_temp_hyst, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_temp_hyst, 0644,
show_auto_temp, set_auto_temp, 2, 0);
-static SENSOR_DEVICE_ATTR_2(pwm3_auto_point2_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm3_auto_point2_temp, 0644,
show_auto_temp, set_auto_temp, 2, 2);
-static SENSOR_DEVICE_ATTR_2(pwm3_auto_point3_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm3_auto_point3_temp, 0644,
show_auto_temp, set_auto_temp, 2, 3);
-static SENSOR_DEVICE_ATTR_2(pwm3_auto_point4_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm3_auto_point4_temp, 0644,
show_auto_temp, set_auto_temp, 2, 4);
-static SENSOR_DEVICE_ATTR_2(pwm3_auto_start, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm3_auto_start, 0644,
show_auto_pwm, set_auto_pwm, 2, 0);
-static SENSOR_DEVICE_ATTR(pwm3_auto_slope, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm3_auto_slope, 0644,
show_auto_pwm_slope, set_auto_pwm_slope, 2);
-static SENSOR_DEVICE_ATTR(pwm4_enable, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm4_enable, 0644,
show_pwm_enable, set_pwm_enable, 3);
-static SENSOR_DEVICE_ATTR(pwm4, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 3);
-static SENSOR_DEVICE_ATTR(pwm4_freq, S_IRUGO, show_pwm_freq, NULL, 3);
-static SENSOR_DEVICE_ATTR(pwm4_auto_channels_temp, S_IRUGO,
+static SENSOR_DEVICE_ATTR(pwm4, 0644, show_pwm, set_pwm, 3);
+static SENSOR_DEVICE_ATTR(pwm4_freq, 0444, show_pwm_freq, NULL, 3);
+static SENSOR_DEVICE_ATTR(pwm4_auto_channels_temp, 0444,
show_pwm_temp_map, set_pwm_temp_map, 3);
-static SENSOR_DEVICE_ATTR_2(pwm4_auto_point1_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm4_auto_point1_temp, 0644,
show_auto_temp, set_auto_temp, 2, 1);
-static SENSOR_DEVICE_ATTR_2(pwm4_auto_point1_temp_hyst, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm4_auto_point1_temp_hyst, 0644,
show_auto_temp, set_auto_temp, 2, 0);
-static SENSOR_DEVICE_ATTR_2(pwm4_auto_point2_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm4_auto_point2_temp, 0644,
show_auto_temp, set_auto_temp, 2, 2);
-static SENSOR_DEVICE_ATTR_2(pwm4_auto_point3_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm4_auto_point3_temp, 0644,
show_auto_temp, set_auto_temp, 2, 3);
-static SENSOR_DEVICE_ATTR_2(pwm4_auto_start, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm4_auto_start, 0644,
show_auto_pwm, set_auto_pwm, 3, 0);
-static SENSOR_DEVICE_ATTR(pwm4_auto_slope, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm4_auto_slope, 0644,
show_auto_pwm_slope, set_auto_pwm_slope, 3);
-static SENSOR_DEVICE_ATTR(pwm5_enable, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm5_enable, 0644,
show_pwm_enable, set_pwm_enable, 4);
-static SENSOR_DEVICE_ATTR(pwm5, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 4);
-static SENSOR_DEVICE_ATTR(pwm5_freq, S_IRUGO, show_pwm_freq, NULL, 4);
-static SENSOR_DEVICE_ATTR(pwm5_auto_channels_temp, S_IRUGO,
+static SENSOR_DEVICE_ATTR(pwm5, 0644, show_pwm, set_pwm, 4);
+static SENSOR_DEVICE_ATTR(pwm5_freq, 0444, show_pwm_freq, NULL, 4);
+static SENSOR_DEVICE_ATTR(pwm5_auto_channels_temp, 0444,
show_pwm_temp_map, set_pwm_temp_map, 4);
-static SENSOR_DEVICE_ATTR_2(pwm5_auto_point1_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm5_auto_point1_temp, 0644,
show_auto_temp, set_auto_temp, 2, 1);
-static SENSOR_DEVICE_ATTR_2(pwm5_auto_point1_temp_hyst, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm5_auto_point1_temp_hyst, 0644,
show_auto_temp, set_auto_temp, 2, 0);
-static SENSOR_DEVICE_ATTR_2(pwm5_auto_point2_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm5_auto_point2_temp, 0644,
show_auto_temp, set_auto_temp, 2, 2);
-static SENSOR_DEVICE_ATTR_2(pwm5_auto_point3_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm5_auto_point3_temp, 0644,
show_auto_temp, set_auto_temp, 2, 3);
-static SENSOR_DEVICE_ATTR_2(pwm5_auto_start, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm5_auto_start, 0644,
show_auto_pwm, set_auto_pwm, 4, 0);
-static SENSOR_DEVICE_ATTR(pwm5_auto_slope, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm5_auto_slope, 0644,
show_auto_pwm_slope, set_auto_pwm_slope, 4);
-static SENSOR_DEVICE_ATTR(pwm6_enable, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm6_enable, 0644,
show_pwm_enable, set_pwm_enable, 5);
-static SENSOR_DEVICE_ATTR(pwm6, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 5);
-static SENSOR_DEVICE_ATTR(pwm6_freq, S_IRUGO, show_pwm_freq, NULL, 5);
-static SENSOR_DEVICE_ATTR(pwm6_auto_channels_temp, S_IRUGO,
+static SENSOR_DEVICE_ATTR(pwm6, 0644, show_pwm, set_pwm, 5);
+static SENSOR_DEVICE_ATTR(pwm6_freq, 0444, show_pwm_freq, NULL, 5);
+static SENSOR_DEVICE_ATTR(pwm6_auto_channels_temp, 0444,
show_pwm_temp_map, set_pwm_temp_map, 5);
-static SENSOR_DEVICE_ATTR_2(pwm6_auto_point1_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm6_auto_point1_temp, 0644,
show_auto_temp, set_auto_temp, 2, 1);
-static SENSOR_DEVICE_ATTR_2(pwm6_auto_point1_temp_hyst, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm6_auto_point1_temp_hyst, 0644,
show_auto_temp, set_auto_temp, 2, 0);
-static SENSOR_DEVICE_ATTR_2(pwm6_auto_point2_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm6_auto_point2_temp, 0644,
show_auto_temp, set_auto_temp, 2, 2);
-static SENSOR_DEVICE_ATTR_2(pwm6_auto_point3_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm6_auto_point3_temp, 0644,
show_auto_temp, set_auto_temp, 2, 3);
-static SENSOR_DEVICE_ATTR_2(pwm6_auto_start, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm6_auto_start, 0644,
show_auto_pwm, set_auto_pwm, 5, 0);
-static SENSOR_DEVICE_ATTR(pwm6_auto_slope, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm6_auto_slope, 0644,
show_auto_pwm_slope, set_auto_pwm_slope, 5);
/* Alarms */
@@ -2389,27 +2339,27 @@ static ssize_t clear_intrusion(struct device *dev,
return count;
}
-static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 8);
-static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 9);
-static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 10);
-static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 11);
-static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 12);
-static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 13);
-static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 14);
-static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 15);
-static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 0);
-static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 1);
-static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 2);
-static SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, 3);
-static SENSOR_DEVICE_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, 6);
-static SENSOR_DEVICE_ATTR(fan6_alarm, S_IRUGO, show_alarm, NULL, 7);
-static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 16);
-static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 17);
-static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 18);
-static SENSOR_DEVICE_ATTR(temp4_alarm, S_IRUGO, show_alarm, NULL, 19);
-static SENSOR_DEVICE_ATTR(temp5_alarm, S_IRUGO, show_alarm, NULL, 20);
-static SENSOR_DEVICE_ATTR(temp6_alarm, S_IRUGO, show_alarm, NULL, 21);
-static SENSOR_DEVICE_ATTR(intrusion0_alarm, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(in0_alarm, 0444, show_alarm, NULL, 8);
+static SENSOR_DEVICE_ATTR(in1_alarm, 0444, show_alarm, NULL, 9);
+static SENSOR_DEVICE_ATTR(in2_alarm, 0444, show_alarm, NULL, 10);
+static SENSOR_DEVICE_ATTR(in3_alarm, 0444, show_alarm, NULL, 11);
+static SENSOR_DEVICE_ATTR(in4_alarm, 0444, show_alarm, NULL, 12);
+static SENSOR_DEVICE_ATTR(in5_alarm, 0444, show_alarm, NULL, 13);
+static SENSOR_DEVICE_ATTR(in6_alarm, 0444, show_alarm, NULL, 14);
+static SENSOR_DEVICE_ATTR(in7_alarm, 0444, show_alarm, NULL, 15);
+static SENSOR_DEVICE_ATTR(fan1_alarm, 0444, show_alarm, NULL, 0);
+static SENSOR_DEVICE_ATTR(fan2_alarm, 0444, show_alarm, NULL, 1);
+static SENSOR_DEVICE_ATTR(fan3_alarm, 0444, show_alarm, NULL, 2);
+static SENSOR_DEVICE_ATTR(fan4_alarm, 0444, show_alarm, NULL, 3);
+static SENSOR_DEVICE_ATTR(fan5_alarm, 0444, show_alarm, NULL, 6);
+static SENSOR_DEVICE_ATTR(fan6_alarm, 0444, show_alarm, NULL, 7);
+static SENSOR_DEVICE_ATTR(temp1_alarm, 0444, show_alarm, NULL, 16);
+static SENSOR_DEVICE_ATTR(temp2_alarm, 0444, show_alarm, NULL, 17);
+static SENSOR_DEVICE_ATTR(temp3_alarm, 0444, show_alarm, NULL, 18);
+static SENSOR_DEVICE_ATTR(temp4_alarm, 0444, show_alarm, NULL, 19);
+static SENSOR_DEVICE_ATTR(temp5_alarm, 0444, show_alarm, NULL, 20);
+static SENSOR_DEVICE_ATTR(temp6_alarm, 0444, show_alarm, NULL, 21);
+static SENSOR_DEVICE_ATTR(intrusion0_alarm, 0644,
show_alarm, clear_intrusion, 4);
static ssize_t show_beep(struct device *dev, struct device_attribute *attr,
@@ -2449,29 +2399,29 @@ static ssize_t set_beep(struct device *dev, struct device_attribute *attr,
return count;
}
-static SENSOR_DEVICE_ATTR(in0_beep, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(in0_beep, 0644,
show_beep, set_beep, 1);
-static SENSOR_DEVICE_ATTR(in1_beep, S_IRUGO, show_beep, NULL, 1);
-static SENSOR_DEVICE_ATTR(in2_beep, S_IRUGO, show_beep, NULL, 1);
-static SENSOR_DEVICE_ATTR(in3_beep, S_IRUGO, show_beep, NULL, 1);
-static SENSOR_DEVICE_ATTR(in4_beep, S_IRUGO, show_beep, NULL, 1);
-static SENSOR_DEVICE_ATTR(in5_beep, S_IRUGO, show_beep, NULL, 1);
-static SENSOR_DEVICE_ATTR(in6_beep, S_IRUGO, show_beep, NULL, 1);
-static SENSOR_DEVICE_ATTR(in7_beep, S_IRUGO, show_beep, NULL, 1);
+static SENSOR_DEVICE_ATTR(in1_beep, 0444, show_beep, NULL, 1);
+static SENSOR_DEVICE_ATTR(in2_beep, 0444, show_beep, NULL, 1);
+static SENSOR_DEVICE_ATTR(in3_beep, 0444, show_beep, NULL, 1);
+static SENSOR_DEVICE_ATTR(in4_beep, 0444, show_beep, NULL, 1);
+static SENSOR_DEVICE_ATTR(in5_beep, 0444, show_beep, NULL, 1);
+static SENSOR_DEVICE_ATTR(in6_beep, 0444, show_beep, NULL, 1);
+static SENSOR_DEVICE_ATTR(in7_beep, 0444, show_beep, NULL, 1);
/* fanX_beep writability is set later */
-static SENSOR_DEVICE_ATTR(fan1_beep, S_IRUGO, show_beep, set_beep, 0);
-static SENSOR_DEVICE_ATTR(fan2_beep, S_IRUGO, show_beep, set_beep, 0);
-static SENSOR_DEVICE_ATTR(fan3_beep, S_IRUGO, show_beep, set_beep, 0);
-static SENSOR_DEVICE_ATTR(fan4_beep, S_IRUGO, show_beep, set_beep, 0);
-static SENSOR_DEVICE_ATTR(fan5_beep, S_IRUGO, show_beep, set_beep, 0);
-static SENSOR_DEVICE_ATTR(fan6_beep, S_IRUGO, show_beep, set_beep, 0);
-static SENSOR_DEVICE_ATTR(temp1_beep, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(fan1_beep, 0444, show_beep, set_beep, 0);
+static SENSOR_DEVICE_ATTR(fan2_beep, 0444, show_beep, set_beep, 0);
+static SENSOR_DEVICE_ATTR(fan3_beep, 0444, show_beep, set_beep, 0);
+static SENSOR_DEVICE_ATTR(fan4_beep, 0444, show_beep, set_beep, 0);
+static SENSOR_DEVICE_ATTR(fan5_beep, 0444, show_beep, set_beep, 0);
+static SENSOR_DEVICE_ATTR(fan6_beep, 0444, show_beep, set_beep, 0);
+static SENSOR_DEVICE_ATTR(temp1_beep, 0644,
show_beep, set_beep, 2);
-static SENSOR_DEVICE_ATTR(temp2_beep, S_IRUGO, show_beep, NULL, 2);
-static SENSOR_DEVICE_ATTR(temp3_beep, S_IRUGO, show_beep, NULL, 2);
-static SENSOR_DEVICE_ATTR(temp4_beep, S_IRUGO, show_beep, NULL, 2);
-static SENSOR_DEVICE_ATTR(temp5_beep, S_IRUGO, show_beep, NULL, 2);
-static SENSOR_DEVICE_ATTR(temp6_beep, S_IRUGO, show_beep, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp2_beep, 0444, show_beep, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp3_beep, 0444, show_beep, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp4_beep, 0444, show_beep, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp5_beep, 0444, show_beep, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp6_beep, 0444, show_beep, NULL, 2);
static ssize_t vrm_show(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -2537,11 +2487,11 @@ static ssize_t show_label(struct device *dev, struct device_attribute *attr,
return sprintf(buf, "%s\n", label);
}
-static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_label, NULL, 0);
-static SENSOR_DEVICE_ATTR(in7_label, S_IRUGO, show_label, NULL, 1);
-static SENSOR_DEVICE_ATTR(in8_label, S_IRUGO, show_label, NULL, 2);
+static SENSOR_DEVICE_ATTR(in3_label, 0444, show_label, NULL, 0);
+static SENSOR_DEVICE_ATTR(in7_label, 0444, show_label, NULL, 1);
+static SENSOR_DEVICE_ATTR(in8_label, 0444, show_label, NULL, 2);
/* AVCC3 */
-static SENSOR_DEVICE_ATTR(in9_label, S_IRUGO, show_label, NULL, 3);
+static SENSOR_DEVICE_ATTR(in9_label, 0444, show_label, NULL, 3);
static umode_t it87_in_is_visible(struct kobject *kobj,
struct attribute *attr, int index)
@@ -2769,7 +2719,7 @@ static umode_t it87_fan_is_visible(struct kobject *kobj,
return 0;
/* first fan beep attribute is writable */
if (i == __ffs(data->has_fan))
- return attr->mode | S_IWUSR;
+ return attr->mode | 0200;
}
if (a == 4 && has_16bit_fans(data)) /* divisor */
@@ -2832,11 +2782,11 @@ static umode_t it87_pwm_is_visible(struct kobject *kobj,
/* pwmX_auto_channels_temp is only writable if auto pwm is supported */
if (a == 3 && (has_old_autopwm(data) || has_newer_autopwm(data)))
- return attr->mode | S_IWUSR;
+ return attr->mode | 0200;
/* pwm2_freq is writable if there are two pwm frequency selects */
if (has_pwm_freq2(data) && i == 1 && a == 2)
- return attr->mode | S_IWUSR;
+ return attr->mode | 0200;
return attr->mode;
}
--
2.20.1
From b0b52a4b645a1079341bdb6dd60d98ff3cb855ea Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Mon, 2 Oct 2017 11:18:33 -0700
Subject: [PATCH 50/61] Experimental support for IT8606E
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 23 ++++++++++++++++++++---
1 file changed, 20 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index a43da8c..b553bbd 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -11,6 +11,7 @@
* similar parts. The other devices are supported by different drivers.
*
* Supports: IT8603E Super I/O chip w/LPC interface
+ * IT8606E Super I/O chip w/LPC interface
* IT8607E Super I/O chip w/LPC interface
* IT8613E Super I/O chip w/LPC interface
* IT8620E Super I/O chip w/LPC interface
@@ -78,8 +79,8 @@
enum chips { it87, it8712, it8716, it8718, it8720, it8721, it8728, it8732,
it8771, it8772, it8781, it8782, it8783, it8786, it8790,
- it8792, it8603, it8607, it8613, it8620, it8622, it8625, it8628,
- it8655, it8665, it8686 };
+ it8792, it8603, it8606, it8607, it8613, it8620, it8622, it8625,
+ it8628, it8655, it8665, it8686 };
static unsigned short force_id;
module_param(force_id, ushort, 0000);
@@ -182,6 +183,7 @@ static inline void superio_exit(int ioreg, bool doexit)
#define IT8786E_DEVID 0x8786
#define IT8790E_DEVID 0x8790
#define IT8603E_DEVID 0x8603
+#define IT8606E_DEVID 0x8606
#define IT8607E_DEVID 0x8607
#define IT8613E_DEVID 0x8613
#define IT8620E_DEVID 0x8620
@@ -568,6 +570,17 @@ static const struct it87_devices it87_devices[] = {
.num_temp_map = 4,
.peci_mask = 0x07,
},
+ [it8606] = {
+ .name = "it8606",
+ .suffix = "E",
+ .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
+ | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
+ | FEAT_AVCC3 | FEAT_PWM_FREQ2 | FEAT_SCALING,
+ .num_temp_limit = 3,
+ .num_temp_offset = 3,
+ .num_temp_map = 3,
+ .peci_mask = 0x07,
+ },
[it8607] = {
.name = "it8607",
.suffix = "E",
@@ -3013,6 +3026,9 @@ static int __init it87_find(int sioaddr, unsigned short *address,
case IT8623E_DEVID:
sio_data->type = it8603;
break;
+ case IT8606E_DEVID:
+ sio_data->type = it8606;
+ break;
case IT8607E_DEVID:
sio_data->type = it8607;
break;
@@ -3183,7 +3199,8 @@ static int __init it87_find(int sioaddr, unsigned short *address,
sio_data->beep_pin = superio_inb(sioaddr,
IT87_SIO_BEEP_PIN_REG) & 0x3f;
- } else if (sio_data->type == it8603 || sio_data->type == it8607) {
+ } else if (sio_data->type == it8603 || sio_data->type == it8606 ||
+ sio_data->type == it8607) {
int reg27, reg29;
superio_select(sioaddr, GPIO);
--
2.20.1
From a8b35f063527be3a71d20ccfbf208cba347b1570 Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Mon, 2 Oct 2017 14:08:29 -0700
Subject: [PATCH 51/61] Report actual chip name, not its ID
For some recent chips (at least IT8792E/IT8795E), the value of the chip ID
register does not match the chip name. Display the textual, not the value
of the ID register, in the kernel log.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 60 +++++++++++++++++++++++++++++-----------------------------
1 file changed, 30 insertions(+), 30 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index b553bbd..8e4c4e1 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -335,7 +335,7 @@ static const u16 IT87_REG_TEMP_SRC1[] = { 0x21d, 0x21e, 0x21f };
struct it87_devices {
const char *name;
- const char * const suffix;
+ const char * const model;
u32 features;
u8 num_temp_limit;
u8 num_temp_offset;
@@ -377,7 +377,7 @@ struct it87_devices {
static const struct it87_devices it87_devices[] = {
[it87] = {
.name = "it87",
- .suffix = "F",
+ .model = "IT87F",
.features = FEAT_OLD_AUTOPWM | FEAT_FANCTL_ONOFF,
/* may need to overwrite */
.num_temp_limit = 3,
@@ -386,7 +386,7 @@ static const struct it87_devices it87_devices[] = {
},
[it8712] = {
.name = "it8712",
- .suffix = "F",
+ .model = "IT8712F",
.features = FEAT_OLD_AUTOPWM | FEAT_VID | FEAT_FANCTL_ONOFF,
/* may need to overwrite */
.num_temp_limit = 3,
@@ -395,7 +395,7 @@ static const struct it87_devices it87_devices[] = {
},
[it8716] = {
.name = "it8716",
- .suffix = "F",
+ .model = "IT8716F",
.features = FEAT_16BIT_FANS | FEAT_VID
| FEAT_FAN16_CONFIG | FEAT_FIVE_FANS | FEAT_PWM_FREQ2
| FEAT_FANCTL_ONOFF,
@@ -405,7 +405,7 @@ static const struct it87_devices it87_devices[] = {
},
[it8718] = {
.name = "it8718",
- .suffix = "F",
+ .model = "IT8718F",
.features = FEAT_16BIT_FANS | FEAT_VID
| FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS
| FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF,
@@ -416,7 +416,7 @@ static const struct it87_devices it87_devices[] = {
},
[it8720] = {
.name = "it8720",
- .suffix = "F",
+ .model = "IT8720F",
.features = FEAT_16BIT_FANS | FEAT_VID
| FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS
| FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF,
@@ -427,7 +427,7 @@ static const struct it87_devices it87_devices[] = {
},
[it8721] = {
.name = "it8721",
- .suffix = "F",
+ .model = "IT8721F",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI
| FEAT_FAN16_CONFIG | FEAT_FIVE_FANS | FEAT_IN7_INTERNAL
@@ -440,7 +440,7 @@ static const struct it87_devices it87_devices[] = {
},
[it8728] = {
.name = "it8728",
- .suffix = "F",
+ .model = "IT8728F",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_PECI | FEAT_FIVE_FANS
| FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2 | FEAT_SCALING
@@ -452,7 +452,7 @@ static const struct it87_devices it87_devices[] = {
},
[it8732] = {
.name = "it8732",
- .suffix = "F",
+ .model = "IT8732F",
.features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS
| FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI
| FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_FOUR_FANS
@@ -465,7 +465,7 @@ static const struct it87_devices it87_devices[] = {
},
[it8771] = {
.name = "it8771",
- .suffix = "E",
+ .model = "IT8771E",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
| FEAT_PWM_FREQ2 | FEAT_SCALING | FEAT_FANCTL_ONOFF,
@@ -480,7 +480,7 @@ static const struct it87_devices it87_devices[] = {
},
[it8772] = {
.name = "it8772",
- .suffix = "E",
+ .model = "IT8772E",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
| FEAT_PWM_FREQ2 | FEAT_SCALING | FEAT_FANCTL_ONOFF,
@@ -495,7 +495,7 @@ static const struct it87_devices it87_devices[] = {
},
[it8781] = {
.name = "it8781",
- .suffix = "F",
+ .model = "IT8781F",
.features = FEAT_16BIT_FANS
| FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_PWM_FREQ2
| FEAT_FANCTL_ONOFF,
@@ -506,7 +506,7 @@ static const struct it87_devices it87_devices[] = {
},
[it8782] = {
.name = "it8782",
- .suffix = "F",
+ .model = "IT8782F",
.features = FEAT_16BIT_FANS
| FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_PWM_FREQ2
| FEAT_FANCTL_ONOFF,
@@ -517,7 +517,7 @@ static const struct it87_devices it87_devices[] = {
},
[it8783] = {
.name = "it8783",
- .suffix = "E/F",
+ .model = "IT8783E/F",
.features = FEAT_16BIT_FANS
| FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_PWM_FREQ2
| FEAT_FANCTL_ONOFF,
@@ -528,7 +528,7 @@ static const struct it87_devices it87_devices[] = {
},
[it8786] = {
.name = "it8786",
- .suffix = "E",
+ .model = "IT8786E",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
| FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF,
@@ -539,7 +539,7 @@ static const struct it87_devices it87_devices[] = {
},
[it8790] = {
.name = "it8790",
- .suffix = "E",
+ .model = "IT8790E",
.features = FEAT_NEWER_AUTOPWM | FEAT_10_9MV_ADC | FEAT_SCALING
| FEAT_16BIT_FANS | FEAT_TEMP_PECI
| FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF,
@@ -550,7 +550,7 @@ static const struct it87_devices it87_devices[] = {
},
[it8792] = {
.name = "it8792",
- .suffix = "E",
+ .model = "IT8792E/IT8795E",
.features = FEAT_NEWER_AUTOPWM | FEAT_10_9MV_ADC | FEAT_SCALING
| FEAT_16BIT_FANS | FEAT_TEMP_PECI
| FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF,
@@ -561,7 +561,7 @@ static const struct it87_devices it87_devices[] = {
},
[it8603] = {
.name = "it8603",
- .suffix = "E",
+ .model = "IT8603E",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
| FEAT_AVCC3 | FEAT_PWM_FREQ2 | FEAT_SCALING,
@@ -572,7 +572,7 @@ static const struct it87_devices it87_devices[] = {
},
[it8606] = {
.name = "it8606",
- .suffix = "E",
+ .model = "IT8606E",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
| FEAT_AVCC3 | FEAT_PWM_FREQ2 | FEAT_SCALING,
@@ -583,7 +583,7 @@ static const struct it87_devices it87_devices[] = {
},
[it8607] = {
.name = "it8607",
- .suffix = "E",
+ .model = "IT8607E",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_PECI | FEAT_IN7_INTERNAL | FEAT_NEW_TEMPMAP
| FEAT_AVCC3 | FEAT_PWM_FREQ2 | FEAT_SCALING
@@ -595,7 +595,7 @@ static const struct it87_devices it87_devices[] = {
},
[it8613] = {
.name = "it8613",
- .suffix = "E",
+ .model = "IT8613E",
.features = FEAT_NEWER_AUTOPWM | FEAT_11MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_PECI | FEAT_FIVE_FANS
| FEAT_FIVE_PWM | FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2
@@ -607,7 +607,7 @@ static const struct it87_devices it87_devices[] = {
},
[it8620] = {
.name = "it8620",
- .suffix = "E",
+ .model = "IT8620E",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_PECI | FEAT_SIX_FANS
| FEAT_IN7_INTERNAL | FEAT_SIX_PWM | FEAT_PWM_FREQ2
@@ -620,7 +620,7 @@ static const struct it87_devices it87_devices[] = {
},
[it8622] = {
.name = "it8622",
- .suffix = "E",
+ .model = "IT8622E",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_PECI | FEAT_FIVE_FANS | FEAT_FOUR_TEMP
| FEAT_FIVE_PWM | FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2
@@ -633,7 +633,7 @@ static const struct it87_devices it87_devices[] = {
},
[it8625] = {
.name = "it8625",
- .suffix = "E",
+ .model = "IT8625E",
.features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS
| FEAT_AVCC3 | FEAT_NEW_TEMPMAP
| FEAT_11MV_ADC | FEAT_IN7_INTERNAL | FEAT_SIX_FANS
@@ -645,7 +645,7 @@ static const struct it87_devices it87_devices[] = {
},
[it8628] = {
.name = "it8628",
- .suffix = "E",
+ .model = "IT8628E",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_PECI | FEAT_SIX_FANS
| FEAT_IN7_INTERNAL | FEAT_SIX_PWM | FEAT_PWM_FREQ2
@@ -658,7 +658,7 @@ static const struct it87_devices it87_devices[] = {
},
[it8655] = {
.name = "it8655",
- .suffix = "E",
+ .model = "IT8655E",
.features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS
| FEAT_AVCC3 | FEAT_NEW_TEMPMAP | FEAT_SCALING
| FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_BANK_SEL,
@@ -669,7 +669,7 @@ static const struct it87_devices it87_devices[] = {
},
[it8665] = {
.name = "it8665",
- .suffix = "E",
+ .model = "IT8665E",
.features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS
| FEAT_AVCC3 | FEAT_NEW_TEMPMAP | FEAT_SCALING
| FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_SIX_FANS
@@ -681,7 +681,7 @@ static const struct it87_devices it87_devices[] = {
},
[it8686] = {
.name = "it8686",
- .suffix = "E",
+ .model = "IT8686E",
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_SIX_FANS | FEAT_NEW_TEMPMAP
| FEAT_IN7_INTERNAL | FEAT_SIX_PWM | FEAT_PWM_FREQ2
@@ -3098,8 +3098,8 @@ static int __init it87_find(int sioaddr, unsigned short *address,
if (base)
snprintf(mmio_str, sizeof(mmio_str), " [MMIO at %pa]", &base);
- pr_info("Found IT%04x%s chip at 0x%x%s, revision %d\n", chip_type,
- it87_devices[sio_data->type].suffix,
+ pr_info("Found %s chip at 0x%x%s, revision %d\n",
+ it87_devices[sio_data->type].model,
*address, mmio_str, sio_data->revision);
/* in7 (VSB or VCCH5V) is always internal on some chips */
--
2.20.1
From 5a60a93685957557668ad07893b0be5c329f9a26 Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Fri, 6 Oct 2017 16:14:31 -0700
Subject: [PATCH 52/61] Do not disable SMBs unless really necessary
Only disable SMBus if we are going to read/write data.
Disabling it on each attribute read can result in system
instabilities.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 8e4c4e1..084e9f4 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -782,7 +782,6 @@ struct it87_data {
const u8 *REG_TEMP_HIGH;
unsigned short addr;
- const char *name;
struct mutex update_lock;
char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */
@@ -1130,15 +1129,19 @@ static void it87_unlock(struct it87_data *data)
static struct it87_data *it87_update_device(struct device *dev)
{
struct it87_data *data = dev_get_drvdata(dev);
+ struct it87_data *ret = data;
int err;
int i;
- err = it87_lock(data);
- if (err)
- return ERR_PTR(err);
+ mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ + HZ / 2) ||
!data->valid) {
+ err = smbus_disable(data);
+ if (err) {
+ ret = ERR_PTR(err);
+ goto unlock;
+ }
if (update_vbat) {
/*
* Cleared after each update, so reenable. Value
@@ -1234,9 +1237,11 @@ static struct it87_data *it87_update_device(struct device *dev)
}
data->last_updated = jiffies;
data->valid = 1;
+ smbus_enable(data);
}
- it87_unlock(data);
- return data;
+unlock:
+ mutex_unlock(&data->update_lock);
+ return ret;
}
static ssize_t show_in(struct device *dev, struct device_attribute *attr,
--
2.20.1
From 49f0b68ac3516b9e4a3fdbe7e19264c054f8fb76 Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Sat, 7 Oct 2017 07:38:41 -0700
Subject: [PATCH 53/61] Fix PECI/AMDTSI selection
We can not use register 0x98 since it is typically not programmed
on systems selecting PECI. Try register 0x0a (Interface Selection)
which should be a better fit anyway.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 084e9f4..5597af3 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -253,6 +253,10 @@ static bool fix_pwm_polarity;
* Super-I/O configuration space.
*/
#define IT87_REG_VID 0x0a
+
+/* Interface Selection register on other chips */
+#define IT87_REG_IFSEL 0x0a
+
/*
* The IT8705F and IT8712F earlier than revision 0x08 use register 0x0b
* for fan divisors. Later IT8712F revisions must use 16-bit tachometer
@@ -1459,11 +1463,12 @@ static int get_temp_type(struct it87_data *data, int index)
if (type)
return type;
- /* Dectect PECI vs. AMDTSI if possible */
+ /* Dectect PECI vs. AMDTSI */
ttype = 6;
- if ((has_temp_peci(data, index)) && data->type != it8721) {
- extra = data->read(data, 0x98); /* PCH/AMDTSI host status */
- if (extra & BIT(6))
+ if ((has_temp_peci(data, index)) || data->type == it8721 ||
+ data->type == it8720) {
+ extra = data->read(data, IT87_REG_IFSEL);
+ if ((extra & 0x70) == 0x40)
ttype = 5;
}
--
2.20.1
From 989fdbb56735e6cf80852675b50ac0b71ee30973 Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Sun, 3 Dec 2017 10:28:15 -0800
Subject: [PATCH 54/61] Add comment explaining why smbus_disable is needed in
probe
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 5597af3..6e5cbec 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -3985,6 +3985,17 @@ static int it87_probe(struct platform_device *pdev)
/* Initialize register pointers */
it87_init_regs(pdev);
+ /*
+ * We need to disable SMBus before we can read any registers in
+ * the envmon address space, even if it is for chip identification
+ * purposes. If the chip has SMBus client support, it likely also has
+ * multi-page envmon registers, so we have to set the page anyway
+ * before accessing those registers. Kind of a chicken-and-egg
+ * problem.
+ * Fortunately, the chip was already identified through the SIO
+ * address space, only recent chips are affected, and this is just
+ * an additional safeguard.
+ */
err = smbus_disable(data);
if (err)
return err;
--
2.20.1
From b1b7f22f52955fcbf9723cb3ef51bcc659745e5e Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Fri, 19 Jan 2018 12:30:24 -0800
Subject: [PATCH 55/61] Fix up fan / pwm detection for IT8625/IT8665
Hope it is correct this time around.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 24 ++++++++++++++----------
1 file changed, 14 insertions(+), 10 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 6e5cbec..0d16b4d 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -3435,15 +3435,9 @@ static int __init it87_find(int sioaddr, unsigned short *address,
reg2d = superio_inb(sioaddr, IT87_SIO_PINX4_REG);
regd3 = superio_inb(sioaddr, IT87_SIO_GPIO9_REG);
- /* Check for pwm2, fan2 */
+ /* Check for pwm2 */
if (reg29 & BIT(1))
sio_data->skip_pwm |= BIT(1);
- /*
- * Note: Table 6-1 in datasheet claims that FAN_TAC2
- * would be enabled with 29h[2]=0.
- */
- if (reg2d & BIT(4))
- sio_data->skip_fan |= BIT(1);
/* Check for pwm3, fan3 */
if (reg27 & BIT(6))
@@ -3451,28 +3445,38 @@ static int __init it87_find(int sioaddr, unsigned short *address,
if (reg27 & BIT(7))
sio_data->skip_fan |= BIT(2);
- /* Check for pwm4, fan4, pwm5, fan5 */
+ /* Check for fan2, pwm4, fan4, pwm5, fan5 */
if (sio_data->type == it8625) {
int reg25 = superio_inb(sioaddr, IT87_SIO_GPIO1_REG);
+ if (reg29 & BIT(2))
+ sio_data->skip_fan |= BIT(1);
if (reg25 & BIT(6))
sio_data->skip_fan |= BIT(3);
if (reg25 & BIT(5))
sio_data->skip_pwm |= BIT(3);
if (reg27 & BIT(3))
sio_data->skip_pwm |= BIT(4);
- if (reg27 & BIT(1))
+ if (!(reg27 & BIT(1)))
sio_data->skip_fan |= BIT(4);
} else {
int reg26 = superio_inb(sioaddr, IT87_SIO_GPIO2_REG);
+ if (reg2d & BIT(4))
+ sio_data->skip_fan |= BIT(1);
if (regd3 & BIT(2))
sio_data->skip_pwm |= BIT(3);
if (regd3 & BIT(3))
sio_data->skip_fan |= BIT(3);
if (reg26 & BIT(5))
sio_data->skip_pwm |= BIT(4);
- if (reg26 & BIT(4))
+ /*
+ * Table 6-1 in datasheet claims that FAN_TAC5 would
+ * be enabled with 26h[4]=0. This contradicts with the
+ * information in section 8.3.9 and with feedback from
+ * users.
+ */
+ if (!(reg26 & BIT(4)))
sio_data->skip_fan |= BIT(4);
}
--
2.20.1
From ae52e2d59103eed6fd49621c626785298bb07e9a Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Wed, 14 Feb 2018 08:57:46 -0800
Subject: [PATCH 56/61] Save and restore bank around envmon register accesses
if needed
If an external EC accesses the chip through SMBus registers
and if the chip's environmental registers are paged, it is likely
that the EC modifies the page register. If so, it likely will not
update the page on each access but assume that it "owns" the chip.
If the driver then modifies the page register, subsequent accesses
from the EC will likely have unpredictable results.
To avoid that problem, let's save the page register value after
disabling SMBus accesses and restore the original value when done.
This is only necessary if accesses are not handled through MMIO
since we don't touch the page register in that case.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 29 +++++++++++++++++------------
1 file changed, 17 insertions(+), 12 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 0d16b4d..03cddf7 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -766,6 +766,7 @@ struct it87_data {
u8 old_peci_mask;
u8 smbus_bitmap; /* !=0 if SMBus needs to be disabled */
+ u8 saved_bank; /* saved bank register value */
u8 ec_special_config; /* EC special config register restore value */
u8 sioaddr; /* SIO port address */
bool doexit; /* true if exit from sio config is ok */
@@ -957,6 +958,18 @@ static const unsigned int pwm_freq[8] = {
750000,
};
+static int _it87_io_read(struct it87_data *data, u16 reg)
+{
+ outb_p(reg, data->addr + IT87_ADDR_REG_OFFSET);
+ return inb_p(data->addr + IT87_DATA_REG_OFFSET);
+}
+
+static void _it87_io_write(struct it87_data *data, u16 reg, u8 value)
+{
+ outb_p(reg, data->addr + IT87_ADDR_REG_OFFSET);
+ outb_p(value, data->addr + IT87_DATA_REG_OFFSET);
+}
+
static int smbus_disable(struct it87_data *data)
{
int err;
@@ -969,6 +982,8 @@ static int smbus_disable(struct it87_data *data)
superio_outb(data->sioaddr, IT87_SPECIAL_CFG_REG,
data->ec_special_config & ~data->smbus_bitmap);
superio_exit(data->sioaddr, data->doexit);
+ if (has_bank_sel(data) && !data->mmio)
+ data->saved_bank = _it87_io_read(data, IT87_REG_BANK);
}
return 0;
}
@@ -978,6 +993,8 @@ static int smbus_enable(struct it87_data *data)
int err;
if (data->smbus_bitmap) {
+ if (has_bank_sel(data) && !data->mmio)
+ _it87_io_write(data, IT87_REG_BANK, data->saved_bank);
err = superio_enter(data->sioaddr);
if (err)
return err;
@@ -990,18 +1007,6 @@ static int smbus_enable(struct it87_data *data)
return 0;
}
-static int _it87_io_read(struct it87_data *data, u16 reg)
-{
- outb_p(reg, data->addr + IT87_ADDR_REG_OFFSET);
- return inb_p(data->addr + IT87_DATA_REG_OFFSET);
-}
-
-static void _it87_io_write(struct it87_data *data, u16 reg, u8 value)
-{
- outb_p(reg, data->addr + IT87_ADDR_REG_OFFSET);
- outb_p(value, data->addr + IT87_DATA_REG_OFFSET);
-}
-
static u8 it87_io_set_bank(struct it87_data *data, u8 bank)
{
u8 _bank = bank;
--
2.20.1
From 2e62e132236665e2468d26d2516e4db515419cad Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Mon, 26 Feb 2018 19:19:09 -0800
Subject: [PATCH 57/61] Fix scaling for IT8732F
3.3V channels report the wrong voltages on IT8732F since the scaling bit
is not set.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 03cddf7..bf63cba 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -460,7 +460,7 @@ static const struct it87_devices it87_devices[] = {
.features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS
| FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI
| FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_FOUR_FANS
- | FEAT_FOUR_PWM | FEAT_FANCTL_ONOFF,
+ | FEAT_FOUR_PWM | FEAT_FANCTL_ONOFF | FEAT_SCALING,
.num_temp_limit = 3,
.num_temp_offset = 3,
.num_temp_map = 3,
--
2.20.1
From c8c4a216bece7bf6c9c0e6083478ff8ecbed6a1d Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Mon, 26 Feb 2018 21:02:58 -0800
Subject: [PATCH 58/61] Add preliminary support for IT8736F and IT8738E SPLIT
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 49 +++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 45 insertions(+), 4 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index bf63cba..00fdf71 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -31,6 +31,8 @@
* IT8726F Super I/O chip w/LPC interface
* IT8728F Super I/O chip w/LPC interface
* IT8732F Super I/O chip w/LPC interface
+ * IT8736F Super I/O chip w/LPC interface
+ * IT8738E Super I/O chip w/LPC interface
* IT8758E Super I/O chip w/LPC interface
* IT8771E Super I/O chip w/LPC interface
* IT8772E Super I/O chip w/LPC interface
@@ -78,6 +80,7 @@
#define DRVNAME "it87"
enum chips { it87, it8712, it8716, it8718, it8720, it8721, it8728, it8732,
+ it8736, it8738,
it8771, it8772, it8781, it8782, it8783, it8786, it8790,
it8792, it8603, it8606, it8607, it8613, it8620, it8622, it8625,
it8628, it8655, it8665, it8686 };
@@ -174,6 +177,8 @@ static inline void superio_exit(int ioreg, bool doexit)
#define IT8726F_DEVID 0x8726
#define IT8728F_DEVID 0x8728
#define IT8732F_DEVID 0x8732
+#define IT8736F_DEVID 0x8736
+#define IT8738E_DEVID 0x8738
#define IT8792E_DEVID 0x8733
#define IT8771E_DEVID 0x8771
#define IT8772E_DEVID 0x8772
@@ -467,6 +472,33 @@ static const struct it87_devices it87_devices[] = {
.peci_mask = 0x07,
.old_peci_mask = 0x02, /* Actually reports PCH */
},
+ [it8736] = {
+ .name = "it8736",
+ .model = "IT8736F",
+ .features = FEAT_16BIT_FANS
+ | FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI
+ | FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_FOUR_FANS
+ | FEAT_FANCTL_ONOFF | FEAT_SCALING,
+ .num_temp_limit = 3,
+ .num_temp_offset = 3,
+ .num_temp_map = 3,
+ .peci_mask = 0x07,
+ .old_peci_mask = 0x02, /* Actually reports PCH */
+ },
+ [it8738] = {
+ .name = "it8738",
+ .model = "IT8738E",
+ .features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS
+ | FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI
+ | FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL
+ | FEAT_FANCTL_ONOFF | FEAT_SCALING
+ | FEAT_AVCC3,
+ .num_temp_limit = 3,
+ .num_temp_offset = 3,
+ .num_temp_map = 3,
+ .peci_mask = 0x07,
+ .old_peci_mask = 0x02,
+ },
[it8771] = {
.name = "it8771",
.model = "IT8771E",
@@ -3005,6 +3037,12 @@ static int __init it87_find(int sioaddr, unsigned short *address,
case IT8732F_DEVID:
sio_data->type = it8732;
break;
+ case IT8736F_DEVID:
+ sio_data->type = it8736;
+ break;
+ case IT8738E_DEVID:
+ sio_data->type = it8738;
+ break;
case IT8792E_DEVID:
sio_data->type = it8792;
/*
@@ -3378,7 +3416,8 @@ static int __init it87_find(int sioaddr, unsigned short *address,
sio_data->beep_pin = superio_inb(sioaddr,
IT87_SIO_BEEP_PIN_REG) & 0x3f;
- } else if (sio_data->type == it8732) {
+ } else if (sio_data->type == it8732 || sio_data->type == it8736 ||
+ sio_data->type == it8738) {
int reg;
superio_select(sioaddr, GPIO);
@@ -3400,9 +3439,11 @@ static int __init it87_find(int sioaddr, unsigned short *address,
sio_data->skip_fan |= BIT(3);
/* Check if AVCC is on VIN3 */
- reg = superio_inb(sioaddr, IT87_SIO_PINX2_REG);
- if (reg & BIT(0))
- sio_data->internal |= BIT(0);
+ if (sio_data->type != it8738) {
+ reg = superio_inb(sioaddr, IT87_SIO_PINX2_REG);
+ if (reg & BIT(0))
+ sio_data->internal |= BIT(0);
+ }
sio_data->beep_pin = superio_inb(sioaddr,
IT87_SIO_BEEP_PIN_REG) & 0x3f;
--
2.20.1
From 4bbd97a6b958d7b9ef748b54829b615366410d6e Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Tue, 29 May 2018 12:26:50 -0700
Subject: [PATCH 59/61] Fix temperature type for peci/amdtsi if
diode/thermistor is also set
PECI / AMDTSI has higher priority than thermal diode/thermistor settings.
Always report PECI/AMDTSI if it is enabled on a given port.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 00fdf71..48e59db 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -1529,7 +1529,7 @@ static int get_temp_type(struct it87_data *data, int index)
if ((has_temp_peci(data, index) && (reg >> 6 == index + 1)) ||
(has_temp_old_peci(data, index) && (extra & 0x80)))
type = ttype; /* Intel PECI or AMDTSI */
- if (reg & BIT(index))
+ else if (reg & BIT(index))
type = 3; /* thermal diode */
else if (reg & BIT(index + 3))
type = 4; /* thermistor */
--
2.20.1
From 682880bf621693066e1a94297a7d1a3afad699dc Mon Sep 17 00:00:00 2001
From: Guenter Roeck <linux@roeck-us.net>
Date: Wed, 6 Jun 2018 15:19:47 -0700
Subject: [PATCH 60/61] Enable all temperature registers for IT8655E and
IT8665E
Those chips always have all 6 temperature registers enabled.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 43 ++++++++++++++++++++++++-------------------
1 file changed, 24 insertions(+), 19 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 48e59db..1306f60 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -697,7 +697,8 @@ static const struct it87_devices it87_devices[] = {
.model = "IT8655E",
.features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS
| FEAT_AVCC3 | FEAT_NEW_TEMPMAP | FEAT_SCALING
- | FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_BANK_SEL,
+ | FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_BANK_SEL
+ | FEAT_SIX_TEMP | FEAT_MMIO,
.num_temp_limit = 6,
.num_temp_offset = 6,
.num_temp_map = 6,
@@ -709,7 +710,7 @@ static const struct it87_devices it87_devices[] = {
.features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS
| FEAT_AVCC3 | FEAT_NEW_TEMPMAP | FEAT_SCALING
| FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_SIX_FANS
- | FEAT_SIX_PWM | FEAT_BANK_SEL | FEAT_MMIO,
+ | FEAT_SIX_PWM | FEAT_BANK_SEL | FEAT_MMIO | FEAT_SIX_TEMP,
.num_temp_limit = 6,
.num_temp_offset = 6,
.num_temp_map = 6,
@@ -4095,23 +4096,27 @@ static int it87_probe(struct platform_device *pdev)
if (has_four_temp(data)) {
data->has_temp |= BIT(3);
} else if (has_six_temp(data)) {
- u8 reg = data->read(data, IT87_REG_TEMP456_ENABLE);
-
- /* Check for additional temperature sensors */
- if ((reg & 0x03) >= 0x02)
- data->has_temp |= BIT(3);
- if (((reg >> 2) & 0x03) >= 0x02)
- data->has_temp |= BIT(4);
- if (((reg >> 4) & 0x03) >= 0x02)
- data->has_temp |= BIT(5);
-
- /* Check for additional voltage sensors */
- if ((reg & 0x03) == 0x01)
- data->has_in |= BIT(10);
- if (((reg >> 2) & 0x03) == 0x01)
- data->has_in |= BIT(11);
- if (((reg >> 4) & 0x03) == 0x01)
- data->has_in |= BIT(12);
+ if (sio_data->type == it8655 || sio_data->type == it8665) {
+ data->has_temp |= BIT(3) | BIT(4) | BIT(5);
+ } else {
+ u8 reg = data->read(data, IT87_REG_TEMP456_ENABLE);
+
+ /* Check for additional temperature sensors */
+ if ((reg & 0x03) >= 0x02)
+ data->has_temp |= BIT(3);
+ if (((reg >> 2) & 0x03) >= 0x02)
+ data->has_temp |= BIT(4);
+ if (((reg >> 4) & 0x03) >= 0x02)
+ data->has_temp |= BIT(5);
+
+ /* Check for additional voltage sensors */
+ if ((reg & 0x03) == 0x01)
+ data->has_in |= BIT(10);
+ if (((reg >> 2) & 0x03) == 0x01)
+ data->has_in |= BIT(11);
+ if (((reg >> 4) & 0x03) == 0x01)
+ data->has_in |= BIT(12);
+ }
}
data->has_beep = !!sio_data->beep_pin;
--
2.20.1
From 98aa44e4a53accd31889050a89d9fc57504830ef Mon Sep 17 00:00:00 2001
From: airbjorn <gerhart@posteo.de>
Date: Wed, 13 Jun 2018 11:04:40 +0200
Subject: [PATCH 61/61] auto-adjust loop threshold to changes in the array size
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
it87.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 1306f60..6f5bb8e 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -1977,7 +1977,7 @@ static ssize_t set_pwm_freq(struct device *dev, struct device_attribute *attr,
val *= has_newer_autopwm(data) ? 256 : 128;
/* Search for the nearest available frequency */
- for (i = 0; i < 7; i++) {
+ for (i = 0; i < ARRAY_SIZE(pwm_freq) - 1; i++) {
if (val > (pwm_freq[i] + pwm_freq[i + 1]) / 2)
break;
}
--
2.20.1