[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250810084307.41243-1-chenchuande@gmail.com>
Date: Sun, 10 Aug 2025 16:43:07 +0800
From: Chuande Chen <chenchuande@...il.com>
To: jdelvare@...e.com
Cc: linux@...ck-us.net,
linux-hwmon@...r.kernel.org,
linux-kernel@...r.kernel.org,
chuachen@...co.com,
chenchuande@...il.com
Subject: [PATCH] hwmon: sbtsi_temp: AMD CPU extended temperature range support
From: Chuande Chen <chuachen@...co.com>
Many AMD CPUs can support this feature now.
We would get a wrong CPU DIE temp if don't consider this.
In low-temperature environments, the CPU die temperature
can drop below zero.
So many platform would like to make extended temperature range
as their default configuration.
Default temperature range (0C to 255.875C) degree celsius.
Extended temperature range (-49C to +206.875C) degree celsius.
Ref Doc: AMD V3000 PPR (Doc ID #56558).
Signed-off-by: Chuande Chen <chuachen@...co.com>
---
drivers/hwmon/sbtsi_temp.c | 32 +++++++++++++++++++++++++-------
1 file changed, 25 insertions(+), 7 deletions(-)
diff --git a/drivers/hwmon/sbtsi_temp.c b/drivers/hwmon/sbtsi_temp.c
index 3c839f56c..15e49c2a0 100644
--- a/drivers/hwmon/sbtsi_temp.c
+++ b/drivers/hwmon/sbtsi_temp.c
@@ -30,6 +30,14 @@
#define SBTSI_REG_TEMP_LOW_DEC 0x14 /* RW */
#define SBTSI_CONFIG_READ_ORDER_SHIFT 5
+/*
+ * Bit for temperature measurement range.
+ * Value=0: Use default temperature range (0C to 255.875C) for reporting temperature.
+ * Value=1: Use extended temperature range (-49C to +206.875C) for reporting temperature.
+ */
+#define SBTSI_CONFIG_EXT_RAGE_SHIFT 2
+
+#define SBTSI_TEMP_EXT_RAGE_ADJ 49000
#define SBTSI_TEMP_MIN 0
#define SBTSI_TEMP_MAX 255875
@@ -74,7 +82,12 @@ static int sbtsi_read(struct device *dev, enum hwmon_sensor_types type,
{
struct sbtsi_data *data = dev_get_drvdata(dev);
s32 temp_int, temp_dec;
- int err;
+ int err, cfg;
+
+ err = i2c_smbus_read_byte_data(data->client, SBTSI_REG_CONFIG);
+ if (err < 0)
+ return err;
+ cfg = err;
switch (attr) {
case hwmon_temp_input:
@@ -85,12 +98,8 @@ static int sbtsi_read(struct device *dev, enum hwmon_sensor_types type,
* so integer part should be read first. If bit == 1, read
* order should be reversed.
*/
- err = i2c_smbus_read_byte_data(data->client, SBTSI_REG_CONFIG);
- if (err < 0)
- return err;
-
mutex_lock(&data->lock);
- if (err & BIT(SBTSI_CONFIG_READ_ORDER_SHIFT)) {
+ if (cfg & BIT(SBTSI_CONFIG_READ_ORDER_SHIFT)) {
temp_dec = i2c_smbus_read_byte_data(data->client, SBTSI_REG_TEMP_DEC);
temp_int = i2c_smbus_read_byte_data(data->client, SBTSI_REG_TEMP_INT);
} else {
@@ -122,6 +131,8 @@ static int sbtsi_read(struct device *dev, enum hwmon_sensor_types type,
return temp_dec;
*val = sbtsi_reg_to_mc(temp_int, temp_dec);
+ if (cfg & BIT(SBTSI_CONFIG_EXT_RAGE_SHIFT))
+ *val -= SBTSI_TEMP_EXT_RAGE_ADJ;
return 0;
}
@@ -130,9 +141,14 @@ static int sbtsi_write(struct device *dev, enum hwmon_sensor_types type,
u32 attr, int channel, long val)
{
struct sbtsi_data *data = dev_get_drvdata(dev);
- int reg_int, reg_dec, err;
+ int reg_int, reg_dec, err, cfg;
u8 temp_int, temp_dec;
+ err = i2c_smbus_read_byte_data(data->client, SBTSI_REG_CONFIG);
+ if (err < 0)
+ return err;
+ cfg = err;
+
switch (attr) {
case hwmon_temp_max:
reg_int = SBTSI_REG_TEMP_HIGH_INT;
@@ -146,6 +162,8 @@ static int sbtsi_write(struct device *dev, enum hwmon_sensor_types type,
return -EINVAL;
}
+ if (cfg & BIT(SBTSI_CONFIG_EXT_RAGE_SHIFT))
+ val += SBTSI_TEMP_EXT_RAGE_ADJ;
val = clamp_val(val, SBTSI_TEMP_MIN, SBTSI_TEMP_MAX);
sbtsi_mc_to_reg(val, &temp_int, &temp_dec);
--
2.39.5 (Apple Git-154)
Powered by blists - more mailing lists