summaryrefslogtreecommitdiffstats
path: root/sys/dev/gpio/gpioiic.c
diff options
context:
space:
mode:
authorloos <loos@FreeBSD.org>2014-02-13 17:58:52 +0000
committerloos <loos@FreeBSD.org>2014-02-13 17:58:52 +0000
commit4969f2c1cac596d80cba8e9f98f3be2f87a8c639 (patch)
treefbcaee70b7518ece1d94e6c256911369f0bcbcbd /sys/dev/gpio/gpioiic.c
parent03c3f2092682aca3cb1c101cb3ee84621f5447f0 (diff)
downloadFreeBSD-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.c40
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 }
};
OpenPOWER on IntegriCloud