static int musb_host_test_mode(unsigned char cmd){ //musb_otg_env_init(); #ifdef MTK_FAN5405_SUPPORT fan5405_set_opa_mode(1); fan5405_set_otg_pl(1); fan5405_set_otg_en(1); #elif defined(MTK_BQ24158_SUPPORT) bq24158_set_opa_mode(1); bq24158_set_otg_pl(1); bq24158_set_otg_en(1); #elif defined(MTK_NCP1851_SUPPORT) || defined(MTK_BQ24196_SUPPORT) tbl_charger_otg_vbus(1); #else #if !(defined(CONFIG_MT6585_FPGA) || defined(CONFIG_MT6577_FPGA) || defined(CONFIG_MT6589_FPGA) || defined(CONFIG_MT6582_FPGA)) #if defined(GPIO_OTG_DRVVBUS_PIN) mt_set_gpio_mode(GPIO_OTG_DRVVBUS_PIN,6); //mt_set_gpio_out (GPIO_OTG_DRVVBUS_PIN, 1); #endif #endif #endif musb_otg_reset_usb (); host_test_mode(mtk_musb,cmd); return 0; }
static int musb_host_test_mode(unsigned char cmd){ //musb_otg_env_init(); #ifdef MTK_FAN5405_SUPPORT fan5405_set_opa_mode(1); fan5405_set_otg_pl(1); fan5405_set_otg_en(1); #elif defined(MTK_BQ24158_SUPPORT) bq24158_set_opa_mode(1); bq24158_set_otg_pl(1); bq24158_set_otg_en(1); //<2013/3/4-22419-jessicatseng, [Pelican] Some bq24157 related files are not integrated into JB2 #elif defined(MTK_BQ24157_SUPPORT) bq24157_set_opa_mode(1); bq24157_set_otg_pl(1); bq24157_set_otg_en(1); //>2013/3/4-22419-jessicatseng #elif defined(MTK_NCP1851_SUPPORT) || defined(MTK_BQ24196_SUPPORT) tbl_charger_otg_vbus(1); #else #if !(defined(CONFIG_MT6585_FPGA) || defined(CONFIG_MT6577_FPGA) || defined(CONFIG_MT6589_FPGA) || defined(CONFIG_MT6582_FPGA)) mt_set_gpio_mode(GPIO_OTG_DRVVBUS_PIN,6); //mt_set_gpio_out (GPIO_OTG_DRVVBUS_PIN, 1); #endif #endif musb_otg_reset_usb (); host_test_mode(mtk_musb,cmd); return 0; }
static kal_uint32 charging_enable(void *data) { kal_uint32 status = STATUS_OK; kal_uint32 enable = *(kal_uint32*)(data); if(KAL_TRUE == enable) { bq24158_set_ce(0); bq24158_set_hz_mode(0); bq24158_set_opa_mode(0); } else { #if defined(CONFIG_USB_MTK_HDRC_HCD) //if(mt_usb_is_device()) #endif { mt_set_gpio_mode(gpio_number,gpio_off_mode); mt_set_gpio_dir(gpio_number,gpio_off_dir); mt_set_gpio_out(gpio_number,gpio_off_out); // bq24158_set_ce(1); } } return status; }
static void mtk_set_vbus(struct musb *musb, int is_on) { DBG(0,"mt65xx_usb20_vbus++,is_on=%d\r\n",is_on); #ifndef CONFIG_MT6589_FPGA if(is_on){ //power on VBUS, implement later... #ifdef MTK_FAN5405_SUPPORT fan5405_set_opa_mode(1); fan5405_set_otg_pl(1); fan5405_set_otg_en(1); #elif defined(MTK_BQ24158_SUPPORT) bq24158_set_opa_mode(1); bq24158_set_otg_pl(1); bq24158_set_otg_en(1); //<2013/1/21-20645-jessicatseng, [Pelican] Intrgrate charging IC BQ24157 for PRE-MP SW #elif defined(MTK_BQ24157_SUPPORT) bq24157_set_opa_mode(1); bq24157_set_otg_pl(1); bq24157_set_otg_en(1); //>2013/1/21-20645-jessicatseng #elif defined(MTK_NCP1851_SUPPORT) || defined(MTK_BQ24196_SUPPORT) tbl_charger_otg_vbus((work_busy(&musb->id_pin_work.work)<< 8)| 1); #else mt_set_gpio_out(GPIO_OTG_DRVVBUS_PIN,GPIO_OUT_ONE); #endif } else { //power off VBUS, implement later... #ifdef MTK_FAN5405_SUPPORT fan5405_config_interface_liao(0x01,0x30); fan5405_config_interface_liao(0x02,0x8e); #elif defined(MTK_BQ24158_SUPPORT) bq24158_config_interface_reg(0x01,0x30); bq24158_config_interface_reg(0x02,0x8e); //<2013/1/21-20645-jessicatseng, [Pelican] Intrgrate charging IC BQ24157 for PRE-MP SW #elif defined(MTK_BQ24157_SUPPORT) bq24157_config_interface_liao(0x01,0x30); bq24157_config_interface_liao(0x02,0x8e); //>2013/1/21-20645-jessicatseng #elif defined(MTK_NCP1851_SUPPORT) || defined(MTK_BQ24196_SUPPORT) tbl_charger_otg_vbus((work_busy(&musb->id_pin_work.work)<< 8)| 0); #else mt_set_gpio_out(GPIO_OTG_DRVVBUS_PIN,GPIO_OUT_ZERO); #endif } #endif return; }
void mt_usb_set_vbus(struct musb *musb, int is_on) { DBG(0,"mt65xx_usb20_vbus++,is_on=%d\r\n",is_on); #ifndef FPGA_PLATFORM if(is_on){ //power on VBUS, implement later... #ifdef MTK_FAN5405_SUPPORT fan5405_set_opa_mode(1); fan5405_set_otg_pl(1); fan5405_set_otg_en(1); #elif defined(MTK_BQ24157_SUPPORT) bq24157_set_opa_mode(1); bq24157_set_otg_pl(1); bq24157_set_otg_en(1); #elif defined(MTK_BQ24158_SUPPORT) bq24158_set_opa_mode(1); bq24158_set_otg_pl(1); bq24158_set_otg_en(1); #elif defined(MTK_NCP1851_SUPPORT) || defined(MTK_BQ24196_SUPPORT) tbl_charger_otg_vbus((work_busy(&musb->id_pin_work.work)<< 8)| 1); #else mt_set_gpio_mode(GPIO_OTG_DRVVBUS_PIN,GPIO_OTG_DRVVBUS_PIN_M_GPIO); mt_set_gpio_out(GPIO_OTG_DRVVBUS_PIN,GPIO_OUT_ONE); #endif } else { //power off VBUS, implement later... #ifdef MTK_FAN5405_SUPPORT fan5405_config_interface_liao(0x01,0x30); fan5405_config_interface_liao(0x02,0x8e); #elif defined(MTK_BQ24157_SUPPORT) bq24157_config_interface_liao(0x01,0x30); bq24157_config_interface_liao(0x02,0x8e); #elif defined(MTK_BQ24158_SUPPORT) bq24158_config_interface_liao(0x01,0x30); bq24158_config_interface_liao(0x02,0x8e); #elif defined(MTK_NCP1851_SUPPORT) || defined(MTK_BQ24196_SUPPORT) tbl_charger_otg_vbus((work_busy(&musb->id_pin_work.work)<< 8)| 0); #else mt_set_gpio_mode(GPIO_OTG_DRVVBUS_PIN,GPIO_OTG_DRVVBUS_PIN_M_GPIO); mt_set_gpio_out(GPIO_OTG_DRVVBUS_PIN,GPIO_OUT_ZERO); #endif } #endif }
int musb_otg_exec_cmd(unsigned int cmd){ unsigned char devctl; unsigned char intrusb; unsigned short intrtx; unsigned char power; unsigned short csr0; unsigned int usb_l1intp; unsigned int usb_l1ints; unsigned int ret; unsigned long timeout; bool timeout_flag = false; if(!mtk_musb){ DBG(0,"mtk_musb is NULL,error!\n"); } switch(cmd){ case HOST_CMD_ENV_INIT: musb_otg_env_init(); return 0; case HOST_CMD_ENV_EXIT: musb_otg_env_exit (); return 0; } //init musb_writeb(mtk_musb->mregs, MUSB_POWER, 0x21); musb_writeb(mtk_musb->mregs, MUSB_DEVCTL, 0); msleep(300); #ifdef DX_DBG devctl = musb_readb (mtk_musb->mregs,MUSB_DEVCTL); power = musb_readb (mtk_musb->mregs,MUSB_POWER); intrusb = musb_readb(mtk_musb->mregs,MUSB_INTRUSB); DBG(0,"1:cmd=%d,devctl=0x%x,power=0x%x,intrusb=0x%x\n",cmd,devctl,power,intrusb); #endif musb_writew(mtk_musb->mregs,MUSB_INTRRX,0xffff); musb_writew(mtk_musb->mregs,MUSB_INTRTX,0xffff); musb_writeb(mtk_musb->mregs,MUSB_INTRUSB,0xff); msleep(10); #ifdef DX_DBG devctl = musb_readb (mtk_musb->mregs,MUSB_DEVCTL); power = musb_readb (mtk_musb->mregs,MUSB_POWER); intrusb = musb_readb(mtk_musb->mregs,MUSB_INTRUSB); DBG(0,"2:cmd=%d,devctl=0x%x,power=0x%x,intrusb=0x%x\n",cmd,devctl,power,intrusb); #endif high_speed = false; g_exec = 1; DBG(0,"before exec:cmd=%d\n",cmd); switch(cmd){ //electrical case OTG_CMD_E_ENABLE_VBUS: DBG(0,"musb::enable VBUS!\n"); musb_otg_set_session (true); #ifdef MTK_FAN5405_SUPPORT fan5405_set_opa_mode(1); fan5405_set_otg_pl(1); fan5405_set_otg_en(1); #elif defined(MTK_BQ24158_SUPPORT) bq24158_set_opa_mode(1); bq24158_set_otg_pl(1); bq24158_set_otg_en(1); #endif while(g_exec) msleep(100); musb_otg_set_session (false); #ifdef MTK_FAN5405_SUPPORT fan5405_config_interface_liao(0x01,0x30); fan5405_config_interface_liao(0x02,0x8e); #elif defined(MTK_BQ24158_SUPPORT) bq24158_config_interface_reg(0x01,0x30); bq24158_config_interface_reg(0x02,0x8e); #endif break; case OTG_CMD_E_ENABLE_SRP: //need to clear session? DBG(0,"musb::enable srp!\n"); musb_otg_reset_usb(); USBPHY_WRITE8 (0x6c, 0x1); USBPHY_WRITE8 (0x6d, 0x1); musb_writeb(mtk_musb->mregs,0x7B,1); musb_otg_set_session (true); while(g_exec){ msleep(100); } musb_otg_set_session (false); break; case OTG_CMD_E_START_DET_SRP: //need as a A-device musb_writeb(mtk_musb->mregs, MUSB_DEVCTL, 0); devctl = musb_readb (mtk_musb->mregs, MUSB_DEVCTL); while(g_exec&&(devctl & 0x18)){//VBUS[1:0] should be 0, it indicate below SessionEnd DBG(0,"musb::not below session end!\n"); msleep(100); devctl = musb_readb (mtk_musb->mregs,MUSB_DEVCTL); } while(g_exec&&(!(devctl & 0x10))){ DBG(0,"musb::not above session end!\n"); msleep(100); devctl = musb_readb (mtk_musb->mregs,MUSB_DEVCTL); } devctl |= MUSB_DEVCTL_SESSION; musb_writeb(mtk_musb->mregs, MUSB_DEVCTL, devctl); while(g_exec) msleep(100); musb_writeb(mtk_musb->mregs, MUSB_DEVCTL, 0); break; case OTG_CMD_E_START_DET_VBUS: usb_l1intp = musb_readl(mtk_musb->mregs,USB_L1INTP); usb_l1intp &= ~(1<<10); musb_writel(mtk_musb->mregs,USB_L1INTP,usb_l1intp); usb_l1ints = musb_readl(mtk_musb->mregs,USB_L1INTS); while((usb_l1ints&(1<<8))==0){ DBG(0,"musb::vbus is 0!\n"); msleep(100); usb_l1ints = musb_readl(mtk_musb->mregs,USB_L1INTS); } DBG(0,"musb::vbus is detected!\n"); power = musb_readb (mtk_musb->mregs,MUSB_POWER); power |= MUSB_POWER_SOFTCONN; musb_writeb(mtk_musb->mregs, MUSB_POWER, power); while(g_exec) msleep(100); musb_writeb(mtk_musb->mregs, MUSB_POWER, 0x21); break; case OTG_CMD_P_B_UUT_TD59: is_td_59 = true; if(is_td_59) DBG(0, "TD5.9 will be tested!\n"); break; //protocal case OTG_CMD_P_A_UUT: DBG(0,"A-UUT starts...\n"); //polling the session req from B-OPT and start a new session device_enumed = false; TD_4_6: musb_otg_reset_usb(); DBG(0,"A-UUT reset success\n"); timeout = jiffies + 5*HZ; musb_writeb(mtk_musb->mregs, MUSB_DEVCTL, 0); devctl = musb_readb (mtk_musb->mregs, MUSB_DEVCTL); while(g_exec&&(devctl & 0x18)){//VBUS[1:0] should be 0, it indicate below SessionEnd DBG(0,"musb::not below session end!\n"); msleep(100); if(time_after(jiffies,timeout)){ timeout_flag = true; break; } devctl = musb_readb (mtk_musb->mregs,MUSB_DEVCTL); } if(timeout_flag){ timeout_flag = false; musb_otg_reset_usb(); DBG(0,"timeout for below session end, after reset usb, devctl=0x%x\n",musb_readb(mtk_musb->mregs,MUSB_DEVCTL)); } DBG(0,"polling session request,begin\n"); ret = musb_polling_bus_interrupt(MUSB_INTR_SESSREQ); DBG(0,"polling session request,done,ret=0x%x\n",ret); if(TEST_IS_STOP == ret) break; musb_otg_set_session(true);//session is set and VBUS will be out. #if 1 power = musb_readb(mtk_musb->mregs,MUSB_POWER); power &= ~MUSB_POWER_SOFTCONN; musb_writeb(mtk_musb->mregs,MUSB_POWER,power); #endif //polling the connect interrupt from B-OPT DBG(0,"polling connect interrupt,begin\n"); ret = musb_polling_bus_interrupt(MUSB_INTR_CONNECT); DBG(0,"polling connect interrupt,done,ret=0x%x\n",ret); if(TEST_IS_STOP == ret) break; if(DEV_NOT_CONNECT == ret){ DBG(0,"device is not connected in 15s\n"); g_otg_message.msg = OTG_MSG_DEV_NOT_RESPONSE; break; } DBG(0,"musb::connect interrupt is detected!\n"); msleep(100);//the test is fail beacuse the reset starts less than100 ms from the B-OPT connect. the IF test needs //reset the bus,check whether it is a hs device musb_h_reset();//should last for more than 50ms, TD.4.2 musb_h_enumerate(); //suspend the bus csr0 = musb_readw(mtk_musb->mregs, MUSB_OTG_CSR0); DBG(0,"after enum B-OPT,csr0=0x%x\n",csr0); musb_h_suspend(); //polling the disconnect interrupt from B-OPT, and remote wakeup(TD.4.8) DBG(0,"polling disconnect or remote wakeup,begin\n"); ret = musb_polling_bus_interrupt(MUSB_INTR_DISCONNECT|MUSB_INTR_RESUME); DBG(0,"polling disconnect or remote wakeup,done,ret=0x%x\n",ret); if(TEST_IS_STOP == ret) break; if(MUSB_INTR_RESUME == ret){ //for TD4.8 musb_h_remote_wakeup(); //maybe need to access the B-OPT, get device descriptor if(g_exec) wait_for_completion (&stop_event); break; } //polling the reset interrupt from B-OPT if(!(ret & MUSB_INTR_RESET)){ DBG(0,"polling reset for B-OPT,begin\n"); ret = musb_polling_bus_interrupt(MUSB_INTR_RESET); DBG(0,"polling reset for B-OPT,done,ret=0x%x\n",ret); if(TEST_IS_STOP == ret) break; if(DEV_NOT_RESET == ret){ if(g_exec) wait_for_completion (&stop_event); break; } } DBG(0,"after receive reset,devctl=0x%x,csr0=0x%x\n",musb_readb(mtk_musb->mregs, MUSB_DEVCTL),musb_readw(mtk_musb->mregs, MUSB_OTG_CSR0)); //enumerate and polling the suspend interrupt form B-OPT do{ intrtx = musb_readw(mtk_musb->mregs, MUSB_INTRTX); mb(); musb_writew(mtk_musb->mregs, MUSB_INTRTX, intrtx); intrusb = musb_readb(mtk_musb->mregs, MUSB_INTRUSB); mb(); musb_writeb(mtk_musb->mregs, MUSB_INTRUSB,intrusb); if(intrtx || (intrusb&MUSB_INTR_SUSPEND)){ if(intrtx){ if(intrtx&0x1) musb_d_enumerated(); } if(intrusb){ if(intrusb&MUSB_INTR_SUSPEND){//maybe receive disconnect interrupt when the session is end if(device_enumed){ break;//return form the while loop } else{//TD.4.6 musb_d_soft_connect (false); goto TD_4_6; } } } } else wait_for_completion_timeout(&stop_event,1); } while(g_exec);//the enum will be repeated for 5 times if(!g_exec){ break;//return form the switch-case } DBG(0,"polling connect form B-OPT,begin\n"); ret = musb_polling_bus_interrupt(MUSB_INTR_CONNECT);//B-OPT will connect again 100ms after A disconnect DBG(0,"polling connect form B-OPT,done,ret=0x%x\n",ret); if(TEST_IS_STOP == ret) break; musb_h_reset();//should reset bus again, TD.4.7 wait_for_completion (&stop_event); DBG(0,"the test as A-UUT is done\n"); break; case OTG_CMD_P_B_UUT: musb_otg_reset_usb(); //The B-UUT issues an SRP to start a session with the A-OPT musb_otg_set_session (true); //100ms after VBUS begins to decay the A-OPT powers VBUS timeout = jiffies + 5 * HZ; devctl = musb_readb (mtk_musb->mregs, MUSB_DEVCTL); while(((devctl & MUSB_DEVCTL_VBUS)>>MUSB_DEVCTL_VBUS_SHIFT)<0x3){ if(time_after(jiffies, timeout)){ timeout_flag = true; break; } msleep(100); devctl = musb_readb (mtk_musb->mregs,MUSB_DEVCTL); } if(timeout_flag){ DBG(0,"B-UUT set vbus timeout\n"); g_otg_message.msg = OTG_MSG_DEV_NOT_RESPONSE; timeout_flag = false; break; } //After detecting the VBUS, B-UUT should connect to the A_OPT power = musb_readb(mtk_musb->mregs, MUSB_POWER); power |= MUSB_POWER_HSENAB; musb_writeb(mtk_musb->mregs, MUSB_POWER,power); //TD5_5: musb_d_soft_connect(true); device_enumed = false; //polling the reset single form the A-OPT DBG(0,"polling reset form A-OPT,begin\n"); ret = musb_polling_bus_interrupt(MUSB_INTR_RESET); DBG(0,"polling reset form A-OPT,done,ret=0x%x\n",ret); if(TEST_IS_STOP == ret) break; power = musb_readb(mtk_musb->mregs,MUSB_POWER); if(power & MUSB_POWER_HSMODE){ high_speed = true; } else high_speed = false; //The A-OPT enumerates the B-UUT TD6_13: do{ intrtx = musb_readw(mtk_musb->mregs, MUSB_INTRTX); mb(); musb_writew(mtk_musb->mregs, MUSB_INTRTX,intrtx); intrusb = musb_readb(mtk_musb->mregs, MUSB_INTRUSB); mb(); musb_writeb(mtk_musb->mregs, MUSB_INTRUSB,intrusb); if(intrtx || (intrusb & 0xf7)){ if(intrtx){ //DBG(0,"B-enum,intrtx=0x%x\n",intrtx); if(intrtx&0x1) DBG(0,"ep0 interrupt\n"); musb_d_enumerated(); } if(intrusb){ if(intrusb & 0xf7) DBG(0,"B-enum,intrusb=0x%x,power=0x%x\n",intrusb,musb_readb(mtk_musb->mregs,MUSB_POWER)); if((device_enumed)&&(intrusb & MUSB_INTR_SUSPEND)){ DBG(0,"suspend interrupt is received,power=0x%x,devctl=0x%x\n",musb_readb(mtk_musb->mregs,MUSB_POWER),musb_readb(mtk_musb->mregs,MUSB_DEVCTL)); break; } } } else{ DBG(0,"power=0x%x,devctl=0x%x,intrtx=0x%x,intrusb=0x%x\n",musb_readb(mtk_musb->mregs,MUSB_POWER),musb_readb(mtk_musb->mregs,MUSB_DEVCTL),musb_readw(mtk_musb->mregs,MUSB_INTRTX),musb_readb(mtk_musb->mregs,MUSB_INTRUSB)); wait_for_completion_timeout (&stop_event,1); } } while(g_exec); if(!g_exec) break; DBG(0,"hnp start\n"); if(intrusb & MUSB_INTR_RESUME) goto TD6_13; if(!(intrusb & MUSB_INTR_CONNECT)){ //polling the connect from A-OPT, the UUT acts as host DBG(0,"polling connect or resume form A-OPT,begin\n"); ret = musb_polling_bus_interrupt(MUSB_INTR_CONNECT|MUSB_INTR_RESUME); DBG(0,"polling connect or resume form A-OPT,done,ret=0x%x\n",ret); if(TEST_IS_STOP == ret) break; if(MUSB_INTR_RESUME == ret){ goto TD6_13; } if(DEV_HNP_TIMEOUT == ret){ DBG(0,"B-UUT HNP timeout\n"); devctl = musb_readb(mtk_musb->mregs,MUSB_DEVCTL); //DBG(0,"hnp timeout,power=0x%x,devctl=0x%x\n",musb_readb(mtk_musb->mregs,MUSB_POWER),devctl); devctl &= ~MUSB_DEVCTL_HR; musb_writeb(mtk_musb->mregs,MUSB_DEVCTL,devctl); if(is_td_59) g_otg_message.msg = OTG_MSG_DEV_NOT_RESPONSE; break; } } //reset the bus and check whether it is a hs device musb_h_reset(); musb_h_enumerate(); //suspend the bus musb_h_suspend(); //polling the disconnect interrupt from A-OPT DBG(0,"polling disconnect form A-OPT,begin\n"); ret = musb_polling_bus_interrupt(MUSB_INTR_DISCONNECT); DBG(0,"polling disconnect form A-OPT,done,ret=0x%x\n",ret); //DBG(0,"power=0x%x,devctl=0x%x,intrusb=0x%x\n",musb_readb(mtk_musb->mregs,MUSB_POWER),musb_readb(mtk_musb->mregs,MUSB_DEVCTL),musb_readb(mtk_musb->mregs,MUSB_INTRUSB)); if(TEST_IS_STOP == ret) break; DBG(0,"A-OPT is disconnected, UUT will be back to device\n"); if(!(ret & MUSB_INTR_RESET)){ musb_d_soft_connect(true); //polling the reset single form the A-OPT DBG(0,"polling reset form A-OPT,begin\n"); ret = musb_polling_bus_interrupt(MUSB_INTR_RESET); //musb_d_reset (); DBG(0,"polling reset form A-OPT,done,ret=0x%x\n",ret); if(TEST_IS_STOP == ret) break; } device_enumed = false; if(g_exec) goto TD6_13;//TD5_5 wait_for_completion(&stop_event); DBG(0,"test as B_UUT is done\n"); break; case HOST_CMD_TEST_SE0_NAK: case HOST_CMD_TEST_J: case HOST_CMD_TEST_K: case HOST_CMD_TEST_PACKET: case HOST_CMD_SUSPEND_RESUME: case HOST_CMD_GET_DESCRIPTOR: case HOST_CMD_SET_FEATURE: musb_host_test_mode(cmd); while(g_exec) msleep(100); break; } DBG(0,"musb_otg_exec_cmd--\n"); return 0; }