[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20251226222001.41914-1-yahoo@perenite.com>
Date: Fri, 26 Dec 2025 23:20:01 +0100
From: "benoit.masson" <yahoo@...enite.com>
To: jdelvare@...e.com,
linux@...ck-us.net
Cc: linux-hwmon@...r.kernel.org,
linux-kernel@...r.kernel.org,
"benoit.masson" <yahoo@...enite.com>
Subject: [PATCH] hwmon: it87: expose additional temperature limits
Signed-off-by: benoit.masson <yahoo@...enite.com>
---
drivers/hwmon/it87.c | 91 ++++++++++++++++++++++++++++++++++++--------
1 file changed, 76 insertions(+), 15 deletions(-)
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 1107039d2b6a..d50c40f8607f 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -246,7 +246,9 @@ 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_TEMP_OFFSET[] = { 0x56, 0x57, 0x59 };
+static const u8 IT87_REG_TEMP_OFFSET[] = { 0x56, 0x57, 0x59, 0x5a, 0x90, 0x91 };
+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
@@ -260,8 +262,12 @@ 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_HIGH_8686[] =
+ { 0x40, 0x42, 0x44, 0xb4, 0xb6, 0xb8 };
+static const u8 IT87_REG_TEMP_LOW[] = { 0x41, 0x43, 0x45, 0x47, 0xb5, 0xb7 };
+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
@@ -610,6 +616,9 @@ 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 */
+ const u8 *reg_temp_low;
+ const u8 *reg_temp_high;
+ const u8 *reg_temp_offset;
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 */
@@ -1011,15 +1020,15 @@ static struct it87_data *it87_update_device(struct device *dev)
i < data->num_temp_offset)
data->temp[i][3] =
it87_read_value(data,
- IT87_REG_TEMP_OFFSET[i]);
+ data->reg_temp_offset[i]);
if (i >= data->num_temp_limit)
continue;
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 */
@@ -1199,10 +1208,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);
@@ -1211,7 +1220,7 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr,
it87_write_value(data, IT87_REG_BEEP_ENABLE, regval);
}
data->valid = false;
- reg = IT87_REG_TEMP_OFFSET[nr];
+ reg = data->reg_temp_offset[nr];
break;
}
@@ -1243,8 +1252,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)
{
@@ -2415,24 +2442,46 @@ static umode_t it87_temp_is_visible(struct kobject *kobj,
{
struct device *dev = kobj_to_dev(kobj);
struct it87_data *data = dev_get_drvdata(dev);
- int i = index / 7; /* temperature index */
- int a = index % 7; /* attribute index */
+ int i, a;
- if (index >= 21) {
+ if (index < 21) {
+ i = index / 7; /* temperature index */
+ a = index % 7; /* attribute index */
+ } else if (index < 24) {
i = index - 21 + 3;
a = 0;
+ } else {
+ int off = index - 24;
+
+ i = 3 + off / 3;
+ switch (off % 3) {
+ case 0:
+ a = 1;
+ break;
+ case 1:
+ a = 2;
+ break;
+ default:
+ a = 5;
+ break;
+ }
}
if (!(data->has_temp & BIT(i)))
return 0;
+ if ((a == 1 || a == 2 || a == 4) &&
+ i >= data->num_temp_limit)
+ return 0;
+
if (a == 3) {
if (get_temp_type(data, i) == 0)
return 0;
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)
@@ -2467,8 +2516,17 @@ 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_offset.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_offset.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_offset.dev_attr.attr,
NULL
};
@@ -3277,9 +3335,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);
}
}
@@ -3514,6 +3572,9 @@ static int it87_probe(struct platform_device *pdev)
data->num_temp_offset = 0;
data->num_temp_map = chip->num_temp_map ?
chip->num_temp_map : IT87_TEMP_MAP_DEFAULT;
+ data->reg_temp_low = IT87_REG_TEMP_LOW;
+ data->reg_temp_high = IT87_REG_TEMP_HIGH;
+ data->reg_temp_offset = IT87_REG_TEMP_OFFSET;
if (has_new_tempmap(data)) {
data->pwm_temp_map_mask = 0x07;
data->pwm_temp_map_shift = 3;
--
2.50.1 (Apple Git-155)
Powered by blists - more mailing lists