📄 ftc_fotg2xx.c
字号:
// Output:0:OK// others:Fail//*********************************************************static u8 OTGC_AP_Set_to_Host(void){ DBG_OTG_FUNCC("+OTGC_AP_Set_to_Host()\n"); pFTC_OTG->otg.host->A_Disable_Set_Feature_HNP=1; if (mdwOTGC_Control_ID_Rd()==0) { //For A Device if (pFTC_OTG->otg.state==OTG_STATE_A_IDLE) { mdwOTGC_Control_A_BUS_DROP_Clr(); mdwOTGC_Control_A_BUS_REQ_Set(); //Turn On VBUS mdwOTGC_Control_A_SRP_DET_EN_Clr(); while(mdwOTGC_Control_A_VBUS_VLD_Rd()==0) ; pFTC_OTG->otg.state=OTG_STATE_A_HOST; INFO(pFTC_OTG,">>> Set to Host Finish...\n"); OTGH_Open(); return(0); } if (pFTC_OTG->otg.state==OTG_STATE_A_HOST) { INFO(pFTC_OTG,">>> Device-A is already in the Host Mode...\n"); return(0); } if (pFTC_OTG->otg.state==OTG_STATE_A_PERIPHERAL) { INFO(pFTC_OTG,">>> Set to Host Fail...Device-A is PERIPHERAL Mode(Bus control by B-Device)...\n"); return(-1); } else { INFO(pFTC_OTG,">>> Set to Host Fail...(Current State = %s)\n",OTGC_state_string(pFTC_OTG->otg.state)); return(-1); } } else { //For B Device if (pFTC_OTG->otg.state==OTG_STATE_B_IDLE) { //Step1: pFTC_OTG->otg.gadget->ops->wakeup((pFTC_OTG->otg.gadget)); //Issue SRP/HNP return(0); } if (pFTC_OTG->otg.state==OTG_STATE_B_HOST) { INFO(pFTC_OTG,">>> Device-B is already in the Host Mode...\n"); return(0); } if (pFTC_OTG->otg.state==OTG_STATE_B_PERIPHERAL) { if (OTGC_AP_Set_to_Idle()==0) pFTC_OTG->otg.gadget->ops->wakeup((pFTC_OTG->otg.gadget)); //Issue SRP/HNP else INFO(pFTC_OTG,">>> Set to Host Fail...Device-B is PERIPHERAL Mode(Bus control by A-Device)...\n"); return(0); } else { ERROR(pFTC_OTG,"??? Set to Host Fail...(Current State = %s)\n",OTGC_state_string(pFTC_OTG->otg.state)); return(1); } } return(0);}//*********************************************************// Name: OTGC_AP_Set_to_Peripheral// Description: AP will call this function call to set device to Peripheral// Input:void// Output:0:OK// others:Fail//*********************************************************static u8 OTGC_AP_Set_to_Peripheral(void){ DBG_OTG_FUNCC("+OTGC_AP_Set_to_Peripheral()\n"); if (mdwOTGC_Control_ID_Rd()==0) { //For A Device ERROR(pFTC_OTG,"??? Cannot Set Device-A to Peripheral mode...\n"); return(0); } else { //For B Device if (pFTC_OTG->otg.state==OTG_STATE_B_IDLE) { OTGP_Open(); return(0); } else { ERROR(pFTC_OTG,"??? Cat not set to Peripheral(When B Device is not in idle)(State=%d)...\n",pFTC_OTG->otg.state); return(-1); } } return(0);}//*********************************************************// Name: OTGC_AP_enable_device// Description: AP will call this function call to enable device// Input:void// Output:0:OK// others:Fail//*********************************************************static u8 OTGC_AP_enable_device(void){ DBG_OTG_FUNCC("+OTGC_AP_enable_device()\n"); mdwOTGC_ChipEnable_INTEnable_Set(); return(0);}//*********************************************************// Name: OTGC_AP_CMD_mdelay_test_Fun// Description: To test the mdelay function// Input: void// Output: int//*********************************************************static int OTGC_AP_CMD_mdelay_test_Fun(void){ u32 wTemp; printk("*** mdelay Test (unit=1ms) ***\n"); wTemp=0; do { mdelay(1); wTemp++; if ((wTemp%1000)==0) printk(">>> mdelay test => %d sec\n",(wTemp/1000)); }while(wTemp<10*1000); printk("*** mdelay Test (unit=10ms) ***\n"); wTemp=0; do { mdelay(10); wTemp++; if ((wTemp%100)==0) printk(">>> mdelay test => %d sec\n",(wTemp/100)); }while(wTemp<10*100); printk("*** mdelay Test (unit=100ms) ***\n"); wTemp=0; do { mdelay(100); wTemp++; if ((wTemp%10)==0) printk(">>> mdelay test => %d sec\n",(wTemp/10)); }while(wTemp<10*10); printk("*** mdelay Test (unit=1000ms) ***\n"); wTemp=0; do { mdelay(1000); wTemp++; printk(">>> mdelay test => %d sec\n",(wTemp)); } while(wTemp<10); return(0);}//*********************************************************// Name: OTGC_AP_Dump_Reg_Fun// Description: To dump the memory// Input: void// Output:int//*********************************************************static int OTGC_AP_Dump_Reg_Fun(void){ u32 regadd=0x00; printk(" ******** Dump the OTG200 Register ********\n"); do { printk("%3x =>>> %8x %8x %8x %8x\n",regadd, mdwFOTGPort(regadd), (mdwFOTGPort((regadd+4))) ,(mdwFOTGPort((regadd+8))) ,(mdwFOTGPort((regadd+12)))); regadd+=0x10; } while(regadd<0x200); return(0);}//*********************************************************// Name: OTGC_AP_ioctl// Description: Request from user mode AP// Input:struct inode * inode, struct file * file// ,unsigned int cmd,unsigned long arg// Output: int//*********************************************************static unsigned long ulAP_REG_Address=0;static int OTGC_AP_ioctl(struct inode * inode, struct file * file ,unsigned int cmd,unsigned long arg){ DBG_OTG_FUNCC("+OTGC_AP_ioctl()\n"); switch(cmd){ case OTG_AP_CMD_GET_STATE: return(OTGC_AP_Get_State()); break; case OTG_AP_CMD_SET_HOST: return(OTGC_AP_Set_to_Host()); break; case OTG_AP_CMD_SET_IDLE: return(OTGC_AP_Set_to_Idle()); break; case OTG_AP_CMD_SET_PERIPHERAL: return(OTGC_AP_Set_to_Peripheral()); break; case OTG_AP_CMD_ENABLE_DEV: //john0217 add for enable device return(OTGC_AP_enable_device()); break; case OTG_AP_CMD_MDELAY_100: mdelay(100); return(0); break; case OTG_AP_CMD_TEST_MDELAY: return(OTGC_AP_CMD_mdelay_test_Fun()); break; case OTG_AP_CMD_TEST_DUMP_REG: return(OTGC_AP_Dump_Reg_Fun()); break; case OTG_AP_CMD_TEST_SET_REG_ADD: ulAP_REG_Address=arg; printk(">>> OTG Driver set address=0x%x\n", (u32) arg); return(0); break; case OTG_AP_CMD_TEST_REG_WRITE: mdwFOTGPort(ulAP_REG_Address)=arg; printk(">>> OTG Driver write (data=0x%x) to (address=0x%x)\n", (u32)arg,(u32)ulAP_REG_Address); return(0); break; //case OTG_AP_CMD_TMP_FORCE_FULL: // pFTC_OTG->iTMP_Force_Speed=1; // return(0); // break; //case OTG_AP_CMD_TMP_FORCE_HIGH: // pFTC_OTG->iTMP_Force_Speed=2; // return(0); // break; //case OTG_AP_CMD_TMP_FORCE_CLEAN: // pFTC_OTG->iTMP_Force_Speed=0; // return(0); // break; } return 0;}//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------//--------Group-3:Interface between Host/Peripheral/OTG Function --------------//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------//*********************************************************// Name: FOTG2XX_get_otg_transceiver// Description: Host/Peripheral Driver will call this function to get// the (single) OTG transceiver driver// Input:void// Output:the structure pointer//*********************************************************struct otg_transceiver *FOTG2XX_get_otg_transceiver(void){ INFO(pFTC_OTG,">>> +FOTG2XX_get_otg_transceiver\n"); if (xceiv) return ((struct otg_transceiver *)xceiv); else { ERROR(pFTC_OTG,"??? Error for FOTG2XX_get_otg_transceiver...\n"); return ((struct otg_transceiver *)xceiv); }}EXPORT_SYMBOL(FOTG2XX_get_otg_transceiver);//*********************************************************// Name: FOTG2XX_set_host// Description:// 1.Call from Host-mode// 2.bind/unbind the host control// 3.Let OTG know how to call the Host Function Call// Input:1.*otg// 2.*host = 0 => Unbing host// *host = 1 => Bing host// Output: 0 => ok//*********************************************************static int FOTG2XX_set_host(struct otg_transceiver *potg, struct usb_bus *host){ struct FTC_OTGC_STS *fotg = container_of(potg, struct FTC_OTGC_STS, otg); DBG_OTG_FUNCC("+(FOTG2XX_set_host)\n"); //<1>.Checking input if (!potg || fotg != pFTC_OTG) return -ENODEV; //<2>.Unbind host processing if (!host) { OTGH_Close();//Disable Interrupt fotg->otg.host = 0; return 0; } //<3>.Bind the host control fotg->otg.host = host; ERROR(&fotg->client.dev, "registered host\n");#ifdef CONFIG_USB_GADGET_FOTG2XX if (fotg->otg.gadget) OTGC_Init();#else printk("OTG2XX act as HOST only (don't need to wait gadget driver)\n"); OTGC_Init();#endif return 0;}//*********************************************************// Name: FOTG2XX_set_peripheral// Description:// 1.Call from Peripheral-mode// 2.bind/unbind the Peripheral control// 3.Let OTG know how to call the Peripheral Function Call// Input: 1.*otg// 2.*gadget = 0 => Unbing host// *gadget = 1 => Bing host// Output:void//*********************************************************static int FOTG2XX_set_peripheral(struct otg_transceiver *potg, struct usb_gadget *gadget){ struct FTC_OTGC_STS *fotg = container_of(potg, struct FTC_OTGC_STS, otg); DBG_OTG_FUNCC("+(FOTG2XX_set_peripheral)\n"); if (!potg || fotg != pFTC_OTG) return -ENODEV; //<1>.Handle the event of unbind peripheral driver if (!gadget) { OTGP_Close();//Disable Interrupt if (!fotg->otg.default_a)//For A => After unbind driver => drop the VBUS OTGC_enable_vbus_draw(1); fotg->otg.gadget = 0; return 0; } /* gadget driver may be suspended until vbus_connect () */ if (fotg->otg.host) OTGC_Init(); //john0215 move code, to let gadget can run in kernel mode // call OTGC_Init() before set fotg->otg.gadget //<2>.Handle the event of binding peripheral driver fotg->otg.gadget = gadget; INFO(&fotg->client.dev, "registered gadget\n"); return 0;}//*********************************************************// Name: FOTG2XX_set_power// Description:// 1.Effective for B Device// 2.B device can set the VBUS power after receiving// the SET_CONFIGURATION// PS:Faraday do not have this feature// Input: void// Output:void//*********************************************************static int FOTG2XX_set_power(struct otg_transceiver *dev, unsigned mA){ printk("Set_power don't support by Faraday\n"); return 0;}//*********************************************************// Name: FOTG2XX_start_srp// Description:// 1.Call from B-Peripheral mode// 2.Issue the SRP// Input: struct otg_transceiver *dev// Output:int//*********************************************************static int FOTG2XX_start_srp(struct otg_transceiver *dev)//Only For B-Device{ u32 wTemp; struct FTC_OTGC_STS *fotg = container_of(dev, struct FTC_OTGC_STS, otg); DBG_OTG_FUNCC("+(FOTG2XX_start_srp)\n"); //Reset phy // OTGC_A_PHY_Reset(); //<1>.Checking condition if (!dev || fotg != pFTC_OTG || fotg->otg.state != OTG_STATE_B_IDLE) return -ENODEV; //<2>.Checking OTG_BSESSEND if (!mdwOTGC_Control_B_SESS_END_Rd()) return -EINVAL; //<3>.Issue the SRP mdwOTGC_INT_STS_Clr(OTGC_INT_BSRPDN);//Clear the interrupt status fotg->otg.state = OTG_STATE_B_SRP_INIT; mUsbUnPLGClr();//Pull high the D+ mdwOTGC_Control_B_HNP_EN_Clr(); mdwOTGC_Control_B_BUS_REQ_Set();//Issue the bus requst //<4>.Waiting for the SRP complete //Here we must use the polling to wait the SRP complete // mdelay (11); wTemp=0; do { if (mdwOTGC_INT_STS_Rd()&OTGC_INT_BSRPDN) { INFO(pFTC_OTG,">>> OTG-B:SRP Detected OK...\n"); goto Detected_SRP_OK; } mdelay (1); wTemp++; if (wTemp>(10*1000)) { //Waiting 10 sec ERROR(pFTC_OTG,"??? OTG-B:B can't issue SRP...(wTemp=%d)\n",wTemp); goto Detected_SRP_INIT_FAIL; } } while(1); // <A>.The done interrupt //<4>.Waiting for the VBUS-Turn-onDetected_SRP_OK: if (OTGC_Waiting_VBUS_On(10000)==0) { //Waiting Host turn on VBUS 10 sec //Turn On VBUS ok fotg->otg.state = OTG_STATE_B_PERIPHERAL; OTGP_Open(); return (0); } else { //Time Out=>Type-A do not turn on the bus ERROR(pFTC_OTG,"??? OTG-B:Device-A Not Responding(Waiting Drive VBUS Fail)...\n"); goto Detected_SRP_INIT_FAIL; }Detected_SRP_INIT_FAIL: //Recover to the original state mUsbUnPLGSet();//Pull low the D+ mdwOTGC_Control_B_BUS_REQ_Clr(); fotg->otg.state = OTG_STATE_B_IDLE; return(1);}//*********************************************************// Name: FOTG2XX_start_hnp// Description:Call from Host(A) to start HNP// Input: void// Output:void//*********************************************************static int FOTG2XX_start_hnp(struct otg_transceiver *dev){ int wTemp; struct FTC_OTGC_STS *fotg; DBG_OTG_FUNCC("+(FOTG2XX_start_hnp)\n"); fotg = pFTC_OTG; //<1>.Close the Host OTGH_Close(); //<2>.Open the Peripheral OTGP_Open(); //<3>.Enable Register //Set HW
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -