summaryrefslogtreecommitdiffstats
path: root/sys/arm/at91/at91_pinctrl.c
diff options
context:
space:
mode:
authorian <ian@FreeBSD.org>2014-09-13 19:59:16 +0000
committerian <ian@FreeBSD.org>2014-09-13 19:59:16 +0000
commit5f75e2409e764d364e8f9bda5f5ff7c6bd30358e (patch)
treecbb4da663394948b7786e6bacd9aae6bf17f6456 /sys/arm/at91/at91_pinctrl.c
parent16f9b5fe6559a389e5d49e1a29b8cd8d887d1542 (diff)
downloadFreeBSD-src-5f75e2409e764d364e8f9bda5f5ff7c6bd30358e.zip
FreeBSD-src-5f75e2409e764d364e8f9bda5f5ff7c6bd30358e.tar.gz
Convert the at91_pinctrl driver to use the new fdt_pinctrl interface.
Diffstat (limited to 'sys/arm/at91/at91_pinctrl.c')
-rw-r--r--sys/arm/at91/at91_pinctrl.c135
1 files changed, 57 insertions, 78 deletions
diff --git a/sys/arm/at91/at91_pinctrl.c b/sys/arm/at91/at91_pinctrl.c
index 31140da..7a90f0f 100644
--- a/sys/arm/at91/at91_pinctrl.c
+++ b/sys/arm/at91/at91_pinctrl.c
@@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
#include <arm/at91/at91_piovar.h>
#include <dev/fdt/fdt_common.h>
+#include <dev/fdt/fdt_pinctrl.h>
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
@@ -250,6 +251,8 @@ at91_pinctrl_attach(device_t dev)
device_set_ivars(cdev, di);
}
+ fdt_pinctrl_register(dev, "atmel,pins");
+
return (bus_generic_attach(dev));
}
@@ -370,93 +373,70 @@ pinctrl_print_child(device_t bus, device_t child)
const char *periphs[] = {"gpio", "periph A", "periph B", "periph C", "periph D", "periph E" };
-static void
-pinctrl_walk_tree(device_t bus, phandle_t node)
+struct pincfg {
+ uint32_t unit;
+ uint32_t pin;
+ uint32_t periph;
+ uint32_t flags;
+};
+
+static int
+pinctrl_configure_pins(device_t bus, phandle_t cfgxref)
{
struct pinctrl_softc *sc;
- char status[10];
+ struct pincfg *cfg, *cfgdata;
char name[32];
- phandle_t pinctrl[32], pins[32 * 4], scratch;
- ssize_t len, npins;
- int i, j;
+ phandle_t node;
+ ssize_t npins;
+ int i;
sc = device_get_softc(bus);
- for (node = OF_child(node); node > 0; node = OF_peer(node)) {
- pinctrl_walk_tree(bus, node);
- memset(status, 0, sizeof(status));
- memset(name, 0, sizeof(name));
- OF_getprop(node, "status", status, sizeof(status));
- OF_getprop(node, "name", name, sizeof(name));
- if (strcmp(status, "okay") != 0) {
-// printf("pinctrl: skipping node %s status %s\n", name,
-// status);
- continue;
- }
- len = OF_getencprop(node, "pinctrl-0", pinctrl, sizeof(pinctrl));
- if (len <= 0) {
-// printf("pinctrl: skipping node %s no pinctrl-0\n",
-// name, status);
- continue;
- }
- len /= sizeof(phandle_t);
- printf("pinctrl: Found active node %s\n", name);
- for (i = 0; i < len; i++) {
- scratch = OF_node_from_xref(pinctrl[i]);
- npins = OF_getencprop(scratch, "atmel,pins", pins,
- sizeof(pins));
- if (npins <= 0) {
- printf("We're doing it wrong %s\n", name);
- continue;
- }
- memset(name, 0, sizeof(name));
- OF_getprop(scratch, "name", name, sizeof(name));
- npins /= (4 * 4);
- printf("----> need to cope with %d more pins for %s\n",
- npins, name);
- for (j = 0; j < npins; j++) {
- uint32_t unit = pins[j * 4];
- uint32_t pin = pins[j * 4 + 1];
- uint32_t periph = pins[j * 4 + 2];
- uint32_t flags = pins[j * 4 + 3];
- uint32_t pio;
-
- pio = (0xfffffff & sc->ranges[0].bus) +
- 0x200 * unit;
- printf("P%c%d %s %#x\n", unit + 'A', pin,
- periphs[periph], flags);
- switch (periph) {
- case 0:
- at91_pio_use_gpio(pio, 1u << pin);
- at91_pio_gpio_pullup(pio, 1u << pin,
- !!(flags & 1));
- at91_pio_gpio_high_z(pio, 1u << pin,
- !!(flags & 2));
- at91_pio_gpio_set_deglitch(pio,
- 1u << pin, !!(flags & 4));
-// at91_pio_gpio_pulldown(pio, 1u << pin,
-// !!(flags & 8));
-// at91_pio_gpio_dis_schmidt(pio,
-// 1u << pin, !!(flags & 16));
- break;
- case 1:
- at91_pio_use_periph_a(pio, 1u << pin,
- flags);
- break;
- case 2:
- at91_pio_use_periph_b(pio, 1u << pin,
- flags);
- break;
- }
- }
+ node = OF_node_from_xref(cfgxref);
+ memset(name, 0, sizeof(name));
+ OF_getprop(node, "name", name, sizeof(name));
+ npins = OF_getencprop_alloc(node, "atmel,pins", sizeof(*cfgdata),
+ (void **)&cfgdata);
+ if (npins < 0) {
+ printf("We're doing it wrong %s\n", name);
+ return (ENXIO);
+ }
+ if (npins == 0)
+ return (0);
+ for (i = 0, cfg = cfgdata; i < npins; i++, cfg++) {
+ uint32_t pio;
+ pio = (0xfffffff & sc->ranges[0].bus) + 0x200 * cfg->unit;
+ printf("P%c%d %s %#x\n", cfg->unit + 'A', cfg->pin,
+ periphs[cfg->periph], cfg->flags);
+ switch (cfg->periph) {
+ case 0:
+ at91_pio_use_gpio(pio, 1u << cfg->pin);
+ at91_pio_gpio_pullup(pio, 1u << cfg->pin,
+ !!(cfg->flags & 1));
+ at91_pio_gpio_high_z(pio, 1u << cfg->pin,
+ !!(cfg->flags & 2));
+ at91_pio_gpio_set_deglitch(pio,
+ 1u << cfg->pin, !!(cfg->flags & 4));
+// at91_pio_gpio_pulldown(pio, 1u << cfg->pin,
+// !!(cfg->flags & 8));
+// at91_pio_gpio_dis_schmidt(pio,
+// 1u << cfg->pin, !!(cfg->flags & 16));
+ break;
+ case 1:
+ at91_pio_use_periph_a(pio, 1u << cfg->pin, cfg->flags);
+ break;
+ case 2:
+ at91_pio_use_periph_b(pio, 1u << cfg->pin, cfg->flags);
+ break;
}
}
+ free(cfgdata, M_OFWPROP);
+ return (0);
}
static void
pinctrl_new_pass(device_t bus)
{
struct pinctrl_softc *sc;
- phandle_t node;
sc = device_get_softc(bus);
@@ -466,10 +446,7 @@ pinctrl_new_pass(device_t bus)
return;
sc->done_pinmux++;
- node = OF_peer(0);
- if (node == -1)
- return;
- pinctrl_walk_tree(bus, node);
+ fdt_pinctrl_configure_tree(bus);
}
static device_method_t at91_pinctrl_methods[] = {
@@ -496,6 +473,8 @@ static device_method_t at91_pinctrl_methods[] = {
DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node),
DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type),
+ /* fdt_pintrl interface */
+ DEVMETHOD(fdt_pinctrl_configure,pinctrl_configure_pins),
DEVMETHOD_END
};
OpenPOWER on IntegriCloud