[ARM] 3284/1: S3C2400 - adds support to GPIO

Patch from Lucas Correia Villa Real

This patch adds support to GPIO on the S3C2400, which is going to
be used by the GP32 machine and the SMDK2400 development board.

Signed-off-by: Lucas Correia Villa Real <lucasvr@gobolinux.org>
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
Lucas Correia Villa Real 2006-02-01 21:24:23 +00:00 committed by Russell King
parent 7610dfa372
commit 0ca5bc3de7
7 changed files with 181 additions and 65 deletions

View File

@ -10,9 +10,13 @@ obj-m :=
obj-n := obj-n :=
obj- := obj- :=
# S3C2400 support files
obj-$(CONFIG_CPU_S3C2400) += s3c2400-gpio.o
# S3C2410 support files # S3C2410 support files
obj-$(CONFIG_CPU_S3C2410) += s3c2410.o obj-$(CONFIG_CPU_S3C2410) += s3c2410.o
obj-$(CONFIG_CPU_S3C2410) += s3c2410-gpio.o
obj-$(CONFIG_S3C2410_DMA) += dma.o obj-$(CONFIG_S3C2410_DMA) += dma.o
# Power Management support # Power Management support
@ -25,6 +29,7 @@ obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o
obj-$(CONFIG_CPU_S3C2440) += s3c2440.o s3c2440-dsc.o obj-$(CONFIG_CPU_S3C2440) += s3c2440.o s3c2440-dsc.o
obj-$(CONFIG_CPU_S3C2440) += s3c2440-irq.o obj-$(CONFIG_CPU_S3C2440) += s3c2440-irq.o
obj-$(CONFIG_CPU_S3C2440) += s3c2440-clock.o obj-$(CONFIG_CPU_S3C2440) += s3c2440-clock.o
obj-$(CONFIG_CPU_S3C2440) += s3c2410-gpio.o
# bast extras # bast extras

View File

