aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorGuenter Roeck <guenter.roeck@ericsson.com>2011-03-07 21:34:50 -0500
committerGuenter Roeck <guenter.roeck@ericsson.com>2011-03-15 01:39:11 -0400
commit9f6ad1ce6484a92ef864e00611a8ef3daf9c986d (patch)
tree8aabd7f60d7a6ccfc62beb37356180c37f7b64e0 /drivers
parent8677011a5d8e0358ce5ae26d82dfcddcad073c47 (diff)
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 92540c9cd34e..6474512f49b0 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)
359static int pmbus_reg2data_linear(struct pmbus_data *data, 359static int pmbus_reg2data_linear(struct pmbus_data *data,
360 struct pmbus_sensor *sensor) 360 struct pmbus_sensor *sensor)
361{ 361{
362 s16 exponent, mantissa; 362 s16 exponent;
363 s32 mantissa;
363 long val; 364 long val;
364 365
365 if (sensor->class == PSC_VOLTAGE_OUT) { 366 if (sensor->class == PSC_VOLTAGE_OUT) { /* LINEAR16 */
366 exponent = data->exponent; 367 exponent = data->exponent;
367 mantissa = (s16) sensor->data; 368 mantissa = (u16) sensor->data;
368 } else { 369 } else { /* LINEAR11 */
369 exponent = (sensor->data >> 11) & 0x001f; 370 exponent = (sensor->data >> 11) & 0x001f;
370 mantissa = sensor->data & 0x07ff; 371 mantissa = sensor->data & 0x07ff;
371 372
372 if (exponent > 0x0f) 373 if (exponent > 0x0f)
373 exponent |= 0xffe0; /* sign extend exponent */ 374 exponent |= 0xffe0; /* sign extend exponent */
374 if (mantissa > 0x03ff) 375 if (mantissa > 0x03ff)
375 mantissa |= 0xf800; /* sign extend mantissa */ 376 mantissa |= 0xfffff800; /* sign extend mantissa */
376 } 377 }
377 378
378 val = mantissa; 379 val = mantissa;
@@ -454,19 +455,18 @@ static int pmbus_reg2data(struct pmbus_data *data, struct pmbus_sensor *sensor)
454static u16 pmbus_data2reg_linear(struct pmbus_data *data, 455static u16 pmbus_data2reg_linear(struct pmbus_data *data,
455 enum pmbus_sensor_classes class, long val) 456 enum pmbus_sensor_classes class, long val)
456{ 457{
457 s16 exponent = 0, mantissa = 0; 458 s16 exponent = 0, mantissa;
458 bool negative = false; 459 bool negative = false;
459 460
460 /* simple case */ 461 /* simple case */
461 if (val == 0) 462 if (val == 0)
462 return 0; 463 return 0;
463 464
464 if (val < 0) {
465 negative = true;
466 val = -val;
467 }
468
469 if (class == PSC_VOLTAGE_OUT) { 465 if (class == PSC_VOLTAGE_OUT) {
466 /* LINEAR16 does not support negative voltages */
467 if (val < 0)
468 return 0;
469
470 /* 470 /*
471 * For a static exponents, we don't have a choice 471 * For a static exponents, we don't have a choice
472 * but to adjust the value to it. 472 * but to adjust the value to it.
@@ -476,9 +476,12 @@ static u16 pmbus_data2reg_linear(struct pmbus_data *data,
476 else 476 else
477 val >>= data->exponent; 477 val >>= data->exponent;
478 val = DIV_ROUND_CLOSEST(val, 1000); 478 val = DIV_ROUND_CLOSEST(val, 1000);
479 if (val > 0x7fff) 479 return val & 0xffff;
480 val = 0x7fff; 480 }
481 return negative ? -val : val; 481
482 if (val < 0) {
483 negative = true;
484 val = -val;
482 } 485 }
483 486
484 /* Power is in uW. Convert to mW before converting. */ 487 /* Power is in uW. Convert to mW before converting. */