summaryrefslogtreecommitdiff
path: root/plat/allwinner
diff options
context:
space:
mode:
authorAndre Przywara <andre.przywara@arm.com>2018-10-14 12:03:23 +0100
committerAndre Przywara <andre.przywara@arm.com>2018-10-20 16:23:59 +0100
commit7020dca0bdad580d322839fcade8265d64a2e886 (patch)
treeb1326565503abcf394bd429c7eccdb8f78759012 /plat/allwinner
parent4ec1a2399cf6e182ba2828a40795912d20eca1ab (diff)
allwinner: Introduce GPIO helper function
Many boards without a dedicated PMIC contain simple regulators, which can be controlled via GPIO pins. To later allow turning them off easily, introduce a simple function to configure a given pin as a GPIO out pin and set it to the desired level. Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Diffstat (limited to 'plat/allwinner')
-rw-r--r--plat/allwinner/common/include/sunxi_private.h1
-rw-r--r--plat/allwinner/common/sunxi_common.c29
2 files changed, 30 insertions, 0 deletions
diff --git a/plat/allwinner/common/include/sunxi_private.h b/plat/allwinner/common/include/sunxi_private.h
index 9d20f607..54cc27e4 100644
--- a/plat/allwinner/common/include/sunxi_private.h
+++ b/plat/allwinner/common/include/sunxi_private.h
@@ -18,5 +18,6 @@ int sunxi_pmic_setup(uint16_t socid);
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 ea77afb5..88156b51 100644
--- a/plat/allwinner/common/sunxi_common.c
+++ b/plat/allwinner/common/sunxi_common.c
@@ -71,3 +71,32 @@ uint16_t sunxi_read_soc_id(void)
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));
+}