2008-07-03 11:24:25 +01:00
/* linux/arch/arm/plat-s3c24xx/gpiolib.c
*
* Copyright ( c ) 2008 Simtec Electronics
* http : //armlinux.simtec.co.uk/
* Ben Dooks < ben @ simtec . co . uk >
*
* S3C24XX GPIOlib 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 .
*/
# include <linux/kernel.h>
# include <linux/init.h>
# include <linux/module.h>
# include <linux/interrupt.h>
2009-05-17 22:47:07 +01:00
# include <linux/sysdev.h>
2008-07-03 11:24:25 +01:00
# include <linux/ioport.h>
# include <linux/io.h>
# include <linux/gpio.h>
2009-04-17 12:36:43 +01:00
# include <mach/gpio-core.h>
2008-08-05 16:14:15 +01:00
# include <mach/hardware.h>
2008-07-03 11:24:25 +01:00
# include <asm/irq.h>
2008-12-12 00:24:30 +00:00
# include <plat/pm.h>
2008-07-03 11:24:25 +01:00
2008-08-05 16:14:15 +01:00
# include <mach/regs-gpio.h>
2008-07-03 11:24:25 +01:00
static int s3c24xx_gpiolib_banka_input ( struct gpio_chip * chip , unsigned offset )
{
return - EINVAL ;
}
static int s3c24xx_gpiolib_banka_output ( struct gpio_chip * chip ,
unsigned offset , int value )
{
2008-10-31 16:14:31 +00:00
struct s3c_gpio_chip * ourchip = to_s3c_gpio ( chip ) ;
2008-07-03 11:24:25 +01:00
void __iomem * base = ourchip - > base ;
unsigned long flags ;
unsigned long dat ;
unsigned long con ;
local_irq_save ( flags ) ;
con = __raw_readl ( base + 0x00 ) ;
dat = __raw_readl ( base + 0x04 ) ;
dat & = ~ ( 1 < < offset ) ;
if ( value )
dat | = 1 < < offset ;
__raw_writel ( dat , base + 0x04 ) ;
con & = ~ ( 1 < < offset ) ;
__raw_writel ( con , base + 0x00 ) ;
__raw_writel ( dat , base + 0x04 ) ;
local_irq_restore ( flags ) ;
return 0 ;
}
2009-01-08 12:40:50 +00:00
static int s3c24xx_gpiolib_bankf_toirq ( struct gpio_chip * chip , unsigned offset )
{
if ( offset < 4 )
return IRQ_EINT0 + offset ;
if ( offset < 8 )
return IRQ_EINT4 + offset - 4 ;
return - EINVAL ;
}
static int s3c24xx_gpiolib_bankg_toirq ( struct gpio_chip * chip , unsigned offset )
{
return IRQ_EINT8 + offset ;
}
2008-10-31 16:14:34 +00:00
struct s3c_gpio_chip s3c24xx_gpios [ ] = {
2008-07-03 11:24:25 +01:00
[ 0 ] = {
2009-05-17 22:18:27 +01:00
. base = S3C2410_GPACON ,
2008-12-12 00:24:30 +00:00
. pm = __gpio_pm ( & s3c_gpio_pm_1bit ) ,
2008-07-03 11:24:25 +01:00
. chip = {
2009-05-17 22:32:23 +01:00
. base = S3C2410_GPA ( 0 ) ,
2008-07-03 11:24:25 +01:00
. owner = THIS_MODULE ,
. label = " GPIOA " ,
. ngpio = 24 ,
. direction_input = s3c24xx_gpiolib_banka_input ,
. direction_output = s3c24xx_gpiolib_banka_output ,
} ,
} ,
[ 1 ] = {
2009-05-17 22:18:27 +01:00
. base = S3C2410_GPBCON ,
2008-12-12 00:24:30 +00:00
. pm = __gpio_pm ( & s3c_gpio_pm_2bit ) ,
2008-07-03 11:24:25 +01:00
. chip = {
2009-05-17 22:32:23 +01:00
. base = S3C2410_GPB ( 0 ) ,
2008-07-03 11:24:25 +01:00
. owner = THIS_MODULE ,
. label = " GPIOB " ,
. ngpio = 16 ,
} ,
} ,
[ 2 ] = {
2009-05-17 22:18:27 +01:00
. base = S3C2410_GPCCON ,
2008-12-12 00:24:30 +00:00
. pm = __gpio_pm ( & s3c_gpio_pm_2bit ) ,
2008-07-03 11:24:25 +01:00
. chip = {
2009-05-17 22:32:23 +01:00
. base = S3C2410_GPC ( 0 ) ,
2008-07-03 11:24:25 +01:00
. owner = THIS_MODULE ,
. label = " GPIOC " ,
. ngpio = 16 ,
} ,
} ,
[ 3 ] = {
2009-05-17 22:18:27 +01:00
. base = S3C2410_GPDCON ,
2008-12-12 00:24:30 +00:00
. pm = __gpio_pm ( & s3c_gpio_pm_2bit ) ,
2008-07-03 11:24:25 +01:00
. chip = {
2009-05-17 22:32:23 +01:00
. base = S3C2410_GPD ( 0 ) ,
2008-07-03 11:24:25 +01:00
. owner = THIS_MODULE ,
. label = " GPIOD " ,
. ngpio = 16 ,
} ,
} ,
[ 4 ] = {
2009-05-17 22:18:27 +01:00
. base = S3C2410_GPECON ,
2008-12-12 00:24:30 +00:00
. pm = __gpio_pm ( & s3c_gpio_pm_2bit ) ,
2008-07-03 11:24:25 +01:00
. chip = {
2009-05-17 22:32:23 +01:00
. base = S3C2410_GPE ( 0 ) ,
2008-07-03 11:24:25 +01:00
. label = " GPIOE " ,
. owner = THIS_MODULE ,
. ngpio = 16 ,
} ,
} ,
[ 5 ] = {
2009-05-17 22:18:27 +01:00
. base = S3C2410_GPFCON ,
2008-12-12 00:24:30 +00:00
. pm = __gpio_pm ( & s3c_gpio_pm_2bit ) ,
2008-07-03 11:24:25 +01:00
. chip = {
2009-05-17 22:32:23 +01:00
. base = S3C2410_GPF ( 0 ) ,
2008-07-03 11:24:25 +01:00
. owner = THIS_MODULE ,
. label = " GPIOF " ,
. ngpio = 8 ,
2009-01-08 12:40:50 +00:00
. to_irq = s3c24xx_gpiolib_bankf_toirq ,
2008-07-03 11:24:25 +01:00
} ,
} ,
[ 6 ] = {
2009-05-17 22:18:27 +01:00
. base = S3C2410_GPGCON ,
2008-12-12 00:24:30 +00:00
. pm = __gpio_pm ( & s3c_gpio_pm_2bit ) ,
2008-07-03 11:24:25 +01:00
. chip = {
2009-05-17 22:32:23 +01:00
. base = S3C2410_GPG ( 0 ) ,
2008-07-03 11:24:25 +01:00
. owner = THIS_MODULE ,
. label = " GPIOG " ,
2009-05-18 20:10:43 +01:00
. ngpio = 16 ,
2009-01-08 12:40:50 +00:00
. to_irq = s3c24xx_gpiolib_bankg_toirq ,
2008-07-03 11:24:25 +01:00
} ,
2009-05-18 20:10:43 +01:00
} , {
. base = S3C2410_GPHCON ,
. pm = __gpio_pm ( & s3c_gpio_pm_2bit ) ,
. chip = {
. base = S3C2410_GPH ( 0 ) ,
. owner = THIS_MODULE ,
. label = " GPIOH " ,
. ngpio = 11 ,
} ,
2008-07-03 11:24:25 +01:00
} ,
} ;
static __init int s3c24xx_gpiolib_init ( void )
{
2008-10-31 16:14:34 +00:00
struct s3c_gpio_chip * chip = s3c24xx_gpios ;
2008-07-03 11:24:25 +01:00
int gpn ;
2008-10-31 16:14:34 +00:00
for ( gpn = 0 ; gpn < ARRAY_SIZE ( s3c24xx_gpios ) ; gpn + + , chip + + )
2008-10-31 16:14:31 +00:00
s3c_gpiolib_add ( chip ) ;
2008-07-03 11:24:25 +01:00
return 0 ;
}
2009-05-18 20:03:23 +01:00
core_initcall ( s3c24xx_gpiolib_init ) ;