support rk3066b usb
authorlyz <lyz@rock-chips.com>
Tue, 4 Sep 2012 06:46:08 +0000 (14:46 +0800)
committerlyz <lyz@rock-chips.com>
Tue, 4 Sep 2012 06:46:08 +0000 (14:46 +0800)
drivers/usb/dwc_otg/dwc_otg_pcd.c
drivers/usb/dwc_otg/usbdev_rk30.c

index cb9a149d95ce5160490452b7bb907d27dc5f97c6..3348828180011e33f73a95dea39559ba6a5b209c 100755 (executable)
@@ -1777,9 +1777,12 @@ static void dwc_otg_pcd_check_vbus_timer( unsigned long data )
            _pcd->vbus_status = 1;
             if(_pcd->conn_en)
                 goto connect;
-            else
+            else{
                 // not connect, suspend phy
                 pldata->phy_suspend(pldata, USB_PHY_SUSPEND);
+                udelay(3);
+                pldata->clock_enable( pldata, 0);
+            }
         } 
         else if((_pcd->conn_en)&&(_pcd->conn_status>=0)&&(_pcd->conn_status <3)){
             DWC_PRINT("********soft reconnect******************************************\n");
@@ -1794,6 +1797,8 @@ static void dwc_otg_pcd_check_vbus_timer( unsigned long data )
                 
             // not connect, suspend phy
             pldata->phy_suspend(pldata, USB_PHY_SUSPEND);
+            udelay(3);
+            pldata->clock_enable( pldata, 0);
         }
        }else {
         _pcd->vbus_status = 0;
@@ -1802,9 +1807,12 @@ static void dwc_otg_pcd_check_vbus_timer( unsigned long data )
              dwc_otg_msc_unlock(_pcd);
         }
         /* every 500 ms open usb phy power and start 1 jiffies timer to get vbus */
-        else if( pldata->phy_status == 0 ) 
+        else if( pldata->phy_status == 0 ){ 
             /* no vbus detect here , close usb phy  */
             pldata->phy_suspend(pldata, USB_PHY_SUSPEND);
+            udelay(3);
+            pldata->clock_enable( pldata, 0);          
+        }
     }
     add_timer(&_pcd->check_vbus_timer); 
        local_irq_restore(flags);
@@ -1813,6 +1821,7 @@ static void dwc_otg_pcd_check_vbus_timer( unsigned long data )
 connect:
     if(_pcd->conn_status==0)
         dwc_otg_msc_lock(_pcd);
+    pldata->clock_enable( pldata, 1);  
     pldata->phy_suspend(pldata, USB_PHY_ENABLED);
     schedule_delayed_work( &_pcd->reconnect , 8 ); /* delay 1 jiffies */
     _pcd->check_vbus_timer.expires = jiffies + (HZ<<1); /* 1 s */
index 0d6f0e940984cffa3b5afda5a31b5b46fef4d48e..acf5e4d798f4a1540d6481c63c34f4c0d8b0daf9 100755 (executable)
 #include <mach/cru.h>\r
 \r
 #include "usbdev_rk.h"\r
-#include "dwc_otg_regs.h"\r
+#include "dwc_otg_regs.h" \r
+\r
 #ifdef CONFIG_ARCH_RK30\r
 \r
 #define GRF_REG_BASE   RK30_GRF_BASE   \r
 #define USBOTG_SIZE    RK30_USBOTG20_SIZE\r
 #ifdef CONFIG_ARCH_RK3066B\r
 #define USBGRF_SOC_STATUS0     (GRF_REG_BASE+0xac)\r
-#define USBGRF_UOC0_CON2       (GRF_REG_BASE+0x118) // USBGRF_UOC0_CON3\r
-#define USBGRF_UOC1_CON2       (GRF_REG_BASE+0x128) // USBGRF_UOC1_CON3\r
+#define USBGRF_UOC0_CON2       (GRF_REG_BASE+0x114)\r
+#define USBGRF_UOC0_CON3       (GRF_REG_BASE+0x118)\r
+#define USBGRF_UOC1_CON2       (GRF_REG_BASE+0x124)\r
+#define USBGRF_UOC1_CON3       (GRF_REG_BASE+0x128)\r
 #else\r
 #define USBGRF_SOC_STATUS0     (GRF_REG_BASE+0x15c)\r
 #define USBGRF_UOC0_CON2       (GRF_REG_BASE+0x184)\r
