USB: support usb otg and host20 functions
authorwlf <wulf@rock-chips.com>
Thu, 13 Feb 2014 07:45:30 +0000 (15:45 +0800)
committerwlf <wulf@rock-chips.com>
Thu, 13 Feb 2014 07:45:30 +0000 (15:45 +0800)
19 files changed:
arch/arm/boot/dts/rk3188.dtsi [changed mode: 0644->0755]
arch/arm/configs/rockchip_defconfig
drivers/usb/Kconfig
drivers/usb/Makefile
drivers/usb/core/hcd.c [changed mode: 0644->0755]
drivers/usb/core/hub.c [changed mode: 0644->0755]
drivers/usb/dwc_otg/Kconfig
drivers/usb/dwc_otg/Makefile
drivers/usb/dwc_otg/dwc_otg_attr.c
drivers/usb/dwc_otg/dwc_otg_cil.c
drivers/usb/dwc_otg/dwc_otg_driver.c
drivers/usb/dwc_otg/dwc_otg_hcd.c
drivers/usb/dwc_otg/dwc_otg_hcd.h
drivers/usb/dwc_otg/dwc_otg_hcd_queue.c
drivers/usb/dwc_otg/dwc_otg_pcd.c
drivers/usb/dwc_otg/usbdev_rk.h
drivers/usb/dwc_otg/usbdev_rk30.c [changed mode: 0755->0644]
drivers/usb/gadget/android.c
drivers/usb/gadget/composite.c

old mode 100644 (file)
new mode 100755 (executable)
index eaf10c7..4f4154a
                        reg = <1>;
                };
        };
+
+       dwc_control_usb: dwc-control-usb@0x200080ac {
+               compatible = "rockchip,dwc-control-usb";
+               reg = <0x200080ac 0x4>,
+                     <0x2000810c 0x10>,
+                     <0x2000811c 0x10>;
+               reg-names = "GRF_SOC_STATUS0",
+                           "GRF_UOC0_BASE",
+                           "GRF_UOC1_BASE";
+               gpios = <&gpio0 GPIO_C0 GPIO_ACTIVE_LOW>, <&gpio3 GPIO_D5 GPIO_ACTIVE_LOW>;
+       };
+
+       usb@10180000 {
+               compatible = "rockchip,usb20_otg";
+               reg = <0x10180000 0x40000>;
+               interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+               /*clocks = <&clk_gates1 5>, <&clk_gates5 13>;*/
+               /*clock-names = "otgphy0", "hclk_otg0"*/
+       };
+
+       usb@101c0000 {
+               compatible = "rockchip,usb20_host";
+               reg = <0x101c0000 0x40000>;
+               interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+               /*clocks = <&clk_gates1 6>, <&clk_gates7 3>;*/
+               /*clock-names = "otgphy1", "hclk_otg1"*/
+       };
+
 };
index c90fabf3b60ac85770b2eb45a64dbd8df07c7762..b8645530990db1deab160d963b2e74490bffd296 100755 (executable)
@@ -422,6 +422,9 @@ CONFIG_USB_STORAGE_ONETOUCH=y
 CONFIG_USB_STORAGE_KARMA=y
 CONFIG_USB_STORAGE_CYPRESS_ATACB=y
 CONFIG_USB_STORAGE_ENE_UB6250=y
+CONFIG_USB20_HOST=y
+CONFIG_USB20_OTG=y
+CONFIG_DWC_OTG_BOTH_HOST_SLAVE=y
 CONFIG_USB_TRANCEVIBRATOR=y
 CONFIG_USB_OTG_WAKELOCK=y
 CONFIG_USB_GADGET=y
index 92e1dc94ecc87d2bd11cc8033a7bf4acc6a088a5..749bd14a9837164d4853cf7c1a20eb5382b8e02c 100644 (file)
@@ -148,6 +148,8 @@ source "drivers/usb/dwc3/Kconfig"
 
 source "drivers/usb/chipidea/Kconfig"
 
+source "drivers/usb/dwc_otg/Kconfig"
+
 comment "USB port drivers"
 
 if USB
index c41feba8d5c0737c926aa6a576f50b0c290a626a..cfc8ceafa240ac8602984df5b7412487c6169bf4 100644 (file)
@@ -50,6 +50,7 @@ obj-$(CONFIG_EARLY_PRINTK_DBGP)       += early/
 obj-$(CONFIG_USB_ATM)          += atm/
 obj-$(CONFIG_USB_SPEEDTOUCH)   += atm/
 
+obj-$(CONFIG_DWC_OTG)          += dwc_otg/
 obj-$(CONFIG_USB_MUSB_HDRC)    += musb/
 obj-$(CONFIG_USB_CHIPIDEA)     += chipidea/
 obj-$(CONFIG_USB_RENESAS_USBHS)        += renesas_usbhs/
old mode 100644 (file)
new mode 100755 (executable)
index d3aa353..176f8af
@@ -1657,8 +1657,12 @@ void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, int status)
 
        /* pass ownership to the completion handler */
        urb->status = status;
-       urb->complete (urb);
+       if(!atomic_read(&urb->use_count)){
+               printk("%s %d\n", __func__, atomic_read(&urb->use_count));
+               return;
+       }
        atomic_dec (&urb->use_count);
+       urb->complete (urb);
        if (unlikely(atomic_read(&urb->reject)))
                wake_up (&usb_kill_urb_queue);
        usb_put_urb (urb);
old mode 100644 (file)
new mode 100755 (executable)
index 4d25bff..7783a70
@@ -1639,6 +1639,7 @@ static void hub_disconnect(struct usb_interface *intf)
        kref_put(&hub->kref, hub_release);
 }
 
+struct usb_hub *g_dwc_otg_root_hub20 = NULL;
 static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
 {
        struct usb_host_interface *desc;
@@ -1728,6 +1729,9 @@ descriptor_error:
                return -ENOMEM;
        }
 
+       if(!g_dwc_otg_root_hub20){
+               g_dwc_otg_root_hub20 = hub;
+       }
        kref_init(&hub->kref);
        INIT_LIST_HEAD(&hub->event_list);
        hub->intfdev = &intf->dev;
@@ -4053,11 +4057,16 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
                udev->ttport = hdev->ttport;
        } else if (udev->speed != USB_SPEED_HIGH
                        && hdev->speed == USB_SPEED_HIGH) {
+               /* yk@rk 20110617
+                * parent hub has no TT would not be error in rk29
+                */
+               #if 0
                if (!hub->tt.hub) {
                        dev_err(&udev->dev, "parent hub has no TT\n");
                        retval = -EINVAL;
                        goto fail;
                }
+               #endif
                udev->tt = &hub->tt;
                udev->ttport = port1;
        }
@@ -4874,6 +4883,16 @@ static void hub_events(void)
         } /* end while (1) */
 }
 
