add linux interface for spi_gpio.c
authorroot <root@lw-desktop.(none)>
Fri, 30 Jul 2010 06:05:17 +0000 (14:05 +0800)
committerroot <root@lw-desktop.(none)>
Fri, 30 Jul 2010 06:05:17 +0000 (14:05 +0800)
arch/arm/mach-rk2818/include/mach/gpio.h
arch/arm/mach-rk2818/include/mach/spi_fpga.h
drivers/fpga/spi_gpio.c [changed mode: 0644->0755]

index fba5bf1165e5a05d978e3d8fc359b452c9c78fab..e75f459ed58287efcbb38bf55ed157c5438c30b9 100755 (executable)
@@ -168,14 +168,116 @@ struct rk2818_gpio_bank {
 #define        RK2818_PIN_PH6  (PIN_BASE + 7*NUM_GROUP + 6)
 #define        RK2818_PIN_PH7  (PIN_BASE + 7*NUM_GROUP + 7)
 /***********************define extern gpio pin num******************************/
-#define        RK2818_PIN_PI0 (GPIOS_EXPANDER_BASE + 0)
-#define        RK2818_PIN_PI1 (GPIOS_EXPANDER_BASE +1)
-#define        RK2818_PIN_PI2 (GPIOS_EXPANDER_BASE +2)
-#define        RK2818_PIN_PI3 (GPIOS_EXPANDER_BASE +3)
-#define        RK2818_PIN_PI4 (GPIOS_EXPANDER_BASE +4)
-#define        RK2818_PIN_PI5 (GPIOS_EXPANDER_BASE +5)
-#define        RK2818_PIN_PI6 (GPIOS_EXPANDER_BASE +6)
-#define        RK2818_PIN_PI7 (GPIOS_EXPANDER_BASE +7)
+#if defined(CONFIG_SPI_GPIO)
+#define        FPGA_PIN_PA0 (GPIOS_EXPANDER_BASE + 0*NUM_GROUP + 0)
+#define        FPGA_PIN_PA1 (GPIOS_EXPANDER_BASE + 0*NUM_GROUP + 1)
+#define        FPGA_PIN_PA2 (GPIOS_EXPANDER_BASE + 0*NUM_GROUP + 2)
+#define        FPGA_PIN_PA3 (GPIOS_EXPANDER_BASE + 0*NUM_GROUP + 3)
+#define        FPGA_PIN_PA4 (GPIOS_EXPANDER_BASE + 0*NUM_GROUP + 4)
+#define        FPGA_PIN_PA5 (GPIOS_EXPANDER_BASE + 0*NUM_GROUP + 5)
+#define        FPGA_PIN_PA6 (GPIOS_EXPANDER_BASE + 0*NUM_GROUP + 6)
+#define        FPGA_PIN_PA7 (GPIOS_EXPANDER_BASE + 0*NUM_GROUP + 7)
+
+#define        FPGA_PIN_PB0 (GPIOS_EXPANDER_BASE + 1*NUM_GROUP + 0)
+#define        FPGA_PIN_PB1 (GPIOS_EXPANDER_BASE + 1*NUM_GROUP + 1)
+#define        FPGA_PIN_PB2 (GPIOS_EXPANDER_BASE + 1*NUM_GROUP + 2)
+#define        FPGA_PIN_PB3 (GPIOS_EXPANDER_BASE + 1*NUM_GROUP + 3)
+#define        FPGA_PIN_PB4 (GPIOS_EXPANDER_BASE + 1*NUM_GROUP + 4)
+#define        FPGA_PIN_PB5 (GPIOS_EXPANDER_BASE + 1*NUM_GROUP + 5)
+#define        FPGA_PIN_PB6 (GPIOS_EXPANDER_BASE + 1*NUM_GROUP + 6)
+#define        FPGA_PIN_PB7 (GPIOS_EXPANDER_BASE + 1*NUM_GROUP + 7)
+
+#define        FPGA_PIN_PC0 (GPIOS_EXPANDER_BASE + 2*NUM_GROUP + 0)
+#define        FPGA_PIN_PC1 (GPIOS_EXPANDER_BASE + 2*NUM_GROUP + 1)
+#define        FPGA_PIN_PC2 (GPIOS_EXPANDER_BASE + 2*NUM_GROUP + 2)
+#define        FPGA_PIN_PC3 (GPIOS_EXPANDER_BASE + 2*NUM_GROUP + 3)
+#define        FPGA_PIN_PC4 (GPIOS_EXPANDER_BASE + 2*NUM_GROUP + 4)
+#define        FPGA_PIN_PC5 (GPIOS_EXPANDER_BASE + 2*NUM_GROUP + 5)
+#define        FPGA_PIN_PC6 (GPIOS_EXPANDER_BASE + 2*NUM_GROUP + 6)
+#define        FPGA_PIN_PC7 (GPIOS_EXPANDER_BASE + 2*NUM_GROUP + 7)
+
+#define        FPGA_PIN_PD0 (GPIOS_EXPANDER_BASE + 3*NUM_GROUP + 0)
+#define        FPGA_PIN_PD1 (GPIOS_EXPANDER_BASE + 3*NUM_GROUP + 1)
+#define        FPGA_PIN_PD2 (GPIOS_EXPANDER_BASE + 3*NUM_GROUP + 2)
+#define        FPGA_PIN_PD3 (GPIOS_EXPANDER_BASE + 3*NUM_GROUP + 3)
+#define        FPGA_PIN_PD4 (GPIOS_EXPANDER_BASE + 3*NUM_GROUP + 4)
+#define        FPGA_PIN_PD5 (GPIOS_EXPANDER_BASE + 3*NUM_GROUP + 5)
+#define        FPGA_PIN_PD6 (GPIOS_EXPANDER_BASE + 3*NUM_GROUP + 6)
+#define        FPGA_PIN_PD7 (GPIOS_EXPANDER_BASE + 3*NUM_GROUP + 7)
+
+#define        FPGA_PIN_PE0 (GPIOS_EXPANDER_BASE + 4*NUM_GROUP + 0)
+#define        FPGA_PIN_PE1 (GPIOS_EXPANDER_BASE + 4*NUM_GROUP + 1)
+#define        FPGA_PIN_PE2 (GPIOS_EXPANDER_BASE + 4*NUM_GROUP + 2)
+#define        FPGA_PIN_PE3 (GPIOS_EXPANDER_BASE + 4*NUM_GROUP + 3)
+#define        FPGA_PIN_PE4 (GPIOS_EXPANDER_BASE + 4*NUM_GROUP + 4)
+#define        FPGA_PIN_PE5 (GPIOS_EXPANDER_BASE + 4*NUM_GROUP + 5)
+#define        FPGA_PIN_PE6 (GPIOS_EXPANDER_BASE + 4*NUM_GROUP + 6)
+#define        FPGA_PIN_PE7 (GPIOS_EXPANDER_BASE + 4*NUM_GROUP + 7)
+
+#define        FPGA_PIN_PF0 (GPIOS_EXPANDER_BASE + 5*NUM_GROUP + 0)
+#define        FPGA_PIN_PF1 (GPIOS_EXPANDER_BASE + 5*NUM_GROUP + 1)
+#define        FPGA_PIN_PF2 (GPIOS_EXPANDER_BASE + 5*NUM_GROUP + 2)
+#define        FPGA_PIN_PF3 (GPIOS_EXPANDER_BASE + 5*NUM_GROUP + 3)
+#define        FPGA_PIN_PF4 (GPIOS_EXPANDER_BASE + 5*NUM_GROUP + 4)
+#define        FPGA_PIN_PF5 (GPIOS_EXPANDER_BASE + 5*NUM_GROUP + 5)
+#define        FPGA_PIN_PF6 (GPIOS_EXPANDER_BASE + 5*NUM_GROUP + 6)
+#define        FPGA_PIN_PF7 (GPIOS_EXPANDER_BASE + 5*NUM_GROUP + 7)
+
+#define        FPGA_PIN_PG0 (GPIOS_EXPANDER_BASE + 6*NUM_GROUP + 0)
+#define        FPGA_PIN_PG1 (GPIOS_EXPANDER_BASE + 6*NUM_GROUP + 1)
+#define        FPGA_PIN_PG2 (GPIOS_EXPANDER_BASE + 6*NUM_GROUP + 2)
+#define        FPGA_PIN_PG3 (GPIOS_EXPANDER_BASE + 6*NUM_GROUP + 3)
+#define        FPGA_PIN_PG4 (GPIOS_EXPANDER_BASE + 6*NUM_GROUP + 4)
+#define        FPGA_PIN_PG5 (GPIOS_EXPANDER_BASE + 6*NUM_GROUP + 5)
+#define        FPGA_PIN_PG6 (GPIOS_EXPANDER_BASE + 6*NUM_GROUP + 6)
+#define        FPGA_PIN_PG7 (GPIOS_EXPANDER_BASE + 6*NUM_GROUP + 7)
+
+#define        FPGA_PIN_PH0 (GPIOS_EXPANDER_BASE + 7*NUM_GROUP + 0)
+#define        FPGA_PIN_PH1 (GPIOS_EXPANDER_BASE + 7*NUM_GROUP + 1)
+#define        FPGA_PIN_PH2 (GPIOS_EXPANDER_BASE + 7*NUM_GROUP + 2)
+#define        FPGA_PIN_PH3 (GPIOS_EXPANDER_BASE + 7*NUM_GROUP + 3)
+#define        FPGA_PIN_PH4 (GPIOS_EXPANDER_BASE + 7*NUM_GROUP + 4)
+#define        FPGA_PIN_PH5 (GPIOS_EXPANDER_BASE + 7*NUM_GROUP + 5)
+#define        FPGA_PIN_PH6 (GPIOS_EXPANDER_BASE + 7*NUM_GROUP + 6)
+#define        FPGA_PIN_PH7 (GPIOS_EXPANDER_BASE + 7*NUM_GROUP + 7)
+
+#define        FPGA_PIN_PI0 (GPIOS_EXPANDER_BASE + 8*NUM_GROUP + 0)
+#define        FPGA_PIN_PI1 (GPIOS_EXPANDER_BASE + 8*NUM_GROUP + 1)
+#define        FPGA_PIN_PI2 (GPIOS_EXPANDER_BASE + 8*NUM_GROUP + 2)
+#define        FPGA_PIN_PI3 (GPIOS_EXPANDER_BASE + 8*NUM_GROUP + 3)
+#define        FPGA_PIN_PI4 (GPIOS_EXPANDER_BASE + 8*NUM_GROUP + 4)
+#define        FPGA_PIN_PI5 (GPIOS_EXPANDER_BASE + 8*NUM_GROUP + 5)
+#define        FPGA_PIN_PI6 (GPIOS_EXPANDER_BASE + 8*NUM_GROUP + 6)
+#define        FPGA_PIN_PI7 (GPIOS_EXPANDER_BASE + 8*NUM_GROUP + 7)
+
+#define        FPGA_PIN_PJ0 (GPIOS_EXPANDER_BASE + 9*NUM_GROUP + 0)
+#define        FPGA_PIN_PJ1 (GPIOS_EXPANDER_BASE + 9*NUM_GROUP + 1)
+#define        FPGA_PIN_PJ2 (GPIOS_EXPANDER_BASE + 9*NUM_GROUP + 2)
+#define        FPGA_PIN_PJ3 (GPIOS_EXPANDER_BASE + 9*NUM_GROUP + 3)
+#define        FPGA_PIN_PJ4 (GPIOS_EXPANDER_BASE + 9*NUM_GROUP + 4)
+#define        FPGA_PIN_PJ5 (GPIOS_EXPANDER_BASE + 9*NUM_GROUP + 5)
+#define        FPGA_PIN_PJ6 (GPIOS_EXPANDER_BASE + 9*NUM_GROUP + 6)
+#define        FPGA_PIN_PJ7 (GPIOS_EXPANDER_BASE + 9*NUM_GROUP + 7)
+
+#define        FPGA_PIN_PK0 (GPIOS_EXPANDER_BASE + 10*NUM_GROUP + 0)
+#define        FPGA_PIN_PK1 (GPIOS_EXPANDER_BASE + 10*NUM_GROUP + 1)
+#define        FPGA_PIN_PK2 (GPIOS_EXPANDER_BASE + 10*NUM_GROUP + 2)
+#define        FPGA_PIN_PK3 (GPIOS_EXPANDER_BASE + 10*NUM_GROUP + 3)
+#define        FPGA_PIN_PK4 (GPIOS_EXPANDER_BASE + 10*NUM_GROUP + 4)
+#define        FPGA_PIN_PK5 (GPIOS_EXPANDER_BASE + 10*NUM_GROUP + 5)
+#define        FPGA_PIN_PK6 (GPIOS_EXPANDER_BASE + 10*NUM_GROUP + 6)
+#define        FPGA_PIN_PK7 (GPIOS_EXPANDER_BASE + 10*NUM_GROUP + 7)
+
+#define        FPGA_PIN_PL0 (GPIOS_EXPANDER_BASE + 11*NUM_GROUP + 0)
+#define        FPGA_PIN_PL1 (GPIOS_EXPANDER_BASE + 11*NUM_GROUP + 1)
+#define        FPGA_PIN_PL2 (GPIOS_EXPANDER_BASE + 11*NUM_GROUP + 2)
+#define        FPGA_PIN_PL3 (GPIOS_EXPANDER_BASE + 11*NUM_GROUP + 3)
+#define        FPGA_PIN_PL4 (GPIOS_EXPANDER_BASE + 11*NUM_GROUP + 4)
+#define        FPGA_PIN_PL5 (GPIOS_EXPANDER_BASE + 11*NUM_GROUP + 5)
+#define        FPGA_PIN_PL6 (GPIOS_EXPANDER_BASE + 11*NUM_GROUP + 6)
+#define        FPGA_PIN_PL7 (GPIOS_EXPANDER_BASE + 11*NUM_GROUP + 7)
+
+#endif
 #ifndef __ASSEMBLY__
 extern void __init rk2818_gpio_init(struct rk2818_gpio_bank *data, int nr_banks);
 extern void __init rk2818_gpio_irq_setup(void);
@@ -211,10 +313,12 @@ static inline int irq_to_gpio(unsigned irq)
     {
         return (RK2818_PIN_PE0 + (irq - __gpio_to_irq(RK2818_PIN_PE0)));
     }
-   else if((irq - __gpio_to_irq(RK2818_PIN_PA0)) <3*NUM_GROUP)
+#if defined(CONFIG_SPI_GPIO)
+   else if((irq - __gpio_to_irq(FPGA_PIN_PA0)) <2*NUM_GROUP)
    {
-       return (RK2818_PIN_PI0 + (irq - __gpio_to_irq(RK2818_PIN_PI0)));
+       return (FPGA_PIN_PA0 + (irq - __gpio_to_irq(FPGA_PIN_PA0)));
     }
+#endif
     else
     {
         return -ENXIO;
index dfc5e60c58a413820c1e5cbff5ba129ec45e0598..51a402bd0b33d1d7879b460b1630af9a4b9cb854 100755 (executable)
@@ -501,6 +501,7 @@ extern int spi_request_gpio_irq(eSpiGpioPinNum_t PinNum, pSpiFunc Routine, eSpiG
 extern int spi_free_gpio_irq(eSpiGpioPinNum_t PinNum);\r
 extern int spi_gpio_handle_irq(struct spi_device *spi);\r
 extern int spi_gpio_init(void);\r
+extern void spi_gpio_irq_setup(void);\r
 extern int spi_gpio_register(struct spi_fpga_port *port);\r
 extern int spi_gpio_unregister(struct spi_fpga_port *port);\r
 #endif\r
old mode 100644 (file)
new mode 100755 (executable)
index 2c0821f..6c95195
@@ -26,7 +26,8 @@
 #include <linux/jiffies.h>\r
 #include <linux/i2c.h>\r
 #include <mach/rk2818_iomap.h>\r
-\r
+#include <linux/irq.h>\r
+#include <asm/gpio.h>\r
 #include <mach/spi_fpga.h>\r
 \r
 #if defined(CONFIG_SPI_GPIO_DEBUG)\r
@@ -35,7 +36,7 @@
 #define DBG(x...)\r
 #endif\r
 \r
-#define SPI_GPIO_TEST 0\r
+#define SPI_GPIO_TEST 1\r
 #define HIGH_SPI_TEST 1\r
 spinlock_t             gpio_lock;\r
 spinlock_t             gpio_state_lock;\r
@@ -45,6 +46,7 @@ static unsigned short int gGpio0State = 0;
 static SPI_GPIO_PDATA g_spiGpioVectorTable[SPI_GPIO_IRQ_NUM] = \\r
 {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}}; \r
 \r
+/************FPGA ²Ù×÷GPIOµÄº¯ÊýʵÏÖ************************/\r
 \r
 static void spi_gpio_write_reg(int reg, int PinNum, int set)\r
 {\r
@@ -111,7 +113,7 @@ int spi_gpio_int_sel(eSpiGpioPinNum_t PinNum,eSpiGpioTypeSel_t type)
 {\r
        int reg = get_gpio_addr(PinNum);\r
        //struct spi_fpga_port *port = pFpgaPort;\r
-       \r
+       DBG("%s:PinNum=%d,type=%d\n",__FUNCTION__,PinNum,type);\r
        if(ICE_SEL_GPIO0 == reg)\r
        {\r
                reg |= ICE_SEL_GPIO0_TYPE;\r
@@ -313,7 +315,7 @@ int spi_gpio_enable_int(eSpiGpioPinNum_t PinNum)
                reg |= ICE_SEL_GPIO0_INT_EN;\r
                if((state & (1 << PinNum )) == 0)\r
                {\r
-                       printk("Fail to enable int because it is gpio pin!\n");\r
+                       printk("%s:Fail to enable int because it is gpio pin!\n",__FUNCTION__);\r
                        return -1;\r
                }\r
                DBG("%s,PinNum=%d,IntEn=%d\n",__FUNCTION__,PinNum,SPI_GPIO_INT_ENABLE);         \r
@@ -344,7 +346,7 @@ int spi_gpio_disable_int(eSpiGpioPinNum_t PinNum)
 \r
                if((state & (1 << PinNum )) == 0)\r
                {\r
-                       printk("Fail to enable int because it is gpio pin!\n");\r
+                       printk("%s:Fail to enable int because it is gpio pin!\n",__FUNCTION__);\r
                        return -1;\r
                }\r
        \r
@@ -376,7 +378,7 @@ int spi_gpio_set_int_trigger(eSpiGpioPinNum_t PinNum,eSpiGpioIntType_t IntType)
 \r
                if((state & (1 << PinNum )) == 0)\r
                {\r
-                       printk("Fail to enable int because it is gpio pin!\n");\r
+                       printk("%s:Fail to enable int because it is gpio pin!\n",__FUNCTION__);\r
                        return -1;\r
                }\r
        \r
@@ -450,7 +452,7 @@ int spi_free_gpio_irq(eSpiGpioPinNum_t PinNum)
        return 0;\r
 }\r
        \r
-\r
+#if 0\r
 int spi_gpio_handle_irq(struct spi_device *spi)\r
 {\r
        int gpio_iir, i;\r
@@ -481,6 +483,35 @@ int spi_gpio_handle_irq(struct spi_device *spi)
        return  0;\r
 \r
 }\r
+#else\r
+int spi_gpio_handle_irq(struct spi_device *spi)\r
+{\r
+       int gpio_iir, i;\r
+       int state;\r
+       int irq;\r
+       spin_lock(&gpio_state_lock);\r
+       state = gGpio0State;\r
+       spin_unlock(&gpio_state_lock);\r
+\r
+       gpio_iir = spi_gpio_read_iir() & 0xffff;        \r
+       if(gpio_iir == 0xffff)\r
+               return -1;\r
+\r
+       DBG("gpio_iir=0x%x\n",gpio_iir);\r
+       for(i=0; i<SPI_GPIO_IRQ_NUM; i++)\r
+       {\r
+               if(((gpio_iir & (1 << i)) == 0) && ((state & (1 << i)) != 0))\r
+               {\r
+                       irq = gpio_to_irq(i);\r
+                       generic_handle_irq(irq);\r
+                       printk("%s:pin=%d,irq=%d\n",__FUNCTION__,i,irq);\r
+               }                       \r
+       }       \r
+\r
+       return  0;\r
+\r
+}\r
+#endif\r
 \r
 #if SPI_GPIO_TEST\r
 static irqreturn_t spi_gpio_int_test_0(int irq, void *dev)\r
@@ -532,7 +563,7 @@ void spi_gpio_work_handler(struct work_struct *work)
        }\r
 \r
 #elif (FPGA_TYPE == ICE_CC196)\r
-\r
+#if 0\r
        for(i=16;i<81;i++)\r
        {\r
                spi_gpio_set_pinlevel(i, TestGpioPinLevel);\r
@@ -549,6 +580,28 @@ void spi_gpio_work_handler(struct work_struct *work)
        }\r
 \r
        DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);\r
+#else\r
+       for(i=4;i<81;i++)\r
+       {\r
+               gpio_direction_output(FPGA_PIN_PA0+i,TestGpioPinLevel);\r
+               ret = gpio_direction_input(FPGA_PIN_PA0+i);\r
+               if (ret) {\r
+                       printk("%s:failed to set GPIO[%d] input\n",__FUNCTION__,FPGA_PIN_PA0+i);\r
+               }\r
+               ret = gpio_get_value (FPGA_PIN_PA0+i);\r
+               if(ret != TestGpioPinLevel)\r
+               {\r
+                       #if SPI_FPGA_TEST_DEBUG\r
+                       spi_test_wrong_handle();\r
+                       #endif\r
+                       printk("err:%s:PinNum=%d,set_pinlevel=%d but get_pinlevel=%d\n",__FUNCTION__,i,TestGpioPinLevel,ret);   \r
+               }\r
+       }\r
+\r
+       DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);\r
+#endif\r
+\r
+       \r
 \r
 #endif\r
 \r
@@ -565,7 +618,7 @@ static void spi_testgpio_timer(unsigned long data)
 \r
 #endif\r
 \r
-int spi_gpio_init(void)\r
+int spi_gpio_init_first(void)\r
 {\r
        int i,ret;\r
        struct spi_fpga_port *port = pFpgaPort;\r
@@ -749,9 +802,8 @@ int spi_gpio_init(void)
        spi_gpio_set_pindirection(SPI_GPIO_P4_08, SPI_GPIO_OUT);\r
        \r
 #endif\r
-\r
 #if SPI_GPIO_TEST\r
-\r
+#if 0\r
        for(i=0;i<81;i++)\r
        {\r
                if(i<4)\r
@@ -793,8 +845,7 @@ int spi_gpio_init(void)
 \r
        }\r
 #endif\r
-\r
-\r
+#endif\r
 #endif\r
 \r
        return 0;\r
@@ -830,8 +881,318 @@ int spi_gpio_unregister(struct spi_fpga_port *port)
        return 0;\r
 }\r
 \r
-MODULE_DESCRIPTION("Driver for spi2gpio.");\r
-MODULE_AUTHOR("luowei <lw@rock-chips.com>");\r
-MODULE_LICENSE("GPL");\r
+#if 1\r
+\r
+/************³éÏóGPIO½Ó¿Úº¯ÊýʵÏÖ²¿·Ö************************/\r
+static int spi_gpiolib_direction_input(struct gpio_chip *chip, unsigned offset)\r
+{\r
+       int pinnum = offset + chip->base -GPIOS_EXPANDER_BASE;\r
+       DBG("%s:pinnum=%d\n",__FUNCTION__,pinnum);\r
+       if(pinnum < 16)\r
+       spi_gpio_int_sel(pinnum,SPI_GPIO0_IS_GPIO);\r
+       return spi_gpio_set_pindirection(pinnum, SPI_GPIO_IN);\r
+}\r
+\r
+static int spi_gpiolib_direction_output(struct gpio_chip *chip, unsigned offset, int val)\r
+{\r
+       int pinnum = offset + chip->base -GPIOS_EXPANDER_BASE;\r
+       if(pinnum < 16)\r
+       spi_gpio_int_sel(pinnum,SPI_GPIO0_IS_GPIO);\r
+       DBG("%s:pinnum=%d\n",__FUNCTION__,pinnum);\r
+       if(GPIO_HIGH == val)\r
+       spi_gpio_set_pinlevel(pinnum,SPI_GPIO_HIGH);\r
+       else\r
+       spi_gpio_set_pinlevel(pinnum,SPI_GPIO_LOW);\r
+       return spi_gpio_set_pindirection(pinnum, SPI_GPIO_OUT);\r
+}\r
+\r
+static int spi_gpiolib_get_pinlevel(struct gpio_chip *chip, unsigned int offset)\r
+{\r
+       int pinnum = offset + chip->base -GPIOS_EXPANDER_BASE;\r
+       DBG("%s:pinnum=%d\n",__FUNCTION__,pinnum);\r
+       return spi_gpio_get_pinlevel(pinnum);\r
+}\r
+\r
+static void spi_gpiolib_set_pinlevel(struct gpio_chip *chip, unsigned int offset, int val)\r
+{\r
+       int pinnum = offset + chip->base -GPIOS_EXPANDER_BASE;\r
+       DBG("%s:pinnum=%d\n",__FUNCTION__,pinnum);\r
+       if(GPIO_HIGH == val)\r
+       spi_gpio_set_pinlevel(pinnum,SPI_GPIO_HIGH);\r
+       else\r
+       spi_gpio_set_pinlevel(pinnum,SPI_GPIO_LOW);\r
+}\r
+\r
+static int spi_gpiolib_pull_updown(struct gpio_chip *chip, unsigned offset, unsigned val)\r
+{\r
+       return 0;       //FPGA do not support pull up or down\r
+}\r
+\r
+static void spi_gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip)\r
+{\r
+       //to do \r
+}\r
+\r
+static int spi_gpiolib_to_irq(struct gpio_chip *chip, unsigned offset)\r
+{\r
+       if(offset < CONFIG_EXPANDED_GPIO_IRQ_NUM)\r
+       return offset + NR_AIC_IRQS + CONFIG_RK28_GPIO_IRQ;\r
+       else\r
+       return -EINVAL;\r
+}\r
+\r
+struct fpga_gpio_bank {\r
+       unsigned short id;                      //GPIO¼Ä´æÆ÷×éµÄIDʶ±ðºÅ\r
+       unsigned long offset;           //GPIO0»òGPIO1µÄ»ùµØÖ·\r
+       struct clk *clock;              /* associated clock */\r
+};\r
+\r
+struct fpga_gpio_chip {\r
+       struct gpio_chip        chip;\r
+       struct fpga_gpio_chip   *next;          /* Bank sharing same clock */\r
+       struct fpga_gpio_bank   *bank;          /* Bank definition */\r
+       void __iomem            *regbase;       /* Base of register bank */\r
+};\r
+\r
+#define SPI_GPIO_CHIP_DEF(name, base_gpio, nr_gpio)                    \\r
+       {                                                               \\r
+               .chip = {                                               \\r
+                       .label            = name,                       \\r
+                       .direction_input  = spi_gpiolib_direction_input, \\r
+                       .direction_output = spi_gpiolib_direction_output, \\r
+                       .get              = spi_gpiolib_get_pinlevel,           \\r
+                       .set              = spi_gpiolib_set_pinlevel,           \\r
+                       .pull_updown  = spi_gpiolib_pull_updown,         \\r
+                       .dbg_show         = spi_gpiolib_dbg_show,       \\r
+                       .to_irq       = spi_gpiolib_to_irq,     \\r
+                       .base             = base_gpio,                  \\r
+                       .ngpio            = nr_gpio,                    \\r
+               },                                                      \\r
+       }\r
 \r
