> From: Jeremie Courreges-Anglas <[email protected]>
> Date: Mon, 11 May 2020 11:40:23 +0200
> Content-Type: text/plain
>
> On Fri, May 08 2020, Jeremie Courreges-Anglas <[email protected]> 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 :)
This wouldn't do the right thing if you have both acpibat(4) and
acpisbs(4), but I think that is already broken.
ok kettenis@
> 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
>
>