2011-02-14 16:33:10 +09:00
/* linux/arch/arm/mach-exynos4/gpiolib.c
2010-10-14 15:52:16 +09:00
*
2011-02-14 16:33:10 +09:00
* Copyright ( c ) 2010 - 2011 Samsung Electronics Co . , Ltd .
2010-10-14 15:52:16 +09:00
* http : //www.samsung.com
*
2011-02-14 16:33:10 +09:00
* EXYNOS4 - GPIOlib support
2010-10-14 15:52:16 +09:00
*
* 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>
# include <linux/gpio.h>
# include <mach/map.h>
# include <plat/gpio-core.h>
# include <plat/gpio-cfg.h>
# include <plat/gpio-cfg-helpers.h>
2011-06-07 14:04:49 +05:30
int s3c_gpio_setpull_exynos4 ( struct s3c_gpio_chip * chip ,
unsigned int off , s3c_gpio_pull_t pull )
{
if ( pull = = S3C_GPIO_PULL_UP )
pull = 3 ;
return s3c_gpio_setpull_updown ( chip , off , pull ) ;
}
s3c_gpio_pull_t s3c_gpio_getpull_exynos4 ( struct s3c_gpio_chip * chip ,
unsigned int off )
{
s3c_gpio_pull_t pull ;
pull = s3c_gpio_getpull_updown ( chip , off ) ;
if ( pull = = 3 )
pull = S3C_GPIO_PULL_UP ;
return pull ;
}
2010-10-14 15:52:16 +09:00
static struct s3c_gpio_cfg gpio_cfg = {
. set_config = s3c_gpio_setcfg_s3c64xx_4bit ,
2011-06-07 14:04:49 +05:30
. set_pull = s3c_gpio_setpull_exynos4 ,
. get_pull = s3c_gpio_getpull_exynos4 ,
2010-10-14 15:52:16 +09:00
} ;
static struct s3c_gpio_cfg gpio_cfg_noint = {
. set_config = s3c_gpio_setcfg_s3c64xx_4bit ,
2011-06-07 14:04:49 +05:30
. set_pull = s3c_gpio_setpull_exynos4 ,
. get_pull = s3c_gpio_getpull_exynos4 ,
2010-10-14 15:52:16 +09:00
} ;
/*
* Following are the gpio banks in v310 .
*
* The ' config ' member when left to NULL , is initialized to the default
* structure gpio_cfg in the init function below .
*
* The ' base ' member is also initialized in the init function below .
* Note : The initialization of ' base ' member of s3c_gpio_chip structure
* uses the above macro and depends on the banks being listed in order here .
*/
2011-02-14 16:33:10 +09:00
static struct s3c_gpio_chip exynos4_gpio_part1_4bit [ ] = {
2010-10-14 15:52:16 +09:00
{
. chip = {
2011-02-14 16:33:10 +09:00
. base = EXYNOS4_GPA0 ( 0 ) ,
. ngpio = EXYNOS4_GPIO_A0_NR ,
2010-10-14 15:52:16 +09:00
. label = " GPA0 " ,
} ,
} , {
. chip = {
2011-02-14 16:33:10 +09:00
. base = EXYNOS4_GPA1 ( 0 ) ,
. ngpio = EXYNOS4_GPIO_A1_NR ,
2010-10-14 15:52:16 +09:00
. label = " GPA1 " ,
} ,
} , {
. chip = {
2011-02-14 16:33:10 +09:00
. base = EXYNOS4_GPB ( 0 ) ,
. ngpio = EXYNOS4_GPIO_B_NR ,
2010-10-14 15:52:16 +09:00
. label = " GPB " ,
} ,
} , {
. chip = {
2011-02-14 16:33:10 +09:00
. base = EXYNOS4_GPC0 ( 0 ) ,
. ngpio = EXYNOS4_GPIO_C0_NR ,
2010-10-14 15:52:16 +09:00
. label = " GPC0 " ,
} ,
} , {
. chip = {
2011-02-14 16:33:10 +09:00
. base = EXYNOS4_GPC1 ( 0 ) ,
. ngpio = EXYNOS4_GPIO_C1_NR ,
2010-10-14 15:52:16 +09:00
. label = " GPC1 " ,
} ,
} , {
. chip = {
2011-02-14 16:33:10 +09:00
. base = EXYNOS4_GPD0 ( 0 ) ,
. ngpio = EXYNOS4_GPIO_D0_NR ,
2010-10-14 15:52:16 +09:00
. label = " GPD0 " ,
} ,
} , {
. chip = {
2011-02-14 16:33:10 +09:00
. base = EXYNOS4_GPD1 ( 0 ) ,
. ngpio = EXYNOS4_GPIO_D1_NR ,
2010-10-14 15:52:16 +09:00
. label = " GPD1 " ,
} ,
} , {
. chip = {
2011-02-14 16:33:10 +09:00
. base = EXYNOS4_GPE0 ( 0 ) ,
. ngpio = EXYNOS4_GPIO_E0_NR ,
2010-10-14 15:52:16 +09:00
. label = " GPE0 " ,
} ,
} , {
. chip = {
2011-02-14 16:33:10 +09:00
. base = EXYNOS4_GPE1 ( 0 ) ,
. ngpio = EXYNOS4_GPIO_E1_NR ,
2010-10-14 15:52:16 +09:00
. label = " GPE1 " ,
} ,
} , {
. chip = {
2011-02-14 16:33:10 +09:00
. base = EXYNOS4_GPE2 ( 0 ) ,
. ngpio = EXYNOS4_GPIO_E2_NR ,
2010-10-14 15:52:16 +09:00
. label = " GPE2 " ,
} ,
} , {
. chip = {
2011-02-14 16:33:10 +09:00
. base = EXYNOS4_GPE3 ( 0 ) ,
. ngpio = EXYNOS4_GPIO_E3_NR ,
2010-10-14 15:52:16 +09:00
. label = " GPE3 " ,
} ,
} , {
. chip = {
2011-02-14 16:33:10 +09:00
. base = EXYNOS4_GPE4 ( 0 ) ,
. ngpio = EXYNOS4_GPIO_E4_NR ,
2010-10-14 15:52:16 +09:00
. label = " GPE4 " ,
} ,
} , {
. chip = {
2011-02-14 16:33:10 +09:00
. base = EXYNOS4_GPF0 ( 0 ) ,
. ngpio = EXYNOS4_GPIO_F0_NR ,
2010-10-14 15:52:16 +09:00
. label = " GPF0 " ,
} ,
} , {
. chip = {
2011-02-14 16:33:10 +09:00
. base = EXYNOS4_GPF1 ( 0 ) ,
. ngpio = EXYNOS4_GPIO_F1_NR ,
2010-10-14 15:52:16 +09:00
. label = " GPF1 " ,
} ,
} , {
. chip = {
2011-02-14 16:33:10 +09:00
. base = EXYNOS4_GPF2 ( 0 ) ,
. ngpio = EXYNOS4_GPIO_F2_NR ,
2010-10-14 15:52:16 +09:00
. label = " GPF2 " ,
} ,
} , {
. chip = {
2011-02-14 16:33:10 +09:00
. base = EXYNOS4_GPF3 ( 0 ) ,
. ngpio = EXYNOS4_GPIO_F3_NR ,
2010-10-14 15:52:16 +09:00
. label = " GPF3 " ,
} ,
} ,
} ;
2011-02-14 16:33:10 +09:00
static struct s3c_gpio_chip exynos4_gpio_part2_4bit [ ] = {
2010-10-14 15:52:16 +09:00
{
. chip = {
2011-02-14 16:33:10 +09:00
. base = EXYNOS4_GPJ0 ( 0 ) ,
. ngpio = EXYNOS4_GPIO_J0_NR ,
2010-10-14 15:52:16 +09:00
. label = " GPJ0 " ,
} ,
} , {
. chip = {
2011-02-14 16:33:10 +09:00
. base = EXYNOS4_GPJ1 ( 0 ) ,
. ngpio = EXYNOS4_GPIO_J1_NR ,
2010-10-14 15:52:16 +09:00
. label = " GPJ1 " ,
} ,
} , {
. chip = {
2011-02-14 16:33:10 +09:00
. base = EXYNOS4_GPK0 ( 0 ) ,
. ngpio = EXYNOS4_GPIO_K0_NR ,
2010-10-14 15:52:16 +09:00
. label = " GPK0 " ,
} ,
} , {
. chip = {
2011-02-14 16:33:10 +09:00
. base = EXYNOS4_GPK1 ( 0 ) ,
. ngpio = EXYNOS4_GPIO_K1_NR ,
2010-10-14 15:52:16 +09:00
. label = " GPK1 " ,
} ,
} , {
. chip = {
2011-02-14 16:33:10 +09:00
. base = EXYNOS4_GPK2 ( 0 ) ,
. ngpio = EXYNOS4_GPIO_K2_NR ,
2010-10-14 15:52:16 +09:00
. label = " GPK2 " ,
} ,
} , {
. chip = {
2011-02-14 16:33:10 +09:00
. base = EXYNOS4_GPK3 ( 0 ) ,
. ngpio = EXYNOS4_GPIO_K3_NR ,
2010-10-14 15:52:16 +09:00
. label = " GPK3 " ,
} ,
} , {
. chip = {
2011-02-14 16:33:10 +09:00
. base = EXYNOS4_GPL0 ( 0 ) ,
. ngpio = EXYNOS4_GPIO_L0_NR ,
2010-10-14 15:52:16 +09:00
. label = " GPL0 " ,
} ,
} , {
. chip = {
2011-02-14 16:33:10 +09:00
. base = EXYNOS4_GPL1 ( 0 ) ,
. ngpio = EXYNOS4_GPIO_L1_NR ,
2010-10-14 15:52:16 +09:00
. label = " GPL1 " ,
} ,
} , {
. chip = {
2011-02-14 16:33:10 +09:00
. base = EXYNOS4_GPL2 ( 0 ) ,
. ngpio = EXYNOS4_GPIO_L2_NR ,
2010-10-14 15:52:16 +09:00
. label = " GPL2 " ,
} ,
2011-03-15 21:17:43 +09:00
} , {
. config = & gpio_cfg_noint ,
. chip = {
. base = EXYNOS4_GPY0 ( 0 ) ,
. ngpio = EXYNOS4_GPIO_Y0_NR ,
. label = " GPY0 " ,
} ,
} , {
. config = & gpio_cfg_noint ,
. chip = {
. base = EXYNOS4_GPY1 ( 0 ) ,
. ngpio = EXYNOS4_GPIO_Y1_NR ,
. label = " GPY1 " ,
} ,
} , {
. config = & gpio_cfg_noint ,
. chip = {
. base = EXYNOS4_GPY2 ( 0 ) ,
. ngpio = EXYNOS4_GPIO_Y2_NR ,
. label = " GPY2 " ,
} ,
} , {
. config = & gpio_cfg_noint ,
. chip = {
. base = EXYNOS4_GPY3 ( 0 ) ,
. ngpio = EXYNOS4_GPIO_Y3_NR ,
. label = " GPY3 " ,
} ,
} , {
. config = & gpio_cfg_noint ,
. chip = {
. base = EXYNOS4_GPY4 ( 0 ) ,
. ngpio = EXYNOS4_GPIO_Y4_NR ,
. label = " GPY4 " ,
} ,
} , {
. config = & gpio_cfg_noint ,
. chip = {
. base = EXYNOS4_GPY5 ( 0 ) ,
. ngpio = EXYNOS4_GPIO_Y5_NR ,
. label = " GPY5 " ,
} ,
} , {
. config = & gpio_cfg_noint ,
. chip = {
. base = EXYNOS4_GPY6 ( 0 ) ,
. ngpio = EXYNOS4_GPIO_Y6_NR ,
. label = " GPY6 " ,
} ,
2010-10-14 15:52:16 +09:00
} , {
. base = ( S5P_VA_GPIO2 + 0xC00 ) ,
. config = & gpio_cfg_noint ,
. irq_base = IRQ_EINT ( 0 ) ,
. chip = {
2011-02-14 16:33:10 +09:00
. base = EXYNOS4_GPX0 ( 0 ) ,
. ngpio = EXYNOS4_GPIO_X0_NR ,
2010-10-14 15:52:16 +09:00
. label = " GPX0 " ,
. to_irq = samsung_gpiolib_to_irq ,
} ,
} , {
. base = ( S5P_VA_GPIO2 + 0xC20 ) ,
. config = & gpio_cfg_noint ,
. irq_base = IRQ_EINT ( 8 ) ,
. chip = {
2011-02-14 16:33:10 +09:00
. base = EXYNOS4_GPX1 ( 0 ) ,
. ngpio = EXYNOS4_GPIO_X1_NR ,
2010-10-14 15:52:16 +09:00
. label = " GPX1 " ,
. to_irq = samsung_gpiolib_to_irq ,
} ,
} , {
. base = ( S5P_VA_GPIO2 + 0xC40 ) ,
. config = & gpio_cfg_noint ,
. irq_base = IRQ_EINT ( 16 ) ,
. chip = {
2011-02-14 16:33:10 +09:00
. base = EXYNOS4_GPX2 ( 0 ) ,
. ngpio = EXYNOS4_GPIO_X2_NR ,
2010-10-14 15:52:16 +09:00
. label = " GPX2 " ,
. to_irq = samsung_gpiolib_to_irq ,
} ,
} , {
. base = ( S5P_VA_GPIO2 + 0xC60 ) ,
. config = & gpio_cfg_noint ,
. irq_base = IRQ_EINT ( 24 ) ,
. chip = {
2011-02-14 16:33:10 +09:00
. base = EXYNOS4_GPX3 ( 0 ) ,
. ngpio = EXYNOS4_GPIO_X3_NR ,
2010-10-14 15:52:16 +09:00
. label = " GPX3 " ,
. to_irq = samsung_gpiolib_to_irq ,
} ,
} ,
} ;
2011-02-14 16:33:10 +09:00
static struct s3c_gpio_chip exynos4_gpio_part3_4bit [ ] = {
2010-10-14 15:52:16 +09:00
{
. chip = {
2011-02-14 16:33:10 +09:00
. base = EXYNOS4_GPZ ( 0 ) ,
. ngpio = EXYNOS4_GPIO_Z_NR ,
2010-10-14 15:52:16 +09:00
. label = " GPZ " ,
} ,
} ,
} ;
2011-02-14 16:33:10 +09:00
static __init int exynos4_gpiolib_init ( void )
2010-10-14 15:52:16 +09:00
{
struct s3c_gpio_chip * chip ;
int i ;
2011-03-15 21:17:43 +09:00
int group = 0 ;
2010-10-14 15:52:16 +09:00
int nr_chips ;
/* GPIO part 1 */
2011-02-14 16:33:10 +09:00
chip = exynos4_gpio_part1_4bit ;
nr_chips = ARRAY_SIZE ( exynos4_gpio_part1_4bit ) ;
2010-10-14 15:52:16 +09:00
for ( i = 0 ; i < nr_chips ; i + + , chip + + ) {
2011-03-15 21:17:43 +09:00
if ( chip - > config = = NULL ) {
2010-10-14 15:52:16 +09:00
chip - > config = & gpio_cfg ;
2011-03-15 21:17:43 +09:00
/* Assign the GPIO interrupt group */
chip - > group = group + + ;
}
2010-10-14 15:52:16 +09:00
if ( chip - > base = = NULL )
chip - > base = S5P_VA_GPIO1 + ( i ) * 0x20 ;
}
2011-02-14 16:33:10 +09:00
samsung_gpiolib_add_4bit_chips ( exynos4_gpio_part1_4bit , nr_chips ) ;
2010-10-14 15:52:16 +09:00
/* GPIO part 2 */
2011-02-14 16:33:10 +09:00
chip = exynos4_gpio_part2_4bit ;
nr_chips = ARRAY_SIZE ( exynos4_gpio_part2_4bit ) ;
2010-10-14 15:52:16 +09:00
for ( i = 0 ; i < nr_chips ; i + + , chip + + ) {
2011-03-15 21:17:43 +09:00
if ( chip - > config = = NULL ) {
2010-10-14 15:52:16 +09:00
chip - > config = & gpio_cfg ;
2011-03-15 21:17:43 +09:00
/* Assign the GPIO interrupt group */
chip - > group = group + + ;
}
2010-10-14 15:52:16 +09:00
if ( chip - > base = = NULL )
chip - > base = S5P_VA_GPIO2 + ( i ) * 0x20 ;
}
2011-02-14 16:33:10 +09:00
samsung_gpiolib_add_4bit_chips ( exynos4_gpio_part2_4bit , nr_chips ) ;
2010-10-14 15:52:16 +09:00
/* GPIO part 3 */
2011-02-14 16:33:10 +09:00
chip = exynos4_gpio_part3_4bit ;
nr_chips = ARRAY_SIZE ( exynos4_gpio_part3_4bit ) ;
2010-10-14 15:52:16 +09:00
for ( i = 0 ; i < nr_chips ; i + + , chip + + ) {
2011-03-15 21:17:43 +09:00
if ( chip - > config = = NULL ) {
2010-10-14 15:52:16 +09:00
chip - > config = & gpio_cfg ;
2011-03-15 21:17:43 +09:00
/* Assign the GPIO interrupt group */
chip - > group = group + + ;
}
2010-10-14 15:52:16 +09:00
if ( chip - > base = = NULL )
chip - > base = S5P_VA_GPIO3 + ( i ) * 0x20 ;
}
2011-02-14 16:33:10 +09:00
samsung_gpiolib_add_4bit_chips ( exynos4_gpio_part3_4bit , nr_chips ) ;
2011-03-15 21:17:43 +09:00
s5p_register_gpioint_bank ( IRQ_GPIO_XA , 0 , IRQ_GPIO1_NR_GROUPS ) ;
s5p_register_gpioint_bank ( IRQ_GPIO_XB , IRQ_GPIO1_NR_GROUPS , IRQ_GPIO2_NR_GROUPS ) ;
2010-10-14 15:52:16 +09:00
return 0 ;
}
2011-02-14 16:33:10 +09:00
core_initcall ( exynos4_gpiolib_init ) ;