On Fri, May 08 2020, Jeremie Courreges-Anglas <j...@wxcvbn.org> wrote: > Overall remaining battery power is currently the average of the > remaining power (in percents) of each battery. This is misleading if > your laptop uses a large external battery which drains out first, and > a smaller internal battery (common scheme on eg thinkpad machines). > Overall battery power decreases much faster when you switch to the > smaller battery. This odd behavior was reported by a friend a few weeks > ago. > > The diff below attempts to fix this: compute the sum of the remaining > power and capacity, *then* compute the overall remaining percentage. > No regression on my thinkpad x270 with two batteries of similar > capacity. I don't know whether the original reporter will be able to > test this soon. > > The code touches the acpisbs(4) bits, hopefully without changing the > current behavior. acpisbs(4) currently doesn't support multiple > batteries. > > Test reports, feedback, oks welcome.
I got successful test reports from benno@ and fellow lidstah (original reporter). With a 6600mAh external battery and a 2200mAh internal battery, lidstah sees an overall battery percentage at ~22% instead of ~50% when the external battery drains out. Still looking for oks :) Index: acpi.c =================================================================== RCS file: /d/cvs/src/sys/dev/acpi/acpi.c,v retrieving revision 1.383 diff -u -p -p -u -r1.383 acpi.c --- acpi.c 8 May 2020 11:18:01 -0000 1.383 +++ acpi.c 8 May 2020 15:04:50 -0000 @@ -3503,7 +3503,7 @@ acpiioctl(dev_t dev, u_long cmd, caddr_t struct acpi_sbs *sbs; struct apm_power_info *pi = (struct apm_power_info *)data; int bats; - unsigned int remaining, rem, minutes, rate; + unsigned int capacity, remaining, minutes, rate; int s; if (!acpi_cd.cd_ndevs || APMUNIT(dev) != 0 || @@ -3554,7 +3554,8 @@ acpiioctl(dev_t dev, u_long cmd, caddr_t pi->battery_life = 0; pi->minutes_left = 0; bats = 0; - remaining = rem = 0; + capacity = 0; + remaining = 0; minutes = 0; rate = 0; SLIST_FOREACH(bat, &sc->sc_bat, aba_link) { @@ -3565,11 +3566,9 @@ acpiioctl(dev_t dev, u_long cmd, caddr_t continue; bats++; - rem = (bat->aba_softc->sc_bst.bst_capacity * 100) / - bat->aba_softc->sc_bix.bix_last_capacity; - if (rem > 100) - rem = 100; - remaining += rem; + capacity += bat->aba_softc->sc_bix.bix_last_capacity; + remaining += min(bat->aba_softc->sc_bst.bst_capacity, + bat->aba_softc->sc_bix.bix_last_capacity); if (bat->aba_softc->sc_bst.bst_rate == BST_UNKNOWN) continue; @@ -3587,10 +3586,9 @@ acpiioctl(dev_t dev, u_long cmd, caddr_t continue; bats++; - rem = sbs->asbs_softc->sc_battery.rel_charge; - if (rem > 100) - rem = 100; - remaining += rem; + capacity += 100; + remaining += min(100, + sbs->asbs_softc->sc_battery.rel_charge); if (sbs->asbs_softc->sc_battery.run_time == ACPISBS_VALUE_UNKNOWN) @@ -3613,7 +3611,7 @@ acpiioctl(dev_t dev, u_long cmd, caddr_t pi->minutes_left = 60 * minutes / rate; /* running on battery */ - pi->battery_life = remaining / bats; + pi->battery_life = remaining * 100 / capacity; if (pi->battery_life > 50) pi->battery_state = APM_BATT_HIGH; else if (pi->battery_life > 25) -- jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF DDCC 0DFA 74AE 1524 E7EE