diff options
author | Lennert Buytenhek <buytenh@wantstofly.org> | 2006-03-20 18:10:14 +0100 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2006-03-21 23:06:12 +0100 |
commit | a8e19667a42d752f3eca6eaa17aa5d6f93066dfe (patch) | |
tree | 7bf3b7eb8ac3fb6c18b3a8c33a88d6d2158f45e4 /arch/arm | |
parent | [ARM] 3369/1: ep93xx: add core cirrus ep93xx support (diff) | |
download | linux-a8e19667a42d752f3eca6eaa17aa5d6f93066dfe.tar.xz linux-a8e19667a42d752f3eca6eaa17aa5d6f93066dfe.zip |
[ARM] 3371/1: ep93xx: gpio support
Patch from Lennert Buytenhek
Add support for setting the direction of and getting/setting the
value of the 64 GPIO lines.
Signed-off-by: Lennert Buytenhek <buytenh@wantstofly.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/mach-ep93xx/core.c | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index f831f74dc8cc..7d3e79990fad 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c @@ -45,6 +45,7 @@ #include <asm/mach/map.h> #include <asm/mach/time.h> #include <asm/mach/irq.h> +#include <asm/arch/gpio.h> #include <asm/hardware/vic.h> @@ -147,6 +148,73 @@ struct sys_timer ep93xx_timer = { /************************************************************************* + * GPIO handling for EP93xx + *************************************************************************/ +static unsigned char data_register_offset[8] = { + 0x00, 0x04, 0x08, 0x0c, 0x20, 0x30, 0x38, 0x40, +}; + +static unsigned char data_direction_register_offset[8] = { + 0x10, 0x14, 0x18, 0x1c, 0x24, 0x34, 0x3c, 0x44, +}; + +void gpio_line_config(int line, int direction) +{ + unsigned int data_direction_register; + unsigned long flags; + unsigned char v; + + data_direction_register = + EP93XX_GPIO_REG(data_direction_register_offset[line >> 3]); + + local_irq_save(flags); + if (direction == GPIO_OUT) { + v = __raw_readb(data_direction_register); + v |= 1 << (line & 7); + __raw_writeb(v, data_direction_register); + } else if (direction == GPIO_IN) { + v = __raw_readb(data_direction_register); + v &= ~(1 << (line & 7)); + __raw_writeb(v, data_direction_register); + } + local_irq_restore(flags); +} +EXPORT_SYMBOL(gpio_line_config); + +int gpio_line_get(int line) +{ + unsigned int data_register; + + data_register = EP93XX_GPIO_REG(data_register_offset[line >> 3]); + + return !!(__raw_readb(data_register) & (1 << (line & 7))); +} +EXPORT_SYMBOL(gpio_line_get); + +void gpio_line_set(int line, int value) +{ + unsigned int data_register; + unsigned long flags; + unsigned char v; + + data_register = EP93XX_GPIO_REG(data_register_offset[line >> 3]); + + local_irq_save(flags); + if (value == EP93XX_GPIO_HIGH) { + v = __raw_readb(data_register); + v |= 1 << (line & 7); + __raw_writeb(v, data_register); + } else if (value == EP93XX_GPIO_LOW) { + v = __raw_readb(data_register); + v &= ~(1 << (line & 7)); + __raw_writeb(v, data_register); + } + local_irq_restore(flags); +} +EXPORT_SYMBOL(gpio_line_set); + + +/************************************************************************* * EP93xx IRQ handling *************************************************************************/ void __init ep93xx_init_irq(void) |