hwmon: (corsair-psu) Update calculation of LINEAR11 values
authorWilken Gottwalt <wilken.gottwalt@posteo.net>
Sat, 27 Feb 2021 09:34:42 +0000 (10:34 +0100)
committerGuenter Roeck <linux@roeck-us.net>
Tue, 20 Apr 2021 13:50:14 +0000 (06:50 -0700)
Changes the way how LINEAR11 values are calculated. The new method
increases the precision of 2-3 digits.

old method:
corsairpsu-hid-3-1
Adapter: HID adapter
v_in:        230.00 V
v_out +12v:   12.00 V
v_out +5v:     5.00 V
v_out +3.3v:   3.00 V
psu fan:        0 RPM
vrm temp:     +44.0°C
case temp:    +37.0°C
power total: 152.00 W
power +12v:  112.00 W
power +5v:    38.00 W
power +3.3v:   5.00 W
curr in:          N/A
curr +12v:     9.00 A
curr +5v:      7.00 A
curr +3.3v:  1000.00 mA

new method:
corsairpsu-hid-3-1
Adapter: HID adapter
v_in:        230.00 V
v_out +12v:   12.16 V
v_out +5v:     5.01 V
v_out +3.3v:   3.30 V
psu fan:        0 RPM
vrm temp:     +44.5°C
case temp:    +37.8°C
power total: 148.00 W
power +12v:  108.00 W
power +5v:    37.00 W
power +3.3v:   4.50 W
curr in:          N/A
curr +12v:     9.25 A
curr +5v:      7.50 A
curr +3.3v:    1.50 A

Co-developed-by: Jack Doan <me@jackdoan.com>
Signed-off-by: Jack Doan <me@jackdoan.com>
Signed-off-by: Wilken Gottwalt <wilken.gottwalt@posteo.net>
Link: https://lore.kernel.org/r/YDoSMqFbgoTXyoru@monster.powergraphx.local
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
drivers/hwmon/corsair-psu.c

index 9949405..b0953ee 100644 (file)
@@ -119,27 +119,13 @@ struct corsairpsu_data {
 };
 
 /* some values are SMBus LINEAR11 data which need a conversion */
-static int corsairpsu_linear11_to_int(const int val)
+static int corsairpsu_linear11_to_int(const u16 val, const int scale)
 {
-       int exp = (val & 0xFFFF) >> 0x0B;
-       int mant = val & 0x7FF;
-       int i;
-
-       if (exp > 0x0F)
-               exp -= 0x20;
-       if (mant > 0x3FF)
-               mant -= 0x800;
-       if ((mant & 0x01) == 1)
-               ++mant;
-       if (exp < 0) {
-               for (i = 0; i < -exp; ++i)
-                       mant /= 2;
-       } else {
-               for (i = 0; i < exp; ++i)
-                       mant *= 2;
-       }
+       const int exp = ((s16)val) >> 11;
+       const int mant = (((s16)(val & 0x7ff)) << 5) >> 5;
+       const int result = mant * scale;
 
-       return mant;
+       return (exp >= 0) ? (result << exp) : (result >> -exp);
 }
 
 static int corsairpsu_usb_cmd(struct corsairpsu_data *priv, u8 p0, u8 p1, u8 p2, void *data)
@@ -249,14 +235,14 @@ static int corsairpsu_get_value(struct corsairpsu_data *priv, u8 cmd, u8 rail, l
        case PSU_CMD_RAIL_AMPS:
        case PSU_CMD_TEMP0:
        case PSU_CMD_TEMP1:
-               *val = corsairpsu_linear11_to_int(tmp & 0xFFFF) * 1000;
+               *val = corsairpsu_linear11_to_int(tmp & 0xFFFF, 1000);
                break;
        case PSU_CMD_FAN:
-               *val = corsairpsu_linear11_to_int(tmp & 0xFFFF);
+               *val = corsairpsu_linear11_to_int(tmp & 0xFFFF, 1);
                break;
        case PSU_CMD_RAIL_WATTS:
        case PSU_CMD_TOTAL_WATTS:
-               *val = corsairpsu_linear11_to_int(tmp & 0xFFFF) * 1000000;
+               *val = corsairpsu_linear11_to_int(tmp & 0xFFFF, 1000000);
                break;
        case PSU_CMD_TOTAL_UPTIME:
        case PSU_CMD_UPTIME: