| From b42016a1f859149aee1a4e560dec049ad650e748 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Fri, 24 Sep 2021 12:30:11 +0300 |
| Subject: hwmon: (tmp421) fix rounding for negative values |
| |
| From: Paul Fertser <fercerpav@gmail.com> |
| |
| [ Upstream commit 724e8af85854c4d3401313b6dd7d79cf792d8990 ] |
| |
| Old code produces -24999 for 0b1110011100000000 input in standard format due to |
| always rounding up rather than "away from zero". |
| |
| Use the common macro for division, unify and simplify the conversion code along |
| the way. |
| |
| Fixes: 9410700b881f ("hwmon: Add driver for Texas Instruments TMP421/422/423 sensor chips") |
| Signed-off-by: Paul Fertser <fercerpav@gmail.com> |
| Link: https://lore.kernel.org/r/20210924093011.26083-3-fercerpav@gmail.com |
| Signed-off-by: Guenter Roeck <linux@roeck-us.net> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/hwmon/tmp421.c | 24 ++++++++---------------- |
| 1 file changed, 8 insertions(+), 16 deletions(-) |
| |
| diff --git a/drivers/hwmon/tmp421.c b/drivers/hwmon/tmp421.c |
| index c9ef83627bb7..b963a369c5ab 100644 |
| --- a/drivers/hwmon/tmp421.c |
| +++ b/drivers/hwmon/tmp421.c |
| @@ -100,23 +100,17 @@ struct tmp421_data { |
| s16 temp[4]; |
| }; |
| |
| -static int temp_from_s16(s16 reg) |
| +static int temp_from_raw(u16 reg, bool extended) |
| { |
| /* Mask out status bits */ |
| int temp = reg & ~0xf; |
| |
| - return (temp * 1000 + 128) / 256; |
| -} |
| - |
| -static int temp_from_u16(u16 reg) |
| -{ |
| - /* Mask out status bits */ |
| - int temp = reg & ~0xf; |
| - |
| - /* Add offset for extended temperature range. */ |
| - temp -= 64 * 256; |
| + if (extended) |
| + temp = temp - 64 * 256; |
| + else |
| + temp = (s16)temp; |
| |
| - return (temp * 1000 + 128) / 256; |
| + return DIV_ROUND_CLOSEST(temp * 1000, 256); |
| } |
| |
| static int tmp421_update_device(struct tmp421_data *data) |
| @@ -172,10 +166,8 @@ static int tmp421_read(struct device *dev, enum hwmon_sensor_types type, |
| |
| switch (attr) { |
| case hwmon_temp_input: |
| - if (tmp421->config & TMP421_CONFIG_RANGE) |
| - *val = temp_from_u16(tmp421->temp[channel]); |
| - else |
| - *val = temp_from_s16(tmp421->temp[channel]); |
| + *val = temp_from_raw(tmp421->temp[channel], |
| + tmp421->config & TMP421_CONFIG_RANGE); |
| return 0; |
| case hwmon_temp_fault: |
| /* |
| -- |
| 2.33.0 |
| |