@@ -93,32 +96,56 @@ static struct resource usb20_otg_resource[] = {
 void usb20otg_hw_init(void)\r
 {\r
 #ifndef CONFIG_USB20_HOST\r
-    // close USB 2.0 HOST phy and clock\r
-    unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC1_CON2);\r
-    *otg_phy_con1 = 0x554|(0xfff<<16);   // enter suspend.\r
+        // close USB 2.0 HOST phy and clock\r
+#ifdef CONFIG_ARCH_RK3066B\r
+        unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC1_CON2);\r
+        unsigned int * otg_phy_con2 = (unsigned int*)(USBGRF_UOC1_CON3);\r
+        *otg_phy_con1 =  (0x01<<2)|((0x01<<2)<<16);     //enable soft control\r
+        *otg_phy_con2 =  0x2A|(0x3F<<16);               // enter suspend   \r
+#else\r
+        unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC1_CON2);\r
+        *otg_phy_con1 = 0x554|(0xfff<<16);   // enter suspend.\r
 #endif\r
-    // usb phy config init\r
-\r
-    // other haredware init\r
+#endif\r
+        // usb phy config init\r
+    \r
+        // other haredware init\r
 #ifdef CONFIG_ARCH_RK3066B\r
-//  conflict with pwm2\r
-//    rk30_mux_api_set(GPIO3D5_PWM2_JTAGTCK_OTGDRVVBUS_NAME, GPIO3D_OTGDRVVBUS);\r
+    //GPIO init\r
+        rk30_mux_api_set(GPIO0D6_SPI1CLK_NAME, GPIO0D_GPIO0D6);\r
 #else\r
-    rk30_mux_api_set(GPIO0A5_OTGDRVVBUS_NAME, GPIO0A_OTG_DRV_VBUS);\r
+        rk30_mux_api_set(GPIO0A5_OTGDRVVBUS_NAME, GPIO0A_OTG_DRV_VBUS);\r
 #endif\r
 }\r
