From 6caabb8ebe7013549ea587750cb68d177b554408 Mon Sep 17 00:00:00 2001 From: jcs Date: Fri, 1 Jul 2016 15:02:49 +0000 Subject: [PATCH] add a simple keyboard backlight driver for some chromebooks, adjustable with wsconsctl keyboard.backlight ok bmercer, kettenis --- sys/arch/amd64/conf/GENERIC | 3 +- sys/dev/acpi/acpicbkbd.c | 140 ++++++++++++++++++++++++++++++++++++ sys/dev/acpi/files.acpi | 7 +- 3 files changed, 148 insertions(+), 2 deletions(-) create mode 100644 sys/dev/acpi/acpicbkbd.c diff --git a/sys/arch/amd64/conf/GENERIC b/sys/arch/amd64/conf/GENERIC index c9d46faa1a0..7cb016a2139 100644 --- a/sys/arch/amd64/conf/GENERIC +++ b/sys/arch/amd64/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.422 2016/06/28 04:41:37 jmatthew Exp $ +# $OpenBSD: GENERIC,v 1.423 2016/07/01 15:02:49 jcs Exp $ # # For further information on compiling OpenBSD kernels, see the config(8) # man page. @@ -64,6 +64,7 @@ aibs* at acpi? bytgpio* at acpi? chvgpio* at acpi? sdhc* at acpi? +acpicbkbd* at acpi? mpbios0 at bios0 diff --git a/sys/dev/acpi/acpicbkbd.c b/sys/dev/acpi/acpicbkbd.c new file mode 100644 index 00000000000..b0951a792f0 --- /dev/null +++ b/sys/dev/acpi/acpicbkbd.c @@ -0,0 +1,140 @@ +/* $OpenBSD: acpicbkbd.c,v 1.1 2016/07/01 15:02:49 jcs Exp $ */ +/* + * Copyright (c) 2016 joshua stein + * + * Permission to use, copy, modify, and/or 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 +#include + +#include +#include +#include + +#include + +#ifdef ACPICBKBD_DEBUG +#define DPRINTF(x) printf x +#else +#define DPRINTF(x) +#endif + +#define ACPICBKBD_MAX_BACKLIGHT 100 + +struct acpicbkbd_softc { + struct device sc_dev; + struct acpi_softc *sc_acpi; + struct aml_node *sc_devnode; + + uint64_t sc_backlight; +}; + +int acpicbkbd_match(struct device *, void *, void *); +void acpicbkbd_attach(struct device *, struct device *, void *); + +int acpicbkbd_get_backlight(struct wskbd_backlight *); +int acpicbkbd_set_backlight(struct wskbd_backlight *); +void acpicbkbd_write_backlight(void *, int); +extern int (*wskbd_get_backlight)(struct wskbd_backlight *); +extern int (*wskbd_set_backlight)(struct wskbd_backlight *); + +struct cfattach acpicbkbd_ca = { + sizeof(struct acpicbkbd_softc), acpicbkbd_match, acpicbkbd_attach +}; + +struct cfdriver acpicbkbd_cd = { + NULL, "acpicbkbd", DV_DULL +}; + +const char *acpicbkbd_hids[] = { + "GOOG0002", + NULL +}; + +int +acpicbkbd_match(struct device *parent, void *match, void *aux) +{ + struct acpi_attach_args *aaa = aux; + struct cfdata *cf = match; + + return acpi_matchhids(aaa, acpicbkbd_hids, cf->cf_driver->cd_name); +} + +void +acpicbkbd_attach(struct device *parent, struct device *self, void *aux) +{ + struct acpicbkbd_softc *sc = (struct acpicbkbd_softc *)self; + struct acpi_attach_args *aa = aux; + + sc->sc_acpi = (struct acpi_softc *)parent; + sc->sc_devnode = aa->aaa_node; + + printf(": %s", sc->sc_devnode->name); + + if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "KBQC", + 0, NULL, &sc->sc_backlight) == 0) { + wskbd_get_backlight = acpicbkbd_get_backlight; + wskbd_set_backlight = acpicbkbd_set_backlight; + } else + printf(", no backlight control"); + + printf("\n"); +} + +int +acpicbkbd_get_backlight(struct wskbd_backlight *kbl) +{ + struct acpicbkbd_softc *sc = acpicbkbd_cd.cd_devs[0]; + + KASSERT(sc != NULL); + + kbl->min = 0; + kbl->max = ACPICBKBD_MAX_BACKLIGHT; + kbl->curval = sc->sc_backlight; + + return 0; +} + +int +acpicbkbd_set_backlight(struct wskbd_backlight *kbl) +{ + struct acpicbkbd_softc *sc = acpicbkbd_cd.cd_devs[0]; + + KASSERT(sc != NULL); + + if (kbl->curval > ACPICBKBD_MAX_BACKLIGHT) + return EINVAL; + + sc->sc_backlight = kbl->curval; + + acpi_addtask(sc->sc_acpi, acpicbkbd_write_backlight, sc, 0); + acpi_wakeup(sc->sc_acpi); + + return 0; +} + +void +acpicbkbd_write_backlight(void *arg0, int arg1) +{ + struct acpicbkbd_softc *sc = arg0; + struct aml_value arg; + + DPRINTF(("%s: writing backlight of %lld\n", DEVNAME(sc), + sc->sc_backlight)); + + memset(&arg, 0, sizeof(arg)); + arg.type = AML_OBJTYPE_INTEGER; + arg.v_integer = sc->sc_backlight; + aml_evalname(sc->sc_acpi, sc->sc_devnode, "KBCM", 1, &arg, NULL); +} diff --git a/sys/dev/acpi/files.acpi b/sys/dev/acpi/files.acpi index 0798ca324e7..076596a3848 100644 --- a/sys/dev/acpi/files.acpi +++ b/sys/dev/acpi/files.acpi @@ -1,4 +1,4 @@ -# $OpenBSD: files.acpi,v 1.32 2016/05/07 23:10:50 kettenis Exp $ +# $OpenBSD: files.acpi,v 1.33 2016/07/01 15:02:49 jcs Exp $ # # Config file and device description for machine-independent ACPI code. # Included by ports that need it. @@ -130,3 +130,8 @@ file dev/acpi/sdhc_acpi.c sdhc_acpi device dwiic: i2cbus attach dwiic at acpi file dev/acpi/dwiic.c dwiic + +# Chromebook keyboard backlight +device acpicbkbd +attach acpicbkbd at acpi +file dev/acpi/acpicbkbd.c acpicbkbd -- 2.20.1