svn commit: r333031 - in head/sys: arm/mv dts dts/arm

Marcin Wojtas mw at FreeBSD.org
Thu Apr 26 19:00:50 UTC 2018


Author: mw
Date: Thu Apr 26 19:00:48 2018
New Revision: 333031
URL: https://svnweb.freebsd.org/changeset/base/333031

Log:
  Update mv_gpio driver to new FreeBSD API
  
  This patch implements and exports functions described
  in gpio_if.m file. It also uses new gpiobus_attach_bus function
  instead of adding gpioc and gpiobus as children. It removes
  ulgy reading SoC ID and related if..else, so it depends only on
  data read from FDT.
  
  Submitted by: Patryk Duda <pdk at semihalf.com>
  Reviewed by: manu
  Obtained from: Semihalf
  Sponsored by: Stormshield
  Differential Revision: https://reviews.freebsd.org/D14756

Modified:
  head/sys/arm/mv/gpio.c
  head/sys/dts/arm/db78100.dts
  head/sys/dts/arm/db88f5182.dts
  head/sys/dts/arm/db88f5281.dts
  head/sys/dts/arm/db88f6281.dts
  head/sys/dts/arm/dockstar.dts
  head/sys/dts/arm/sheevaplug.dts
  head/sys/dts/bindings-gpio.txt

Modified: head/sys/arm/mv/gpio.c
==============================================================================
--- head/sys/arm/mv/gpio.c	Thu Apr 26 19:00:35 2018	(r333030)
+++ head/sys/arm/mv/gpio.c	Thu Apr 26 19:00:48 2018	(r333031)
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
 #include <machine/bus.h>
 #include <machine/intr.h>
 
+#include <dev/gpio/gpiobusvar.h>
 #include <dev/fdt/fdt_common.h>
 #include <dev/ofw/ofw_bus.h>
 #include <dev/ofw/ofw_bus_subr.h>
@@ -58,8 +59,15 @@ __FBSDID("$FreeBSD$");
 #include <arm/mv/mvvar.h>
 #include <arm/mv/mvreg.h>
 
+#include "gpio_if.h"
+
 #define GPIO_MAX_INTR_COUNT	8
 #define GPIO_PINS_PER_REG	32
+#define GPIO_GENERIC_CAP	(GPIO_PIN_INPUT | GPIO_PIN_OUTPUT |		\
+				GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL |	\
+				GPIO_PIN_TRISTATE | GPIO_PIN_PULLUP |		\
+				GPIO_PIN_PULLDOWN | GPIO_PIN_INVIN |		\
+				GPIO_PIN_INVOUT)
 
 #define DEBOUNCE_CHECK_MS	1
 #define DEBOUNCE_LO_HI_MS	2