+static struct fpga_gpio_chip spi_gpio_chip[] = {\r
+       SPI_GPIO_CHIP_DEF("PIO0", GPIOS_EXPANDER_BASE+0*NUM_GROUP, NUM_GROUP),\r
+       SPI_GPIO_CHIP_DEF("PIO0", GPIOS_EXPANDER_BASE+1*NUM_GROUP, NUM_GROUP),\r
+       SPI_GPIO_CHIP_DEF("PIO1", GPIOS_EXPANDER_BASE+2*NUM_GROUP, NUM_GROUP),\r
+       SPI_GPIO_CHIP_DEF("PIO1", GPIOS_EXPANDER_BASE+3*NUM_GROUP, NUM_GROUP),\r
+       SPI_GPIO_CHIP_DEF("PIO2", GPIOS_EXPANDER_BASE+4*NUM_GROUP, NUM_GROUP),\r
+       SPI_GPIO_CHIP_DEF("PIO2", GPIOS_EXPANDER_BASE+5*NUM_GROUP, NUM_GROUP),\r
+       SPI_GPIO_CHIP_DEF("PIO3", GPIOS_EXPANDER_BASE+6*NUM_GROUP, NUM_GROUP),\r
+       SPI_GPIO_CHIP_DEF("PIO3", GPIOS_EXPANDER_BASE+7*NUM_GROUP, NUM_GROUP),\r
+       SPI_GPIO_CHIP_DEF("PIO4", GPIOS_EXPANDER_BASE+8*NUM_GROUP, NUM_GROUP),\r
+       SPI_GPIO_CHIP_DEF("PIO4", GPIOS_EXPANDER_BASE+9*NUM_GROUP, NUM_GROUP),\r
+       SPI_GPIO_CHIP_DEF("PIO5", GPIOS_EXPANDER_BASE+10*NUM_GROUP, NUM_GROUP),\r
+       SPI_GPIO_CHIP_DEF("PIO5", GPIOS_EXPANDER_BASE+11*NUM_GROUP, NUM_GROUP),\r
+};\r
+\r
+\r
+static void spi_gpio_irq_enable(unsigned irq)\r
+{\r
+       int gpio = irq_to_gpio(irq) - GPIOS_EXPANDER_BASE;\r
+       DBG("%s:line=%d,gpio=%d\n",__FUNCTION__,__LINE__,gpio);\r
+       if(gpio < 16)\r
+       spi_gpio_int_sel(gpio,SPI_GPIO0_IS_INT);\r
+       else\r
+       {\r
+               printk("err:%s:pin %d don't support gpio irq!\n",__FUNCTION__,gpio);\r
+               return;\r
+       }\r
+       spi_gpio_enable_int(gpio);      \r
+}\r
 \r
