Add support for multiple batteries to acpithinkpad setchargestart and
authorclaudio <claudio@openbsd.org>
Fri, 7 Jul 2023 07:37:59 +0000 (07:37 +0000)
committerclaudio <claudio@openbsd.org>
Fri, 7 Jul 2023 07:37:59 +0000 (07:37 +0000)
setchargestop. With this laptops like x270 or x240 properly set the
thresholds for both batteries.
Tested by kn@ and jmatthew@
OK kettenis@

sys/dev/acpi/acpi.c
sys/dev/acpi/acpithinkpad.c
sys/dev/acpi/acpivar.h

index 778a3fc..11bdd85 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpi.c,v 1.423 2023/07/06 06:58:07 deraadt Exp $ */
+/* $OpenBSD: acpi.c,v 1.424 2023/07/07 07:37:59 claudio Exp $ */
 /*
  * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
  * Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
@@ -3270,6 +3270,17 @@ acpi_foundsbs(struct aml_node *node, void *arg)
        return (0);
 }
 
+int
+acpi_batcount(struct acpi_softc *sc)
+{
+       struct acpi_bat *bat;
+       int count = 0;
+
+       SLIST_FOREACH(bat, &sc->sc_bat, aba_link)
+               count++;
+       return count;
+}
+
 int
 acpi_apminfo(struct apm_power_info *pi)
 {
index 13ea8d8..e9f56e0 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: acpithinkpad.c,v 1.73 2023/05/20 12:02:46 kettenis Exp $      */
+/*     $OpenBSD: acpithinkpad.c,v 1.74 2023/07/07 07:37:59 claudio Exp $       */
 /*
  * Copyright (c) 2008 joshua stein <jcs@openbsd.org>
  *
@@ -906,16 +906,18 @@ thinkpad_battery_inhibit_charge(int state)
 {
        struct acpithinkpad_softc *sc = acpithinkpad_cd.cd_devs[0];
        struct aml_value arg;
-       int battery = 1;
+       int battery, count;
        uint64_t ret;
 
-       memset(&arg, 0, sizeof(arg));
-       arg.type = AML_OBJTYPE_INTEGER;
-       arg.v_integer = (0xffff << 8) | (battery << 4) | state;
-       if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "BICS",
-           1, &arg, &ret) || (ret & THINKPAD_BATTERY_ERROR))
-               return EIO;
-
+       count = acpi_batcount(sc->sc_acpi);
+       for (battery = 1; battery <= count; battery++) {
+               memset(&arg, 0, sizeof(arg));
+               arg.type = AML_OBJTYPE_INTEGER;
+               arg.v_integer = (0xffff << 8) | (battery << 4) | state;
+               if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "BICS",
+                   1, &arg, &ret) || (ret & THINKPAD_BATTERY_ERROR))
+                       return EIO;
+       }
        return 0;
 }
 
@@ -924,16 +926,18 @@ thinkpad_battery_force_discharge(int state)
 {
        struct acpithinkpad_softc *sc = acpithinkpad_cd.cd_devs[0];
        struct aml_value arg;
-       int battery = 1;
+       int battery, count;
        uint64_t ret;
 
-       memset(&arg, 0, sizeof(arg));
-       arg.type = AML_OBJTYPE_INTEGER;
-       arg.v_integer = (battery << THINKPAD_BATTERY_SHIFT) | state;
-       if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "BDSS",
-           1, &arg, &ret) || (ret & THINKPAD_BATTERY_ERROR))
-               return EIO;
-
+       count = acpi_batcount(sc->sc_acpi);
+       for (battery = 1; battery <= count; battery++) {
+               memset(&arg, 0, sizeof(arg));
+               arg.type = AML_OBJTYPE_INTEGER;
+               arg.v_integer = (battery << THINKPAD_BATTERY_SHIFT) | state;
+               if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "BDSS",
+                   1, &arg, &ret) || (ret & THINKPAD_BATTERY_ERROR))
+                       return EIO;
+       }
        return 0;
 }
 
@@ -980,19 +984,21 @@ thinkpad_battery_setchargestart(int start)
 {
        struct acpithinkpad_softc *sc = acpithinkpad_cd.cd_devs[0];
        struct aml_value arg;
-       int battery = 1;
+       int battery, count;
        uint64_t ret;
 
        if (start >= hw_battery_chargestop)
                return EINVAL;
 
-       memset(&arg, 0, sizeof(arg));
-       arg.type = AML_OBJTYPE_INTEGER;
-       arg.v_integer = (battery << THINKPAD_BATTERY_SHIFT) | start;
-       if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "BCCS",
-           1, &arg, &ret) || (ret & THINKPAD_BATTERY_ERROR))
-               return EIO;
-
+       count = acpi_batcount(sc->sc_acpi);
+       for (battery = 1; battery <= count; battery++) {
+               memset(&arg, 0, sizeof(arg));
+               arg.type = AML_OBJTYPE_INTEGER;
+               arg.v_integer = (battery << THINKPAD_BATTERY_SHIFT) | start;
+               if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "BCCS",
+                   1, &arg, &ret) || (ret & THINKPAD_BATTERY_ERROR))
+                       return EIO;
+       }
        hw_battery_chargestart = start;
        return 0;
 }
@@ -1002,7 +1008,7 @@ thinkpad_battery_setchargestop(int stop)
 {
        struct acpithinkpad_softc *sc = acpithinkpad_cd.cd_devs[0];
        struct aml_value arg;
-       int battery = 1;
+       int battery, count;
        uint64_t ret;
 
        if (stop <= hw_battery_chargestart)
@@ -1011,13 +1017,15 @@ thinkpad_battery_setchargestop(int stop)
        if (stop == 100)
                stop = 0;
 
-       memset(&arg, 0, sizeof(arg));
-       arg.type = AML_OBJTYPE_INTEGER;
-       arg.v_integer = (battery << THINKPAD_BATTERY_SHIFT) | stop;
-       if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "BCSS",
-           1, &arg, &ret) || (ret & THINKPAD_BATTERY_ERROR))
-               return EIO;
-
+       count = acpi_batcount(sc->sc_acpi);
+       for (battery = 1; battery <= count; battery++) {
+               memset(&arg, 0, sizeof(arg));
+               arg.type = AML_OBJTYPE_INTEGER;
+               arg.v_integer = (battery << THINKPAD_BATTERY_SHIFT) | stop;
+               if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "BCSS",
+                   1, &arg, &ret) || (ret & THINKPAD_BATTERY_ERROR))
+                       return EIO;
+       }
        hw_battery_chargestop = (stop == 0) ? 100 : stop;
        return 0;
 }
index d783dd2..51eae66 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: acpivar.h,v 1.123 2023/06/29 20:58:08 dv Exp $        */
+/*     $OpenBSD: acpivar.h,v 1.124 2023/07/07 07:37:59 claudio Exp $   */
 /*
  * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
  *
@@ -385,6 +385,7 @@ void        acpi_indicator(struct acpi_softc *, int);
 void   acpi_disable_allgpes(struct acpi_softc *);
 void   acpi_enable_wakegpes(struct acpi_softc *, int);
 
+int    acpi_batcount(struct acpi_softc *);
 struct apm_power_info;
 int    acpi_apminfo(struct apm_power_info *);