svn commit: r261843 - in head: share/man/man4 sys/dev/gpio
Luiz Otavio O Souza
loos at FreeBSD.org
Thu Feb 13 17:58:53 UTC 2014
Author: loos
Date: Thu Feb 13 17:58:52 2014
New Revision: 261843
URL: http://svnweb.freebsd.org/changeset/base/261843
Log:
Add OFW support to the in tree gpio compatible devices: gpioiic(4) and
gpioled(4).
Tested on RPi and BBB (using the hardware I2C controller and gpioiic(4) for
the I2C tests). It was also verified for regressions on RSPRO (MIPS/ar71xx)
used as reference for a non OFW-based system.
Update the gpioled(4) and gpioiic(4) man pages with some details and
examples about the FDT/OFW support.
Some compatibility details pointed out by imp@ will follow in subsequent
commits.
Approved by: adrian (mentor, implicit)
Modified:
head/share/man/man4/gpioiic.4
head/share/man/man4/gpioled.4
head/sys/dev/gpio/gpioiic.c
head/sys/dev/gpio/gpioled.c
Modified: head/share/man/man4/gpioiic.4
==============================================================================
--- head/share/man/man4/gpioiic.4 Thu Feb 13 17:08:29 2014 (r261842)
+++ head/share/man/man4/gpioiic.4 Thu Feb 13 17:58:52 2014 (r261843)
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd November 5, 2013
+.Dd February 13, 2014
.Dt GPIOIIC 4
.Os
.Sh NAME
@@ -65,7 +65,7 @@ This is a bitmask of the pins on the
that are to be used for SCLOCK and SDATA from the GPIO IIC
bit-banging bus.
To configure pin 0 and 7, use the bitmask of
-10000001 and convert it to a hexadecimal value of 0x0081.
+0b10000001 and convert it to a hexadecimal value of 0x0081.
Please note that this mask should only ever have two bits set
(any others bits - i.e., pins - will be ignored).
.It Va hint.gpioiic.%d.scl
@@ -73,13 +73,77 @@ Indicates which bit in the
.Va hint.gpioiic.%d.pins
should be used as the SCLOCK
source.
+Optional, defaults to 0.
.It Va hint.gpioiic.%d.sda
Indicates which bit in the
.Va hint.gpioiic.%d.pins
should be used as the SDATA
source.
+Optional, defaults to 1.
+.El
+.Pp
+On a
+.Xr FDT 4
+based system, like
+.Li ARM , the dts part for a
+.Nm gpioiic
+device usually looks like:
+.Bd -literal
+gpio: gpio {
+
+ gpio-controller;
+ ...
+
+ gpioiic0 {
+ compatible = "gpioiic";
+ /*
+ * Attach to GPIO pins 21 and 22. Set them
+ * initially as inputs.
+ */
+ gpios = <&gpio 21 1 0
+ &gpio 22 1 0>;
+ scl = <0>; /* GPIO pin 21 - optional */
+ sda = <1>; /* GPIO pin 22 - optional */
+
+ /* This is an example of a gpioiic child. */
+ gpioiic-child0 {
+ compatible = "lm75";
+ i2c-address = <0x4f>;
+ };
+ };
+};
+.Ed
+.Pp
+Where:
+.Bl -tag -width ".Va compatible"
+.It Va compatible
+Should always be set to "gpioiic".
+.It Va gpios
+The
+.Va gpios
+property indicates which GPIO pins should be used for SCLOCK and SDATA
+on the GPIO IIC bit-banging bus.
+For more details about the
+.Va gpios
+property, please consult
+.Pa /usr/src/sys/boot/fdt/dts/bindings-gpio.txt .
+.It Va scl
+The
+.Va scl
+option indicates which bit in the
+.Va gpios
+should be used as the SCLOCK source.
+Optional, defaults to 0.
+.It Va sda
+The
+.Va sda
+option indicates which bit in the
+.Va gpios
+should be used as the SDATA source.
+Optional, defaults to 1.
.El
.Sh SEE ALSO
+.Xr fdt 4 ,
.Xr gpio 4 ,
.Xr gpioled 4 ,
.Xr iic 4 ,
Modified: head/share/man/man4/gpioled.4
==============================================================================
--- head/share/man/man4/gpioled.4 Thu Feb 13 17:08:29 2014 (r261842)
+++ head/share/man/man4/gpioled.4 Thu Feb 13 17:58:52 2014 (r261843)
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd November 5, 2013
+.Dd February 13, 2014
.Dt GPIOLED 4
.Os
.Sh NAME
@@ -68,7 +68,75 @@ Which pin on the GPIO interface to map t
Please note that this mask should only ever have one bit set
(any others bits - i.e., pins - will be ignored).
.El
+.Pp
+On a
+.Xr FDT 4
+based system, like
+.Li ARM , the dts part for a
+.Nm gpioled
+device usually looks like:
+.Bd -literal
+gpio: gpio {
+
+ gpio-controller;
+ ...
+
+ led0 {
+ compatible = "gpioled";
+ gpios = <&gpio 16 2 0>; /* GPIO pin 16. */
+ name = "ok";
+ };
+
+ led1 {
+ compatible = "gpioled";
+ gpios = <&gpio 17 2 0>; /* GPIO pin 17. */
+ name = "user-led1";
+ };
+};
+.Ed
+.Pp
+And optionally, you can choose combine all the leds under a single
+.Dq gpio-leds
+compatible node:
+.Bd -literal
+simplebus0 {
+
+ ...
+
+ leds {
+ compatible = "gpio-leds";
+
+ led0 {
+ gpios = <&gpio 16 2 0>;
+ name = "ok"
+ };
+
+ led1 {
+ gpios = <&gpio 17 2 0>;
+ name = "user-led1"
+ };
+ };
+};
+.Ed
+.Pp
+Both methods are equally supported and it is possible to have the leds
+defined with any sort of mix between the methods.
+The only restriction is that a GPIO pin cannot be mapped by two different
+(gpio)leds.
+.Pp
+For more details about the
+.Va gpios
+property, please consult
+.Pa /usr/src/sys/boot/fdt/dts/bindings-gpio.txt .
+.Pp
+The property
+.Va name
+is the arbitrary name of device in
+.Pa /dev/led/
+to create for
+.Xr led 4 .
.Sh SEE ALSO
+.Xr fdt 4 ,
.Xr gpio 4 ,
.Xr led 4 ,
.Xr gpioiic 4
Modified: head/sys/dev/gpio/gpioiic.c
==============================================================================
--- head/sys/dev/gpio/gpioiic.c Thu Feb 13 17:08:29 2014 (r261842)
+++ head/sys/dev/gpio/gpioiic.c Thu Feb 13 17:58:52 2014 (r261843)
@@ -28,6 +28,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_platform.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
@@ -38,6 +40,12 @@ __FBSDID("$FreeBSD$");
#include <sys/gpio.h>
#include "gpiobus_if.h"
+#ifdef FDT
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/fdt/fdt_common.h>
+#endif
+
#include <dev/iicbus/iiconf.h>
#include <dev/iicbus/iicbus.h>
@@ -71,6 +79,10 @@ static int
gpioiic_probe(device_t dev)
{
+#ifdef FDT
+ if (!ofw_bus_is_compatible(dev, "gpioiic"))
+ return (ENXIO);
+#endif
device_set_desc(dev, "GPIO I2C bit-banging driver");
return (0);
@@ -81,6 +93,10 @@ gpioiic_attach(device_t dev)
{
struct gpioiic_softc *sc = device_get_softc(dev);
device_t bitbang;
+#ifdef FDT
+ phandle_t node;
+ pcell_t pin;
+#endif
sc->sc_dev = dev;
sc->sc_busdev = device_get_parent(dev);
@@ -91,6 +107,15 @@ gpioiic_attach(device_t dev)
device_get_unit(dev), "sda", &sc->sda_pin))
sc->sda_pin = SDA_PIN_DEFAULT;
+#ifdef FDT
+ if ((node = ofw_bus_get_node(dev)) == -1)
+ return (ENXIO);
+ if (OF_getencprop(node, "scl", &pin, sizeof(pin)) > 0)
+ sc->scl_pin = (int)pin;
+ if (OF_getencprop(node, "sda", &pin, sizeof(pin)) > 0)
+ sc->sda_pin = (int)pin;
+#endif
+
/* add generic bit-banging code */
bitbang = device_add_child(dev, "iicbb", -1);
device_probe_and_attach(bitbang);
@@ -209,6 +234,16 @@ gpioiic_reset(device_t dev, u_char speed
return (IIC_ENOADDR);
}
+#ifdef FDT
+static phandle_t
+gpioiic_get_node(device_t bus, device_t dev)
+{
+
+ /* We only have one child, the iicbb, which needs our own node. */
+ return (ofw_bus_get_node(bus));
+}
+#endif
+
static devclass_t gpioiic_devclass;
static device_method_t gpioiic_methods[] = {
@@ -225,6 +260,11 @@ static device_method_t gpioiic_methods[]
DEVMETHOD(iicbb_getscl, gpioiic_getscl),
DEVMETHOD(iicbb_reset, gpioiic_reset),
+#ifdef FDT
+ /* OFW bus interface */
+ DEVMETHOD(ofw_bus_get_node, gpioiic_get_node),
+#endif
+
{ 0, 0 }
};
Modified: head/sys/dev/gpio/gpioled.c
==============================================================================
--- head/sys/dev/gpio/gpioled.c Thu Feb 13 17:08:29 2014 (r261842)
+++ head/sys/dev/gpio/gpioled.c Thu Feb 13 17:58:52 2014 (r261843)
@@ -27,6 +27,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_platform.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bio.h>
@@ -39,6 +41,12 @@ __FBSDID("$FreeBSD$");
#include <sys/module.h>
#include <sys/mutex.h>
+#ifdef FDT
+#include <dev/fdt/fdt_common.h>
+#include <dev/gpio/gpiobusvar.h>
+#include <dev/ofw/ofw_bus.h>
+#endif
+
#include <dev/led/led.h>
#include <sys/gpio.h>
#include "gpiobus_if.h"
@@ -84,10 +92,65 @@ gpioled_control(void *priv, int onoff)
GPIOLED_UNLOCK(sc);
}
+#ifdef FDT
+static void
+gpioled_identify(driver_t *driver, device_t bus)
+{
+ phandle_t child, leds, root;
+
+ root = OF_finddevice("/");
+ if (root == 0)
+ return;
+ leds = fdt_find_compatible(root, "gpio-leds", 1);
+ if (leds == 0)
+ return;
+
+ /* Traverse the 'gpio-leds' node and add its children. */
+ for (child = OF_child(leds); child != 0; child = OF_peer(child))
+ if (ofw_gpiobus_add_fdt_child(bus, child) == NULL)
+ continue;
+}
+#endif
+
static int
gpioled_probe(device_t dev)
{
+#ifdef FDT
+ int match;
+ phandle_t node;
+ char *compat;
+
+ /*
+ * We can match against our own node compatible string and also against
+ * our parent node compatible string. The first is normally used to
+ * describe leds on a gpiobus and the later when there is a common node
+ * compatible with 'gpio-leds' which is used to concentrate all the
+ * leds nodes on the dts.
+ */
+ match = 0;
+ if (ofw_bus_is_compatible(dev, "gpioled"))
+ match = 1;
+
+ if (match == 0) {
+ if ((node = ofw_bus_get_node(dev)) == -1)
+ return (ENXIO);
+ if ((node = OF_parent(node)) == -1)
+ return (ENXIO);
+ if (OF_getprop_alloc(node, "compatible", 1,
+ (void **)&compat) == -1)
+ return (ENXIO);
+
+ if (strcasecmp(compat, "gpio-leds") == 0)
+ match = 1;
+
+ free(compat, M_OFWPROP);
+ }
+
+ if (match == 0)
+ return (ENXIO);
+#endif
device_set_desc(dev, "GPIO led");
+
return (0);
}
@@ -95,18 +158,35 @@ static int
gpioled_attach(device_t dev)
{
struct gpioled_softc *sc;
+#ifdef FDT
+ phandle_t node;
+ char *name;
+#else
const char *name;
+#endif
sc = device_get_softc(dev);
sc->sc_dev = dev;
sc->sc_busdev = device_get_parent(dev);
GPIOLED_LOCK_INIT(sc);
+#ifdef FDT
+ name = NULL;
+ if ((node = ofw_bus_get_node(dev)) == -1)
+ return (ENXIO);
+ if (OF_getprop_alloc(node, "label", 1, (void **)&name) == -1)
+ OF_getprop_alloc(node, "name", 1, (void **)&name);
+#else
if (resource_string_value(device_get_name(dev),
device_get_unit(dev), "name", &name))
name = NULL;
+#endif
sc->sc_leddev = led_create(gpioled_control, sc, name ? name :
device_get_nameunit(dev));
+#ifdef FDT
+ if (name != NULL)
+ free(name, M_OFWPROP);
+#endif
return (0);
}
@@ -129,6 +209,9 @@ static devclass_t gpioled_devclass;
static device_method_t gpioled_methods[] = {
/* Device interface */
+#ifdef FDT
+ DEVMETHOD(device_identify, gpioled_identify),
+#endif
DEVMETHOD(device_probe, gpioled_probe),
DEVMETHOD(device_attach, gpioled_attach),
DEVMETHOD(device_detach, gpioled_detach),
More information about the svn-src-all
mailing list