add falling and rising edge support for fpga's gpio interrupt,add support that fpga...
authorluowei <lw@rock-chips.com>
Thu, 16 Sep 2010 03:32:43 +0000 (11:32 +0800)
committerluowei <lw@rock-chips.com>
Thu, 16 Sep 2010 03:34:23 +0000 (11:34 +0800)
arch/arm/mach-rk2818/include/mach/spi_fpga.h
drivers/fpga/spi_fpga_init.c
drivers/fpga/spi_gpio.c

index d5c7023608128baaa6f4d4e5320b02fdb85b8b3a..63ead95f6534a4c05c050d5dc48d126784236a3b 100755 (executable)
@@ -203,6 +203,7 @@ struct spi_fpga_port {
 #define ICE_INT_TYPE_I2C3              (~(1<<4))\r
 #define ICE_INT_TYPE_GPIO              (~(1<<5))\r
 #define ICE_INT_TYPE_DPRAM             (~(1<<6))\r
+#define ICE_INT_TYPE_SLEEP             (~(1<<7))\r
 \r
 #define ICE_INT_I2C_ACK                        (~(1<<0))\r
 #define ICE_INT_I2C_READ               (~(1<<1))\r
@@ -231,12 +232,17 @@ struct spi_fpga_port {
 #define ICE_SEL_GPIO0_DIR                      (0X01)\r
 #define ICE_SEL_GPIO0_DATA                     (0X02)\r
 #define ICE_SEL_GPIO0_INT_EN           (0X03)\r
-#define ICE_SEL_GPIO0_INT_TRI          (0X04)\r
+#define ICE_SEL_GPIO0_INT_TRI          (0X04)          //0:falling edge  1:rising edge\r
 #define ICE_SEL_GPIO0_INT_STATE                (0X05)\r
+#define ICE_SEL_GPIO0_INT_TYPE         (0X06)          //0:edge 1:level,if 1 then support falling and rising trigger\r
+#define ICE_SEL_GPIO0_INT_WAKE         (0X07)          \r
 \r
 #define        ICE_SEL_GPIO_DIR                        (0X01)\r
 #define        ICE_SEL_GPIO_DATA                       (0X02)\r
 \r
+#define ICE_STATUS_SLEEP                       1\r
+#define ICE_STATUS_WAKE                                0\r
+\r
 /*spi to i2c*/\r
 \r
 typedef enum I2C_ch\r
@@ -344,10 +350,17 @@ typedef enum eSpiGpioPinInt
 }eSpiGpioPinInt_t;\r
 \r
 \r
-typedef enum eSpiGpioIntType \r
+typedef enum eSpiGpioIntTri \r
 {\r
        SPI_GPIO_EDGE_FALLING = 0,\r
        SPI_GPIO_EDGE_RISING,\r
+}eSpiGpioIntTri_t;\r
+\r
+\r
+typedef enum eSpiGpioIntType \r
+{\r
+       SPI_GPIO_EDGE = 0,\r
+       SPI_GPIO_LEVEL,\r
 }eSpiGpioIntType_t;\r
 \r
 typedef enum eSpiGpioPinDirection\r
@@ -532,9 +545,9 @@ extern int spi_gpio_set_pinlevel(eSpiGpioPinNum_t PinNum, eSpiGpioPinLevel_t Pin
 extern eSpiGpioPinLevel_t spi_gpio_get_pinlevel(eSpiGpioPinNum_t PinNum);\r
 extern int spi_gpio_enable_int(eSpiGpioPinNum_t PinNum);\r
 extern int spi_gpio_disable_int(eSpiGpioPinNum_t PinNum);\r
-extern int spi_gpio_set_int_trigger(eSpiGpioPinNum_t PinNum,eSpiGpioIntType_t IntType);\r
+extern int spi_gpio_set_int_trigger(eSpiGpioPinNum_t PinNum,eSpiGpioIntTri_t IntTri);\r
 extern int spi_gpio_read_iir(void);\r
-extern int spi_request_gpio_irq(eSpiGpioPinNum_t PinNum, pSpiFunc Routine, eSpiGpioIntType_t IntType,void *dev_id);\r
+extern int spi_request_gpio_irq(eSpiGpioPinNum_t PinNum, pSpiFunc Routine, eSpiGpioIntTri_t IntType,void *dev_id);\r
 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
index 0ec51b5877258f05e7b65bb90d820709b83feb6e..623e3b6ddb4b80428c5d5d9d7fc28dbab99b2dde 100755 (executable)
@@ -444,9 +444,14 @@ static void spi_fpga_irq_work_handler(struct work_struct *work)
                spi_dpram_handle_ack(spi);\r
 #endif\r
        }\r
+       else if((ret | ICE_INT_TYPE_SLEEP) == ICE_INT_TYPE_SLEEP)\r
+       {\r
+               DBG("%s:ICE_INT_TYPE_SLEEP ret=0x%x\n",__FUNCTION__,ret);\r
+               printk("FPGA wake up system now ...\n");\r
+       }\r
        else\r
        {\r
-               printk("%s:NO such INT TYPE,ret=0x%x\n",__FUNCTION__,ret);\r
+               printk("warning:ret=0x%x\n",ret);\r
        }\r
 \r
        DBG("Enter::%s,LINE=%d\n",__FUNCTION__,__LINE__);\r
@@ -472,7 +477,7 @@ static irqreturn_t spi_fpga_irq(int irq, void *dev_id)
 }\r
 \r
 \r
