From: lhh Date: Tue, 26 Oct 2010 12:46:27 +0000 (+0800) Subject: add rk29 gpio X-Git-Tag: firefly_0821_release~11040 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=7ac0f1107b49a64fe1c49c83b56c2e3deb625237;p=firefly-linux-kernel-4.4.55.git add rk29 gpio --- diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b35fec253dec..5aa36c4f303e 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -724,7 +724,8 @@ config ARCH_RK29 select COMMON_CLKDEV select GENERIC_TIME select GENERIC_CLOCKEVENTS - select ARM_GIC + select ARCH_REQUIRE_GPIOLIB + select ARM_GIC help Support for Rockchip RK29 soc. diff --git a/arch/arm/mach-rk29/Makefile b/arch/arm/mach-rk29/Makefile index 70dfd7de6331..ba023c534364 100644 --- a/arch/arm/mach-rk29/Makefile +++ b/arch/arm/mach-rk29/Makefile @@ -1,2 +1,2 @@ -obj-y += timer.o io.o devices.o iomux.o clock.o rk29-pl330.o dma.o +obj-y += timer.o io.o devices.o iomux.o clock.o rk29-pl330.o dma.o gpio.o obj-$(CONFIG_MACH_RK29SDK) += board-rk29sdk.o diff --git a/arch/arm/mach-rk29/board-rk29sdk.c b/arch/arm/mach-rk29/board-rk29sdk.c index 9191fc992dc3..eb4b35e0f32e 100644 --- a/arch/arm/mach-rk29/board-rk29sdk.c +++ b/arch/arm/mach-rk29/board-rk29sdk.c @@ -30,6 +30,8 @@ #include #include +#include +#include #include #include #include @@ -42,6 +44,38 @@ extern struct sys_timer rk29_timer; + +static struct rk29_gpio_bank rk29_gpiobankinit[] = { + { + .id = RK29_ID_GPIO0, + .offset = RK29_GPIO0_BASE, + }, + { + .id = RK29_ID_GPIO1, + .offset = RK29_GPIO1_BASE, + }, + { + .id = RK29_ID_GPIO2, + .offset = RK29_GPIO2_BASE, + }, + { + .id = RK29_ID_GPIO3, + .offset = RK29_GPIO3_BASE, + }, + { + .id = RK29_ID_GPIO4, + .offset = RK29_GPIO4_BASE, + }, + { + .id = RK29_ID_GPIO5, + .offset = RK29_GPIO5_BASE, + }, + { + .id = RK29_ID_GPIO6, + .offset = RK29_GPIO6_BASE, + }, +}; + static struct platform_device *devices[] __initdata = { #ifdef CONFIG_UART1_RK29 &rk29_device_uart1, @@ -58,8 +92,8 @@ static void __init rk29_gic_init_irq(void) static void __init machine_rk29_init_irq(void) { rk29_gic_init_irq(); - //rk29_gpio_init(rk29_gpioBank, 8); - //rk29_gpio_irq_setup(); + rk29_gpio_init(rk29_gpiobankinit, MAX_BANK); + rk29_gpio_irq_setup(); } static void __init machine_rk29_board_init(void) { @@ -70,7 +104,7 @@ static void __init machine_rk29_mapio(void) { rk29_map_common_io(); rk29_clock_init(); - //rk29_iomux_init(); + rk29_iomux_init(); } MACHINE_START(RK29, "RK29board") diff --git a/arch/arm/mach-rk29/gpio.c b/arch/arm/mach-rk29/gpio.c new file mode 100644 index 000000000000..fd40ceb9a918 --- /dev/null +++ b/arch/arm/mach-rk29/gpio.c @@ -0,0 +1,656 @@ +/* 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 + + +#define to_rk29_gpio_chip(c) container_of(c, struct rk29_gpio_chip, chip) + +struct rk29_gpio_chip { + struct gpio_chip chip; + struct rk29_gpio_chip *next; /* Bank sharing same clock */ + struct rk29_gpio_bank *bank; /* Bank definition */ + unsigned char __iomem *regbase; /* Base of register bank */ +}; + +static struct lock_class_key gpio_lock_class; + +static void rk29_gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip); +static void rk29_gpiolib_set(struct gpio_chip *chip, unsigned offset, int val); +static int rk29_gpiolib_get(struct gpio_chip *chip, unsigned offset); +static int rk29_gpiolib_direction_output(struct gpio_chip *chip,unsigned offset, int val); +static int rk29_gpiolib_direction_input(struct gpio_chip *chip,unsigned offset); +static int rk29_gpiolib_PullUpDown(struct gpio_chip *chip, unsigned offset, unsigned enable); +static int rk29_gpiolib_to_irq(struct gpio_chip *chip,unsigned offset); + +#define RK29_GPIO_CHIP(name, base_gpio, nr_gpio) \ + { \ + .chip = { \ + .label = name, \ + .direction_input = rk29_gpiolib_direction_input, \ + .direction_output = rk29_gpiolib_direction_output, \ + .get = rk29_gpiolib_get, \ + .set = rk29_gpiolib_set, \ + .pull_updown = rk29_gpiolib_PullUpDown, \ + .dbg_show = rk29_gpiolib_dbg_show, \ + .to_irq = rk29_gpiolib_to_irq, \ + .base = base_gpio, \ + .ngpio = nr_gpio, \ + }, \ + } + +static struct rk29_gpio_chip rk29gpio_chip[] = { + RK29_GPIO_CHIP("GPIO0A", PIN_BASE + 0*NUM_GROUP, NUM_GROUP), + RK29_GPIO_CHIP("GPIO0B", PIN_BASE + 1*NUM_GROUP, NUM_GROUP), + RK29_GPIO_CHIP("GPIO0C", PIN_BASE + 2*NUM_GROUP, NUM_GROUP), + RK29_GPIO_CHIP("GPIO0D", PIN_BASE + 3*NUM_GROUP, NUM_GROUP), + RK29_GPIO_CHIP("GPIO1A", PIN_BASE + 4*NUM_GROUP, NUM_GROUP), + RK29_GPIO_CHIP("GPIO1B", PIN_BASE + 5*NUM_GROUP, NUM_GROUP), + RK29_GPIO_CHIP("GPIO1C", PIN_BASE + 6*NUM_GROUP, NUM_GROUP), + RK29_GPIO_CHIP("GPIO1D", PIN_BASE + 7*NUM_GROUP, NUM_GROUP), + RK29_GPIO_CHIP("GPIO2A", PIN_BASE + 8*NUM_GROUP, NUM_GROUP), + RK29_GPIO_CHIP("GPIO2B", PIN_BASE + 9*NUM_GROUP, NUM_GROUP), + RK29_GPIO_CHIP("GPIO2C", PIN_BASE + 10*NUM_GROUP, NUM_GROUP), + RK29_GPIO_CHIP("GPIO2D", PIN_BASE + 11*NUM_GROUP, NUM_GROUP), + RK29_GPIO_CHIP("GPIO3A", PIN_BASE + 12*NUM_GROUP, NUM_GROUP), + RK29_GPIO_CHIP("GPIO3B", PIN_BASE + 13*NUM_GROUP, NUM_GROUP), + RK29_GPIO_CHIP("GPIO3C", PIN_BASE + 14*NUM_GROUP, NUM_GROUP), + RK29_GPIO_CHIP("GPIO3D", PIN_BASE + 15*NUM_GROUP, NUM_GROUP), + RK29_GPIO_CHIP("GPIO4A", PIN_BASE + 16*NUM_GROUP, NUM_GROUP), + RK29_GPIO_CHIP("GPIO4B", PIN_BASE + 17*NUM_GROUP, NUM_GROUP), + RK29_GPIO_CHIP("GPIO4C", PIN_BASE + 18*NUM_GROUP, NUM_GROUP), + RK29_GPIO_CHIP("GPIO4D", PIN_BASE + 19*NUM_GROUP, NUM_GROUP), + RK29_GPIO_CHIP("GPIO5A", PIN_BASE + 20*NUM_GROUP, NUM_GROUP), + RK29_GPIO_CHIP("GPIO5B", PIN_BASE + 21*NUM_GROUP, NUM_GROUP), + RK29_GPIO_CHIP("GPIO5C", PIN_BASE + 22*NUM_GROUP, NUM_GROUP), + RK29_GPIO_CHIP("GPIO5D", PIN_BASE + 23*NUM_GROUP, NUM_GROUP), + RK29_GPIO_CHIP("GPIO6A", PIN_BASE + 24*NUM_GROUP, NUM_GROUP), + RK29_GPIO_CHIP("GPIO6B", PIN_BASE + 25*NUM_GROUP, NUM_GROUP), + RK29_GPIO_CHIP("GPIO6C", PIN_BASE + 26*NUM_GROUP, NUM_GROUP), + RK29_GPIO_CHIP("GPIO6D", PIN_BASE + 27*NUM_GROUP, NUM_GROUP), +}; + +static inline void rk29_gpio_write(unsigned char __iomem *regbase, unsigned int regOff,unsigned int val) +{ + __raw_writel(val,regbase + regOff); +} + +static inline unsigned int rk29_gpio_read(unsigned char __iomem *regbase, unsigned int regOff) +{ + return __raw_readl(regbase + regOff); +} + +static inline void rk29_gpio_bitOp(unsigned char __iomem *regbase, unsigned int regOff,unsigned int mask,unsigned char opFlag) +{ + unsigned int valTemp = 0; + + if(opFlag == 0)//¶Ô¼Ä´æÆ÷ÏàӦλ½øÐÐÓë0²Ù×÷ + { + valTemp = rk29_gpio_read(regbase,regOff); + valTemp &= (~mask);; + rk29_gpio_write(regbase,regOff,valTemp); + } + else if(opFlag == 1)//¶Ô¼Ä´æÆ÷ÏàӦλ½øÐлò1²Ù×÷ + { + valTemp = rk29_gpio_read(regbase,regOff); + valTemp |= mask; + rk29_gpio_write(regbase,regOff,valTemp); + } +} + +static inline struct gpio_chip *pin_to_gpioChip(unsigned pin) +{ + if(pin < PIN_BASE) + return NULL; + + pin -= PIN_BASE; + pin /= NUM_GROUP; + if (likely(pin < (MAX_BANK*4))) + return &(rk29gpio_chip[pin].chip); + return NULL; +} + +static inline unsigned pin_to_mask(unsigned pin) +{ + if(pin < PIN_BASE) + return 0; + pin -= PIN_BASE; + return 1ul << (pin % (NUM_GROUP*4)); +} + +static inline unsigned offset_to_mask(unsigned offset) +{ + return 1ul << (offset % (NUM_GROUP*4)); +} + +static int GPIOSetPinLevel(struct gpio_chip *chip, unsigned int mask,eGPIOPinLevel_t level) +{ + struct rk29_gpio_chip *rk29_gpio = to_rk29_gpio_chip(chip); + unsigned char __iomem *gpioRegBase = rk29_gpio->regbase; + + if(!rk29_gpio || !gpioRegBase) + { + return -1; + } + + rk29_gpio_bitOp(gpioRegBase,GPIO_SWPORT_DDR,mask,1); + rk29_gpio_bitOp(gpioRegBase,GPIO_SWPORT_DR,mask,level); + return 0; +} + +static int GPIOGetPinLevel(struct gpio_chip *chip, unsigned int mask) +{ + unsigned int valTemp; + struct rk29_gpio_chip *rk29_gpio = to_rk29_gpio_chip(chip); + unsigned char __iomem *gpioRegBase = rk29_gpio->regbase; + + if(!rk29_gpio || !gpioRegBase) + { + return -1; + } + + valTemp = rk29_gpio_read(gpioRegBase,GPIO_EXT_PORT); + return ((valTemp & mask) != 0); +} + +static int GPIOSetPinDirection(struct gpio_chip *chip, unsigned int mask,eGPIOPinDirection_t direction) +{ + struct rk29_gpio_chip *rk29_gpio = to_rk29_gpio_chip(chip); + unsigned char __iomem *gpioRegBase = rk29_gpio->regbase; + + if(!rk29_gpio || !gpioRegBase) + { + return -1; + } + + rk29_gpio_bitOp(gpioRegBase,GPIO_SWPORT_DDR,mask,direction); + rk29_gpio_bitOp(gpioRegBase,GPIO_DEBOUNCE,mask,1); + + return 0; + +} + +static int GPIOEnableIntr(struct gpio_chip *chip, unsigned int mask) +{ + struct rk29_gpio_chip *rk29_gpio = to_rk29_gpio_chip(chip); + unsigned char __iomem *gpioRegBase = rk29_gpio->regbase; + + if(!rk29_gpio || !gpioRegBase) + { + return -1; + } + + rk29_gpio_bitOp(gpioRegBase,GPIO_INTEN,mask,1); + return 0; +} + +static int GPIOSetIntrType(struct gpio_chip *chip, unsigned int mask, eGPIOIntType_t IntType) +{ + struct rk29_gpio_chip *rk29_gpio = to_rk29_gpio_chip(chip); + unsigned char __iomem *gpioRegBase = rk29_gpio->regbase; + + if(!rk29_gpio || !gpioRegBase) + { + return -1; + } + + switch ( IntType ) + { + case GPIOLevelLow: + rk29_gpio_bitOp(gpioRegBase,GPIO_INT_POLARITY,mask,0); + rk29_gpio_bitOp(gpioRegBase,GPIO_INTTYPE_LEVEL,mask,0); + break; + case GPIOLevelHigh: + rk29_gpio_bitOp(gpioRegBase,GPIO_INTTYPE_LEVEL,mask,0); + rk29_gpio_bitOp(gpioRegBase,GPIO_INT_POLARITY,mask,1); + break; + case GPIOEdgelFalling: + rk29_gpio_bitOp(gpioRegBase,GPIO_INTTYPE_LEVEL,mask,1); + rk29_gpio_bitOp(gpioRegBase,GPIO_INT_POLARITY,mask,0); + break; + case GPIOEdgelRising: + rk29_gpio_bitOp(gpioRegBase,GPIO_INTTYPE_LEVEL,mask,1); + rk29_gpio_bitOp(gpioRegBase,GPIO_INT_POLARITY,mask,1); + break; + default: + return(-1); + } + return(0); +} + +static int gpio_irq_set_wake(unsigned irq, unsigned state) +{ + unsigned int pin = irq_to_gpio(irq); + unsigned bank = (pin - PIN_BASE) / (NUM_GROUP*4); + unsigned int irq_number; + + if (unlikely(bank >= MAX_BANK)) + return -EINVAL; + + switch ( rk29gpio_chip[bank].bank->id ) + { + case RK29_ID_GPIO0: + irq_number = IRQ_GPIO0; + break; + case RK29_ID_GPIO1: + irq_number = IRQ_GPIO1; + break; + case RK29_ID_GPIO2: + irq_number = IRQ_GPIO2; + break; + case RK29_ID_GPIO3: + irq_number = IRQ_GPIO3; + break; + case RK29_ID_GPIO4: + irq_number = IRQ_GPIO4; + break; + case RK29_ID_GPIO5: + irq_number = IRQ_GPIO5; + break; + case RK29_ID_GPIO6: + irq_number = IRQ_GPIO6; + break; + default: + return 0; + } + + set_irq_wake(irq_number, state); + + return 0; +} + +static int gpio_irq_type(unsigned irq, unsigned type) +{ + unsigned int pin = irq_to_gpio(irq); + struct gpio_chip *chip = pin_to_gpioChip(pin); + unsigned mask = pin_to_mask(pin); + + if(!chip || !mask) + return -EINVAL; + //ÉèÖÃΪÖжÏ֮ǰ£¬±ØÐëÏÈÉèÖÃΪÊäÈë״̬ + GPIOSetPinDirection(chip,mask,GPIO_IN); + + switch (type) { + case IRQ_TYPE_NONE: + break; + case IRQ_TYPE_EDGE_RISING: + GPIOSetIntrType(chip,mask,GPIOEdgelRising); + break; + case IRQ_TYPE_EDGE_FALLING: + GPIOSetIntrType(chip,mask,GPIOEdgelFalling); + break; + case IRQ_TYPE_EDGE_BOTH: + break; + case IRQ_TYPE_LEVEL_HIGH: + GPIOSetIntrType(chip,mask,GPIOLevelHigh); + break; + case IRQ_TYPE_LEVEL_LOW: + GPIOSetIntrType(chip,mask,GPIOLevelLow); + break; + default: + return -EINVAL; + } + return 0; +} + +static int GPIOUnInmarkIntr(struct gpio_chip *chip, unsigned int mask) +{ + struct rk29_gpio_chip *rk29_gpio = to_rk29_gpio_chip(chip); + unsigned char __iomem *gpioRegBase = rk29_gpio->regbase; + + if(!rk29_gpio || !gpioRegBase) + { + return -1; + } + + rk29_gpio_bitOp(gpioRegBase,GPIO_INTMASK,mask,0); + return 0; +} + +static int GPIOInmarkIntr(struct gpio_chip *chip, unsigned int mask) +{ + struct rk29_gpio_chip *rk29_gpio = to_rk29_gpio_chip(chip); + unsigned char __iomem *gpioRegBase = rk29_gpio->regbase; + + if(!rk29_gpio || !gpioRegBase) + { + return -1; + } + + rk29_gpio_bitOp(gpioRegBase,GPIO_INTMASK,mask,1); + return 0; +} + +static void gpio_irq_unmask(unsigned irq) +{ + unsigned int pin = irq_to_gpio(irq); + struct gpio_chip *chip = pin_to_gpioChip(pin); + unsigned mask = pin_to_mask(pin); + + if (chip && mask) + GPIOUnInmarkIntr(chip,mask); +} + +static void gpio_irq_mask(unsigned irq) +{ + unsigned int pin = irq_to_gpio(irq); + struct gpio_chip *chip = pin_to_gpioChip(pin); + unsigned mask = pin_to_mask(pin); + + if(chip && mask) + GPIOInmarkIntr(chip,mask); +} + +static int GPIODisableIntr(struct gpio_chip *chip, unsigned int mask) +{ + struct rk29_gpio_chip *rk29_gpio = to_rk29_gpio_chip(chip); + unsigned char __iomem *gpioRegBase = rk29_gpio->regbase; + + if(!rk29_gpio || !gpioRegBase) + { + return -1; + } + + rk29_gpio_bitOp(gpioRegBase,GPIO_INTEN,mask,0); + return 0; +} + +static void gpio_irq_disable(unsigned irq) +{ + unsigned int pin = irq_to_gpio(irq); + struct gpio_chip *chip = pin_to_gpioChip(pin); + unsigned mask = pin_to_mask(pin); + + if(chip && mask) + GPIODisableIntr(chip,mask); +} + +static void gpio_irq_enable(unsigned irq) +{ + unsigned int pin = irq_to_gpio(irq); + struct gpio_chip *chip = pin_to_gpioChip(pin); + unsigned mask = pin_to_mask(pin); + + if(chip && mask) + GPIOEnableIntr(chip,mask); +} + +static int GPIOPullUpDown(struct gpio_chip *chip, unsigned int offset, unsigned enable) +{ + unsigned char temp=0; + struct rk29_gpio_chip *rk29_gpio = to_rk29_gpio_chip(chip); + unsigned char __iomem *pGrfRegBase = (unsigned char __iomem *)RK29_GRF_BASE; + + if(!rk29_gpio || !pGrfRegBase) + { + return -1; + } + + if(offset >= 8) + { + return -1; + } + + if(rk29_gpio->bank->id%2 == 1) + { + temp = 16; + } + return 0; +} + + +static int rk29_gpiolib_direction_output(struct gpio_chip *chip,unsigned offset, int val) +{ + unsigned mask = offset_to_mask(offset); + + if(GPIOSetPinDirection(chip,mask,GPIO_OUT) == 0) + { + return GPIOSetPinLevel(chip,mask,val); + } + else + { + return -1; + } +} + +static int rk29_gpiolib_direction_input(struct gpio_chip *chip,unsigned offset) +{ + unsigned mask = offset_to_mask(offset); + + return GPIOSetPinDirection(chip,mask,GPIO_IN); +} + + +static int rk29_gpiolib_get(struct gpio_chip *chip, unsigned offset) +{ + unsigned mask = offset_to_mask(offset); + + return GPIOGetPinLevel(chip,mask); +} + +static void rk29_gpiolib_set(struct gpio_chip *chip, unsigned offset, int val) +{ + unsigned mask = offset_to_mask(offset); + + GPIOSetPinLevel(chip,mask,val); +} + +static int rk29_gpiolib_PullUpDown(struct gpio_chip *chip, unsigned offset, unsigned enable) +{ + return GPIOPullUpDown(chip, offset, enable); +} + +static int rk29_gpiolib_to_irq(struct gpio_chip *chip, + unsigned offset) +{ + struct rk29_gpio_chip *rk29_gpio = to_rk29_gpio_chip(chip); + + if(!rk29_gpio) + { + return -1; + } + + return offset + NR_IRQS; +} + +static void rk29_gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip) +{ + + int i; + + for (i = 0; i < chip->ngpio; i++) { + unsigned pin = chip->base + i; + struct gpio_chip *chip = pin_to_gpioChip(pin); + unsigned mask = pin_to_mask(pin); + const char *gpio_label; + + if(!chip ||!mask) + 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 || !mask) + { + seq_printf(s, "!chip || !mask\t"); + return; + } + + GPIOSetPinDirection(chip,mask,GPIO_IN); + seq_printf(s, "pin=%d,level=%d\t", pin,GPIOGetPinLevel(chip,mask)); + seq_printf(s, "\t"); + } + } +} + +static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) +{ + unsigned pin,gpioToirq=0; + struct irq_desc *gpio; + struct rk29_gpio_chip *rk29_gpio; + unsigned char __iomem *gpioRegBase; + u32 isr; + + rk29_gpio = get_irq_chip_data(irq); + gpioRegBase = rk29_gpio->regbase; + + //ÆÁ±ÎÖжÏ6»ò7 + desc->chip->mask(irq); + //¶ÁÈ¡µ±Ç°ÖжÏ״̬£¬¼´²éѯ¾ßÌåÊÇGPIOµÄÄĸöPINÒýÆðµÄÖÐ¶Ï + isr = rk29_gpio_read(gpioRegBase,GPIO_INT_STATUS); + if (!isr) { + desc->chip->unmask(irq); + return; + } + + pin = rk29_gpio->chip.base; + gpioToirq = gpio_to_irq(pin); + gpio = &irq_desc[gpioToirq]; + + while (isr) { + if (isr & 1) { + { + unsigned int gpio_Int_Level = 0; + unsigned int mask = pin_to_mask(pin); + if(!mask) + break; + gpio_Int_Level = rk29_gpio_read(gpioRegBase,GPIO_INTTYPE_LEVEL); + if(gpio_Int_Level == 0)//±íʾ´ËÖжÏÀàÐÍÊǵçƽÖÐ¶Ï + { + rk29_gpio_bitOp(gpioRegBase,GPIO_INTMASK,mask,1); + } + generic_handle_irq(gpioToirq); + + if(gpio_Int_Level)//±íʾ´ËÖжÏÀàÐÍÊDZßÑØÖÐ¶Ï + { + rk29_gpio_bitOp(gpioRegBase,GPIO_PORTS_EOI,mask,1); + } + else//±íʾ´ËÖжÏÀàÐÍÊǵçƽÖÐ¶Ï + { + rk29_gpio_bitOp(gpioRegBase,GPIO_INTMASK,mask,0); + } + } + } + pin++; + gpio++; + isr >>= 1; + gpioToirq = gpio_to_irq(pin); + } + + desc->chip->unmask(irq); + /* now it may re-trigger */ +} + +static struct irq_chip rk29gpio_irqchip = { + .name = "RK29_GPIOIRQ", + .enable = gpio_irq_enable, + .disable = gpio_irq_disable, + .mask = gpio_irq_mask, + .unmask = gpio_irq_unmask, + .set_type = gpio_irq_type, + .set_wake = gpio_irq_set_wake, +}; + +void __init rk29_gpio_irq_setup(void) +{ + unsigned int i,j, pin,irq=IRQ_GPIO0; + struct rk29_gpio_chip *this; + + this = rk29gpio_chip; + pin = NR_IRQS; + + for(i=0;iregbase,GPIO_INTEN,0); + for (j = 0; j < 32; j++) + { + lockdep_set_class(&irq_desc[pin+j].lock, &gpio_lock_class); + /* + * Can use the "simple" and not "edge" handler since it's + * shorter, and the AIC handles interrupts sanely. + */ + set_irq_chip(pin+j, &rk29gpio_irqchip); + set_irq_handler(pin+j, handle_simple_irq); + set_irq_flags(pin+j, IRQF_VALID); + } + + switch ( this->bank->id ) + { + case RK29_ID_GPIO0: + irq = IRQ_GPIO0; + break; + case RK29_ID_GPIO1: + irq = IRQ_GPIO1; + break; + case RK29_ID_GPIO2: + irq = IRQ_GPIO2; + break; + case RK29_ID_GPIO3: + irq = IRQ_GPIO3; + break; + case RK29_ID_GPIO4: + irq = IRQ_GPIO4; + break; + case RK29_ID_GPIO5: + irq = IRQ_GPIO5; + break; + case RK29_ID_GPIO6: + irq = IRQ_GPIO6; + break; + } + + set_irq_chip_data(irq, this); + set_irq_chained_handler(irq, gpio_irq_handler); + this += 4; + pin += 32; + } + printk("rk2818_gpio_irq_setup: %d gpio irqs in 7 banks\n", pin - PIN_BASE); +} + +void __init rk29_gpio_init(struct rk29_gpio_bank *data, int nr_banks) +{ + unsigned i; + struct rk29_gpio_chip *rk29_gpio, *last = NULL; + + for (i = 0; i < nr_banks; i++) { + rk29_gpio = &rk29gpio_chip[i]; + rk29_gpio->bank = &data[i]; + rk29_gpio->regbase = (unsigned char __iomem *)rk29_gpio->bank->offset; + if(last) + last->next = rk29_gpio; + last = rk29_gpio; + + gpiochip_add(&rk29_gpio->chip); + } + printk("rk29_gpio_init:nr_banks=%d\n",nr_banks); +} \ No newline at end of file diff --git a/arch/arm/mach-rk29/include/mach/gpio.h b/arch/arm/mach-rk29/include/mach/gpio.h index 23263b155d6c..93a28a5220fd 100644 --- a/arch/arm/mach-rk29/include/mach/gpio.h +++ b/arch/arm/mach-rk29/include/mach/gpio.h @@ -15,5 +15,317 @@ #ifndef __ARCH_ARM_MACH_RK29_GPIO_H #define __ARCH_ARM_MACH_RK29_GPIO_H +typedef enum eGPIOPinLevel +{ + GPIO_LOW=0, + GPIO_HIGH +}eGPIOPinLevel_t; -#endif +typedef enum eGPIOPinDirection +{ + GPIO_IN=0, + GPIO_OUT +}eGPIOPinDirection_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 RK29_ID_GPIO0 0 +#define RK29_ID_GPIO1 1 +#define RK29_ID_GPIO2 2 +#define RK29_ID_GPIO3 3 +#define RK29_ID_GPIO4 4 +#define RK29_ID_GPIO5 5 +#define RK29_ID_GPIO6 6 + +#define NUM_GROUP 8 +#define PIN_BASE 0 +#define MAX_BANK 7 + +#define RK29_PIN0_PA0 (0*NUM_GROUP + PIN_BASE + 0); +#define RK29_PIN0_PA1 (0*NUM_GROUP + PIN_BASE + 1); +#define RK29_PIN0_PA2 (0*NUM_GROUP + PIN_BASE + 2); +#define RK29_PIN0_PA3 (0*NUM_GROUP + PIN_BASE + 3); +#define RK29_PIN0_PA4 (0*NUM_GROUP + PIN_BASE + 4); +#define RK29_PIN0_PA5 (0*NUM_GROUP + PIN_BASE + 5); +#define RK29_PIN0_PA6 (0*NUM_GROUP + PIN_BASE + 6); +#define RK29_PIN0_PA7 (0*NUM_GROUP + PIN_BASE + 7); +#define RK29_PIN0_PB0 (1*NUM_GROUP + PIN_BASE + 0); +#define RK29_PIN0_PB1 (1*NUM_GROUP + PIN_BASE + 1); +#define RK29_PIN0_PB2 (1*NUM_GROUP + PIN_BASE + 2); +#define RK29_PIN0_PB3 (1*NUM_GROUP + PIN_BASE + 3); +#define RK29_PIN0_PB4 (1*NUM_GROUP + PIN_BASE + 4); +#define RK29_PIN0_PB5 (1*NUM_GROUP + PIN_BASE + 5); +#define RK29_PIN0_PB6 (1*NUM_GROUP + PIN_BASE + 6); +#define RK29_PIN0_PB7 (1*NUM_GROUP + PIN_BASE + 7); +#define RK29_PIN0_PC0 (2*NUM_GROUP + PIN_BASE + 0); +#define RK29_PIN0_PC1 (2*NUM_GROUP + PIN_BASE + 1); +#define RK29_PIN0_PC2 (2*NUM_GROUP + PIN_BASE + 2); +#define RK29_PIN0_PC3 (2*NUM_GROUP + PIN_BASE + 3); +#define RK29_PIN0_PC4 (2*NUM_GROUP + PIN_BASE + 4); +#define RK29_PIN0_PC5 (2*NUM_GROUP + PIN_BASE + 5); +#define RK29_PIN0_PC6 (2*NUM_GROUP + PIN_BASE + 6); +#define RK29_PIN0_PC7 (2*NUM_GROUP + PIN_BASE + 7); +#define RK29_PIN0_PD0 (3*NUM_GROUP + PIN_BASE + 0); +#define RK29_PIN0_PD1 (3*NUM_GROUP + PIN_BASE + 1); +#define RK29_PIN0_PD2 (3*NUM_GROUP + PIN_BASE + 2); +#define RK29_PIN0_PD3 (3*NUM_GROUP + PIN_BASE + 3); +#define RK29_PIN0_PD4 (3*NUM_GROUP + PIN_BASE + 4); +#define RK29_PIN0_PD5 (3*NUM_GROUP + PIN_BASE + 5); +#define RK29_PIN0_PD6 (3*NUM_GROUP + PIN_BASE + 6); +#define RK29_PIN0_PD7 (3*NUM_GROUP + PIN_BASE + 7); + +#define RK29_PIN1_PA0 (4*NUM_GROUP + PIN_BASE + 0); +#define RK29_PIN1_PA1 (4*NUM_GROUP + PIN_BASE + 1); +#define RK29_PIN1_PA2 (4*NUM_GROUP + PIN_BASE + 2); +#define RK29_PIN1_PA3 (4*NUM_GROUP + PIN_BASE + 3); +#define RK29_PIN1_PA4 (4*NUM_GROUP + PIN_BASE + 4); +#define RK29_PIN1_PA5 (4*NUM_GROUP + PIN_BASE + 5); +#define RK29_PIN1_PA6 (4*NUM_GROUP + PIN_BASE + 6); +#define RK29_PIN1_PA7 (4*NUM_GROUP + PIN_BASE + 7); +#define RK29_PIN1_PB0 (5*NUM_GROUP + PIN_BASE + 0); +#define RK29_PIN1_PB1 (5*NUM_GROUP + PIN_BASE + 1); +#define RK29_PIN1_PB2 (5*NUM_GROUP + PIN_BASE + 2); +#define RK29_PIN1_PB3 (5*NUM_GROUP + PIN_BASE + 3); +#define RK29_PIN1_PB4 (5*NUM_GROUP + PIN_BASE + 4); +#define RK29_PIN1_PB5 (5*NUM_GROUP + PIN_BASE + 5); +#define RK29_PIN1_PB6 (5*NUM_GROUP + PIN_BASE + 6); +#define RK29_PIN1_PB7 (5*NUM_GROUP + PIN_BASE + 7); +#define RK29_PIN1_PC0 (6*NUM_GROUP + PIN_BASE + 0); +#define RK29_PIN1_PC1 (6*NUM_GROUP + PIN_BASE + 1); +#define RK29_PIN1_PC2 (6*NUM_GROUP + PIN_BASE + 2); +#define RK29_PIN1_PC3 (6*NUM_GROUP + PIN_BASE + 3); +#define RK29_PIN1_PC4 (6*NUM_GROUP + PIN_BASE + 4); +#define RK29_PIN1_PC5 (6*NUM_GROUP + PIN_BASE + 5); +#define RK29_PIN1_PC6 (6*NUM_GROUP + PIN_BASE + 6); +#define RK29_PIN1_PC7 (6*NUM_GROUP + PIN_BASE + 7); +#define RK29_PIN1_PD0 (7*NUM_GROUP + PIN_BASE + 0); +#define RK29_PIN1_PD1 (7*NUM_GROUP + PIN_BASE + 1); +#define RK29_PIN1_PD2 (7*NUM_GROUP + PIN_BASE + 2); +#define RK29_PIN1_PD3 (7*NUM_GROUP + PIN_BASE + 3); +#define RK29_PIN1_PD4 (7*NUM_GROUP + PIN_BASE + 4); +#define RK29_PIN1_PD5 (7*NUM_GROUP + PIN_BASE + 5); +#define RK29_PIN1_PD6 (7*NUM_GROUP + PIN_BASE + 6); +#define RK29_PIN1_PD7 (7*NUM_GROUP + PIN_BASE + 7); + +#define RK29_PIN2_PA0 (8*NUM_GROUP + PIN_BASE + 0); +#define RK29_PIN2_PA1 (8*NUM_GROUP + PIN_BASE + 1); +#define RK29_PIN2_PA2 (8*NUM_GROUP + PIN_BASE + 2); +#define RK29_PIN2_PA3 (8*NUM_GROUP + PIN_BASE + 3); +#define RK29_PIN2_PA4 (8*NUM_GROUP + PIN_BASE + 4); +#define RK29_PIN2_PA5 (8*NUM_GROUP + PIN_BASE + 5); +#define RK29_PIN2_PA6 (8*NUM_GROUP + PIN_BASE + 6); +#define RK29_PIN2_PA7 (8*NUM_GROUP + PIN_BASE + 7); +#define RK29_PIN2_PB0 (9*NUM_GROUP + PIN_BASE + 0); +#define RK29_PIN2_PB1 (9*NUM_GROUP + PIN_BASE + 1); +#define RK29_PIN2_PB2 (9*NUM_GROUP + PIN_BASE + 2); +#define RK29_PIN2_PB3 (9*NUM_GROUP + PIN_BASE + 3); +#define RK29_PIN2_PB4 (9*NUM_GROUP + PIN_BASE + 4); +#define RK29_PIN2_PB5 (9*NUM_GROUP + PIN_BASE + 5); +#define RK29_PIN2_PB6 (9*NUM_GROUP + PIN_BASE + 6); +#define RK29_PIN2_PB7 (9*NUM_GROUP + PIN_BASE + 7); +#define RK29_PIN2_PC0 (10*NUM_GROUP + PIN_BASE + 0); +#define RK29_PIN2_PC1 (10*NUM_GROUP + PIN_BASE + 1); +#define RK29_PIN2_PC2 (10*NUM_GROUP + PIN_BASE + 2); +#define RK29_PIN2_PC3 (10*NUM_GROUP + PIN_BASE + 3); +#define RK29_PIN2_PC4 (10*NUM_GROUP + PIN_BASE + 4); +#define RK29_PIN2_PC5 (10*NUM_GROUP + PIN_BASE + 5); +#define RK29_PIN2_PC6 (10*NUM_GROUP + PIN_BASE + 6); +#define RK29_PIN2_PC7 (10*NUM_GROUP + PIN_BASE + 7); +#define RK29_PIN2_PD0 (11*NUM_GROUP + PIN_BASE + 0); +#define RK29_PIN2_PD1 (11*NUM_GROUP + PIN_BASE + 1); +#define RK29_PIN2_PD2 (11*NUM_GROUP + PIN_BASE + 2); +#define RK29_PIN2_PD3 (11*NUM_GROUP + PIN_BASE + 3); +#define RK29_PIN2_PD4 (11*NUM_GROUP + PIN_BASE + 4); +#define RK29_PIN2_PD5 (11*NUM_GROUP + PIN_BASE + 5); +#define RK29_PIN2_PD6 (11*NUM_GROUP + PIN_BASE + 6); +#define RK29_PIN2_PD7 (11*NUM_GROUP + PIN_BASE + 7); + +#define RK29_PIN3_PA0 (12*NUM_GROUP + PIN_BASE + 0); +#define RK29_PIN3_PA1 (12*NUM_GROUP + PIN_BASE + 1); +#define RK29_PIN3_PA2 (12*NUM_GROUP + PIN_BASE + 2); +#define RK29_PIN3_PA3 (12*NUM_GROUP + PIN_BASE + 3); +#define RK29_PIN3_PA4 (12*NUM_GROUP + PIN_BASE + 4); +#define RK29_PIN3_PA5 (12*NUM_GROUP + PIN_BASE + 5); +#define RK29_PIN3_PA6 (12*NUM_GROUP + PIN_BASE + 6); +#define RK29_PIN3_PA7 (12*NUM_GROUP + PIN_BASE + 7); +#define RK29_PIN3_PB0 (13*NUM_GROUP + PIN_BASE + 0); +#define RK29_PIN3_PB1 (13*NUM_GROUP + PIN_BASE + 1); +#define RK29_PIN3_PB2 (13*NUM_GROUP + PIN_BASE + 2); +#define RK29_PIN3_PB3 (13*NUM_GROUP + PIN_BASE + 3); +#define RK29_PIN3_PB4 (13*NUM_GROUP + PIN_BASE + 4); +#define RK29_PIN3_PB5 (13*NUM_GROUP + PIN_BASE + 5); +#define RK29_PIN3_PB6 (13*NUM_GROUP + PIN_BASE + 6); +#define RK29_PIN3_PB7 (13*NUM_GROUP + PIN_BASE + 7); +#define RK29_PIN3_PC0 (14*NUM_GROUP + PIN_BASE + 0); +#define RK29_PIN3_PC1 (14*NUM_GROUP + PIN_BASE + 1); +#define RK29_PIN3_PC2 (14*NUM_GROUP + PIN_BASE + 2); +#define RK29_PIN3_PC3 (14*NUM_GROUP + PIN_BASE + 3); +#define RK29_PIN3_PC4 (14*NUM_GROUP + PIN_BASE + 4); +#define RK29_PIN3_PC5 (14*NUM_GROUP + PIN_BASE + 5); +#define RK29_PIN3_PC6 (14*NUM_GROUP + PIN_BASE + 6); +#define RK29_PIN3_PC7 (14*NUM_GROUP + PIN_BASE + 7); +#define RK29_PIN3_PD0 (15*NUM_GROUP + PIN_BASE + 0); +#define RK29_PIN3_PD1 (15*NUM_GROUP + PIN_BASE + 1); +#define RK29_PIN3_PD2 (15*NUM_GROUP + PIN_BASE + 2); +#define RK29_PIN3_PD3 (15*NUM_GROUP + PIN_BASE + 3); +#define RK29_PIN3_PD4 (15*NUM_GROUP + PIN_BASE + 4); +#define RK29_PIN3_PD5 (15*NUM_GROUP + PIN_BASE + 5); +#define RK29_PIN3_PD6 (15*NUM_GROUP + PIN_BASE + 6); +#define RK29_PIN3_PD7 (15*NUM_GROUP + PIN_BASE + 7); + +#define RK29_PIN4_PA0 (16*NUM_GROUP + PIN_BASE + 0); +#define RK29_PIN4_PA1 (16*NUM_GROUP + PIN_BASE + 1); +#define RK29_PIN4_PA2 (16*NUM_GROUP + PIN_BASE + 2); +#define RK29_PIN4_PA3 (16*NUM_GROUP + PIN_BASE + 3); +#define RK29_PIN4_PA4 (16*NUM_GROUP + PIN_BASE + 4); +#define RK29_PIN4_PA5 (16*NUM_GROUP + PIN_BASE + 5); +#define RK29_PIN4_PA6 (16*NUM_GROUP + PIN_BASE + 6); +#define RK29_PIN4_PA7 (16*NUM_GROUP + PIN_BASE + 7); +#define RK29_PIN4_PB0 (17*NUM_GROUP + PIN_BASE + 0); +#define RK29_PIN4_PB1 (17*NUM_GROUP + PIN_BASE + 1); +#define RK29_PIN4_PB2 (17*NUM_GROUP + PIN_BASE + 2); +#define RK29_PIN4_PB3 (17*NUM_GROUP + PIN_BASE + 3); +#define RK29_PIN4_PB4 (17*NUM_GROUP + PIN_BASE + 4); +#define RK29_PIN4_PB5 (17*NUM_GROUP + PIN_BASE + 5); +#define RK29_PIN4_PB6 (17*NUM_GROUP + PIN_BASE + 6); +#define RK29_PIN4_PB7 (17*NUM_GROUP + PIN_BASE + 7); +#define RK29_PIN4_PC0 (18*NUM_GROUP + PIN_BASE + 0); +#define RK29_PIN4_PC1 (18*NUM_GROUP + PIN_BASE + 1); +#define RK29_PIN4_PC2 (18*NUM_GROUP + PIN_BASE + 2); +#define RK29_PIN4_PC3 (18*NUM_GROUP + PIN_BASE + 3); +#define RK29_PIN4_PC4 (18*NUM_GROUP + PIN_BASE + 4); +#define RK29_PIN4_PC5 (18*NUM_GROUP + PIN_BASE + 5); +#define RK29_PIN4_PC6 (18*NUM_GROUP + PIN_BASE + 6); +#define RK29_PIN4_PC7 (18*NUM_GROUP + PIN_BASE + 7); +#define RK29_PIN4_PD0 (19*NUM_GROUP + PIN_BASE + 0); +#define RK29_PIN4_PD1 (19*NUM_GROUP + PIN_BASE + 1); +#define RK29_PIN4_PD2 (19*NUM_GROUP + PIN_BASE + 2); +#define RK29_PIN4_PD3 (19*NUM_GROUP + PIN_BASE + 3); +#define RK29_PIN4_PD4 (19*NUM_GROUP + PIN_BASE + 4); +#define RK29_PIN4_PD5 (19*NUM_GROUP + PIN_BASE + 5); +#define RK29_PIN4_PD6 (19*NUM_GROUP + PIN_BASE + 6); +#define RK29_PIN4_PD7 (19*NUM_GROUP + PIN_BASE + 7); + +#define RK29_PIN5_PA0 (20*NUM_GROUP + PIN_BASE + 0); +#define RK29_PIN5_PA1 (20*NUM_GROUP + PIN_BASE + 1); +#define RK29_PIN5_PA2 (20*NUM_GROUP + PIN_BASE + 2); +#define RK29_PIN5_PA3 (20*NUM_GROUP + PIN_BASE + 3); +#define RK29_PIN5_PA4 (20*NUM_GROUP + PIN_BASE + 4); +#define RK29_PIN5_PA5 (20*NUM_GROUP + PIN_BASE + 5); +#define RK29_PIN5_PA6 (20*NUM_GROUP + PIN_BASE + 6); +#define RK29_PIN5_PA7 (20*NUM_GROUP + PIN_BASE + 7); +#define RK29_PIN5_PB0 (21*NUM_GROUP + PIN_BASE + 0); +#define RK29_PIN5_PB1 (21*NUM_GROUP + PIN_BASE + 1); +#define RK29_PIN5_PB2 (21*NUM_GROUP + PIN_BASE + 2); +#define RK29_PIN5_PB3 (21*NUM_GROUP + PIN_BASE + 3); +#define RK29_PIN5_PB4 (21*NUM_GROUP + PIN_BASE + 4); +#define RK29_PIN5_PB5 (21*NUM_GROUP + PIN_BASE + 5); +#define RK29_PIN5_PB6 (21*NUM_GROUP + PIN_BASE + 6); +#define RK29_PIN5_PB7 (21*NUM_GROUP + PIN_BASE + 7); +#define RK29_PIN5_PC0 (22*NUM_GROUP + PIN_BASE + 0); +#define RK29_PIN5_PC1 (22*NUM_GROUP + PIN_BASE + 1); +#define RK29_PIN5_PC2 (22*NUM_GROUP + PIN_BASE + 2); +#define RK29_PIN5_PC3 (22*NUM_GROUP + PIN_BASE + 3); +#define RK29_PIN5_PC4 (22*NUM_GROUP + PIN_BASE + 4); +#define RK29_PIN5_PC5 (22*NUM_GROUP + PIN_BASE + 5); +#define RK29_PIN5_PC6 (22*NUM_GROUP + PIN_BASE + 6); +#define RK29_PIN5_PC7 (22*NUM_GROUP + PIN_BASE + 7); +#define RK29_PIN5_PD0 (23*NUM_GROUP + PIN_BASE + 0); +#define RK29_PIN5_PD1 (23*NUM_GROUP + PIN_BASE + 1); +#define RK29_PIN5_PD2 (23*NUM_GROUP + PIN_BASE + 2); +#define RK29_PIN5_PD3 (23*NUM_GROUP + PIN_BASE + 3); +#define RK29_PIN5_PD4 (23*NUM_GROUP + PIN_BASE + 4); +#define RK29_PIN5_PD5 (23*NUM_GROUP + PIN_BASE + 5); +#define RK29_PIN5_PD6 (23*NUM_GROUP + PIN_BASE + 6); +#define RK29_PIN5_PD7 (23*NUM_GROUP + PIN_BASE + 7); + +#define RK29_PIN6_PA0 (24*NUM_GROUP + PIN_BASE + 0); +#define RK29_PIN6_PA1 (24*NUM_GROUP + PIN_BASE + 1); +#define RK29_PIN6_PA2 (24*NUM_GROUP + PIN_BASE + 2); +#define RK29_PIN6_PA3 (24*NUM_GROUP + PIN_BASE + 3); +#define RK29_PIN6_PA4 (24*NUM_GROUP + PIN_BASE + 4); +#define RK29_PIN6_PA5 (24*NUM_GROUP + PIN_BASE + 5); +#define RK29_PIN6_PA6 (24*NUM_GROUP + PIN_BASE + 6); +#define RK29_PIN6_PA7 (24*NUM_GROUP + PIN_BASE + 7); +#define RK29_PIN6_PB0 (25*NUM_GROUP + PIN_BASE + 0); +#define RK29_PIN6_PB1 (25*NUM_GROUP + PIN_BASE + 1); +#define RK29_PIN6_PB2 (25*NUM_GROUP + PIN_BASE + 2); +#define RK29_PIN6_PB3 (25*NUM_GROUP + PIN_BASE + 3); +#define RK29_PIN6_PB4 (25*NUM_GROUP + PIN_BASE + 4); +#define RK29_PIN6_PB5 (25*NUM_GROUP + PIN_BASE + 5); +#define RK29_PIN6_PB6 (25*NUM_GROUP + PIN_BASE + 6); +#define RK29_PIN6_PB7 (25*NUM_GROUP + PIN_BASE + 7); +#define RK29_PIN6_PC0 (26*NUM_GROUP + PIN_BASE + 0); +#define RK29_PIN6_PC1 (26*NUM_GROUP + PIN_BASE + 1); +#define RK29_PIN6_PC2 (26*NUM_GROUP + PIN_BASE + 2); +#define RK29_PIN6_PC3 (26*NUM_GROUP + PIN_BASE + 3); +#define RK29_PIN6_PC4 (26*NUM_GROUP + PIN_BASE + 4); +#define RK29_PIN6_PC5 (26*NUM_GROUP + PIN_BASE + 5); +#define RK29_PIN6_PC6 (26*NUM_GROUP + PIN_BASE + 6); +#define RK29_PIN6_PC7 (26*NUM_GROUP + PIN_BASE + 7); +#define RK29_PIN6_PD0 (27*NUM_GROUP + PIN_BASE + 0); +#define RK29_PIN6_PD1 (27*NUM_GROUP + PIN_BASE + 1); +#define RK29_PIN6_PD2 (27*NUM_GROUP + PIN_BASE + 2); +#define RK29_PIN6_PD3 (27*NUM_GROUP + PIN_BASE + 3); +#define RK29_PIN6_PD4 (27*NUM_GROUP + PIN_BASE + 4); +#define RK29_PIN6_PD5 (27*NUM_GROUP + PIN_BASE + 5); +#define RK29_PIN6_PD6 (27*NUM_GROUP + PIN_BASE + 6); +#define RK29_PIN6_PD7 (27*NUM_GROUP + PIN_BASE + 7); + +#define ARCH_NR_GPIOS (NUM_GROUP*MAX_BANK*4) + +struct rk29_gpio_bank { + unsigned short id; + unsigned long offset; +}; + +#ifndef __ASSEMBLY__ +extern void __init rk29_gpio_init(struct rk29_gpio_bank *data, int nr_banks); +extern void __init rk29_gpio_irq_setup(void); +/*-------------------------------------------------------------------------*/ + +/* 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 */ + +#define gpio_get_value __gpio_get_value +#define gpio_set_value __gpio_set_value +#define gpio_cansleep __gpio_cansleep + +static inline int gpio_to_irq(unsigned gpio) +{ + return gpio; +} + +static inline int irq_to_gpio(unsigned irq) +{ + return irq; +} + +#endif /* __ASSEMBLY__ */ + +#endif + diff --git a/arch/arm/mach-rk29/include/mach/iomux.h b/arch/arm/mach-rk29/include/mach/iomux.h index 1dbc794e4260..41fade1bdfcb 100644 --- a/arch/arm/mach-rk29/include/mach/iomux.h +++ b/arch/arm/mach-rk29/include/mach/iomux.h @@ -692,6 +692,13 @@ #define GPIO5C1_EBCSDDO1_SMCDATA1_NAME "gpio5c1_ebcsddo1_smcdata1_name" #define GPIO5C0_EBCSDDO0_SMCDATA0_NAME "gpio5c0_ebcsddo0_smcdata0_name" +#define GRF_GPIO0_PULL 0x0078 +#define GRF_GPIO1_PULL 0x007C +#define GRF_GPIO2_PULL 0x0080 +#define GRF_GPIO3_PULL 0x0084 +#define GRF_GPIO4_PULL 0x0088 +#define GRF_GPIO5_PULL 0x008C +#define GRF_GPIO6_PULL 0x0090 #define MUX_CFG(desc,reg,off,interl,mux_mode,bflags) \ { \ diff --git a/arch/arm/mach-rk29/include/mach/rk29_iomap.h b/arch/arm/mach-rk29/include/mach/rk29_iomap.h index fa1fadcc2c50..bea219587a5d 100644 --- a/arch/arm/mach-rk29/include/mach/rk29_iomap.h +++ b/arch/arm/mach-rk29/include/mach/rk29_iomap.h @@ -123,6 +123,7 @@ #define RK29_I2C0_SIZE SZ_16K #define RK29_UART0_PHYS 0x20030000 #define RK29_UART0_SIZE SZ_16K +#define RK29_GPIO0_BASE (RK29_ADDR_BASE1+0x34000) #define RK29_GPIO0_PHYS 0x20034000 #define RK29_GPIO0_SIZE SZ_16K #define RK29_TIMER0_BASE (RK29_ADDR_BASE1+0x38000) @@ -131,8 +132,10 @@ #define RK29_TIMER1_BASE (RK29_ADDR_BASE1+0x3A000) #define RK29_TIMER1_PHYS 0x2003A000 #define RK29_TIMER1_SIZE SZ_8K +#define RK29_GPIO4_BASE (RK29_ADDR_BASE1+0x3C000) #define RK29_GPIO4_PHYS 0x2003C000 #define RK29_GPIO4_SIZE SZ_8K +#define RK29_GPIO6_BASE (RK29_ADDR_BASE1+0x3E000) #define RK29_GPIO6_PHYS 0x2003E000 #define RK29_GPIO6_SIZE SZ_8K @@ -170,12 +173,16 @@ #define RK29_DMA2_SIZE SZ_16K #define RK29_SMC_PHYS 0x2007C000 #define RK29_SMC_SIZE SZ_16K +#define RK29_GPIO1_BASE (RK29_ADDR_BASE1+0x80000) #define RK29_GPIO1_PHYS 0x20080000 #define RK29_GPIO1_SIZE SZ_16K +#define RK29_GPIO2_BASE (RK29_ADDR_BASE1+0x84000) #define RK29_GPIO2_PHYS 0x20084000 #define RK29_GPIO2_SIZE SZ_16K +#define RK29_GPIO3_BASE (RK29_ADDR_BASE1+0x88000) #define RK29_GPIO3_PHYS 0x20088000 #define RK29_GPIO3_SIZE SZ_16K +#define RK29_GPIO5_BASE (RK29_ADDR_BASE1+0x8C000) #define RK29_GPIO5_PHYS 0x2008C000 #define RK29_GPIO5_SIZE SZ_16K #endif diff --git a/arch/arm/mach-rk29/io.c b/arch/arm/mach-rk29/io.c index 99117d0e0285..163fffe13c21 100644 --- a/arch/arm/mach-rk29/io.c +++ b/arch/arm/mach-rk29/io.c @@ -38,6 +38,13 @@ static struct map_desc rk29_io_desc[] __initdata = { RK29_DEVICE(UART1), RK29_DEVICE(GRF), RK29_DEVICE(CRU), + RK29_DEVICE(GPIO0), + RK29_DEVICE(GPIO1), + RK29_DEVICE(GPIO2), + RK29_DEVICE(GPIO3), + RK29_DEVICE(GPIO4), + RK29_DEVICE(GPIO5), + RK29_DEVICE(GPIO6), }; void __init rk29_map_common_io(void) diff --git a/drivers/serial/rk29_serial.c b/drivers/serial/rk29_serial.c index 0fd57bfd70ad..72bbe3647768 100644 --- a/drivers/serial/rk29_serial.c +++ b/drivers/serial/rk29_serial.c @@ -104,14 +104,14 @@ static void rk29_serial_pm(struct uart_port *port, unsigned int state, * Enable the peripheral clock for this serial port. * This is called on uart_open() or a resume event. */ - //clk_enable(rk29_port->clk); + clk_enable(rk29_port->clk); break; case 3: /* * Disable the peripheral clock for this serial port. * This is called on uart_close() or a suspend event. */ - //clk_disable(rk29_port->clk); + clk_disable(rk29_port->clk); break; default: printk(KERN_ERR "rk29_serial: unknown pm %d\n", state); @@ -266,7 +266,7 @@ static void rk29_serial_shutdown(struct uart_port *port) { struct rk29_port *rk29_port = UART_TO_RK29(port); rk29_uart_write(port,0x00,UART_IER); - //clk_disable(rk29_port->clk); + clk_disable(rk29_port->clk); free_irq(port->irq, port); } /* @@ -286,7 +286,7 @@ static int rk29_serial_startup(struct uart_port *port) rk29_serial_shutdown(port); return retval; } - //clk_enable(rk29_port->clk); + clk_enable(rk29_port->clk); rk29_uart_write(port,0xf1,UART_FCR); rk29_uart_write(port,0x01,UART_SFE);///enable fifo rk29_uart_write(port,UART_IER_RECV_DATA_AVAIL_INT_ENABLE,UART_IER); //enable uart recevice IRQ @@ -635,7 +635,7 @@ static int __devinit rk29_serial_probe(struct platform_device *pdev) port->dev = &pdev->dev; rk29_port = UART_TO_RK29(port); - ///rk29_port->clk = clk_get(&pdev->dev, "uart"); + rk29_port->clk = clk_get(&pdev->dev, "uart"); if (unlikely(IS_ERR(rk29_port->clk))) return PTR_ERR(rk29_port->clk); port->uartclk = 24000000; ///clk_get_rate(rk29_port->clk); @@ -658,7 +658,7 @@ static int __devexit rk29_serial_remove(struct platform_device *pdev) { struct rk29_port *rk29_port = platform_get_drvdata(pdev); - ///clk_put(rk29_port->clk); + clk_put(rk29_port->clk); return 0; }