Skip to content

Commit

Permalink
[ARM] 3284/1: S3C2400 - adds support to GPIO
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Lucas Correia Villa Real authored and Russell King committed Feb 1, 2006
1 parent 7610dfa commit 0ca5bc3
Show file tree
Hide file tree
Showing 7 changed files with 181 additions and 65 deletions.
5 changes: 5 additions & 0 deletions arch/arm/mach-s3c2410/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,13 @@ obj-m :=
obj-n :=
obj- :=

# S3C2400 support files
obj-$(CONFIG_CPU_S3C2400) += s3c2400-gpio.o

# S3C2410 support files

obj-$(CONFIG_CPU_S3C2410) += s3c2410.o
obj-$(CONFIG_CPU_S3C2410) += s3c2410-gpio.o
obj-$(CONFIG_S3C2410_DMA) += dma.o

# Power Management support
Expand All @@ -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-irq.o
obj-$(CONFIG_CPU_S3C2440) += s3c2440-clock.o
obj-$(CONFIG_CPU_S3C2440) += s3c2410-gpio.o

# bast extras

Expand Down
72 changes: 8 additions & 64 deletions arch/arm/mach-s3c2410/gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
* 05-Nov-2004 BJD EXPORT_SYMBOL() added for all code
* 13-Mar-2005 BJD Updates for __iomem
* 26-Oct-2005 BJD Added generic configuration types
* 15-Jan-2006 LCVR Added support for the S3C2400
*/


Expand All @@ -48,7 +49,7 @@

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 con;
unsigned long flags;
Expand Down Expand Up @@ -95,7 +96,7 @@ EXPORT_SYMBOL(s3c2410_gpio_cfgpin);

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;

if (pin < S3C2410_GPIO_BANKB) {
Expand All @@ -111,7 +112,7 @@ EXPORT_SYMBOL(s3c2410_gpio_getcfg);

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 flags;
unsigned long up;
Expand All @@ -133,7 +134,7 @@ EXPORT_SYMBOL(s3c2410_gpio_pullup);

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 flags;
unsigned long dat;
Expand All @@ -152,7 +153,7 @@ EXPORT_SYMBOL(s3c2410_gpio_setpin);

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);

return __raw_readl(base + 0x04) & (1<< offs);
Expand All @@ -166,70 +167,13 @@ unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change)
unsigned long misccr;

local_irq_save(flags);
misccr = __raw_readl(S3C2410_MISCCR);
misccr = __raw_readl(S3C24XX_MISCCR);
misccr &= ~clear;
misccr ^= change;
__raw_writel(misccr, S3C2410_MISCCR);
__raw_writel(misccr, S3C24XX_MISCCR);
local_irq_restore(flags);

return 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);
45 changes: 45 additions & 0 deletions arch/arm/mach-s3c2410/s3c2400-gpio.c
Original file line number Diff line number Diff line change
@@ -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);
93 changes: 93 additions & 0 deletions arch/arm/mach-s3c2410/s3c2410-gpio.c
Original file line number Diff line number Diff line change
@@ -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);
2 changes: 1 addition & 1 deletion arch/arm/mach-s3c2410/sleep.S
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ ENTRY(s3c2410_cpu_suspend)
@@ prepare cpu to sleep

ldr r4, =S3C2410_REFRESH
ldr r5, =S3C2410_MISCCR
ldr r5, =S3C24XX_MISCCR
ldr r6, =S3C2410_CLKCON
ldr r7, [ r4 ] @ get REFRESH (and ensure in TLB)
ldr r8, [ r5 ] @ get MISCCR (and ensure in TLB)
Expand Down
7 changes: 7 additions & 0 deletions include/asm-arm/arch-s3c2410/hardware.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
* 14-Sep-2004 BJD Added misccr and getpin to gpio
* 01-Oct-2004 BJD Added the new gpio functions
* 16-Oct-2004 BJD Removed the clock variables
* 15-Jan-2006 LCVR Added s3c2400_gpio_getirq()
*/

#ifndef __ASM_ARCH_HARDWARE_H
Expand Down Expand Up @@ -55,6 +56,12 @@ extern unsigned int s3c2410_gpio_getcfg(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
*
* set the irq filtering on the given pin
Expand Down
22 changes: 22 additions & 0 deletions include/asm-arm/arch-s3c2410/regs-gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
* 28-Mar-2005 LCVR Fixed definition of GPB10
* 26-Oct-2005 BJD Added generic configuration types
* 27-Nov-2005 LCVR Added definitions to S3C2400 registers
* 15-Jan-2006 LCVR Written S3C24XX_GPIO_BASE() macro
*/


Expand All @@ -39,6 +40,27 @@
#define S3C2410_GPIO_BANKG (32*6)
#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_OFFSET(pin) ((pin) & 31)

Expand Down

0 comments on commit 0ca5bc3

Please sign in to comment.