diff --git a/plat/allwinner/common/include/sunxi_private.h b/plat/allwinner/common/include/sunxi_private.h index 9d20f60..54cc27e 100644 --- a/plat/allwinner/common/include/sunxi_private.h +++ b/plat/allwinner/common/include/sunxi_private.h @@ -18,5 +18,6 @@ void sunxi_security_setup(void); uint16_t sunxi_read_soc_id(void); +void sunxi_set_gpio_out(char port, int pin, bool level_high); #endif /* SUNXI_PRIVATE_H */ diff --git a/plat/allwinner/common/sunxi_common.c b/plat/allwinner/common/sunxi_common.c index ea77afb..88156b5 100644 --- a/plat/allwinner/common/sunxi_common.c +++ b/plat/allwinner/common/sunxi_common.c @@ -71,3 +71,32 @@ return reg >> 16; } + +/* + * Configure a given pin to the GPIO-OUT function and sets its level. + * The port is given as a capital letter, the pin is the number within + * this port group. + * So to set pin PC7 to high, use: sunxi_set_gpio_out('C', 7, true); + */ +void sunxi_set_gpio_out(char port, int pin, bool level_high) +{ + uintptr_t port_base; + + if (port < 'A' || port > 'L') + return; + if (port == 'L') + port_base = SUNXI_R_PIO_BASE; + else + port_base = SUNXI_PIO_BASE + (port - 'A') * 0x24; + + /* Set the new level first before configuring the pin. */ + if (level_high) + mmio_setbits_32(port_base + 0x10, BIT(pin)); + else + mmio_clrbits_32(port_base + 0x10, BIT(pin)); + + /* configure pin as GPIO out (4(3) bits per pin, 1: GPIO out */ + mmio_clrsetbits_32(port_base + (pin / 8) * 4, + 0x7 << ((pin % 8) * 4), + 0x1 << ((pin % 8) * 4)); +}