aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
authorEugene Shalygin <eugene.shalygin@gmail.com>2022-02-11 17:48:55 +0100
committerGuenter Roeck <linux@roeck-us.net>2022-02-27 17:03:18 -0800
commit8aba9ca62677570abf8c6b62611adb85bf1580ca (patch)
treef13b8d1c38639fcd691dec2d333da57cafcde44b /drivers/hwmon
parenthwmon: (tc654) Add thermal_cooling device support (diff)
downloadlinux-dev-8aba9ca62677570abf8c6b62611adb85bf1580ca.tar.xz
linux-dev-8aba9ca62677570abf8c6b62611adb85bf1580ca.zip
hwmon: (asus-ec-sensors) deduce sensor signedness from its type
Reading DSDT code for ASUS X470-based boards (the ones served by the asus_wmi_Sensors driver), where ASUS put hardware monitoring functions into the WMI code, reveals that fan and current sensors data is unsigned. For the current sensor that was confirmed by a user who showed high enough current value for overflow. Thus let's assume that the signedness of the sensors is determined by its type and that only temperature ones provide signed numbers. Signed-off-by: Eugene Shalygin <eugene.shalygin@gmail.com> Link: https://lore.kernel.org/r/20220211164855.265698-1-eugene.shalygin@gmail.com Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/asus-ec-sensors.c40
1 files changed, 31 insertions, 9 deletions
diff --git a/drivers/hwmon/asus-ec-sensors.c b/drivers/hwmon/asus-ec-sensors.c
index bfac08a5dc57..d2b84578d2af 100644
--- a/drivers/hwmon/asus-ec-sensors.c
+++ b/drivers/hwmon/asus-ec-sensors.c
@@ -266,6 +266,15 @@ static u8 register_index(u16 reg)
return reg & 0x00ff;
}
+static bool is_sensor_data_signed(const struct ec_sensor_info *si)
+{
+ /*
+ * guessed from WMI functions in DSDT code for boards
+ * of the X470 generation
+ */
+ return si->type == hwmon_temp;
+}
+
static const struct ec_sensor_info *
get_sensor_info(const struct ec_sensors_data *state, int index)
{
@@ -420,15 +429,28 @@ static int asus_ec_block_read(const struct device *dev,
static inline s32 get_sensor_value(const struct ec_sensor_info *si, u8 *data)
{
- switch (si->addr.components.size) {
- case 1:
- return (s8)*data;
- case 2:
- return (s16)get_unaligned_be16(data);
- case 4:
- return (s32)get_unaligned_be32(data);
- default:
- return 0;
+ if (is_sensor_data_signed(si)) {
+ switch (si->addr.components.size) {
+ case 1:
+ return (s8)*data;
+ case 2:
+ return (s16)get_unaligned_be16(data);
+ case 4:
+ return (s32)get_unaligned_be32(data);
+ default:
+ return 0;
+ }
+ } else {
+ switch (si->addr.components.size) {
+ case 1:
+ return *data;
+ case 2:
+ return get_unaligned_be16(data);
+ case 4:
+ return get_unaligned_be32(data);
+ default:
+ return 0;
+ }
}
}