@@ -67,6 +75,7 @@ __FBSDID("$FreeBSD$");
 #define DEBOUNCE_CHECK_TICKS	((hz / 1000) * DEBOUNCE_CHECK_MS)
 
 struct mv_gpio_softc {
+	device_t		sc_busdev;
 	struct resource	*	mem_res;
 	int			mem_rid;
 	struct resource	*	irq_res[GPIO_MAX_INTR_COUNT];
@@ -134,6 +143,19 @@ int mv_gpio_configure(device_t, uint32_t, uint32_t, ui
 void mv_gpio_out(device_t, uint32_t, uint8_t, uint8_t);
 uint8_t mv_gpio_in(device_t, uint32_t);
 
+/*
+ * GPIO interface
+ */
+static device_t mv_gpio_get_bus(device_t);
+static int mv_gpio_pin_max(device_t, int *);
+static int mv_gpio_pin_getcaps(device_t, uint32_t, uint32_t *);
+static int mv_gpio_pin_getflags(device_t, uint32_t, uint32_t *);
+static int mv_gpio_pin_getname(device_t, uint32_t, char *);
+static int mv_gpio_pin_setflags(device_t, uint32_t, uint32_t);
+static int mv_gpio_pin_set(device_t, uint32_t, unsigned int);
+static int mv_gpio_pin_get(device_t, uint32_t, unsigned int *);
+static int mv_gpio_pin_toggle(device_t, uint32_t);
+
 #define MV_GPIO_LOCK()		mtx_lock_spin(&sc->mutex)
 #define MV_GPIO_UNLOCK()	mtx_unlock_spin(&sc->mutex)
 #define MV_GPIO_ASSERT_LOCKED()	mtx_assert(&sc->mutex, MA_OWNED)
@@ -141,7 +163,19 @@ uint8_t mv_gpio_in(device_t, uint32_t);
 static device_method_t mv_gpio_methods[] = {
 	DEVMETHOD(device_probe,		mv_gpio_probe),
 	DEVMETHOD(device_attach,	mv_gpio_attach),
-	{ 0, 0 }
+
+	/* GPIO protocol */
+	DEVMETHOD(gpio_get_bus,		mv_gpio_get_bus),
+	DEVMETHOD(gpio_pin_max,		mv_gpio_pin_max),
+	DEVMETHOD(gpio_pin_getname,	mv_gpio_pin_getname),
+	DEVMETHOD(gpio_pin_getflags,	mv_gpio_pin_getflags),
+	DEVMETHOD(gpio_pin_getcaps,	mv_gpio_pin_getcaps),
+	DEVMETHOD(gpio_pin_setflags,	mv_gpio_pin_setflags),
+	DEVMETHOD(gpio_pin_get,		mv_gpio_pin_get),
+	DEVMETHOD(gpio_pin_set,		mv_gpio_pin_set),
+	DEVMETHOD(gpio_pin_toggle,	mv_gpio_pin_toggle),
+
+	DEVMETHOD_END
 };
 
 static driver_t mv_gpio_driver = {
@@ -152,31 +186,23 @@ static driver_t mv_gpio_driver = {
 
 static devclass_t mv_gpio_devclass;
 
-DRIVER_MODULE(gpio, simplebus, mv_gpio_driver, mv_gpio_devclass, 0, 0);
+DRIVER_MODULE(mv_gpio, simplebus, mv_gpio_driver, mv_gpio_devclass, 0, 0);
 
-typedef int (*gpios_phandler_t)(device_t, phandle_t, pcell_t *, int);
-
-struct gpio_ctrl_entry {
-	const char		*compat;
-	gpios_phandler_t	handler;
-};
-
 static int mv_handle_gpios_prop(device_t, phandle_t, pcell_t *, int);
-int gpio_get_config_from_dt(void);
 
-struct gpio_ctrl_entry gpio_controllers[] = {
-	{ "mrvl,gpio", &mv_handle_gpios_prop },
-	{ NULL, NULL }
+struct ofw_compat_data gpio_controllers[] = {
+	{ "mrvl,gpio", (uintptr_t)&mv_handle_gpios_prop },
+	{ "marvell,orion-gpio", (uintptr_t)&mv_handle_gpios_prop },
+	{ NULL, 0 }
 };
 
 static int
 mv_gpio_probe(device_t dev)
 {
-
 	if (!ofw_bus_status_okay(dev))
 		return (ENXIO);
 
-	if (!ofw_bus_is_compatible(dev, "mrvl,gpio"))
+	if (ofw_bus_search_compatible(dev, gpio_controllers)->ocd_data == 0)
 		return (ENXIO);
 
 	device_set_desc(dev, "Marvell Integrated GPIO Controller");
@@ -188,7 +214,6 @@ mv_gpio_attach(device_t dev)
 {
 	int error, i, size;
 	struct mv_gpio_softc *sc;
-	uint32_t dev_id, rev_id;
 	pcell_t pincnt = 0;
 	pcell_t irq_cells = 0;
 	phandle_t iparent;
@@ -197,34 +222,22 @@ mv_gpio_attach(device_t dev)
 	if (sc == NULL)
 		return (ENXIO);
 
-	/* Get chip id and revision */
-	soc_id(&dev_id, &rev_id);
-
-	if (dev_id == MV_DEV_88F5182 ||
-	    dev_id == MV_DEV_88F5281 ||
-	    dev_id == MV_DEV_MV78100 ||
-	    dev_id == MV_DEV_MV78100_Z0 ) {
-		sc->pin_num = 32;
-		sc->irq_num = 4;
-
-	} else if (dev_id == MV_DEV_88F6281 ||
-	    dev_id == MV_DEV_88F6282) {
-		sc->pin_num = 50;
-		sc->irq_num = 7;
-
-	} else {
-		if (OF_getencprop(ofw_bus_get_node(dev), "pin-count", &pincnt,
-		    sizeof(pcell_t)) >= 0 ||
-		    OF_getencprop(ofw_bus_get_node(dev), "ngpios", &pincnt,
-		    sizeof(pcell_t)) >= 0) {
-			sc->pin_num = pincnt;
+	if (OF_getencprop(ofw_bus_get_node(dev), "pin-count", &pincnt,
+	    sizeof(pcell_t)) >= 0 ||
+	    OF_getencprop(ofw_bus_get_node(dev), "ngpios", &pincnt,
+	    sizeof(pcell_t)) >= 0) {
+		sc->pin_num = MIN(pincnt, MV_GPIO_MAX_NPINS);
+		if (bootverbose)
 			device_printf(dev, "%d pins available\n", sc->pin_num);
-		} else {
-			device_printf(dev, "ERROR: no pin-count entry found!\n");
-			return (ENXIO);
-		}
+	} else {
+		device_printf(dev, "ERROR: no pin-count or ngpios entry found!\n");
+		return (ENXIO);
 	}
 
+	/* Assign generic capabilities to every gpio pin */
+	for(i = 0; i < sc->pin_num; i++)
+		sc->gpio_setup[i].gp_caps = GPIO_GENERIC_CAP;
+
 	/* Find root interrupt controller */
 	iparent = ofw_bus_find_iparent(ofw_bus_get_node(dev));
 	if (iparent == 0) {
@@ -315,8 +328,13 @@ mv_gpio_attach(device_t dev)
 	/* Clear interrupt status. */
 	bus_space_write_4(sc->bst, sc->bsh, GPIO_INT_CAUSE, 0);
 
-	device_add_child(dev, "gpioc", device_get_unit(dev));
-	device_add_child(dev, "gpiobus", device_get_unit(dev));
+	sc->sc_busdev = gpiobus_attach_bus(dev);
+	if (sc->sc_busdev == NULL) {
+		mtx_destroy(&sc->mutex);
+		bus_release_resource(dev, SYS_RES_IRQ,
+			sc->irq_rid[i], sc->irq_res[i]);
+		return (ENXIO);
+	}
 
 	return (0);
 }
@@ -535,6 +553,16 @@ mv_gpio_configure(device_t dev, uint32_t pin, uint32_t
 
 	MV_GPIO_LOCK();
 
+	if ((mask & flags) & GPIO_PIN_INPUT)
+		mv_gpio_out_en(dev, pin, 0);
+	if ((mask & flags) & GPIO_PIN_OUTPUT) {
+		if ((flags & mask) & GPIO_PIN_OPENDRAIN)
+			mv_gpio_value_set(dev, pin, 0);
+		else
+			mv_gpio_value_set(dev, pin, 1);
+		mv_gpio_out_en(dev, pin, 1);
+	}
+
 	if (mask & MV_GPIO_OUT_BLINK)
 		mv_gpio_blink(dev, pin, flags & MV_GPIO_OUT_BLINK);
 	if (mask & MV_GPIO_IN_POL_LOW)
@@ -799,7 +827,7 @@ mv_gpio_in(device_t dev, uint32_t pin)
 	struct mv_gpio_softc *sc;
 	sc = (struct mv_gpio_softc *)device_get_softc(dev);
 
-	MV_GPIO_LOCK();
+	MV_GPIO_ASSERT_LOCKED();
 
 	if (sc->gpio_setup[pin].gp_flags & MV_GPIO_IN_DEBOUNCE) {
 		if (sc->gpio_setup[pin].gp_flags & MV_GPIO_IN_POL_LOW)
@@ -814,7 +842,6 @@ mv_gpio_in(device_t dev, uint32_t pin)
 	} else
 		state = (mv_gpio_value_get(dev, pin, 0) ? 1 : 0);
 
-
 	return (state);
 }
 
@@ -997,6 +1024,8 @@ mv_gpio_value_set(device_t dev, uint32_t pin, uint8_t 
 	struct mv_gpio_softc *sc;
 	sc = (struct mv_gpio_softc *)device_get_softc(dev);
 
+	MV_GPIO_ASSERT_LOCKED();
+
 	if (pin >= sc->pin_num)
 		return;
 
@@ -1013,9 +1042,8 @@ mv_handle_gpios_prop(device_t dev, phandle_t ctrl, pce
 {
 	pcell_t gpio_cells, pincnt;
 	int inc, t, tuples, tuple_size;
-	int dir, flags, pin;
+	int flags, pin;
 	u_long gpio_ctrl, size;
-	struct mv_gpio_softc sc;
 
 	pincnt = 0;
 	if (!OF_hasprop(ctrl, "gpio-controller"))
@@ -1024,7 +1052,7 @@ mv_handle_gpios_prop(device_t dev, phandle_t ctrl, pce
 
 	if (OF_getencprop(ctrl, "#gpio-cells", &gpio_cells, sizeof(pcell_t)) < 0)
 		return (ENXIO);
-	if (gpio_cells != 3)
+	if (gpio_cells != 2)
 		return (ENXIO);
 
 	tuple_size = gpio_cells * sizeof(pcell_t) + sizeof(phandle_t);
@@ -1033,10 +1061,6 @@ mv_handle_gpios_prop(device_t dev, phandle_t ctrl, pce
 	if (fdt_regsize(ctrl, &gpio_ctrl, &size))
 		return (ENXIO);
 
-	if (OF_getencprop(ctrl, "pin-count", &pincnt, sizeof(pcell_t)) < 0)
-		return (ENXIO);
-	sc.pin_num = pincnt;
-
 	/*
 	 * Skip controller reference, since controller's phandle is given
 	 * explicitly (in a function argument).
@@ -1046,22 +1070,9 @@ mv_handle_gpios_prop(device_t dev, phandle_t ctrl, pce
 
 	for (t = 0; t < tuples; t++) {
 		pin = gpios[0];
-		dir = gpios[1];
-		flags = gpios[2];
+		flags = gpios[1];
 
 		mv_gpio_configure(dev, pin, flags, ~0);
-
-		if (dir == 1)
-			/* Input. */
-			mv_gpio_out_en(dev, pin, 0);
-		else {
-			/* Output. */
-			if (flags & MV_GPIO_OUT_OPEN_DRAIN)
-				mv_gpio_out(dev, pin, 0, 1);
-
-			if (flags & MV_GPIO_OUT_OPEN_SRC)
-				mv_gpio_out(dev, pin, 1, 1);
-		}
 		gpios += gpio_cells + inc;
 	}
 
@@ -1075,12 +1086,13 @@ mv_gpio_init(device_t dev)
 {
 	phandle_t child, parent, root, ctrl;
 	pcell_t gpios[MAX_PINS_PER_NODE * GPIOS_PROP_CELLS];
-	struct gpio_ctrl_entry *e;
+	struct ofw_compat_data *e;
 	int len, rv;
 
 	root = OF_finddevice("/");
 	len = 0;
 	parent = root;
+	rv = 0;
 
 	/* Traverse through entire tree to find nodes with 'gpios' prop */
 	for (child = OF_child(parent); child != 0; child = OF_peer(child)) {
@@ -1098,30 +1110,175 @@ mv_gpio_init(device_t dev)
 			/* Get 'gpios' property. */
 			OF_getencprop(child, "gpios", gpios, len);
 
-			e = (struct gpio_ctrl_entry *)&gpio_controllers;
+			/*
+			 * First cell of 'gpios' property should
+			 * contain a ref. to a node defining GPIO
+			 * controller.
+			 */
+			ctrl = OF_node_from_xref(gpios[0]);
 
+			if(ctrl != ofw_bus_get_node(dev)) {
+				/* Not this gpio controller */
+				device_printf(dev, "Not this gpio controller ctrl: %x, dev: %x\n",
+					 ctrl, ofw_bus_get_node(dev));
+				continue;
+			}
+
+			e = gpio_controllers;
+
 			/* Find and call a handler. */
-			for (; e->compat; e++) {
-				/*
-				 * First cell of 'gpios' property should
-				 * contain a ref. to a node defining GPIO
-				 * controller.
-				 */
-				ctrl = OF_node_from_xref(gpios[0]);
+			for (; e->ocd_str; e++) {
 
-				if (ofw_bus_node_is_compatible(ctrl, e->compat))
+				if (ofw_bus_node_is_compatible(ctrl,e->ocd_str)) {
 					/* Call a handler. */
-					if ((rv = e->handler(dev, ctrl,
-					    (pcell_t *)&gpios, len)))
-						return (rv);
+					rv |= mv_handle_gpios_prop(dev, ctrl,
+					    (pcell_t *)&gpios, len);
+				}
 			}
 		}
 
-		if (OF_peer(child) == 0) {
+		while (OF_peer(child) == 0 && parent != root) {
 			/* No more siblings. */
 			child = parent;
 			parent = OF_parent(child);
 		}
 	}
+	return (rv);
+}
+
+static int
+mv_gpio_pin_max(device_t dev, int *maxpin)
+{
+	struct mv_gpio_softc *sc;
+	if (maxpin == NULL)
+		return (EINVAL);
+
+	sc = device_get_softc(dev);
+	*maxpin = sc->pin_num;
+
 	return (0);
+}
+
+static int
+mv_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
+{
+	struct mv_gpio_softc *sc = device_get_softc(dev);
+	if (caps == NULL)
+		return (EINVAL);
+
+	if (pin >= sc->pin_num)
+		return (EINVAL);
+
+	MV_GPIO_LOCK();
+	*caps = sc->gpio_setup[pin].gp_caps;
+	MV_GPIO_UNLOCK();
+
+	return (0);
+}
+
+static int
+mv_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
+{
+	struct mv_gpio_softc *sc = device_get_softc(dev);
+	if (flags == NULL)
+		return (EINVAL);
+
+	if (pin >= sc->pin_num)
+		return (EINVAL);
+
+	MV_GPIO_LOCK();
+	*flags = sc->gpio_setup[pin].gp_flags;
+	MV_GPIO_UNLOCK();
+
+	return (0);
+}
+
+static int
+mv_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
+{
+	struct mv_gpio_softc *sc = device_get_softc(dev);
+	if (name == NULL)
+		return (EINVAL);
+
+	if (pin >= sc->pin_num)
+		return (EINVAL);
+
+	MV_GPIO_LOCK();
+	memcpy(name, sc->gpio_setup[pin].gp_name, GPIOMAXNAME);
+	MV_GPIO_UNLOCK();
+
+	return (0);
+}
+
+static int
+mv_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
+{
+	int ret;
+	struct mv_gpio_softc *sc = device_get_softc(dev);
+	if (pin >= sc->pin_num)
+		return (EINVAL);
+
+	/* Check for unwanted flags. */
+	if ((flags & sc->gpio_setup[pin].gp_caps) != flags)
+		return (EINVAL);
+
+	ret = mv_gpio_configure(dev, pin, flags, ~0);
+
+	return (ret);
+}
+
+static int
+mv_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
+{
+	struct mv_gpio_softc *sc = device_get_softc(dev);
+	if (pin >= sc->pin_num)
+		return (EINVAL);
+
+	MV_GPIO_LOCK();
+	mv_gpio_value_set(dev, pin, value);
+	MV_GPIO_UNLOCK();
+
+	return (0);
+}
+
+static int
+mv_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *value)
+{
+	struct mv_gpio_softc *sc = device_get_softc(dev);
+	if (value == NULL)
+		return (EINVAL);
+
+	if (pin >= sc->pin_num)
+		return (EINVAL);
+
+	MV_GPIO_LOCK();
+	*value = mv_gpio_in(dev, pin);
+	MV_GPIO_UNLOCK();
+
+	return (0);
+}
+
+static int
+mv_gpio_pin_toggle(device_t dev, uint32_t pin)
+{
+	struct mv_gpio_softc *sc = device_get_softc(dev);
+	uint32_t value;
+	if (pin >= sc->pin_num)
+		return (EINVAL);
+
+	MV_GPIO_LOCK();
+	value = mv_gpio_in(dev, pin);
+	value = (~value) & 1;
+	mv_gpio_value_set(dev, pin, value);
+	MV_GPIO_UNLOCK();
+
+	return (0);
+}
+
+static device_t
+mv_gpio_get_bus(device_t dev)
+{
+	struct mv_gpio_softc *sc = device_get_softc(dev);
+
+	return (sc->sc_busdev);
 }

Modified: head/sys/dts/arm/db78100.dts
==============================================================================
--- head/sys/dts/arm/db78100.dts	Thu Apr 26 19:00:35 2018	(r333030)
+++ head/sys/dts/arm/db78100.dts	Thu Apr 26 19:00:48 2018	(r333031)
@@ -165,7 +165,7 @@
 		};
 
 		GPIO: gpio at 10100 {
-			#gpio-cells = <3>;
+			#gpio-cells = <2>;
 			compatible = "mrvl,gpio";
 			reg = <0x10100 0x20>;
 			gpio-controller;

Modified: head/sys/dts/arm/db88f5182.dts
==============================================================================
--- head/sys/dts/arm/db88f5182.dts	Thu Apr 26 19:00:35 2018	(r333030)
+++ head/sys/dts/arm/db88f5182.dts	Thu Apr 26 19:00:48 2018	(r333031)
@@ -152,7 +152,7 @@
 		};
 
 		GPIO: gpio at 10100 {
-			#gpio-cells = <3>;
+			#gpio-cells = <2>;
 			compatible = "mrvl,gpio";
 			reg = <0x10100 0x20>;
 			gpio-controller;

Modified: head/sys/dts/arm/db88f5281.dts
==============================================================================
--- head/sys/dts/arm/db88f5281.dts	Thu Apr 26 19:00:35 2018	(r333030)
+++ head/sys/dts/arm/db88f5281.dts	Thu Apr 26 19:00:48 2018	(r333031)
@@ -152,7 +152,7 @@
 		};
 
 		GPIO: gpio at 10100 {
-			#gpio-cells = <3>;
+			#gpio-cells = <2>;
 			compatible = "mrvl,gpio";
 			reg = <0x10100 0x20>;
 			gpio-controller;

Modified: head/sys/dts/arm/db88f6281.dts
==============================================================================
--- head/sys/dts/arm/db88f6281.dts	Thu Apr 26 19:00:35 2018	(r333030)
+++ head/sys/dts/arm/db88f6281.dts	Thu Apr 26 19:00:48 2018	(r333031)
@@ -156,7 +156,7 @@
 		};
 
 		GPIO: gpio at 10100 {
-			#gpio-cells = <3>;
+			#gpio-cells = <2>;
 			compatible = "mrvl,gpio";
 			reg = <0x10100 0x20>;
 			gpio-controller;

Modified: head/sys/dts/arm/dockstar.dts
==============================================================================
--- head/sys/dts/arm/dockstar.dts	Thu Apr 26 19:00:35 2018	(r333030)
+++ head/sys/dts/arm/dockstar.dts	Thu Apr 26 19:00:48 2018	(r333031)
@@ -141,7 +141,7 @@
 		};
 
 		GPIO: gpio at 10100 {
-			#gpio-cells = <3>;
+			#gpio-cells = <2>;
 			compatible = "mrvl,gpio";
 			reg = <0x10100 0x20>;
 			gpio-controller;

Modified: head/sys/dts/arm/sheevaplug.dts
==============================================================================
--- head/sys/dts/arm/sheevaplug.dts	Thu Apr 26 19:00:35 2018	(r333030)
+++ head/sys/dts/arm/sheevaplug.dts	Thu Apr 26 19:00:48 2018	(r333031)
@@ -153,7 +153,7 @@
 		};
 
 		GPIO: gpio at 10100 {
-			#gpio-cells = <3>;
+			#gpio-cells = <2>;
 			compatible = "mrvl,gpio";
 			reg = <0x10100 0x20>;
 			gpio-controller;

Modified: head/sys/dts/bindings-gpio.txt
==============================================================================
--- head/sys/dts/bindings-gpio.txt	Thu Apr 26 19:00:35 2018	(r333030)
+++ head/sys/dts/bindings-gpio.txt	Thu Apr 26 19:00:48 2018	(r333031)
@@ -65,37 +65,42 @@ Description:	The gpios property of a device node defin
 		information like pin number, direction and various flags.
 
 Example:
-		gpios = <&GPIO 0 1 0		/* GPIO[0]:  IN,  NONE */
-			 &GPIO 1 2 0>;		/* GPIO[1]:  OUT, NONE */
+		gpios = <&GPIO 0 1		/* GPIO[0]:  FLAGS */
+			 &GPIO 1 2>;		/* GPIO[1]:  FLAGS */
 
 
-3. "mrvl,gpio" controller GPIO specifier
+3. GPIO controller specifier
 
 	<phandle pin dir flags>
 
 
 pin:	0-MAX				GPIO pin number.
 
-dir:
-	1		IN		Input direction.
-	2		OUT		Output direction.
-
 flags:
-	0x0000----	IN_NONE
-	0x0001----	IN_POL_LOW	Polarity low (active-low).
-	0x0002----	IN_IRQ_EDGE	Interrupt, edge triggered.
-	0x0004----	IN_IRQ_LEVEL	Interrupt, level triggered.
-	
-	0x----0000	OUT_NONE
-	0x----0001	OUT_BLINK	Blink on the pin.
-	0x----0002	OUT_OPEN_DRAIN	Open drain output line.
-	0x----0004	OUT_OPEN_SRC	Open source output line.
+	Available flags are listed in sys/conf.h. Following combination
+	can be supported by the controller. For details please refer
+	to controller's GPIO reference manual.
 
+	GPIO_PIN_INPUT		0x0001	Input direction
+	GPIO_PIN_OUTPUT		0x0002	Output direction
+	GPIO_PIN_OPENDRAIN	0x0004	Open-drain output
+	GPIO_PIN_OPENSOURCE	0x0008	Open-source output
+	GPIO_PIN_PUSHPULL	0x0010	Push-pull output
+	GPIO_PIN_TRISTATE	0x0020	Output disabled
+	GPIO_PIN_PULLUP		0x0040	Internal pull-up enabled
+	GPIO_PIN_PULLDOWN	0x0080	Internal pull-down enabled
+	GPIO_PIN_INVIN		0x0100	Invert input
+	GPIO_PIN_INVOUT		0x0200	Invert output
+	GPIO_PIN_PULSATE	0x0400	Pulsate in hardware
+	GPIO_PIN_IRQ_POL_EDG	0x0800	IRQ active single edge
+	GPIO_PIN_IRQ_POL_DBL	0x1000	IRQ active double edge
+	GPIO_PIN_IRQ_POL_LVL	0x2000	IRQ active level
+	GPIO_PIN_IRQ_DEBOUNCE	0x4000	Debounce on IRQ pin
 
 Example:
-	gpios = <&GPIO 0  1 0x00000000		/* GPIO[0]:   IN */
-		 &GPIO 1  2 0x00000000		/* GPIO[1]:   OUT */
-		 &GPIO 2  1 0x00020000		/* GPIO[2]:   IN, IRQ (edge) */
-		 &GPIO 3  1 0x00040000		/* GPIO[3]:   IN, IRQ (level) */
+	gpios = <&GPIO 0  0x00000001	/* GPIO[0]:   IN */
+		 &GPIO 1  0x00000002	/* GPIO[1]:   OUT */
+		 &GPIO 2  0x00000801	/* GPIO[2]:   IN, IRQ (edge) */
+		 &GPIO 3  0x00004001	/* GPIO[3]:   IN, IRQ (level) */
 		 ...
-		 &GPIO 10 2 0x00000001>;	/* GPIO[10]:  OUT, blink */
+		 &GPIO 10 0x00000401>;	/* GPIO[10]:  OUT, blink */


More information about the svn-src-all mailing list