From 919e499a364bebd0032f2f7b92051fb4f301f66f Mon Sep 17 00:00:00 2001 From: Alexandru Gagniuc Date: Thu, 2 Jan 2014 03:59:24 -0500 Subject: [PATCH] cpu/allwinner/a10: Add functions for driving GPIO pins Change-Id: I9473a6e574c3af02d154a7e30245f0dc0b238300 Signed-off-by: Alexandru Gagniuc Reviewed-on: http://review.coreboot.org/4599 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel Reviewed-by: David Hendricks --- src/cpu/allwinner/a10/Makefile.inc | 1 + src/cpu/allwinner/a10/gpio.c | 98 ++++++++++++++++++++++++++++++ src/cpu/allwinner/a10/gpio.h | 8 +++ 3 files changed, 107 insertions(+) create mode 100644 src/cpu/allwinner/a10/gpio.c 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 + * Subject to the GNU GPL v2, or (at your option) any later version. + */ + +#include "gpio.h" + +#include + +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);