> Date: Tue, 9 Nov 2021 15:43:04 +0000 > From: Klemens Nanni <k...@openbsd.org> > > This populates `systat sensors' with the correct lid status on my > Pinebook Pro: > > -gpio-key-lid at mainbus0 not configured > -gpio-key-power at mainbus0 not configured > +gpiokeys0 at mainbus0: "Lid" > +gpiokeys0 at mainbus0: "Power" > > 0/1 <-> closed/open is mapped exactly like acpibtn(4) already does on > other machines, to maintain consistent user experience across devices. > > Next steps are: > - hook up lid status with `machdep.lidaction', see acpibtn(4) > - handle power button -> hook up machdep.pwraction, see acpibtn(4) > > > Sort gpio{led,charger,keys} while here. > > Feedback? OK?
ok kettenis@ > diff 83b213946bcaccd148d4a46b6ebda89b120fc778 refs/heads/master > blob - ab52b74cf7e9895cbcb29532b9898cdaf33e89f3 > blob + 0891a80caf135b983dea282f281d7f6089b52e30 > --- distrib/sets/lists/man/mi > +++ distrib/sets/lists/man/mi > @@ -1423,6 +1423,7 @@ > ./usr/share/man/man4/gpiocharger.4 > ./usr/share/man/man4/gpiodcf.4 > ./usr/share/man/man4/gpioiic.4 > +./usr/share/man/man4/gpiokeys.4 > ./usr/share/man/man4/gpioleds.4 > ./usr/share/man/man4/gpioow.4 > ./usr/share/man/man4/graphaudio.4 > blob - c32bc8962cd103da4ed17ad63a2162f63a16e639 > blob + 6057d2a559120ada9f43ae0f5e5e6eb63a514be8 > --- share/man/man4/Makefile > +++ share/man/man4/Makefile > @@ -37,7 +37,7 @@ MAN= aac.4 abcrtc.4 abl.4 ac97.4 acphy.4 acrtc.4 \ > fuse.4 fxp.4 \ > gdt.4 gentbi.4 gem.4 gfrtc.4 gif.4 glenv.4 glkgpio.4 gpio.4 \ > gpiocharger.4 gpiodcf.4 \ > - gpioiic.4 gpioleds.4 gpioow.4 graphaudio.4 gre.4 gscsio.4 \ > + gpioiic.4 gpiokeys.4 gpioleds.4 gpioow.4 graphaudio.4 gre.4 gscsio.4 \ > hds.4 hiclock.4 hidwusb.4 hil.4 hilid.4 hilkbd.4 hilms.4 \ > hireset.4 hitemp.4 hme.4 hotplug.4 hsq.4 \ > hvn.4 hvs.4 hyperv.4 \ > blob - /dev/null > blob + 44c147f04672fa1b72820ebd7692d7efbe17ceae (mode 644) > --- /dev/null > +++ share/man/man4/gpiokeys.4 > @@ -0,0 +1,50 @@ > +.\" $OpenBSD: $ > +.\" > +.\" Copyright (c) 2021 Klemens Nanni <k...@openbsd.org> > +.\" > +.\" Permission to use, copy, modify, and distribute this software for any > +.\" purpose with or without fee is hereby granted, provided that the above > +.\" copyright notice and this permission notice appear in all copies. > +.\" > +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES > +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF > +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR > +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES > +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN > +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF > +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. > +.\" > +.Dd $Mdocdate: September 02 2021 $ > +.Dt GPIOKEYS 4 > +.Os > +.Sh NAME > +.Nm gpiokeys > +.Nd GPIO keys > +.Sh SYNOPSIS > +.Cd "gpiokeys* at fdt?" > +.Sh DESCRIPTION > +The > +.Nm > +driver handles events triggered by GPIO keys. > +Currently, only lid status events are supported. > +.Pp > +The lid status is set up as a sensor and can be monitored using > +.Xr sysctl 8 > +or > +.Xr sensorsd 8 . > +.Sh SEE ALSO > +.Xr gpio 4 , > +.Xr intro 4 , > +.Xr sensorsd 8 , > +.Xr sysctl 8 > +.Sh HISTORY > +The > +.Nm > +driver first appeared in > +.Ox 7.1 . > +.Sh AUTHORS > +.An -nosplit > +The > +.Nm > +driver was written by > +.An Klemens Nanni Aq Mt k...@openbsd.org . > blob - 809ece860c07df596da208638f2f3facc829cb72 > blob + 0ceac9b6159e5cfe43fc4e601274100df1c40ffa > --- sys/arch/arm64/conf/GENERIC > +++ sys/arch/arm64/conf/GENERIC > @@ -131,8 +131,9 @@ amdgpu* at pci? > drm* at amdgpu? > wsdisplay* at amdgpu? > > -gpioleds* at fdt? > gpiocharger* at fdt? > +gpiokeys* at fdt? > +gpioleds* at fdt? > > # Apple > apldart* at fdt? > blob - 301500e9b0c6501be4d55feb5135ca223d6337cc > blob + 3d73e22edf7802172b29a26cb8b503eaeb8f3aa9 > --- sys/dev/fdt/files.fdt > +++ sys/dev/fdt/files.fdt > @@ -589,10 +589,14 @@ device dapmic > attach dapmic at i2c > file dev/fdt/dapmic.c dapmic > > -device gpioleds > -attach gpioleds at fdt > -file dev/fdt/gpioleds.c gpioleds > - > device gpiocharger > attach gpiocharger at fdt > file dev/fdt/gpiocharger.c gpiocharger > + > +device gpioleds > +attach gpioleds at fdt > +file dev/fdt/gpioleds.c gpioleds > + > +device gpiokeys > +attach gpiokeys at fdt > +file dev/fdt/gpiokeys.c gpiokeys > blob - /dev/null > blob + 4b4ca55a5c825ad8d66fbc8ec198bbcd13352b7c (mode 644) > --- /dev/null > +++ sys/dev/fdt/gpiokeys.c > @@ -0,0 +1,179 @@ > +/* $OpenBSD: $ */ > +/* > + * Copyright (c) 2021 Klemens Nanni <k...@openbsd.org> > + * > + * Permission to use, copy, modify, and distribute this software for any > + * purpose with or without fee is hereby granted, provided that the above > + * copyright notice and this permission notice appear in all copies. > + * > + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES > + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF > + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR > + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES > + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN > + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF > + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. > + */ > + > +#include <sys/param.h> > +#include <sys/systm.h> > +#include <sys/device.h> > +#include <sys/gpio.h> > +#include <sys/malloc.h> > +#include <sys/queue.h> > + > +#include <machine/bus.h> > +#include <machine/fdt.h> > + > +#include <dev/gpio/gpiovar.h> > +#include <dev/ofw/ofw_gpio.h> > +#include <dev/ofw/ofw_pinctrl.h> > +#include <dev/ofw/openfirm.h> > +#include <dev/ofw/fdt.h> > + > +#include <sys/sensors.h> > + > +#define DEVNAME(_s) ((_s)->sc_dev.dv_xname) > + > +/* > + * Defines from Linux, see: > + * Documentation/input/event-codes.rst > + * include/dt-bindings/input/linux-event-codes.h > + */ > +enum gpiokeys_event_type { > + GPIOKEYS_EV_KEY = 1, > + GPIOKEYS_EV_SW = 5, > +}; > + > +enum gpiokeys_switch_event { > + GPIOKEYS_SW_LID = 0, /* set = lid closed */ > +}; > + > +struct gpiokeys_key { > + uint32_t *key_pin; > + uint32_t key_input_type; > + uint32_t key_code; > + struct ksensor key_sensor; > + SLIST_ENTRY(gpiokeys_key) entries; > +}; > + > +struct gpiokeys_softc { > + struct device sc_dev; > + int sc_node; > + struct ksensordev sc_sensordev; > + SLIST_HEAD(, gpiokeys_key) sc_keys; > +}; > + > +int gpiokeys_match(struct device *, void *, void *); > +void gpiokeys_attach(struct device *, struct device *, void *); > + > +const struct cfattach gpiokeys_ca = { > + sizeof (struct gpiokeys_softc), gpiokeys_match, gpiokeys_attach > +}; > + > +struct cfdriver gpiokeys_cd = { > + NULL, "gpiokeys", DV_DULL > +}; > + > +void gpiokeys_update_key(void *); > + > +int > +gpiokeys_match(struct device *parent, void *match, void *aux) > +{ > + const struct fdt_attach_args *faa = aux; > + > + return OF_is_compatible(faa->fa_node, "gpio-keys") || > + OF_is_compatible(faa->fa_node, "gpio-keys-polled"); > +} > + > +void > +gpiokeys_attach(struct device *parent, struct device *self, void *aux) > +{ > + struct gpiokeys_softc *sc = (struct gpiokeys_softc *)self; > + struct fdt_attach_args *faa = aux; > + struct gpiokeys_key *key; > + char *label; > + uint32_t code; > + int node, len, gpios_len, have_sensors = 0; > + > + SLIST_INIT(&sc->sc_keys); > + > + pinctrl_byname(faa->fa_node, "default"); > + > + for (node = OF_child(faa->fa_node); node; node = OF_peer(node)) { > + if (OF_getprop(node, "linux,code", &code, sizeof(code)) == -1) > + continue; > + gpios_len = OF_getproplen(node, "gpios"); > + if (gpios_len <= 0) > + continue; > + len = OF_getproplen(node, "label"); > + if (len <= 0) > + continue; > + label = malloc(len, M_TEMP, M_WAITOK); > + if (OF_getprop(node, "label", label, len) != len) { > + free(label, M_TEMP, len); > + continue; > + } > + key = malloc(sizeof(*key), M_DEVBUF, M_WAITOK | M_ZERO); > + key->key_input_type = OF_getpropint(node, "linux,input-type", > + GPIOKEYS_EV_KEY); > + key->key_code = code; > + key->key_pin = malloc(gpios_len, M_DEVBUF, M_WAITOK); > + OF_getpropintarray(node, "gpios", key->key_pin, gpios_len); > + gpio_controller_config_pin(key->key_pin, GPIO_CONFIG_INPUT); > + > + switch (key->key_input_type) { > + case GPIOKEYS_EV_SW: > + switch (key->key_code) { > + case GPIOKEYS_SW_LID: > + strlcpy(key->key_sensor.desc, "lid open", > + sizeof(key->key_sensor.desc)); > + key->key_sensor.type = SENSOR_INDICATOR; > + sensor_attach(&sc->sc_sensordev, > &key->key_sensor); > + sensor_task_register(key, gpiokeys_update_key, > 1); > + have_sensors = 1; > + break; > + } > + break; > + } > + > + printf("%s \"%s\"", SLIST_EMPTY(&sc->sc_keys) ? ":" : ",", > + label); > + free(label, M_TEMP, len); > + > + SLIST_INSERT_HEAD(&sc->sc_keys, key, entries); > + } > + > + if (have_sensors) { > + strlcpy(sc->sc_sensordev.xname, DEVNAME(sc), > + sizeof(sc->sc_sensordev.xname)); > + sensordev_install(&sc->sc_sensordev); > + } > + > + if (SLIST_EMPTY(&sc->sc_keys)) > + printf(": no keys"); > + printf("\n"); > +} > + > +void > +gpiokeys_update_key(void *arg) > +{ > + struct gpiokeys_key *key = arg; > + int val; > + > + val = gpio_controller_get_pin(key->key_pin); > + > + switch (key->key_input_type) { > + case GPIOKEYS_EV_SW: > + switch (key->key_code) { > + case GPIOKEYS_SW_LID: > + /* > + * Match acpibtn(4), i.e. closed ThinkPad lid yields > + * hw.sensors.acpibtn1.indicator0=Off (lid open) > + */ > + key->key_sensor.value = !val; > + break; > + } > + break; > + } > +} > >