Commit 0c2a40e2 authored by Guenter Roeck's avatar Guenter Roeck

hwmon: (lm95241) Fix negative temperature results

Negative temperatures were returned in degrees C instead of milli-Degrees C.
Also, negative temperatures were reported for remote temperature sensors even
if the chip was configured for positive-only results.

Fix by detecting temperature modes, and by treating negative temperatures
similar to positive temperatures, with appropriate sign extension.
Signed-off-by: default avatarGuenter Roeck <guenter.roeck@ericsson.com>
Acked-by: default avatarJean Delvare <khali@linux-fr.org>
Cc: stable@kernel.org # 2.6.30+
parent 27739e69
...@@ -98,11 +98,16 @@ struct lm95241_data { ...@@ -98,11 +98,16 @@ struct lm95241_data {
}; };
/* Conversions */ /* Conversions */
static int TempFromReg(u8 val_h, u8 val_l) static int temp_from_reg_signed(u8 val_h, u8 val_l)
{ {
if (val_h & 0x80) s16 val_hl = (val_h << 8) | val_l;
return val_h - 0x100; return val_hl * 1000 / 256;
return val_h * 1000 + val_l * 1000 / 256; }
static int temp_from_reg_unsigned(u8 val_h, u8 val_l)
{
u16 val_hl = (val_h << 8) | val_l;
return val_hl * 1000 / 256;
} }
static struct lm95241_data *lm95241_update_device(struct device *dev) static struct lm95241_data *lm95241_update_device(struct device *dev)
...@@ -135,10 +140,13 @@ static ssize_t show_input(struct device *dev, struct device_attribute *attr, ...@@ -135,10 +140,13 @@ static ssize_t show_input(struct device *dev, struct device_attribute *attr,
char *buf) char *buf)
{ {
struct lm95241_data *data = lm95241_update_device(dev); struct lm95241_data *data = lm95241_update_device(dev);
int index = to_sensor_dev_attr(attr)->index;
return snprintf(buf, PAGE_SIZE - 1, "%d\n", return snprintf(buf, PAGE_SIZE - 1, "%d\n",
TempFromReg(data->temp[to_sensor_dev_attr(attr)->index], index == 0 || (data->config & (1 << (index / 2))) ?
data->temp[to_sensor_dev_attr(attr)->index + 1])); temp_from_reg_signed(data->temp[index], data->temp[index + 1]) :
temp_from_reg_unsigned(data->temp[index],
data->temp[index + 1]));
} }
static ssize_t show_type(struct device *dev, struct device_attribute *attr, static ssize_t show_type(struct device *dev, struct device_attribute *attr,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment