Skip to content

Commit

Permalink
hwmon: (pmbus) Fix LINEAR16 data format
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Guenter Roeck committed Mar 15, 2011
1 parent 8677011 commit 9f6ad1c
Showing 1 changed file with 17 additions and 14 deletions.
31 changes: 17 additions & 14 deletions drivers/hwmon/pmbus_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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.
Expand All @@ -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. */
Expand Down

0 comments on commit 9f6ad1c

Please sign in to comment.