-static int spi_set_sysclk(int set)\r
+static int spi_fpga_set_sysclk(int set)\r
 {\r
        rk2818_mux_api_set(GPIOH7_HSADCCLK_SEL_NAME,IOMUXB_GPIO1_D7);   \r
        gpio_direction_output(SPI_FPGA_STANDBY_PIN,set);\r
@@ -480,6 +485,19 @@ static int spi_set_sysclk(int set)
        return 0;\r
 }\r
 \r
+static int spi_fpga_set_status(struct spi_fpga_port *port, int stat)\r
+{\r
+       if(stat == ICE_STATUS_SLEEP)\r
+       {\r
+               spi_out(port, (ICE_SEL_GPIO0 | ICE_SEL_GPIO0_INT_WAKE), ICE_STATUS_SLEEP, SEL_GPIO);\r
+       }\r
+       else\r
+       {\r
+               spi_out(port, (ICE_SEL_GPIO0 | ICE_SEL_GPIO0_INT_WAKE), ICE_STATUS_WAKE, SEL_GPIO);\r
+       }\r
+\r
+       return 0;\r
+}\r
 \r
 static int spi_fpga_rst(void)\r
 {\r
@@ -528,8 +546,8 @@ static int __devinit spi_fpga_probe(struct spi_device * spi)
                printk("%s:failed to request standby pin\n",__FUNCTION__);\r
                return ret;\r
        }\r
-       spi_set_sysclk(GPIO_HIGH);\r
-\r
+       spi_fpga_set_sysclk(GPIO_HIGH);\r
+       \r
 #if SPI_FPGA_TRANS_WORK\r
        init_waitqueue_head(&port->wait_wq);\r
        init_waitqueue_head(&port->wait_rq);\r
@@ -545,7 +563,8 @@ static int __devinit spi_fpga_probe(struct spi_device * spi)
        INIT_LIST_HEAD(&port->trans_queue);\r
 #endif\r
 \r
