diff options
author | Armin Wolf <W_Armin@gmx.de> | 2022-12-24 05:18:53 +0100 |
---|---|---|
committer | Guenter Roeck <linux@roeck-us.net> | 2023-01-03 13:26:45 -0800 |
commit | ca8fd8c16a8b77dfcf7f6ce52d2c863220693a78 (patch) | |
tree | e6c9bd21e2b79b7ba86f321dd5ac887637672553 /drivers/hwmon/ftsteutates.c | |
parent | 88603b6dc419445847923fcb7fe5080067a30f98 (diff) |
hwmon: (ftsteutates) Fix scaling of measurements
A user complained that the ftsteutates driver was displaying
bogus values since its introduction. This happens because the
sensor measurements need to be scaled in order to produce
meaningful results:
- the fan speed needs to be multiplied by 60 since its in RPS
- the temperature is in degrees celsius and needs an offset of 64
- the voltage is in 1/256 of 3.3V
The offical datasheet says the voltage needs to be divided by 256,
but this is likely an off-by-one-error, since even the BIOS
devides by 255 (otherwise 3.3V could not be measured).
The voltage channels additionally need a board-specific multiplier,
however this can be done by the driver since its board-specific.
The reason the missing scaling of measurements is the way Fujitsu
used this driver when it was still out-of-tree. Back then, all
scaling was done in userspace by libsensors, even the generic one.
Tested on a Fujitsu DS3401-B1.
Fixes: 08426eda58e0 ("hwmon: Add driver for FTS BMC chip "Teutates"")
Signed-off-by: Armin Wolf <W_Armin@gmx.de>
Link: https://lore.kernel.org/r/20221224041855.83981-2-W_Armin@gmx.de
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Diffstat (limited to 'drivers/hwmon/ftsteutates.c')
-rw-r--r-- | drivers/hwmon/ftsteutates.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/drivers/hwmon/ftsteutates.c b/drivers/hwmon/ftsteutates.c index f5b8e724a8ca..ffa0bb364877 100644 --- a/drivers/hwmon/ftsteutates.c +++ b/drivers/hwmon/ftsteutates.c @@ -12,6 +12,7 @@ #include <linux/i2c.h> #include <linux/init.h> #include <linux/jiffies.h> +#include <linux/math.h> #include <linux/module.h> #include <linux/mutex.h> #include <linux/slab.h> @@ -347,13 +348,15 @@ static ssize_t in_value_show(struct device *dev, { struct fts_data *data = dev_get_drvdata(dev); int index = to_sensor_dev_attr(devattr)->index; - int err; + int value, err; err = fts_update_device(data); if (err < 0) return err; - return sprintf(buf, "%u\n", data->volt[index]); + value = DIV_ROUND_CLOSEST(data->volt[index] * 3300, 255); + + return sprintf(buf, "%d\n", value); } static ssize_t temp_value_show(struct device *dev, @@ -361,13 +364,15 @@ static ssize_t temp_value_show(struct device *dev, { struct fts_data *data = dev_get_drvdata(dev); int index = to_sensor_dev_attr(devattr)->index; - int err; + int value, err; err = fts_update_device(data); if (err < 0) return err; - return sprintf(buf, "%u\n", data->temp_input[index]); + value = (data->temp_input[index] - 64) * 1000; + + return sprintf(buf, "%d\n", value); } static ssize_t temp_fault_show(struct device *dev, @@ -436,13 +441,15 @@ static ssize_t fan_value_show(struct device *dev, { struct fts_data *data = dev_get_drvdata(dev); int index = to_sensor_dev_attr(devattr)->index; - int err; + int value, err; err = fts_update_device(data); if (err < 0) return err; - return sprintf(buf, "%u\n", data->fan_input[index]); + value = data->fan_input[index] * 60; + + return sprintf(buf, "%d\n", value); } static ssize_t fan_source_show(struct device *dev, |