diff options
author | loos <loos@FreeBSD.org> | 2014-02-13 17:58:52 +0000 |
---|---|---|
committer | loos <loos@FreeBSD.org> | 2014-02-13 17:58:52 +0000 |
commit | 4969f2c1cac596d80cba8e9f98f3be2f87a8c639 (patch) | |
tree | fbcaee70b7518ece1d94e6c256911369f0bcbcbd /sys/dev/gpio/gpioiic.c | |
parent | 03c3f2092682aca3cb1c101cb3ee84621f5447f0 (diff) | |
download | FreeBSD-src-4969f2c1cac596d80cba8e9f98f3be2f87a8c639.zip FreeBSD-src-4969f2c1cac596d80cba8e9f98f3be2f87a8c639.tar.gz |
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)
Diffstat (limited to 'sys/dev/gpio/gpioiic.c')
-rw-r--r-- | sys/dev/gpio/gpioiic.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/sys/dev/gpio/gpioiic.c b/sys/dev/gpio/gpioiic.c index 37af21c..d7772b6 100644 --- a/sys/dev/gpio/gpioiic.c +++ b/sys/dev/gpio/gpioiic.c @@ -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, u_char addr, u_char *oldaddr) 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 } }; |