-       spi_fpga_rst();\r
+       spi_fpga_rst();         //reset fpga\r
+       \r
        sprintf(b, "fpga_irq_workqueue");\r
        port->fpga_irq_workqueue = create_rt_workqueue(b);\r
        if (!port->fpga_irq_workqueue) {\r
@@ -617,8 +636,10 @@ static int __devinit spi_fpga_probe(struct spi_device * spi)
        }       \r
        DBG("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);\r
        pFpgaPort = port;\r
+\r
        \r
 #if defined(CONFIG_SPI_FPGA_GPIO)\r
+       spi_fpga_set_status(port, ICE_STATUS_WAKE);\r
        spi_gpio_init();\r
 #endif\r
 \r
@@ -653,7 +674,7 @@ static int spi_fpga_wait_suspend(struct spi_fpga_port *port)
        int i,n_tx,n_rx;\r
        for(i=0;i<1000;i++)\r
        {\r
-               n_tx = spi_in(port, UART_LSR, READ_TOP_INT);\r
+               n_tx = spi_in(port, UART_LSR, READ_TOP_INT);    //CONFIG_SPI_FPGA_UART = 1\r
                n_rx = spi_in(port, UART_LSR, SEL_UART);\r
                if((((n_tx >> 8) & 0x3f) == 0) && (((n_rx >> 8) & 0x3f) == 0))  //no data in tx_buf and rx_buf\r
                {\r
@@ -667,27 +688,37 @@ static int spi_fpga_wait_suspend(struct spi_fpga_port *port)
 \r
 static int spi_fpga_suspend(struct spi_device *spi, pm_message_t state)\r
 {\r
+\r
        struct spi_fpga_port *port = dev_get_drvdata(&spi->dev);\r
        int ret;\r
        ret = spi_fpga_wait_suspend(port);\r
        if(!ret)\r
        {\r
-               spi_set_sysclk(GPIO_LOW);\r
+               spi_fpga_set_status(port, ICE_STATUS_SLEEP);    //CONFIG_SPI_FPGA_GPIO = 1\r
+               udelay(1);\r
+               spi_fpga_set_sysclk(GPIO_LOW);\r
        }\r
        else\r
        {\r
                printk("fail to suspend fpga because it is sending or recieve data!\n");\r
                return -1;\r
        }\r
+\r
        printk("%s\n",__FUNCTION__);\r
+\r
        return 0;\r
 }\r
 \r
 static int spi_fpga_resume(struct spi_device *spi)\r
 {\r
-       //struct spi_fpga_port *port = dev_get_drvdata(&spi->dev);\r
-       spi_set_sysclk(GPIO_HIGH);\r
+\r
+       struct spi_fpga_port *port = dev_get_drvdata(&spi->dev);\r
+       spi_fpga_set_sysclk(GPIO_HIGH);\r
+       udelay(1);\r
+       spi_fpga_set_status(port, ICE_STATUS_WAKE);\r
+\r
        printk("%s\n",__FUNCTION__);\r
+\r
        return 0;\r
 }\r
 \r
index 34067f97544e3f31821c395a8be5230a2426d16a..a1af5b11c5718f00704ec9179c8e69823a57bbb5 100755 (executable)
@@ -364,7 +364,7 @@ int spi_gpio_disable_int(eSpiGpioPinNum_t PinNum)
 }\r
 \r
 \r
-int spi_gpio_set_int_trigger(eSpiGpioPinNum_t PinNum,eSpiGpioIntType_t IntType)\r
+int spi_gpio_set_int_trigger(eSpiGpioPinNum_t PinNum,eSpiGpioIntTri_t IntTri)\r
 {\r
        int reg = get_gpio_addr(PinNum);\r
        //struct spi_fpga_port *port = pFpgaPort;\r
@@ -383,6 +383,40 @@ int spi_gpio_set_int_trigger(eSpiGpioPinNum_t PinNum,eSpiGpioIntType_t IntType)
                        return -1;\r
                }\r
        \r
+               DBG("%s,PinNum=%d,IntTri=%d\n",__FUNCTION__,PinNum,IntTri);     \r
+               \r
+               spi_gpio_write_reg(reg, PinNum, IntTri);\r
+               \r
+       }\r
+       else\r
+       {\r
+               printk("%s:error\n",__FUNCTION__);\r
+               return -1;\r
+       }\r
+\r
+       return 0;\r
+}\r
+\r
+\r
+int spi_gpio_set_int_type(eSpiGpioPinNum_t PinNum,eSpiGpioIntType_t IntType)\r
+{\r
+       int reg = get_gpio_addr(PinNum);\r
+       //struct spi_fpga_port *port = pFpgaPort;\r
+       int state;\r
+       spin_lock(&gpio_state_lock);\r
+       state = gGpio0State;\r
+       spin_unlock(&gpio_state_lock);\r
+       \r
+       if(ICE_SEL_GPIO0 == reg)\r
+       {\r
+               reg |= ICE_SEL_GPIO0_INT_TYPE;\r
+\r
+               if((state & (1 << PinNum )) == 0)\r
+               {\r
+                       printk("%s:Fail to enable int because it is gpio pin!\n",__FUNCTION__);\r
+                       return -1;\r
+               }\r
+       \r
                DBG("%s,PinNum=%d,IntType=%d\n",__FUNCTION__,PinNum,IntType);   \r
                \r
                spi_gpio_write_reg(reg, PinNum, IntType);\r
@@ -408,7 +442,7 @@ int spi_gpio_read_iir(void)
        return ret;\r
 }\r
 \r
-int spi_request_gpio_irq(eSpiGpioPinNum_t PinNum, pSpiFunc Routine, eSpiGpioIntType_t IntType,void *dev_id)\r
+int spi_request_gpio_irq(eSpiGpioPinNum_t PinNum, pSpiFunc Routine, eSpiGpioIntTri_t IntType,void *dev_id)\r
 {                      \r
 #if 0\r
        if(PinNum >= SPI_GPIO_IRQ_NUM)\r
@@ -537,6 +571,9 @@ void spi_gpio_work_handler(struct work_struct *work)
        }\r
 \r
 #elif (FPGA_TYPE == ICE_CC196)\r
+       gpio_direction_output(RK2818_PIN_PE0,0);\r
+       udelay(2);\r
+       gpio_direction_output(RK2818_PIN_PE0,1);\r
        for(i=4;i<81;i++)\r
        {\r
                gpio_direction_output(SPI_FPGA_EXPANDER_BASE+i,TestGpioPinLevel);\r
@@ -563,7 +600,7 @@ void spi_gpio_work_handler(struct work_struct *work)
 static void spi_testgpio_timer(unsigned long data)\r
 {\r
        struct spi_fpga_port *port = (struct spi_fpga_port *)data;\r
-       port->gpio.gpio_timer.expires  = jiffies + msecs_to_jiffies(1000);\r
+       port->gpio.gpio_timer.expires  = jiffies + msecs_to_jiffies(3000);\r
        add_timer(&port->gpio.gpio_timer);\r
        queue_work(port->gpio.spi_gpio_workqueue, &port->gpio.spi_gpio_work);\r
 }\r
@@ -870,7 +907,7 @@ static void _spi_gpio_irq_disable(unsigned irq)
 static int _spi_gpio_irq_set_type(unsigned int irq, unsigned int type)\r
 {\r
        int gpio = irq_to_gpio(irq) - SPI_FPGA_EXPANDER_BASE;\r
-       int int_type = 0;\r
+       int int_tri = 0, int_type = 0;\r
        DBG("%s:line=%d,irq=%d,type=%d,gpio=%d\n",__FUNCTION__,__LINE__,irq,type,gpio);\r
        if(gpio < 16)\r
        spi_gpio_int_sel(gpio,SPI_GPIO0_IS_INT);\r
@@ -882,16 +919,23 @@ static int _spi_gpio_irq_set_type(unsigned int irq, unsigned int type)
        switch(type)\r
        {\r
                case IRQF_TRIGGER_FALLING:\r
-                       int_type = SPI_GPIO_EDGE_FALLING;\r
+                       int_type = SPI_GPIO_EDGE;\r
+                       int_tri = SPI_GPIO_EDGE_FALLING;\r
                        break;\r
                case IRQF_TRIGGER_RISING:\r
-                       int_type = SPI_GPIO_EDGE_RISING;\r
+                       int_type = SPI_GPIO_EDGE;\r
+                       int_tri = SPI_GPIO_EDGE_RISING;\r
+                       break;\r
+               case (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING):\r
+                       int_type = SPI_GPIO_LEVEL;\r
+                       int_tri = SPI_GPIO_EDGE_FALLING;\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
+       spi_gpio_set_int_type(gpio, int_type);\r
+       spi_gpio_set_int_trigger(gpio, int_tri);\r
        return 0;\r
 }\r
 \r
@@ -1105,7 +1149,7 @@ void spi_gpio_test_gpio_irq_init(void)
                        break;\r
 \r
                        case 3:\r
-                       ret = request_irq(irq ,spi_gpio_int_test_3,IRQF_TRIGGER_FALLING,NULL,port);\r
+                       ret = request_irq(irq ,spi_gpio_int_test_3,(IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING),NULL,port);\r
                        if(ret)\r
                        {\r
                                printk("%s:unable to request GPIO[%d] irq\n",__FUNCTION__,gpio);\r