+/* yk@rk 20100730
+ * * disconnect all devices on dwc otg controller root hub
+ */
+void dwc_otg_hub_disconnect_device(struct usb_hub *hub)
+{
+       hub_port_connect_change(hub, 1, 0, 0x2);
+}
+
+EXPORT_SYMBOL_GPL(dwc_otg_hub_disconnect_device);
+
 static int hub_thread(void *__unused)
 {
        /* khubd needs to be freezable to avoid intefering with USB-PERSIST
index 87d2a37e401804eb0bfca627890d735a6299d142..967f87f1c4d5ea90ee334e2f8a907711a52feac7 100755 (executable)
@@ -1,15 +1,3 @@
-config USB11_HOST 
-       tristate "RockChip USB 1.1 host controller"
-       depends on USB
-       ---help---
-         This driver supports Rockchip USB 1.1 HOST
-         controller.
-
-config USB11_HOST_EN
-       bool "---usb1.1 host controller enable"
-       depends on USB11_HOST
-       default y
-
 config USB20_HOST
        tristate "Rockchip USB 2.0 host controller"
        depends on USB
index 2a27dfe6ab8cdb821a7f9be714e578fa93e128bb..c23bce656c5476a7d1ad1a0d61cf591c078dc110 100755 (executable)
@@ -29,6 +29,6 @@ dwc_otg-objs    := dwc_otg_driver.o dwc_otg_attr.o
 dwc_otg-objs    += dwc_otg_cil.o dwc_otg_cil_intr.o
 dwc_otg-objs    += dwc_otg_pcd.o dwc_otg_pcd_intr.o
 dwc_otg-objs    += dwc_otg_hcd.o dwc_otg_hcd_intr.o dwc_otg_hcd_queue.o
-dwc_otg-objs   += usbdev_rk30.o usbdev_rk2928.o usbdev_rk3026.o
+dwc_otg-objs   += usbdev_rk30.o
 
 obj-$(CONFIG_DWC_OTG) := dwc_otg.o
index 9b7a5d3355aad440e88a5c9801baf4ff4c948c8f..8420ba9b06855e771bcef14fa1e51ac2543d94fa 100755 (executable)
@@ -424,7 +424,7 @@ DEVICE_ATTR(regvalue,  S_IRUGO|S_IWUSR, regvalue_show, regvalue_store);
 /*
  * Attributes
  */
-DWC_OTG_DEVICE_ATTR_BITFIELD_RO(mode,&(otg_dev->core_if->core_global_regs->gotgctl),(1<<20),20,"Mode");
+DWC_OTG_DEVICE_ATTR_BITFIELD_RO(mode,&(otg_dev->core_if->core_global_regs->gintsts),(1<<0),0,"Mode");
 DWC_OTG_DEVICE_ATTR_BITFIELD_RW(hnpcapable,&(otg_dev->core_if->core_global_regs->gusbcfg),(1<<9),9,"Mode");
 DWC_OTG_DEVICE_ATTR_BITFIELD_RW(srpcapable,&(otg_dev->core_if->core_global_regs->gusbcfg),(1<<8),8,"Mode");
 
@@ -648,7 +648,7 @@ static ssize_t regdump_show( struct device *_dev,
        return sprintf( buf, "Register Dump\n" );
 }
 
-DEVICE_ATTR(regdump, S_IRUGO|S_IWUSR, regdump_show, 0);
+DEVICE_ATTR(regdump, S_IRUGO, regdump_show, 0);
 
 /**
  * Dump the current hcd state.
@@ -663,7 +663,7 @@ static ssize_t hcddump_show( struct device *_dev,
        return sprintf( buf, "HCD Dump\n" );
 }
 
-DEVICE_ATTR(hcddump, S_IRUGO|S_IWUSR, hcddump_show, 0);
+DEVICE_ATTR(hcddump, S_IRUGO, hcddump_show, 0);
 
 /**
  * Dump the average frame remaining at SOF. This can be used to
@@ -680,7 +680,7 @@ static ssize_t hcd_frrem_show( struct device *_dev,
        return sprintf( buf, "HCD Dump Frame Remaining\n" );
 }
 
-DEVICE_ATTR(hcd_frrem, S_IRUGO|S_IWUSR, hcd_frrem_show, 0);
+DEVICE_ATTR(hcd_frrem, S_IRUGO, hcd_frrem_show, 0);
 
 /**
  * Displays the time required to read the GNPTXFSIZ register many times (the
@@ -707,7 +707,7 @@ static ssize_t rd_reg_test_show( struct device *_dev,
                        RW_REG_COUNT, time * MSEC_PER_JIFFIE, time );
 }
 
-DEVICE_ATTR(rd_reg_test, S_IRUGO|S_IWUSR, rd_reg_test_show, 0);
+DEVICE_ATTR(rd_reg_test, S_IRUGO, rd_reg_test_show, 0);
 
 /**
  * Displays the time required to write the GNPTXFSIZ register many times (the
@@ -734,7 +734,7 @@ static ssize_t wr_reg_test_show( struct device *_dev,
                        RW_REG_COUNT, time * MSEC_PER_JIFFIE, time);
 }
 
-DEVICE_ATTR(wr_reg_test, S_IRUGO|S_IWUSR, wr_reg_test_show, 0);
+DEVICE_ATTR(wr_reg_test, S_IRUGO, wr_reg_test_show, 0);
 extern int dwc_debug(dwc_otg_core_if_t *core_if, int flag);
 
 static ssize_t debug_show( struct device *_dev, 
index 649b76b16a34b009e8896f7580af7174db7f5359..8bf8a734c1db24d4d88013b0ef050539e3385052 100755 (executable)
@@ -702,40 +702,41 @@ void dwc_otg_core_dev_init(dwc_otg_core_if_t *_core_if)
                _core_if->core_global_regs;
        dwc_otg_dev_if_t *dev_if = _core_if->dev_if;
        volatile dcfg_data_t dcfg = {.d32 = 0};
-    volatile dctl_data_t dctl = {.d32 = 0};
-    volatile grstctl_t grstctl = {.d32 = 0};
-    volatile depctl_data_t depctl = {.d32 = 0};
-    volatile daint_data_t daintmsk = {.d32 = 0};
-    volatile gahbcfg_data_t gahbcfg = {.d32 = 0};
+       volatile dctl_data_t dctl = {.d32 = 0};
+       volatile grstctl_t grstctl = {.d32 = 0};
+       volatile depctl_data_t depctl = {.d32 = 0};
+       volatile daint_data_t daintmsk = {.d32 = 0};
+       volatile gahbcfg_data_t gahbcfg = {.d32 = 0};
        volatile dthrctl_data_t dthrctl;
        dwc_otg_core_reset(_core_if);
        /* Restart the Phy Clock */
        dwc_write_reg32(_core_if->pcgcctl, 0);
        /* soft disconnect */
-    dctl.d32 = dwc_read_reg32( &_core_if->dev_if->dev_global_regs->dctl );
-    dctl.b.sftdiscon = 1;
-    dwc_write_reg32( &_core_if->dev_if->dev_global_regs->dctl, dctl.d32 );
+       dctl.d32 = dwc_read_reg32( &_core_if->dev_if->dev_global_regs->dctl );
+       dctl.b.sftdiscon = 1;
+       dwc_write_reg32( &_core_if->dev_if->dev_global_regs->dctl, dctl.d32 );
 #ifdef CONFIG_ARCH_RK29
        /* Configure data FIFO sizes, RK29 otg has 0x3c0 dwords total */
-    dwc_write_reg32( &global_regs->grxfsiz, 0x00000210 );
-    dwc_write_reg32( &global_regs->gnptxfsiz, 0x00100210 );                            //ep0 tx fifo
-    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
+       dwc_write_reg32( &global_regs->grxfsiz, 0x00000210 );
+       dwc_write_reg32( &global_regs->gnptxfsiz, 0x00100210 );                         //ep0 tx fifo
+       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
 #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");
+       defined(CONFIG_ARCH_RK2928)|| defined(CONFIG_ARCH_RK3026) ||\
+       defined(CONFIG_ARCH_ROCKCHIP))
+       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
-    dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[0], 0x01000130 );  //ep1 tx fifo
-    dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[1], 0x00800230 );  //ep3 tx fifo
-    dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[2], 0x008002b0 );  //ep5 tx fifo
-    dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[3], 0x00800330 );  //ep7 tx fifo
-    dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[4], 0x001003b0 );  //ep9 tx fifo
+       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
+       dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[1], 0x00800230 );       //ep3 tx fifo
+       dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[2], 0x008002b0 );       //ep5 tx fifo
+       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
 
        if(_core_if->en_multiple_tx_fifo && _core_if->dma_enable)
@@ -790,45 +791,45 @@ void dwc_otg_core_dev_init(dwc_otg_core_if_t *_core_if)
        depctl.d32 = 0;
        depctl.b.epdis = 1;
        depctl.b.snak = 1;
-    dwc_write_reg32( &dev_if->in_ep_regs[0]->diepctl, depctl.d32 );
-    dwc_write_reg32( &dev_if->in_ep_regs[0]->dieptsiz, 0 );
-    dwc_write_reg32( &dev_if->in_ep_regs[0]->diepdma, 0 );
-    dwc_write_reg32( &dev_if->in_ep_regs[0]->diepint, 0xff );
+       dwc_write_reg32( &dev_if->in_ep_regs[0]->diepctl, depctl.d32 );
+       dwc_write_reg32( &dev_if->in_ep_regs[0]->dieptsiz, 0 );
+       dwc_write_reg32( &dev_if->in_ep_regs[0]->diepdma, 0 );
+       dwc_write_reg32( &dev_if->in_ep_regs[0]->diepint, 0xff );
 
-    dwc_write_reg32( &dev_if->out_ep_regs[0]->doepctl, depctl.d32 );
-    dwc_write_reg32( &dev_if->out_ep_regs[0]->doeptsiz, 0 );
-    dwc_write_reg32( &dev_if->out_ep_regs[0]->doepdma, 0 );
-    dwc_write_reg32( &dev_if->out_ep_regs[0]->doepint, 0xff );
+       dwc_write_reg32( &dev_if->out_ep_regs[0]->doepctl, depctl.d32 );
+       dwc_write_reg32( &dev_if->out_ep_regs[0]->doeptsiz, 0 );
+       dwc_write_reg32( &dev_if->out_ep_regs[0]->doepdma, 0 );
+       dwc_write_reg32( &dev_if->out_ep_regs[0]->doepint, 0xff );
 
        depctl.d32 = 0;
        depctl.b.setd0pid = 1;
-    dwc_write_reg32( &dev_if->in_ep_regs[1]->diepctl, depctl.d32);
+       dwc_write_reg32( &dev_if->in_ep_regs[1]->diepctl, depctl.d32);
        depctl.b.snak = 1;
        depctl.b.txfnum = 2;
        depctl.b.eptype = 2;
-    depctl.b.usbactep = 1;
-    depctl.b.mps = 0x200;
-    dwc_write_reg32( &dev_if->out_ep_regs[2]->doepctl, depctl.d32 );
-    dwc_write_reg32( &dev_if->out_ep_regs[2]->doepint, 0xff );
-
-    /* global register initial */
-    dwc_write_reg32( &dev_if->dev_global_regs->diepmsk, 0x2f );//device IN interrutp mask
-    dwc_write_reg32( &dev_if->dev_global_regs->doepmsk, 0x0f );//device OUT interrutp mask
-    dwc_write_reg32( &dev_if->dev_global_regs->daint, 0xffffffff ); //clear all pending intrrupt
-    daintmsk.b.inep0 = 1;
-    daintmsk.b.inep1 = 1;
-    daintmsk.b.outep0 = 1;
-    daintmsk.b.outep2 = 1;
-    dwc_write_reg32( &dev_if->dev_global_regs->daintmsk, daintmsk.d32 );
+       depctl.b.usbactep = 1;
+       depctl.b.mps = 0x200;
+       dwc_write_reg32( &dev_if->out_ep_regs[2]->doepctl, depctl.d32 );
+       dwc_write_reg32( &dev_if->out_ep_regs[2]->doepint, 0xff );
+
+       /* global register initial */
+       dwc_write_reg32( &dev_if->dev_global_regs->diepmsk, 0x2f );//device IN interrutp mask
+       dwc_write_reg32( &dev_if->dev_global_regs->doepmsk, 0x0f );//device OUT interrutp mask
+       dwc_write_reg32( &dev_if->dev_global_regs->daint, 0xffffffff ); //clear all pending intrrupt
+       daintmsk.b.inep0 = 1;
+       daintmsk.b.inep1 = 1;
+       daintmsk.b.outep0 = 1;
+       daintmsk.b.outep2 = 1;
+       dwc_write_reg32( &dev_if->dev_global_regs->daintmsk, daintmsk.d32 );
     
-    dwc_write_reg32( &global_regs->gintsts, 0xffffffff );
-    dwc_write_reg32( &global_regs->gotgint, 0xffffffff );
-    dwc_otg_enable_device_interrupts(_core_if);
-    gahbcfg.d32 = 0;
-    gahbcfg.b.glblintrmsk = 1;
-    gahbcfg.b.dmaenable = 1;
+       dwc_write_reg32( &global_regs->gintsts, 0xffffffff );
+       dwc_write_reg32( &global_regs->gotgint, 0xffffffff );
+       dwc_otg_enable_device_interrupts(_core_if);
+       gahbcfg.d32 = 0;
+       gahbcfg.b.glblintrmsk = 1;
+       gahbcfg.b.dmaenable = 1;
        gahbcfg.b.hburstlen = DWC_GAHBCFG_INT_DMA_BURST_INCR16; // yk@20101221
