From: Peter Hessler Subject: Re: qcpas: generate apm events upon ac state changes To: Landry Breuil Cc: tech@openbsd.org, patrick@openbsd.org Date: Fri, 8 Nov 2024 19:08:38 +0100 OK On 2024 Nov 08 (Fri) at 19:06:44 +0100 (+0100), Landry Breuil wrote: :hi, : :small diff that allows qcpas to send apm events when the ac is plugged :in/unplugged, thanks jca@ for the pointer. : :in userland, that's used by sysutils/upower that gives me the fancy battery/ac :status via xfce4-power-manager on the x13s, before that it never got events on :ac state changes, only the battery levels. : :i don't know if events should be sent upon battery level changes, i know upower :doesn't use them as it reads the 'remaining capacity' value from :hw.sensors.qcpas0, cf https://gitlab.freedesktop.org/upower/upower/-/blob/master/src/openbsd/up-backend.c?ref_type=heads#L393. : :will also test on the omnibook x14 in a few. : :Index: qcpas.c :=================================================================== :RCS file: /cvs/src/sys/dev/fdt/qcpas.c,v :diff -u -p -r1.7 qcpas.c :--- qcpas.c 1 Sep 2024 03:14:48 -0000 1.7 :+++ qcpas.c 8 Nov 2024 17:51:25 -0000 :@@ -1532,9 +1532,13 @@ qcpas_pmic_rtr_bat_status(struct qcpas_s : info->minutes_left = (60 * delta) / abs(bat->rate); : : if (bat->power_state & BATTMGR_PWR_STATE_AC_ON) { :+ if (info->ac_state != APM_AC_ON) :+ apm_record_event(APM_POWER_CHANGE); : info->ac_state = APM_AC_ON; : hw_power = 1; : } else { :+ if (info->ac_state != APM_AC_OFF) :+ apm_record_event(APM_POWER_CHANGE); : info->ac_state = APM_AC_OFF; : hw_power = 0; : } : :i'm also attaching a small test program that prints apm events received by :kqueue on stderr. : :comments ? : :Landry :#include /* errno */ :#include /* open() */ :#include :/* kevent() */ :#include :#include :#include :#include /* ioctl() */ :/* APM macros */ :#include :/* sysctl() */ :#include : :int main() { : int kq, nevents, apm_fd; : struct kevent ev; : struct timespec ts = {600, 0}, sts = {0, 0}; : if ((apm_fd = open("/dev/apm", O_RDONLY)) == -1) { : printf("failed opening apmdev\n"); : if (errno != ENXIO && errno != ENOENT) : return 1; : } : kq = kqueue(); : if (kq <= 0) : return 2; : EV_SET(&ev, apm_fd, EVFILT_READ, EV_ADD | EV_ENABLE | EV_CLEAR, : 0, 0, NULL); : nevents = 1; : if (kevent(kq, &ev, nevents, NULL, 0, &sts) < 0) : return 3; : /* blocking wait on kqueue */ : printf("starting loop\n"); : for (;;) { : int rv; : /* 10mn timeout */ : sts = ts; : if ((rv = kevent(kq, NULL, 0, &ev, 1, &sts)) < 0) { : printf("failed kevent ?\n"); : break; : } : printf("got kevent\n"); : if (!rv) : continue; : if (ev.ident == apm_fd && APM_EVENT_TYPE(ev.data) == APM_POWER_CHANGE ) { : printf("event\n"); : } : printf("id=%lu, data=%lld\n",ev.ident, ev.data); : } : printf("exited loop\n"); :} -- TV is chewing gum for the eyes. -- Frank Lloyd Wright