Commit 9f6ad1ce6484a92ef864e00611a8ef3daf9c986d

Authored by Guenter Roeck
1 parent 8677011a5d

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>

Showing 1 changed file with 17 additions and 14 deletions Side-by-side Diff

drivers/hwmon/pmbus_core.c
... ... @@ -359,20 +359,21 @@
359 359 static int pmbus_reg2data_linear(struct pmbus_data *data,
360 360 struct pmbus_sensor *sensor)
361 361 {
362   - s16 exponent, mantissa;
  362 + s16 exponent;
  363 + s32 mantissa;
363 364 long val;
364 365  
365   - if (sensor->class == PSC_VOLTAGE_OUT) {
  366 + if (sensor->class == PSC_VOLTAGE_OUT) { /* LINEAR16 */
366 367 exponent = data->exponent;
367   - mantissa = (s16) sensor->data;
368   - } else {
  368 + mantissa = (u16) sensor->data;
  369 + } else { /* LINEAR11 */
369 370 exponent = (sensor->data >> 11) & 0x001f;
370 371 mantissa = sensor->data & 0x07ff;
371 372  
372 373 if (exponent > 0x0f)
373 374 exponent |= 0xffe0; /* sign extend exponent */
374 375 if (mantissa > 0x03ff)
375   - mantissa |= 0xf800; /* sign extend mantissa */
  376 + mantissa |= 0xfffff800; /* sign extend mantissa */
376 377 }
377 378  
378 379 val = mantissa;
379 380  
380 381  
... ... @@ -454,19 +455,18 @@
454 455 static u16 pmbus_data2reg_linear(struct pmbus_data *data,
455 456 enum pmbus_sensor_classes class, long val)
456 457 {
457   - s16 exponent = 0, mantissa = 0;
  458 + s16 exponent = 0, mantissa;
458 459 bool negative = false;
459 460  
460 461 /* simple case */
461 462 if (val == 0)
462 463 return 0;
463 464  
464   - if (val < 0) {
465   - negative = true;
466   - val = -val;
467   - }
468   -
469 465 if (class == PSC_VOLTAGE_OUT) {
  466 + /* LINEAR16 does not support negative voltages */
  467 + if (val < 0)
  468 + return 0;
  469 +
470 470 /*
471 471 * For a static exponents, we don't have a choice
472 472 * but to adjust the value to it.
... ... @@ -476,9 +476,12 @@
476 476 else
477 477 val >>= data->exponent;
478 478 val = DIV_ROUND_CLOSEST(val, 1000);
479   - if (val > 0x7fff)
480   - val = 0x7fff;
481   - return negative ? -val : val;
  479 + return val & 0xffff;
  480 + }
  481 +
  482 + if (val < 0) {
  483 + negative = true;
  484 + val = -val;
482 485 }
483 486  
484 487 /* Power is in uW. Convert to mW before converting. */