-    dwc_write_reg32( &global_regs->gahbcfg, gahbcfg.d32 );
+       dwc_write_reg32( &global_regs->gahbcfg, gahbcfg.d32 );
 }
 
 /** 
index ddee92afa23950565bbe9a06309ac090e48ab3b4..49cbbb8b7170866f2b626da1bc75a16cbd25f139 100755 (executable)
@@ -62,6 +62,8 @@
 
 #include "linux/dwc_otg_plat.h"
 #include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
 #include "dwc_otg_attr.h"
 #include "dwc_otg_driver.h"
 #include "dwc_otg_cil.h"
@@ -79,6 +81,8 @@ static const char dwc_driver_name[] = "usb20_otg";
 
 dwc_otg_device_t* g_otgdev = NULL;
 
+extern struct dwc_otg_platform_data usb20otg_pdata;
+extern struct dwc_otg_platform_data usb20host_pdata;
 /*-------------------------------------------------------------------------*/
 /* Encapsulate the module parameter settings */
 
@@ -332,11 +336,11 @@ static ssize_t dbg_level_store(struct device_driver *_drv, const char *_buf,
 static DRIVER_ATTR(debuglevel, S_IRUGO|S_IWUSR, dbg_level_show, dbg_level_store);
 #ifdef CONFIG_USB
 
-extern struct usb_hub *g_root_hub20;
+extern struct usb_hub *g_dwc_otg_root_hub20;
 #ifdef DWC_BOTH_HOST_SLAVE
 extern void hcd_start( dwc_otg_core_if_t *_core_if );
 
-extern void hub_disconnect_device(struct usb_hub *hub);
+extern void dwc_otg_hub_disconnect_device(struct usb_hub *hub);
 
 static ssize_t force_usb_mode_show(struct device_driver *_drv, char *_buf)
 {
@@ -388,7 +392,7 @@ void dwc_otg_force_device(dwc_otg_core_if_t *core_if)
        printk("dwc_otg_force_device,already in B_PERIPHERAL,everest\n");
        return;
     }
-       hub_disconnect_device(g_root_hub20);
+    dwc_otg_hub_disconnect_device(g_dwc_otg_root_hub20);
     otg_dev->core_if->op_state = B_PERIPHERAL;
        /* Reset the Controller */
        dwc_otg_core_reset( core_if );
@@ -510,7 +514,7 @@ static ssize_t force_usb_mode_store(struct device_driver *_drv, const char *_buf
                                        dwc_otg_force_device(core_if);
                                }
                                //if(dwc_otg_connid(core_if))
-                               //      hub_disconnect_device();
+                               //      dwc_otg_hub_disconnect_device(g_dwc_otg_root_hub20);
                                //core_if->usb_mode = new_mode;
                                //      dwc_otg_force_device(core_if);
                        }
@@ -1112,6 +1116,7 @@ static irqreturn_t dwc_otg_common_irq(int _irq, void *_dev)
        return IRQ_RETVAL(retval);
 }
 
+#ifdef CONFIG_USB20_OTG
 /**
  * This function is called when a lm_device is unregistered with the
  * dwc_otg_driver. This happens, for example, when the rmmod command is
@@ -1198,31 +1203,41 @@ static int dwc_otg_driver_remove(struct platform_device *pdev)
  *
  * @param[in] pdev  platform_device definition
  */
-static __devinit int dwc_otg_driver_probe(struct platform_device *pdev)
+static int dwc_otg_driver_probe(struct platform_device *pdev)
 {
-       int retval = 0;
-       struct resource *res_base;
-       struct device *dev = &pdev->dev;
-       dwc_otg_device_t *dwc_otg_device;
-       int32_t snpsid;
-       int irq;
-       struct dwc_otg_platform_data *pldata = dev->platform_data;
+       struct device_node      *node = pdev->dev.of_node;
+       int                     retval = 0;
+       struct resource         *res_base;
+       struct device           *dev = &pdev->dev;
+       dwc_otg_device_t        *dwc_otg_device;
+       int32_t                 snpsid;
+       int                     irq;
+       struct                  dwc_otg_platform_data *pldata;
+
+       dev->platform_data = &usb20otg_pdata;
+       pldata =  dev->platform_data;
+       pldata->dev = dev;
+
+       if (!node) {
+               dev_err(dev, "device node not found\n");
+               return -EINVAL;
+       }
 
-    // clock and hw init
-    if(pldata->hw_init)
-        pldata->hw_init();
+       // clock and hw init
+       if(pldata->hw_init)
+               pldata->hw_init();
         
     
-    if(pldata->clock_init){
-        pldata->clock_init(pldata);
-        pldata->clock_enable(pldata, 1);
-        }
+       if(pldata->clock_init){
+               pldata->clock_init(pldata);
+               pldata->clock_enable(pldata, 1);
+       }
 
-    if(pldata->phy_suspend)
-        pldata->phy_suspend(pldata, USB_PHY_ENABLED);
+       if(pldata->phy_suspend)
+               pldata->phy_suspend(pldata, USB_PHY_ENABLED);
         
-    if(pldata->soft_reset)
-        pldata->soft_reset();
+       if(pldata->soft_reset)
+               pldata->soft_reset();
 
        dwc_otg_device = kmalloc(sizeof(dwc_otg_device_t), GFP_KERNEL);
        
@@ -1244,7 +1259,7 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev)
        if (!res_base)
                goto fail;
 
-       dwc_otg_device->base =  ioremap(res_base->start,res_base->end-res_base->start+1);
+       dwc_otg_device->base =  devm_ioremap_resource(dev, res_base);
        if (dwc_otg_device->base == NULL)
        {
                dev_err(dev, "ioremap() failed\n");
@@ -1307,7 +1322,7 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev)
 
        /*
         * Create Device Attributes in sysfs
-        */      
+        */
        dwc_otg_attr_create(dev);
 #ifndef CONFIG_DWC_OTG_DEVICE_ONLY
        retval |= device_create_file(dev, &dev_attr_enable);
@@ -1492,6 +1507,11 @@ static void dwc_otg_driver_shutdown(struct platform_device *_dev )
  * to this driver. The remove function is called when a device is
  * unregistered with the bus driver.
  */
+static const struct of_device_id usb20_otg_of_match[] = {
+       { .compatible = "rockchip,usb20_otg", },
+       {},
+};
+MODULE_DEVICE_TABLE(of, usb20_otg_of_match);
 static struct platform_driver dwc_otg_driver = {
        .probe = dwc_otg_driver_probe,
        .remove = dwc_otg_driver_remove,
@@ -1500,13 +1520,15 @@ static struct platform_driver dwc_otg_driver = {
        .shutdown = dwc_otg_driver_shutdown,
        .driver = {
                   .name = dwc_driver_name,
-                  .owner = THIS_MODULE},
+                  .owner = THIS_MODULE,
+                  .of_match_table = of_match_ptr(usb20_otg_of_match),
+       },
 };
-
+#endif
 
 #ifdef CONFIG_USB20_HOST
 extern void dwc_otg_hcd_remove(struct device *dev);
-extern int __devinit host20_hcd_init(struct device *_dev);
+extern int host20_hcd_init(struct device *_dev);
 
 
 static int host20_driver_remove(struct platform_device *pdev)
@@ -1573,30 +1595,40 @@ static int host20_driver_remove(struct platform_device *pdev)
  *
  * @param[in] pdev  platform_device definition
  */
