summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorGuenter Roeck <guenter.roeck@ericsson.com>2011-03-08 02:34:50 (GMT)
committerGuenter Roeck <guenter.roeck@ericsson.com>2011-03-15 05:39:11 (GMT)
commit9f6ad1ce6484a92ef864e00611a8ef3daf9c986d (patch)
tree8aabd7f60d7a6ccfc62beb37356180c37f7b64e0 /drivers
parent8677011a5d8e0358ce5ae26d82dfcddcad073c47 (diff)
downloadlinux-9f6ad1ce6484a92ef864e00611a8ef3daf9c986d.tar.xz
hwmon: (pmbus) Fix LINEAR16 data format
LINEAR16 data format is unsigned, not signed. Impact is that affected attributes report negative values in the upper half of the supported value range. Signed-off-by: Guenter Roeck <guenter.roeck@ericsson.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/hwmon/pmbus_core.c31
1 files changed, 17 insertions, 14 deletions
diff --git a/drivers/hwmon/pmbus_core.c b/drivers/hwmon/pmbus_core.c
index 92540c9..6474512 100644
--- a/drivers/hwmon/pmbus_core.c
+++ b/drivers/hwmon/pmbus_core.c
@@ -359,20 +359,21 @@ static struct pmbus_data *pmbus_update_device(struct device *dev)
static int pmbus_reg2data_linear(struct pmbus_data *data,
struct pmbus_sensor *sensor)
{
- s16 exponent, mantissa;
+ s16 exponent;
+ s32 mantissa;
long val;
- if (sensor->class == PSC_VOLTAGE_OUT) {
+ if (sensor->class == PSC_VOLTAGE_OUT) { /* LINEAR16 */
exponent = data->exponent;
- mantissa = (s16) sensor->data;
- } else {
+ mantissa = (u16) sensor->data;
+ } else { /* LINEAR11 */
exponent = (sensor->data >> 11) & 0x001f;
mantissa = sensor->data & 0x07ff;
if (exponent > 0x0f)
exponent |= 0xffe0; /* sign extend exponent */
if (mantissa > 0x03ff)
- mantissa |= 0xf800; /* sign extend mantissa */
+ mantissa |= 0xfffff800; /* sign extend mantissa */
}
val = mantissa;
@@ -454,19 +455,18 @@ static int pmbus_reg2data(struct pmbus_data *data, struct pmbus_sensor *sensor)
static u16 pmbus_data2reg_linear(struct pmbus_data *data,
enum pmbus_sensor_classes class, long val)
{
- s16 exponent = 0, mantissa = 0;
+ s16 exponent = 0, mantissa;
bool negative = false;
/* simple case */
if (val == 0)
return 0;
- if (val < 0) {
- negative = true;
- val = -val;
- }
-
if (class == PSC_VOLTAGE_OUT) {
+ /* LINEAR16 does not support negative voltages */
+ if (val < 0)
+ return 0;
+
/*
* For a static exponents, we don't have a choice
* but to adjust the value to it.
@@ -476,9 +476,12 @@ static u16 pmbus_data2reg_linear(struct pmbus_data *data,
else
val >>= data->exponent;
val = DIV_ROUND_CLOSEST(val, 1000);
- if (val > 0x7fff)
- val = 0x7fff;
- return negative ? -val : val;
+ return val & 0xffff;
+ }
+
+ if (val < 0) {
+ negative = true;
+ val = -val;
}
/* Power is in uW. Convert to mW before converting. */