static ssize_t mt_usb_store_cmode(struct device* dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned int cmode; if (!dev) { DBG(0,"dev is null!!\n"); return count; } else if (1 == sscanf(buf, "%d", &cmode)) { DBG(0, "cmode=%d, cable_mode=%d\n", cmode, cable_mode); if (cmode >= CABLE_MODE_MAX) cmode = CABLE_MODE_NORMAL; if (cable_mode != cmode) { if(mtk_musb) { if(down_interruptible(&mtk_musb->musb_lock)) xlog_printk(ANDROID_LOG_ERROR, "USB20", "%s: busy, Couldn't get musb_lock\n", __func__); } if(cmode == CABLE_MODE_CHRG_ONLY) { // IPO shutdown, disable USB if(mtk_musb) { mtk_musb->in_ipo_off = true; } } else if(cmode == CABLE_MODE_NORMAL) { // IPO bootup, enable USB if(mtk_musb) { mtk_musb->in_ipo_off = false; } } mt_usb_disconnect(); cable_mode = cmode; msleep(10); //ALPS00114502 //check that "if USB cable connected and than call mt_usb_connect" //Then, the Bat_Thread won't be always wakeup while no USB/chatger cable and IPO mode //mt_usb_connect(); usb_check_connect(); //ALPS00114502 #ifdef CONFIG_USB_MTK_OTG if(cmode == CABLE_MODE_CHRG_ONLY) { if(mtk_musb && mtk_musb->is_host) { // shut down USB host for IPO musb_stop(mtk_musb); /* Think about IPO shutdown with A-cable, then switch to B-cable and IPO bootup. We need a point to clear session bit */ musb_writeb(mtk_musb->mregs, MUSB_DEVCTL, (~MUSB_DEVCTL_SESSION)&musb_readb(mtk_musb->mregs,MUSB_DEVCTL)); } else { switch_int_to_host_and_mask(); // mask ID pin interrupt even if A-cable is not plugged in } } else if(cmode == CABLE_MODE_NORMAL) { switch_int_to_host(); // resotre ID pin interrupt } #endif if(mtk_musb) { up(&mtk_musb->musb_lock); } } } return count; }
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); }