Module Name: src Committed By: jmcneill Date: Sat Jul 8 00:55:02 UTC 2017
Modified Files: src/sys/dev/fdt: files.fdt Added Files: src/sys/dev/fdt: gpioleds.c Log Message: Add GPIO LED driver. To generate a diff of this commit: cvs rdiff -u -r1.17 -r1.18 src/sys/dev/fdt/files.fdt cvs rdiff -u -r0 -r1.1 src/sys/dev/fdt/gpioleds.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/fdt/files.fdt diff -u src/sys/dev/fdt/files.fdt:1.17 src/sys/dev/fdt/files.fdt:1.18 --- src/sys/dev/fdt/files.fdt:1.17 Thu Jun 29 17:04:17 2017 +++ src/sys/dev/fdt/files.fdt Sat Jul 8 00:55:02 2017 @@ -1,4 +1,4 @@ -# $NetBSD: files.fdt,v 1.17 2017/06/29 17:04:17 jmcneill Exp $ +# $NetBSD: files.fdt,v 1.18 2017/07/08 00:55:02 jmcneill Exp $ include "external/bsd/libfdt/conf/files.libfdt" @@ -22,6 +22,10 @@ device gpiokeys: sysmon_envsys, sysmon_p attach gpiokeys at fdt file dev/fdt/gpiokeys.c gpiokeys +device gpioleds: leds +attach gpioleds at fdt +file dev/fdt/gpioleds.c gpioleds + file dev/fdt/fdt_openfirm.c fdtbus file dev/fdt/fdt_subr.c fdtbus file dev/fdt/fdt_clock.c fdtbus Added files: Index: src/sys/dev/fdt/gpioleds.c diff -u /dev/null src/sys/dev/fdt/gpioleds.c:1.1 --- /dev/null Sat Jul 8 00:55:02 2017 +++ src/sys/dev/fdt/gpioleds.c Sat Jul 8 00:55:02 2017 @@ -0,0 +1,113 @@ +/* $NetBSD: gpioleds.c,v 1.1 2017/07/08 00:55:02 jmcneill Exp $ */ + +/*- + * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: gpioleds.c,v 1.1 2017/07/08 00:55:02 jmcneill Exp $"); + +#include <sys/param.h> +#include <sys/kernel.h> +#include <sys/systm.h> +#include <sys/device.h> +#include <sys/kmem.h> +#include <sys/bus.h> +#include <sys/gpio.h> + +#include <dev/led.h> + +#include <dev/fdt/fdtvar.h> + +static int gpioleds_match(device_t, cfdata_t, void *); +static void gpioleds_attach(device_t, device_t, void *); + +CFATTACH_DECL_NEW(gpioleds, 0, gpioleds_match, gpioleds_attach, NULL, NULL); + +static int +gpioleds_get(void *priv) +{ + struct fdtbus_gpio_pin *pin = priv; + + return fdtbus_gpio_read(pin); +} + +static void +gpioleds_set(void *priv, int state) +{ + struct fdtbus_gpio_pin *pin = priv; + + fdtbus_gpio_write(pin, state); +} + +static int +gpioleds_match(device_t parent, cfdata_t cf, void *aux) +{ + const char * const compatible[] = { "gpio-leds", NULL }; + const struct fdt_attach_args *faa = aux; + + return of_match_compatible(faa->faa_phandle, compatible); +} + +static void +gpioleds_attach(device_t parent, device_t self, void *aux) +{ + const struct fdt_attach_args *faa = aux; + const int phandle = faa->faa_phandle; + struct fdtbus_gpio_pin *pin; + const char *default_state; + char label[64]; + int child; + + aprint_naive("\n"); + aprint_normal(":"); + + for (child = OF_child(phandle); child; child = OF_peer(child)) { + /* Get the label, fallback to node name */ + if (OF_getprop(child, "label", label, sizeof(label)) <= 0 && + OF_getprop(child, "name", label, sizeof(label)) <= 0) + continue; + + /* Get the output pin */ + pin = fdtbus_gpio_acquire(child, "gpios", GPIO_PIN_OUTPUT); + if (pin == NULL) + continue; + + /* Attach the LED */ + if (led_attach(label, pin, gpioleds_get, gpioleds_set) == NULL) + continue; + + aprint_normal(" %s", label); + + /* Set default state */ + default_state = fdtbus_get_string(child, "default-state"); + if (default_state && strcmp(default_state, "on") == 0) + gpioleds_set(pin, LED_STATE_ON); + else if (default_state && strcmp(default_state, "off") == 0) + gpioleds_set(pin, LED_STATE_OFF); + } + + aprint_normal("\n"); +}