Home | History | Annotate | Line # | Download | only in sunxi
sunxi_gpio.c revision 1.24
      1 /* $NetBSD: sunxi_gpio.c,v 1.24 2019/05/27 23:26:20 jmcneill Exp $ */
      2 
      3 /*-
      4  * Copyright (c) 2017 Jared McNeill <jmcneill (at) invisible.ca>
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  * SUCH DAMAGE.
     27  */
     28 
     29 #include "opt_soc.h"
     30 
     31 #include <sys/cdefs.h>
     32 __KERNEL_RCSID(0, "$NetBSD: sunxi_gpio.c,v 1.24 2019/05/27 23:26:20 jmcneill Exp $");
     33 
     34 #include <sys/param.h>
     35 #include <sys/bus.h>
     36 #include <sys/device.h>
     37 #include <sys/intr.h>
     38 #include <sys/systm.h>
     39 #include <sys/mutex.h>
     40 #include <sys/kmem.h>
     41 #include <sys/gpio.h>
     42 #include <sys/bitops.h>
     43 #include <sys/lwp.h>
     44 
     45 #include <dev/fdt/fdtvar.h>
     46 #include <dev/gpio/gpiovar.h>
     47 
     48 #include <arm/sunxi/sunxi_gpio.h>
     49 
     50 #define	SUNXI_GPIO_MAX_EINT_BANK	5
     51 #define	SUNXI_GPIO_MAX_EINT		32
     52 
     53 #define	SUNXI_GPIO_MAX_BANK		26
     54 
     55 #define	SUNXI_GPIO_PORT(port)		(0x24 * (port))
     56 #define SUNXI_GPIO_CFG(port, pin)	(SUNXI_GPIO_PORT(port) + 0x00 + (0x4 * ((pin) / 8)))
     57 #define  SUNXI_GPIO_CFG_PINMASK(pin)	(0x7 << (((pin) % 8) * 4))
     58 #define	SUNXI_GPIO_DATA(port)		(SUNXI_GPIO_PORT(port) + 0x10)
     59 #define	SUNXI_GPIO_DRV(port, pin)	(SUNXI_GPIO_PORT(port) + 0x14 + (0x4 * ((pin) / 16)))
     60 #define  SUNXI_GPIO_DRV_PINMASK(pin)	(0x3 << (((pin) % 16) * 2))
     61 #define	SUNXI_GPIO_PULL(port, pin)	(SUNXI_GPIO_PORT(port) + 0x1c + (0x4 * ((pin) / 16)))
     62 #define	 SUNXI_GPIO_PULL_DISABLE	0
     63 #define	 SUNXI_GPIO_PULL_UP		1
     64 #define	 SUNXI_GPIO_PULL_DOWN		2
     65 #define  SUNXI_GPIO_PULL_PINMASK(pin)	(0x3 << (((pin) % 16) * 2))
     66 #define	SUNXI_GPIO_INT_CFG(bank, eint)	(0x200 + (0x20 * (bank)) + (0x4 * ((eint) / 8)))
     67 #define	 SUNXI_GPIO_INT_MODEMASK(eint)	(0xf << (((eint) % 8) * 4))
     68 #define	  SUNXI_GPIO_INT_MODE_POS_EDGE		0x0
     69 #define	  SUNXI_GPIO_INT_MODE_NEG_EDGE		0x1
     70 #define	  SUNXI_GPIO_INT_MODE_HIGH_LEVEL	0x2
     71 #define	  SUNXI_GPIO_INT_MODE_LOW_LEVEL		0x3
     72 #define	  SUNXI_GPIO_INT_MODE_DOUBLE_EDGE	0x4
     73 #define	SUNXI_GPIO_INT_CTL(bank)	(0x210 + 0x20 * (bank))
     74 #define	SUNXI_GPIO_INT_STATUS(bank)	(0x214 + 0x20 * (bank))
     75 #define	SUNXI_GPIO_GRP_CONFIG(bank)	(0x300 + 0x4 * (bank))
     76 #define	 SUNXI_GPIO_GRP_IO_BIAS_CONFIGMASK	0xf
     77 
     78 static const struct of_compat_data compat_data[] = {
     79 #ifdef SOC_SUN4I_A10
     80 	{ "allwinner,sun4i-a10-pinctrl",	(uintptr_t)&sun4i_a10_padconf },
     81 #endif
     82 #ifdef SOC_SUN5I_A13
     83 	{ "allwinner,sun5i-a13-pinctrl",	(uintptr_t)&sun5i_a13_padconf },
     84 	{ "nextthing,gr8-pinctrl",		(uintptr_t)&sun5i_a13_padconf },
     85 #endif
     86 #ifdef SOC_SUN6I_A31
     87 	{ "allwinner,sun6i-a31-pinctrl",	(uintptr_t)&sun6i_a31_padconf },
     88 	{ "allwinner,sun6i-a31-r-pinctrl",	(uintptr_t)&sun6i_a31_r_padconf },
     89 #endif
     90 #ifdef SOC_SUN7I_A20
     91 	{ "allwinner,sun7i-a20-pinctrl",	(uintptr_t)&sun7i_a20_padconf },
     92 #endif
     93 #ifdef SOC_SUN8I_A83T
     94 	{ "allwinner,sun8i-a83t-pinctrl",	(uintptr_t)&sun8i_a83t_padconf },
     95 	{ "allwinner,sun8i-a83t-r-pinctrl",	(uintptr_t)&sun8i_a83t_r_padconf },
     96 #endif
     97 #ifdef SOC_SUN8I_H3
     98 	{ "allwinner,sun8i-h3-pinctrl",		(uintptr_t)&sun8i_h3_padconf },
     99 	{ "allwinner,sun8i-h3-r-pinctrl",	(uintptr_t)&sun8i_h3_r_padconf },
    100 #endif
    101 #ifdef SOC_SUN9I_A80
    102 	{ "allwinner,sun9i-a80-pinctrl",	(uintptr_t)&sun9i_a80_padconf },
    103 	{ "allwinner,sun9i-a80-r-pinctrl",	(uintptr_t)&sun9i_a80_r_padconf },
    104 #endif
    105 #ifdef SOC_SUN50I_A64
    106 	{ "allwinner,sun50i-a64-pinctrl",	(uintptr_t)&sun50i_a64_padconf },
    107 	{ "allwinner,sun50i-a64-r-pinctrl",	(uintptr_t)&sun50i_a64_r_padconf },
    108 #endif
    109 #ifdef SOC_SUN50I_H5
    110 	{ "allwinner,sun50i-h5-pinctrl",	(uintptr_t)&sun8i_h3_padconf },
    111 	{ "allwinner,sun50i-h5-r-pinctrl",	(uintptr_t)&sun8i_h3_r_padconf },
    112 #endif
    113 #ifdef SOC_SUN50I_H6
    114 	{ "allwinner,sun50i-h6-pinctrl",	(uintptr_t)&sun50i_h6_padconf },
    115 	{ "allwinner,sun50i-h6-r-pinctrl",	(uintptr_t)&sun50i_h6_r_padconf },
    116 #endif
    117 	{ NULL }
    118 };
    119 
    120 struct sunxi_gpio_eint {
    121 	int (*eint_func)(void *);
    122 	void *eint_arg;
    123 	int eint_flags;
    124 	int eint_bank;
    125 	int eint_num;
    126 };
    127 
    128 struct sunxi_gpio_softc {
    129 	device_t sc_dev;
    130 	bus_space_tag_t sc_bst;
    131 	bus_space_handle_t sc_bsh;
    132 	int sc_phandle;
    133 	const struct sunxi_gpio_padconf *sc_padconf;
    134 	kmutex_t sc_lock;
    135 
    136 	struct gpio_chipset_tag sc_gp;
    137 	gpio_pin_t *sc_pins;
    138 	device_t sc_gpiodev;
    139 
    140 	struct fdtbus_regulator *sc_pin_supply[SUNXI_GPIO_MAX_BANK];
    141 
    142 	u_int sc_eint_bank_max;
    143 
    144 	void *sc_ih;
    145 	struct sunxi_gpio_eint sc_eint[SUNXI_GPIO_MAX_EINT_BANK][SUNXI_GPIO_MAX_EINT];
    146 };
    147 
    148 struct sunxi_gpio_pin {
    149 	struct sunxi_gpio_softc *pin_sc;
    150 	const struct sunxi_gpio_pins *pin_def;
    151 	int pin_flags;
    152 	bool pin_actlo;
    153 };
    154 
    155 #define GPIO_READ(sc, reg) 		\
    156     bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
    157 #define GPIO_WRITE(sc, reg, val) 	\
    158     bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
    159 
    160 static int	sunxi_gpio_match(device_t, cfdata_t, void *);
    161 static void	sunxi_gpio_attach(device_t, device_t, void *);
    162 
    163 CFATTACH_DECL_NEW(sunxi_gpio, sizeof(struct sunxi_gpio_softc),
    164 	sunxi_gpio_match, sunxi_gpio_attach, NULL, NULL);
    165 
    166 static const struct sunxi_gpio_pins *
    167 sunxi_gpio_lookup(struct sunxi_gpio_softc *sc, uint8_t port, uint8_t pin)
    168 {
    169 	const struct sunxi_gpio_pins *pin_def;
    170 	u_int n;
    171 
    172 	for (n = 0; n < sc->sc_padconf->npins; n++) {
    173 		pin_def = &sc->sc_padconf->pins[n];
    174 		if (pin_def->port == port && pin_def->pin == pin)
    175 			return pin_def;
    176 	}
    177 
    178 	return NULL;
    179 }
    180 
    181 static const struct sunxi_gpio_pins *
    182 sunxi_gpio_lookup_byname(struct sunxi_gpio_softc *sc, const char *name)
    183 {
    184 	const struct sunxi_gpio_pins *pin_def;
    185 	u_int n;
    186 
    187 	for (n = 0; n < sc->sc_padconf->npins; n++) {
    188 		pin_def = &sc->sc_padconf->pins[n];
    189 		if (strcmp(pin_def->name, name) == 0)
    190 			return pin_def;
    191 	}
    192 
    193 	return NULL;
    194 }
    195 
    196 static int
    197 sunxi_gpio_setfunc(struct sunxi_gpio_softc *sc,
    198     const struct sunxi_gpio_pins *pin_def, const char *func)
    199 {
    200 	uint32_t cfg;
    201 	u_int n;
    202 
    203 	KASSERT(mutex_owned(&sc->sc_lock));
    204 
    205 	const bus_size_t cfg_reg = SUNXI_GPIO_CFG(pin_def->port, pin_def->pin);
    206 	const uint32_t cfg_mask = SUNXI_GPIO_CFG_PINMASK(pin_def->pin);
    207 
    208 	for (n = 0; n < SUNXI_GPIO_MAXFUNC; n++) {
    209 		if (pin_def->functions[n] == NULL)
    210 			continue;
    211 		if (strcmp(pin_def->functions[n], func) == 0) {
    212 			cfg = GPIO_READ(sc, cfg_reg);
    213 			cfg &= ~cfg_mask;
    214 			cfg |= __SHIFTIN(n, cfg_mask);
    215 #ifdef SUNXI_GPIO_DEBUG
    216 			device_printf(sc->sc_dev, "P%c%02d cfg %08x -> %08x\n",
    217 			    pin_def->port + 'A', pin_def->pin, GPIO_READ(sc, cfg_reg), cfg);
    218 #endif
    219 			GPIO_WRITE(sc, cfg_reg, cfg);
    220 			return 0;
    221 		}
    222 	}
    223 
    224 	/* Function not found */
    225 	device_printf(sc->sc_dev, "function '%s' not supported on P%c%02d\n",
    226 	    func, pin_def->port + 'A', pin_def->pin);
    227 
    228 	return ENXIO;
    229 }
    230 
    231 static int
    232 sunxi_gpio_setpull(struct sunxi_gpio_softc *sc,
    233     const struct sunxi_gpio_pins *pin_def, int flags)
    234 {
    235 	uint32_t pull;
    236 
    237 	KASSERT(mutex_owned(&sc->sc_lock));
    238 
    239 	const bus_size_t pull_reg = SUNXI_GPIO_PULL(pin_def->port, pin_def->pin);
    240 	const uint32_t pull_mask = SUNXI_GPIO_PULL_PINMASK(pin_def->pin);
    241 
    242 	pull = GPIO_READ(sc, pull_reg);
    243 	pull &= ~pull_mask;
    244 	if (flags & GPIO_PIN_PULLUP)
    245 		pull |= __SHIFTIN(SUNXI_GPIO_PULL_UP, pull_mask);
    246 	else if (flags & GPIO_PIN_PULLDOWN)
    247 		pull |= __SHIFTIN(SUNXI_GPIO_PULL_DOWN, pull_mask);
    248 	else
    249 		pull |= __SHIFTIN(SUNXI_GPIO_PULL_DISABLE, pull_mask);
    250 #ifdef SUNXI_GPIO_DEBUG
    251 	device_printf(sc->sc_dev, "P%c%02d pull %08x -> %08x\n",
    252 	    pin_def->port + 'A', pin_def->pin, GPIO_READ(sc, pull_reg), pull);
    253 #endif
    254 	GPIO_WRITE(sc, pull_reg, pull);
    255 
    256 	return 0;
    257 }
    258 
    259 static int
    260 sunxi_gpio_setdrv(struct sunxi_gpio_softc *sc,
    261     const struct sunxi_gpio_pins *pin_def, int drive_strength)
    262 {
    263 	uint32_t drv;
    264 
    265 	KASSERT(mutex_owned(&sc->sc_lock));
    266 
    267 	if (drive_strength < 10 || drive_strength > 40)
    268 		return EINVAL;
    269 
    270 	const bus_size_t drv_reg = SUNXI_GPIO_DRV(pin_def->port, pin_def->pin);
    271 	const uint32_t drv_mask = SUNXI_GPIO_DRV_PINMASK(pin_def->pin);
    272 
    273 	drv = GPIO_READ(sc, drv_reg);
    274 	drv &= ~drv_mask;
    275 	drv |= __SHIFTIN((drive_strength / 10) - 1, drv_mask);
    276 #ifdef SUNXI_GPIO_DEBUG
    277 	device_printf(sc->sc_dev, "P%c%02d drv %08x -> %08x\n",
    278 	    pin_def->port + 'A', pin_def->pin, GPIO_READ(sc, drv_reg), drv);
    279 #endif
    280 	GPIO_WRITE(sc, drv_reg, drv);
    281 
    282 	return 0;
    283 }
    284 
    285 static int
    286 sunxi_gpio_ctl(struct sunxi_gpio_softc *sc, const struct sunxi_gpio_pins *pin_def,
    287     int flags)
    288 {
    289 	KASSERT(mutex_owned(&sc->sc_lock));
    290 
    291 	if (flags & GPIO_PIN_INPUT)
    292 		return sunxi_gpio_setfunc(sc, pin_def, "gpio_in");
    293 	if (flags & GPIO_PIN_OUTPUT)
    294 		return sunxi_gpio_setfunc(sc, pin_def, "gpio_out");
    295 
    296 	return EINVAL;
    297 }
    298 
    299 static void *
    300 sunxi_gpio_acquire(device_t dev, const void *data, size_t len, int flags)
    301 {
    302 	struct sunxi_gpio_softc * const sc = device_private(dev);
    303 	const struct sunxi_gpio_pins *pin_def;
    304 	struct sunxi_gpio_pin *gpin;
    305 	const u_int *gpio = data;
    306 	int error;
    307 
    308 	if (len != 16)
    309 		return NULL;
    310 
    311 	const uint8_t port = be32toh(gpio[1]) & 0xff;
    312 	const uint8_t pin = be32toh(gpio[2]) & 0xff;
    313 	const bool actlo = be32toh(gpio[3]) & 1;
    314 
    315 	pin_def = sunxi_gpio_lookup(sc, port, pin);
    316 	if (pin_def == NULL)
    317 		return NULL;
    318 
    319 	mutex_enter(&sc->sc_lock);
    320 	error = sunxi_gpio_ctl(sc, pin_def, flags);
    321 	mutex_exit(&sc->sc_lock);
    322 
    323 	if (error != 0)
    324 		return NULL;
    325 
    326 	gpin = kmem_zalloc(sizeof(*gpin), KM_SLEEP);
    327 	gpin->pin_sc = sc;
    328 	gpin->pin_def = pin_def;
    329 	gpin->pin_flags = flags;
    330 	gpin->pin_actlo = actlo;
    331 
    332 	return gpin;
    333 }
    334 
    335 static void
    336 sunxi_gpio_release(device_t dev, void *priv)
    337 {
    338 	struct sunxi_gpio_softc * const sc = device_private(dev);
    339 	struct sunxi_gpio_pin *pin = priv;
    340 
    341 	mutex_enter(&sc->sc_lock);
    342 	sunxi_gpio_ctl(pin->pin_sc, pin->pin_def, GPIO_PIN_INPUT);
    343 	mutex_exit(&sc->sc_lock);
    344 
    345 	kmem_free(pin, sizeof(*pin));
    346 }
    347 
    348 static int
    349 sunxi_gpio_read(device_t dev, void *priv, bool raw)
    350 {
    351 	struct sunxi_gpio_softc * const sc = device_private(dev);
    352 	struct sunxi_gpio_pin *pin = priv;
    353 	const struct sunxi_gpio_pins *pin_def = pin->pin_def;
    354 	uint32_t data;
    355 	int val;
    356 
    357 	KASSERT(sc == pin->pin_sc);
    358 
    359 	const bus_size_t data_reg = SUNXI_GPIO_DATA(pin_def->port);
    360 	const uint32_t data_mask = __BIT(pin_def->pin);
    361 
    362 	/* No lock required for reads */
    363 	data = GPIO_READ(sc, data_reg);
    364 	val = __SHIFTOUT(data, data_mask);
    365 	if (!raw && pin->pin_actlo)
    366 		val = !val;
    367 
    368 #ifdef SUNXI_GPIO_DEBUG
    369 	device_printf(dev, "P%c%02d rd %08x (%d %d)\n",
    370 	    pin_def->port + 'A', pin_def->pin, data,
    371 	    __SHIFTOUT(val, data_mask), val);
    372 #endif
    373 
    374 	return val;
    375 }
    376 
    377 static void
    378 sunxi_gpio_write(device_t dev, void *priv, int val, bool raw)
    379 {
    380 	struct sunxi_gpio_softc * const sc = device_private(dev);
    381 	struct sunxi_gpio_pin *pin = priv;
    382 	const struct sunxi_gpio_pins *pin_def = pin->pin_def;
    383 	uint32_t data;
    384 
    385 	KASSERT(sc == pin->pin_sc);
    386 
    387 	const bus_size_t data_reg = SUNXI_GPIO_DATA(pin_def->port);
    388 	const uint32_t data_mask = __BIT(pin_def->pin);
    389 
    390 	if (!raw && pin->pin_actlo)
    391 		val = !val;
    392 
    393 	mutex_enter(&sc->sc_lock);
    394 	data = GPIO_READ(sc, data_reg);
    395 	data &= ~data_mask;
    396 	data |= __SHIFTIN(val, data_mask);
    397 #ifdef SUNXI_GPIO_DEBUG
    398 	device_printf(dev, "P%c%02d wr %08x -> %08x\n",
    399 	    pin_def->port + 'A', pin_def->pin, GPIO_READ(sc, data_reg), data);
    400 #endif
    401 	GPIO_WRITE(sc, data_reg, data);
    402 	mutex_exit(&sc->sc_lock);
    403 }
    404 
    405 static struct fdtbus_gpio_controller_func sunxi_gpio_funcs = {
    406 	.acquire = sunxi_gpio_acquire,
    407 	.release = sunxi_gpio_release,
    408 	.read = sunxi_gpio_read,
    409 	.write = sunxi_gpio_write,
    410 };
    411 
    412 static int
    413 sunxi_gpio_intr(void *priv)
    414 {
    415 	struct sunxi_gpio_softc * const sc = priv;
    416 	struct sunxi_gpio_eint *eint;
    417 	uint32_t status, bit;
    418 	u_int bank;
    419 	int ret = 0;
    420 
    421 	for (bank = 0; bank <= sc->sc_eint_bank_max; bank++) {
    422 		status = GPIO_READ(sc, SUNXI_GPIO_INT_STATUS(bank));
    423 		if (status == 0)
    424 			continue;
    425 		GPIO_WRITE(sc, SUNXI_GPIO_INT_STATUS(bank), status);
    426 
    427 		while ((bit = ffs32(status)) != 0) {
    428 			status &= ~__BIT(bit - 1);
    429 			eint = &sc->sc_eint[bank][bit - 1];
    430 			if (eint->eint_func == NULL)
    431 				continue;
    432 			const bool mpsafe = (eint->eint_flags & FDT_INTR_MPSAFE) != 0;
    433 			if (!mpsafe)
    434 				KERNEL_LOCK(1, curlwp);
    435 			ret |= eint->eint_func(eint->eint_arg);
    436 			if (!mpsafe)
    437 				KERNEL_UNLOCK_ONE(curlwp);
    438 		}
    439 	}
    440 
    441 	return ret;
    442 }
    443 
    444 static void *
    445 sunxi_gpio_establish(device_t dev, u_int *specifier, int ipl, int flags,
    446     int (*func)(void *), void *arg)
    447 {
    448 	struct sunxi_gpio_softc * const sc = device_private(dev);
    449 	const struct sunxi_gpio_pins *pin_def;
    450 	struct sunxi_gpio_eint *eint;
    451 	uint32_t val;
    452 	u_int mode;
    453 
    454 	if (ipl != IPL_VM) {
    455 		aprint_error_dev(dev, "%s: wrong IPL %d (expected %d)\n",
    456 		    __func__, ipl, IPL_VM);
    457 		return NULL;
    458 	}
    459 
    460 	/* 1st cell is the bank */
    461 	/* 2nd cell is the pin */
    462 	/* 3rd cell is flags */
    463 	const u_int port = be32toh(specifier[0]);
    464 	const u_int pin = be32toh(specifier[1]);
    465 	const u_int type = be32toh(specifier[2]) & 0xf;
    466 
    467 	switch (type) {
    468 	case FDT_INTR_TYPE_POS_EDGE:
    469 		mode = SUNXI_GPIO_INT_MODE_POS_EDGE;
    470 		break;
    471 	case FDT_INTR_TYPE_NEG_EDGE:
    472 		mode = SUNXI_GPIO_INT_MODE_NEG_EDGE;
    473 		break;
    474 	case FDT_INTR_TYPE_DOUBLE_EDGE:
    475 		mode = SUNXI_GPIO_INT_MODE_DOUBLE_EDGE;
    476 		break;
    477 	case FDT_INTR_TYPE_HIGH_LEVEL:
    478 		mode = SUNXI_GPIO_INT_MODE_HIGH_LEVEL;
    479 		break;
    480 	case FDT_INTR_TYPE_LOW_LEVEL:
    481 		mode = SUNXI_GPIO_INT_MODE_LOW_LEVEL;
    482 		break;
    483 	default:
    484 		aprint_error_dev(dev, "%s: unsupported irq type 0x%x\n",
    485 		    __func__, type);
    486 		return NULL;
    487 	}
    488 
    489 	pin_def = sunxi_gpio_lookup(sc, port, pin);
    490 	if (pin_def == NULL)
    491 		return NULL;
    492 	if (pin_def->functions[pin_def->eint_func] == NULL ||
    493 	    strcmp(pin_def->functions[pin_def->eint_func], "irq") != 0)
    494 		return NULL;
    495 
    496 	KASSERT(pin_def->eint_num < SUNXI_GPIO_MAX_EINT);
    497 
    498 	mutex_enter(&sc->sc_lock);
    499 
    500 	eint = &sc->sc_eint[pin_def->eint_bank][pin_def->eint_num];
    501 	if (eint->eint_func != NULL) {
    502 		mutex_exit(&sc->sc_lock);
    503 		return NULL;	/* in use */
    504 	}
    505 
    506 	/* Set function */
    507 	if (sunxi_gpio_setfunc(sc, pin_def, "irq") != 0) {
    508 		mutex_exit(&sc->sc_lock);
    509 		return NULL;
    510 	}
    511 
    512 	eint->eint_func = func;
    513 	eint->eint_arg = arg;
    514 	eint->eint_flags = flags;
    515 	eint->eint_bank = pin_def->eint_bank;
    516 	eint->eint_num = pin_def->eint_num;
    517 
    518 	/* Configure eint mode */
    519 	val = GPIO_READ(sc, SUNXI_GPIO_INT_CFG(eint->eint_bank, eint->eint_num));
    520 	val &= ~SUNXI_GPIO_INT_MODEMASK(eint->eint_num);
    521 	val |= __SHIFTIN(mode, SUNXI_GPIO_INT_MODEMASK(eint->eint_num));
    522 	GPIO_WRITE(sc, SUNXI_GPIO_INT_CFG(eint->eint_bank, eint->eint_num), val);
    523 
    524 	/* Enable eint */
    525 	val = GPIO_READ(sc, SUNXI_GPIO_INT_CTL(eint->eint_bank));
    526 	val |= __BIT(eint->eint_num);
    527 	GPIO_WRITE(sc, SUNXI_GPIO_INT_CTL(eint->eint_bank), val);
    528 
    529 	mutex_exit(&sc->sc_lock);
    530 
    531 	return eint;
    532 }
    533 
    534 static void
    535 sunxi_gpio_disestablish(device_t dev, void *ih)
    536 {
    537 	struct sunxi_gpio_softc * const sc = device_private(dev);
    538 	struct sunxi_gpio_eint * const eint = ih;
    539 	uint32_t val;
    540 
    541 	KASSERT(eint->eint_func != NULL);
    542 
    543 	mutex_enter(&sc->sc_lock);
    544 
    545 	/* Disable eint */
    546 	val = GPIO_READ(sc, SUNXI_GPIO_INT_CTL(eint->eint_bank));
    547 	val &= ~__BIT(eint->eint_num);
    548 	GPIO_WRITE(sc, SUNXI_GPIO_INT_CTL(eint->eint_bank), val);
    549 	GPIO_WRITE(sc, SUNXI_GPIO_INT_STATUS(eint->eint_bank), __BIT(eint->eint_num));
    550 
    551 	eint->eint_func = NULL;
    552 	eint->eint_arg = NULL;
    553 	eint->eint_flags = 0;
    554 
    555 	mutex_exit(&sc->sc_lock);
    556 }
    557 
    558 static bool
    559 sunxi_gpio_intrstr(device_t dev, u_int *specifier, char *buf, size_t buflen)
    560 {
    561 	struct sunxi_gpio_softc * const sc = device_private(dev);
    562 	const struct sunxi_gpio_pins *pin_def;
    563 
    564 	/* 1st cell is the bank */
    565 	/* 2nd cell is the pin */
    566 	/* 3rd cell is flags */
    567 	if (!specifier)
    568 		return false;
    569 	const u_int port = be32toh(specifier[0]);
    570 	const u_int pin = be32toh(specifier[1]);
    571 
    572 	pin_def = sunxi_gpio_lookup(sc, port, pin);
    573 	if (pin_def == NULL)
    574 		return false;
    575 
    576 	snprintf(buf, buflen, "GPIO %s", pin_def->name);
    577 
    578 	return true;
    579 }
    580 
    581 static struct fdtbus_interrupt_controller_func sunxi_gpio_intrfuncs = {
    582 	.establish = sunxi_gpio_establish,
    583 	.disestablish = sunxi_gpio_disestablish,
    584 	.intrstr = sunxi_gpio_intrstr,
    585 };
    586 
    587 static const char *
    588 sunxi_pinctrl_parse_function(int phandle)
    589 {
    590 	const char *function;
    591 
    592 	function = fdtbus_pinctrl_parse_function(phandle);
    593 	if (function != NULL)
    594 		return function;
    595 
    596 	return fdtbus_get_string(phandle, "allwinner,function");
    597 }
    598 
    599 static const char *
    600 sunxi_pinctrl_parse_pins(int phandle, int *pins_len)
    601 {
    602 	const char *pins;
    603 	int len;
    604 
    605 	pins = fdtbus_pinctrl_parse_pins(phandle, pins_len);
    606 	if (pins != NULL)
    607 		return pins;
    608 
    609 	len = OF_getproplen(phandle, "allwinner,pins");
    610 	if (len > 0) {
    611 		*pins_len = len;
    612 		return fdtbus_get_prop(phandle, "allwinner,pins", pins_len);
    613 	}
    614 
    615 	return NULL;
    616 }
    617 
    618 static int
    619 sunxi_pinctrl_parse_bias(int phandle)
    620 {
    621 	u_int pull;
    622 	int bias;
    623 
    624 	bias = fdtbus_pinctrl_parse_bias(phandle, NULL);
    625 	if (bias != -1)
    626 		return bias;
    627 
    628 	if (of_getprop_uint32(phandle, "allwinner,pull", &pull) == 0) {
    629 		switch (pull) {
    630 		case 0:
    631 			bias = 0;
    632 			break;
    633 		case 1:
    634 			bias = GPIO_PIN_PULLUP;
    635 			break;
    636 		case 2:
    637 			bias = GPIO_PIN_PULLDOWN;
    638 			break;
    639 		}
    640 	}
    641 
    642 	return bias;
    643 }
    644 
    645 static int
    646 sunxi_pinctrl_parse_drive_strength(int phandle)
    647 {
    648 	int val;
    649 
    650 	val = fdtbus_pinctrl_parse_drive_strength(phandle);
    651 	if (val != -1)
    652 		return val;
    653 
    654 	if (of_getprop_uint32(phandle, "allwinner,drive", &val) == 0)
    655 		return (val + 1) * 10;
    656 
    657 	return -1;
    658 }
    659 
    660 static void
    661 sunxi_pinctrl_enable_regulator(struct sunxi_gpio_softc *sc,
    662     const struct sunxi_gpio_pins *pin_def)
    663 {
    664 	char supply_prop[16];
    665 	uint32_t val;
    666 	u_int uvol;
    667 	int error;
    668 
    669 	const char c = tolower(pin_def->name[1]);
    670 	if (c < 'a' || c > 'z')
    671 		return;
    672 	const int index = c - 'a';
    673 
    674 	if (sc->sc_pin_supply[index] != NULL) {
    675 		/* Already enabled */
    676 		return;
    677 	}
    678 
    679 	snprintf(supply_prop, sizeof(supply_prop), "vcc-p%c-supply", c);
    680 	sc->sc_pin_supply[index] = fdtbus_regulator_acquire(sc->sc_phandle, supply_prop);
    681 	if (sc->sc_pin_supply[index] == NULL)
    682 		return;
    683 
    684 	aprint_debug_dev(sc->sc_dev, "enable \"%s\"\n", supply_prop);
    685 	error = fdtbus_regulator_enable(sc->sc_pin_supply[index]);
    686 	if (error != 0)
    687 		aprint_error_dev(sc->sc_dev, "failed to enable %s: %d\n", supply_prop, error);
    688 
    689 	if (sc->sc_padconf->has_io_bias_config) {
    690 		error = fdtbus_regulator_get_voltage(sc->sc_pin_supply[index], &uvol);
    691 		if (error != 0) {
    692 			aprint_error_dev(sc->sc_dev, "failed to get %s voltage: %d\n",
    693 			    supply_prop, error);
    694 			uvol = 0;
    695 		}
    696 		if (uvol != 0) {
    697 			if (uvol <= 1800000)
    698 				val = 0x0;	/* 1.8V */
    699 			else if (uvol <= 2500000)
    700 				val = 0x6;	/* 2.5V */
    701 			else if (uvol <= 2800000)
    702 				val = 0x9;	/* 2.8V */
    703 			else if (uvol <= 3000000)
    704 				val = 0xa;	/* 3.0V */
    705 			else
    706 				val = 0xd;	/* 3.3V */
    707 
    708 			aprint_debug_dev(sc->sc_dev, "set io bias config for port %d to 0x%x\n",
    709 			    pin_def->port, val);
    710 			val = GPIO_READ(sc, SUNXI_GPIO_GRP_CONFIG(pin_def->port));
    711 			val &= ~SUNXI_GPIO_GRP_IO_BIAS_CONFIGMASK;
    712 			val |= __SHIFTIN(val, SUNXI_GPIO_GRP_IO_BIAS_CONFIGMASK);
    713 			GPIO_WRITE(sc, SUNXI_GPIO_GRP_CONFIG(pin_def->port), val);
    714 		}
    715 	}
    716 }
    717 
    718 static int
    719 sunxi_pinctrl_set_config(device_t dev, const void *data, size_t len)
    720 {
    721 	struct sunxi_gpio_softc * const sc = device_private(dev);
    722 	const struct sunxi_gpio_pins *pin_def;
    723 	int pins_len;
    724 
    725 	if (len != 4)
    726 		return -1;
    727 
    728 	const int phandle = fdtbus_get_phandle_from_native(be32dec(data));
    729 
    730 	/*
    731 	 * Required: pins, function
    732 	 * Optional: bias, drive strength
    733 	 */
    734 
    735 	const char *function = sunxi_pinctrl_parse_function(phandle);
    736 	if (function == NULL)
    737 		return -1;
    738 	const char *pins = sunxi_pinctrl_parse_pins(phandle, &pins_len);
    739 	if (pins == NULL)
    740 		return -1;
    741 
    742 	const int bias = sunxi_pinctrl_parse_bias(phandle);
    743 	const int drive_strength = sunxi_pinctrl_parse_drive_strength(phandle);
    744 
    745 	mutex_enter(&sc->sc_lock);
    746 
    747 	for (; pins_len > 0;
    748 	    pins_len -= strlen(pins) + 1, pins += strlen(pins) + 1) {
    749 		pin_def = sunxi_gpio_lookup_byname(sc, pins);
    750 		if (pin_def == NULL) {
    751 			aprint_error_dev(dev, "unknown pin name '%s'\n", pins);
    752 			continue;
    753 		}
    754 		if (sunxi_gpio_setfunc(sc, pin_def, function) != 0)
    755 			continue;
    756 
    757 		if (bias != -1)
    758 			sunxi_gpio_setpull(sc, pin_def, bias);
    759 
    760 		if (drive_strength != -1)
    761 			sunxi_gpio_setdrv(sc, pin_def, drive_strength);
    762 
    763 		sunxi_pinctrl_enable_regulator(sc, pin_def);
    764 	}
    765 
    766 	mutex_exit(&sc->sc_lock);
    767 
    768 	return 0;
    769 }
    770 
    771 static struct fdtbus_pinctrl_controller_func sunxi_pinctrl_funcs = {
    772 	.set_config = sunxi_pinctrl_set_config,
    773 };
    774 
    775 static int
    776 sunxi_gpio_pin_read(void *priv, int pin)
    777 {
    778 	struct sunxi_gpio_softc * const sc = priv;
    779 	const struct sunxi_gpio_pins *pin_def = &sc->sc_padconf->pins[pin];
    780 	uint32_t data;
    781 	int val;
    782 
    783 	KASSERT(pin < sc->sc_padconf->npins);
    784 
    785 	const bus_size_t data_reg = SUNXI_GPIO_DATA(pin_def->port);
    786 	const uint32_t data_mask = __BIT(pin_def->pin);
    787 
    788 	/* No lock required for reads */
    789 	data = GPIO_READ(sc, data_reg);
    790 	val = __SHIFTOUT(data, data_mask);
    791 
    792 	return val;
    793 }
    794 
    795 static void
    796 sunxi_gpio_pin_write(void *priv, int pin, int val)
    797 {
    798 	struct sunxi_gpio_softc * const sc = priv;
    799 	const struct sunxi_gpio_pins *pin_def = &sc->sc_padconf->pins[pin];
    800 	uint32_t data;
    801 
    802 	KASSERT(pin < sc->sc_padconf->npins);
    803 
    804 	const bus_size_t data_reg = SUNXI_GPIO_DATA(pin_def->port);
    805 	const uint32_t data_mask = __BIT(pin_def->pin);
    806 
    807 	mutex_enter(&sc->sc_lock);
    808 	data = GPIO_READ(sc, data_reg);
    809 	if (val)
    810 		data |= data_mask;
    811 	else
    812 		data &= ~data_mask;
    813 	GPIO_WRITE(sc, data_reg, data);
    814 	mutex_exit(&sc->sc_lock);
    815 }
    816 
    817 static void
    818 sunxi_gpio_pin_ctl(void *priv, int pin, int flags)
    819 {
    820 	struct sunxi_gpio_softc * const sc = priv;
    821 	const struct sunxi_gpio_pins *pin_def = &sc->sc_padconf->pins[pin];
    822 
    823 	KASSERT(pin < sc->sc_padconf->npins);
    824 
    825 	mutex_enter(&sc->sc_lock);
    826 	sunxi_gpio_ctl(sc, pin_def, flags);
    827 	sunxi_gpio_setpull(sc, pin_def, flags);
    828 	mutex_exit(&sc->sc_lock);
    829 }
    830 
    831 static void
    832 sunxi_gpio_attach_ports(struct sunxi_gpio_softc *sc)
    833 {
    834 	const struct sunxi_gpio_pins *pin_def;
    835 	struct gpio_chipset_tag *gp = &sc->sc_gp;
    836 	struct gpiobus_attach_args gba;
    837 	u_int pin;
    838 
    839 	gp->gp_cookie = sc;
    840 	gp->gp_pin_read = sunxi_gpio_pin_read;
    841 	gp->gp_pin_write = sunxi_gpio_pin_write;
    842 	gp->gp_pin_ctl = sunxi_gpio_pin_ctl;
    843 
    844 	const u_int npins = sc->sc_padconf->npins;
    845 	sc->sc_pins = kmem_zalloc(sizeof(*sc->sc_pins) * npins, KM_SLEEP);
    846 
    847 	for (pin = 0; pin < sc->sc_padconf->npins; pin++) {
    848 		pin_def = &sc->sc_padconf->pins[pin];
    849 		sc->sc_pins[pin].pin_num = pin;
    850 		sc->sc_pins[pin].pin_caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT |
    851 		    GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN;
    852 		sc->sc_pins[pin].pin_state = sunxi_gpio_pin_read(sc, pin);
    853 		strlcpy(sc->sc_pins[pin].pin_defname, pin_def->name,
    854 		    sizeof(sc->sc_pins[pin].pin_defname));
    855 	}
    856 
    857 	memset(&gba, 0, sizeof(gba));
    858 	gba.gba_gc = gp;
    859 	gba.gba_pins = sc->sc_pins;
    860 	gba.gba_npins = npins;
    861 	sc->sc_gpiodev = config_found_ia(sc->sc_dev, "gpiobus", &gba, NULL);
    862 }
    863 
    864 static int
    865 sunxi_gpio_match(device_t parent, cfdata_t cf, void *aux)
    866 {
    867 	struct fdt_attach_args * const faa = aux;
    868 
    869 	return of_match_compat_data(faa->faa_phandle, compat_data);
    870 }
    871 
    872 static void
    873 sunxi_gpio_attach(device_t parent, device_t self, void *aux)
    874 {
    875 	struct sunxi_gpio_softc * const sc = device_private(self);
    876 	struct fdt_attach_args * const faa = aux;
    877 	const int phandle = faa->faa_phandle;
    878 	char intrstr[128];
    879 	struct fdtbus_reset *rst;
    880 	struct clk *clk;
    881 	bus_addr_t addr;
    882 	bus_size_t size;
    883 	int child;
    884 
    885 	if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
    886 		aprint_error(": couldn't get registers\n");
    887 		return;
    888 	}
    889 
    890 	if ((clk = fdtbus_clock_get_index(phandle, 0)) != NULL)
    891 		if (clk_enable(clk) != 0) {
    892 			aprint_error(": couldn't enable clock\n");
    893 			return;
    894 		}
    895 
    896 	if ((rst = fdtbus_reset_get_index(phandle, 0)) != NULL)
    897 		if (fdtbus_reset_deassert(rst) != 0) {
    898 			aprint_error(": couldn't de-assert reset\n");
    899 			return;
    900 		}
    901 
    902 	sc->sc_dev = self;
    903 	sc->sc_phandle = phandle;
    904 	sc->sc_bst = faa->faa_bst;
    905 	if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
    906 		aprint_error(": couldn't map registers\n");
    907 		return;
    908 	}
    909 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM);
    910 	sc->sc_padconf = (void *)of_search_compatible(phandle, compat_data)->data;
    911 
    912 	aprint_naive("\n");
    913 	aprint_normal(": PIO\n");
    914 
    915 	fdtbus_register_gpio_controller(self, phandle, &sunxi_gpio_funcs);
    916 
    917 	for (child = OF_child(phandle); child; child = OF_peer(child)) {
    918 		bool is_valid =
    919 		    (of_hasprop(child, "function") && of_hasprop(child, "pins")) ||
    920 		    (of_hasprop(child, "allwinner,function") && of_hasprop(child, "allwinner,pins"));
    921 		if (!is_valid)
    922 			continue;
    923 		fdtbus_register_pinctrl_config(self, child, &sunxi_pinctrl_funcs);
    924 	}
    925 
    926 	fdtbus_pinctrl_configure();
    927 
    928 	sunxi_gpio_attach_ports(sc);
    929 
    930 	/* Disable all external interrupts */
    931 	for (int i = 0; i < sc->sc_padconf->npins; i++) {
    932 		const struct sunxi_gpio_pins *pin_def = &sc->sc_padconf->pins[i];
    933 		if (pin_def->eint_func == 0)
    934 			continue;
    935 		GPIO_WRITE(sc, SUNXI_GPIO_INT_CTL(pin_def->eint_bank), __BIT(pin_def->eint_num));
    936 		GPIO_WRITE(sc, SUNXI_GPIO_INT_STATUS(pin_def->eint_bank), __BIT(pin_def->eint_num));
    937 
    938 		if (sc->sc_eint_bank_max < pin_def->eint_bank)
    939 			sc->sc_eint_bank_max = pin_def->eint_bank;
    940 	}
    941 	KASSERT(sc->sc_eint_bank_max < SUNXI_GPIO_MAX_EINT_BANK);
    942 
    943 	if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) {
    944 		aprint_error_dev(self, "failed to decode interrupt\n");
    945 		return;
    946 	}
    947 	sc->sc_ih = fdtbus_intr_establish(phandle, 0, IPL_VM, FDT_INTR_MPSAFE,
    948 	    sunxi_gpio_intr, sc);
    949 	if (sc->sc_ih == NULL) {
    950 		aprint_error_dev(self, "failed to establish interrupt on %s\n",
    951 		    intrstr);
    952 		return;
    953 	}
    954 	aprint_normal_dev(self, "interrupting on %s\n", intrstr);
    955 	fdtbus_register_interrupt_controller(self, phandle,
    956 	    &sunxi_gpio_intrfuncs);
    957 }
    958