From 600a85f556b783b5c619c4b6a576d5b2471be1ca Mon Sep 17 00:00:00 2001 From: "benoit.masson" Date: Sun, 30 Aug 2026 00:01:49 +0200 Subject: [PATCH] hwmon: (it87) add IT8613E support Teach the Super I/O probe path to recognize IT8613E and add its hardware monitoring configuration. Add feature flags, 11 mV ADC scaling, the IT8665-style PWM register map, six PWM temperature mapping sources, and GPIO pin-mux checks. Only three temperature inputs are currently known, so retain the existing three temperature limit and offset resources. Document the chip in the hwmon guide. Signed-off-by: benoit.masson Signed-off-by: Jerome Tollet Link: https://patch.msgid.link/5afd336442307450f77467b2a749d405970a2099.1788040385.git.jerome.tollet@gmail.com Signed-off-by: Guenter Roeck --- Documentation/hwmon/it87.rst | 8 +++++ drivers/hwmon/it87.c | 63 ++++++++++++++++++++++++++++++++++-- 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/Documentation/hwmon/it87.rst b/Documentation/hwmon/it87.rst index fc1c90b023ae..c33ba8a0749a 100644 --- a/Documentation/hwmon/it87.rst +++ b/Documentation/hwmon/it87.rst @@ -11,6 +11,14 @@ Supported chips: Datasheet: Not publicly available + * IT8613E + + Prefix: 'it8613' + + Addresses scanned: from Super I/O config space (8 I/O ports) + + Datasheet: Not publicly available + * IT8620E Prefix: 'it8620' diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 232cc8586258..2757d428a23d 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c @@ -36,6 +36,7 @@ * IT8790E Super I/O chip w/LPC interface * IT8792E Super I/O chip w/LPC interface * IT87952E Super I/O chip w/LPC interface + * IT8613E Super I/O chip w/LPC interface * Sis950 A clone of the IT8705F * * Copyright (C) 2001 Chris Gauthron @@ -65,7 +66,7 @@ enum chips { it87, it8712, it8716, it8718, it8720, it8721, it8728, it8732, it8771, it8772, it8781, it8782, it8783, it8786, it8790, - it8792, it8603, it8620, it8622, it8628, it8689, it87952 }; + it8792, it8603, it8613, it8620, it8622, it8628, it8689, it87952 }; static struct platform_device *it87_pdev[2]; @@ -159,6 +160,7 @@ static inline void superio_exit(int ioreg, bool noexit) #define IT8786E_DEVID 0x8786 #define IT8790E_DEVID 0x8790 #define IT8603E_DEVID 0x8603 +#define IT8613E_DEVID 0x8613 #define IT8620E_DEVID 0x8620 #define IT8622E_DEVID 0x8622 #define IT8623E_DEVID 0x8623 @@ -333,6 +335,7 @@ struct it87_devices { #define FEAT_FOUR_TEMP BIT(22) #define FEAT_FANCTL_ONOFF BIT(23) /* chip has FAN_CTL ON/OFF */ #define FEAT_NEW_TEMPMAP BIT(24) /* PWM uses extended temp map */ +#define FEAT_11MV_ADC BIT(25) static const struct it87_devices it87_devices[] = { [it87] = { @@ -515,6 +518,18 @@ static const struct it87_devices it87_devices[] = { .num_temp_map = 4, .peci_mask = 0x07, }, + [it8613] = { + .name = "it8613", + .model = "IT8613E", + /* Only three temperature inputs are currently known. */ + .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_NEW_TEMPMAP, + .reg_pwm = IT87_REG_PWM_8665, + .num_temp_map = 6, + .peci_mask = 0x07, + }, [it8620] = { .name = "it8620", .model = "IT8620E", @@ -577,6 +592,7 @@ static const struct it87_devices it87_devices[] = { #define has_16bit_fans(data) ((data)->features & FEAT_16BIT_FANS) #define has_12mv_adc(data) ((data)->features & FEAT_12MV_ADC) #define has_10_9mv_adc(data) ((data)->features & FEAT_10_9MV_ADC) +#define has_11mv_adc(data) ((data)->features & FEAT_11MV_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) @@ -607,7 +623,8 @@ static const struct it87_devices it87_devices[] = { #define has_vin3_5v(data) ((data)->features & FEAT_VIN3_5V) #define has_noconf(data) ((data)->features & FEAT_NOCONF) #define has_scaling(data) ((data)->features & (FEAT_12MV_ADC | \ - FEAT_10_9MV_ADC)) + FEAT_10_9MV_ADC | \ + FEAT_11MV_ADC)) #define has_fanctl_onoff(data) ((data)->features & FEAT_FANCTL_ONOFF) #define has_new_tempmap(data) ((data)->features & FEAT_NEW_TEMPMAP) @@ -712,6 +729,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)) @@ -2919,6 +2938,9 @@ static int __init it87_find(int sioaddr, unsigned short *address, case IT8623E_DEVID: sio_data->type = it8603; break; + case IT8613E_DEVID: + sio_data->type = it8613; + break; case IT8620E_DEVID: sio_data->type = it8620; break; @@ -3096,6 +3118,43 @@ static int __init it87_find(int sioaddr, unsigned short *address, 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; + } 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) {