-static __devinit int host20_driver_probe(struct platform_device *pdev)
+static int host20_driver_probe(struct platform_device *pdev)
 {
-       struct resource *res_base;
-       int retval = 0;
-       struct device *dev = &pdev->dev;
-       dwc_otg_device_t *dwc_otg_device;
-       int32_t snpsid;
-       int irq;
-       struct dwc_otg_platform_data *pldata = dev->platform_data;
-    
-    // clock and hw init
-    if(pldata->hw_init)
-        pldata->hw_init();
+       struct device_node      *node = pdev->dev.of_node;
+       struct resource         *res_base;
+       int                     retval = 0;
+       struct device           *dev = &pdev->dev;
+       dwc_otg_device_t        *dwc_otg_device;
+       int32_t                 snpsid;
+       int                     irq;
+       struct dwc_otg_platform_data *pldata;
+
+       dev->platform_data = &usb20host_pdata;
+       pldata = dev->platform_data;
+       pldata->dev = dev;
+
+       if (!node) {
+               dev_err(dev, "device node not found\n");
+               return -EINVAL;
+       }
+
+       // clock and hw init
+       if(pldata->hw_init)
+               pldata->hw_init();
         
-    if(pldata->clock_init){
-        pldata->clock_init(pldata);
-        pldata->clock_enable(pldata, 1);
-        }
+       if(pldata->clock_init){
+               pldata->clock_init(pldata);
+               pldata->clock_enable(pldata, 1);
+       }
 
-    if(pldata->phy_suspend)
-        pldata->phy_suspend(pldata, USB_PHY_ENABLED);
+       if(pldata->phy_suspend)
+               pldata->phy_suspend(pldata, USB_PHY_ENABLED);
         
-    if(pldata->soft_reset)
-        pldata->soft_reset();
+       if(pldata->soft_reset)
+               pldata->soft_reset();
             
        /*
         *Enable usb phy
@@ -1622,9 +1654,8 @@ static __devinit int host20_driver_probe(struct platform_device *pdev)
        if (!res_base)
                goto fail;
 
-       dwc_otg_device->base =
-               ioremap(res_base->start,res_base->end-res_base->start+1);
-    DWC_PRINT("%s host2.0 reg addr: 0x%x remap:0x%x\n",__func__,
+       dwc_otg_device->base = devm_ioremap_resource(dev, res_base);
+       DWC_PRINT("%s host2.0 reg addr: 0x%x remap:0x%x\n",__func__,
                (unsigned)res_base->start, (unsigned)dwc_otg_device->base);
        if (dwc_otg_device->base == NULL)
        {
@@ -1736,12 +1767,19 @@ static __devinit int host20_driver_probe(struct platform_device *pdev)
        return retval;
 }
 
+static const struct of_device_id usb20_host_of_match[] = {
+       { .compatible = "rockchip,usb20_host", },
+       {},
+};
+MODULE_DEVICE_TABLE(of, usb20_host_of_match);
 static struct platform_driver host20_driver = {
        .probe = host20_driver_probe,
        .remove = host20_driver_remove,
        .driver = {
                   .name = "usb20_host",
-                  .owner = THIS_MODULE},
+                  .owner = THIS_MODULE,
+                  .of_match_table = of_match_ptr(usb20_host_of_match),
+       },
 };
 #endif
 
@@ -1761,6 +1799,7 @@ static int __init dwc_otg_driver_init(void)
     /*
      *  USB2.0 OTG controller
      */
+#ifdef CONFIG_USB20_OTG
        retval = platform_driver_register(&dwc_otg_driver);
        if (retval < 0) 
        {
@@ -1777,18 +1816,22 @@ static int __init dwc_otg_driver_init(void)
 #endif
 
 #ifdef CONFIG_RK_USB_UART
-if(driver_create_file(&dwc_otg_driver.driver, &driver_attr_dwc_otg_force_uart))
-    pr_warning("DWC_OTG: Failed to create driver dwc_otg_force_uart file");
-#endif    
+       if(driver_create_file(&dwc_otg_driver.driver, &driver_attr_dwc_otg_force_uart))
+               pr_warning("DWC_OTG: Failed to create driver dwc_otg_force_uart file");
+#endif
+
 #ifndef CONFIG_DWC_OTG_HOST_ONLY
        if(driver_create_file(&dwc_otg_driver.driver, &driver_attr_vbus_status))
                pr_warning("DWC_OTG: Failed to create driver vbus status file");
 #endif
+       
 #ifdef DWC_BOTH_HOST_SLAVE
     if(driver_create_file(&dwc_otg_driver.driver, &driver_attr_force_usb_mode))
                pr_warning("DWC_OTG: Failed to create driver force usb mode file\n");
 #endif
-    
+
+#endif
+
     /*
      *  USB2.0 host controller
      */
@@ -1829,25 +1872,28 @@ static void __exit dwc_otg_driver_cleanup(void)
 {
        DWC_PRINT("dwc_otg_driver_cleanup()\n");
 
+#ifdef CONFIG_USB20_OTG
        driver_remove_file(&dwc_otg_driver.driver, &driver_attr_version);
        driver_remove_file(&dwc_otg_driver.driver, &driver_attr_debuglevel);
     
 #ifdef DWC_BOTH_HOST_SLAVE     
-        driver_remove_file(&dwc_otg_driver.driver, &driver_attr_force_usb_mode);
+       driver_remove_file(&dwc_otg_driver.driver, &driver_attr_force_usb_mode);
 #endif
+
 #ifndef CONFIG_DWC_OTG_HOST_ONLY
-    driver_remove_file(&dwc_otg_driver.driver, &driver_attr_dwc_otg_conn_en);
+       driver_remove_file(&dwc_otg_driver.driver, &driver_attr_dwc_otg_conn_en);
 #endif
 
 #ifdef CONFIG_RK_USB_UART
-    driver_remove_file(&dwc_otg_driver.driver, &driver_attr_dwc_otg_force_uart);
+       driver_remove_file(&dwc_otg_driver.driver, &driver_attr_dwc_otg_force_uart);
 #endif
 
 #ifndef CONFIG_DWC_OTG_HOST_ONLY
-    driver_remove_file(&dwc_otg_driver.driver, &driver_attr_vbus_status);
+       driver_remove_file(&dwc_otg_driver.driver, &driver_attr_vbus_status);
 #endif
 
        platform_driver_unregister(&dwc_otg_driver);
+#endif
        
 #ifdef CONFIG_USB11_HOST
        platform_driver_unregister(&host11_driver);
index bfaa2d02db3e1d8957d9a3b2c945d0e6f1c27eb6..976b56726e6352c5080b95649654150c5bf8dff0 100755 (executable)
@@ -73,7 +73,7 @@ static int dwc_otg_hcd_suspend(struct usb_hcd *hcd)
     if(!(dwc_otg_hcd->host_enabled&1))
         return 0;
     hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
-#ifdef CONFIG_USB_SUSPEND    
+#ifdef CONFIG_PM_RUNTIME
     if((!hprt0.b.prtena))
         return 0;
 #endif        
@@ -135,7 +135,7 @@ static int dwc_otg_hcd_resume(struct usb_hcd *hcd)
        DWC_PRINT("%s, usb device mode\n", __func__);
        return 0;
     }
-//#ifdef CONFIG_USB_SUSPEND    
+//#ifdef CONFIG_PM_RUNTIME
     if(!(dwc_otg_hcd->host_enabled&1))
         return 0;
 //#endif
@@ -158,7 +158,7 @@ static int dwc_otg_hcd_resume(struct usb_hcd *hcd)
     dwc_write_reg32(&core_if->core_global_regs->gintmsk, gintmsk.d32);
         
     hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
-#ifdef CONFIG_USB_SUSPEND    
+#ifdef CONFIG_PM_RUNTIME
     if(!hprt0.b.prtena)
         return 0;
 #endif
@@ -717,7 +717,7 @@ static void dwc_otg_hcd_connect_detect(unsigned long pdata)
  * a negative error on failure.
  */
 extern uint32_t g_dbg_lvl;
-int __devinit dwc_otg_hcd_init(struct device *dev)
+int  dwc_otg_hcd_init(struct device *dev)
 {
        struct usb_hcd *hcd = NULL;
        dwc_otg_hcd_t *dwc_otg_hcd = NULL;
@@ -1044,7 +1044,7 @@ static struct tasklet_struct host20_reset_tasklet = {
        .data = 0,
 };
 
-int __devinit host20_hcd_init(struct device *dev)
+int host20_hcd_init(struct device *dev)
 {
        struct usb_hcd *hcd = NULL;
        dwc_otg_hcd_t *dwc_otg_hcd = NULL;
@@ -2328,7 +2328,7 @@ int dwc_otg_hcd_hub_control(struct usb_hcd *_hcd,
                        dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
                        break;
                case USB_PORT_FEAT_SUSPEND:
-               #ifdef CONFIG_USB_SUSPEND
+               #ifdef CONFIG_PM_RUNTIME
                        break;
                #endif
                        DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
@@ -2514,7 +2514,7 @@ int dwc_otg_hcd_hub_control(struct usb_hcd *_hcd,
 
                switch (_wValue) {
                case USB_PORT_FEAT_SUSPEND:
-               #ifdef CONFIG_USB_SUSPEND
+               #ifdef CONFIG_PM_RUNTIME
                        break;
                #endif
                        DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
index cdf9a184a574e2063f21233f098eb67df84e6617..1afd8b56ec5157fe9715fbb0600136adf2083683 100755 (executable)
@@ -427,7 +427,7 @@ static inline struct usb_hcd *dwc_otg_hcd_to_hcd(dwc_otg_hcd_t *dwc_otg_hcd)
 
 /** @name HCD Create/Destroy Functions */
 /** @{ */
-extern int __init dwc_otg_hcd_init(struct device *_dev);
+extern int dwc_otg_hcd_init(struct device *_dev);
 extern void dwc_otg_hcd_remove(struct device *_dev);
 /** @} */
 
index a0b9357626584c2d4af78a6a60524ea78ab42ee9..3a0c8957c558147c055b454fdb4b0e7a60f01e2d 100755 (executable)
@@ -247,7 +247,7 @@ static int periodic_channel_available(dwc_otg_hcd_t *_hcd)
         * non-periodic transactions.
         */
        int status;
-#if defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK3188)
+#if CONFIG_ARCH_ROCKCHIP
        int num_channels;
 
        num_channels = _hcd->core_if->core_params->host_channels;
index 50ec2d87860509fbae80633c766faedea2442d18..de81406162b9e32400e6931230a642b144adc5ee 100755 (executable)
@@ -86,6 +86,7 @@
 #include "dwc_otg_regs.h"
 
 #include "usbdev_rk.h"
+
 /**
  * Static PCD pointer for use in usb_gadget_register_driver and
  * usb_gadget_unregister_driver.  Initialized in dwc_otg_pcd_init.
@@ -1058,12 +1059,43 @@ static int dwc_otg_pcd_pullup(struct usb_gadget *_gadget, int is_on)
     return 0;
 }
 
+static int dwc_otg_gadget_start(struct usb_gadget *g,
+                               struct usb_gadget_driver *driver)
+{
+       DWC_DEBUGPL(DBG_PCD, "registering gadget driver '%s'\n", driver->driver.name);
+       if (s_pcd == 0)
+       {
+               DWC_ERROR("ENODEV\n");
+               return -ENODEV;
+       }
+       if (s_pcd->driver != 0)
+       {
+               DWC_ERROR("EBUSY (%p)\n", s_pcd->driver);
+               return -EBUSY;
+       }
+       /* hook up the driver */
+       s_pcd->driver = driver;
+       s_pcd->gadget.dev.driver = &driver->driver;
+
+       DWC_DEBUGPL(DBG_PCD, "bind to driver %s\n", driver->driver.name);
+
+       return 0;
+}
+
+static int dwc_otg_gadget_stop(struct usb_gadget *g,
+                               struct usb_gadget_driver *driver)
+{
+       return 0;
+}
+
 static const struct usb_gadget_ops dwc_otg_pcd_ops = 
 {
        .get_frame       = dwc_otg_pcd_get_frame,
        .wakeup          = dwc_otg_pcd_wakeup,
        .pullup      = dwc_otg_pcd_pullup,
        // current versions must always be self-powered
+       .udc_start              = dwc_otg_gadget_start,
+       .udc_stop               = dwc_otg_gadget_stop,
 };
 
 /**
@@ -1899,7 +1931,7 @@ int dwc_otg_pcd_init(struct device *dev)
        static char pcd_name[] = "dwc_otg_pcd";
        dwc_otg_pcd_t *pcd;
        dwc_otg_device_t *otg_dev = (dwc_otg_device_t *)(*((uint32_t *)dev->platform_data));
-    dwc_otg_core_if_t *core_if = otg_dev->core_if; 
+       dwc_otg_core_if_t *core_if = otg_dev->core_if;
        struct dwc_otg_platform_data *pldata = dev->platform_data;
        int retval = 0;
        int irq;
@@ -1927,12 +1959,13 @@ int dwc_otg_pcd_init(struct device *dev)
        pcd->gadget.dev.init_name= "gadget";
        pcd->gadget.ops = &dwc_otg_pcd_ops;
        
-       pcd->gadget.is_dualspeed = 0;
+//     pcd->gadget.is_dualspeed = 0;
        pcd->gadget.is_otg = 0;
+       pcd->gadget.max_speed = USB_SPEED_HIGH;
        pcd->driver = 0;
-    pcd->conn_en = 0;
+       pcd->conn_en = 0;
        /* Register the gadget device */
-       retval = device_register( &pcd->gadget.dev );
+       retval = usb_add_gadget_udc(dev, &pcd->gadget);
        if(retval != 0)
        {
                DWC_ERROR("device_register failed\n");
@@ -2072,7 +2105,7 @@ void dwc_otg_pcd_remove( struct device *dev )
  *
  * @param _driver The driver being registered
  */
+#if 0
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
 int usb_gadget_probe_driver(struct usb_gadget_driver *_driver,
                int (*bind)(struct usb_gadget *))
@@ -2135,7 +2168,6 @@ EXPORT_SYMBOL(usb_gadget_probe_driver);
 #else
 EXPORT_SYMBOL(usb_gadget_register_driver);
 #endif
-
 /**
  * This function unregisters a gadget driver
  *
@@ -2166,4 +2198,5 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *_driver)
        return 0;
 }
 EXPORT_SYMBOL(usb_gadget_unregister_driver);
+#endif
 #endif /* DWC_HOST_ONLY */
index 672fdd737a09f15bd930055ad197e0bb36931968..19cd5e835022a5931115ce4a367c785c86674358 100755 (executable)
@@ -1,3 +1,5 @@
+#ifndef __USBDEV_RK_H\r
+#define __USBDEV_RK_H\r
 \r
 #define USB_PHY_ENABLED 0\r
 #define USB_PHY_SUSPEND 1\r
@@ -12,6 +14,7 @@
 \r
 struct dwc_otg_platform_data {\r
     void *privdata;\r
+    struct device *dev;\r
     struct clk* phyclk;\r
     struct clk* ahbclk;\r
     struct clk* busclk;\r
@@ -36,3 +39,13 @@ struct rkehci_platform_data{
        void (*soft_reset)(void);\r
        int clk_status;\r
 };\r
+\r
+struct dwc_otg_control_usb {\r
+       void *grf_soc_status0;\r
+       void *grf_uoc0_base;\r
+       void *grf_uoc1_base;\r
+       struct gpio *host_gpios;\r
+       struct gpio *otg_gpios;\r
+};\r
+\r
+#endif\r
old mode 100755 (executable)
new mode 100644 (file)
index d7c21d0..cb4da87
-#include <linux/kernel.h>\r
-#include <linux/platform_device.h>\r
-#include <linux/delay.h>\r
-#include <linux/dma-mapping.h>\r
-#include <linux/clk.h>\r
-\r
-#include <mach/irqs.h>\r
-#include <mach/gpio.h>\r
-#include <mach/iomux.h>\r
-#include <mach/cru.h>\r
-\r
-#include "usbdev_rk.h"\r
-#include "dwc_otg_regs.h" \r
-\r
-#if defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK3188)\r
-\r
-#define GRF_REG_BASE   RK30_GRF_BASE   \r
-#define USBOTG_SIZE    RK30_USBOTG20_SIZE\r
-#if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)\r
-#define USBGRF_SOC_STATUS0     (GRF_REG_BASE+0xac)\r
-#define USBGRF_UOC0_CON0       (GRF_REG_BASE+0x10c)\r
-#define USBGRF_UOC0_CON2       (GRF_REG_BASE+0x114)\r
-#define USBGRF_UOC0_CON3       (GRF_REG_BASE+0x118)\r
-#define USBGRF_UOC1_CON0       (GRF_REG_BASE+0x11C)\r
-#define USBGRF_UOC1_CON2       (GRF_REG_BASE+0x124)\r
-#define USBGRF_UOC1_CON3       (GRF_REG_BASE+0x128)\r
-#define USBGRF_UOC3_CON0       (GRF_REG_BASE+0x138)\r
-\r
-#define USBGRF_UOC2_CON0       (GRF_REG_BASE+0x12C)\r
-#if defined(CONFIG_SOC_RK3066B) || defined(CONFIG_SOC_RK3108) \r
-#define RK3066B_HOST_DRV_VBUS RK30_PIN0_PD7\r
-#define RK3066B_OTG_DRV_VBUS  RK30_PIN0_PD6\r
-#elif defined(CONFIG_SOC_RK3168) || defined(CONFIG_SOC_RK3188) || defined(CONFIG_SOC_RK3168M) || defined(CONFIG_SOC_RK3188M)\r
-#define RK3066B_HOST_DRV_VBUS RK30_PIN0_PC0\r
-#define RK3066B_OTG_DRV_VBUS  RK30_PIN3_PD5\r
-#elif defined(CONFIG_SOC_RK3028)\r
-#define RK3066B_HOST_DRV_VBUS RK30_PIN1_PA4\r
-#define RK3066B_OTG_DRV_VBUS  RK30_PIN3_PD7\r
-#endif\r
-\r
-#else\r
-#define USBGRF_SOC_STATUS0     (GRF_REG_BASE+0x15c)\r
-#define USBGRF_UOC0_CON2       (GRF_REG_BASE+0x184)\r
-#define USBGRF_UOC1_CON2       (GRF_REG_BASE+0x190)\r
-#endif\r
-\r
-int dwc_otg_check_dpdm(void)\r
-{\r
-       static uint8_t * reg_base = 0;\r
-    volatile unsigned int * otg_dctl;\r
-    volatile unsigned int * otg_gotgctl;\r
-    volatile unsigned int * otg_hprt0;\r
-    int bus_status = 0;\r
-    unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC0_CON2);\r
-    \r
-    // softreset & clockgate \r
-    *(unsigned int*)(RK30_CRU_BASE+0x120) = ((7<<5)<<16)|(7<<5);    // otg0 phy clkgate\r
-    udelay(3);\r
-    *(unsigned int*)(RK30_CRU_BASE+0x120) = ((7<<5)<<16)|(0<<5);    // otg0 phy clkgate\r
-    dsb();\r
-    *(unsigned int*)(RK30_CRU_BASE+0xd4) = ((1<<5)<<16);    // otg0 phy clkgate\r
-    *(unsigned int*)(RK30_CRU_BASE+0xe4) = ((1<<13)<<16);   // otg0 hclk clkgate\r
-    *(unsigned int*)(RK30_CRU_BASE+0xe0) = ((3<<5)<<16);    // hclk usb clkgate\r
-    \r
-    // exit phy suspend \r
-        *otg_phy_con1 = ((0x01<<2)<<16);    // exit suspend.\r
-    \r
-    // soft connect\r
-    if(reg_base == 0){\r
-        reg_base = ioremap(RK30_USBOTG20_PHYS,USBOTG_SIZE);\r
-        if(!reg_base){\r
-            bus_status = -1;\r
-            goto out;\r
-        }\r
-    }\r
-    mdelay(105);\r
-    printk("regbase %p 0x%x, otg_phy_con%p, 0x%x\n",\r
-        reg_base, *(reg_base), otg_phy_con1, *otg_phy_con1);\r
-    otg_dctl = (unsigned int * )(reg_base+0x804);\r
-    otg_gotgctl = (unsigned int * )(reg_base);\r
-    otg_hprt0 = (unsigned int * )(reg_base + DWC_OTG_HOST_PORT_REGS_OFFSET);\r
-    if(*otg_gotgctl &(1<<19)){\r
-        bus_status = 1;\r
-        *otg_dctl &= ~2;\r
-        mdelay(50);    // delay about 10ms\r
-    // check dp,dm\r
-        if((*otg_hprt0 & 0xc00)==0xc00)\r
-            bus_status = 2;\r
-    }\r
-out:\r
-    return bus_status;\r
-}\r
-\r
-EXPORT_SYMBOL(dwc_otg_check_dpdm);\r
-\r
-#ifdef CONFIG_USB20_OTG\r
-/*DWC_OTG*/\r
-static struct resource usb20_otg_resource[] = {\r
-       {\r
-               .start = IRQ_USB_OTG,\r
-               .end   = IRQ_USB_OTG,\r
-               .flags = IORESOURCE_IRQ,\r
-       },\r
-       {\r
-               .start = RK30_USBOTG20_PHYS,\r
-               .end   = RK30_USBOTG20_PHYS + RK30_USBOTG20_SIZE - 1,\r
-               .flags = IORESOURCE_MEM,\r
-       },\r
-\r
-};\r
-\r
-void usb20otg_hw_init(void)\r
-{\r
-#ifndef CONFIG_USB20_HOST\r
-        // close USB 2.0 HOST phy and clock\r
-#if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)\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
-#endif\r
-        // usb phy config init\r
-#ifdef CONFIG_ARCH_RK3188\r
-        //usb phy enter usb mode\r
-        unsigned int * otg_phy_con3 = (unsigned int*)(USBGRF_UOC0_CON0);\r
-        *otg_phy_con3 = (0x0300 << 16);\r
-       //Disconnect Threshold Adjustment\r
-       *otg_phy_con3 = (0x07<<1)|((0x07<<1)<<16);      \r
-#endif    \r
-        // other haredware init\r
-#if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)\r
-        //GPIO init\r
-        gpio_request(RK3066B_OTG_DRV_VBUS, NULL);\r
-        gpio_direction_output(RK3066B_OTG_DRV_VBUS, GPIO_LOW);\r
-#else\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
-#if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)\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
-void usb20otg_soft_reset(void)\r
-{\r
-    cru_set_soft_reset(SOFT_RST_USBOTG0, true);\r
-    cru_set_soft_reset(SOFT_RST_USBPHY0, true);\r
-    cru_set_soft_reset(SOFT_RST_OTGC0, true);\r
-    udelay(1);\r
-\r
-    cru_set_soft_reset(SOFT_RST_USBOTG0, false);\r
-    cru_set_soft_reset(SOFT_RST_USBPHY0, false);\r
-    cru_set_soft_reset(SOFT_RST_OTGC0, false);\r
-    mdelay(1);\r
-}\r
-void usb20otg_clock_init(void* pdata)\r
-{\r
-    struct dwc_otg_platform_data *usbpdata=pdata;\r
-    struct clk* ahbclk,*phyclk;\r
-    ahbclk = clk_get(NULL, "hclk_otg0");\r
-    phyclk = clk_get(NULL, "otgphy0");\r
-       usbpdata->phyclk = phyclk;\r
-       usbpdata->ahbclk = ahbclk;\r
-}\r
-void usb20otg_clock_enable(void* pdata, int enable)\r
-{\r
-    struct dwc_otg_platform_data *usbpdata=pdata;\r
-\r
-    if(enable){\r
-        clk_enable(usbpdata->ahbclk);\r
-        clk_enable(usbpdata->phyclk);\r
-    }\r
-    else{\r
-        clk_disable(usbpdata->phyclk);\r
-        clk_disable(usbpdata->ahbclk);\r
-    }\r
-}\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
-#if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)\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
-#endif\r
-            default:\r
-                break;\r
-        }\r
-        return ret;\r
-}\r
-\r
-#ifdef CONFIG_RK_USB_UART\r
-void dwc_otg_uart_mode(void* pdata, int enter_usb_uart_mode)\r
-{\r
-       unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC0_CON0);\r
-             \r
-       if(1 == enter_usb_uart_mode){  //enter uart mode\r
-               /*note: can't disable otg here! If otg disable, the ID change\r
-               *interrupt can't be triggered when otg cable connect without\r
-               *device.At the same time, uart can't be used normally \r
-               */\r
-               //*otg_phy_con1 = (0x10 | (0x10 << 16));//otg disable\r
-               *otg_phy_con1 = (0x0300 | (0x0300 << 16));//bypass dm       \r
-       }\r
-       if(0 == enter_usb_uart_mode){  //enter usb mode \r
-               *otg_phy_con1 = (0x0300 << 16); //bypass dm disable\r
-               //*otg_phy_con1 = (0x10 << 16);//otg enable             \r
-       }\r
-}\r
-#endif\r
-\r
-#if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)\r
-void usb20otg_power_enable(int enable)\r
-{ \r
-    unsigned int usbgrf_status = *(unsigned int*)(USBGRF_SOC_STATUS0);\r
-    if(0 == enable)//disable\r
-    {\r
-        gpio_set_value(RK3066B_OTG_DRV_VBUS, GPIO_LOW); \r
-\r
-    }\r
-    if(1 == enable)//enable\r
-    {\r
-        gpio_set_value(RK3066B_OTG_DRV_VBUS, GPIO_HIGH); \r
-    }   \r
-}\r
-#endif\r
-struct dwc_otg_platform_data usb20otg_pdata = {\r
-    .phyclk = NULL,\r
-    .ahbclk = NULL,\r
-    .busclk = NULL,\r
-    .phy_status = 0,\r
-    .hw_init=usb20otg_hw_init,\r
-    .phy_suspend=usb20otg_phy_suspend,\r
-    .soft_reset=usb20otg_soft_reset,\r
-    .clock_init=usb20otg_clock_init,\r
-    .clock_enable=usb20otg_clock_enable,\r
-    .get_status=usb20otg_get_status,\r
-#if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)\r
-    .power_enable=usb20otg_power_enable,\r
-#endif\r
-#ifdef CONFIG_RK_USB_UART\r
-    .dwc_otg_uart_mode=dwc_otg_uart_mode,\r
-#endif\r
-};\r
-\r
-struct platform_device device_usb20_otg = {\r
-       .name             = "usb20_otg",\r
-       .id               = -1,\r
-       .num_resources    = ARRAY_SIZE(usb20_otg_resource),\r
-       .resource         = usb20_otg_resource,\r
-       .dev            = {\r
-               .platform_data  = &usb20otg_pdata,\r
-       },\r
-};\r
-#endif\r
-#ifdef CONFIG_USB20_HOST\r
-static struct resource usb20_host_resource[] = {\r
-    {\r
-        .start = IRQ_USB_HOST,\r
-        .end   = IRQ_USB_HOST,\r
-        .flags = IORESOURCE_IRQ,\r
-    },\r
-    {\r
-        .start = RK30_USBHOST20_PHYS,\r
-        .end   = RK30_USBHOST20_PHYS + RK30_USBHOST20_SIZE - 1,\r
-        .flags = IORESOURCE_MEM,\r
-    },\r
-\r
-};\r
-void usb20host_hw_init(void)\r
-{\r
-    // usb phy config init\r
-#ifdef CONFIG_ARCH_RK3188\r
-    //Disconnect Threshold Adjustment\r
-    unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC1_CON0);\r
-    *otg_phy_con1 = (0x07<<1)|((0x07<<1)<<16);\r
-#endif    \r
-\r
-    // other haredware init\r
-#if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)\r
-    gpio_request(RK3066B_HOST_DRV_VBUS, NULL);\r
-    gpio_direction_output(RK3066B_HOST_DRV_VBUS, GPIO_HIGH);\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
-#if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)\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
-    cru_set_soft_reset(SOFT_RST_USBOTG1, true);\r
-    cru_set_soft_reset(SOFT_RST_USBPHY1, true);\r
-    cru_set_soft_reset(SOFT_RST_OTGC1, true);\r
-    udelay(5);\r
-\r
-    cru_set_soft_reset(SOFT_RST_USBOTG1, false);\r
-    cru_set_soft_reset(SOFT_RST_USBPHY1, false);\r
-    cru_set_soft_reset(SOFT_RST_OTGC1, false);\r
-    mdelay(2);\r
-}\r
-void usb20host_clock_init(void* pdata)\r
-{\r
-    struct dwc_otg_platform_data *usbpdata=pdata;\r
-    struct clk* ahbclk,*phyclk;\r
-    ahbclk = clk_get(NULL, "hclk_otg1");\r
-    phyclk = clk_get(NULL, "otgphy1");\r
-       usbpdata->phyclk = phyclk;\r
-       usbpdata->ahbclk = ahbclk;\r
-}\r
-void usb20host_clock_enable(void* pdata, int enable)\r
-{\r
-    struct dwc_otg_platform_data *usbpdata=pdata;\r
-    \r
-    if(enable){\r
-        clk_enable(usbpdata->ahbclk);\r
-        clk_enable(usbpdata->phyclk);\r
-    }\r
-    else{\r
-        clk_disable(usbpdata->phyclk);\r
-        clk_disable(usbpdata->ahbclk);\r
-    }\r
-}\r
-int usb20host_get_status(int id)\r
-{\r
-    int ret = -1;\r
-    unsigned int usbgrf_status = *(unsigned int*)(USBGRF_SOC_STATUS0);\r
-    switch(id)\r
-    {\r
-#if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)\r
-        case USB_STATUS_BVABLID:\r
-            // bvalid in grf\r
-            ret = (usbgrf_status &(1<<17));\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
-#else\r
-        case USB_STATUS_BVABLID:\r
-            // bvalid in grf\r
-            ret = (usbgrf_status &(1<<22));\r
-            break;\r
-        case USB_STATUS_DPDM:\r
-            // dpdm in grf\r
-            ret = (usbgrf_status &(3<<23));\r
-            break;\r
-        case USB_STATUS_ID:\r
-            // id in grf\r
-            ret = 0;\r
-            break;\r
-#endif\r
-        default:\r
-            break;\r
-    }\r
-    return ret;\r
-}\r
-\r
-#if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)\r
-void usb20host_power_enable(int enable)\r
-{ \r
-\r
-    if(0 == enable)//disable\r
-    {\r
-        //ret = gpio_request(RK3066B_HOST_DRV_VBUS, NULL);\r
-        //if (ret != 0) {\r
-        //    gpio_free(RK3066B_HOST_DRV_VBUS);\r
-        //}\r
-        //gpio_direction_output(RK3066B_HOST_DRV_VBUS, 1);\r
-        //gpio_set_value(RK3066B_HOST_DRV_VBUS, 0);\r
-        //printk("!!!!!!!!!!!!!!!!!!!disable host power!!!!!!!!!!!!!!!!!!\n");\r
-    }\r
-\r
-    if(1 == enable)//enable\r
-    {\r
-        gpio_set_value(RK3066B_HOST_DRV_VBUS, GPIO_HIGH);\r
-        //printk("!!!!!!!!!!!!!!!!!!!!!enable host power!!!!!!!!!!!!!!!!!!\n");\r
-    }   \r
-}\r
-#endif\r
-struct dwc_otg_platform_data usb20host_pdata = {\r
-    .phyclk = NULL,\r
-    .ahbclk = NULL,\r
-    .busclk = NULL,\r
-    .phy_status = 0,\r
-    .hw_init=usb20host_hw_init,\r
-    .phy_suspend=usb20host_phy_suspend,\r
-    .soft_reset=usb20host_soft_reset,\r
-    .clock_init=usb20host_clock_init,\r
-    .clock_enable=usb20host_clock_enable,\r
-    .get_status=usb20host_get_status,\r
-#if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)\r
-    .power_enable=usb20host_power_enable,\r
-#endif    \r
-};\r
-\r
-struct platform_device device_usb20_host = {\r
-    .name             = "usb20_host",\r
-    .id               = -1,\r
-    .num_resources    = ARRAY_SIZE(usb20_host_resource),\r
-    .resource         = usb20_host_resource,\r
-       .dev            = {\r
-               .platform_data  = &usb20host_pdata,\r
-       },\r
-};\r
-#endif\r
-#ifdef CONFIG_USB_EHCI_RK\r
-void rkehci_hw_init(void)\r
-{\r
-       unsigned int * phy_con0 = (unsigned int*)(USBGRF_UOC2_CON0);\r
-       unsigned int * phy_con1 = (unsigned int*)(USBGRF_UOC1_CON0);\r
-       unsigned int * phy_con2 = (unsigned int*)(USBGRF_UOC0_CON0);\r
-       unsigned int * phy_con3 = (unsigned int*)(USBGRF_UOC3_CON0);\r
-       // usb phy config init\r
-       // hsic phy config init, set hsicphy_txsrtune\r
-       *phy_con0 = ((0xf<<6)<<16)|(0xf<<6);\r
-\r
-       // other haredware init\r
-       // set common_on, in suspend mode, otg/host PLL blocks remain powered\r
-#ifdef CONFIG_ARCH_RK3188\r
-       *phy_con1 = (1<<16)|0;\r
-#else\r
-       *phy_con2 = (1<<16)|0;\r
-#endif\r
-       /* change INCR to INCR16 or INCR8(beats less than 16)\r
-        * or INCR4(beats less than 8) or SINGLE(beats less than 4)\r
-        */\r
-       *phy_con3 = 0x00ff00bc;\r
-}\r
-\r
-void rkehci_clock_init(void* pdata)\r
-{\r
-       struct rkehci_platform_data *usbpdata=pdata;\r
-\r
-#ifdef CONFIG_ARCH_RK3188  \r
-       struct clk *clk_otg, *clk_hs;\r
-\r
-       /* By default, hsicphy_480m's parent is otg phy 480MHz clk\r
-        * rk3188 must use host phy 480MHz clk\r
-        */\r
-       clk_hs = clk_get(NULL, "hsicphy_480m");\r
-       clk_otg = clk_get(NULL, "otgphy1_480m");\r
-       clk_set_parent(clk_hs, clk_otg);\r
-#endif\r
-\r
-       usbpdata->hclk_hsic = clk_get(NULL, "hclk_hsic");\r
-       usbpdata->hsic_phy_480m = clk_get(NULL, "hsicphy_480m");\r
-       usbpdata->hsic_phy_12m = clk_get(NULL, "hsicphy_12m");\r
-}\r
-\r
-void rkehci_clock_enable(void* pdata, int enable)\r
-{\r
-       struct rkehci_platform_data *usbpdata=pdata;\r
-\r
-       if(enable == usbpdata->clk_status)\r
-               return;\r
-\r
-       if(enable){\r
-               clk_enable(usbpdata->hclk_hsic);\r
-               clk_enable(usbpdata->hsic_phy_480m);\r
-               clk_enable(usbpdata->hsic_phy_12m);\r
-               usbpdata->clk_status = 1;\r
-       }else{\r
-               clk_disable(usbpdata->hsic_phy_12m);\r
-               clk_disable(usbpdata->hsic_phy_480m);\r
-               clk_disable(usbpdata->hclk_hsic);\r
-               usbpdata->clk_status = 0;\r
-       }\r
-}\r
-\r
-void rkehci_soft_reset(void)\r
-{\r
-       unsigned int * phy_con0 = (unsigned int*)(USBGRF_UOC2_CON0);\r
-\r
-       cru_set_soft_reset(SOFT_RST_HSICPHY, true);\r
-       udelay(12);\r
-       cru_set_soft_reset(SOFT_RST_HSICPHY, false);\r
-       mdelay(2);\r
-\r
-       *phy_con0 = ((1<<10)<<16)|(1<<10);\r
-       udelay(2);\r
-       *phy_con0 = ((1<<10)<<16)|(0<<10);\r
-       udelay(2);\r
-\r
-       cru_set_soft_reset(SOFT_RST_HSIC_AHB, true);\r
-       udelay(2);\r
-       cru_set_soft_reset(SOFT_RST_HSIC_AHB, false);\r
-       udelay(2);\r
-}\r
-\r
-struct rkehci_platform_data rkehci_pdata = {\r
-       .hclk_hsic = NULL,\r
-       .hsic_phy_12m = NULL,\r
-       .hsic_phy_480m = NULL,\r
-       .clk_status = -1,\r
-       .hw_init = rkehci_hw_init,\r
-       .clock_init = rkehci_clock_init,\r
-       .clock_enable = rkehci_clock_enable,\r
-       .soft_reset = rkehci_soft_reset,\r
-};\r
-\r
-static struct resource resources_hsusb_host[] = {\r
-    {\r
-        .start = IRQ_HSIC,\r
-        .end   = IRQ_HSIC,\r
-        .flags = IORESOURCE_IRQ,\r
-    },\r
-    {\r
-        .start = RK30_HSIC_PHYS,\r
-        .end   = RK30_HSIC_PHYS + RK30_HSIC_SIZE - 1,\r
-        .flags = IORESOURCE_MEM,\r
-    },\r
-};\r
-\r
-struct platform_device device_hsusb_host = {\r
-    .name           = "rk_hsusb_host",\r
-    .id             = -1,\r
-    .num_resources  = ARRAY_SIZE(resources_hsusb_host),\r
-    .resource       = resources_hsusb_host,\r
-    .dev            = {\r
-        .coherent_dma_mask      = 0xffffffff,\r
-        .platform_data  = &rkehci_pdata,\r
-    },\r
-};\r
-#endif\r
-\r
-static int __init usbdev_init_devices(void)\r
-{\r
-#ifdef CONFIG_USB_EHCI_RK\r
-       platform_device_register(&device_hsusb_host);\r
-#endif\r
-#ifdef CONFIG_USB20_OTG\r
-       platform_device_register(&device_usb20_otg);\r
-#endif\r
-#ifdef CONFIG_USB20_HOST\r
-       platform_device_register(&device_usb20_host);\r
-#endif\r
-    return 0;\r
-}\r
-arch_initcall(usbdev_init_devices);\r
-#endif\r
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of_gpio.h>
+#include <linux/gpio.h>
+#include "usbdev_rk.h"
+#include "dwc_otg_regs.h"
+
+static struct dwc_otg_control_usb *control_usb;
+
+int dwc_otg_check_dpdm(void)
+{
+       int bus_status = 0;
+       return bus_status;
+}
+
+EXPORT_SYMBOL(dwc_otg_check_dpdm);
+
+#ifdef CONFIG_USB20_OTG
+
+void usb20otg_hw_init(void)
+{
+#ifndef CONFIG_USB20_HOST
+       unsigned int * otg_phy_con1 = (control_usb->grf_uoc1_base + 0x8);
+       unsigned int * otg_phy_con2 = (control_usb->grf_uoc1_base + 0xc);
+       *otg_phy_con1 = (0x01<<2)|((0x01<<2)<<16);     //enable soft control
+       *otg_phy_con2 = 0x2A|(0x3F<<16);               // enter suspend
+#endif
+       /* usb phy config init
+        * usb phy enter usb mode */
+       unsigned int * otg_phy_con3 = (control_usb->grf_uoc0_base);
+       *otg_phy_con3 = (0x0300 << 16);
+
+       /* other haredware init,include:
+        * DRV_VBUS GPIO init */
+       gpio_direction_output(control_usb->otg_gpios->gpio, 0);
+}
+
+void usb20otg_phy_suspend(void* pdata, int suspend)
+{
+       struct dwc_otg_platform_data *usbpdata=pdata;
+       unsigned int * otg_phy_con1 = (control_usb->grf_uoc0_base + 0x8);
+       unsigned int * otg_phy_con2 = (control_usb->grf_uoc0_base + 0xc);
+
+       if(suspend){
+               *otg_phy_con1 = (0x01<<2)|((0x01<<2)<<16);      //enable soft control
+               *otg_phy_con2 = 0x2A|(0x3F<<16);                // enter suspend
+               usbpdata->phy_status = 1;
+       }else{
+               *otg_phy_con1 = ((0x01<<2)<<16);                // exit suspend.
+               usbpdata->phy_status = 0;
+       }
+}
+
+void usb20otg_soft_reset(void)
+{
+}
+
+void usb20otg_clock_init(void* pdata)
+{
+       /*
+       struct dwc_otg_platform_data *usbpdata=pdata;
+       struct clk* ahbclk,*phyclk;
+
+       ahbclk = devm_clk_get(usbpdata->dev, "hclk_otg0");
+       if (IS_ERR(ahbclk)) {
+               dev_err(usbpdata->dev, "Failed to get hclk_otg0\n");
+               return;
+       }
+
+       phyclk = devm_clk_get(usbpdata->dev, "otgphy0");
+       if (IS_ERR(phyclk)) {
+               dev_err(usbpdata->dev, "Failed to get otgphy0\n");
+               return;
+       }
+
+       usbpdata->phyclk = phyclk;
+       usbpdata->ahbclk = ahbclk;*/
+}
+
+void usb20otg_clock_enable(void* pdata, int enable)
+{
+       /*
+       struct dwc_otg_platform_data *usbpdata=pdata;
+
+       if(enable){
+               clk_prepare_enable(usbpdata->ahbclk);
+               clk_prepare_enable(usbpdata->phyclk);
+       }else{
+               clk_disable_unprepare(usbpdata->ahbclk);
+               clk_disable_unprepare(usbpdata->phyclk);
+       }
+       */
+}
+
+int usb20otg_get_status(int id)
+{
+       int ret = -1;
+       unsigned int usbgrf_status = *(unsigned int*)(control_usb->grf_soc_status0);
+
+       switch(id){
+               case USB_STATUS_BVABLID:
+                       // bvalid in grf
+                       ret = (usbgrf_status &(1<<10));
+                       break;
+               case USB_STATUS_DPDM:
+                       // dpdm in grf
+                       ret = (usbgrf_status &(3<<11));
+                       break;
+               case USB_STATUS_ID:
+                       // id in grf
+                       ret = (usbgrf_status &(1<<13));
+                       break;
+               default:
+                       break;
+       }
+
+       return ret;
+}
+
+#ifdef CONFIG_RK_USB_UART
+void dwc_otg_uart_mode(void* pdata, int enter_usb_uart_mode)
+{
+       unsigned int * otg_phy_con1 = (unsigned int*)(control_usb->grf_uoc0_base);
+
+       if(1 == enter_usb_uart_mode){
+               /* enter uart mode
+                * note: can't disable otg here! If otg disable, the ID change
+                * interrupt can't be triggered when otg cable connect without
+                * device.At the same time, uart can't be used normally
+                */
+               *otg_phy_con1 = (0x0300 | (0x0300 << 16));      //bypass dm
+       }else if(0 == enter_usb_uart_mode){
+               /* enter usb mode */
+               *otg_phy_con1 = (0x0300 << 16);                 //bypass dm disable
+       }
+}
+#endif
+
+void usb20otg_power_enable(int enable)
+{
+       if(0 == enable){//disable otg_drv power
+               gpio_set_value(control_usb->otg_gpios->gpio, 0);
+       }else if(1 == enable){//enable otg_drv power
+               gpio_set_value(control_usb->otg_gpios->gpio, 1);
+       }
+}
+
+struct dwc_otg_platform_data usb20otg_pdata = {
+       .phyclk = NULL,
+       .ahbclk = NULL,
+       .busclk = NULL,
+       .phy_status = 0,
+       .hw_init=usb20otg_hw_init,
+       .phy_suspend=usb20otg_phy_suspend,
+       .soft_reset=usb20otg_soft_reset,
+       .clock_init=usb20otg_clock_init,
+       .clock_enable=usb20otg_clock_enable,
+       .get_status=usb20otg_get_status,
+       .power_enable=usb20otg_power_enable,
+#ifdef CONFIG_RK_USB_UART
+       .dwc_otg_uart_mode=dwc_otg_uart_mode,
+#endif
+};
+
+#endif
+
+#ifdef CONFIG_USB20_HOST
+void usb20host_hw_init(void)
+{
+       /* usb phy config init */
+
+       /* other haredware init,include:
+        * DRV_VBUS GPIO init */
+       gpio_direction_output(control_usb->host_gpios->gpio, 1);
+
+}
+
+void usb20host_phy_suspend(void* pdata, int suspend)
+{
+       struct dwc_otg_platform_data *usbpdata=pdata;
+       unsigned int * otg_phy_con1 = (unsigned int*)(control_usb->grf_uoc1_base + 0x8);
+       unsigned int * otg_phy_con2 = (unsigned int*)(control_usb->grf_uoc1_base + 0xc);
+
+       if(suspend){
+               *otg_phy_con1 =  (0x01<<2)|((0x01<<2)<<16);     // enable soft control
+               *otg_phy_con2 =  0x2A|(0x3F<<16);               // enter suspend
+               usbpdata->phy_status = 1;
+       }else{
+               *otg_phy_con1 = ((0x01<<2)<<16);                // exit suspend.
+               usbpdata->phy_status = 0;
+       }
+}
+
+void usb20host_soft_reset(void)
+{
+}
+
+void usb20host_clock_init(void* pdata)
+{
+       /*
+       struct dwc_otg_platform_data *usbpdata=pdata;
+       struct clk* ahbclk,*phyclk;
+
+       ahbclk = devm_clk_get(usbpdata->dev, "hclk_otg1");
+       if (IS_ERR(ahbclk)) {
+               dev_err(usbpdata->dev, "Failed to get hclk_otg1\n");
+               return;
+       }
+
+       phyclk = devm_clk_get(usbpdata->dev, "otgphy1");
+       if (IS_ERR(phyclk)) {
+               dev_err(usbpdata->dev, "Failed to get otgphy1\n");
+               return;
+       }
+
+       usbpdata->phyclk = phyclk;
+       usbpdata->ahbclk = ahbclk;*/
+}
+
+void usb20host_clock_enable(void* pdata, int enable)
+{
+       /*
+       struct dwc_otg_platform_data *usbpdata=pdata;
+
+       if(enable){
+               clk_prepare_enable(usbpdata->ahbclk);
+               clk_prepare_enable(usbpdata->phyclk);
+       }else{
+               clk_disable_unprepare(usbpdata->ahbclk);
+               clk_disable_unprepare(usbpdata->phyclk);
+       }*/
+}
+
+int usb20host_get_status(int id)
+{
+       int ret = -1;
+       unsigned int usbgrf_status = *(unsigned int*)(control_usb->grf_soc_status0);
+
+       switch(id){
+               case USB_STATUS_BVABLID:
+                       // bvalid in grf
+                       ret = (usbgrf_status &(1<<17));
+                       break;
+               case USB_STATUS_DPDM:
+                       // dpdm in grf
+                       ret = (usbgrf_status &(3<<18));
+                       break;
+               case USB_STATUS_ID:
+                       // id in grf
+                       ret = (usbgrf_status &(1<<20));
+                       break;
+               default:
+                       break;
+       }
+
+       return ret;
+}
+
+void usb20host_power_enable(int enable)
+{
+       if(0 == enable){//disable host_drv power
+               //do not disable power in default
+       }else if(1 == enable){//enable host_drv power
+               gpio_set_value(control_usb->host_gpios->gpio, 1);
+       }
+}
+
+struct dwc_otg_platform_data usb20host_pdata = {
+       .phyclk = NULL,
+       .ahbclk = NULL,
+       .busclk = NULL,
+       .phy_status = 0,
+       .hw_init=usb20host_hw_init,
+       .phy_suspend=usb20host_phy_suspend,
+       .soft_reset=usb20host_soft_reset,
+       .clock_init=usb20host_clock_init,
+       .clock_enable=usb20host_clock_enable,
+       .get_status=usb20host_get_status,
+       .power_enable=usb20host_power_enable,
+};
+#endif
+
+static int dwc_otg_control_usb_probe(struct platform_device *pdev)
+{
+       struct resource *res;
+       int gpio, err;
+       struct device_node *np = pdev->dev.of_node;
+
+       control_usb = devm_kzalloc(&pdev->dev, sizeof(*control_usb),GFP_KERNEL);
+       if (!control_usb) {
+               dev_err(&pdev->dev, "unable to alloc memory for control usb\n");
+               return -ENOMEM;
+       }
+
+       res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+                                               "GRF_SOC_STATUS0");
+       control_usb->grf_soc_status0 = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(control_usb->grf_soc_status0))
+               return PTR_ERR(control_usb->grf_soc_status0);
+
+       res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+                                               "GRF_UOC0_BASE");
+       control_usb->grf_uoc0_base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(control_usb->grf_uoc0_base))
+               return PTR_ERR(control_usb->grf_uoc0_base);
+
+       res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+                                               "GRF_UOC1_BASE");
+       control_usb->grf_uoc1_base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(control_usb->grf_uoc1_base))
+               return PTR_ERR(control_usb->grf_uoc1_base);
+
+       control_usb->host_gpios = devm_kzalloc(&pdev->dev, sizeof(struct gpio), GFP_KERNEL);
+
+       gpio =  of_get_named_gpio(np, "gpios", 0);
+       if(!gpio_is_valid(gpio)){
+               dev_err(&pdev->dev, "invalid host gpio%d\n", gpio);
+               return -EINVAL;
+       }
+       control_usb->host_gpios->gpio = gpio;
+       err = devm_gpio_request(&pdev->dev, gpio, "host_drv_gpio");
+       if (err) {
+               dev_err(&pdev->dev,
+                       "failed to request GPIO%d for host_drv\n",
+                       gpio);
+               return err;
+       }
+
+       control_usb->otg_gpios = devm_kzalloc(&pdev->dev, sizeof(struct gpio), GFP_KERNEL);
+
+       gpio =  of_get_named_gpio(np, "gpios", 1);
+       if(!gpio_is_valid(gpio)){
+               dev_err(&pdev->dev, "invalid otg gpio%d\n", gpio);
+               return -EINVAL;
+       }
+       control_usb->otg_gpios->gpio = gpio;
+       err = devm_gpio_request(&pdev->dev, gpio, "otg_drv_gpio");
+       if (err) {
+               dev_err(&pdev->dev,
+                       "failed to request GPIO%d for otg_drv\n",
+                       gpio);
+               return err;
+       }
+
+       return 0;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id dwc_otg_control_usb_id_table[] = {
+       { .compatible = "rockchip,dwc-control-usb" },
+       {}
+};
+MODULE_DEVICE_TABLE(of, dwc_otg_control_usb_id_table);
+#endif
+
+static struct platform_driver dwc_otg_control_usb_driver = {
+       .probe          = dwc_otg_control_usb_probe,
+       .driver         = {
+               .name   = "dwc-control-usb",
+               .owner  = THIS_MODULE,
+               .of_match_table = of_match_ptr(dwc_otg_control_usb_id_table),
+       },
+};
+
+static int __init dwc_otg_control_usb_init(void)
+{
+       return platform_driver_register(&dwc_otg_control_usb_driver);
+}
+subsys_initcall(dwc_otg_control_usb_init);
+
+static void __exit dwc_otg_control_usb_exit(void)
+{
+       platform_driver_unregister(&dwc_otg_control_usb_driver);
+}
+
+module_exit(dwc_otg_control_usb_exit);
+MODULE_ALIAS("platform: dwc_control_usb");
+MODULE_AUTHOR("RockChip Inc.");
+MODULE_DESCRIPTION("RockChip Control Module USB Driver");
+MODULE_LICENSE("GPL v2");
index 04cbeb134814ae925beead5f9387bb8350dd4b38..6de842d6af97455320a6218db32ce090e2a9034d 100644 (file)
@@ -48,8 +48,8 @@ MODULE_VERSION("1.0");
 static const char longname[] = "Gadget Android";
 
 /* Default vendor and product IDs, overridden by userspace */
-#define VENDOR_ID              0x18D1
-#define PRODUCT_ID             0x0001
+#define VENDOR_ID              0x2207
+#define PRODUCT_ID             0x2910
 
 struct android_usb_function {
        char *name;
index 2dd57853de67360511a32946a93785165ebee46f..b331472cd307b659843d665eed35a2b3acf0cb29 100644 (file)
@@ -636,6 +636,9 @@ static int set_config(struct usb_composite_dev *cdev,
 
        cdev->config = c;
 
+       /* reset delay status to zero every time usb reconnect */
+       cdev->delayed_status = 0;
+
        /* Initialize all interfaces by setting them to altsetting zero. */
        for (tmp = 0; tmp < MAX_CONFIG_INTERFACES; tmp++) {
                struct usb_function     *f = c->interface[tmp];
@@ -1839,6 +1842,8 @@ void usb_composite_setup_continue(struct usb_composite_dev *cdev)
                        req->status = 0;
                        composite_setup_complete(cdev->gadget->ep0, req);
                }
+       }else{
+               WARN(cdev, "%s: Unexpected delayed status 0x%x\n", __func__, cdev->delayed_status);
        }
 
        spin_unlock_irqrestore(&cdev->lock, flags);