示例#1
0
int musb_hub_control(
	struct usb_hcd	*hcd,
	u16		typeReq,
	u16		wValue,
	u16		wIndex,
	char		*buf,
	u16		wLength)
{
	struct musb	*musb = hcd_to_musb(hcd);
	u32		temp;
	int		retval = 0;
	unsigned long	flags;

	spin_lock_irqsave(&musb->lock, flags);

	if (unlikely(!HCD_HW_ACCESSIBLE(hcd))) {
		spin_unlock_irqrestore(&musb->lock, flags);
		return -ESHUTDOWN;
	}

	/* hub features:  always zero, setting is a NOP
	 * port features: reported, sometimes updated when host is active
	 * no indicators
	 */
	switch (typeReq) {
	case ClearHubFeature:
	case SetHubFeature:
		switch (wValue) {
		case C_HUB_OVER_CURRENT:
		case C_HUB_LOCAL_POWER:
			break;
		default:
			goto error;
		}
		break;
	case ClearPortFeature:
		if ((wIndex & 0xff) != 1)
			goto error;

		switch (wValue) {
		case USB_PORT_FEAT_ENABLE:
			break;
		case USB_PORT_FEAT_SUSPEND:
			musb_port_suspend(musb, false);
			break;
		case USB_PORT_FEAT_POWER:
			if (!hcd->self.is_b_host)
				musb_platform_set_vbus(musb, 0);
			break;
		case USB_PORT_FEAT_C_CONNECTION:
		case USB_PORT_FEAT_C_ENABLE:
		case USB_PORT_FEAT_C_OVER_CURRENT:
		case USB_PORT_FEAT_C_RESET:
		case USB_PORT_FEAT_C_SUSPEND:
			break;
		default:
			goto error;
		}
		dev_dbg(musb->controller, "clear feature %d\n", wValue);
		musb->port1_status &= ~(1 << wValue);
		break;
	case GetHubDescriptor:
		{
		struct usb_hub_descriptor *desc = (void *)buf;

		desc->bDescLength = 9;
		desc->bDescriptorType = 0x29;
		desc->bNbrPorts = 1;
		desc->wHubCharacteristics = cpu_to_le16(
				  0x0001	/* per-port power switching */
				| 0x0010	/* no overcurrent reporting */
				);
		desc->bPwrOn2PwrGood = 5;	/* msec/2 */
		desc->bHubContrCurrent = 0;

		/* workaround bogus struct definition */
		desc->u.hs.DeviceRemovable[0] = 0x02;	/* port 1 */
		desc->u.hs.DeviceRemovable[1] = 0xff;
		}
		break;
	case GetHubStatus:
		temp = 0;
		*(__le32 *) buf = cpu_to_le32(temp);
		break;
	case GetPortStatus:
		if (wIndex != 1)
			goto error;

		put_unaligned(cpu_to_le32(musb->port1_status
					& ~MUSB_PORT_STAT_RESUME),
				(__le32 *) buf);

		/* port change status is more interesting */
		dev_dbg(musb->controller, "port status %08x\n",
				musb->port1_status);
		break;
	case SetPortFeature:
		if ((wIndex & 0xff) != 1)
			goto error;

		switch (wValue) {
		case USB_PORT_FEAT_POWER:
			/* NOTE: this controller has a strange state machine
			 * that involves "requesting sessions" according to
			 * magic side effects from incompletely-described
			 * rules about startup...
			 *
			 * This call is what really starts the host mode; be
			 * very careful about side effects if you reorder any
			 * initialization logic, e.g. for OTG, or change any
			 * logic relating to VBUS power-up.
			 */
			if (!hcd->self.is_b_host && musb_has_gadget(musb))
				musb_start(musb);
			break;
		case USB_PORT_FEAT_RESET:
			musb_port_reset(musb, true);
			break;
		case USB_PORT_FEAT_SUSPEND:
			musb_port_suspend(musb, true);
			break;
		case USB_PORT_FEAT_TEST:
			if (unlikely(is_host_active(musb)))
				goto error;

			wIndex >>= 8;
			switch (wIndex) {
			case 1:
				pr_debug("TEST_J\n");
				temp = MUSB_TEST_J;
				break;
			case 2:
				pr_debug("TEST_K\n");
				temp = MUSB_TEST_K;
				break;
			case 3:
				pr_debug("TEST_SE0_NAK\n");
				temp = MUSB_TEST_SE0_NAK;
				break;
			case 4:
				pr_debug("TEST_PACKET\n");
				temp = MUSB_TEST_PACKET;
				musb_load_testpacket(musb);
				break;
			case 5:
				pr_debug("TEST_FORCE_ENABLE\n");
				temp = MUSB_TEST_FORCE_HOST
					| MUSB_TEST_FORCE_HS;

				musb_writeb(musb->mregs, MUSB_DEVCTL,
						MUSB_DEVCTL_SESSION);
				break;
			case 6:
				pr_debug("TEST_FIFO_ACCESS\n");
				temp = MUSB_TEST_FIFO_ACCESS;
				break;
			default:
				goto error;
			}
			musb_writeb(musb->mregs, MUSB_TESTMODE, temp);
			break;
		default:
			goto error;
		}
		dev_dbg(musb->controller, "set feature %d\n", wValue);
		musb->port1_status |= 1 << wValue;
		break;

	default:
error:
		/* "protocol stall" on error */
		retval = -EPIPE;
	}
	spin_unlock_irqrestore(&musb->lock, flags);
	return retval;
}
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);
            musb_platform_set_vbus(mtk_musb, 1);
            while(g_exec)
                msleep(100);
            musb_otg_set_session (false);
            musb_platform_set_vbus(mtk_musb, 0);
            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;

}
示例#3
0
static void musb_id_pin_work(struct work_struct *data)
{
    u8 devctl = 0;
    unsigned long flags;

    spin_lock_irqsave(&mtk_musb->lock, flags);
    musb_generic_disable(mtk_musb);
    spin_unlock_irqrestore(&mtk_musb->lock, flags);

	down(&mtk_musb->musb_lock);
	DBG(0, "work start, is_host=%d\n", mtk_musb->is_host);
	if(mtk_musb->in_ipo_off) {
		DBG(0, "do nothing due to in_ipo_off\n");
		goto out;
	}

	mtk_musb ->is_host = musb_is_host();
	DBG(0,"musb is as %s\n",mtk_musb->is_host?"host":"device");
	switch_set_state((struct switch_dev *)&otg_state, mtk_musb->is_host);

	if (mtk_musb->is_host) {
		//setup fifo for host mode
		ep_config_from_table_for_host(mtk_musb);
		wake_lock(&mtk_musb->usb_lock);
		musb_platform_set_vbus(mtk_musb, 1);

        /* for no VBUS sensing IP*/
        #if 1
		/* wait VBUS ready */
		msleep(100);
		/* clear session*/
		devctl = musb_readb(mtk_musb->mregs,MUSB_DEVCTL);
		musb_writeb(mtk_musb->mregs, MUSB_DEVCTL, (devctl&(~MUSB_DEVCTL_SESSION)));
		/* USB MAC OFF*/
		/* VBUSVALID=0, AVALID=0, BVALID=0, SESSEND=1, IDDIG=X */
		USBPHY_SET8(0x6c, 0x10);
		USBPHY_CLR8(0x6c, 0x2e);
		USBPHY_SET8(0x6d, 0x3e);
		DBG(0,"force PHY to idle, 0x6d=%x, 0x6c=%x\n",USBPHY_READ8(0x6d), USBPHY_READ8(0x6c));
		/* wait */
		msleep(5);
		/* restart session */
		devctl = musb_readb(mtk_musb->mregs,MUSB_DEVCTL);
		musb_writeb(mtk_musb->mregs, MUSB_DEVCTL, (devctl| MUSB_DEVCTL_SESSION));
		/* USB MAC ONand Host Mode*/
		/* VBUSVALID=1, AVALID=1, BVALID=1, SESSEND=0, IDDIG=0 */
		USBPHY_CLR8(0x6c, 0x10);
		USBPHY_SET8(0x6c, 0x2c);
		USBPHY_SET8(0x6d, 0x3e);
		DBG(0,"force PHY to host mode, 0x6d=%x, 0x6c=%x\n",USBPHY_READ8(0x6d), USBPHY_READ8(0x6c));
        #endif

		musb_start(mtk_musb);
		MUSB_HST_MODE(mtk_musb);
		switch_int_to_device(mtk_musb);
	} else {
		DBG(0,"devctl is %x\n",musb_readb(mtk_musb->mregs,MUSB_DEVCTL));
		musb_writeb(mtk_musb->mregs,MUSB_DEVCTL,0);
		if (wake_lock_active(&mtk_musb->usb_lock))
			wake_unlock(&mtk_musb->usb_lock);
		musb_platform_set_vbus(mtk_musb, 0);

        /* for no VBUS sensing IP */
        #if 1
        /* USB MAC OFF*/
		/* VBUSVALID=0, AVALID=0, BVALID=0, SESSEND=1, IDDIG=X */
		USBPHY_SET8(0x6c, 0x10);
		USBPHY_CLR8(0x6c, 0x2e);
		USBPHY_SET8(0x6d, 0x3e);
		DBG(0,"force PHY to idle, 0x6d=%x, 0x6c=%x\n", USBPHY_READ8(0x6d), USBPHY_READ8(0x6c));
        #endif

		musb_stop(mtk_musb);
		//ALPS00849138
		mtk_musb->xceiv->state =  OTG_STATE_B_IDLE;
		MUSB_DEV_MODE(mtk_musb);
		switch_int_to_host(mtk_musb);
	}
out:
	DBG(0, "work end, is_host=%d\n", mtk_musb->is_host);
	up(&mtk_musb->musb_lock);

}
static int musb_host_test_mode(unsigned char cmd){
    musb_platform_set_vbus(mtk_musb, 1);
    musb_otg_reset_usb ();
    host_test_mode(mtk_musb,cmd);
		return 0;
}