+\r
 void usb20otg_phy_suspend(void* pdata, int suspend)\r
 {\r
-    struct dwc_otg_platform_data *usbpdata=pdata;\r
-    unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC0_CON2);\r
-    if(suspend){\r
-        *otg_phy_con1 = 0x554|(0xfff<<16);   // enter suspend.\r
-        usbpdata->phy_status = 1;\r
-    }\r
-    else{\r
-        *otg_phy_con1 = ((0x01<<2)<<16);    // exit suspend.\r
-        usbpdata->phy_status = 0;\r
-    }\r
+#ifdef CONFIG_ARCH_RK3066B\r
+        struct dwc_otg_platform_data *usbpdata=pdata;\r
+        unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC0_CON2);\r
+        unsigned int * otg_phy_con2 = (unsigned int*)(USBGRF_UOC0_CON3);\r
+        if(suspend){\r
+            *otg_phy_con1 =  (0x01<<2)|((0x01<<2)<<16); ;   //enable soft control\r
+            *otg_phy_con2 =  0x2A|(0x3F<<16);;              // enter suspend\r
+            usbpdata->phy_status = 1;\r
+        }\r
+        else{\r
+            *otg_phy_con1 = ((0x01<<2)<<16);    // exit suspend.\r
+            usbpdata->phy_status = 0;\r
+        }\r
+#else\r
+        struct dwc_otg_platform_data *usbpdata=pdata;\r
+        unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC0_CON2);\r
+        if(suspend){\r
+            *otg_phy_con1 = 0x554|(0xfff<<16);   // enter suspend.\r
+            usbpdata->phy_status = 1;\r
+        }\r
+        else{\r
+            *otg_phy_con1 = ((0x01<<2)<<16);    // exit suspend.\r
+            usbpdata->phy_status = 0;\r
+        }\r
+#endif\r
+\r
 }\r
 void usb20otg_soft_reset(void)\r
 {\r
@@ -159,44 +186,66 @@ void usb20otg_clock_enable(void* pdata, int enable)
 }\r
 int usb20otg_get_status(int id)\r
 {\r
-    int ret = -1;\r
-    unsigned int usbgrf_status = *(unsigned int*)(USBGRF_SOC_STATUS0);\r
-    switch(id)\r
-    {\r
+        int ret = -1;\r
+        unsigned int usbgrf_status = *(unsigned int*)(USBGRF_SOC_STATUS0);\r
+        switch(id)\r
+        {\r
 #ifdef CONFIG_ARCH_RK3066B\r
-        case USB_STATUS_BVABLID:\r
-            // bvalid in grf\r
-            ret = (usbgrf_status &(1<<10));\r
-            break;\r
-        case USB_STATUS_DPDM:\r
-            // dpdm in grf\r
-            ret = (usbgrf_status &(3<<11));\r
-            break;\r
-        case USB_STATUS_ID:\r
-            // id in grf\r
-            ret = (usbgrf_status &(1<<13));\r
-            break;\r
+            case USB_STATUS_BVABLID:\r
+                // bvalid in grf\r
+                ret = (usbgrf_status &(1<<10));\r
+                break;\r
+            case USB_STATUS_DPDM:\r
+                // dpdm in grf\r
+                ret = (usbgrf_status &(3<<11));\r
+                break;\r
+            case USB_STATUS_ID:\r
+                // id in grf\r
+                ret = (usbgrf_status &(1<<13));\r
+                break;\r
 #else\r
-        case USB_STATUS_BVABLID:\r
-            // bvalid in grf\r
-            ret = (usbgrf_status &0x20000);\r
-            break;\r
-        case USB_STATUS_DPDM:\r
-            // dpdm in grf\r
-            ret = (usbgrf_status &(3<<18));\r
-            break;\r
-        case USB_STATUS_ID:\r
-            // id in grf\r
-            ret = (usbgrf_status &(1<<20));\r
-            break;\r
+            case USB_STATUS_BVABLID:\r
+                // bvalid in grf\r
+                ret = (usbgrf_status &0x20000);\r
+                break;\r
+            case USB_STATUS_DPDM:\r
+                // dpdm in grf\r
+                ret = (usbgrf_status &(3<<18));\r
+                break;\r
+            case USB_STATUS_ID:\r
+                // id in grf\r
+                ret = (usbgrf_status &(1<<20));\r
+                break;\r
 #endif\r
-        default:\r
-            break;\r
-    }\r
-    return ret;\r
+            default:\r
+                break;\r
+        }\r
+        return ret;\r
 }\r
