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: Guenter Roeck <guenter.roeck@ericsson.com> Acked-by: Jean Delvare <khali@linux-fr.org> Cc: stable@kernel.org # 2.6.30+
This commit is contained in:
@@ -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,
|
|||||||
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,
|
||||||
|
Reference in New Issue
Block a user