diff options
| author | Roman Yeryomin <roman@advem.lv> | 2013-05-17 20:40:24 +0300 |
|---|---|---|
| committer | Roman Yeryomin <roman@advem.lv> | 2013-05-17 20:40:24 +0300 |
| commit | e6d87036412b952cb083eff2dc716aee97a771f2 (patch) | |
| tree | 273dd3daaa85553832d3cc6d48276229dc7fbe09 /target/linux/realtek/files/drivers/usb/dwc_otg | |
| parent | a18fec42221baa52fff4c5ffd45ec8f32e3add36 (diff) | |
Move to rsdk 3.2.4. Compiles cleanly.
Signed-off-by: Roman Yeryomin <roman@advem.lv>
Diffstat (limited to 'target/linux/realtek/files/drivers/usb/dwc_otg')
12 files changed, 416 insertions, 100 deletions
diff --git a/target/linux/realtek/files/drivers/usb/dwc_otg/Kconfig b/target/linux/realtek/files/drivers/usb/dwc_otg/Kconfig index fe5415aab..93f2c3252 100644 --- a/target/linux/realtek/files/drivers/usb/dwc_otg/Kconfig +++ b/target/linux/realtek/files/drivers/usb/dwc_otg/Kconfig @@ -19,4 +19,67 @@ config DWC_OTG_DEVICE_ONLY config RTL_OTGCTRL bool "Enable Realtek usb auto_det control circuit" +config RTL_USB_OTG + bool + default y if DWC_OTG +config RTL_ULINKER_USB_SUPPORT + bool "Realtek Universal Linker USB support" + depends on DWC_OTG + #select COMPAT_NET_DEV_OPS + #select RTK_VLAN_SUPPORT + #select RTK_VLAN_NEW_FEATURE + #select SCSI + #select SCSI_PROC_FS + #select BLK_DEV_SD + #select SCSI_LOWLEVEL + #select USB_ANNOUNCE_NEW_DEVICES + #select USB_DEVICE_CLASS + #select USB_MON + #select USB_EHCI_HCD + #select USB_EHCI_ROOT_HUB_TT + #select USB_OHCI_HCD + #select USB_STORAGE + #select USB_GADGET + #select USB_GADGET_VBUS_DRAW="2" + #select USB_GADGET_SELECTED + #select USB_OTG_RTL8672 + #select USB_OTG_DEVICE_RTL8672 + #select USB_GADGET_DUALSPEED + #select USB_ETH + #select USB_ETH_RNDIS + #select USB + #select USB_DEBUG + #### power saving + #select ARCH_CPU_SLEEP + #select USB_FILE_STORAGE + +## for init wlan driver by echo proc +#config RTL_ULINKER_WLAN_DELAY_INIT +# bool +# default y if RTL_ULINKER_USB_SUPPORT + +## for mode switch +config RTL_ULINKER_GADGET + bool + default y if RTL_ULINKER_USB_SUPPORT + +## for echo mac address +config RTL_ULINKER_OTG_MACADDR + bool + default y if RTL_ULINKER_USB_SUPPORT + +## for domain name query +config RTL_ULINKER_DNS + bool + default y if RTL_ULINKER_USB_SUPPORT + +## for bridge shortcut +config RTL_ULINKER_BRSC + bool + default y if RTL_ULINKER_USB_SUPPORT + +## for bridge shortcut, rx tasklet +config RTL_ULINKER_BRSC_TASKLET + bool + default y if RTL_ULINKER_BRSC diff --git a/target/linux/realtek/files/drivers/usb/dwc_otg/Makefile b/target/linux/realtek/files/drivers/usb/dwc_otg/Makefile index 54140d00d..66ca363d3 100644 --- a/target/linux/realtek/files/drivers/usb/dwc_otg/Makefile +++ b/target/linux/realtek/files/drivers/usb/dwc_otg/Makefile @@ -27,9 +27,9 @@ dwc_otg-objs := dwc_otg_driver.o dwc_otg-objs += dwc_otg_cil.o dwc_otg_cil_intr.o -ifeq ($(CONFIG_USB_OTG_DEVICE_RTL8672),y) +#ifeq ($(CONFIG_USB_OTG_DEVICE_RTL8672),y) dwc_otg-objs += dwc_otg_pcd.o dwc_otg_pcd_intr.o -endif +#endif ifeq ($(CONFIG_USB),y) dwc_otg-objs += dwc_otg_hcd.o dwc_otg_hcd_intr.o dwc_otg_hcd_queue.o @@ -39,6 +39,7 @@ endif obj-y += lm.o #obj-y += dwc_otg.o -obj-y += rtk_otg_autodet.o +obj-$(CONFIG_RTL_OTGCTRL) += rtk_otg_autodet.o + clean: rm -rf *.o *.ko .*cmd *.mod.c .tmp_versions
\ No newline at end of file diff --git a/target/linux/realtek/files/drivers/usb/dwc_otg/dwc_otg_driver.c b/target/linux/realtek/files/drivers/usb/dwc_otg/dwc_otg_driver.c index 22321bd9c..d405e31e7 100644 --- a/target/linux/realtek/files/drivers/usb/dwc_otg/dwc_otg_driver.c +++ b/target/linux/realtek/files/drivers/usb/dwc_otg/dwc_otg_driver.c @@ -944,7 +944,7 @@ static struct lm_driver dwc_otg_driver = void dwc_otg_phy_write(unsigned char reg, unsigned char val) { - #define USB2_PHY_DELAY __delay(200) + #define USB2_PHY_DELAY __delay(1000) if((reg < 0xE0) || (reg > 0xF6) || ((reg>0xE7)&&(reg<0xF0))) { printk("DWC_OTG: Wrong register address: 0x%02x\n", reg); @@ -961,7 +961,7 @@ void dwc_otg_phy_write(unsigned char reg, unsigned char val) REG32(0xb8000090) = (val << 11) | tmp; USB2_PHY_DELAY; #endif - REG32(0xb8003314) = (val << 16) | tmp; USB2_PHY_DELAY; + //REG32(0xb8003314) = (val << 16) | tmp; USB2_PHY_DELAY; REG32(0xb8030034) = ((reg & 0x0F) << 16) | 0x00004002; USB2_PHY_DELAY; REG32(0xb8030034) = ((reg & 0x0F) << 16) | 0x00004000; USB2_PHY_DELAY; REG32(0xb8030034) = ((reg & 0x0F) << 16) | 0x00004002; USB2_PHY_DELAY; @@ -1090,12 +1090,24 @@ unsigned int Get_IDDIG_Level() Enable_AutoDetectionCircuit(int en) { #define SYS_OTG_CONTROL 0xb8000098 + #define SYS_PIN_MUX 0xb8000040 if(en==1) - { REG32(SYS_OTG_CONTROL) |= (1<<0); //active_otgctrl=1, enable elvis auto-det circuit + { + unsigned int r; + REG32(SYS_PIN_MUX) &= ~(0x7); //bit [2:0]=0 + + REG32(SYS_OTG_CONTROL) |= (1<<0); //active_otgctrl=1, enable elvis auto-det circuit + + r=REG32(SYS_OTG_CONTROL); + r = r &~((0xf<<6)|(0xf<<10)|(0x7<<14)); //clear + REG32(SYS_OTG_CONTROL) = r| (10<<6)|(10<<10)|(4<<14); //setting + + REG32(SYS_OTG_CONTROL) |= (1<<5); //OTGCMP_EN=1 REG32(SYS_OTG_CONTROL) |= (1<<1); //start } else { REG32(SYS_OTG_CONTROL) &= ~(1<<1); //stop + REG32(SYS_OTG_CONTROL) &= ~(1<<5); //OTGCMP_EN=0 REG32(SYS_OTG_CONTROL) &= ~(1<<0); //active_otgctrl=0 , disable elvis auto-det circuit } } @@ -1154,6 +1166,8 @@ int otg_reset_procedure(int mode) gHostMode=mode; if(gHostMode==1) Set_IDDIG_Level(1,0); // 1:device 0:host else Set_IDDIG_Level(1,1); // 1:device 0:host +#elif defined(CONFIG_RTL_ULINKER) + gHostMode=1-Get_IDDIG_Level(); #else //auto-det ckt decide iddig #if 0 //1: internal enable auto-det, Enable_AutoDetectionCircuit(1); @@ -1162,7 +1176,7 @@ int otg_reset_procedure(int mode) gHostMode=1-Get_IDDIG_Level(); #endif //---------------------------------------- -#if 0 // +#if 1 // Set_SelUSBPort(2); // pass 1: is one port, other value is 2port #else //dynamic get if(Get_SelUSBPort()==1) @@ -1181,8 +1195,25 @@ int otg_reset_procedure(int mode) #endif #if 1 + //USBPhyReset(0); //1: in reset, 0: working //PHYPatch(); //wei add + dwc_otg_phy_write(0xe0,0x99); //disconnect, work + dwc_otg_phy_write(0xe1,0xac); //disconnect, work + dwc_otg_phy_write(0xe2,0x98); //disconnect, work + dwc_otg_phy_write(0xe3,0xc1); //disconnect, work + dwc_otg_phy_write(0xe4,0x1); //disconnect, work + dwc_otg_phy_write(0xe5,0x89); //disconnect, work + dwc_otg_phy_write(0xe6,0x98); //disconnect, worki + dwc_otg_phy_write(0xe7,0x1d); //disconnect, work + dwc_otg_phy_write(0xf0,0xfc); //disconnect, work + dwc_otg_phy_write(0xf1,0x8c); //disconnect, work + dwc_otg_phy_write(0xf2,0x0); //disconnect, work + dwc_otg_phy_write(0xf3,0x11); //disconnect, work + dwc_otg_phy_write(0xf4,0xfb); //disconnect, work + dwc_otg_phy_write(0xf5,0xd2); //disconnect, + dwc_otg_phy_write(0xf6,0x0); //disconnect, work + dwc_otg_phy_write(0xe6,0xb8); //disconnect, work int i; for(i=0xe0;i<=0xe7; i++) @@ -1223,7 +1254,12 @@ int dwc_otg_driver_init(void) #if 1 //for 8196D printk("-------8196D OTG init \n"); // otg_proc_init(); + +#if defined(CONFIG_RTL_ULINKER) int rc=otg_reset_procedure(0); +#else + int rc=otg_reset_procedure(1); +#endif if(rc) { printk("OTG: reset procedure init fail \n"); return rc; @@ -1279,7 +1315,7 @@ int dwc_otg_driver_init(void) else { printk("PHY IS normal\n"); tmp = tmp & 0xFF00FF00; - REG32(0xb8003314) = tmp|0x00000038; USB2_PHY_DELAY; //write usb port0's phy reg 0xE7 to change vbusvalid threshold down to 3.3V +// REG32(0xb8003314) = tmp|0x00000038; USB2_PHY_DELAY; //write usb port0's phy reg 0xE7 to change vbusvalid threshold down to 3.3V REG32(0xb80210A4) = 0x00370000; USB2_PHY_DELAY; REG32(0xb80210A4) = 0x00270000; USB2_PHY_DELAY; REG32(0xb80210A4) = 0x00370000; USB2_PHY_DELAY; @@ -1322,6 +1358,9 @@ int dwc_otg_driver_init(void) printf("PHY reg F1=%x\n", dwc_otg_phy_read(0xF1)); printf("PHY reg F2=%x\n", dwc_otg_phy_read(0xF2)); #endif + //Enhance USB 3.0 IOT issues + dwc_otg_phy_write(0xE2, 0x99); + dwc_otg_phy_write(0xE6, 0xc8); #if DRIVER_USING_LM //cathy, allocate a lmdev device for driver @@ -1335,8 +1374,10 @@ int dwc_otg_driver_init(void) lmdev->resource.start = OTG_BASE; //base of OTG, 0xb8030000 lmdev->resource.end = lmdev->resource.start + 0x0003ffff; lmdev->resource.flags = IORESOURCE_MEM; -#define USB_D_IRQ 11 //wei add ,11 - lmdev->irq = USB_D_IRQ; //irq of usb device +//#define USB_D_IRQ 11 //wei add ,11 +// lmdev->irq = USB_D_IRQ; //irq of usb device + lmdev->irq = BSP_OTG_IRQ; //irq of usb device + lmdev->id = 0; lm_device_register(lmdev); @@ -1391,7 +1432,7 @@ int dwc_otg_driver_init(void) return retval; } -#ifndef CONFIG_RTL_OTGCTRL +#if !defined(CONFIG_RTL_OTGCTRL) && !defined(CONFIG_RTL_ULINKER) module_init(dwc_otg_driver_init); #endif @@ -1429,7 +1470,7 @@ void dwc_otg_driver_cleanup(void) clear_bit(OTG_DRIVER_LOADED, &otg_driver_loaded); } -#ifndef CONFIG_RTL_OTGCTRL +#if !defined(CONFIG_RTL_OTGCTRL) && !defined(CONFIG_RTL_ULINKER) module_exit(dwc_otg_driver_cleanup); #endif diff --git a/target/linux/realtek/files/drivers/usb/dwc_otg/dwc_otg_driver.h b/target/linux/realtek/files/drivers/usb/dwc_otg/dwc_otg_driver.h index 33182611a..1aad97ea9 100644 --- a/target/linux/realtek/files/drivers/usb/dwc_otg/dwc_otg_driver.h +++ b/target/linux/realtek/files/drivers/usb/dwc_otg/dwc_otg_driver.h @@ -50,7 +50,7 @@ struct dwc_otg_hcd; * This structure is a wrapper that encapsulates the driver components used to * manage a single DWC_otg controller. */ - +#define IOT_ENHANCED_USB 1//JASON_PATCH 1 #define DRIVER_USING_LM 1 typedef struct dwc_otg_device diff --git a/target/linux/realtek/files/drivers/usb/dwc_otg/dwc_otg_hcd.c b/target/linux/realtek/files/drivers/usb/dwc_otg/dwc_otg_hcd.c index 412da41e1..6f8b59a49 100644 --- a/target/linux/realtek/files/drivers/usb/dwc_otg/dwc_otg_hcd.c +++ b/target/linux/realtek/files/drivers/usb/dwc_otg/dwc_otg_hcd.c @@ -89,6 +89,38 @@ static const struct hc_driver dwc_otg_hc_driver = { }; +#if 0//def RTL8672_OTG_ROOT_HUB_SPEED_SWITCH +#include <linux/usb_ch9.h> + +#ifdef CONFIG_USB_RTL8187SU_SOFTAP +void hcd_reinit(dwc_otg_hcd_t *_hcd); +#else +static void hcd_reinit(dwc_otg_hcd_t *_hcd); +#endif + +static void dwc_otg_hcd_speed_switch(dwc_otg_hcd_t *hcd, int speed) +{ + hprt0_data_t hprt0; + + /* speed is not different from before */ + if(hcd->core_if->core_params->speed == speed) + return; + + hcd->core_if->core_params->speed = speed; + + /* turn off port power */ + hprt0.d32 = dwc_otg_read_hprt0(hcd->core_if); + hprt0.b.prtpwr = 0; + dwc_write_reg32(hcd->core_if->host_if->hprt0, hprt0.d32); + + /* reinit otg and hcd */ + dwc_otg_core_init(hcd->core_if); + dwc_otg_enable_global_interrupts(hcd->core_if); + hcd_reinit(hcd); + + return; +} +#endif /** @@ -364,7 +396,7 @@ static int32_t dwc_otg_hcd_disconnect_cb( void *_p ) * longer a B-host. */ ((struct usb_hcd *)_p)->self.is_b_host = 0; -#if 0 //cathy have +#if 1 //cathy have dwc_otg_hcd->disconn_cnt++; if(!timer_pending(&dwc_otg_hcd->disconn_cnt_timer)) mod_timer(&dwc_otg_hcd->disconn_cnt_timer, jiffies+200); @@ -892,7 +924,7 @@ void dwc_otg_hcd_stop(struct usb_hcd *_hcd) /** Returns the current frame number. */ int dwc_otg_hcd_get_frame_number(struct usb_hcd *_hcd) { - printk("%s \n", __FUNCTION__); + //printk("%s \n", __FUNCTION__); dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(_hcd); hfnum_data_t hfnum; @@ -1093,8 +1125,10 @@ int dwc_otg_hcd_urb_dequeue(struct usb_hcd *_hcd, { unsigned long flags; dwc_otg_hcd_t *dwc_otg_hcd; - dwc_otg_qtd_t *urb_qtd; + dwc_otg_qtd_t *urb_qtd = NULL; dwc_otg_qh_t *qh; + struct list_head *qtd_item; +int retval = 0; struct usb_host_endpoint *_ep = dwc_urb_to_endpoint(_urb); @@ -1106,6 +1140,32 @@ int dwc_otg_hcd_urb_dequeue(struct usb_hcd *_hcd, urb_qtd = (dwc_otg_qtd_t *)_urb->hcpriv; qh = (dwc_otg_qh_t *)_ep->hcpriv; +#ifdef IOT_ENHANCED_USB //JASON_PATCH + + if(NULL == qh) { + printk("<%s %d> qh is NULL !\n", __func__, __LINE__); + retval = -1; + goto done; + //return -1; + } + for (qtd_item = qh->qtd_list.next; + qtd_item != &qh->qtd_list; + qtd_item = qtd_item->next) { + urb_qtd = list_entry(qtd_item, dwc_otg_qtd_t, qtd_list_entry); + if (urb_qtd->urb == _urb) { + break; + } + } + if((NULL == urb_qtd) || (urb_qtd->urb!=_urb)) { + printk("<%s %d> urb_qtd=%p, urb_qtd->urb=%p, _urb=%p\n", __func__, __LINE__, urb_qtd, urb_qtd ? urb_qtd->urb : 0, _urb); + retval = -1; + goto done; + //return -1; + } + + +#endif + #ifdef DEBUG if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) { dump_urb_info(_urb, "dwc_otg_hcd_urb_dequeue"); @@ -1144,18 +1204,20 @@ int dwc_otg_hcd_urb_dequeue(struct usb_hcd *_hcd, dwc_otg_hcd_qh_remove(dwc_otg_hcd, qh); } +done: + local_irq_restore(flags); _urb->hcpriv = NULL; /* Higher layer software sets URB status. */ - usb_hcd_giveback_urb(_hcd, _urb, 0); + usb_hcd_giveback_urb(_hcd, _urb, status); if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) { DWC_PRINT("Called usb_hcd_giveback_urb()\n"); DWC_PRINT(" urb->status = %d\n", _urb->status); } - return 0; + return retval; } @@ -1762,7 +1824,8 @@ static void do_in_ack(void) //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32); } #endif /* DWC_HS_ELECT_TST */ - +#define REG32(reg) (*(volatile unsigned int *)((unsigned int)reg)) +extern Enable_OTG_Suspend(int sel, int en); //sel=0 src from sys, then see en, sel=1, src from otg mac, /** Handles hub class-specific requests.*/ int dwc_otg_hcd_hub_control(struct usb_hcd *_hcd, u16 _typeReq, @@ -1986,6 +2049,22 @@ int dwc_otg_hcd_hub_control(struct usb_hcd *_hcd, } switch (_wValue) { +#ifdef IOT_ENHANCED_USB //JASON_PATCH +#if 0//def RTL8672_OTG_ROOT_HUB_SPEED_SWITCH + case USB_PORT_FEAT_LOWSPEED: + // DWC_DEBUGPL("DWC OTG HCD HUB CONTROL - " +// "SetPortFeature - USB_PORT_FEAT_LOWSPEED\n"); + //switch root hub to full speed + dwc_otg_hcd_speed_switch(dwc_otg_hcd, DWC_SPEED_PARAM_FULL); + break; + case USB_PORT_FEAT_HIGHSPEED: +// DWC_DEBUGPL("DWC OTG HCD HUB CONTROL - " +// "SetPortFeature - USB_PORT_FEAT_HIGHSPEED\n"); + //switch root hub to high speed + dwc_otg_hcd_speed_switch(dwc_otg_hcd, DWC_SPEED_PARAM_HIGH); + break; +#endif +#endif case USB_PORT_FEAT_SUSPEND: DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - " "SetPortFeature - USB_PORT_FEAT_SUSPEND\n"); @@ -2030,13 +2109,19 @@ int dwc_otg_hcd_hub_control(struct usb_hcd *_hcd, * the reset is started within 1ms of the HNP * success interrupt. */ if (!_hcd->self.is_b_host) { - hprt0.b.prtrst = 1; - dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32); + MDELAY (1); + hprt0.b.prtrst = 1; + hprt0.b.prtena=1; + dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32); + MDELAY (500); } /* Clear reset bit in 10ms (FS/LS) or 50ms (HS) */ MDELAY (60); + Enable_OTG_Suspend(0,0); hprt0.b.prtrst = 0; + hprt0.b.prtena=0; dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32); + MDELAY (500); break; #ifdef DWC_HS_ELECT_TST @@ -2794,7 +2879,7 @@ void dwc_otg_hcd_complete_urb(dwc_otg_hcd_t *_hcd, struct urb *_urb, int _status _urb->status = _status; _urb->hcpriv = NULL; - usb_hcd_giveback_urb(dwc_otg_hcd_to_hcd(_hcd), _urb, 0); + usb_hcd_giveback_urb(dwc_otg_hcd_to_hcd(_hcd), _urb, _status); } /* diff --git a/target/linux/realtek/files/drivers/usb/dwc_otg/dwc_otg_hcd_intr.c b/target/linux/realtek/files/drivers/usb/dwc_otg/dwc_otg_hcd_intr.c index 755f21bbb..dd2b06613 100644 --- a/target/linux/realtek/files/drivers/usb/dwc_otg/dwc_otg_hcd_intr.c +++ b/target/linux/realtek/files/drivers/usb/dwc_otg/dwc_otg_hcd_intr.c @@ -700,6 +700,9 @@ update_isoc_urb_state(dwc_otg_hcd_t *_hcd, frame_desc->actual_length = get_actual_xfer_length(_hc, _hc_regs, _qtd, _halt_status, NULL); + + urb->actual_length+=frame_desc->actual_length ; //avoid interrupt endpoint issue for web cam + break; case DWC_OTG_HC_XFER_FRAME_OVERRUN: urb->error_count++; diff --git a/target/linux/realtek/files/drivers/usb/dwc_otg/dwc_otg_hcd_queue.c b/target/linux/realtek/files/drivers/usb/dwc_otg/dwc_otg_hcd_queue.c index 779cd0583..d8d831043 100644 --- a/target/linux/realtek/files/drivers/usb/dwc_otg/dwc_otg_hcd_queue.c +++ b/target/linux/realtek/files/drivers/usb/dwc_otg/dwc_otg_hcd_queue.c @@ -147,7 +147,7 @@ void dwc_otg_hcd_qh_init(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh, struct urb *_ur /* FS/LS Enpoint on HS Hub * NOT virtual root hub */ _qh->do_split = 0; -#if 0 +#if 1 if (_urb->dev->speed == USB_SPEED_LOW || _urb->dev->speed == USB_SPEED_FULL) { if (_urb->dev->tt != NULL @@ -284,12 +284,12 @@ static int check_periodic_bandwidth(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh) status = 0; - if (_hcd->core_if->core_params->speed == DWC_SPEED_PARAM_HIGH) { + if ((_hcd->core_if->core_params->speed == DWC_SPEED_PARAM_HIGH)||_qh->do_split) { /* * High speed mode. * Max periodic usecs is 80% x 125 usec = 100 usec. */ - max_claimed_usecs = 100 - _qh->usecs; + max_claimed_usecs = 900 - _qh->usecs; } else { /* * Full speed mode. diff --git a/target/linux/realtek/files/drivers/usb/dwc_otg/dwc_otg_pcd.c b/target/linux/realtek/files/drivers/usb/dwc_otg/dwc_otg_pcd.c index 96cb50296..0f611789e 100644 --- a/target/linux/realtek/files/drivers/usb/dwc_otg/dwc_otg_pcd.c +++ b/target/linux/realtek/files/drivers/usb/dwc_otg/dwc_otg_pcd.c @@ -79,7 +79,15 @@ #include "dwc_otg_driver.h" #include "dwc_otg_pcd.h" +#ifdef CONFIG_RTL_USB_OTG +#include "otg_dbg.h" +enum { + RTL_GADGET_FSG, + RTL_GADGET_ETH, +}; +extern int rtl_otg_gadget; +#endif /** * Static PCD pointer for use in usb_gadget_register_driver and @@ -1597,10 +1605,19 @@ int dwc_otg_pcd_init(struct lm_device *_lmdev) #if 0 //wei add for bind gadget usb_gadget_register_driver( pcd->driver); //wei add #else - extern int eth_reg_again(); - int ret=eth_reg_again(); - if(ret!=0) printk("gadget register rc=%d\n", ret); -#endif + #if defined(CONFIG_RTL_ULINKER) + if (rtl_otg_gadget == RTL_GADGET_FSG) { + extern int fsg_reg_again(); + int ret=fsg_reg_again(); + if(ret!=0) printk("gadget register rc=%d\n", ret); + } + else { + extern int eth_reg_again(); + int ret=eth_reg_again(); + if(ret!=0) printk("gadget register rc=%d\n", ret); + } + #endif + #endif /* @@ -1698,8 +1715,16 @@ void dwc_otg_pcd_remove( struct lm_device *_lmdev ) #if 0 // for un-bind gadget usb_gadget_unregister_driver( pcd->driver); #else - extern int eth_unreg_again(); - eth_unreg_again(); + #if defined(CONFIG_RTL_ULINKER_GADGET) + if (rtl_otg_gadget == RTL_GADGET_FSG) { + extern int fsg_unreg_again(); + fsg_unreg_again(); + } + else { + extern int eth_unreg_again(); + eth_unreg_again(); + } + #endif #endif } @@ -1736,11 +1761,13 @@ int usb_gadget_register_driver(struct usb_gadget_driver *_driver) DWC_DEBUGPL(DBG_PCD, "registering gadget driver '%s'\n", _driver->driver.name); - if (!_driver || _driver->speed == USB_SPEED_UNKNOWN || - !_driver->bind || - !_driver->unbind || +#ifdef IOT_ENHANCED_USB //JASON_PATCH + if (!_driver || + _driver->speed == USB_SPEED_UNKNOWN || !_driver->disconnect || !_driver->setup) + +#endif { DWC_DEBUGPL(DBG_PCDV,"EINVAL\n"); return -EINVAL; @@ -1762,6 +1789,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *_driver) DWC_DEBUGPL(DBG_PCD, "bind to driver %s\n", _driver->driver.name); retval = _driver->bind(&s_pcd->gadget); + if (retval) { DWC_ERROR("bind to driver %s --> error %d\n", diff --git a/target/linux/realtek/files/drivers/usb/dwc_otg/dwc_otg_pcd_intr.c b/target/linux/realtek/files/drivers/usb/dwc_otg/dwc_otg_pcd_intr.c index 7123a9e77..42d9ca523 100644 --- a/target/linux/realtek/files/drivers/usb/dwc_otg/dwc_otg_pcd_intr.c +++ b/target/linux/realtek/files/drivers/usb/dwc_otg/dwc_otg_pcd_intr.c @@ -37,6 +37,10 @@ #include "dwc_otg_pcd.h" #include <linux/usb/cdc.h> +#if 1//defined(CONFIG_RTL_ULINKER_BRSC) +#include "linux/ulinker_brsc.h" +#endif + #define DEBUG_EP0 /* request functions defined in "dwc_otg_pcd.c" */ @@ -753,7 +757,13 @@ int32_t dwc_otg_pcd_handle_usb_reset_intr( dwc_otg_pcd_t * _pcd) dctl_data_t dctl = {.d32=0}; int i = 0; gintsts_data_t gintsts; - + +#if defined(CONFIG_RTL_ULINKER) + extern unsigned long rst_jiffies; + rst_jiffies = jiffies; + BDBG_GADGET_MODE_SWITCH("[%s:%d] rst_jiffies[%lu]\n", __FUNCTION__, __LINE__, rst_jiffies); +#endif + DWC_PRINT("USB RESET\n"); /* reset the HNP settings */ @@ -1808,12 +1818,14 @@ static void complete_ep( dwc_otg_pcd_ep_t *_ep ) if (deptsiz.b.xfersize == 0 && deptsiz.b.pktcnt == 0 && _ep->dwc_ep.xfer_count == _ep->dwc_ep.xfer_len) { + #if !defined(CONFIG_RTL_ULINKER) //only support zlp on endpoint 1 (bulk in) if((_ep->dwc_ep.num == 1) && !_ep->dwc_ep.sent_zlp && !(_ep->dwc_ep.xfer_len & (_ep->dwc_ep.maxpacket-1))){ _ep->dwc_ep.sent_zlp = 1; is_last = ep_in_zlp(_ep); } else + #endif is_last = 1; } @@ -2311,7 +2323,7 @@ do { \ ep1xferincomplete--; } else { //cathy, ep3, to fix ep3 wrong fifo pointer problem - dwc_otg_flush_tx_fifo(core_if, 1); + //dwc_otg_flush_tx_fifo(core_if, 1); } complete_ep( ep ); } @@ -2664,6 +2676,12 @@ int32_t dwc_otg_pcd_handle_out_nak_effective( dwc_otg_pcd_t *_pcd ) * All interrupt registers are processed from LSB to MSB. * */ +#if defined(CONFIG_RTL_ULINKER) +int fsg_init_once = 0; +#endif +#if ULINKER_BRSC_RECOVER_TX_REQ +dwc_otg_pcd_t *my_pcd = NULL; +#endif int32_t dwc_otg_pcd_handle_intr( dwc_otg_pcd_t *_pcd ) { dwc_otg_core_if_t *core_if = GET_CORE_IF(_pcd); @@ -2674,6 +2692,13 @@ int32_t dwc_otg_pcd_handle_intr( dwc_otg_pcd_t *_pcd ) gintsts_data_t gintr_status; int32_t retval = 0; +#if ULINKER_BRSC_RECOVER_TX_REQ + if (my_pcd == NULL) + my_pcd = _pcd; + else if (my_pcd != _pcd) { + printk("\n\t\t[%s:%d] my_pcd != _pcd\n\n", __FUNCTION__, __LINE__); + } +#endif #ifdef VERBOSE DWC_DEBUGPL(DBG_ANY, "%s() gintsts=%08x gintmsk=%08x\n", @@ -2695,6 +2720,7 @@ int32_t dwc_otg_pcd_handle_intr( dwc_otg_pcd_t *_pcd ) gintr_status.d32 = dwc_otg_read_core_intr(core_if); if (!gintr_status.d32) { + SPIN_UNLOCK(&_pcd->lock); return 0; } //printk("---2-------------------------\n"); @@ -2774,4 +2800,44 @@ int32_t dwc_otg_pcd_handle_intr( dwc_otg_pcd_t *_pcd ) return retval; } +#if ULINKER_BRSC_RECOVER_TX_REQ +int early_tx_complete (void) +{ + int32_t retval = 0; + int inepint = 0; + + gintsts_data_t gintr_status; + dwc_otg_core_global_regs_t *global_regs = + my_pcd->otg_dev->core_if->core_global_regs; + + gintr_status.d32 = dwc_read_reg32( &global_regs->gintsts) & + dwc_read_reg32( &global_regs->gintmsk); + + if (!gintr_status.d32) + { + BRSC_COUNTER_UPDATE(otg_status_fail); + return 0; + } + + if (gintr_status.b.inepint) + { + BRSC_COUNTER_UPDATE(otg_inepint); + inepint = 1; + retval |= dwc_otg_pcd_handle_in_ep_intr( my_pcd ); + } + if (gintr_status.b.outepintr) + { + BRSC_COUNTER_UPDATE(otg_outepintr); + retval |= dwc_otg_pcd_handle_out_ep_intr( my_pcd ); + } + + if (inepint) + retval = 11; + + return retval; +} +#endif /* #if ULINKER_BRSC_RECOVER_TX_REQ */ + + + #endif /* DWC_HOST_ONLY */ diff --git a/target/linux/realtek/files/drivers/usb/dwc_otg/dwc_otg_plat.h b/target/linux/realtek/files/drivers/usb/dwc_otg/dwc_otg_plat.h index f40779365..a84d49e5c 100644 --- a/target/linux/realtek/files/drivers/usb/dwc_otg/dwc_otg_plat.h +++ b/target/linux/realtek/files/drivers/usb/dwc_otg/dwc_otg_plat.h @@ -230,7 +230,7 @@ static inline uint32_t SET_DEBUG_LEVEL( const uint32_t _new ) * </code> */ //#define DEBUG -#if 1 //def DEBUG +#if CONFIG_DWC_OTG_DEBUG //def DEBUG #if 0 //#define DWC_DEBUGPL(lvl, x...) do{ if ((lvl)&g_dbg_lvl)printk( KERN_DEBUG USB_DWC x ); }while(0) diff --git a/target/linux/realtek/files/drivers/usb/dwc_otg/rtk_otg_autodet.c b/target/linux/realtek/files/drivers/usb/dwc_otg/rtk_otg_autodet.c index ace88c33f..a71b8e1c8 100644 --- a/target/linux/realtek/files/drivers/usb/dwc_otg/rtk_otg_autodet.c +++ b/target/linux/realtek/files/drivers/usb/dwc_otg/rtk_otg_autodet.c @@ -6,22 +6,38 @@ void dump_autodet_reg() { #define GETBITVAL(v,bit) ((v&(1<<bit))>>bit) - unsigned int val=REG32(0xb8000098) ; //auto_det_ctrl + unsigned int val=REG32(SYS_OTG_CONTROL) ; //auto_det_ctrl printk("Otg_Ctrl_Reg=%x \n", val); int force=GETBITVAL(val,2); - printk(" b02 [I] Otg_Mux_Sel=%x, %s mode \n", GETBITVAL(val,2), force? "Force": "Auto" ); + printk(" b02 [I] Otg_Mux_Sel=%x, %s mode \n", force, force? "Force": "Auto" ); printk(" b19 [I] Vbus_On=%x \n", GETBITVAL(val,19)); printk(" b20 [I] PJ_On=%x \n", GETBITVAL(val,20)); printk(" b21 [I] PJ_Toggle=%x \n", GETBITVAL(val,21)); - printk(" b22 [I] Device_Connect=%x \n", GETBITVAL(val,22)); - printk(" b23 [I] Host_Disconnect=%x \n", GETBITVAL(val,23)); + printk(" b22 [I] Phy Device_Connect=%x \n", GETBITVAL(val,22)); + printk(" b23 [I] Phy Host_Disconnect=%x \n", GETBITVAL(val,23)); + + int connect_sel=GETBITVAL(val,17); + printk(" b17 [I] OTG Connect Sel=%x, From Phy %s \n", connect_sel, connect_sel?"NOT DisConnect":"Connect" ); printk(" b24 [O] Pow_PJ_On=%x \n", GETBITVAL(val,24)); printk(" b25 [O] Pow_VB_On=%x \n", GETBITVAL(val,25)); if(force) - printk(" b03 [I] Otg_force_dev=%x \n", GETBITVAL(val,3)); - printk(" b18 [O] Otg_cfg_dev_r=%x \n", GETBITVAL(val,18)); + printk(" b03 [I] Otg_force_dev=%x, force use \n", GETBITVAL(val,3)); + printk(" b18 [O] Otg_cfg_dev_r=%x, auto use \n", GETBITVAL(val,18)); + + + #define GET_MVAL(v,bitpos,pat) ((v& ((unsigned int)pat<<bitpos))>>bitpos) + #define RANG1 1 + #define RANG2 3 + #define RANG3 7 + #define RANG4 0xf + printk(" b05 OTGCMP_EN=%x \n", GET_MVAL(val,5, RANG1)); + printk(" b09:06 Vref_L=%x\n", GET_MVAL(val,6, RANG4)); + printk(" b13:10 Vref_H=%x\n", GET_MVAL(val,10, RANG4)); + printk(" b16:14 Vbus_th=%x \n", GET_MVAL(val,14, RANG3)); + + printk("\n"); } @@ -45,11 +61,17 @@ void USBPHY_CHIP_Active(int portnum, int active) //1: in reset, 0: working #define SYS_USB_PHY 0xb8000090 if(portnum==0) { if(active==0) REG32(SYS_USB_PHY) &= ~(1<<10); //usbphy_reset=0 - else REG32(SYS_USB_PHY) |= (1<<10); //usbphy_reset=1 + else + { REG32(SYS_USB_PHY) |= (1<<8); //usbphy_en=1 + REG32(SYS_USB_PHY) |= (1<<10); //usbphy_reset=1 + } } else if(portnum==1) { if(active==0) REG32(SYS_USB_PHY) &= ~(1<<21); //usbphy_reset=0 - else REG32(SYS_USB_PHY) |= (1<<21); //usbphy_reset=1 + else + { REG32(SYS_USB_PHY) |= (1<<19); //usbphy_en=1 + REG32(SYS_USB_PHY) |= (1<<21); //usbphy_reset=1 + } } } @@ -200,21 +222,30 @@ int otg_proc_write_procmem(struct file *file, const char *buf, unsigned long cou else if (!strcmp(tmp, "dump otg")) - { extern int gHostMode; + { + + extern int gHostMode; printk("gHostMode=%d\n", gHostMode); + + extern unsigned long otg_driver_loaded; + printk("otg_driver_loaded=%d\n", otg_driver_loaded); + +#if 0 extern struct lm_device *glmdev; //wei add struct lm_device *pdev=glmdev; printk("glmdev=%x\n", pdev); dwc_otg_device_t *otg_dev = platform_get_drvdata(pdev); printk("otg_dev=%x\n", otg_dev); + /* dwc_otg_hcd_t *dwc_otg_hcd = otg_dev->hcd; printk("dwc_otg_hcd=%x\n",dwc_otg_hcd ); struct usb_hcd *hcd = dwc_otg_hcd_to_hcd(dwc_otg_hcd); printk("hcd=%x\n",jcd ); */ - +#endif } + else if (!strcmp(tmp, "dump otgctrl")) { dump_autodet_reg(); @@ -229,7 +260,7 @@ int otg_proc_write_procmem(struct file *file, const char *buf, unsigned long cou // printk("gad <0|1 >! \n"); printk("otg <0|1> \n"); printk("ehci <0|1> \n"); - printk("port <0|1> \n"); + printk("port <0|1|?> \n"); printk("autodet <0|1> \n"); printk("idpin <0|1> \n"); @@ -308,7 +339,7 @@ static void otg_timer_isr(unsigned long data) static void otgctrl_work_func(struct work_struct *work) //static void otg_timer_isr(unsigned long data) { - //TurnOn_OTGCtrl_Interrupt(0); + int old=TurnOn_OTGCtrl_Interrupt(0); dump_autodet_reg(); @@ -318,7 +349,7 @@ static void otgctrl_work_func(struct work_struct *work) unsigned int v=(priv->curr_val) ; -#if 0 //see idpin result +#if 0 //software only see idpin result //plugin: PC-> usb disk if( ( (v&OTGCTRL_CFG_DEV_R)==0) && @@ -375,49 +406,43 @@ static void otgctrl_work_func(struct work_struct *work) priv->nFirst=1; } #endif -#if 1 +#if 1 //software decide the state machine if(v&OTGCTRL_PJ_ON) { //connect=1 //if( (v&OTGCTRL_DEVICE_CONNECT) &&(priv->mode==0)) if( ((v&OTGCTRL_DEVICE_DISCONNECT)==0) &&(priv->mode==0) ) { - //change port - //USBPHY_CHIP_Active(1,0); - //USBPHY_UTMI_Reset(1, 1); - - //USBPHY_CHIP_Active(1,1); - //USBPHY_UTMI_Reset(1, 0); - - // - int old=TurnOn_OTGCtrl_Interrupt(0); - #if P1_HOST_USING_EHCI //EHCI - Set_SelUSBPort(1); - ehci_hcd_init(); - ohci_hcd_mod_init(); - #else - dwc_otg_driver_init(); - #endif - priv->mode=1; - TurnOn_OTGCtrl_Interrupt(old); + //change port + //USBPHY_CHIP_Active(1,0); + //USBPHY_UTMI_Reset(1, 1); + + //USBPHY_CHIP_Active(1,1); + //USBPHY_UTMI_Reset(1, 0); + + printk("OTGCTRL: PJ on, Det device plugin\n"); + + #if P1_HOST_USING_EHCI //EHCI + Set_SelUSBPort(1); + ehci_hcd_init(); + ohci_hcd_mod_init(); + #else + dwc_otg_driver_init(); + #endif + priv->mode=1; } //dis-connect=1 else if( (v&OTGCTRL_DEVICE_DISCONNECT) && (priv->mode==1) ) { - #if P1_HOST_USING_EHCI - ehci_hcd_cleanup(); - //ohci_hcd_mod_exit(); - #else - dwc_otg_driver_cleanup(); - #endif -/* - USBPHY_CHIP_Active(1, 0); - USBPHY_CHIP_Active(1, 1); - USBPHY_UTMI_Reset(1, 1); - USBPHY_UTMI_Reset(1, 0); -*/ + #if P1_HOST_USING_EHCI + ehci_hcd_cleanup(); + //ohci_hcd_mod_exit(); + #else + dwc_otg_driver_cleanup(); + #endif + priv->mode=0; } @@ -425,7 +450,7 @@ static void otgctrl_work_func(struct work_struct *work) else if( (v&OTGCTRL_DEVICE_DISCONNECT) && (priv->mode==0) &&(v&OTGCTRL_VBUS_ON) ) { Set_SelUSBPort(0); - printk("Vbus on, Det host plugin\n"); + printk("OTGCTRL: Vbus on, Det host plugin\n"); priv->mode=3; dwc_otg_driver_init(); @@ -444,7 +469,7 @@ static void otgctrl_work_func(struct work_struct *work) if( ((v&OTGCTRL_DEVICE_DISCONNECT)==0) &&(priv->mode==0) ) { Set_SelUSBPort(0); - printk("Vbus on, Det Device plugin\n"); + printk("OTGCTRL: Vbus on, Det Device plugin\n"); priv->mode=4; dwc_otg_driver_init(); @@ -456,10 +481,10 @@ static void otgctrl_work_func(struct work_struct *work) } //--------------- - else if( ((v&OTGCTRL_DEVICE_DISCONNECT)==0) &&(priv->mode==0) ) + else if( (v&OTGCTRL_DEVICE_DISCONNECT) &&(priv->mode==0) ) { Set_SelUSBPort(0); - printk("Vbus on, Det host plugin\n"); + printk("OTGCTRL: Vbus on, Det host plugin\n"); priv->mode=5; dwc_otg_driver_init(); @@ -472,6 +497,8 @@ static void otgctrl_work_func(struct work_struct *work) } } #endif + + TurnOn_OTGCtrl_Interrupt(old); } //-------------------------------------------------------------------------------------------- @@ -484,7 +511,7 @@ static irqreturn_t otg_ctrl_irq(int _irq, void *_dev) //printk("0xb8003000=%x \n", REG32(0xb8003000) ); //dump_autodet_reg(); - unsigned int v=REG32(0xb8000098); + unsigned int v=REG32(SYS_OTG_CONTROL); //if(v&OTGCTRL_DEVICE_CONNECT) { @@ -499,7 +526,7 @@ static irqreturn_t otg_ctrl_irq(int _irq, void *_dev) //schedule_work(&otgctrl_work.start_work); PREPARE_DELAYED_WORK(&otgctrl_work.start_work, otgctrl_work_func); - schedule_delayed_work(&otgctrl_work.start_work, 50); + schedule_delayed_work(&otgctrl_work.start_work, 100); @@ -537,15 +564,14 @@ struct device gUSB1CtrlDev; //-------------------------------------------------------------------------------------------- void otg_ctrl_init(void) { - + Enable_AutoDetectionCircuit(0); + //wei add for test - struct proc_dir_entry *entry=create_proc_entry("otg", 0, NULL); - if (entry) - { entry->write_proc=otg_proc_write_procmem; - entry->read_proc=otg_proc_read_procmem; - } - - + struct proc_dir_entry *entry=create_proc_entry("otg", 0, NULL); + if (entry) + { entry->write_proc=otg_proc_write_procmem; + entry->read_proc=otg_proc_read_procmem; + } int retval = request_irq(BSP_OTGCTRL_IRQ, otg_ctrl_irq, IRQF_DISABLED, "otg_ctrl", &gOtgCtrlDev ); if(retval!=0) @@ -593,16 +619,16 @@ void otg_ctrl_init(void) //top, enable auto-det HangUpRes(1); - //REG32(0xb8000098)&=~(1<<17); //0: connect is come from connect - REG32(0xb8000098)|=(1<<17); //1: connect is come from dis-connect + //REG32(SYS_OTG_CONTROL)&=~(1<<17); //0: connect is come from connect + REG32(SYS_OTG_CONTROL)|=(1<<17); //1: connect is come from dis-connect //Set_SelUSBPort(0); - + USBPHY_CHIP_Active(1,1); USBPHY_UTMI_Reset(1,0); - //Enable_AutoDetectionCircuit(0); - Enable_AutoDetectionCircuit(1); + Enable_AutoDetectionCircuit(0); + //Enable_AutoDetectionCircuit(1); Set_IDDIG_Level(0,0); #endif printk("OTGCTRL: init ok\n"); diff --git a/target/linux/realtek/files/drivers/usb/dwc_otg/rtk_otg_autodet.h b/target/linux/realtek/files/drivers/usb/dwc_otg/rtk_otg_autodet.h index 284a22f84..e43baf83d 100644 --- a/target/linux/realtek/files/drivers/usb/dwc_otg/rtk_otg_autodet.h +++ b/target/linux/realtek/files/drivers/usb/dwc_otg/rtk_otg_autodet.h @@ -21,6 +21,9 @@ #include "dwc_otg_pcd.h" #include "dwc_otg_hcd.h" + +#define SYS_OTG_CONTROL 0xb8000098 + #define OTGCTRL_CFG_DEV_R (1<<18) #define OTGCTRL_VBUS_ON (1<<19) #define OTGCTRL_PJ_ON (1<<20) |
