summaryrefslogtreecommitdiff
path: root/src/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu')
-rw-r--r--src/cpu/allwinner/a10/Makefile.inc1
-rw-r--r--src/cpu/allwinner/a10/gpio.c98
-rw-r--r--src/cpu/allwinner/a10/gpio.h8
3 files changed, 107 insertions, 0 deletions
diff --git a/src/cpu/allwinner/a10/Makefile.inc b/src/cpu/allwinner/a10/Makefile.inc
index 686552921a..8e743a2d42 100644
--- a/src/cpu/allwinner/a10/Makefile.inc
+++ b/src/cpu/allwinner/a10/Makefile.inc
@@ -1,4 +1,5 @@
bootblock-y += clock.c
+bootblock-y += gpio.c
bootblock-y += pinmux.c
bootblock-y += bootblock_media.c
bootblock-$(CONFIG_BOOTBLOCK_CONSOLE) += uart.c
diff --git a/src/cpu/allwinner/a10/gpio.c b/src/cpu/allwinner/a10/gpio.c
new file mode 100644
index 0000000000..295cdf2054
--- /dev/null
+++ b/src/cpu/allwinner/a10/gpio.c
@@ -0,0 +1,98 @@
+/*
+ * Basic GPIO helpers for Allwinner CPUs
+ *
+ * Copyright (C) 2013 Alexandru Gagniuc <mr.nuke.me@gmail.com>
+ * Subject to the GNU GPL v2, or (at your option) any later version.
+ */
+
+#include "gpio.h"
+
+#include <arch/io.h>
+
+static struct a10_gpio *const gpio = (void *)GPIO_BASE;
+
+/**
+ * \brief Set a single output pin
+ *
+ * @param[in] port GPIO port of the pin (GPA -> GPS)
+ * @param[in] pin the pin number in the given port (1 -> 31)
+ */
+void gpio_set(u8 port, u8 pin)
+{
+ u32 reg32;
+
+ if ((port > GPS))
+ return;
+
+ reg32 = gpio_read(port);
+ reg32 |= (1 << pin);
+ gpio_write(port, reg32);
+}
+
+/**
+ * \brief Clear a single output pin
+ *
+ * @param[in] port GPIO port of the pin (GPA -> GPS)
+ * @param[in] pin the pin number in the given port (1 -> 31)
+ */
+void gpio_clear(u8 port, u8 pin)
+{
+ u32 reg32;
+ if ((port > GPS))
+ return;
+
+ reg32 = gpio_read(port);
+ reg32 &= ~(1 << pin);
+ gpio_write(port, reg32);
+}
+
+/**
+ * \brief Get the status of a single input pin
+ *
+ * @param[in] port GPIO port of the pin (GPA -> GPS)
+ * @param[in] pin the pin number in the given port (1 -> 31)
+ * @return 1 if the pin is high, or 0 if the pin is low
+ */
+int gpio_get(u8 port, u8 pin)
+{
+ if ((port > GPS))
+ return 0;
+
+ return (gpio_read(port) & (1 << pin)) ? 1 : 0;
+}
+
+/**
+ * \brief Write to a GPIO port
+ *
+ * Write the state of all output pins in the GPIO port. This only affects pins
+ * configured as output pins.
+ *
+ * @param[in] port GPIO port of the pin (GPA -> GPS)
+ * @param[in] value 32-bit mask indicating which pins to set. For a set bit, the
+ * corresponding pin will be set. Otherwise, it will be cleared
+ */
+void gpio_write(u8 port, u32 val)
+{
+ if ((port > GPS))
+ return;
+
+ write32(val, &gpio->port[port].dat);
+}
+
+/**
+ * \brief Write to a GPIO port
+ *
+ * Read the state of all input pins in the GPIO port.
+ *
+ * @param[in] port GPIO port of the pin (GPA -> GPS)
+ * @return 32-bit mask indicating which pins are high. For each set bit, the
+ * corresponding pin is high. The value of bits corresponding to pins
+ * which are not configured as inputs is undefined.
+ */
+u32 gpio_read(u8 port)
+{
+ if ((port > GPS))
+ return 0;
+
+ return read32(&gpio->port[port].dat);
+}
diff --git a/src/cpu/allwinner/a10/gpio.h b/src/cpu/allwinner/a10/gpio.h
index e4b24ea3fc..b20d75962b 100644
--- a/src/cpu/allwinner/a10/gpio.h
+++ b/src/cpu/allwinner/a10/gpio.h
@@ -50,6 +50,14 @@ struct a10_gpio {
u32 sdr_pad_pul;
} __attribute__ ((packed));
+/* gpio.c */
+void gpio_set(u8 port, u8 pin);
+void gpio_clear(u8 port, u8 pin);
+int gpio_get(u8 port, u8 pin);
+void gpio_write(u8 port, u32 val);
+u32 gpio_read(u8 port);
+
+/* pinmux.c */
void gpio_set_pin_func(u8 port, u8 pin, u8 pad_func);
void gpio_set_multipin_func(u8 port, u32 pin_mask, u8 pad_func);