Correct the way remaining battery life is calculated
Previously, if a system had multiple batteries, the remaining life percentage was calculated as the average of each battery's percent remaining. This results in rather incorrect values when you consider the case of the Thinkpad X270 that has a small 3 cell internally battery, and a hot-swappable 9 cell battery that is used first. Battery 0 is at 100%, but battery 1 is at 10%, you do not infact have 55% of your capacity remaining. The new method calculates the percentage based on remaining capacity out of total capacity, giving a much more accurate reading. PR: 229818 Submitted by: Keegan Drake H.P. <kd-dev@pm.me> MFC after: 2 weeks Sponsored by: Klara Systems Event: Waterloo Hackathon 2019
This commit is contained in:
parent
3038f1af7b
commit
e7fc15972b
@ -119,7 +119,7 @@ int
|
||||
acpi_battery_get_battinfo(device_t dev, struct acpi_battinfo *battinfo)
|
||||
{
|
||||
int batt_stat, devcount, dev_idx, error, i;
|
||||
int total_cap, total_min, valid_rate, valid_units;
|
||||
int total_cap, total_lfcap, total_min, valid_rate, valid_units;
|
||||
devclass_t batt_dc;
|
||||
device_t batt_dev;
|
||||
struct acpi_bst *bst;
|
||||
@ -152,6 +152,7 @@ acpi_battery_get_battinfo(device_t dev, struct acpi_battinfo *battinfo)
|
||||
*/
|
||||
dev_idx = -1;
|
||||
batt_stat = valid_rate = valid_units = 0;
|
||||
total_cap = total_lfcap = 0;
|
||||
for (i = 0; i < devcount; i++) {
|
||||
/* Default info for every battery is "not present". */
|
||||
acpi_reset_battinfo(&bi[i]);
|
||||
@ -210,16 +211,22 @@ acpi_battery_get_battinfo(device_t dev, struct acpi_battinfo *battinfo)
|
||||
if (!acpi_battery_bif_valid(bif))
|
||||
continue;
|
||||
|
||||
/* Calculate percent capacity remaining. */
|
||||
bi[i].cap = (100 * bst[i].cap) / bif->lfcap;
|
||||
|
||||
/*
|
||||
* Some laptops report the "design-capacity" instead of the
|
||||
* "real-capacity" when the battery is fully charged. That breaks
|
||||
* the above arithmetic as it needs to be 100% maximum.
|
||||
*/
|
||||
if (bi[i].cap > 100)
|
||||
bi[i].cap = 100;
|
||||
if (bst[i].cap > bif->lfcap)
|
||||
bst[i].cap = bif->lfcap;
|
||||
|
||||
/* Calculate percent capacity remaining. */
|
||||
bi[i].cap = (100 * bst[i].cap) / bif->lfcap;
|
||||
|
||||
/* If this battery is not present, don't use its capacity. */
|
||||
if (bi[i].cap != -1) {
|
||||
total_cap += bst[i].cap;
|
||||
total_lfcap += bif->lfcap;
|
||||
}
|
||||
|
||||
/*
|
||||
* On systems with more than one battery, they may get used
|
||||
@ -241,7 +248,7 @@ acpi_battery_get_battinfo(device_t dev, struct acpi_battinfo *battinfo)
|
||||
}
|
||||
|
||||
/* Pass 2: calculate capacity and remaining time for all batteries. */
|
||||
total_cap = total_min = 0;
|
||||
total_min = 0;
|
||||
for (i = 0; i < devcount; i++) {
|
||||
/*
|
||||
* If any batteries are discharging, use the sum of the bst.rate
|
||||
@ -253,10 +260,6 @@ acpi_battery_get_battinfo(device_t dev, struct acpi_battinfo *battinfo)
|
||||
else
|
||||
bi[i].min = 0;
|
||||
total_min += bi[i].min;
|
||||
|
||||
/* If this battery is not present, don't use its capacity. */
|
||||
if (bi[i].cap != -1)
|
||||
total_cap += bi[i].cap;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -265,7 +268,7 @@ acpi_battery_get_battinfo(device_t dev, struct acpi_battinfo *battinfo)
|
||||
*/
|
||||
if (valid_units > 0) {
|
||||
if (dev == NULL) {
|
||||
battinfo->cap = total_cap / valid_units;
|
||||
battinfo->cap = (total_cap * 100) / total_lfcap;
|
||||
battinfo->min = total_min;
|
||||
battinfo->state = batt_stat;
|
||||
battinfo->rate = valid_rate;
|
||||
|
Loading…
x
Reference in New Issue
Block a user