+static void spi_gpio_irq_disable(unsigned irq)\r
+{\r
+       int gpio = irq_to_gpio(irq) - GPIOS_EXPANDER_BASE;\r
+       DBG("%s:line=%d,gpio=%d\n",__FUNCTION__,__LINE__,gpio);\r
+       if(gpio < 16)\r
+       spi_gpio_int_sel(gpio,SPI_GPIO0_IS_INT);\r
+       else\r
+       {\r
+               printk("err:%s:pin %d don't support gpio irq!\n",__FUNCTION__,gpio);\r
+               return;\r
+       }\r
+       spi_gpio_disable_int(gpio);\r
+\r
+}\r
+\r
+\r
+static void spi_gpio_irq_mask(unsigned int irq)\r
+{\r
+       //FPGA do not support irq mask\r
+}\r
+\r
+static void spi_gpio_irq_unmask(unsigned int irq)\r
+{\r
+       //FPGA do not support irq unmask\r
+}\r
+\r
+static int spi_gpio_irq_set_type(unsigned int irq, unsigned int type)\r
+{\r
+       int gpio = irq_to_gpio(irq) - GPIOS_EXPANDER_BASE;\r
+       int int_type = 0;\r
+       DBG("%s:line=%d,type=%d\n",__FUNCTION__,__LINE__,type);\r
+       if(gpio < 16)\r
+       spi_gpio_int_sel(gpio,SPI_GPIO0_IS_INT);\r
+       else\r
+       {\r
+               printk("err:%s:pin %d don't support gpio irq!\n",__FUNCTION__,gpio);\r
+               return -1;\r
+       }\r
+       switch(type)\r
+       {\r
+               case GPIOEdgelFalling:\r
+                       int_type = SPI_GPIO_EDGE_FALLING;\r
+                       break;\r
+               case GPIOEdgelRising:\r
+                       int_type = SPI_GPIO_EDGE_RISING;\r
+                       break;\r
+               default:\r
+                       printk("err:%s:FPGA don't support this intterupt type!\n",__FUNCTION__);        \r
+                       break;\r
+       }\r
+       spi_gpio_set_int_trigger(gpio, int_type);\r
+       return 0;\r
+}\r
+\r
+static int spi_gpio_irq_set_wake(unsigned irq, unsigned state)\r
+{\r
+       //unsigned int pin = irq_to_gpio(irq);\r
+       set_irq_wake(irq, state);\r
+       return 0;\r
+}\r
+\r
+static struct irq_chip spi_gpio_irq_chip = {\r
+       .name           = "SPI_GPIO_IRQ",\r
+       .enable                 = spi_gpio_irq_enable,\r
+       .disable                = spi_gpio_irq_disable,\r
+       .mask           = spi_gpio_irq_mask,\r
+       .unmask         = spi_gpio_irq_unmask,\r
+       .set_type               = spi_gpio_irq_set_type,\r
+       .set_wake       = spi_gpio_irq_set_wake,\r
+};\r
+\r
+void spi_gpio_test_gpio_irq_init(void)\r
+{\r
+#if SPI_GPIO_TEST\r
+       struct spi_fpga_port *port = pFpgaPort;\r
+       int i,gpio,ret;\r
+\r
+       for(i=0;i<81;i++)\r
+       {\r
+               gpio = FPGA_PIN_PA0+i;\r
+               ret = gpio_request(gpio, NULL);\r
+               if (ret) {\r
+                       printk("%s:failed to request GPIO[%d]\n",__FUNCTION__,gpio);\r
+               }\r
+       }\r
+#if 1\r
+       for(i=0;i<4;i++)\r
+       {\r
+               gpio = FPGA_PIN_PA0+i;\r
+               \r
+               switch(i)\r
+               {\r
+                       case 0:\r
+                       ret = request_irq(gpio_to_irq(gpio),spi_gpio_int_test_0,IRQF_TRIGGER_FALLING,NULL,port);\r
+                       if(ret)\r
+                       {\r
+                               printk("unable to request GPIO[%d] irq\n",gpio);\r
+                               gpio_free(gpio);\r
+                       }       \r
+                       break;\r
+\r
+                       case 1:\r
+                       ret = request_irq(gpio_to_irq(gpio),spi_gpio_int_test_1,IRQF_TRIGGER_FALLING,NULL,port);\r
+                       if(ret)\r
+                       {\r
+                               printk("unable to request GPIO[%d] irq\n",gpio);\r
+                               gpio_free(gpio);\r
+                       }       \r
+                       break;\r
+\r
+                       case 2:\r
+                       ret = request_irq(gpio_to_irq(gpio),spi_gpio_int_test_2,IRQF_TRIGGER_FALLING,NULL,port);\r
+                       if(ret)\r
+                       {\r
+                               printk("unable to request GPIO[%d] irq\n",gpio);\r
+                               gpio_free(gpio);\r
+                       }       \r
+                       break;\r
+\r
+                       case 3:\r
+                       ret = request_irq(gpio_to_irq(gpio),spi_gpio_int_test_3,IRQF_TRIGGER_FALLING,NULL,port);\r
+                       if(ret)\r
+                       {\r
+                               printk("unable to request GPIO[%d] irq\n",gpio);\r
+                               gpio_free(gpio);\r
+                       }       \r
+                       break;\r
+                       \r
+                       default:\r
+                       break;\r
+               }\r
+       \r
+       }\r
+#endif\r
+\r
+#endif\r
+\r
+}\r
+\r
+int spi_gpio_banks;\r
+static struct lock_class_key gpio_lock_class;\r
+int spi_gpio_init(void)\r
+{\r
+       unsigned                i;\r
+       struct fpga_gpio_chip *fpga_gpio_chip;\r
+       spi_gpio_banks = 12;    \r
+       spi_gpio_init_first();\r
+       for (i = 0; i < 12; i++) \r
+       {       \r
+               fpga_gpio_chip = &spi_gpio_chip[i];\r
+               gpiochip_add(&fpga_gpio_chip->chip);\r
+       }\r
+\r
+       return 0;\r
+}\r
+\r
+/*\r
+ * Called from the processor-specific init to enable GPIO interrupt support.\r
+ */\r
+void spi_gpio_irq_setup(void)\r
+{\r
+       unsigned        int     i,j, pin;\r
+       struct fpga_gpio_chip *this;\r
+       \r
+       this = spi_gpio_chip;\r
+       pin = NR_AIC_IRQS + CONFIG_RK28_GPIO_IRQ;\r
+\r
+       for(i=0;i<2;i++)\r
+       {\r
+               for (j = 0; j < 8; j++) \r
+               {\r
+                       lockdep_set_class(&irq_desc[pin+j].lock, &gpio_lock_class);\r
+                       /*\r
+                        * Can use the "simple" and not "edge" handler since it's\r
+                        * shorter, and the AIC handles interrupts sanely.\r
+                        */\r
+                       set_irq_chip(pin+j, &spi_gpio_irq_chip);\r
+                       set_irq_handler(pin+j, handle_simple_irq);\r
+                       set_irq_flags(pin+j, IRQF_VALID);\r
+                       //set_irq_chip_data(pin+j, this);\r
+                       //set_irq_chained_handler(pin+j, spi_fpga_irq);\r
+               }\r
+\r
+               this += 4; \r
+               pin += 8;\r
+       }\r
+       printk("%s: %d gpio irqs in %d banks\n", __FUNCTION__, pin-GPIOS_EXPANDER_BASE, spi_gpio_banks);\r
+#if SPI_GPIO_TEST\r
+       spi_gpio_test_gpio_irq_init();\r
+#endif\r
+}\r
+#endif\r
+\r
+MODULE_DESCRIPTION("Driver for spi2gpio.");\r
+MODULE_AUTHOR("luowei <lw@rock-chips.com>");\r
+MODULE_LICENSE("GPL");
\ No newline at end of file