So the Linux developers decided to change the bindings for the sunxi
pinctrl devices.  You know, it's supposed to a stable ABI...

This diff updates the sxipio(4) driver to support the new binding in
addition to the old binding.  There is a subtle change in that it now
leaves the current configuration of pull up/down and drive strength
alone if there is no explicit configuration information.  The Linux
driver code is pretty incomprehensible, but I think that's what we're
supposed to do.

Tested on my Banana Pi with a dtb generated from the current Linux
sources.  The pin configurations change a bit, but all the changes
make sense if I compare the old and the new dtb.

ok?


Index: sxipio.c
===================================================================
RCS file: /cvs/src/sys/dev/fdt/sxipio.c,v
retrieving revision 1.1
diff -u -p -r1.1 sxipio.c
--- sxipio.c    21 Jan 2017 08:26:49 -0000      1.1
+++ sxipio.c    1 May 2017 20:48:50 -0000
@@ -206,6 +206,36 @@ sxipio_attach(struct device *parent, str
        printf(": %d pins\n", sc->sc_npins);
 }
 
+int
+sxipio_drive(int node)
+{
+       int drive;
+
+       drive = OF_getpropint(node, "allwinner,drive", -1);
+       if (drive >= 0)
+               return drive;
+       drive = OF_getpropint(node, "drive-strength", 0) - 10;
+       if (drive >= 0)
+               return (drive / 10);
+       return -1;
+}
+
+int
+sxipio_pull(int node)
+{
+       int pull;
+
+       pull = OF_getpropint(node, "allwinner,pull", -1);
+       if (pull >= 0)
+               return pull;
+       if (OF_getproplen(node, "bias-disable") == 0)
+               return 0;
+       if (OF_getproplen(node, "bias-pull-up") == 0)
+               return 1;
+       if (OF_getproplen(node, "bias-pull-down") == 0)
+               return 2;
+       return -1;
+}
 
 int
 sxipio_pinctrl(uint32_t phandle, void *cookie)
@@ -213,7 +243,7 @@ sxipio_pinctrl(uint32_t phandle, void *c
        struct sxipio_softc *sc = cookie;
        char func[32];
        char *names, *name;
-       int port, pin, off;
+       int port, pin, off, mask;
        int mux, drive, pull;
        int node;
        int len;
@@ -225,18 +255,25 @@ sxipio_pinctrl(uint32_t phandle, void *c
                return -1;
 
        len = OF_getprop(node, "allwinner,function", func, sizeof(func));
-       if (len <= 0 || len >= sizeof(func))
-               return -1;
+       if (len <= 0 || len >= sizeof(func)) {
+               len = OF_getprop(node, "function", func, sizeof(func));
+               if (len <= 0 || len >= sizeof(func))
+                       return -1;
+       }
 
        len = OF_getproplen(node, "allwinner,pins");
-       if (len <= 0)
-               return -1;
+       if (len <= 0) {
+               len = OF_getproplen(node, "pins");
+               if (len <= 0)
+                       return -1;
+       }
 
        names = malloc(len, M_TEMP, M_WAITOK);
-       OF_getprop(node, "allwinner,pins", names, len);
+       if (OF_getprop(node, "allwinner,pins", names, len) <= 0)
+               OF_getprop(node, "pins", names, len);
 
-       drive = OF_getpropint(node, "allwinner,drive", 0);
-       pull = OF_getpropint(node, "allwinner,pull", 0);
+       drive = sxipio_drive(node);
+       pull = sxipio_pull(node);
 
        name = names;
        while (len > 0) {
@@ -261,11 +298,13 @@ sxipio_pinctrl(uint32_t phandle, void *c
                mux = sc->sc_pins[i].funcs[j].mux;
 
                s = splhigh();
-               off = (pin & 0x7) << 2;
-               SXICMS4(sc, SXIPIO_CFG(port, pin), 0x7 << off, mux << off);
-               off = (pin & 0xf) << 1;
-               SXICMS4(sc, SXIPIO_DRV(port, pin), 0x3 << off, drive << off);
-               SXICMS4(sc, SXIPIO_PUL(port, pin), 0x3 << off, pull << off);
+               off = (pin & 0x7) << 2, mask = (0x7 << off);
+               SXICMS4(sc, SXIPIO_CFG(port, pin), mask, mux << off);
+               off = (pin & 0xf) << 1, mask = (0x3 << off);
+               if (drive >= 0 && drive < 4)
+                       SXICMS4(sc, SXIPIO_DRV(port, pin), mask, drive << off);
+               if (pull >= 0 && pull < 3)
+                       SXICMS4(sc, SXIPIO_PUL(port, pin), mask, pull << off);
                splx(s);
 
                len -= strlen(name) + 1;

Reply via email to