Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/arm/sunxi Fix support for Allwinner-specific pin bi...



details:   https://anonhg.NetBSD.org/src/rev/6973e98eb7d2
branches:  trunk
changeset: 999285:6973e98eb7d2
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Mon May 27 23:26:20 2019 +0000

description:
Fix support for Allwinner-specific pin bindings and add support for pink bank regulators

diffstat:

 sys/arch/arm/sunxi/sunxi_gpio.c |  79 ++++++++++++++++++++++++++++++++++++++--
 1 files changed, 75 insertions(+), 4 deletions(-)

diffs (156 lines):

diff -r bff606437bbc -r 6973e98eb7d2 sys/arch/arm/sunxi/sunxi_gpio.c
--- a/sys/arch/arm/sunxi/sunxi_gpio.c   Mon May 27 23:18:33 2019 +0000
+++ b/sys/arch/arm/sunxi/sunxi_gpio.c   Mon May 27 23:26:20 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: sunxi_gpio.c,v 1.23 2019/01/26 14:38:30 thorpej Exp $ */
+/* $NetBSD: sunxi_gpio.c,v 1.24 2019/05/27 23:26:20 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2017 Jared McNeill <jmcneill%invisible.ca@localhost>
@@ -29,7 +29,7 @@
 #include "opt_soc.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sunxi_gpio.c,v 1.23 2019/01/26 14:38:30 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sunxi_gpio.c,v 1.24 2019/05/27 23:26:20 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -50,6 +50,8 @@
 #define        SUNXI_GPIO_MAX_EINT_BANK        5
 #define        SUNXI_GPIO_MAX_EINT             32
 
+#define        SUNXI_GPIO_MAX_BANK             26
+
 #define        SUNXI_GPIO_PORT(port)           (0x24 * (port))
 #define SUNXI_GPIO_CFG(port, pin)      (SUNXI_GPIO_PORT(port) + 0x00 + (0x4 * ((pin) / 8)))
 #define  SUNXI_GPIO_CFG_PINMASK(pin)   (0x7 << (((pin) % 8) * 4))
@@ -70,6 +72,8 @@
 #define          SUNXI_GPIO_INT_MODE_DOUBLE_EDGE       0x4
 #define        SUNXI_GPIO_INT_CTL(bank)        (0x210 + 0x20 * (bank))
 #define        SUNXI_GPIO_INT_STATUS(bank)     (0x214 + 0x20 * (bank))
+#define        SUNXI_GPIO_GRP_CONFIG(bank)     (0x300 + 0x4 * (bank))
+#define         SUNXI_GPIO_GRP_IO_BIAS_CONFIGMASK      0xf
 
 static const struct of_compat_data compat_data[] = {
 #ifdef SOC_SUN4I_A10
@@ -125,6 +129,7 @@
        device_t sc_dev;
        bus_space_tag_t sc_bst;
        bus_space_handle_t sc_bsh;
+       int sc_phandle;
        const struct sunxi_gpio_padconf *sc_padconf;
        kmutex_t sc_lock;
 
@@ -132,6 +137,8 @@
        gpio_pin_t *sc_pins;
        device_t sc_gpiodev;
 
+       struct fdtbus_regulator *sc_pin_supply[SUNXI_GPIO_MAX_BANK];
+
        u_int sc_eint_bank_max;
 
        void *sc_ih;
@@ -602,7 +609,7 @@
        len = OF_getproplen(phandle, "allwinner,pins");
        if (len > 0) {
                *pins_len = len;
-               return fdtbus_get_string(phandle, "allwinner,pins");
+               return fdtbus_get_prop(phandle, "allwinner,pins", pins_len);
        }
 
        return NULL;
@@ -650,6 +657,64 @@
        return -1;
 }
 
+static void
+sunxi_pinctrl_enable_regulator(struct sunxi_gpio_softc *sc,
+    const struct sunxi_gpio_pins *pin_def)
+{
+       char supply_prop[16];
+       uint32_t val;
+       u_int uvol;
+       int error;
+
+       const char c = tolower(pin_def->name[1]);
+       if (c < 'a' || c > 'z')
+               return;
+       const int index = c - 'a';
+
+       if (sc->sc_pin_supply[index] != NULL) {
+               /* Already enabled */
+               return;
+       }
+
+       snprintf(supply_prop, sizeof(supply_prop), "vcc-p%c-supply", c);
+       sc->sc_pin_supply[index] = fdtbus_regulator_acquire(sc->sc_phandle, supply_prop);
+       if (sc->sc_pin_supply[index] == NULL)
+               return;
+
+       aprint_debug_dev(sc->sc_dev, "enable \"%s\"\n", supply_prop);
+       error = fdtbus_regulator_enable(sc->sc_pin_supply[index]);
+       if (error != 0)
+               aprint_error_dev(sc->sc_dev, "failed to enable %s: %d\n", supply_prop, error);
+
+       if (sc->sc_padconf->has_io_bias_config) {
+               error = fdtbus_regulator_get_voltage(sc->sc_pin_supply[index], &uvol);
+               if (error != 0) {
+                       aprint_error_dev(sc->sc_dev, "failed to get %s voltage: %d\n",
+                           supply_prop, error);
+                       uvol = 0;
+               }
+               if (uvol != 0) {
+                       if (uvol <= 1800000)
+                               val = 0x0;      /* 1.8V */
+                       else if (uvol <= 2500000)
+                               val = 0x6;      /* 2.5V */
+                       else if (uvol <= 2800000)
+                               val = 0x9;      /* 2.8V */
+                       else if (uvol <= 3000000)
+                               val = 0xa;      /* 3.0V */
+                       else
+                               val = 0xd;      /* 3.3V */
+
+                       aprint_debug_dev(sc->sc_dev, "set io bias config for port %d to 0x%x\n",
+                           pin_def->port, val);
+                       val = GPIO_READ(sc, SUNXI_GPIO_GRP_CONFIG(pin_def->port));
+                       val &= ~SUNXI_GPIO_GRP_IO_BIAS_CONFIGMASK;
+                       val |= __SHIFTIN(val, SUNXI_GPIO_GRP_IO_BIAS_CONFIGMASK);
+                       GPIO_WRITE(sc, SUNXI_GPIO_GRP_CONFIG(pin_def->port), val);
+               }
+       }
+}
+
 static int
 sunxi_pinctrl_set_config(device_t dev, const void *data, size_t len)
 {
@@ -694,6 +759,8 @@
 
                if (drive_strength != -1)
                        sunxi_gpio_setdrv(sc, pin_def, drive_strength);
+
+               sunxi_pinctrl_enable_regulator(sc, pin_def);
        }
 
        mutex_exit(&sc->sc_lock);
@@ -833,6 +900,7 @@
                }
 
        sc->sc_dev = self;
+       sc->sc_phandle = phandle;
        sc->sc_bst = faa->faa_bst;
        if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
                aprint_error(": couldn't map registers\n");
@@ -847,7 +915,10 @@
        fdtbus_register_gpio_controller(self, phandle, &sunxi_gpio_funcs);
 
        for (child = OF_child(phandle); child; child = OF_peer(child)) {
-               if (!of_hasprop(child, "function") || !of_hasprop(child, "pins"))
+               bool is_valid =
+                   (of_hasprop(child, "function") && of_hasprop(child, "pins")) ||
+                   (of_hasprop(child, "allwinner,function") && of_hasprop(child, "allwinner,pins"));
+               if (!is_valid)
                        continue;
                fdtbus_register_pinctrl_config(self, child, &sunxi_pinctrl_funcs);
        }



Home | Main Index | Thread Index | Old Index