\r
 void usb20otg_power_enable(int enable)\r
 {\r
+    int ret;\r
+    if(0 == enable)//disable\r
+    {\r
+    /*    ret = gpio_request(RK30_PIN0_PD6, NULL);\r
+        if (ret != 0) {\r
+            gpio_free(RK30_PIN0_PD6);\r
+        }\r
+        gpio_direction_output(RK30_PIN0_PD6, 1);\r
+        gpio_set_value(RK30_PIN0_PD6, 0);*/ \r
+    }\r
+\r
+    if(1 == enable)//enable\r
+    {\r
+        ret = gpio_request(RK30_PIN0_PD6, NULL);\r
+        if (ret != 0) {\r
+            gpio_free(RK30_PIN0_PD6);\r
+        }\r
+        gpio_direction_output(RK30_PIN0_PD6, 1);\r
+        gpio_set_value(RK30_PIN0_PD6, 1); \r
+    }  \r
+\r
 }\r
 struct dwc_otg_platform_data usb20otg_pdata = {\r
     .phyclk = NULL,\r
@@ -209,6 +258,8 @@ struct dwc_otg_platform_data usb20otg_pdata = {
     .clock_init=usb20otg_clock_init,\r
     .clock_enable=usb20otg_clock_enable,\r
     .get_status=usb20otg_get_status,\r
+    .power_enable=usb20otg_power_enable,\r
+    \r
 };\r
 \r
 struct platform_device device_usb20_otg = {\r
@@ -241,23 +292,42 @@ void usb20host_hw_init(void)
 \r
     // other haredware init\r
 #ifdef CONFIG_ARCH_RK3066B\r
-    rk30_mux_api_set(GPIO3D6_PWM3_JTAGTMS_HOSTDRVVBUS_NAME, GPIO3D_HOSTDRVVBUS);\r
+    rk30_mux_api_set(GPIO0D7_SPI1CSN0_NAME, GPIO0D_GPIO0D7); \r
 #else\r
     rk30_mux_api_set(GPIO0A6_HOSTDRVVBUS_NAME, GPIO0A_HOST_DRV_VBUS);\r
 #endif\r
 }\r
 void usb20host_phy_suspend(void* pdata, int suspend)\r
-{\r
-    struct dwc_otg_platform_data *usbpdata=pdata;\r
-    unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC1_CON2);\r
-    if(suspend){\r
-        *otg_phy_con1 = 0x554|(0xfff<<16);   // enter suspend.\r
-        usbpdata->phy_status = 1;\r
-    }\r
-    else{\r
-        *otg_phy_con1 = ((0x01<<2)<<16);    // exit suspend.\r
-        usbpdata->phy_status = 0;\r
-    }\r
+{ \r
+#ifdef CONFIG_ARCH_RK3066B\r
+        struct dwc_otg_platform_data *usbpdata=pdata;\r
+        unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC1_CON2);\r
+        unsigned int * otg_phy_con2 = (unsigned int*)(USBGRF_UOC1_CON3);\r
+        if(suspend)\r
+        {\r
+            *otg_phy_con1 =  (0x01<<2)|((0x01<<2)<<16); ;   //enable soft control\r
+            *otg_phy_con2 =  0x2A|(0x3F<<16);;                     // enter suspend\r
+            usbpdata->phy_status = 1;\r
+        }\r
+        else\r
+        {\r
+            *otg_phy_con1 = ((0x01<<2)<<16);    // exit suspend.\r
+            usbpdata->phy_status = 0;\r
+        }   \r
+#else\r
+        struct dwc_otg_platform_data *usbpdata=pdata;\r
+        unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC1_CON2);\r
+        if(suspend)\r
+        {\r
+            *otg_phy_con1 = 0x554|(0xfff<<16);   // enter suspend.\r
+            usbpdata->phy_status = 1;\r
+        }\r
+        else\r
+        {\r
+            *otg_phy_con1 = ((0x01<<2)<<16);    // exit suspend.\r
+            usbpdata->phy_status = 0;\r
+        }\r
+#endif \r
 }\r
 void usb20host_soft_reset(void)\r
 {\r
@@ -336,6 +406,29 @@ int usb20host_get_status(int id)
 }\r
 void usb20host_power_enable(int enable)\r
 {\r
+\r
+    int ret;\r
+    if(0 == enable)//disable\r
+    {\r
+        //ret = gpio_request(RK30_PIN0_PD7, NULL);\r
+        //if (ret != 0) {\r
+        //    gpio_free(RK30_PIN0_PD7);\r
+        //}\r
+        //gpio_direction_output(RK30_PIN0_PD7, 1);\r
+        //gpio_set_value(RK30_PIN0_PD7, 0);\r
+        //printk("!!!!!!!!!!!!!!!!!!!disable host power!!!!!!!!!!!!!!!!!!\n");\r
+    }\r
+\r
+    if(1 == enable)//enable\r
+    {\r
+        ret = gpio_request(RK30_PIN0_PD7, NULL);\r
+        if (ret != 0) {\r
+            gpio_free(RK30_PIN0_PD7);\r
+        }\r
+        gpio_direction_output(RK30_PIN0_PD7, 1);\r
+        gpio_set_value(RK30_PIN0_PD7, 1);\r
+        //printk("!!!!!!!!!!!!!!!!!!!!!enable host power!!!!!!!!!!!!!!!!!!\n");\r
+    }  \r
 }\r
 struct dwc_otg_platform_data usb20host_pdata = {\r
     .phyclk = NULL,\r
@@ -348,6 +441,7 @@ struct dwc_otg_platform_data usb20host_pdata = {
     .clock_init=usb20host_clock_init,\r
     .clock_enable=usb20host_clock_enable,\r
     .get_status=usb20host_get_status,\r
+    .power_enable=usb20host_power_enable,\r
 };\r
 \r
 struct platform_device device_usb20_host = {\r