diff options
author | Klemens Nanni <kn@cvs.openbsd.org> | 2021-09-25 10:43:25 +0000 |
---|---|---|
committer | Klemens Nanni <kn@cvs.openbsd.org> | 2021-09-25 10:43:25 +0000 |
commit | 56b8112d6344bfc823f6b80ae3cd8990270344da (patch) | |
tree | fcc182c9df0f4c9408a50aa29d273b7ebf5f7453 /sys | |
parent | a62a0892b022a6b9609cc58dd3ca63cb2641e6a5 (diff) |
Add gpioleds(4) for arm64
This driver provides support for LEDs connected to GPIO pins,
such as those found on the Pinebook Pro.
OK kettenis
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/arm64/conf/GENERIC | 4 | ||||
-rw-r--r-- | sys/dev/fdt/files.fdt | 6 | ||||
-rw-r--r-- | sys/dev/fdt/gpioleds.c | 102 |
3 files changed, 110 insertions, 2 deletions
diff --git a/sys/arch/arm64/conf/GENERIC b/sys/arch/arm64/conf/GENERIC index 2cbabe0629f..bcc95cdab63 100644 --- a/sys/arch/arm64/conf/GENERIC +++ b/sys/arch/arm64/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.206 2021/09/03 14:53:09 patrick Exp $ +# $OpenBSD: GENERIC,v 1.207 2021/09/25 10:43:24 kn Exp $ # # GENERIC machine description file # @@ -131,6 +131,8 @@ amdgpu* at pci? drm* at amdgpu? wsdisplay* at amdgpu? +gpioleds* at fdt? + # Apple apldart* at fdt? apldog* at fdt? early 1 diff --git a/sys/dev/fdt/files.fdt b/sys/dev/fdt/files.fdt index 3b23523493a..7d36eab3ef8 100644 --- a/sys/dev/fdt/files.fdt +++ b/sys/dev/fdt/files.fdt @@ -1,4 +1,4 @@ -# $OpenBSD: files.fdt,v 1.155 2021/06/29 12:43:09 patrick Exp $ +# $OpenBSD: files.fdt,v 1.156 2021/09/25 10:43:24 kn Exp $ # # Config file and device description for machine-independent FDT code. # Included by ports that need it. @@ -588,3 +588,7 @@ file dev/fdt/cwfg.c cwfg device dapmic attach dapmic at i2c file dev/fdt/dapmic.c dapmic + +device gpioleds +attach gpioleds at fdt +file dev/fdt/gpioleds.c gpioleds diff --git a/sys/dev/fdt/gpioleds.c b/sys/dev/fdt/gpioleds.c new file mode 100644 index 00000000000..889d30f1941 --- /dev/null +++ b/sys/dev/fdt/gpioleds.c @@ -0,0 +1,102 @@ +/* $OpenBSD: gpioleds.c,v 1.1 2021/09/25 10:43:24 kn Exp $ */ +/* + * Copyright (c) 2021 Klemens Nanni <kn@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 <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> + +struct gpioleds_softc { + struct device sc_dev; + int sc_node; +}; + +int gpioleds_match(struct device *, void *, void *); +void gpioleds_attach(struct device *, struct device *, void *); + +struct cfattach gpioleds_ca = { + sizeof (struct gpioleds_softc), gpioleds_match, gpioleds_attach +}; + +struct cfdriver gpioleds_cd = { + NULL, "gpioleds", DV_DULL +}; + +int +gpioleds_match(struct device *parent, void *match, void *aux) +{ + const struct fdt_attach_args *faa = aux; + + return OF_is_compatible(faa->fa_node, "gpio-leds"); +} + +void +gpioleds_attach(struct device *parent, struct device *self, void *aux) +{ + struct fdt_attach_args *faa = aux; + uint32_t *led_pin; + char *function, *default_state; + int function_len, default_state_len, gpios_len; + int node, leds = 0; + + pinctrl_byname(faa->fa_node, "default"); + + for (node = OF_child(faa->fa_node); node; node = OF_peer(node)) { + function_len = OF_getproplen(node, "function"); + if (function_len <= 0) + continue; + default_state_len = OF_getproplen(node, "default-state"); + if (default_state_len <= 0) + continue; + gpios_len = OF_getproplen(node, "gpios"); + if (gpios_len <= 0) + continue; + + function = malloc(function_len, M_TEMP, M_WAITOK); + OF_getprop(node, "function", function, function_len); + default_state = malloc(default_state_len, M_TEMP, M_WAITOK); + OF_getprop(node, "default-state", default_state, default_state_len); + led_pin = malloc(gpios_len, M_TEMP, M_WAITOK); + OF_getpropintarray(node, "gpios", led_pin, gpios_len); + gpio_controller_config_pin(led_pin, GPIO_CONFIG_OUTPUT); + if (strcmp(default_state, "on") == 0) + gpio_controller_set_pin(led_pin, 1); + else if (strcmp(default_state, "off") == 0) + gpio_controller_set_pin(led_pin, 0); + + printf("%s \"%s\"", leds++ ? "," : ":", function); + free(function, M_TEMP, function_len); + free(default_state, M_TEMP, default_state_len); + free(led_pin, M_TEMP, gpios_len); + } + + if (leds == 0) { + printf(": no LEDs\n"); + return; + } + printf("\n"); +} |