Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

power: supply: ab8500_fg: Use VBAT-to-Ri if possible

Augment the AB8500 fuel gauge to use the VBAT-to-Ri method of
estimating the internal resistance if possible. Else fall back
to using the temperature-to-Ri or just the default Ri.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>

authored by

Linus Walleij and committed by
Sebastian Reichel
bc5d4a24 e9e7d165

+21 -10
+21 -10
drivers/power/supply/ab8500_fg.c
··· 877 877 /** 878 878 * ab8500_fg_battery_resistance() - Returns the battery inner resistance 879 879 * @di: pointer to the ab8500_fg structure 880 + * @vbat_uncomp_uv: Uncompensated VBAT voltage 880 881 * 881 882 * Returns battery inner resistance added with the fuel gauge resistor value 882 883 * to get the total resistance in the whole link from gnd to bat+ node 883 884 * in milliohm. 884 885 */ 885 - static int ab8500_fg_battery_resistance(struct ab8500_fg *di) 886 + static int ab8500_fg_battery_resistance(struct ab8500_fg *di, int vbat_uncomp_uv) 886 887 { 887 888 struct power_supply_battery_info *bi = di->bm->bi; 888 889 int resistance_percent = 0; 889 890 int resistance; 890 891 891 - resistance_percent = power_supply_temp2resist_simple(bi->resist_table, 892 - bi->resist_table_size, 893 - di->bat_temp / 10); 894 892 /* 895 - * We get a percentage of factory resistance here so first get 896 - * the factory resistance in milliohms then calculate how much 897 - * resistance we have at this temperature. 893 + * Determine the resistance at this voltage. First try VBAT-to-Ri else 894 + * just infer it from the surrounding temperature, if nothing works just 895 + * use the internal resistance. 898 896 */ 899 - resistance = (bi->factory_internal_resistance_uohm / 1000); 900 - resistance = resistance * resistance_percent / 100; 897 + if (power_supply_supports_vbat2ri(bi)) { 898 + resistance = power_supply_vbat2ri(bi, vbat_uncomp_uv, di->flags.charging); 899 + /* Convert to milliohm */ 900 + resistance = resistance / 1000; 901 + } else if (power_supply_supports_temp2ri(bi)) { 902 + resistance_percent = power_supply_temp2resist_simple(bi->resist_table, 903 + bi->resist_table_size, 904 + di->bat_temp / 10); 905 + /* Convert to milliohm */ 906 + resistance = bi->factory_internal_resistance_uohm / 1000; 907 + resistance = resistance * resistance_percent / 100; 908 + } else { 909 + /* Last fallback */ 910 + resistance = bi->factory_internal_resistance_uohm / 1000; 911 + } 901 912 902 913 dev_dbg(di->dev, "%s Temp: %d battery internal resistance: %d" 903 914 " fg resistance %d, total: %d (mOhm)\n", ··· 966 955 vbat_uv = vbat_uv / i; 967 956 968 957 /* Next we apply voltage compensation from internal resistance */ 969 - rcomp = ab8500_fg_battery_resistance(di); 958 + rcomp = ab8500_fg_battery_resistance(di, vbat_uv); 970 959 vbat_uv = vbat_uv - (di->inst_curr_ua * rcomp) / 1000; 971 960 972 961 /* Always keep this state at latest measurement */