* [PATCH v4 0/5] hwmon: it87: add IT8613E support
@ 2026-01-14 22:12 benoit.masson
2026-01-14 22:12 ` [PATCH v4 1/5] hwmon: it87: describe per-chip temperature resources benoit.masson
` (4 more replies)
0 siblings, 5 replies; 10+ messages in thread
From: benoit.masson @ 2026-01-14 22:12 UTC (permalink / raw)
To: Jean Delvare, Guenter Roeck
Cc: linux-hwmon, linux-kernel, Jonathan Corbet, linux-doc, benoit.masson
This series ports IT8613E support from the out-of-tree it87 fork into
upstream in small steps. It first adds per-chip resource metadata and
new PWM temp map handling, then expands temp limits/offsets, adds
IT8613E detection, and finally the IT8613E configuration.
Tested on: IT8613E, MEDION B660H7-M20 BIOS motherboard.
Builds: each patch builds cleanly with W=1
(the only checkpatch warnings are the kept symbolic perms
S_IRUGO | S_IWUSR / S_IRUGO).
Changes in v4:
- Drop FEAT_TEMP_OFFSET and has_temp_offset(); rely on num_temp_offset.
- Initialize num_temp_limit/offset/map for all chips, no runtime defaults.
- Use per-chip reg_pwm pointer instead of type checks; fixes compile error.
- Keep IT8613E feature set aligned with the above (no FEAT_TEMP_OFFSET).
benoit.masson (5):
hwmon: it87: describe per-chip temperature resources
hwmon: it87: prepare for extended PWM temp maps
hwmon: it87: expose additional temperature limits
hwmon: it87: add IT8613E identification
hwmon: it87: add IT8613E configuration
Documentation/hwmon/it87.rst | 8 +
drivers/hwmon/it87.c | 447 ++++++++++++++++++++++++++++-------
2 files changed, 376 insertions(+), 79 deletions(-)
--
2.50.1 (Apple Git-155)
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 1/5] hwmon: it87: describe per-chip temperature resources
2026-01-14 22:12 [PATCH v4 0/5] hwmon: it87: add IT8613E support benoit.masson
@ 2026-01-14 22:12 ` benoit.masson
2026-01-17 14:39 ` Guenter Roeck
2026-01-14 22:12 ` [PATCH v4 2/5] hwmon: it87: prepare for extended PWM temp maps benoit.masson
` (3 subsequent siblings)
4 siblings, 1 reply; 10+ messages in thread
From: benoit.masson @ 2026-01-14 22:12 UTC (permalink / raw)
To: Jean Delvare, Guenter Roeck
Cc: linux-hwmon, linux-kernel, Jonathan Corbet, linux-doc, benoit.masson
Add per-chip temp limit/offset/map counts and wire the driver
to use them.
This keeps existing chips on the previous defaults while allowing newer
chips to advertise larger resources.
Signed-off-by: benoit.masson <yahoo@perenite.com>
---
drivers/hwmon/it87.c | 144 ++++++++++++++++++++++++++++++++-----------
1 file changed, 109 insertions(+), 35 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index e233aafa8856..b50ba1cd2362 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -280,7 +280,6 @@ static const u8 IT87_REG_AUTO_BASE[] = { 0x60, 0x68, 0x70, 0x78, 0xa0, 0xa8 };
#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)
@@ -290,6 +289,9 @@ struct it87_devices {
const char *name;
const char * const model;
u32 features;
+ u8 num_temp_limit;
+ u8 num_temp_offset;
+ u8 num_temp_map;
u8 peci_mask;
u8 old_peci_mask;
u8 smbus_bitmap; /* SMBus enable bits in extra config register */
@@ -300,7 +302,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 */
@@ -333,43 +334,61 @@ static const struct it87_devices it87_devices[] = {
.model = "IT87F",
.features = FEAT_OLD_AUTOPWM | FEAT_FANCTL_ONOFF,
/* may need to overwrite */
+ .num_temp_limit = 3,
+ .num_temp_offset = 0,
+ .num_temp_map = 3,
},
[it8712] = {
.name = "it8712",
.model = "IT8712F",
.features = FEAT_OLD_AUTOPWM | FEAT_VID | FEAT_FANCTL_ONOFF,
/* may need to overwrite */
+ .num_temp_limit = 3,
+ .num_temp_offset = 0,
+ .num_temp_map = 3,
},
[it8716] = {
.name = "it8716",
.model = "IT8716F",
- .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,
+ .num_temp_offset = 3,
+ .num_temp_map = 3,
},
[it8718] = {
.name = "it8718",
.model = "IT8718F",
- .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,
+ .num_temp_offset = 3,
+ .num_temp_map = 3,
.old_peci_mask = 0x4,
},
[it8720] = {
.name = "it8720",
.model = "IT8720F",
- .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,
+ .num_temp_offset = 3,
+ .num_temp_map = 3,
.old_peci_mask = 0x4,
},
[it8721] = {
.name = "it8721",
.model = "IT8721F",
.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_FANCTL_ONOFF,
+ .num_temp_limit = 3,
+ .num_temp_offset = 3,
+ .num_temp_map = 3,
.peci_mask = 0x05,
.old_peci_mask = 0x02, /* Actually reports PCH */
},
@@ -377,18 +396,24 @@ static const struct it87_devices it87_devices[] = {
.name = "it8728",
.model = "IT8728F",
.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_FANCTL_ONOFF,
+ .num_temp_limit = 6,
+ .num_temp_offset = 3,
+ .num_temp_map = 3,
.peci_mask = 0x07,
},
[it8732] = {
.name = "it8732",
.model = "IT8732F",
.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,
+ .num_temp_offset = 3,
+ .num_temp_map = 3,
.peci_mask = 0x07,
.old_peci_mask = 0x02, /* Actually reports PCH */
},
@@ -396,73 +421,97 @@ static const struct it87_devices it87_devices[] = {
.name = "it8771",
.model = "IT8771E",
.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,
/* PECI: guesswork */
/* 12mV ADC (OHM) */
/* 16 bit fans (OHM) */
/* three fans, always 16 bit (guesswork) */
+ .num_temp_limit = 3,
+ .num_temp_offset = 3,
+ .num_temp_map = 3,
.peci_mask = 0x07,
},
[it8772] = {
.name = "it8772",
.model = "IT8772E",
.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,
/* PECI (coreboot) */
/* 12mV ADC (HWSensors4, OHM) */
/* 16 bit fans (HWSensors4, OHM) */
/* three fans, always 16 bit (datasheet) */
+ .num_temp_limit = 3,
+ .num_temp_offset = 3,
+ .num_temp_map = 3,
.peci_mask = 0x07,
},
[it8781] = {
.name = "it8781",
.model = "IT8781F",
- .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,
+ .num_temp_offset = 3,
+ .num_temp_map = 3,
.old_peci_mask = 0x4,
},
[it8782] = {
.name = "it8782",
.model = "IT8782F",
- .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,
+ .num_temp_offset = 3,
+ .num_temp_map = 3,
.old_peci_mask = 0x4,
},
[it8783] = {
.name = "it8783",
.model = "IT8783E/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,
+ .num_temp_offset = 3,
+ .num_temp_map = 3,
.old_peci_mask = 0x4,
},
[it8786] = {
.name = "it8786",
.model = "IT8786E",
.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,
+ .num_temp_map = 3,
.peci_mask = 0x07,
},
[it8790] = {
.name = "it8790",
.model = "IT8790E",
.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 | FEAT_NOCONF,
+ .num_temp_limit = 3,
+ .num_temp_offset = 3,
+ .num_temp_map = 3,
.peci_mask = 0x07,
},
[it8792] = {
.name = "it8792",
.model = "IT8792E/IT8795E",
.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_FANCTL_ONOFF
| FEAT_NOCONF,
+ .num_temp_limit = 3,
+ .num_temp_offset = 3,
+ .num_temp_map = 3,
.peci_mask = 0x07,
.old_peci_mask = 0x02, /* Actually reports PCH */
},
@@ -470,45 +519,60 @@ static const struct it87_devices it87_devices[] = {
.name = "it8603",
.model = "IT8603E",
.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,
+ .num_temp_limit = 3,
+ .num_temp_offset = 3,
+ .num_temp_map = 4,
.peci_mask = 0x07,
},
[it8620] = {
.name = "it8620",
.model = "IT8620E",
.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_FANCTL_ONOFF,
+ .num_temp_limit = 3,
+ .num_temp_offset = 3,
+ .num_temp_map = 3,
.peci_mask = 0x07,
},
[it8622] = {
.name = "it8622",
.model = "IT8622E",
.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_FOUR_TEMP,
- .peci_mask = 0x07,
+ .num_temp_limit = 3,
+ .num_temp_offset = 3,
+ .num_temp_map = 4,
+ .peci_mask = 0x0f,
.smbus_bitmap = BIT(1) | BIT(2),
},
[it8628] = {
.name = "it8628",
.model = "IT8628E",
.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_FANCTL_ONOFF,
+ .num_temp_limit = 6,
+ .num_temp_offset = 3,
+ .num_temp_map = 3,
.peci_mask = 0x07,
},
[it87952] = {
.name = "it87952",
.model = "IT87952E",
.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_FANCTL_ONOFF
| FEAT_NOCONF,
+ .num_temp_limit = 3,
+ .num_temp_offset = 3,
+ .num_temp_map = 3,
.peci_mask = 0x07,
.old_peci_mask = 0x02, /* Actually reports PCH */
},
@@ -519,7 +583,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) \
@@ -578,6 +641,9 @@ struct it87_data {
int sioaddr;
enum chips type;
u32 features;
+ u8 num_temp_limit;
+ u8 num_temp_offset;
+ u8 num_temp_map;
u8 peci_mask;
u8 old_peci_mask;
@@ -926,12 +992,12 @@ 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_offset)
data->temp[i][3] =
it87_read_value(data,
IT87_REG_TEMP_OFFSET[i]);
- if (i >= NUM_TEMP_LIMIT)
+ if (i >= data->num_temp_limit)
continue;
data->temp[i][1] =
@@ -1679,16 +1745,18 @@ 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;
+ u8 num_map;
int map;
if (IS_ERR(data))
return PTR_ERR(data);
+ num_map = data->num_temp_map;
map = data->pwm_temp_map[nr];
- if (map >= 3)
+ if (map >= num_map)
map = 0; /* Should never happen */
- if (nr >= 3) /* pwm channels 3..6 map to temp4..6 */
- map += 3;
+ if (nr >= num_map) /* pwm channels 3..6 map to temp4..6 */
+ map += num_map;
return sprintf(buf, "%d\n", (int)BIT(map));
}
@@ -1700,6 +1768,7 @@ 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;
+ u8 num_map = data->num_temp_map;
long val;
int err;
u8 reg;
@@ -1707,8 +1776,8 @@ static ssize_t set_pwm_temp_map(struct device *dev,
if (kstrtol(buf, 10, &val) < 0)
return -EINVAL;
- if (nr >= 3)
- val -= 3;
+ if (nr >= num_map)
+ val -= num_map;
switch (val) {
case BIT(0):
@@ -2362,7 +2431,7 @@ static umode_t it87_temp_is_visible(struct kobject *kobj,
return attr->mode;
}
- if (a == 5 && !has_temp_offset(data))
+ if (a == 5 && i >= data->num_temp_offset)
return 0;
if (a == 6 && !data->has_beep)
@@ -3206,7 +3275,7 @@ 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++) {
+ 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);
@@ -3399,6 +3468,7 @@ static int it87_probe(struct platform_device *pdev)
struct resource *res;
struct device *dev = &pdev->dev;
struct it87_sio_data *sio_data = dev_get_platdata(dev);
+ const struct it87_devices *chip;
int enable_pwm_interface;
struct device *hwmon_dev;
int err;
@@ -3421,9 +3491,13 @@ static int it87_probe(struct platform_device *pdev)
data->type = sio_data->type;
data->smbus_bitmap = sio_data->smbus_bitmap;
data->ec_special_config = sio_data->ec_special_config;
- 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;
+ chip = &it87_devices[sio_data->type];
+ data->features = chip->features;
+ data->peci_mask = chip->peci_mask;
+ data->old_peci_mask = chip->old_peci_mask;
+ data->num_temp_limit = chip->num_temp_limit;
+ data->num_temp_offset = chip->num_temp_offset;
+ data->num_temp_map = chip->num_temp_map;
/*
* IT8705F Datasheet 0.4.1, 3h == Version G.
* IT8712F Datasheet 0.9.1, section 8.3.5 indicates 8h == Version J.
--
2.50.1 (Apple Git-155)
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 2/5] hwmon: it87: prepare for extended PWM temp maps
2026-01-14 22:12 [PATCH v4 0/5] hwmon: it87: add IT8613E support benoit.masson
2026-01-14 22:12 ` [PATCH v4 1/5] hwmon: it87: describe per-chip temperature resources benoit.masson
@ 2026-01-14 22:12 ` benoit.masson
2026-01-14 22:12 ` [PATCH v4 3/5] hwmon: it87: expose additional temperature limits benoit.masson
` (2 subsequent siblings)
4 siblings, 0 replies; 10+ messages in thread
From: benoit.masson @ 2026-01-14 22:12 UTC (permalink / raw)
To: Jean Delvare, Guenter Roeck
Cc: linux-hwmon, linux-kernel, Jonathan Corbet, linux-doc, benoit.masson
Introduce helper logic for PWM-to-temperature mappings so newer
register layouts can be supported without affecting legacy chips.
Signed-off-by: benoit.masson <yahoo@perenite.com>
---
drivers/hwmon/it87.c | 198 +++++++++++++++++++++++++++++++++----------
1 file changed, 153 insertions(+), 45 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index b50ba1cd2362..2d4264d05bc2 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -250,6 +250,7 @@ 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_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,
@@ -280,6 +281,7 @@ static const u8 IT87_REG_AUTO_BASE[] = { 0x60, 0x68, 0x70, 0x78, 0xa0, 0xa8 };
#define NUM_VIN_LIMIT 8
#define NUM_TEMP 6
#define NUM_TEMP_OFFSET ARRAY_SIZE(IT87_REG_TEMP_OFFSET)
+#define IT87_PWM_OLD_NUM_TEMP 3
#define NUM_FAN ARRAY_SIZE(IT87_REG_FAN)
#define NUM_FAN_DIV 3
#define NUM_PWM ARRAY_SIZE(IT87_REG_PWM)
@@ -289,6 +291,7 @@ struct it87_devices {
const char *name;
const char * const model;
u32 features;
+ const u8 *reg_pwm;
u8 num_temp_limit;
u8 num_temp_offset;
u8 num_temp_map;
@@ -327,6 +330,7 @@ struct it87_devices {
#define FEAT_FOUR_PWM BIT(21) /* Supports four fan controls */
#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 */
static const struct it87_devices it87_devices[] = {
[it87] = {
@@ -334,6 +338,7 @@ static const struct it87_devices it87_devices[] = {
.model = "IT87F",
.features = FEAT_OLD_AUTOPWM | FEAT_FANCTL_ONOFF,
/* may need to overwrite */
+ .reg_pwm = IT87_REG_PWM,
.num_temp_limit = 3,
.num_temp_offset = 0,
.num_temp_map = 3,
@@ -343,6 +348,7 @@ static const struct it87_devices it87_devices[] = {
.model = "IT8712F",
.features = FEAT_OLD_AUTOPWM | FEAT_VID | FEAT_FANCTL_ONOFF,
/* may need to overwrite */
+ .reg_pwm = IT87_REG_PWM,
.num_temp_limit = 3,
.num_temp_offset = 0,
.num_temp_map = 3,
@@ -353,6 +359,7 @@ static const struct it87_devices it87_devices[] = {
.features = FEAT_16BIT_FANS | FEAT_VID
| FEAT_FAN16_CONFIG | FEAT_FIVE_FANS | FEAT_PWM_FREQ2
| FEAT_FANCTL_ONOFF,
+ .reg_pwm = IT87_REG_PWM,
.num_temp_limit = 3,
.num_temp_offset = 3,
.num_temp_map = 3,
@@ -363,6 +370,7 @@ static const struct it87_devices it87_devices[] = {
.features = FEAT_16BIT_FANS | FEAT_VID
| FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS
| FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF,
+ .reg_pwm = IT87_REG_PWM,
.num_temp_limit = 3,
.num_temp_offset = 3,
.num_temp_map = 3,
@@ -374,6 +382,7 @@ static const struct it87_devices it87_devices[] = {
.features = FEAT_16BIT_FANS | FEAT_VID
| FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS
| FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF,
+ .reg_pwm = IT87_REG_PWM,
.num_temp_limit = 3,
.num_temp_offset = 3,
.num_temp_map = 3,
@@ -386,6 +395,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI
| FEAT_FAN16_CONFIG | FEAT_FIVE_FANS | FEAT_IN7_INTERNAL
| FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF,
+ .reg_pwm = IT87_REG_PWM,
.num_temp_limit = 3,
.num_temp_offset = 3,
.num_temp_map = 3,
@@ -399,6 +409,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_TEMP_PECI | FEAT_FIVE_FANS
| FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2
| FEAT_FANCTL_ONOFF,
+ .reg_pwm = IT87_REG_PWM,
.num_temp_limit = 6,
.num_temp_offset = 3,
.num_temp_map = 3,
@@ -411,6 +422,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI
| FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_FOUR_FANS
| FEAT_FOUR_PWM | FEAT_FANCTL_ONOFF,
+ .reg_pwm = IT87_REG_PWM,
.num_temp_limit = 3,
.num_temp_offset = 3,
.num_temp_map = 3,
@@ -427,6 +439,7 @@ static const struct it87_devices it87_devices[] = {
/* 12mV ADC (OHM) */
/* 16 bit fans (OHM) */
/* three fans, always 16 bit (guesswork) */
+ .reg_pwm = IT87_REG_PWM,
.num_temp_limit = 3,
.num_temp_offset = 3,
.num_temp_map = 3,
@@ -442,6 +455,7 @@ static const struct it87_devices it87_devices[] = {
/* 12mV ADC (HWSensors4, OHM) */
/* 16 bit fans (HWSensors4, OHM) */
/* three fans, always 16 bit (datasheet) */
+ .reg_pwm = IT87_REG_PWM,
.num_temp_limit = 3,
.num_temp_offset = 3,
.num_temp_map = 3,
@@ -453,6 +467,7 @@ static const struct it87_devices it87_devices[] = {
.features = FEAT_16BIT_FANS
| FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_PWM_FREQ2
| FEAT_FANCTL_ONOFF,
+ .reg_pwm = IT87_REG_PWM,
.num_temp_limit = 3,
.num_temp_offset = 3,
.num_temp_map = 3,
@@ -464,6 +479,7 @@ static const struct it87_devices it87_devices[] = {
.features = FEAT_16BIT_FANS
| FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_PWM_FREQ2
| FEAT_FANCTL_ONOFF,
+ .reg_pwm = IT87_REG_PWM,
.num_temp_limit = 3,
.num_temp_offset = 3,
.num_temp_map = 3,
@@ -475,6 +491,7 @@ static const struct it87_devices it87_devices[] = {
.features = FEAT_16BIT_FANS
| FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_PWM_FREQ2
| FEAT_FANCTL_ONOFF,
+ .reg_pwm = IT87_REG_PWM,
.num_temp_limit = 3,
.num_temp_offset = 3,
.num_temp_map = 3,
@@ -486,6 +503,7 @@ static const struct it87_devices it87_devices[] = {
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
| FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF,
+ .reg_pwm = IT87_REG_PWM,
.num_temp_limit = 3,
.num_temp_offset = 3,
.num_temp_map = 3,
@@ -497,6 +515,7 @@ static const struct it87_devices it87_devices[] = {
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
| FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF | FEAT_NOCONF,
+ .reg_pwm = IT87_REG_PWM,
.num_temp_limit = 3,
.num_temp_offset = 3,
.num_temp_map = 3,
@@ -509,6 +528,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI
| FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_FANCTL_ONOFF
| FEAT_NOCONF,
+ .reg_pwm = IT87_REG_PWM,
.num_temp_limit = 3,
.num_temp_offset = 3,
.num_temp_map = 3,
@@ -521,6 +541,7 @@ static const struct it87_devices it87_devices[] = {
.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
| FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
| FEAT_AVCC3 | FEAT_PWM_FREQ2,
+ .reg_pwm = IT87_REG_PWM,
.num_temp_limit = 3,
.num_temp_offset = 3,
.num_temp_map = 4,
@@ -533,6 +554,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_TEMP_PECI | FEAT_SIX_FANS
| FEAT_IN7_INTERNAL | FEAT_SIX_PWM | FEAT_PWM_FREQ2
| FEAT_SIX_TEMP | FEAT_VIN3_5V | FEAT_FANCTL_ONOFF,
+ .reg_pwm = IT87_REG_PWM,
.num_temp_limit = 3,
.num_temp_offset = 3,
.num_temp_map = 3,
@@ -545,6 +567,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_TEMP_PECI | FEAT_FIVE_FANS
| FEAT_FIVE_PWM | FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2
| FEAT_AVCC3 | FEAT_VIN3_5V | FEAT_FOUR_TEMP,
+ .reg_pwm = IT87_REG_PWM_8665,
.num_temp_limit = 3,
.num_temp_offset = 3,
.num_temp_map = 4,
@@ -558,6 +581,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_TEMP_PECI | FEAT_SIX_FANS
| FEAT_IN7_INTERNAL | FEAT_SIX_PWM | FEAT_PWM_FREQ2
| FEAT_SIX_TEMP | FEAT_VIN3_5V | FEAT_FANCTL_ONOFF,
+ .reg_pwm = IT87_REG_PWM,
.num_temp_limit = 6,
.num_temp_offset = 3,
.num_temp_map = 3,
@@ -570,6 +594,7 @@ static const struct it87_devices it87_devices[] = {
| FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI
| FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_FANCTL_ONOFF
| FEAT_NOCONF,
+ .reg_pwm = IT87_REG_PWM,
.num_temp_limit = 3,
.num_temp_offset = 3,
.num_temp_map = 3,
@@ -612,6 +637,7 @@ static const struct it87_devices it87_devices[] = {
#define has_scaling(data) ((data)->features & (FEAT_12MV_ADC | \
FEAT_10_9MV_ADC))
#define has_fanctl_onoff(data) ((data)->features & FEAT_FANCTL_ONOFF)
+#define has_new_tempmap(data) ((data)->features & FEAT_NEW_TEMPMAP)
struct it87_sio_data {
int sioaddr;
@@ -641,6 +667,7 @@ struct it87_data {
int sioaddr;
enum chips type;
u32 features;
+ const u8 *reg_pwm;
u8 num_temp_limit;
u8 num_temp_offset;
u8 num_temp_map;
@@ -690,7 +717,9 @@ struct it87_data {
u8 has_pwm; /* Bitfield, pwm control enabled */
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[NUM_PWM];/* PWM to temp. chan. mapping */
+ u8 pwm_temp_map_mask;
+ u8 pwm_temp_map_shift;
/* Automatic fan speed control registers */
u8 auto_pwm[NUM_AUTO_PWM][4]; /* [nr][3] is hard-coded */
@@ -772,6 +801,71 @@ static int pwm_from_reg(const struct it87_data *data, u8 reg)
return (reg & 0x7f) << 1;
}
+static inline u8 pwm_temp_map_get(const struct it87_data *data, u8 ctrl)
+{
+ return (ctrl >> data->pwm_temp_map_shift) &
+ data->pwm_temp_map_mask;
+}
+
+static inline u8 pwm_temp_map_set(const struct it87_data *data, u8 ctrl,
+ u8 map)
+{
+ ctrl &= ~(data->pwm_temp_map_mask << data->pwm_temp_map_shift);
+ return ctrl | ((map & data->pwm_temp_map_mask)
+ << data->pwm_temp_map_shift);
+}
+
+static inline u8 pwm_num_temp_map(const struct it87_data *data)
+{
+ return data->num_temp_map;
+}
+
+static unsigned int pwm_temp_channel(const struct it87_data *data,
+ int nr, u8 map)
+{
+ if (has_new_tempmap(data)) {
+ u8 num = pwm_num_temp_map(data);
+
+ if (map >= num)
+ map = 0;
+ return map;
+ }
+
+ if (map >= IT87_PWM_OLD_NUM_TEMP)
+ map = 0;
+
+ if (nr >= IT87_PWM_OLD_NUM_TEMP)
+ map += IT87_PWM_OLD_NUM_TEMP;
+
+ return map;
+}
+
+static int pwm_temp_map_from_channel(const struct it87_data *data, int nr,
+ unsigned int channel, u8 *map)
+{
+ if (has_new_tempmap(data)) {
+ u8 num = pwm_num_temp_map(data);
+
+ if (channel >= num)
+ return -EINVAL;
+ *map = channel;
+ return 0;
+ }
+
+ if (nr >= IT87_PWM_OLD_NUM_TEMP) {
+ if (channel < IT87_PWM_OLD_NUM_TEMP ||
+ channel >= 2 * IT87_PWM_OLD_NUM_TEMP)
+ return -EINVAL;
+ channel -= IT87_PWM_OLD_NUM_TEMP;
+ } else {
+ if (channel >= IT87_PWM_OLD_NUM_TEMP)
+ return -EINVAL;
+ }
+
+ *map = channel;
+ return 0;
+}
+
static int DIV_TO_REG(int val)
{
int answer = 0;
@@ -783,6 +877,11 @@ static int DIV_TO_REG(int val)
#define DIV_FROM_REG(val) BIT(val)
+static inline u16 it87_reg_pwm(const struct it87_data *data, int nr)
+{
+ return data->reg_pwm[nr];
+}
+
/*
* 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.
@@ -863,14 +962,22 @@ static void it87_write_value(struct it87_data *data, u8 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, it87_reg_pwm(data, nr));
if (has_newer_autopwm(data)) {
- data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03;
+ data->pwm_temp_map[nr] =
+ pwm_temp_map_get(data, data->pwm_ctrl[nr]);
+ if (has_new_tempmap(data) &&
+ data->pwm_temp_map[nr] >= pwm_num_temp_map(data))
+ data->pwm_temp_map[nr] = 0;
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;
+ data->pwm_temp_map[nr] =
+ pwm_temp_map_get(data, data->pwm_ctrl[nr]);
+ if (has_new_tempmap(data) &&
+ data->pwm_temp_map[nr] >= pwm_num_temp_map(data))
+ data->pwm_temp_map[nr] = 0;
else /* Manual mode */
data->pwm_duty[nr] = data->pwm_ctrl[nr] & 0x7f;
}
@@ -1600,6 +1707,8 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr,
if (err)
return err;
+ it87_update_pwm_ctrl(data, nr);
+
if (val == 0) {
if (nr < 3 && has_fanctl_onoff(data)) {
int tmp;
@@ -1619,27 +1728,30 @@ 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 = pwm_temp_map_set(data,
+ data->pwm_ctrl[nr] &
+ ~0x80,
+ data->pwm_temp_map[nr]);
} else {
ctrl = data->pwm_duty[nr];
}
data->pwm_ctrl[nr] = ctrl;
- it87_write_value(data, IT87_REG_PWM[nr], ctrl);
+ it87_write_value(data, it87_reg_pwm(data, nr), ctrl);
}
} else {
u8 ctrl;
if (has_newer_autopwm(data)) {
- ctrl = (data->pwm_ctrl[nr] & 0x7c) |
- data->pwm_temp_map[nr];
+ ctrl = pwm_temp_map_set(data,
+ data->pwm_ctrl[nr] & ~0x80,
+ data->pwm_temp_map[nr]);
if (val != 1)
ctrl |= 0x80;
} else {
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, it87_reg_pwm(data, nr), ctrl);
if (has_fanctl_onoff(data) && nr < 3) {
/* set SmartGuardian mode */
@@ -1690,7 +1802,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, it87_reg_pwm(data, nr),
data->pwm_ctrl[nr]);
}
}
@@ -1745,20 +1857,14 @@ 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;
- u8 num_map;
- int map;
+ unsigned int channel;
if (IS_ERR(data))
return PTR_ERR(data);
- num_map = data->num_temp_map;
- map = data->pwm_temp_map[nr];
- if (map >= num_map)
- map = 0; /* Should never happen */
- if (nr >= num_map) /* pwm channels 3..6 map to temp4..6 */
- map += num_map;
+ channel = pwm_temp_channel(data, nr, data->pwm_temp_map[nr]);
- return sprintf(buf, "%d\n", (int)BIT(map));
+ return sprintf(buf, "%d\n", (int)BIT(channel));
}
static ssize_t set_pwm_temp_map(struct device *dev,
@@ -1768,45 +1874,34 @@ 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;
- u8 num_map = data->num_temp_map;
long val;
int err;
- u8 reg;
+ unsigned int channel;
+ u8 map;
- if (kstrtol(buf, 10, &val) < 0)
+ if (kstrtol(buf, 10, &val) < 0 || val <= 0 || !is_power_of_2(val))
return -EINVAL;
- if (nr >= num_map)
- val -= num_map;
-
- switch (val) {
- case BIT(0):
- reg = 0x00;
- break;
- case BIT(1):
- reg = 0x01;
- break;
- case BIT(2):
- reg = 0x02;
- break;
- default:
+ channel = __ffs(val);
+ if (pwm_temp_map_from_channel(data, nr, channel, &map))
return -EINVAL;
- }
err = it87_lock(data);
if (err)
return err;
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) {
- 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]);
+ data->pwm_ctrl[nr] = pwm_temp_map_set(data,
+ data->pwm_ctrl[nr],
+ data->pwm_temp_map[nr]);
+ it87_write_value(data, it87_reg_pwm(data, nr),
+ data->pwm_ctrl[nr]);
}
it87_unlock(data);
return count;
@@ -3357,7 +3452,10 @@ 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;
+ if (has_new_tempmap(data))
+ data->pwm_temp_map[i] = 0;
+ else
+ data->pwm_temp_map[i] = i % IT87_PWM_OLD_NUM_TEMP;
data->pwm_duty[i] = 0x7f; /* Full speed */
data->auto_pwm[i][3] = 0x7f; /* Full speed, hard-coded */
}
@@ -3429,7 +3527,8 @@ 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]);
+ it87_reg_pwm(data,
+ i));
/*
* If any fan is in automatic pwm mode, the polarity
@@ -3444,7 +3543,8 @@ static int it87_check_pwm(struct device *dev)
tmp | 0x87);
for (i = 0; i < 3; i++)
it87_write_value(data,
- IT87_REG_PWM[i],
+ it87_reg_pwm(data,
+ i),
0x7f & ~pwm[i]);
return 1;
}
@@ -3493,11 +3593,19 @@ static int it87_probe(struct platform_device *pdev)
data->ec_special_config = sio_data->ec_special_config;
chip = &it87_devices[sio_data->type];
data->features = chip->features;
+ data->reg_pwm = chip->reg_pwm;
data->peci_mask = chip->peci_mask;
data->old_peci_mask = chip->old_peci_mask;
data->num_temp_limit = chip->num_temp_limit;
data->num_temp_offset = chip->num_temp_offset;
data->num_temp_map = chip->num_temp_map;
+ if (has_new_tempmap(data)) {
+ data->pwm_temp_map_mask = 0x07;
+ data->pwm_temp_map_shift = 3;
+ } else {
+ data->pwm_temp_map_mask = 0x03;
+ data->pwm_temp_map_shift = 0;
+ }
/*
* IT8705F Datasheet 0.4.1, 3h == Version G.
* IT8712F Datasheet 0.9.1, section 8.3.5 indicates 8h == Version J.
--
2.50.1 (Apple Git-155)
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 3/5] hwmon: it87: expose additional temperature limits
2026-01-14 22:12 [PATCH v4 0/5] hwmon: it87: add IT8613E support benoit.masson
2026-01-14 22:12 ` [PATCH v4 1/5] hwmon: it87: describe per-chip temperature resources benoit.masson
2026-01-14 22:12 ` [PATCH v4 2/5] hwmon: it87: prepare for extended PWM temp maps benoit.masson
@ 2026-01-14 22:12 ` benoit.masson
2026-01-14 22:12 ` [PATCH v4 4/5] hwmon: it87: add IT8613E identification benoit.masson
2026-01-14 22:12 ` [PATCH v4 5/5] hwmon: it87: add IT8613E configuration benoit.masson
4 siblings, 0 replies; 10+ messages in thread
From: benoit.masson @ 2026-01-14 22:12 UTC (permalink / raw)
To: Jean Delvare, Guenter Roeck
Cc: linux-hwmon, linux-kernel, Jonathan Corbet, linux-doc, benoit.masson
Expose extra temp min/max/offset/type/alarm attributes when a chip
reports more than three temperature resources.
Signed-off-by: benoit.masson <yahoo@perenite.com>
---
drivers/hwmon/it87.c | 58 ++++++++++++++++++++++++++++++++++++++++----
1 file changed, 53 insertions(+), 5 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 2d4264d05bc2..368ae68ace15 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -1334,8 +1334,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 int get_temp_type(struct it87_data *data, int index)
{
@@ -1461,6 +1479,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 */
@@ -2290,6 +2314,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);
@@ -2350,6 +2377,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)
@@ -2512,14 +2542,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 == 3) {
if (get_temp_type(data, i) == 0)
return 0;
@@ -2561,8 +2589,28 @@ 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
};
--
2.50.1 (Apple Git-155)
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 4/5] hwmon: it87: add IT8613E identification
2026-01-14 22:12 [PATCH v4 0/5] hwmon: it87: add IT8613E support benoit.masson
` (2 preceding siblings ...)
2026-01-14 22:12 ` [PATCH v4 3/5] hwmon: it87: expose additional temperature limits benoit.masson
@ 2026-01-14 22:12 ` benoit.masson
2026-01-14 22:12 ` [PATCH v4 5/5] hwmon: it87: add IT8613E configuration benoit.masson
4 siblings, 0 replies; 10+ messages in thread
From: benoit.masson @ 2026-01-14 22:12 UTC (permalink / raw)
To: Jean Delvare, Guenter Roeck
Cc: linux-hwmon, linux-kernel, Jonathan Corbet, linux-doc, benoit.masson
Teach the Super I/O probe path to recognize IT8613E and advertise
its model name in the supported device list.
Signed-off-by: benoit.masson <yahoo@perenite.com>
---
drivers/hwmon/it87.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 368ae68ace15..4453bf3e8ef4 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -35,6 +35,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
@@ -64,7 +65,7 @@
enum chips { it87, it8712, it8716, it8718, it8720, it8721, it8728, it8732,
it8771, it8772, it8781, it8782, it8783, it8786, it8790,
- it8792, it8603, it8620, it8622, it8628, it87952 };
+ it8792, it8603, it8613, it8620, it8622, it8628, it87952 };
static struct platform_device *it87_pdev[2];
@@ -158,6 +159,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
@@ -547,6 +549,10 @@ static const struct it87_devices it87_devices[] = {
.num_temp_map = 4,
.peci_mask = 0x07,
},
+ [it8613] = {
+ .name = "it8613",
+ .model = "IT8613E",
+ },
[it8620] = {
.name = "it8620",
.model = "IT8620E",
@@ -2988,6 +2994,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;
--
2.50.1 (Apple Git-155)
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 5/5] hwmon: it87: add IT8613E configuration
2026-01-14 22:12 [PATCH v4 0/5] hwmon: it87: add IT8613E support benoit.masson
` (3 preceding siblings ...)
2026-01-14 22:12 ` [PATCH v4 4/5] hwmon: it87: add IT8613E identification benoit.masson
@ 2026-01-14 22:12 ` benoit.masson
4 siblings, 0 replies; 10+ messages in thread
From: benoit.masson @ 2026-01-14 22:12 UTC (permalink / raw)
To: Jean Delvare, Guenter Roeck
Cc: linux-hwmon, linux-kernel, Jonathan Corbet, linux-doc, benoit.masson
Add IT8613E feature flags, resource counts, ADC scaling, and GPIO
quirk handling, then document the chip in the hwmon guide.
Signed-off-by: benoit.masson <yahoo@perenite.com>
---
Documentation/hwmon/it87.rst | 8 ++++++
drivers/hwmon/it87.c | 52 +++++++++++++++++++++++++++++++++++-
2 files changed, 59 insertions(+), 1 deletion(-)
diff --git a/Documentation/hwmon/it87.rst b/Documentation/hwmon/it87.rst
index 5cef4f265000..fa968be84f7c 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 4453bf3e8ef4..6a0ee13bc95f 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -333,6 +333,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] = {
@@ -552,6 +553,14 @@ static const struct it87_devices it87_devices[] = {
[it8613] = {
.name = "it8613",
.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
+ | FEAT_AVCC3 | FEAT_NEW_TEMPMAP,
+ .num_temp_limit = 6,
+ .num_temp_offset = 6,
+ .num_temp_map = 6,
+ .peci_mask = 0x07,
},
[it8620] = {
.name = "it8620",
@@ -612,6 +621,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_peci(data, nr) (((data)->features & FEAT_TEMP_PECI) && \
@@ -641,7 +651,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)
@@ -748,6 +759,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))
@@ -3171,6 +3184,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) {
--
2.50.1 (Apple Git-155)
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 1/5] hwmon: it87: describe per-chip temperature resources
2026-01-14 22:12 ` [PATCH v4 1/5] hwmon: it87: describe per-chip temperature resources benoit.masson
@ 2026-01-17 14:39 ` Guenter Roeck
2026-01-17 22:11 ` Benoit Masson
0 siblings, 1 reply; 10+ messages in thread
From: Guenter Roeck @ 2026-01-17 14:39 UTC (permalink / raw)
To: benoit.masson
Cc: Jean Delvare, linux-hwmon, linux-kernel, Jonathan Corbet, linux-doc
On Wed, Jan 14, 2026 at 11:12:06PM +0100, benoit.masson wrote:
> Add per-chip temp limit/offset/map counts and wire the driver
> to use them.
>
> This keeps existing chips on the previous defaults while allowing newer
> chips to advertise larger resources.
>
> Signed-off-by: benoit.masson <yahoo@perenite.com>
Series applied.
Thanks,
Guenter
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 1/5] hwmon: it87: describe per-chip temperature resources
2026-01-17 14:39 ` Guenter Roeck
@ 2026-01-17 22:11 ` Benoit Masson
2026-01-17 22:53 ` Guenter Roeck
2026-01-17 23:10 ` Guenter Roeck
0 siblings, 2 replies; 10+ messages in thread
From: Benoit Masson @ 2026-01-17 22:11 UTC (permalink / raw)
To: Guenter Roeck
Cc: Jean Delvare, linux-hwmon, linux-kernel, Jonathan Corbet, linux-doc
On Sat, Jan 17, 2026 at 3:39 PM Guenter Roeck <linux@roeck-us.net> wrote:
> Series applied.
Guenter, my appologies but after changing some BIOS parameters of the
IT8613E it seems the patch has something wrong and creates a null
pointer exception. Can you please remove patch for now until I test
all BIOS/changes before re-submiting. I'm sorry for the miss here and
your work pushing for this but prefer to prevent the patch for getting
deeping in the submission chain.
> Thanks,
> Guenter
Tahnks and sorry again for missing this.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 1/5] hwmon: it87: describe per-chip temperature resources
2026-01-17 22:11 ` Benoit Masson
@ 2026-01-17 22:53 ` Guenter Roeck
2026-01-17 23:10 ` Guenter Roeck
1 sibling, 0 replies; 10+ messages in thread
From: Guenter Roeck @ 2026-01-17 22:53 UTC (permalink / raw)
To: Benoit Masson
Cc: Jean Delvare, linux-hwmon, linux-kernel, Jonathan Corbet, linux-doc
On 1/17/26 14:11, Benoit Masson wrote:
> On Sat, Jan 17, 2026 at 3:39 PM Guenter Roeck <linux@roeck-us.net> wrote:
>> Series applied.
> Guenter, my appologies but after changing some BIOS parameters of the
> IT8613E it seems the patch has something wrong and creates a null
> pointer exception. Can you please remove patch for now until I test
> all BIOS/changes before re-submiting. I'm sorry for the miss here and
> your work pushing for this but prefer to prevent the patch for getting
> deeping in the submission chain.
>
>> Thanks,
>> Guenter
> Tahnks and sorry again for missing this.
>
NP, thanks for letting me know. I'll drop the series.
Guenter
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 1/5] hwmon: it87: describe per-chip temperature resources
2026-01-17 22:11 ` Benoit Masson
2026-01-17 22:53 ` Guenter Roeck
@ 2026-01-17 23:10 ` Guenter Roeck
1 sibling, 0 replies; 10+ messages in thread
From: Guenter Roeck @ 2026-01-17 23:10 UTC (permalink / raw)
To: Benoit Masson
Cc: Jean Delvare, linux-hwmon, linux-kernel, Jonathan Corbet, linux-doc
On Sat, Jan 17, 2026 at 11:11:32PM +0100, Benoit Masson wrote:
> On Sat, Jan 17, 2026 at 3:39 PM Guenter Roeck <linux@roeck-us.net> wrote:
> > Series applied.
> Guenter, my appologies but after changing some BIOS parameters of the
> IT8613E it seems the patch has something wrong and creates a null
> pointer exception. Can you please remove patch for now until I test
> all BIOS/changes before re-submiting. I'm sorry for the miss here and
> your work pushing for this but prefer to prevent the patch for getting
> deeping in the submission chain.
>
Does this help ? It is what Gemini had to say about your series.
Guenter
---
My analysis of the top 5 patches in the it87 driver reveals a NULL pointer regression introduced by the series.
The regression is caused by the addition of the IT8613E chip support in commits 8e6b5dcdb757 and 21506a88d3d5. These commits failed to initialize the .reg_pwm field for the it8613 entry in the it87_devices array.
Technical Details:
1. Commit `2fc4e2363316` introduced a new pointer field reg_pwm to struct it87_devices and struct it87_data. It also updated the it87_reg_pwm helper to dereference this pointer:
1 static inline u16 it87_reg_pwm(const struct it87_data *data, int nr)
2 {
3 return data->reg_pwm[nr];
4 }
2. Commit `8e6b5dcdb757` added the it8613 entry to the it87_devices array but missed the .reg_pwm initialization (leaving it as NULL).
3. Commit `21506a88d3d5` further configured the it8613 entry but still did not provide a .reg_pwm value.
4. Registration Crash: During the probe of an IT8613E chip, it87_probe sets data->reg_pwm = chip->reg_pwm (which is NULL). It then calls it87_check_pwm(dev), which calls it87_reg_pwm(data, i). This result in a NULL pointer dereference
when attempting to access data->reg_pwm[i].
Why commit f977d3bf3614 was suspected:
While commit f977d3bf3614 itself is technically safe (as it only added resource counts which were initialized for all existing chips at the time), it was the first patch in the series that introduced per-chip configuration requirements.
The user likely associated the crash with this starting point of the series.
Conclusion:
The bug is in the it8613 device definition. It must be updated to include .reg_pwm = IT87_REG_PWM (or the appropriate register map for that chip). Additionally, there is a potential out-of-bounds access in it87_update_device because it8613
defines .num_temp_offset = 6, but the IT87_REG_TEMP_OFFSET array only has 3 elements.
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-01-17 23:10 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-01-14 22:12 [PATCH v4 0/5] hwmon: it87: add IT8613E support benoit.masson
2026-01-14 22:12 ` [PATCH v4 1/5] hwmon: it87: describe per-chip temperature resources benoit.masson
2026-01-17 14:39 ` Guenter Roeck
2026-01-17 22:11 ` Benoit Masson
2026-01-17 22:53 ` Guenter Roeck
2026-01-17 23:10 ` Guenter Roeck
2026-01-14 22:12 ` [PATCH v4 2/5] hwmon: it87: prepare for extended PWM temp maps benoit.masson
2026-01-14 22:12 ` [PATCH v4 3/5] hwmon: it87: expose additional temperature limits benoit.masson
2026-01-14 22:12 ` [PATCH v4 4/5] hwmon: it87: add IT8613E identification benoit.masson
2026-01-14 22:12 ` [PATCH v4 5/5] hwmon: it87: add IT8613E configuration benoit.masson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®