@ -31,6 +31,7 @@
* 05-Nov-2004 BJD EXPORT_SYMBOL() added for all code * 05-Nov-2004 BJD EXPORT_SYMBOL() added for all code
* 13-Mar-2005 BJD Updates for __iomem * 13-Mar-2005 BJD Updates for __iomem
* 26-Oct-2005 BJD Added generic configuration types * 26-Oct-2005 BJD Added generic configuration types
* 15-Jan-2006 LCVR Added support for the S3C2400
*/ */
@ -48,7 +49,7 @@
void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function) void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function)
{ {
void __iomem *base = S3C2410_GPIO_BASE(pin); void __iomem *base = S3C24XX_GPIO_BASE(pin);
unsigned long mask; unsigned long mask;
unsigned long con; unsigned long con;
unsigned long flags; unsigned long flags;
@ -95,7 +96,7 @@ EXPORT_SYMBOL(s3c2410_gpio_cfgpin);
unsigned int s3c2410_gpio_getcfg(unsigned int pin) unsigned int s3c2410_gpio_getcfg(unsigned int pin)
{ {
void __iomem *base = S3C2410_GPIO_BASE(pin); void __iomem *base = S3C24XX_GPIO_BASE(pin);
unsigned long mask; unsigned long mask;
if (pin < S3C2410_GPIO_BANKB) { if (pin < S3C2410_GPIO_BANKB) {
@ -111,7 +112,7 @@ EXPORT_SYMBOL(s3c2410_gpio_getcfg);
void s3c2410_gpio_pullup(unsigned int pin, unsigned int to) void s3c2410_gpio_pullup(unsigned int pin, unsigned int to)
{ {
void __iomem *base = S3C2410_GPIO_BASE(pin); void __iomem *base = S3C24XX_GPIO_BASE(pin);
unsigned long offs = S3C2410_GPIO_OFFSET(pin); unsigned long offs = S3C2410_GPIO_OFFSET(pin);
unsigned long flags; unsigned long flags;
unsigned long up; unsigned long up;
@ -133,7 +134,7 @@ EXPORT_SYMBOL(s3c2410_gpio_pullup);
void s3c2410_gpio_setpin(unsigned int pin, unsigned int to) void s3c2410_gpio_setpin(unsigned int pin, unsigned int to)
{ {
void __iomem *base = S3C2410_GPIO_BASE(pin); void __iomem *base = S3C24XX_GPIO_BASE(pin);
unsigned long offs = S3C2410_GPIO_OFFSET(pin); unsigned long offs = S3C2410_GPIO_OFFSET(pin);
unsigned long flags; unsigned long flags;
unsigned long dat; unsigned long dat;
@ -152,7 +153,7 @@ EXPORT_SYMBOL(s3c2410_gpio_setpin);
unsigned int s3c2410_gpio_getpin(unsigned int pin) unsigned int s3c2410_gpio_getpin(unsigned int pin)
{ {
void __iomem *base = S3C2410_GPIO_BASE(pin); void __iomem *base = S3C24XX_GPIO_BASE(pin);
unsigned long offs = S3C2410_GPIO_OFFSET(pin); unsigned long offs = S3C2410_GPIO_OFFSET(pin);
return __raw_readl(base + 0x04) & (1<< offs); return __raw_readl(base + 0x04) & (1<< offs);
@ -166,70 +167,13 @@ unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change)
unsigned long misccr; unsigned long misccr;
local_irq_save(flags); local_irq_save(flags);
misccr = __raw_readl(S3C2410_MISCCR); misccr = __raw_readl(S3C24XX_MISCCR);
misccr &= ~clear; misccr &= ~clear;
misccr ^= change; misccr ^= change;
__raw_writel(misccr, S3C2410_MISCCR); __raw_writel(misccr, S3C24XX_MISCCR);
local_irq_restore(flags); local_irq_restore(flags);
return misccr; return misccr;
} }
EXPORT_SYMBOL(s3c2410_modify_misccr); EXPORT_SYMBOL(s3c2410_modify_misccr);
int s3c2410_gpio_getirq(unsigned int pin)
{
if (pin < S3C2410_GPF0 || pin > S3C2410_GPG15_EINT23)
return -1; /* not valid interrupts */
if (pin < S3C2410_GPG0 && pin > S3C2410_GPF7)
return -1; /* not valid pin */
if (pin < S3C2410_GPF4)
return (pin - S3C2410_GPF0) + IRQ_EINT0;
if (pin < S3C2410_GPG0)
return (pin - S3C2410_GPF4) + IRQ_EINT4;
return (pin - S3C2410_GPG0) + IRQ_EINT8;
}
EXPORT_SYMBOL(s3c2410_gpio_getirq);
int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on,
unsigned int config)
{
void __iomem *reg = S3C2410_EINFLT0;
unsigned long flags;
unsigned long val;
if (pin < S3C2410_GPG8 || pin > S3C2410_GPG15)
return -1;
config &= 0xff;
pin -= S3C2410_GPG8_EINT16;
reg += pin & ~3;
local_irq_save(flags);
/* update filter width and clock source */
val = __raw_readl(reg);
val &= ~(0xff << ((pin & 3) * 8));
val |= config << ((pin & 3) * 8);
__raw_writel(val, reg);
/* update filter enable */
val = __raw_readl(S3C2410_EXTINT2);
val &= ~(1 << ((pin * 4) + 3));
val |= on << ((pin * 4) + 3);
__raw_writel(val, S3C2410_EXTINT2);
local_irq_restore(flags);
return 0;
}
EXPORT_SYMBOL(s3c2410_gpio_irqfilter);

View File

@ -0,0 +1,45 @@
/* linux/arch/arm/mach-s3c2410/gpio.c
*
* Copyright (c) 2006 Lucas Correia Villa Real <lucasvr@gobolinux.org>
*
* S3C2400 GPIO support
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Changelog
* 15-Jan-2006 LCVR Splitted from gpio.c, adding support for the S3C2400
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/arch/regs-gpio.h>
int s3c2400_gpio_getirq(unsigned int pin)
{
if (pin < S3C2410_GPE0 || pin > S3C2400_GPE7_EINT7)
return -1; /* not valid interrupts */
return (pin - S3C2410_GPE0) + IRQ_EINT0;
}
EXPORT_SYMBOL(s3c2400_gpio_getirq);

View File

@ -0,0 +1,93 @@
/* linux/arch/arm/mach-s3c2410/gpio.c
*
* Copyright (c) 2004-2006 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* S3C2410 GPIO support
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Changelog
* 15-Jan-2006 LCVR Splitted from gpio.c
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/arch/regs-gpio.h>
int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on,
unsigned int config)
{
void __iomem *reg = S3C2410_EINFLT0;
unsigned long flags;
unsigned long val;
if (pin < S3C2410_GPG8 || pin > S3C2410_GPG15)
return -1;
config &= 0xff;
pin -= S3C2410_GPG8_EINT16;
reg += pin & ~3;
local_irq_save(flags);
/* update filter width and clock source */
val = __raw_readl(reg);
val &= ~(0xff << ((pin & 3) * 8));
val |= config << ((pin & 3) * 8);
__raw_writel(val, reg);
/* update filter enable */
val = __raw_readl(S3C2410_EXTINT2);
val &= ~(1 << ((pin * 4) + 3));
val |= on << ((pin * 4) + 3);
__raw_writel(val, S3C2410_EXTINT2);
local_irq_restore(flags);
return 0;
}
EXPORT_SYMBOL(s3c2410_gpio_irqfilter);
int s3c2410_gpio_getirq(unsigned int pin)
{
if (pin < S3C2410_GPF0 || pin > S3C2410_GPG15_EINT23)
return -1; /* not valid interrupts */
if (pin < S3C2410_GPG0 && pin > S3C2410_GPF7)
return -1; /* not valid pin */
if (pin < S3C2410_GPF4)
return (pin - S3C2410_GPF0) + IRQ_EINT0;
if (pin < S3C2410_GPG0)
return (pin - S3C2410_GPF4) + IRQ_EINT4;
return (pin - S3C2410_GPG0) + IRQ_EINT8;
}
EXPORT_SYMBOL(s3c2410_gpio_getirq);

View File

@ -72,7 +72,7 @@ ENTRY(s3c2410_cpu_suspend)
@@ prepare cpu to sleep @@ prepare cpu to sleep
ldr r4, =S3C2410_REFRESH ldr r4, =S3C2410_REFRESH
ldr r5, =S3C2410_MISCCR ldr r5, =S3C24XX_MISCCR
ldr r6, =S3C2410_CLKCON ldr r6, =S3C2410_CLKCON
ldr r7, [ r4 ] @ get REFRESH (and ensure in TLB) ldr r7, [ r4 ] @ get REFRESH (and ensure in TLB)
ldr r8, [ r5 ] @ get MISCCR (and ensure in TLB) ldr r8, [ r5 ] @ get MISCCR (and ensure in TLB)

View File

@ -17,6 +17,7 @@
* 14-Sep-2004 BJD Added misccr and getpin to gpio * 14-Sep-2004 BJD Added misccr and getpin to gpio
* 01-Oct-2004 BJD Added the new gpio functions * 01-Oct-2004 BJD Added the new gpio functions
* 16-Oct-2004 BJD Removed the clock variables * 16-Oct-2004 BJD Removed the clock variables
* 15-Jan-2006 LCVR Added s3c2400_gpio_getirq()
*/ */
#ifndef __ASM_ARCH_HARDWARE_H #ifndef __ASM_ARCH_HARDWARE_H
@ -55,6 +56,12 @@ extern unsigned int s3c2410_gpio_getcfg(unsigned int pin);
extern int s3c2410_gpio_getirq(unsigned int pin); extern int s3c2410_gpio_getirq(unsigned int pin);
#ifdef CONFIG_CPU_S3C2400
extern int s3c2400_gpio_getirq(unsigned int pin);
#endif /* CONFIG_CPU_S3C2400 */
/* s3c2410_gpio_irqfilter /* s3c2410_gpio_irqfilter
* *
* set the irq filtering on the given pin * set the irq filtering on the given pin

View File

@ -22,6 +22,7 @@
* 28-Mar-2005 LCVR Fixed definition of GPB10 * 28-Mar-2005 LCVR Fixed definition of GPB10
* 26-Oct-2005 BJD Added generic configuration types * 26-Oct-2005 BJD Added generic configuration types
* 27-Nov-2005 LCVR Added definitions to S3C2400 registers * 27-Nov-2005 LCVR Added definitions to S3C2400 registers
* 15-Jan-2006 LCVR Written S3C24XX_GPIO_BASE() macro
*/ */
@ -39,6 +40,27 @@
#define S3C2410_GPIO_BANKG (32*6) #define S3C2410_GPIO_BANKG (32*6)
#define S3C2410_GPIO_BANKH (32*7) #define S3C2410_GPIO_BANKH (32*7)
#ifdef CONFIG_CPU_S3C2400
#define S3C24XX_GPIO_BASE(x) S3C2400_GPIO_BASE(x)
#define S3C24XX_MISCCR S3C2400_MISCCR
#else
#define S3C24XX_GPIO_BASE(x) S3C2410_GPIO_BASE(x)
#define S3C24XX_MISCCR S3C2410_MISCCR
#endif /* CONFIG_CPU_S3C2400 */
/* S3C2400 doesn't have a 1:1 mapping to S3C2410 gpio base pins */
#define S3C2400_BANKNUM(pin) (((pin) & ~31) / 32)
#define S3C2400_BASEA2B(pin) ((((pin) & ~31) >> 2))
#define S3C2400_BASEC2H(pin) ((S3C2400_BANKNUM(pin) * 10) + \
(2 * (S3C2400_BANKNUM(pin)-2)))
#define S3C2400_GPIO_BASE(pin) (pin < S3C2410_GPIO_BANKC ? \
S3C2400_BASEA2B(pin)+S3C24XX_VA_GPIO : \
S3C2400_BASEC2H(pin)+S3C24XX_VA_GPIO)
#define S3C2410_GPIO_BASE(pin) ((((pin) & ~31) >> 1) + S3C24XX_VA_GPIO) #define S3C2410_GPIO_BASE(pin) ((((pin) & ~31) >> 1) + S3C24XX_VA_GPIO)
#define S3C2410_GPIO_OFFSET(pin) ((pin) & 31) #define S3C2410_GPIO_OFFSET(pin) ((pin) & 31)