Index | Thread | Search

From:
Peter Hessler <phessler@theapt.org>
Subject:
Re: qcpas: generate apm events upon ac state changes
To:
Landry Breuil <landry@openbsd.org>
Cc:
tech@openbsd.org, patrick@openbsd.org
Date:
Fri, 8 Nov 2024 19:08:38 +0100

Download raw body.

Thread
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.h> /* errno */
:#include <fcntl.h> /* open() */
:#include <stdio.h>
:/* kevent() */
:#include <sys/types.h>
:#include <sys/event.h>
:#include <sys/time.h>
:#include <sys/ioctl.h> /* ioctl() */
:/* APM macros */
:#include <machine/apmvar.h>
:/* sysctl() */
:#include <sys/param.h>
:
: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