2008-10-31 16:14:33 +00:00
/* arch/arm/plat-s3c64xx/gpiolib.c
*
* Copyright 2008 Openmoko , Inc .
* Copyright 2008 Simtec Electronics
* Ben Dooks < ben @ simtec . co . uk >
* http : //armlinux.simtec.co.uk/
*
* S3C64XX - GPIOlib support
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*/
# include <linux/kernel.h>
# include <linux/irq.h>
# include <linux/io.h>
2010-08-05 07:54:49 +09:00
# include <linux/gpio.h>
2008-10-31 16:14:33 +00:00
# include <mach/map.h>
2010-01-19 17:14:46 +09:00
# include <plat/gpio-core.h>
2008-10-31 16:14:34 +00:00
# include <plat/gpio-cfg.h>
# include <plat/gpio-cfg-helpers.h>
2010-01-26 10:45:40 +09:00
# include <mach/regs-gpio.h>
2008-10-31 16:14:33 +00:00
/* GPIO bank summary:
*
* Bank GPIOs Style SlpCon ExtInt Group
* A 8 4 Bit Yes 1
* B 7 4 Bit Yes 1
* C 8 4 Bit Yes 2
* D 5 4 Bit Yes 3
* E 5 4 Bit Yes None
* F 16 2 Bit Yes 4 [ 1 ]
* G 7 4 Bit Yes 5
* H 10 4 Bit [ 2 ] Yes 6
* I 16 2 Bit Yes None
* J 12 2 Bit Yes None
* K 16 4 Bit [ 2 ] No None
* L 15 4 Bit [ 2 ] No None
* M 6 4 Bit No IRQ_EINT
* N 16 2 Bit No IRQ_EINT
* O 16 2 Bit Yes 7
* P 15 2 Bit Yes 8
* Q 9 2 Bit Yes 9
*
* [ 1 ] BANKF pins 14 , 15 do not form part of the external interrupt sources
* [ 2 ] BANK has two control registers , GPxCON0 and GPxCON1
*/
2008-10-31 16:14:34 +00:00
static struct s3c_gpio_cfg gpio_4bit_cfg_noint = {
. set_config = s3c_gpio_setcfg_s3c64xx_4bit ,
2010-05-06 10:27:16 +09:00
. get_config = s3c_gpio_getcfg_s3c64xx_4bit ,
2008-10-31 16:14:34 +00:00
. set_pull = s3c_gpio_setpull_updown ,
. get_pull = s3c_gpio_getpull_updown ,
} ;
static struct s3c_gpio_cfg gpio_4bit_cfg_eint0111 = {
. cfg_eint = 7 ,
. set_config = s3c_gpio_setcfg_s3c64xx_4bit ,
2010-05-06 10:27:16 +09:00
. get_config = s3c_gpio_getcfg_s3c64xx_4bit ,
2008-10-31 16:14:34 +00:00
. set_pull = s3c_gpio_setpull_updown ,
. get_pull = s3c_gpio_getpull_updown ,
} ;
static struct s3c_gpio_cfg gpio_4bit_cfg_eint0011 = {
. cfg_eint = 3 ,
2010-05-06 10:27:16 +09:00
. get_config = s3c_gpio_getcfg_s3c64xx_4bit ,
2008-10-31 16:14:34 +00:00
. set_config = s3c_gpio_setcfg_s3c64xx_4bit ,
. set_pull = s3c_gpio_setpull_updown ,
. get_pull = s3c_gpio_getpull_updown ,
} ;
2011-03-04 07:55:44 +09:00
static int s3c64xx_gpio2int_gpm ( struct gpio_chip * chip , unsigned pin )
2009-11-20 13:04:13 +01:00
{
return pin < 5 ? IRQ_EINT ( 23 ) + pin : - ENXIO ;
}
2008-10-31 16:14:33 +00:00
static struct s3c_gpio_chip gpio_4bit [ ] = {
{
. base = S3C64XX_GPA_BASE ,
2008-10-31 16:14:34 +00:00
. config = & gpio_4bit_cfg_eint0111 ,
2008-10-31 16:14:33 +00:00
. chip = {
. base = S3C64XX_GPA ( 0 ) ,
. ngpio = S3C64XX_GPIO_A_NR ,
. label = " GPA " ,
} ,
} , {
. base = S3C64XX_GPB_BASE ,
2008-10-31 16:14:34 +00:00
. config = & gpio_4bit_cfg_eint0111 ,
2008-10-31 16:14:33 +00:00
. chip = {
. base = S3C64XX_GPB ( 0 ) ,
. ngpio = S3C64XX_GPIO_B_NR ,
. label = " GPB " ,
} ,
} , {
. base = S3C64XX_GPC_BASE ,
2008-10-31 16:14:34 +00:00
. config = & gpio_4bit_cfg_eint0111 ,
2008-10-31 16:14:33 +00:00
. chip = {
. base = S3C64XX_GPC ( 0 ) ,
. ngpio = S3C64XX_GPIO_C_NR ,
. label = " GPC " ,
} ,
} , {
. base = S3C64XX_GPD_BASE ,
2008-10-31 16:14:34 +00:00
. config = & gpio_4bit_cfg_eint0111 ,
2008-10-31 16:14:33 +00:00
. chip = {
. base = S3C64XX_GPD ( 0 ) ,
. ngpio = S3C64XX_GPIO_D_NR ,
. label = " GPD " ,
} ,
} , {
. base = S3C64XX_GPE_BASE ,
2008-10-31 16:14:34 +00:00
. config = & gpio_4bit_cfg_noint ,
2008-10-31 16:14:33 +00:00
. chip = {
. base = S3C64XX_GPE ( 0 ) ,
. ngpio = S3C64XX_GPIO_E_NR ,
. label = " GPE " ,
} ,
} , {
. base = S3C64XX_GPG_BASE ,
2008-10-31 16:14:34 +00:00
. config = & gpio_4bit_cfg_eint0111 ,
2008-10-31 16:14:33 +00:00
. chip = {
. base = S3C64XX_GPG ( 0 ) ,
. ngpio = S3C64XX_GPIO_G_NR ,
. label = " GPG " ,
} ,
} , {
. base = S3C64XX_GPM_BASE ,
2008-10-31 16:14:34 +00:00
. config = & gpio_4bit_cfg_eint0011 ,
2008-10-31 16:14:33 +00:00
. chip = {
. base = S3C64XX_GPM ( 0 ) ,
. ngpio = S3C64XX_GPIO_M_NR ,
. label = " GPM " ,
2009-11-20 13:04:13 +01:00
. to_irq = s3c64xx_gpio2int_gpm ,
2008-10-31 16:14:33 +00:00
} ,
} ,
} ;
2011-03-04 07:55:44 +09:00
static int s3c64xx_gpio2int_gpl ( struct gpio_chip * chip , unsigned pin )
2009-11-20 13:04:13 +01:00
{
return pin > = 8 ? IRQ_EINT ( 16 ) + pin - 8 : - ENXIO ;
}
2008-10-31 16:14:33 +00:00
static struct s3c_gpio_chip gpio_4bit2 [ ] = {
{
. base = S3C64XX_GPH_BASE + 0x4 ,
2008-10-31 16:14:34 +00:00
. config = & gpio_4bit_cfg_eint0111 ,
2008-10-31 16:14:33 +00:00
. chip = {
. base = S3C64XX_GPH ( 0 ) ,
. ngpio = S3C64XX_GPIO_H_NR ,
. label = " GPH " ,
} ,
} , {
. base = S3C64XX_GPK_BASE + 0x4 ,
2008-10-31 16:14:34 +00:00
. config = & gpio_4bit_cfg_noint ,
2008-10-31 16:14:33 +00:00
. chip = {
. base = S3C64XX_GPK ( 0 ) ,
. ngpio = S3C64XX_GPIO_K_NR ,
. label = " GPK " ,
} ,
} , {
. base = S3C64XX_GPL_BASE + 0x4 ,
2008-10-31 16:14:34 +00:00
. config = & gpio_4bit_cfg_eint0011 ,
2008-10-31 16:14:33 +00:00
. chip = {
. base = S3C64XX_GPL ( 0 ) ,
. ngpio = S3C64XX_GPIO_L_NR ,
. label = " GPL " ,
2009-11-20 13:04:13 +01:00
. to_irq = s3c64xx_gpio2int_gpl ,
2008-10-31 16:14:33 +00:00
} ,
} ,
} ;
2008-10-31 16:14:34 +00:00
static struct s3c_gpio_cfg gpio_2bit_cfg_noint = {
. set_config = s3c_gpio_setcfg_s3c24xx ,
2010-05-06 10:27:16 +09:00
. get_config = s3c_gpio_getcfg_s3c24xx ,
2008-10-31 16:14:34 +00:00
. set_pull = s3c_gpio_setpull_updown ,
. get_pull = s3c_gpio_getpull_updown ,
} ;
static struct s3c_gpio_cfg gpio_2bit_cfg_eint10 = {
. cfg_eint = 2 ,
. set_config = s3c_gpio_setcfg_s3c24xx ,
2010-05-06 10:27:16 +09:00
. get_config = s3c_gpio_getcfg_s3c24xx ,
2008-10-31 16:14:34 +00:00
. set_pull = s3c_gpio_setpull_updown ,
. get_pull = s3c_gpio_getpull_updown ,
} ;
static struct s3c_gpio_cfg gpio_2bit_cfg_eint11 = {
. cfg_eint = 3 ,
. set_config = s3c_gpio_setcfg_s3c24xx ,
2010-05-06 10:27:16 +09:00
. get_config = s3c_gpio_getcfg_s3c24xx ,
2008-10-31 16:14:34 +00:00
. set_pull = s3c_gpio_setpull_updown ,
. get_pull = s3c_gpio_getpull_updown ,
} ;
2008-10-31 16:14:33 +00:00
static struct s3c_gpio_chip gpio_2bit [ ] = {
{
. base = S3C64XX_GPF_BASE ,
2008-10-31 16:14:34 +00:00
. config = & gpio_2bit_cfg_eint11 ,
2008-10-31 16:14:33 +00:00
. chip = {
. base = S3C64XX_GPF ( 0 ) ,
. ngpio = S3C64XX_GPIO_F_NR ,
. label = " GPF " ,
} ,
} , {
. base = S3C64XX_GPI_BASE ,
2008-10-31 16:14:34 +00:00
. config = & gpio_2bit_cfg_noint ,
2008-10-31 16:14:33 +00:00
. chip = {
. base = S3C64XX_GPI ( 0 ) ,
. ngpio = S3C64XX_GPIO_I_NR ,
. label = " GPI " ,
} ,
} , {
. base = S3C64XX_GPJ_BASE ,
2008-10-31 16:14:34 +00:00
. config = & gpio_2bit_cfg_noint ,
2008-10-31 16:14:33 +00:00
. chip = {
. base = S3C64XX_GPJ ( 0 ) ,
. ngpio = S3C64XX_GPIO_J_NR ,
. label = " GPJ " ,
} ,
} , {
. base = S3C64XX_GPN_BASE ,
2010-10-01 11:24:39 +09:00
. irq_base = IRQ_EINT ( 0 ) ,
2008-10-31 16:14:34 +00:00
. config = & gpio_2bit_cfg_eint10 ,
2008-10-31 16:14:33 +00:00
. chip = {
. base = S3C64XX_GPN ( 0 ) ,
. ngpio = S3C64XX_GPIO_N_NR ,
. label = " GPN " ,
2010-10-01 11:24:39 +09:00
. to_irq = samsung_gpiolib_to_irq ,
2008-10-31 16:14:33 +00:00
} ,
} , {
. base = S3C64XX_GPO_BASE ,
2008-10-31 16:14:34 +00:00
. config = & gpio_2bit_cfg_eint11 ,
2008-10-31 16:14:33 +00:00
. chip = {
. base = S3C64XX_GPO ( 0 ) ,
. ngpio = S3C64XX_GPIO_O_NR ,
. label = " GPO " ,
} ,
} , {
. base = S3C64XX_GPP_BASE ,
2008-10-31 16:14:34 +00:00
. config = & gpio_2bit_cfg_eint11 ,
2008-10-31 16:14:33 +00:00
. chip = {
. base = S3C64XX_GPP ( 0 ) ,
. ngpio = S3C64XX_GPIO_P_NR ,
. label = " GPP " ,
} ,
} , {
. base = S3C64XX_GPQ_BASE ,
2008-10-31 16:14:34 +00:00
. config = & gpio_2bit_cfg_eint11 ,
2008-10-31 16:14:33 +00:00
. chip = {
. base = S3C64XX_GPQ ( 0 ) ,
. ngpio = S3C64XX_GPIO_Q_NR ,
. label = " GPQ " ,
} ,
} ,
} ;
2008-12-12 00:24:30 +00:00
static __init void s3c64xx_gpiolib_add_2bit ( struct s3c_gpio_chip * chip )
{
chip - > pm = __gpio_pm ( & s3c_gpio_pm_2bit ) ;
2008-10-31 16:14:33 +00:00
}
static __init void s3c64xx_gpiolib_add ( struct s3c_gpio_chip * chips ,
int nr_chips ,
void ( * fn ) ( struct s3c_gpio_chip * ) )
{
for ( ; nr_chips > 0 ; nr_chips - - , chips + + ) {
if ( fn )
( fn ) ( chips ) ;
s3c_gpiolib_add ( chips ) ;
}
}
static __init int s3c64xx_gpiolib_init ( void )
{
s3c64xx_gpiolib_add ( gpio_4bit , ARRAY_SIZE ( gpio_4bit ) ,
2010-01-19 15:30:54 +09:00
samsung_gpiolib_add_4bit ) ;
2008-10-31 16:14:33 +00:00
s3c64xx_gpiolib_add ( gpio_4bit2 , ARRAY_SIZE ( gpio_4bit2 ) ,
2010-01-19 15:30:54 +09:00
samsung_gpiolib_add_4bit2 ) ;
2008-10-31 16:14:33 +00:00
2008-12-12 00:24:30 +00:00
s3c64xx_gpiolib_add ( gpio_2bit , ARRAY_SIZE ( gpio_2bit ) ,
s3c64xx_gpiolib_add_2bit ) ;
2008-10-31 16:14:33 +00:00
return 0 ;
}
2009-01-23 17:06:23 +00:00
core_initcall ( s3c64xx_gpiolib_init ) ;