2008-07-03 14:24:25 +04:00
/* linux/arch/arm/plat-s3c24xx/gpiolib.c
*
2010-05-03 12:19:49 +04:00
* Copyright ( c ) 2008 - 2010 Simtec Electronics
2008-07-03 14:24:25 +04:00
* 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-18 01:47:07 +04:00
# include <linux/sysdev.h>
2008-07-03 14:24:25 +04:00
# include <linux/ioport.h>
# include <linux/io.h>
# include <linux/gpio.h>
2010-01-19 11:14:46 +03:00
# include <plat/gpio-core.h>
2010-04-30 14:30:35 +04:00
# include <plat/gpio-cfg.h>
# include <plat/gpio-cfg-helpers.h>
2008-08-05 19:14:15 +04:00
# include <mach/hardware.h>
2008-07-03 14:24:25 +04:00
# include <asm/irq.h>
2008-12-12 03:24:30 +03:00
# include <plat/pm.h>
2008-07-03 14:24:25 +04:00
2008-08-05 19:14:15 +04:00
# include <mach/regs-gpio.h>
2008-07-03 14:24:25 +04: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 19:14:31 +03:00
struct s3c_gpio_chip * ourchip = to_s3c_gpio ( chip ) ;
2008-07-03 14:24:25 +04: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 15:40:50 +03: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 ;
}
2010-04-30 14:30:35 +04:00
static struct s3c_gpio_cfg s3c24xx_gpiocfg_banka = {
. set_config = s3c_gpio_setcfg_s3c24xx_a ,
2010-05-06 05:27:16 +04:00
. get_config = s3c_gpio_getcfg_s3c24xx_a ,
2010-04-30 14:30:35 +04:00
} ;
struct s3c_gpio_cfg s3c24xx_gpiocfg_default = {
. set_config = s3c_gpio_setcfg_s3c24xx ,
2010-05-06 05:27:16 +04:00
. get_config = s3c_gpio_getcfg_s3c24xx ,
2010-04-30 14:30:35 +04:00
} ;
2008-10-31 19:14:34 +03:00
struct s3c_gpio_chip s3c24xx_gpios [ ] = {
2008-07-03 14:24:25 +04:00
[ 0 ] = {
2009-05-18 01:18:27 +04:00
. base = S3C2410_GPACON ,
2008-12-12 03:24:30 +03:00
. pm = __gpio_pm ( & s3c_gpio_pm_1bit ) ,
2010-04-30 14:30:35 +04:00
. config = & s3c24xx_gpiocfg_banka ,
2008-07-03 14:24:25 +04:00
. chip = {
2009-05-18 01:32:23 +04:00
. base = S3C2410_GPA ( 0 ) ,
2008-07-03 14:24:25 +04:00
. owner = THIS_MODULE ,
. label = " GPIOA " ,
. ngpio = 24 ,
. direction_input = s3c24xx_gpiolib_banka_input ,
. direction_output = s3c24xx_gpiolib_banka_output ,
} ,
} ,
[ 1 ] = {
2009-05-18 01:18:27 +04:00
. base = S3C2410_GPBCON ,
2008-12-12 03:24:30 +03:00
. pm = __gpio_pm ( & s3c_gpio_pm_2bit ) ,
2008-07-03 14:24:25 +04:00
. chip = {
2009-05-18 01:32:23 +04:00
. base = S3C2410_GPB ( 0 ) ,
2008-07-03 14:24:25 +04:00
. owner = THIS_MODULE ,
. label = " GPIOB " ,
. ngpio = 16 ,
} ,
} ,
[ 2 ] = {
2009-05-18 01:18:27 +04:00
. base = S3C2410_GPCCON ,
2008-12-12 03:24:30 +03:00
. pm = __gpio_pm ( & s3c_gpio_pm_2bit ) ,
2008-07-03 14:24:25 +04:00
. chip = {
2009-05-18 01:32:23 +04:00
. base = S3C2410_GPC ( 0 ) ,
2008-07-03 14:24:25 +04:00
. owner = THIS_MODULE ,
. label = " GPIOC " ,
. ngpio = 16 ,
} ,
} ,
[ 3 ] = {
2009-05-18 01:18:27 +04:00
. base = S3C2410_GPDCON ,
2008-12-12 03:24:30 +03:00
. pm = __gpio_pm ( & s3c_gpio_pm_2bit ) ,
2008-07-03 14:24:25 +04:00
. chip = {
2009-05-18 01:32:23 +04:00
. base = S3C2410_GPD ( 0 ) ,
2008-07-03 14:24:25 +04:00
. owner = THIS_MODULE ,
. label = " GPIOD " ,
. ngpio = 16 ,
} ,
} ,
[ 4 ] = {
2009-05-18 01:18:27 +04:00
. base = S3C2410_GPECON ,
2008-12-12 03:24:30 +03:00
. pm = __gpio_pm ( & s3c_gpio_pm_2bit ) ,
2008-07-03 14:24:25 +04:00
. chip = {
2009-05-18 01:32:23 +04:00
. base = S3C2410_GPE ( 0 ) ,
2008-07-03 14:24:25 +04:00
. label = " GPIOE " ,
. owner = THIS_MODULE ,
. ngpio = 16 ,
} ,
} ,
[ 5 ] = {
2009-05-18 01:18:27 +04:00
. base = S3C2410_GPFCON ,
2008-12-12 03:24:30 +03:00
. pm = __gpio_pm ( & s3c_gpio_pm_2bit ) ,
2008-07-03 14:24:25 +04:00
. chip = {
2009-05-18 01:32:23 +04:00
. base = S3C2410_GPF ( 0 ) ,
2008-07-03 14:24:25 +04:00
. owner = THIS_MODULE ,
. label = " GPIOF " ,
. ngpio = 8 ,
2009-01-08 15:40:50 +03:00
. to_irq = s3c24xx_gpiolib_bankf_toirq ,
2008-07-03 14:24:25 +04:00
} ,
} ,
[ 6 ] = {
2009-05-18 01:18:27 +04:00
. base = S3C2410_GPGCON ,
2008-12-12 03:24:30 +03:00
. pm = __gpio_pm ( & s3c_gpio_pm_2bit ) ,
2010-10-01 06:24:39 +04:00
. irq_base = IRQ_EINT8 ,
2008-07-03 14:24:25 +04:00
. chip = {
2009-05-18 01:32:23 +04:00
. base = S3C2410_GPG ( 0 ) ,
2008-07-03 14:24:25 +04:00
. owner = THIS_MODULE ,
. label = " GPIOG " ,
2009-05-18 23:10:43 +04:00
. ngpio = 16 ,
2010-10-01 06:24:39 +04:00
. to_irq = samsung_gpiolib_to_irq ,
2008-07-03 14:24:25 +04:00
} ,
2009-05-18 23:10:43 +04: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 14:24:25 +04:00
} ,
2010-05-03 12:19:49 +04:00
/* GPIOS for the S3C2443 and later devices. */
{
. base = S3C2440_GPJCON ,
. pm = __gpio_pm ( & s3c_gpio_pm_2bit ) ,
. chip = {
. base = S3C2410_GPJ ( 0 ) ,
. owner = THIS_MODULE ,
. label = " GPIOJ " ,
. ngpio = 16 ,
} ,
} , {
. base = S3C2443_GPKCON ,
. pm = __gpio_pm ( & s3c_gpio_pm_2bit ) ,
. chip = {
. base = S3C2410_GPK ( 0 ) ,
. owner = THIS_MODULE ,
. label = " GPIOK " ,
. ngpio = 16 ,
} ,
} , {
. base = S3C2443_GPLCON ,
. pm = __gpio_pm ( & s3c_gpio_pm_2bit ) ,
. chip = {
. base = S3C2410_GPL ( 0 ) ,
. owner = THIS_MODULE ,
. label = " GPIOL " ,
. ngpio = 15 ,
} ,
} , {
. base = S3C2443_GPMCON ,
. pm = __gpio_pm ( & s3c_gpio_pm_2bit ) ,
. chip = {
. base = S3C2410_GPM ( 0 ) ,
. owner = THIS_MODULE ,
. label = " GPIOM " ,
. ngpio = 2 ,
} ,
} ,
2008-07-03 14:24:25 +04:00
} ;
2010-05-03 12:19:49 +04:00
2008-07-03 14:24:25 +04:00
static __init int s3c24xx_gpiolib_init ( void )
{
2008-10-31 19:14:34 +03:00
struct s3c_gpio_chip * chip = s3c24xx_gpios ;
2008-07-03 14:24:25 +04:00
int gpn ;
2010-04-30 14:30:35 +04:00
for ( gpn = 0 ; gpn < ARRAY_SIZE ( s3c24xx_gpios ) ; gpn + + , chip + + ) {
if ( ! chip - > config )
chip - > config = & s3c24xx_gpiocfg_default ;
2008-10-31 19:14:31 +03:00
s3c_gpiolib_add ( chip ) ;
2010-04-30 14:30:35 +04:00
}
2008-07-03 14:24:25 +04:00
return 0 ;
}
2009-05-18 23:03:23 +04:00
core_initcall ( s3c24xx_gpiolib_init ) ;