Download raw body.
a little more asus wmi
> From: "Ted Unangst" <tedu@tedunangst.com>
> Date: Tue, 10 Jun 2025 02:36:44 -0400
>
> We can support battery chargestop and a fan sensor.
The fan policy stuff needs more discussion. So if you want this to
end up in OpenBSD you'll have to split these bits out. Probably best
to send separate bits for the battery charging stuff and the fan
sensor.
This does need more work. There are several KNF issues with this code.
> Only writing chargestop is supported, and it seems to reset after
> reboot, but otherwise works. Discharged a bit, set it to 90, battery
> is now idle at 95% instead of going up to 100%.
Typically the charge controllers implement some sort of hysteresis for
charging the battery. So stop charging at a certain percentage, and
start charging again at some lower percentage. If that lower value is
known you can do what aplsmc(4) does, so set both stop and start in
the _setchargestop() function and have a _setchargestart() that return
EOPNOTSUPP. But if you don't know, then what you've implemented is
fine.
>
> Index: acpiwmi.c
> ===================================================================
> RCS file: /home/cvs/src/sys/dev/acpi/acpiwmi.c,v
> diff -u -p -r1.5 acpiwmi.c
> --- acpiwmi.c 21 May 2025 02:18:29 -0000 1.5
> +++ acpiwmi.c 10 Jun 2025 06:30:17 -0000
> @@ -250,6 +250,8 @@ struct wmiasus {
> int w_fnlock;
> int w_perf;
> int w_perfid;
> + struct ksensor w_sensfan;
> + struct ksensordev w_sensdev;
> };
>
> #define ASUS_DSTS_PRESENCE 0x00010000
> @@ -267,6 +269,7 @@ struct wmiasus {
> #define ASUS_DEV_FNLOCK 0x00100023
> #define ASUS_DEV_CAMLED 0x00060079
> #define ASUS_DEV_MICLED 0x00040017
> +#define ASUS_DEV_CPUFAN 0x00110013
>
> #define ASUS_FNLOCK_BIOS_DISABLED 0x1
>
> @@ -311,6 +314,61 @@ asus_toggle(struct wmiasus *wh, int devi
> asus_dev_set(wh, devid, *val | mask);
> }
>
> +struct wmiasus *wmi_asus_cookie;
> +/* xxx the order may vary by machine... */
> +static const char *asus_policies[] = { "standard,", "silent,", "perf," };
> +
> +void
> +wmi_asus_setpolicy(char *policy)
> +{
> + struct wmiasus *wh = wmi_asus_cookie;
> + int target = -1;
> +
> + for (int i = 0; i < nitems(asus_policies); i++) {
> + size_t len = strlen(asus_policies[i]);
> + if (strncmp(policy, asus_policies[i], len) == 0) {
> + target = i;
> + memmove(policy, policy + len, strlen(policy + len)+1);
> + break;
> + }
> + }
> + if (target != -1) {
> + wh->w_perf = target;
> + asus_dev_set(wh, wh->w_perfid, wh->w_perf);
> + }
> +}
> +
> +void
> +wmi_asus_getpolicy(char *policy, size_t len)
> +{
> + struct wmiasus *wh = wmi_asus_cookie;
> + int target = wh->w_perf;
> +
> + if (target >= 0 && target < nitems(asus_policies))
> + strlcpy(policy, asus_policies[target], len);
> +}
> +
> +int
> +wmi_asus_battery_setchargestop(int stop)
> +{
> + struct wmiasus *wh = wmi_asus_cookie;
> + extern int hw_battery_chargestop;
> +
> + asus_dev_set(wh, ASUS_DEV_BATTERY, stop);
> + hw_battery_chargestop = stop;
> + return 0;
> +}
> +
> +void
> +wmi_asus_sensor_check(void *arg)
> +{
> + struct wmiasus *wh = arg;
> +
> + int res = asus_dev_get(wh, ASUS_DEV_CPUFAN);
> + if (res > 0 && res & ASUS_DSTS_PRESENCE)
> + wh->w_sensfan.value = (res & 0xffff) * 100;
> +}
> +
> static int
> wmi_asus_init(struct acpiwmi_softc *sc, struct guidinfo *ginfo)
> {
> @@ -342,6 +400,28 @@ wmi_asus_init(struct acpiwmi_softc *sc,
> res = asus_dev_get(wh, ASUS_DEV_PERF_2);
> if (res >= 0)
> wh->w_perfid = ASUS_DEV_PERF_2;
> + if (wh->w_perfid != 0) {
> + extern void (*cpu_setpolicy)(char *);
> + extern void (*cpu_getpolicy)(char *, size_t);
> + cpu_getpolicy = wmi_asus_getpolicy;
> + cpu_setpolicy = wmi_asus_setpolicy;
> + }
> + res = asus_dev_get(wh, ASUS_DEV_BATTERY);
> + if (res > 0 && res & ASUS_DSTS_PRESENCE) {
> + extern int (*hw_battery_setchargestop)(int);
> + hw_battery_setchargestop =
> + wmi_asus_battery_setchargestop;
> + }
> + res = asus_dev_get(wh, ASUS_DEV_CPUFAN);
> + if (res > 0 && res & ASUS_DSTS_PRESENCE) {
> + strlcpy(wh->w_sensdev.xname, DEVNAME(sc), sizeof(wh->w_sensdev.xname));
> + wh->w_sensfan.type = SENSOR_FANRPM;
> + wh->w_sensfan.value = (res & 0xffff) * 100;
> + sensor_attach(&wh->w_sensdev, &wh->w_sensfan);
> + sensordev_install(&wh->w_sensdev);
> + sensor_task_register(wh, wmi_asus_sensor_check, 2);
> + }
> +
> // turn on by default
> asus_toggle(wh, ASUS_DEV_KBDLIGHT, &wh->w_kbdlight);
>
> @@ -352,6 +432,7 @@ wmi_asus_init(struct acpiwmi_softc *sc,
> asus_toggle(wh, ASUS_DEV_FNLOCK, &wh->w_fnlock);
> }
>
> + wmi_asus_cookie = wh;
> return 0;
> }
>
>
>
a little more asus wmi