rk3026: usb: wake up by otg id & bvalid
authorlyz <lyz@rock-chips.com>
Fri, 2 Aug 2013 10:50:31 +0000 (18:50 +0800)
committerlyz <lyz@rock-chips.com>
Fri, 2 Aug 2013 10:57:41 +0000 (18:57 +0800)
arch/arm/plat-rk/usb_detect.c
drivers/usb/dwc_otg/dwc_otg_cil.c
drivers/usb/dwc_otg/usbdev_rk3026.c

index 4754d639d66ecda23a8e2ac717374e7229cf4364..1359512f8013bc415e3468c60eec77a622cf398f 100755 (executable)
@@ -145,57 +145,8 @@ static int __init bvalid_init(void)
 
        return 0;
 }
+#if defined(CONFIG_ARCH_RK2928) || defined(CONFIG_ARCH_RK3188)
 late_initcall(bvalid_init);
 #endif
-
-#if 0
-#include <linux/io.h>
-#include <mach/iomux.h>
-
-static irqreturn_t otg_id_irq_handler(int irq, void *dev_id)
-{
-    unsigned int uoc_con;
-       /* clear irq */
-    uoc_con = readl_relaxed(RK2928_GRF_BASE + GRF_UOC_CON);
-
-
-    
-    if(uoc_con & (1<<1)) //id rise 
-    {
-        writel_relaxed((0x1 << 16) | 0x1, RK2928_GRF_BASE + GRF_UOC_CON);;//clear id rise irq pandding
-    }
-    if(uoc_con & (1<<3))//id fall
-    { 
-#ifdef CONFIG_RK_USB_UART
-        //if(!(readl_relaxed(RK2928_GRF_BASE + 0x014c) & (1<<10))){//id low          
-        writel_relaxed(0x04000000, RK2928_GRF_BASE + GRF_UOC1_CON0);   //enter usb phy    
-    }
-#endif
-    writel_relaxed((0x3 << 16) | 0x3, RK2928_GRF_BASE + GRF_UOC_CON);//clear id fall irq pandding
-   
-       rk28_send_wakeup_key();
-       return IRQ_HANDLED;
-}
-
-static int __init otg_id_irq_init(void)
-{
-       int ret;
-       int irq = IRQ_OTG0_ID;
-
-       ret = request_irq(irq, otg_id_irq_handler, 0, "otg_id_change", NULL);
-       if (ret < 0) {
-               pr_err("%s: request_irq(%d) failed\n", __func__, irq);
-               return ret;
-       }
-
-       /* clear & enable otg change irq */
-       /* for rk3026 enable and clear id_fall_irq & id_rise_irq*/
-       writel_relaxed((0xf << 16) | 0xf, RK2928_GRF_BASE + GRF_UOC_CON);
-
-       enable_irq_wake(irq);
-
-       return 0;
-}
-late_initcall(otg_id_irq_init);
 #endif
 
index 9f02d63ee66f77056b07d444bc6684e4ef131638..f14534394a4c3a8c7c71f89402490cba3bd6e485 100755 (executable)
@@ -722,8 +722,12 @@ void dwc_otg_core_dev_init(dwc_otg_core_if_t *_core_if)
     dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[0], 0x01000220 );  //ep1 tx fifo
     dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[1], 0x00100320 );  //ep3 tx fifo
     dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[2], 0x00800330 );  //ep5 tx fifo
-#endif
-#if defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK3188)
+#else
+
+#if !(defined(CONFIG_ARCH_RK30)  || defined(CONFIG_ARCH_RK3188) || \
+      defined(CONFIG_ARCH_RK2928)|| defined(CONFIG_ARCH_RK3026) )
+    DWC_ERROR("Warning!!! Please Check USB Controller FIFO Configuration\n");
+#endif    
        /* Configure data FIFO sizes, RK30 otg has 0x3cc dwords total */
     dwc_write_reg32( &global_regs->grxfsiz, 0x00000120 );
     dwc_write_reg32( &global_regs->gnptxfsiz, 0x00100120 );                            //ep0 tx fifo
@@ -733,26 +737,6 @@ void dwc_otg_core_dev_init(dwc_otg_core_if_t *_core_if)
     dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[3], 0x00800330 );  //ep7 tx fifo
     dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[4], 0x001003b0 );  //ep9 tx fifo
 #endif
