From 6b41249785be5e6c5a87099aea218cd5c6bbca38 Mon Sep 17 00:00:00 2001 From: lw Date: Tue, 7 Feb 2012 14:15:09 +0800 Subject: [PATCH] rk30:add gpio support --- arch/arm/mach-rk30/common.c | 1 + arch/arm/mach-rk30/include/mach/gpio.h | 424 +++++++++++++++++++++- drivers/gpio/Makefile | 1 + drivers/gpio/gpio-rk30.c | 483 +++++++++++++++++++++++++ 4 files changed, 907 insertions(+), 2 deletions(-) create mode 100755 drivers/gpio/gpio-rk30.c diff --git a/arch/arm/mach-rk30/common.c b/arch/arm/mach-rk30/common.c index d52e55922d72..3ec0c2d558b7 100755 --- a/arch/arm/mach-rk30/common.c +++ b/arch/arm/mach-rk30/common.c @@ -13,6 +13,7 @@ void __init rk30_init_irq(void) { gic_init(0, IRQ_LOCALTIMER, RK30_GICD_BASE, RK30_GICC_BASE); + rk30_gpio_init(); } void __init rk30_map_io(void) diff --git a/arch/arm/mach-rk30/include/mach/gpio.h b/arch/arm/mach-rk30/include/mach/gpio.h index fb35bf93e53a..ea9390c4d0cc 100644 --- a/arch/arm/mach-rk30/include/mach/gpio.h +++ b/arch/arm/mach-rk30/include/mach/gpio.h @@ -2,9 +2,429 @@ #define __MACH_GPIO_H #include + +typedef enum eGPIOPinLevel +{ + GPIO_LOW=0, + GPIO_HIGH +}eGPIOPinLevel_t; + +typedef enum eGPIOPinDirection +{ + GPIO_IN=0, + GPIO_OUT +}eGPIOPinDirection_t; + +typedef enum GPIOPullType { + PullDisable = 0, + PullEnable, + GPIONormal, //PullEnable, please do not use it + GPIOPullUp, //PullEnable, please do not use it + GPIOPullDown,//PullEnable, please do not use it + GPIONOInit,//PullEnable, please do not use it +}eGPIOPullType_t; + +typedef enum GPIOIntType { + GPIOLevelLow=0, + GPIOLevelHigh, + GPIOEdgelFalling, + GPIOEdgelRising +}eGPIOIntType_t; + +//¶¨ÒåGPIOÏà¹Ø¼Ä´æÆ÷Æ«ÒƵØÖ· +#define GPIO_SWPORT_DR 0x00 +#define GPIO_SWPORT_DDR 0x04 +#define GPIO_INTEN 0x30 +#define GPIO_INTMASK 0x34 +#define GPIO_INTTYPE_LEVEL 0x38 +#define GPIO_INT_POLARITY 0x3c +#define GPIO_INT_STATUS 0x40 +#define GPIO_INT_RAWSTATUS 0x44 +#define GPIO_DEBOUNCE 0x48 +#define GPIO_PORTS_EOI 0x4c +#define GPIO_EXT_PORT 0x50 +#define GPIO_LS_SYNC 0x60 + +#define RK30_ID_GPIO0 0 +#define RK30_ID_GPIO1 1 +#define RK30_ID_GPIO2 2 +#define RK30_ID_GPIO3 3 +#define RK30_ID_GPIO4 4 +#define RK30_ID_GPIO5 5 + +#define NUM_GROUP 32 +#define MAX_BANK 7 + +#define PIN_BASE NR_GIC_IRQS + +#define RK30_TOTOL_GPIO_NUM (NUM_GROUP*MAX_BANK) + +#define SPI_FPGA_EXPANDER_BASE (PIN_BASE+RK30_TOTOL_GPIO_NUM) + +#if defined (CONFIG_SPI_FPGA_GPIO) +#define GPIO_EXPANDER_BASE (PIN_BASE+RK30_TOTOL_GPIO_NUM+CONFIG_SPI_FPGA_GPIO_NUM) +#else +#define GPIO_EXPANDER_BASE (PIN_BASE+RK30_TOTOL_GPIO_NUM) +#endif + +#if defined(CONFIG_IOEXTEND_TCA6424) +#define TCA6424_TOTOL_GPIO_NUM 24 +#define TCA6424_TOTOL_GPIO_IRQ_NUM 24 +#define TCA6424_GPIO_EXPANDER_BASE GPIO_EXPANDER_BASE +#else +#define TCA6424_TOTOL_GPIO_NUM 0 +#define TCA6424_TOTOL_GPIO_IRQ_NUM 0 +#endif + +#if defined(CONFIG_GPIO_WM831X) +#define WM831X_TOTOL_GPIO_NUM 12 +#define WM831X_GPIO_EXPANDER_BASE (GPIO_EXPANDER_BASE+TCA6424_TOTOL_GPIO_NUM) +#else +#define WM831X_TOTOL_GPIO_NUM 0 +#define WM831X_GPIO_EXPANDER_BASE (GPIO_EXPANDER_BASE+TCA6424_TOTOL_GPIO_NUM) +#endif + +#if defined (CONFIG_GPIO_WM8994) +#define CONFIG_GPIO_WM8994_NUM 11 +#define WM8994_GPIO_EXPANDER_BASE (GPIO_EXPANDER_BASE+WM831X_TOTOL_GPIO_NUM) +#else +#define CONFIG_GPIO_WM8994_NUM 0 +#endif + +//¶¨ÒåGPIOµÄPIN¿Ú×î´óÊýÄ¿¡£CONFIG_SPI_FPGA_GPIO_NUM±íʾFPGAµÄPIN½ÅÊý¡£ +#define ARCH_NR_GPIOS (PIN_BASE + RK30_TOTOL_GPIO_NUM + TCA6424_TOTOL_GPIO_NUM + WM831X_TOTOL_GPIO_NUM + CONFIG_SPI_FPGA_GPIO_NUM+CONFIG_GPIO_WM8994_NUM) + + +#define RK30_PIN0_PA0 (0*NUM_GROUP + PIN_BASE + 0) +#define RK30_PIN0_PA1 (0*NUM_GROUP + PIN_BASE + 1) +#define RK30_PIN0_PA2 (0*NUM_GROUP + PIN_BASE + 2) +#define RK30_PIN0_PA3 (0*NUM_GROUP + PIN_BASE + 3) +#define RK30_PIN0_PA4 (0*NUM_GROUP + PIN_BASE + 4) +#define RK30_PIN0_PA5 (0*NUM_GROUP + PIN_BASE + 5) +#define RK30_PIN0_PA6 (0*NUM_GROUP + PIN_BASE + 6) +#define RK30_PIN0_PA7 (0*NUM_GROUP + PIN_BASE + 7) +#define RK30_PIN0_PB0 (0*NUM_GROUP + PIN_BASE + 8) +#define RK30_PIN0_PB1 (0*NUM_GROUP + PIN_BASE + 9) +#define RK30_PIN0_PB2 (0*NUM_GROUP + PIN_BASE + 10) +#define RK30_PIN0_PB3 (0*NUM_GROUP + PIN_BASE + 11) +#define RK30_PIN0_PB4 (0*NUM_GROUP + PIN_BASE + 12) +#define RK30_PIN0_PB5 (0*NUM_GROUP + PIN_BASE + 13) +#define RK30_PIN0_PB6 (0*NUM_GROUP + PIN_BASE + 14) +#define RK30_PIN0_PB7 (0*NUM_GROUP + PIN_BASE + 15) +#define RK30_PIN0_PC0 (0*NUM_GROUP + PIN_BASE + 16) +#define RK30_PIN0_PC1 (0*NUM_GROUP + PIN_BASE + 17) +#define RK30_PIN0_PC2 (0*NUM_GROUP + PIN_BASE + 18) +#define RK30_PIN0_PC3 (0*NUM_GROUP + PIN_BASE + 19) +#define RK30_PIN0_PC4 (0*NUM_GROUP + PIN_BASE + 20) +#define RK30_PIN0_PC5 (0*NUM_GROUP + PIN_BASE + 21) +#define RK30_PIN0_PC6 (0*NUM_GROUP + PIN_BASE + 22) +#define RK30_PIN0_PC7 (0*NUM_GROUP + PIN_BASE + 23) +#define RK30_PIN0_PD0 (0*NUM_GROUP + PIN_BASE + 24) +#define RK30_PIN0_PD1 (0*NUM_GROUP + PIN_BASE + 25) +#define RK30_PIN0_PD2 (0*NUM_GROUP + PIN_BASE + 26) +#define RK30_PIN0_PD3 (0*NUM_GROUP + PIN_BASE + 27) +#define RK30_PIN0_PD4 (0*NUM_GROUP + PIN_BASE + 28) +#define RK30_PIN0_PD5 (0*NUM_GROUP + PIN_BASE + 29) +#define RK30_PIN0_PD6 (0*NUM_GROUP + PIN_BASE + 30) +#define RK30_PIN0_PD7 (0*NUM_GROUP + PIN_BASE + 31) + +#define RK30_PIN1_PA0 (1*NUM_GROUP + PIN_BASE + 0) +#define RK30_PIN1_PA1 (1*NUM_GROUP + PIN_BASE + 1) +#define RK30_PIN1_PA2 (1*NUM_GROUP + PIN_BASE + 2) +#define RK30_PIN1_PA3 (1*NUM_GROUP + PIN_BASE + 3) +#define RK30_PIN1_PA4 (1*NUM_GROUP + PIN_BASE + 4) +#define RK30_PIN1_PA5 (1*NUM_GROUP + PIN_BASE + 5) +#define RK30_PIN1_PA6 (1*NUM_GROUP + PIN_BASE + 6) +#define RK30_PIN1_PA7 (1*NUM_GROUP + PIN_BASE + 7) +#define RK30_PIN1_PB0 (1*NUM_GROUP + PIN_BASE + 8) +#define RK30_PIN1_PB1 (1*NUM_GROUP + PIN_BASE + 9) +#define RK30_PIN1_PB2 (1*NUM_GROUP + PIN_BASE + 10) +#define RK30_PIN1_PB3 (1*NUM_GROUP + PIN_BASE + 11) +#define RK30_PIN1_PB4 (1*NUM_GROUP + PIN_BASE + 12) +#define RK30_PIN1_PB5 (1*NUM_GROUP + PIN_BASE + 13) +#define RK30_PIN1_PB6 (1*NUM_GROUP + PIN_BASE + 14) +#define RK30_PIN1_PB7 (1*NUM_GROUP + PIN_BASE + 15) +#define RK30_PIN1_PC0 (1*NUM_GROUP + PIN_BASE + 16) +#define RK30_PIN1_PC1 (1*NUM_GROUP + PIN_BASE + 17) +#define RK30_PIN1_PC2 (1*NUM_GROUP + PIN_BASE + 18) +#define RK30_PIN1_PC3 (1*NUM_GROUP + PIN_BASE + 19) +#define RK30_PIN1_PC4 (1*NUM_GROUP + PIN_BASE + 20) +#define RK30_PIN1_PC5 (1*NUM_GROUP + PIN_BASE + 21) +#define RK30_PIN1_PC6 (1*NUM_GROUP + PIN_BASE + 22) +#define RK30_PIN1_PC7 (1*NUM_GROUP + PIN_BASE + 23) +#define RK30_PIN1_PD0 (1*NUM_GROUP + PIN_BASE + 24) +#define RK30_PIN1_PD1 (1*NUM_GROUP + PIN_BASE + 25) +#define RK30_PIN1_PD2 (1*NUM_GROUP + PIN_BASE + 26) +#define RK30_PIN1_PD3 (1*NUM_GROUP + PIN_BASE + 27) +#define RK30_PIN1_PD4 (1*NUM_GROUP + PIN_BASE + 28) +#define RK30_PIN1_PD5 (1*NUM_GROUP + PIN_BASE + 29) +#define RK30_PIN1_PD6 (1*NUM_GROUP + PIN_BASE + 30) +#define RK30_PIN1_PD7 (1*NUM_GROUP + PIN_BASE + 31) + +#define RK30_PIN2_PA0 (2*NUM_GROUP + PIN_BASE + 0) +#define RK30_PIN2_PA1 (2*NUM_GROUP + PIN_BASE + 1) +#define RK30_PIN2_PA2 (2*NUM_GROUP + PIN_BASE + 2) +#define RK30_PIN2_PA3 (2*NUM_GROUP + PIN_BASE + 3) +#define RK30_PIN2_PA4 (2*NUM_GROUP + PIN_BASE + 4) +#define RK30_PIN2_PA5 (2*NUM_GROUP + PIN_BASE + 5) +#define RK30_PIN2_PA6 (2*NUM_GROUP + PIN_BASE + 6) +#define RK30_PIN2_PA7 (2*NUM_GROUP + PIN_BASE + 7) +#define RK30_PIN2_PB0 (2*NUM_GROUP + PIN_BASE + 8) +#define RK30_PIN2_PB1 (2*NUM_GROUP + PIN_BASE + 9) +#define RK30_PIN2_PB2 (2*NUM_GROUP + PIN_BASE + 10) +#define RK30_PIN2_PB3 (2*NUM_GROUP + PIN_BASE + 11) +#define RK30_PIN2_PB4 (2*NUM_GROUP + PIN_BASE + 12) +#define RK30_PIN2_PB5 (2*NUM_GROUP + PIN_BASE + 13) +#define RK30_PIN2_PB6 (2*NUM_GROUP + PIN_BASE + 14) +#define RK30_PIN2_PB7 (2*NUM_GROUP + PIN_BASE + 15) +#define RK30_PIN2_PC0 (2*NUM_GROUP + PIN_BASE + 16) +#define RK30_PIN2_PC1 (2*NUM_GROUP + PIN_BASE + 17) +#define RK30_PIN2_PC2 (2*NUM_GROUP + PIN_BASE + 18) +#define RK30_PIN2_PC3 (2*NUM_GROUP + PIN_BASE + 19) +#define RK30_PIN2_PC4 (2*NUM_GROUP + PIN_BASE + 20) +#define RK30_PIN2_PC5 (2*NUM_GROUP + PIN_BASE + 21) +#define RK30_PIN2_PC6 (2*NUM_GROUP + PIN_BASE + 22) +#define RK30_PIN2_PC7 (2*NUM_GROUP + PIN_BASE + 23) +#define RK30_PIN2_PD0 (2*NUM_GROUP + PIN_BASE + 24) +#define RK30_PIN2_PD1 (2*NUM_GROUP + PIN_BASE + 25) +#define RK30_PIN2_PD2 (2*NUM_GROUP + PIN_BASE + 26) +#define RK30_PIN2_PD3 (2*NUM_GROUP + PIN_BASE + 27) +#define RK30_PIN2_PD4 (2*NUM_GROUP + PIN_BASE + 28) +#define RK30_PIN2_PD5 (2*NUM_GROUP + PIN_BASE + 29) +#define RK30_PIN2_PD6 (2*NUM_GROUP + PIN_BASE + 30) +#define RK30_PIN2_PD7 (2*NUM_GROUP + PIN_BASE + 31) + +#define RK30_PIN3_PA0 (3*NUM_GROUP + PIN_BASE + 0) +#define RK30_PIN3_PA1 (3*NUM_GROUP + PIN_BASE + 1) +#define RK30_PIN3_PA2 (3*NUM_GROUP + PIN_BASE + 2) +#define RK30_PIN3_PA3 (3*NUM_GROUP + PIN_BASE + 3) +#define RK30_PIN3_PA4 (3*NUM_GROUP + PIN_BASE + 4) +#define RK30_PIN3_PA5 (3*NUM_GROUP + PIN_BASE + 5) +#define RK30_PIN3_PA6 (3*NUM_GROUP + PIN_BASE + 6) +#define RK30_PIN3_PA7 (3*NUM_GROUP + PIN_BASE + 7) +#define RK30_PIN3_PB0 (3*NUM_GROUP + PIN_BASE + 8) +#define RK30_PIN3_PB1 (3*NUM_GROUP + PIN_BASE + 9) +#define RK30_PIN3_PB2 (3*NUM_GROUP + PIN_BASE + 10) +#define RK30_PIN3_PB3 (3*NUM_GROUP + PIN_BASE + 11) +#define RK30_PIN3_PB4 (3*NUM_GROUP + PIN_BASE + 12) +#define RK30_PIN3_PB5 (3*NUM_GROUP + PIN_BASE + 13) +#define RK30_PIN3_PB6 (3*NUM_GROUP + PIN_BASE + 14) +#define RK30_PIN3_PB7 (3*NUM_GROUP + PIN_BASE + 15) +#define RK30_PIN3_PC0 (3*NUM_GROUP + PIN_BASE + 16) +#define RK30_PIN3_PC1 (3*NUM_GROUP + PIN_BASE + 17) +#define RK30_PIN3_PC2 (3*NUM_GROUP + PIN_BASE + 18) +#define RK30_PIN3_PC3 (3*NUM_GROUP + PIN_BASE + 19) +#define RK30_PIN3_PC4 (3*NUM_GROUP + PIN_BASE + 20) +#define RK30_PIN3_PC5 (3*NUM_GROUP + PIN_BASE + 21) +#define RK30_PIN3_PC6 (3*NUM_GROUP + PIN_BASE + 22) +#define RK30_PIN3_PC7 (3*NUM_GROUP + PIN_BASE + 23) +#define RK30_PIN3_PD0 (3*NUM_GROUP + PIN_BASE + 24) +#define RK30_PIN3_PD1 (3*NUM_GROUP + PIN_BASE + 25) +#define RK30_PIN3_PD2 (3*NUM_GROUP + PIN_BASE + 26) +#define RK30_PIN3_PD3 (3*NUM_GROUP + PIN_BASE + 27) +#define RK30_PIN3_PD4 (3*NUM_GROUP + PIN_BASE + 28) +#define RK30_PIN3_PD5 (3*NUM_GROUP + PIN_BASE + 29) +#define RK30_PIN3_PD6 (3*NUM_GROUP + PIN_BASE + 30) +#define RK30_PIN3_PD7 (3*NUM_GROUP + PIN_BASE + 31) + +#define RK30_PIN4_PA0 (4*NUM_GROUP + PIN_BASE + 0) +#define RK30_PIN4_PA1 (4*NUM_GROUP + PIN_BASE + 1) +#define RK30_PIN4_PA2 (4*NUM_GROUP + PIN_BASE + 2) +#define RK30_PIN4_PA3 (4*NUM_GROUP + PIN_BASE + 3) +#define RK30_PIN4_PA4 (4*NUM_GROUP + PIN_BASE + 4) +#define RK30_PIN4_PA5 (4*NUM_GROUP + PIN_BASE + 5) +#define RK30_PIN4_PA6 (4*NUM_GROUP + PIN_BASE + 6) +#define RK30_PIN4_PA7 (4*NUM_GROUP + PIN_BASE + 7) +#define RK30_PIN4_PB0 (4*NUM_GROUP + PIN_BASE + 8) +#define RK30_PIN4_PB1 (4*NUM_GROUP + PIN_BASE + 9) +#define RK30_PIN4_PB2 (4*NUM_GROUP + PIN_BASE + 10) +#define RK30_PIN4_PB3 (4*NUM_GROUP + PIN_BASE + 11) +#define RK30_PIN4_PB4 (4*NUM_GROUP + PIN_BASE + 12) +#define RK30_PIN4_PB5 (4*NUM_GROUP + PIN_BASE + 13) +#define RK30_PIN4_PB6 (4*NUM_GROUP + PIN_BASE + 14) +#define RK30_PIN4_PB7 (4*NUM_GROUP + PIN_BASE + 15) +#define RK30_PIN4_PC0 (4*NUM_GROUP + PIN_BASE + 16) +#define RK30_PIN4_PC1 (4*NUM_GROUP + PIN_BASE + 17) +#define RK30_PIN4_PC2 (4*NUM_GROUP + PIN_BASE + 18) +#define RK30_PIN4_PC3 (4*NUM_GROUP + PIN_BASE + 19) +#define RK30_PIN4_PC4 (4*NUM_GROUP + PIN_BASE + 20) +#define RK30_PIN4_PC5 (4*NUM_GROUP + PIN_BASE + 21) +#define RK30_PIN4_PC6 (4*NUM_GROUP + PIN_BASE + 22) +#define RK30_PIN4_PC7 (4*NUM_GROUP + PIN_BASE + 23) +#define RK30_PIN4_PD0 (4*NUM_GROUP + PIN_BASE + 24) +#define RK30_PIN4_PD1 (4*NUM_GROUP + PIN_BASE + 25) +#define RK30_PIN4_PD2 (4*NUM_GROUP + PIN_BASE + 26) +#define RK30_PIN4_PD3 (4*NUM_GROUP + PIN_BASE + 27) +#define RK30_PIN4_PD4 (4*NUM_GROUP + PIN_BASE + 28) +#define RK30_PIN4_PD5 (4*NUM_GROUP + PIN_BASE + 29) +#define RK30_PIN4_PD6 (4*NUM_GROUP + PIN_BASE + 30) +#define RK30_PIN4_PD7 (4*NUM_GROUP + PIN_BASE + 31) + +#define RK30_PIN6_PD7 (6*NUM_GROUP + PIN_BASE + 31) + +#if defined(CONFIG_SPI_FPGA_GPIO) +#define FPGA_PIO0_00 (SPI_FPGA_EXPANDER_BASE + 0*NUM_GROUP + 0) +#define FPGA_PIO0_01 (SPI_FPGA_EXPANDER_BASE + 0*NUM_GROUP + 1) +#define FPGA_PIO0_02 (SPI_FPGA_EXPANDER_BASE + 0*NUM_GROUP + 2) +#define FPGA_PIO0_03 (SPI_FPGA_EXPANDER_BASE + 0*NUM_GROUP + 3) +#define FPGA_PIO0_04 (SPI_FPGA_EXPANDER_BASE + 0*NUM_GROUP + 4) +#define FPGA_PIO0_05 (SPI_FPGA_EXPANDER_BASE + 0*NUM_GROUP + 5) +#define FPGA_PIO0_06 (SPI_FPGA_EXPANDER_BASE + 0*NUM_GROUP + 6) +#define FPGA_PIO0_07 (SPI_FPGA_EXPANDER_BASE + 0*NUM_GROUP + 7) + +#define FPGA_PIO0_08 (SPI_FPGA_EXPANDER_BASE + 1*NUM_GROUP + 0) +#define FPGA_PIO0_09 (SPI_FPGA_EXPANDER_BASE + 1*NUM_GROUP + 1) +#define FPGA_PIO0_10 (SPI_FPGA_EXPANDER_BASE + 1*NUM_GROUP + 2) +#define FPGA_PIO0_11 (SPI_FPGA_EXPANDER_BASE + 1*NUM_GROUP + 3) +#define FPGA_PIO0_12 (SPI_FPGA_EXPANDER_BASE + 1*NUM_GROUP + 4) +#define FPGA_PIO0_13 (SPI_FPGA_EXPANDER_BASE + 1*NUM_GROUP + 5) +#define FPGA_PIO0_14 (SPI_FPGA_EXPANDER_BASE + 1*NUM_GROUP + 6) +#define FPGA_PIO0_15 (SPI_FPGA_EXPANDER_BASE + 1*NUM_GROUP + 7) + +#define FPGA_PIO1_00 (SPI_FPGA_EXPANDER_BASE + 2*NUM_GROUP + 0) +#define FPGA_PIO1_01 (SPI_FPGA_EXPANDER_BASE + 2*NUM_GROUP + 1) +#define FPGA_PIO1_02 (SPI_FPGA_EXPANDER_BASE + 2*NUM_GROUP + 2) +#define FPGA_PIO1_03 (SPI_FPGA_EXPANDER_BASE + 2*NUM_GROUP + 3) +#define FPGA_PIO1_04 (SPI_FPGA_EXPANDER_BASE + 2*NUM_GROUP + 4) +#define FPGA_PIO1_05 (SPI_FPGA_EXPANDER_BASE + 2*NUM_GROUP + 5) +#define FPGA_PIO1_06 (SPI_FPGA_EXPANDER_BASE + 2*NUM_GROUP + 6) +#define FPGA_PIO1_07 (SPI_FPGA_EXPANDER_BASE + 2*NUM_GROUP + 7) + +#define FPGA_PIO1_08 (SPI_FPGA_EXPANDER_BASE + 3*NUM_GROUP + 0) +#define FPGA_PIO1_09 (SPI_FPGA_EXPANDER_BASE + 3*NUM_GROUP + 1) +#define FPGA_PIO1_10 (SPI_FPGA_EXPANDER_BASE + 3*NUM_GROUP + 2) +#define FPGA_PIO1_11 (SPI_FPGA_EXPANDER_BASE + 3*NUM_GROUP + 3) +#define FPGA_PIO1_12 (SPI_FPGA_EXPANDER_BASE + 3*NUM_GROUP + 4) +#define FPGA_PIO1_13 (SPI_FPGA_EXPANDER_BASE + 3*NUM_GROUP + 5) +#define FPGA_PIO1_14 (SPI_FPGA_EXPANDER_BASE + 3*NUM_GROUP + 6) +#define FPGA_PIO1_15 (SPI_FPGA_EXPANDER_BASE + 3*NUM_GROUP + 7) + +#define FPGA_PIO2_00 (SPI_FPGA_EXPANDER_BASE + 4*NUM_GROUP + 0) +#define FPGA_PIO2_01 (SPI_FPGA_EXPANDER_BASE + 4*NUM_GROUP + 1) +#define FPGA_PIO2_02 (SPI_FPGA_EXPANDER_BASE + 4*NUM_GROUP + 2) +#define FPGA_PIO2_03 (SPI_FPGA_EXPANDER_BASE + 4*NUM_GROUP + 3) +#define FPGA_PIO2_04 (SPI_FPGA_EXPANDER_BASE + 4*NUM_GROUP + 4) +#define FPGA_PIO2_05 (SPI_FPGA_EXPANDER_BASE + 4*NUM_GROUP + 5) +#define FPGA_PIO2_06 (SPI_FPGA_EXPANDER_BASE + 4*NUM_GROUP + 6) +#define FPGA_PIO2_07 (SPI_FPGA_EXPANDER_BASE + 4*NUM_GROUP + 7) + +#define FPGA_PIO2_08 (SPI_FPGA_EXPANDER_BASE + 5*NUM_GROUP + 0) +#define FPGA_PIO2_09 (SPI_FPGA_EXPANDER_BASE + 5*NUM_GROUP + 1) +#define FPGA_PIO2_10 (SPI_FPGA_EXPANDER_BASE + 5*NUM_GROUP + 2) +#define FPGA_PIO2_11 (SPI_FPGA_EXPANDER_BASE + 5*NUM_GROUP + 3) +#define FPGA_PIO2_12 (SPI_FPGA_EXPANDER_BASE + 5*NUM_GROUP + 4) +#define FPGA_PIO2_13 (SPI_FPGA_EXPANDER_BASE + 5*NUM_GROUP + 5) +#define FPGA_PIO2_14 (SPI_FPGA_EXPANDER_BASE + 5*NUM_GROUP + 6) +#define FPGA_PIO2_15 (SPI_FPGA_EXPANDER_BASE + 5*NUM_GROUP + 7) + +#define FPGA_PIO3_00 (SPI_FPGA_EXPANDER_BASE + 6*NUM_GROUP + 0) +#define FPGA_PIO3_01 (SPI_FPGA_EXPANDER_BASE + 6*NUM_GROUP + 1) +#define FPGA_PIO3_02 (SPI_FPGA_EXPANDER_BASE + 6*NUM_GROUP + 2) +#define FPGA_PIO3_03 (SPI_FPGA_EXPANDER_BASE + 6*NUM_GROUP + 3) +#define FPGA_PIO3_04 (SPI_FPGA_EXPANDER_BASE + 6*NUM_GROUP + 4) +#define FPGA_PIO3_05 (SPI_FPGA_EXPANDER_BASE + 6*NUM_GROUP + 5) +#define FPGA_PIO3_06 (SPI_FPGA_EXPANDER_BASE + 6*NUM_GROUP + 6) +#define FPGA_PIO3_07 (SPI_FPGA_EXPANDER_BASE + 6*NUM_GROUP + 7) + +#define FPGA_PIO3_08 (SPI_FPGA_EXPANDER_BASE + 7*NUM_GROUP + 0) +#define FPGA_PIO3_09 (SPI_FPGA_EXPANDER_BASE + 7*NUM_GROUP + 1) +#define FPGA_PIO3_10 (SPI_FPGA_EXPANDER_BASE + 7*NUM_GROUP + 2) +#define FPGA_PIO3_11 (SPI_FPGA_EXPANDER_BASE + 7*NUM_GROUP + 3) +#define FPGA_PIO3_12 (SPI_FPGA_EXPANDER_BASE + 7*NUM_GROUP + 4) +#define FPGA_PIO3_13 (SPI_FPGA_EXPANDER_BASE + 7*NUM_GROUP + 5) +#define FPGA_PIO3_14 (SPI_FPGA_EXPANDER_BASE + 7*NUM_GROUP + 6) +#define FPGA_PIO3_15 (SPI_FPGA_EXPANDER_BASE + 7*NUM_GROUP + 7) + +#define FPGA_PIO4_00 (SPI_FPGA_EXPANDER_BASE + 8*NUM_GROUP + 0) +#define FPGA_PIO4_01 (SPI_FPGA_EXPANDER_BASE + 8*NUM_GROUP + 1) +#define FPGA_PIO4_02 (SPI_FPGA_EXPANDER_BASE + 8*NUM_GROUP + 2) +#define FPGA_PIO4_03 (SPI_FPGA_EXPANDER_BASE + 8*NUM_GROUP + 3) +#define FPGA_PIO4_04 (SPI_FPGA_EXPANDER_BASE + 8*NUM_GROUP + 4) +#define FPGA_PIO4_05 (SPI_FPGA_EXPANDER_BASE + 8*NUM_GROUP + 5) +#define FPGA_PIO4_06 (SPI_FPGA_EXPANDER_BASE + 8*NUM_GROUP + 6) +#define FPGA_PIO4_07 (SPI_FPGA_EXPANDER_BASE + 8*NUM_GROUP + 7) + +#define FPGA_PIO4_08 (SPI_FPGA_EXPANDER_BASE + 9*NUM_GROUP + 0) +#define FPGA_PIO4_09 (SPI_FPGA_EXPANDER_BASE + 9*NUM_GROUP + 1) +#define FPGA_PIO4_10 (SPI_FPGA_EXPANDER_BASE + 9*NUM_GROUP + 2) +#define FPGA_PIO4_11 (SPI_FPGA_EXPANDER_BASE + 9*NUM_GROUP + 3) +#define FPGA_PIO4_12 (SPI_FPGA_EXPANDER_BASE + 9*NUM_GROUP + 4) +#define FPGA_PIO4_13 (SPI_FPGA_EXPANDER_BASE + 9*NUM_GROUP + 5) +#define FPGA_PIO4_14 (SPI_FPGA_EXPANDER_BASE + 9*NUM_GROUP + 6) +#define FPGA_PIO4_15 (SPI_FPGA_EXPANDER_BASE + 9*NUM_GROUP + 7) + +#define FPGA_PIO5_00 (SPI_FPGA_EXPANDER_BASE + 10*NUM_GROUP + 0) +#define FPGA_PIO5_01 (SPI_FPGA_EXPANDER_BASE + 10*NUM_GROUP + 1) +#define FPGA_PIO5_02 (SPI_FPGA_EXPANDER_BASE + 10*NUM_GROUP + 2) +#define FPGA_PIO5_03 (SPI_FPGA_EXPANDER_BASE + 10*NUM_GROUP + 3) +#define FPGA_PIO5_04 (SPI_FPGA_EXPANDER_BASE + 10*NUM_GROUP + 4) +#define FPGA_PIO5_05 (SPI_FPGA_EXPANDER_BASE + 10*NUM_GROUP + 5) +#define FPGA_PIO5_06 (SPI_FPGA_EXPANDER_BASE + 10*NUM_GROUP + 6) +#define FPGA_PIO5_07 (SPI_FPGA_EXPANDER_BASE + 10*NUM_GROUP + 7) + +#define FPGA_PIO5_08 (SPI_FPGA_EXPANDER_BASE + 11*NUM_GROUP + 0) +#define FPGA_PIO5_09 (SPI_FPGA_EXPANDER_BASE + 11*NUM_GROUP + 1) +#define FPGA_PIO5_10 (SPI_FPGA_EXPANDER_BASE + 11*NUM_GROUP + 2) +#define FPGA_PIO5_11 (SPI_FPGA_EXPANDER_BASE + 11*NUM_GROUP + 3) +#define FPGA_PIO5_12 (SPI_FPGA_EXPANDER_BASE + 11*NUM_GROUP + 4) +#define FPGA_PIO5_13 (SPI_FPGA_EXPANDER_BASE + 11*NUM_GROUP + 5) +#define FPGA_PIO5_14 (SPI_FPGA_EXPANDER_BASE + 11*NUM_GROUP + 6) +#define FPGA_PIO5_15 (SPI_FPGA_EXPANDER_BASE + 11*NUM_GROUP + 7) + +#endif + +#if defined(CONFIG_IOEXTEND_TCA6424) +#define TCA6424_P00 (TCA6424_GPIO_EXPANDER_BASE + 0*NUM_GROUP + 0) +#define TCA6424_P01 (TCA6424_GPIO_EXPANDER_BASE + 0*NUM_GROUP + 1) +#define TCA6424_P02 (TCA6424_GPIO_EXPANDER_BASE + 0*NUM_GROUP + 2) +#define TCA6424_P03 (TCA6424_GPIO_EXPANDER_BASE + 0*NUM_GROUP + 3) +#define TCA6424_P04 (TCA6424_GPIO_EXPANDER_BASE + 0*NUM_GROUP + 4) +#define TCA6424_P05 (TCA6424_GPIO_EXPANDER_BASE + 0*NUM_GROUP + 5) +#define TCA6424_P06 (TCA6424_GPIO_EXPANDER_BASE + 0*NUM_GROUP + 6) +#define TCA6424_P07 (TCA6424_GPIO_EXPANDER_BASE + 0*NUM_GROUP + 7) + +#define TCA6424_P10 (TCA6424_GPIO_EXPANDER_BASE + 1*NUM_GROUP + 0) +#define TCA6424_P11 (TCA6424_GPIO_EXPANDER_BASE + 1*NUM_GROUP + 1) +#define TCA6424_P12 (TCA6424_GPIO_EXPANDER_BASE + 1*NUM_GROUP + 2) +#define TCA6424_P13 (TCA6424_GPIO_EXPANDER_BASE + 1*NUM_GROUP + 3) +#define TCA6424_P14 (TCA6424_GPIO_EXPANDER_BASE + 1*NUM_GROUP + 4) +#define TCA6424_P15 (TCA6424_GPIO_EXPANDER_BASE + 1*NUM_GROUP + 5) +#define TCA6424_P16 (TCA6424_GPIO_EXPANDER_BASE + 1*NUM_GROUP + 6) +#define TCA6424_P17 (TCA6424_GPIO_EXPANDER_BASE + 1*NUM_GROUP + 7) + +#define TCA6424_P20 (TCA6424_GPIO_EXPANDER_BASE + 2*NUM_GROUP + 0) +#define TCA6424_P21 (TCA6424_GPIO_EXPANDER_BASE + 2*NUM_GROUP + 1) +#define TCA6424_P22 (TCA6424_GPIO_EXPANDER_BASE + 2*NUM_GROUP + 2) +#define TCA6424_P23 (TCA6424_GPIO_EXPANDER_BASE + 2*NUM_GROUP + 3) +#define TCA6424_P24 (TCA6424_GPIO_EXPANDER_BASE + 2*NUM_GROUP + 4) +#define TCA6424_P25 (TCA6424_GPIO_EXPANDER_BASE + 2*NUM_GROUP + 5) +#define TCA6424_P26 (TCA6424_GPIO_EXPANDER_BASE + 2*NUM_GROUP + 6) +#define TCA6424_P27 (TCA6424_GPIO_EXPANDER_BASE + 2*NUM_GROUP + 7) +#endif + +#if defined(CONFIG_GPIO_WM831X) +#define WM831X_P01 (WM831X_GPIO_EXPANDER_BASE + 0*NUM_GROUP + 0) +#define WM831X_P02 (WM831X_GPIO_EXPANDER_BASE + 0*NUM_GROUP + 1) +#define WM831X_P03 (WM831X_GPIO_EXPANDER_BASE + 0*NUM_GROUP + 2) +#define WM831X_P04 (WM831X_GPIO_EXPANDER_BASE + 0*NUM_GROUP + 3) +#define WM831X_P05 (WM831X_GPIO_EXPANDER_BASE + 0*NUM_GROUP + 4) +#define WM831X_P06 (WM831X_GPIO_EXPANDER_BASE + 0*NUM_GROUP + 5) +#define WM831X_P07 (WM831X_GPIO_EXPANDER_BASE + 0*NUM_GROUP + 6) +#define WM831X_P08 (WM831X_GPIO_EXPANDER_BASE + 0*NUM_GROUP + 7) + +#define WM831X_P09 (WM831X_GPIO_EXPANDER_BASE + 1*NUM_GROUP + 0) +#define WM831X_P10 (WM831X_GPIO_EXPANDER_BASE + 1*NUM_GROUP + 1) +#define WM831X_P11 (WM831X_GPIO_EXPANDER_BASE + 1*NUM_GROUP + 2) +#define WM831X_P12 (WM831X_GPIO_EXPANDER_BASE + 1*NUM_GROUP + 3) +#endif + +extern void __init rk30_gpio_init(void); +/*-------------------------------------------------------------------------*/ -#define ARCH_NR_GPIOS NR_GPIO_IRQS -#define PIN_BASE NR_GIC_IRQS +/* wrappers for "new style" GPIO calls. the old RK2818-specfic ones should + * eventually be removed (along with this errno.h inclusion), and the + * gpio request/free calls should probably be implemented. + */ #include #include /* cansleep wrappers */ diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index c579c8bf5dc8..441f198aac86 100755 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -46,6 +46,7 @@ obj-$(CONFIG_MACH_U300) += gpio-u300.o obj-$(CONFIG_PLAT_NOMADIK) += gpio-nomadik.o obj-$(CONFIG_GPIO_RDC321X) += rdc321x-gpio.o obj-$(CONFIG_ARCH_RK29) += gpio-rk29.o +obj-$(CONFIG_ARCH_RK30) += gpio-rk30.o obj-$(CONFIG_GPIO_JANZ_TTL) += janz-ttl.o obj-$(CONFIG_GPIO_SX150X) += sx150x.o obj-$(CONFIG_GPIO_VX855) += vx855_gpio.o diff --git a/drivers/gpio/gpio-rk30.c b/drivers/gpio/gpio-rk30.c new file mode 100755 index 000000000000..729ea9f3a13e --- /dev/null +++ b/drivers/gpio/gpio-rk30.c @@ -0,0 +1,483 @@ +/* arch/arm/mach-rk29/gpio.c + * + * Copyright (C) 2010 ROCKCHIP, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#define MAX_PIN RK30_PIN6_PD7 + +#define to_rk30_gpio_bank(c) container_of(c, struct rk30_gpio_bank, chip) + +struct rk30_gpio_bank { + struct gpio_chip chip; + unsigned short id; + short irq; + void __iomem *regbase; /* Base of register bank */ + struct clk *clk; + u32 suspend_wakeup; + u32 saved_wakeup; + spinlock_t lock; +}; + +static struct lock_class_key gpio_lock_class; + +static void rk30_gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip); +static void rk30_gpiolib_set(struct gpio_chip *chip, unsigned offset, int val); +static int rk30_gpiolib_get(struct gpio_chip *chip, unsigned offset); +static int rk30_gpiolib_direction_output(struct gpio_chip *chip,unsigned offset, int val); +static int rk30_gpiolib_direction_input(struct gpio_chip *chip,unsigned offset); +static int rk30_gpiolib_pull_updown(struct gpio_chip *chip, unsigned offset, unsigned enable); +static int rk30_gpiolib_to_irq(struct gpio_chip *chip,unsigned offset); + +#define RK30_GPIO_BANK(ID) \ + { \ + .chip = { \ + .label = "gpio" #ID, \ + .direction_input = rk30_gpiolib_direction_input, \ + .direction_output = rk30_gpiolib_direction_output, \ + .get = rk30_gpiolib_get, \ + .set = rk30_gpiolib_set, \ + .pull_updown = rk30_gpiolib_pull_updown, \ + .dbg_show = rk30_gpiolib_dbg_show, \ + .to_irq = rk30_gpiolib_to_irq, \ + .base = PIN_BASE + ID*NUM_GROUP, \ + .ngpio = NUM_GROUP, \ + }, \ + .id = ID, \ + .irq = IRQ_GPIO##ID, \ + .regbase = (unsigned char __iomem *) RK30_GPIO##ID##_BASE, \ + } + +static struct rk30_gpio_bank rk30_gpio_banks[] = { + RK30_GPIO_BANK(0), + RK30_GPIO_BANK(1), + RK30_GPIO_BANK(2), + RK30_GPIO_BANK(3), + RK30_GPIO_BANK(4), + RK30_GPIO_BANK(6), +}; + +static inline void rk30_gpio_bit_op(void __iomem *regbase, unsigned int offset, u32 bit, unsigned char flag) +{ + u32 val = __raw_readl(regbase + offset); + if (flag) + val |= bit; + else + val &= ~bit; + __raw_writel(val, regbase + offset); +} + +static inline struct gpio_chip *pin_to_gpio_chip(unsigned pin) +{ + if (pin < PIN_BASE || pin > MAX_PIN) + return NULL; + + pin -= PIN_BASE; + pin /= NUM_GROUP; + if (likely(pin < ARRAY_SIZE(rk30_gpio_banks))) + return &(rk30_gpio_banks[pin].chip); + return NULL; +} + +static inline unsigned gpio_to_bit(unsigned gpio) +{ + gpio -= PIN_BASE; + return 1u << (gpio % NUM_GROUP); +} + +static inline unsigned offset_to_bit(unsigned offset) +{ + return 1u << offset; +} + +static void GPIOSetPinLevel(void __iomem *regbase, unsigned int bit, eGPIOPinLevel_t level) +{ + rk30_gpio_bit_op(regbase, GPIO_SWPORT_DDR, bit, 1); + rk30_gpio_bit_op(regbase, GPIO_SWPORT_DR, bit, level); +} + +static int GPIOGetPinLevel(void __iomem *regbase, unsigned int bit) +{ + return ((__raw_readl(regbase + GPIO_EXT_PORT) & bit) != 0); +} + +static void GPIOSetPinDirection(void __iomem *regbase, unsigned int bit, eGPIOPinDirection_t direction) +{ + rk30_gpio_bit_op(regbase, GPIO_SWPORT_DDR, bit, direction); + /* Enable debounce may halt cpu on wfi, disable it by default */ + //rk30_gpio_bit_op(regbase, GPIO_DEBOUNCE, bit, 1); +} + +static void GPIOEnableIntr(void __iomem *regbase, unsigned int bit) +{ + rk30_gpio_bit_op(regbase, GPIO_INTEN, bit, 1); +} + +static void GPIODisableIntr(void __iomem *regbase, unsigned int bit) +{ + rk30_gpio_bit_op(regbase, GPIO_INTEN, bit, 0); +} + +static void GPIOAckIntr(void __iomem *regbase, unsigned int bit) +{ + rk30_gpio_bit_op(regbase, GPIO_PORTS_EOI, bit, 1); +} + +static void GPIOSetIntrType(void __iomem *regbase, unsigned int bit, eGPIOIntType_t type) +{ + switch (type) { + case GPIOLevelLow: + rk30_gpio_bit_op(regbase, GPIO_INT_POLARITY, bit, 0); + rk30_gpio_bit_op(regbase, GPIO_INTTYPE_LEVEL, bit, 0); + break; + case GPIOLevelHigh: + rk30_gpio_bit_op(regbase, GPIO_INTTYPE_LEVEL, bit, 0); + rk30_gpio_bit_op(regbase, GPIO_INT_POLARITY, bit, 1); + break; + case GPIOEdgelFalling: + rk30_gpio_bit_op(regbase, GPIO_INTTYPE_LEVEL, bit, 1); + rk30_gpio_bit_op(regbase, GPIO_INT_POLARITY, bit, 0); + break; + case GPIOEdgelRising: + rk30_gpio_bit_op(regbase, GPIO_INTTYPE_LEVEL, bit, 1); + rk30_gpio_bit_op(regbase, GPIO_INT_POLARITY, bit, 1); + break; + } +} + +static int rk30_gpio_irq_set_type(struct irq_data *d, unsigned int type) +{ + struct rk30_gpio_bank *bank = irq_data_get_irq_chip_data(d); + u32 bit = gpio_to_bit(irq_to_gpio(d->irq)); + eGPIOIntType_t int_type; + unsigned long flags; + + switch (type) { + case IRQ_TYPE_EDGE_RISING: + int_type = GPIOEdgelRising; + break; + case IRQ_TYPE_EDGE_FALLING: + int_type = GPIOEdgelFalling; + break; + case IRQ_TYPE_LEVEL_HIGH: + int_type = GPIOLevelHigh; + break; + case IRQ_TYPE_LEVEL_LOW: + int_type = GPIOLevelLow; + break; + default: + return -EINVAL; + } + + spin_lock_irqsave(&bank->lock, flags); + //ÉèÖÃΪÖжÏ֮ǰ£¬±ØÐëÏÈÉèÖÃΪÊäÈë״̬ + GPIOSetPinDirection(bank->regbase, bit, GPIO_IN); + GPIOSetIntrType(bank->regbase, bit, int_type); + spin_unlock_irqrestore(&bank->lock, flags); + + if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) + __irq_set_handler_locked(d->irq, handle_level_irq); + else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) + __irq_set_handler_locked(d->irq, handle_edge_irq); + + return 0; +} + +static int rk30_gpio_irq_set_wake(struct irq_data *d, unsigned int on) +{ + struct rk30_gpio_bank *bank = irq_data_get_irq_chip_data(d); + u32 bit = gpio_to_bit(irq_to_gpio(d->irq)); + unsigned long flags; + + spin_lock_irqsave(&bank->lock, flags); + if (on) + bank->suspend_wakeup |= bit; + else + bank->suspend_wakeup &= ~bit; + spin_unlock_irqrestore(&bank->lock, flags); + + return 0; +} + +static void rk30_gpio_irq_unmask(struct irq_data *d) +{ + struct rk30_gpio_bank *bank = irq_data_get_irq_chip_data(d); + u32 bit = gpio_to_bit(irq_to_gpio(d->irq)); + unsigned long flags; + + spin_lock_irqsave(&bank->lock, flags); + GPIOEnableIntr(bank->regbase, bit); + spin_unlock_irqrestore(&bank->lock, flags); +} + +static void rk30_gpio_irq_mask(struct irq_data *d) +{ + struct rk30_gpio_bank *bank = irq_data_get_irq_chip_data(d); + u32 bit = gpio_to_bit(irq_to_gpio(d->irq)); + unsigned long flags; + + spin_lock_irqsave(&bank->lock, flags); + GPIODisableIntr(bank->regbase, bit); + spin_unlock_irqrestore(&bank->lock, flags); +} + +static void rk30_gpio_irq_ack(struct irq_data *d) +{ + struct rk30_gpio_bank *bank = irq_data_get_irq_chip_data(d); + u32 bit = gpio_to_bit(irq_to_gpio(d->irq)); + + GPIOAckIntr(bank->regbase, bit); +} + +static int rk30_gpiolib_direction_output(struct gpio_chip *chip, unsigned offset, int val) +{ + struct rk30_gpio_bank *bank = to_rk30_gpio_bank(chip); + u32 bit = offset_to_bit(offset); + unsigned long flags; + + spin_lock_irqsave(&bank->lock, flags); + GPIOSetPinDirection(bank->regbase, bit, GPIO_OUT); + GPIOSetPinLevel(bank->regbase, bit, val); + spin_unlock_irqrestore(&bank->lock, flags); + return 0; +} + +static int rk30_gpiolib_direction_input(struct gpio_chip *chip,unsigned offset) +{ + struct rk30_gpio_bank *bank = to_rk30_gpio_bank(chip); + unsigned long flags; + + spin_lock_irqsave(&bank->lock, flags); + GPIOSetPinDirection(bank->regbase, offset_to_bit(offset), GPIO_IN); + spin_unlock_irqrestore(&bank->lock, flags); + return 0; +} + + +static int rk30_gpiolib_get(struct gpio_chip *chip, unsigned offset) +{ + return GPIOGetPinLevel(to_rk30_gpio_bank(chip)->regbase, offset_to_bit(offset)); +} + +static void rk30_gpiolib_set(struct gpio_chip *chip, unsigned offset, int val) +{ + struct rk30_gpio_bank *bank = to_rk30_gpio_bank(chip); + unsigned long flags; + + spin_lock_irqsave(&bank->lock, flags); + GPIOSetPinLevel(bank->regbase, offset_to_bit(offset), val); + spin_unlock_irqrestore(&bank->lock, flags); +} + +static int rk30_gpiolib_pull_updown(struct gpio_chip *chip, unsigned offset, unsigned enable) +{ + struct rk30_gpio_bank *bank = to_rk30_gpio_bank(chip); + unsigned long flags; + + spin_lock_irqsave(&bank->lock, flags); + rk30_gpio_bit_op((void *__iomem) RK30_GRF_BASE, 0x78 + bank->id * 4, offset_to_bit(offset), !enable); + spin_unlock_irqrestore(&bank->lock, flags); + + return 0; +} + +static int rk30_gpiolib_to_irq(struct gpio_chip *chip, unsigned offset) +{ + return chip->base + offset; +} + +static void rk30_gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip) +{ +#if 0 + int i; + + for (i = 0; i < chip->ngpio; i++) { + unsigned pin = chip->base + i; + struct gpio_chip *chip = pin_to_gpioChip(pin); + u32 bit = pin_to_bit(pin); + const char *gpio_label; + + if(!chip ||!bit) + return; + + gpio_label = gpiochip_is_requested(chip, i); + if (gpio_label) { + seq_printf(s, "[%s] GPIO%s%d: ", + gpio_label, chip->label, i); + + if (!chip || !bit) + { + seq_printf(s, "!chip || !bit\t"); + return; + } + + GPIOSetPinDirection(chip,bit,GPIO_IN); + seq_printf(s, "pin=%d,level=%d\t", pin,GPIOGetPinLevel(chip,bit)); + seq_printf(s, "\t"); + } + } +#endif +} + +static void rk30_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) +{ + struct rk30_gpio_bank *bank = irq_get_handler_data(irq); + struct irq_chip *chip = irq_desc_get_chip(desc); + unsigned gpio_irq; + u32 isr, ilr; + unsigned pin; + unsigned unmasked = 0; + + chained_irq_enter(chip, desc); + + isr = __raw_readl(bank->regbase + GPIO_INT_STATUS); + ilr = __raw_readl(bank->regbase + GPIO_INTTYPE_LEVEL); + + gpio_irq = gpio_to_irq(bank->chip.base); + + while (isr) { + pin = fls(isr) - 1; + /* if gpio is edge triggered, clear condition + * before executing the hander so that we don't + * miss edges + */ + if (ilr & (1 << pin)) { + unmasked = 1; + chained_irq_exit(chip, desc); + } + + generic_handle_irq(gpio_irq + pin); + isr &= ~(1 << pin); + } + + if (!unmasked) + chained_irq_exit(chip, desc); +} + +static struct irq_chip rk30_gpio_irq_chip = { + .name = "GPIO", + .irq_ack = rk30_gpio_irq_ack, + .irq_disable = rk30_gpio_irq_mask, + .irq_mask = rk30_gpio_irq_mask, + .irq_unmask = rk30_gpio_irq_unmask, + .irq_set_type = rk30_gpio_irq_set_type, + .irq_set_wake = rk30_gpio_irq_set_wake, +}; + +void __init rk30_gpio_init(void) +{ + unsigned int i, j, pin; + struct rk30_gpio_bank *bank; + + bank = rk30_gpio_banks; + pin = PIN_BASE; + + for (i = 0; i < ARRAY_SIZE(rk30_gpio_banks); i++, bank++, pin += 32) { + spin_lock_init(&bank->lock); + bank->clk = clk_get(NULL, bank->chip.label); + clk_enable(bank->clk); + gpiochip_add(&bank->chip); + + __raw_writel(0, bank->regbase + GPIO_INTEN); + for (j = 0; j < 32; j++) { + unsigned int irq = gpio_to_irq(pin + j); + irq_set_lockdep_class(irq, &gpio_lock_class); + irq_set_chip_data(irq, bank); + irq_set_chip_and_handler(irq, &rk30_gpio_irq_chip, handle_level_irq); + set_irq_flags(irq, IRQF_VALID); + } + + irq_set_handler_data(bank->irq, bank); + irq_set_chained_handler(bank->irq, rk30_gpio_irq_handler); + } + printk("%s: %d gpio irqs in %d banks\n", __func__, pin - PIN_BASE, ARRAY_SIZE(rk30_gpio_banks)); +} + +#ifdef CONFIG_PM +__weak void rk30_setgpio_suspend_board(void) +{ +} + +__weak void rk30_setgpio_resume_board(void) +{ +} + +static int rk30_gpio_suspend(void) +{ + unsigned i; + + rk30_setgpio_suspend_board(); + + for (i = 0; i < ARRAY_SIZE(rk30_gpio_banks); i++) { + struct rk30_gpio_bank *bank = &rk30_gpio_banks[i]; + + bank->saved_wakeup = __raw_readl(bank->regbase + GPIO_INTEN); + __raw_writel(bank->suspend_wakeup, bank->regbase + GPIO_INTEN); + + if (!bank->suspend_wakeup) + clk_disable(bank->clk); + } + + return 0; +} + +static void rk30_gpio_resume(void) +{ + unsigned i; + + for (i = 0; i < ARRAY_SIZE(rk30_gpio_banks); i++) { + struct rk30_gpio_bank *bank = &rk30_gpio_banks[i]; + u32 isr; + + if (!bank->suspend_wakeup) + clk_enable(bank->clk); + + /* keep enable for resume irq */ + isr = __raw_readl(bank->regbase + GPIO_INT_STATUS); + __raw_writel(bank->saved_wakeup | (bank->suspend_wakeup & isr), bank->regbase + GPIO_INTEN); + } + + rk30_setgpio_resume_board(); +} + +static struct syscore_ops rk30_gpio_syscore_ops = { + .suspend = rk30_gpio_suspend, + .resume = rk30_gpio_resume, +}; + +static int __init rk30_gpio_sysinit(void) +{ + register_syscore_ops(&rk30_gpio_syscore_ops); + return 0; +} + +arch_initcall(rk30_gpio_sysinit); +#endif -- 2.34.1