hwmon: (ftsteutates) Fix scaling of measurements
[ Upstream commitca8fd8c16a
] 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:08426eda58
("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> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Родитель
11226ab2f9
Коммит
1721badebf
|
@ -22,6 +22,10 @@ enhancements. It can monitor up to 4 voltages, 16 temperatures and
|
||||||
8 fans. It also contains an integrated watchdog which is currently
|
8 fans. It also contains an integrated watchdog which is currently
|
||||||
implemented in this driver.
|
implemented in this driver.
|
||||||
|
|
||||||
|
The 4 voltages require a board-specific multiplier, since the BMC can
|
||||||
|
only measure voltages up to 3.3V and thus relies on voltage dividers.
|
||||||
|
Consult your motherboard manual for details.
|
||||||
|
|
||||||
To clear a temperature or fan alarm, execute the following command with the
|
To clear a temperature or fan alarm, execute the following command with the
|
||||||
correct path to the alarm file::
|
correct path to the alarm file::
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/jiffies.h>
|
#include <linux/jiffies.h>
|
||||||
|
#include <linux/math.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
#include <linux/slab.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);
|
struct fts_data *data = dev_get_drvdata(dev);
|
||||||
int index = to_sensor_dev_attr(devattr)->index;
|
int index = to_sensor_dev_attr(devattr)->index;
|
||||||
int err;
|
int value, err;
|
||||||
|
|
||||||
err = fts_update_device(data);
|
err = fts_update_device(data);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
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,
|
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);
|
struct fts_data *data = dev_get_drvdata(dev);
|
||||||
int index = to_sensor_dev_attr(devattr)->index;
|
int index = to_sensor_dev_attr(devattr)->index;
|
||||||
int err;
|
int value, err;
|
||||||
|
|
||||||
err = fts_update_device(data);
|
err = fts_update_device(data);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
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,
|
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);
|
struct fts_data *data = dev_get_drvdata(dev);
|
||||||
int index = to_sensor_dev_attr(devattr)->index;
|
int index = to_sensor_dev_attr(devattr)->index;
|
||||||
int err;
|
int value, err;
|
||||||
|
|
||||||
err = fts_update_device(data);
|
err = fts_update_device(data);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
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,
|
static ssize_t fan_source_show(struct device *dev,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче