add rk29 gpio
authorlhh <lhh@rock-chips.com>
Tue, 26 Oct 2010 12:46:27 +0000 (20:46 +0800)
committerlhh <lhh@rock-chips.com>
Tue, 26 Oct 2010 12:46:27 +0000 (20:46 +0800)
arch/arm/Kconfig
arch/arm/mach-rk29/Makefile
arch/arm/mach-rk29/board-rk29sdk.c
arch/arm/mach-rk29/gpio.c [new file with mode: 0644]
arch/arm/mach-rk29/include/mach/gpio.h
arch/arm/mach-rk29/include/mach/iomux.h
arch/arm/mach-rk29/include/mach/rk29_iomap.h
arch/arm/mach-rk29/io.c
drivers/serial/rk29_serial.c

index b35fec253dec861d6079b2d4b475fd6fe8949ce5..5aa36c4f303ec1d9ee3225e28d1f1062f70898ab 100644 (file)
@@ -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.
 
index 70dfd7de6331cd55c375cb926fbecd23226a7161..ba023c53436485b86b439fa1a1fd2e5e5f1210d3 100644 (file)
@@ -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
index 9191fc992dc3b09e9a5827156f486730b61a746e..eb4b35e0f32e0cdbe2d0c165599545ae6ee9ea12 100644 (file)
@@ -30,6 +30,8 @@
 #include <asm/mach/flash.h>\r
 #include <asm/hardware/gic.h>\r
 \r
+#include <mach/iomux.h>\r
+#include <mach/gpio.h>\r
 #include <mach/irqs.h>\r
 #include <mach/rk29_iomap.h>\r
 #include <mach/board.h>\r
 \r
 extern struct sys_timer rk29_timer;\r
 \r
+\r
+static struct rk29_gpio_bank rk29_gpiobankinit[] = {\r
+       {\r
+               .id             = RK29_ID_GPIO0,\r
+               .offset = RK29_GPIO0_BASE,\r
+       },\r
+       {\r
+               .id             = RK29_ID_GPIO1,\r
+               .offset = RK29_GPIO1_BASE,\r
+       }, \r
+       {\r
+               .id             = RK29_ID_GPIO2,\r
+               .offset = RK29_GPIO2_BASE,\r
+       }, \r
+       {\r
+               .id             = RK29_ID_GPIO3,\r
+               .offset = RK29_GPIO3_BASE,\r
+       }, \r
+       {\r
+               .id             = RK29_ID_GPIO4,\r
+               .offset = RK29_GPIO4_BASE,\r
+       }, \r
+       {\r
+               .id             = RK29_ID_GPIO5,\r
+               .offset = RK29_GPIO5_BASE,\r
+       }, \r
+       {\r
+               .id             = RK29_ID_GPIO6,\r
+               .offset = RK29_GPIO6_BASE,\r
+       },      \r
+};\r
+\r
 static struct platform_device *devices[] __initdata = {\r
 #ifdef CONFIG_UART1_RK29       \r
        &rk29_device_uart1,\r
@@ -58,8 +92,8 @@ static void __init rk29_gic_init_irq(void)
 static void __init machine_rk29_init_irq(void)\r
 {\r
        rk29_gic_init_irq();\r
-       //rk29_gpio_init(rk29_gpioBank, 8);\r
-       //rk29_gpio_irq_setup();\r
+       rk29_gpio_init(rk29_gpiobankinit, MAX_BANK);\r
+       rk29_gpio_irq_setup();\r
 }\r
 static void __init machine_rk29_board_init(void)\r
 { \r
@@ -70,7 +104,7 @@ static void __init machine_rk29_mapio(void)
 {\r
        rk29_map_common_io();\r
        rk29_clock_init();\r
-       //rk29_iomux_init();    \r
+       rk29_iomux_init();      \r
 }\r
 \r
 MACHINE_START(RK29, "RK29board")\r
diff --git a/arch/arm/mach-rk29/gpio.c b/arch/arm/mach-rk29/gpio.c
new file mode 100644 (file)
index 0000000..fd40ceb
--- /dev/null
@@ -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 <linux/clk.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/sysdev.h>
+
+#include <mach/hardware.h>
+#include <mach/gpio.h>
+#include <mach/rk29_iomap.h>
+#include <mach/iomux.h>
+#include <asm/gpio.h>
+
+
+#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;i<MAX_BANK;i++)
+       {
+               rk29_gpio_write(this->regbase,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
index 23263b155d6c9c8022880e08e90ec7f6274fa3a5..93a28a5220fd61534675f8b4b39ff0e5881d3f4b 100644 (file)
 #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 <asm/errno.h>
+#include <asm-generic/gpio.h>          /* 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                                                                                              
+                                                                                 
index 1dbc794e4260870c79848be94ecfbb18e85c2df2..41fade1bdfcb0fe419305450520e421c11093c80 100644 (file)
 #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)   \
 {                                                      \
index fa1fadcc2c50f2fcae018c560bf89cd683786b35..bea219587a5d90840ffd0fb558df62c112f7baad 100644 (file)
 #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)
 #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
 
 #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
index 99117d0e028566c6e4baa37a8d551941e2372942..163fffe13c215995c4f7af1020d454ddd37d0600 100644 (file)
@@ -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)
index 0fd57bfd70adaccfd68bdc7dbe2ba0d86394932a..72bbe36477680acb78dc4ebf009ead222d88ef68 100644 (file)
@@ -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;
 }