> 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
> 
> 

Reply via email to