]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
hwmon: (ina238) Modify the calculation formula to adapt to different chips
authorWenliang Yan <wenliang202407@163.com>
Tue, 6 May 2025 05:37:40 +0000 (01:37 -0400)
committerGuenter Roeck <linux@roeck-us.net>
Mon, 12 May 2025 16:41:04 +0000 (09:41 -0700)
Modify the calculation formula to adapt to different chips.

Signed-off-by: Wenliang Yan <wenliang202407@163.com>
Link: https://lore.kernel.org/r/20250506053741.4837-4-wenliang202407@163.com
[groeck: Fixed checkpatch issue (space before and after arithmetic operators)]
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
drivers/hwmon/ina238.c

index 48b61328eb35f098a54363c9bb6d4faf2c858fe0..a4a41742786bd19e1c5dab34c7d71973527161a1 100644 (file)
@@ -270,10 +270,10 @@ static int ina238_read_in(struct device *dev, u32 attr, int channel,
                regval = (s16)regval;
                if (channel == 0)
                        /* gain of 1 -> LSB / 4 */
-                       *val = (regval * INA238_SHUNT_VOLTAGE_LSB) /
-                              (1000 * (4 - data->gain + 1));
+                       *val = (regval * INA238_SHUNT_VOLTAGE_LSB) *
+                                       data->gain / (1000 * 4);
                else
-                       *val = (regval * INA238_BUS_VOLTAGE_LSB) / 1000;
+                       *val = (regval * data->config->bus_voltage_lsb) / 1000;
                break;
        case hwmon_in_max_alarm:
        case hwmon_in_min_alarm:
@@ -298,8 +298,8 @@ static int ina238_write_in(struct device *dev, u32 attr, int channel,
        case 0:
                /* signed value, clamp to max range +/-163 mV */
                regval = clamp_val(val, -163, 163);
-               regval = (regval * 1000 * (4 - data->gain + 1)) /
-                        INA238_SHUNT_VOLTAGE_LSB;
+               regval = (regval * 1000 * 4) /
+                        (INA238_SHUNT_VOLTAGE_LSB * data->gain);
                regval = clamp_val(regval, S16_MIN, S16_MAX);
 
                switch (attr) {
@@ -315,7 +315,7 @@ static int ina238_write_in(struct device *dev, u32 attr, int channel,
        case 1:
                /* signed value, positive values only. Clamp to max 102.396 V */
                regval = clamp_val(val, 0, 102396);
-               regval = (regval * 1000) / INA238_BUS_VOLTAGE_LSB;
+               regval = (regval * 1000) / data->config->bus_voltage_lsb;
                regval = clamp_val(regval, 0, S16_MAX);
 
                switch (attr) {
@@ -370,8 +370,8 @@ static int ina238_read_power(struct device *dev, u32 attr, long *val)
                        return err;
 
                /* Fixed 1mA lsb, scaled by 1000000 to have result in uW */
-               power = div_u64(regval * 1000ULL * INA238_FIXED_SHUNT *
-                               data->gain, 20 * data->rshunt);
+               power = div_u64(regval * 1000ULL * INA238_FIXED_SHUNT * data->gain *
+                               data->config->power_calculate_factor, 4 * 100 * data->rshunt);
                /* Clamp value to maximum value of long */
                *val = clamp_val(power, 0, LONG_MAX);
                break;
@@ -381,8 +381,8 @@ static int ina238_read_power(struct device *dev, u32 attr, long *val)
                        return err;
 
                /* Fixed 1mA lsb, scaled by 1000000 to have result in uW */
-               power = div_u64(regval * 1000ULL * INA238_FIXED_SHUNT *
-                               data->gain, 20 * data->rshunt);
+               power = div_u64(regval * 1000ULL * INA238_FIXED_SHUNT * data->gain *
+                               data->config->power_calculate_factor, 4 * 100 * data->rshunt);
                /* Clamp value to maximum value of long */
                *val = clamp_val(power, 0, LONG_MAX);
                break;
@@ -395,8 +395,8 @@ static int ina238_read_power(struct device *dev, u32 attr, long *val)
                 * Truncated 24-bit compare register, lower 8-bits are
                 * truncated. Same conversion to/from uW as POWER register.
                 */
-               power = div_u64((regval << 8) * 1000ULL * INA238_FIXED_SHUNT *
-                              data->gain, 20 * data->rshunt);
+               power = div_u64((regval << 8) * 1000ULL * INA238_FIXED_SHUNT *  data->gain *
+                               data->config->power_calculate_factor, 4 * 100 * data->rshunt);
                /* Clamp value to maximum value of long */
                *val = clamp_val(power, 0, LONG_MAX);
                break;
@@ -428,8 +428,8 @@ static int ina238_write_power(struct device *dev, u32 attr, long val)
         * register.
         */
        regval = clamp_val(val, 0, LONG_MAX);
-       regval = div_u64(val * 20ULL * data->rshunt,
-                        1000ULL * INA238_FIXED_SHUNT * data->gain);
+       regval = div_u64(val * 4 * 100 * data->rshunt, data->config->power_calculate_factor *
+                       1000ULL * INA238_FIXED_SHUNT * data->gain);
        regval = clamp_val(regval >> 8, 0, U16_MAX);
 
        return regmap_write(data->regmap, INA238_POWER_LIMIT, regval);
@@ -446,17 +446,17 @@ static int ina238_read_temp(struct device *dev, u32 attr, long *val)
                err = regmap_read(data->regmap, INA238_DIE_TEMP, &regval);
                if (err)
                        return err;
-
-               /* Signed, bits 15-4 of register, result in mC */
-               *val = ((s16)regval >> 4) * INA238_DIE_TEMP_LSB;
+               /* Signed, result in mC */
+               *val = div_s64(((s64)((s16)regval) >> data->config->temp_shift) *
+                                               (s64)data->config->temp_lsb, 10000);
                break;
        case hwmon_temp_max:
                err = regmap_read(data->regmap, INA238_TEMP_LIMIT, &regval);
                if (err)
                        return err;
-
-               /* Signed, bits 15-4 of register, result in mC */
-               *val = ((s16)regval >> 4) * INA238_DIE_TEMP_LSB;
+               /* Signed, result in mC */
+               *val = div_s64(((s64)((s16)regval) >> data->config->temp_shift) *
+                                               (s64)data->config->temp_lsb, 10000);
                break;
        case hwmon_temp_max_alarm:
                err = regmap_read(data->regmap, INA238_DIAG_ALERT, &regval);
@@ -480,9 +480,10 @@ static int ina238_write_temp(struct device *dev, u32 attr, long val)
        if (attr != hwmon_temp_max)
                return -EOPNOTSUPP;
 
-       /* Signed, bits 15-4 of register */
-       regval = (val / INA238_DIE_TEMP_LSB) << 4;
-       regval = clamp_val(regval, S16_MIN, S16_MAX) & 0xfff0;
+       /* Signed */
+       regval = clamp_val(val, -40000, 125000);
+       regval = div_s64(val * 10000, data->config->temp_lsb) << data->config->temp_shift;
+       regval = clamp_val(regval, S16_MIN, S16_MAX) & (0xffff << data->config->temp_shift);
 
        return regmap_write(data->regmap, INA238_TEMP_LIMIT, regval);
 }