power: supply: ab8500: Standardize temp res lookup
authorLinus Walleij <linus.walleij@linaro.org>
Sat, 20 Nov 2021 15:53:25 +0000 (16:53 +0100)
committerSebastian Reichel <sebastian.reichel@collabora.com>
Mon, 22 Nov 2021 16:16:26 +0000 (17:16 +0100)
The lookup from battery temperature to internal resistance was
using its own format. Rewrite this to use the table inside
struct power_supply_battery_info:s resist_table.

The supplied resistance table has to be rewritten to express
the resistance in percent of the factory resistance as a
side effect.

We can then rely on the library function
power_supply_temp2resist_simple() to interpolate the internal
resistance percent from the temperature.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
drivers/power/supply/ab8500-bm.h
drivers/power/supply/ab8500_bmdata.c
drivers/power/supply/ab8500_fg.c

index febf2dea853b2479a72f42968b0493d07d0b64ad..af52539a7a7b91b729362da011b4dad6406eb634 100644 (file)
@@ -379,8 +379,6 @@ struct ab8500_maxim_parameters {
  * @r_to_t_tbl:                        table containing resistance to temp points
  * @n_v_cap_tbl_elements:      number of elements in v_to_cap_tbl
  * @v_to_cap_tbl:              Voltage to capacity (in %) table
- * @n_batres_tbl_elements      number of elements in the batres_tbl
- * @batres_tbl                 battery internal resistance vs temperature table
  */
 struct ab8500_battery_type {
        int resis_high;
@@ -397,8 +395,6 @@ struct ab8500_battery_type {
        const struct ab8500_res_to_temp *r_to_t_tbl;
        int n_v_cap_tbl_elements;
        const struct ab8500_v_to_cap *v_to_cap_tbl;
-       int n_batres_tbl_elements;
-       const struct batres_vs_temp *batres_tbl;
 };
 
 /**
@@ -502,17 +498,6 @@ struct res_to_temp {
        int resist;
 };
 
-/**
- * struct batres_vs_temp - defines one point in a temp vs battery internal
- * resistance curve.
- * @temp:                      battery pack temperature in Celsius
- * @resist:                    battery internal reistance in mOhm
- */
-struct batres_vs_temp {
-       int temp;
-       int resist;
-};
-
 /* Forward declaration */
 struct ab8500_fg;
 
index ce0a5fcb317737f368ce201f24588e089ee7ae07..1175532fe017df639751d65f70ab9e754611f4f7 100644 (file)
@@ -67,16 +67,17 @@ static const struct ab8500_res_to_temp temp_tbl[] = {
 
 /*
  * Note that the batres_vs_temp table must be strictly sorted by falling
- * temperature values to work.
+ * temperature values to work. Factory resistance is 300 mOhm and the
+ * resistance values to the right are percentages of 300 mOhm.
  */
-static const struct batres_vs_temp temp_to_batres_tbl_thermistor[] = {
-       { 40, 120},
-       { 30, 135},
-       { 20, 165},
-       { 10, 230},
-       { 00, 325},
-       {-10, 445},
-       {-20, 595},
+static struct power_supply_resistance_temp_table temp_to_batres_tbl_thermistor[] = {
+       { .temp = 40, .resistance = 40 /* 120 mOhm */ },
+       { .temp = 30, .resistance = 45 /* 135 mOhm */ },
+       { .temp = 20, .resistance = 55 /* 165 mOhm */ },
+       { .temp = 10, .resistance = 77 /* 230 mOhm */ },
+       { .temp = 00, .resistance = 108 /* 325 mOhm */ },
+       { .temp = -10, .resistance = 158 /* 445 mOhm */ },
+       { .temp = -20, .resistance = 198 /* 595 mOhm */ },
 };
 
 /* Default battery type for reference designs is the unknown type */
@@ -95,8 +96,6 @@ static struct ab8500_battery_type bat_type_thermistor_unknown = {
        .r_to_t_tbl = temp_tbl,
        .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl),
        .v_to_cap_tbl = cap_tbl,
-       .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
-       .batres_tbl = temp_to_batres_tbl_thermistor,
 };
 
 static const struct ab8500_bm_capacity_levels cap_levels = {
@@ -209,8 +208,16 @@ int ab8500_bm_of_probe(struct power_supply *psy,
                /* Charging stops when we drop below this current */
                bi->charge_term_current_ua = 200000;
 
-       if (bi->factory_internal_resistance_uohm < 0)
+       /*
+        * Internal resistance and factory resistance are tightly coupled
+        * so both MUST be defined or we fall back to defaults.
+        */
+       if ((bi->factory_internal_resistance_uohm < 0) ||
+           !bi->resist_table) {
                bi->factory_internal_resistance_uohm = 300000;
+               bi->resist_table = temp_to_batres_tbl_thermistor;
+               bi->resist_table_size = ARRAY_SIZE(temp_to_batres_tbl_thermistor);
+       }
 
        if (bi->temp_min == INT_MIN)
                bi->temp_min = AB8500_TEMP_UNDER;
index daa008138b059f89e7511a4e3daa0215d27b732c..96bb81e539f0bddb41b160299bbf55635c400672 100644 (file)
@@ -901,44 +901,35 @@ static int ab8500_fg_uncomp_volt_to_capacity(struct ab8500_fg *di)
  * @di:                pointer to the ab8500_fg structure
  *
  * Returns battery inner resistance added with the fuel gauge resistor value
- * to get the total resistance in the whole link from gnd to bat+ node.
+ * to get the total resistance in the whole link from gnd to bat+ node
+ * in milliohm.
  */
 static int ab8500_fg_battery_resistance(struct ab8500_fg *di)
 {
-       int i, tbl_size;
-       const struct batres_vs_temp *tbl;
-       int resist = 0;
-
-       tbl = di->bm->bat_type->batres_tbl;
-       tbl_size = di->bm->bat_type->n_batres_tbl_elements;
-
-       for (i = 0; i < tbl_size; ++i) {
-               if (di->bat_temp / 10 > tbl[i].temp)
-                       break;
-       }
+       struct power_supply_battery_info *bi = &di->bm->bi;
+       int resistance_percent = 0;
+       int resistance;
 
-       if ((i > 0) && (i < tbl_size)) {
-               resist = fixp_linear_interpolate(
-                       tbl[i].temp,
-                       tbl[i].resist,
-                       tbl[i-1].temp,
-                       tbl[i-1].resist,
-                       di->bat_temp / 10);
-       } else if (i == 0) {
-               resist = tbl[0].resist;
-       } else {
-               resist = tbl[tbl_size - 1].resist;
-       }
+       resistance_percent = power_supply_temp2resist_simple(bi->resist_table,
+                                                bi->resist_table_size,
+                                                di->bat_temp / 10);
+       /*
+        * We get a percentage of factory resistance here so first get
+        * the factory resistance in milliohms then calculate how much
+        * resistance we have at this temperature.
+        */
+       resistance = (bi->factory_internal_resistance_uohm / 1000);
+       resistance = resistance * resistance_percent / 100;
 
        dev_dbg(di->dev, "%s Temp: %d battery internal resistance: %d"
            " fg resistance %d, total: %d (mOhm)\n",
-               __func__, di->bat_temp, resist, di->bm->fg_res / 10,
-               (di->bm->fg_res / 10) + resist);
+               __func__, di->bat_temp, resistance, di->bm->fg_res / 10,
+               (di->bm->fg_res / 10) + resistance);
 
        /* fg_res variable is in 0.1mOhm */
-       resist += di->bm->fg_res / 10;
+       resistance += di->bm->fg_res / 10;
 
-       return resist;
+       return resistance;
 }
 
 /**