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