-#ifdef CONFIG_ARCH_RK2928  
-    /* Configure data FIFO sizes, RK30 otg has 0x3cc dwords total */
-    dwc_write_reg32( &global_regs->grxfsiz, 0x00000120 );
-    dwc_write_reg32( &global_regs->gnptxfsiz, 0x00100120 );             //ep0 tx fifo 
-    dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[0], 0x01000130 );   //ep1 tx fifo 256*4Byte
-    dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[1], 0x00800230 );   //ep3 tx fifo 128*4Byte
-    dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[2], 0x008002b0 );   //ep5 tx fifo 128*4Byte
-    dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[3], 0x00800330 );   //ep7 tx fifo 128*4Byte
-    dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[4], 0x001003b0 );   //ep9 tx fifo 16*4Byte
-#endif
-#ifdef CONFIG_ARCH_RK3026  
-        /* Configure data FIFO sizes, RK30 otg has 0x3cc dwords total */
-    dwc_write_reg32( &global_regs->grxfsiz, 0x00000120 );
-    dwc_write_reg32( &global_regs->gnptxfsiz, 0x00100120 );             //ep0 tx fifo 
-    dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[0], 0x01000130 );   //ep1 tx fifo 256*4Byte
-    dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[1], 0x00800230 );   //ep3 tx fifo 128*4Byte
-    dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[2], 0x008002b0 );   //ep5 tx fifo 128*4Byte
-    dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[3], 0x00800330 );   //ep7 tx fifo 128*4Byte
-    dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[4], 0x001003b0 );   //ep9 tx fifo 16*4Byte
-#endif
 
        if(_core_if->en_multiple_tx_fifo && _core_if->dma_enable)
        {
index dd510dfba970b72d9286d4030b219b30b06fe577..c31496cf03f976fde876c858ee79f89a86510c1d 100755 (executable)
@@ -3,11 +3,19 @@
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/wakelock.h>
+#include <linux/workqueue.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
 
 #include <mach/irqs.h>
 #include <mach/gpio.h>
 #include <mach/iomux.h>
 #include <mach/cru.h>
+#include <mach/board.h>
+
+
 #ifdef CONFIG_RK_CONFIG
 #include <mach/config.h>
 #endif
@@ -124,7 +132,7 @@ void usb20otg_phy_suspend(void* pdata, int suspend)
 }
 void usb20otg_soft_reset(void)
 {
-#if 0 //@lyz todo for 3028 phy
+#if 1 //@lyz todo for 3028 phy
     printk("~~~~~~~~~~usb20otg_soft_reset\n");
     //phy reset
     *(unsigned int*)(USBGRF_UOC0_CON0) = 0x00030001;
@@ -414,5 +422,108 @@ static int __init usbdev_init_devices(void)
         return ret;
 }
 arch_initcall(usbdev_init_devices);
+
+
+/*********************************************************************
+                        rk3026 usb detect 
+*********************************************************************/
+
+#define WAKE_LOCK_TIMEOUT (HZ * 10)
+
+static struct wake_lock usb_wakelock;
+static struct delayed_work usb_det_wakeup_work;
+
+inline void do_wakeup(void)
+{
+    wake_lock_timeout(&usb_wakelock, WAKE_LOCK_TIMEOUT);
+       rk28_send_wakeup_key();
+}
+
+
+/*********** handler for bvalid irq ***********/
+
+static irqreturn_t bvalid_irq_handler(int irq, void *dev_id)
+{
+    /* clear irq */
+    writel_relaxed((1 << 31) | (1 << 15), RK2928_GRF_BASE + GRF_UOC0_CON0);
+    
+#ifdef CONFIG_RK_USB_UART
+    /* usb otg dp/dm switch to usb phy */
+    writel_relaxed((3 << (12 + 16)),RK2928_GRF_BASE + GRF_UOC1_CON4);
+#endif
+    
+    schedule_delayed_work(&usb_det_wakeup_work, HZ/10);
+
+    return IRQ_HANDLED;
+}
+
+/***** handler for otg id rise and fall edge *****/
+
+static irqreturn_t id_irq_handler(int irq, void *dev_id)
+{
+    unsigned int uoc_con;
+
+     /* clear irq */
+    uoc_con = readl_relaxed(RK2928_GRF_BASE + GRF_UOC_CON);
+    if(uoc_con & (1<<1))//id rise 
+    {
+        writel_relaxed((0x2 << 16) | 0x2, RK2928_GRF_BASE + GRF_UOC_CON);//clear id rise irq pandding
+    }
+    if(uoc_con & (1<<3))//id fall
+    { 
+        writel_relaxed((0x8 << 16) | 0x8, RK2928_GRF_BASE + GRF_UOC_CON);//clear id fall irq pandding
+    }
+    schedule_delayed_work(&usb_det_wakeup_work, HZ/10);
+    return IRQ_HANDLED;
+}
+
+/***** handler for otg line status change *****/
+
+static irqreturn_t line_irq_handler(int irq, void *dev_id)
+{
+
+    /* clear irq */
+    writel_relaxed((1 << 29) | (1 << 13), RK2928_GRF_BASE + GRF_UOC0_CON0); 
+
+    schedule_delayed_work(&usb_det_wakeup_work, HZ/10);
+    return IRQ_HANDLED;
+}
+
+
+static int __init otg_irq_detect_init(void)
+{
+    int ret;
+    int irq = IRQ_OTG_BVALID;
+
+    wake_lock_init(&usb_wakelock, WAKE_LOCK_SUSPEND, "usb_detect");
+    INIT_DELAYED_WORK(&usb_det_wakeup_work, do_wakeup);
+
+    ret = request_irq(irq, bvalid_irq_handler, 0, "bvalid", NULL);
+    if (ret < 0) {
+        pr_err("%s: request_irq(%d) failed\n", __func__, irq);
+        return ret;
+    }
+    
+    /* clear & enable bvalid irq */
+    writel_relaxed((3 << 30) | (3 << 14), RK2928_GRF_BASE + GRF_UOC0_CON0);
+
+
+    irq = IRQ_OTG0_ID;
+
+    ret = request_irq(irq, id_irq_handler, 0, "otg-id", NULL);
+    if (ret < 0) {
+        pr_err("%s: request_irq(%d) failed\n", __func__, irq);
+        return ret;
+    }
+
+    /* clear & enable otg change irq */
+    /* for rk3026 enable and clear id_fall_irq & id_rise_irq*/
+    writel_relaxed((0xf << 16) | 0xf, RK2928_GRF_BASE + GRF_UOC_CON);
+
+    enable_irq_wake(irq);
+    
+    return 0;
+}
+late_initcall(otg_irq_detect_init);
 #endif