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