Exemple #1
0
int musb_lowlevel_init(struct musb_host_data *host)
{
	void *mbase;
	/* USB spec says it may take up to 1 second for a device to connect */
	unsigned long timeout = get_timer(0) + 1000;
	int ret;

	if (!host->host) {
		printf("MUSB host is not registered\n");
		return -ENODEV;
	}

	ret = musb_start(host->host);
	if (ret)
		return ret;

	mbase = host->host->mregs;
	do {
		if (musb_readb(mbase, MUSB_DEVCTL) & MUSB_DEVCTL_HM)
			break;
	} while (get_timer(0) < timeout);
	if (get_timer(0) >= timeout) {
		musb_stop(host->host);
		return -ENODEV;
	}

	_musb_reset_root_port(host, NULL);
	host->host->is_active = 1;
	host->hcd.hcd_priv = host->host;

	return 0;
}
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;
}
Exemple #3
0
static int ti_musb_host_remove(struct udevice *dev)
{
	struct musb_host_data *host = dev_get_priv(dev);

	musb_stop(host->host);

	return 0;
}
Exemple #4
0
static int musb_usb_remove(struct udevice *dev)
{
	struct pic32_musb_data *pdata = dev_get_priv(dev);

	musb_stop(pdata->mdata.host);

	return 0;
}
Exemple #5
0
void mt_usb_disconnect(void)
{
	os_printk(K_DEBUG,"%s\n", __func__);

	musb_stop(mu3d_musb);

	os_printk(K_DEBUG,"%s-\n", __func__);
}
Exemple #6
0
int usb_lowlevel_stop(int index)
{
	if (!host) {
		printf("MUSB host is not registered\n");
		return -ENODEV;
	}

	musb_stop(host);
	return 0;
}
Exemple #7
0
static void musb_id_pin_work(struct work_struct *data)
{
	//bool is_ready = mtk_musb->is_ready;
	//u8 opstate = 0;
	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_ready = FALSE;
	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);
    	ignore_vbuserr = false;
		musb_set_vbus(mtk_musb,true);
		musb_start(mtk_musb);
		switch_int_to_device();
	} else {
		DBG(0,"devctl is %x\n",musb_readb(mtk_musb->mregs,MUSB_DEVCTL));
		dumpTime(funcWriteb, 0);
		musb_writeb(mtk_musb->mregs,MUSB_DEVCTL,0);
		wake_unlock(&mtk_musb->usb_lock);
		musb_set_vbus(mtk_musb,FALSE);
		/*
		opstate = musb_readb(mtk_musb->mregs,MUSB_OPSTATE);
		while(opstate != OTG_IDLE)
		{
			msleep(10);
			DBG(1,"wait OTG enter IDLE,opstate is %d\n",opstate);
			opstate = musb_readb(mtk_musb->mregs,MUSB_OPSTATE);
		}
		*/
        DBG(0,"musb_stop is called\n");
        //switch_int_to_host(); // move to musb_stop
		musb_stop(mtk_musb);

	}
	//mtk_musb->is_ready = is_ready;
out:
	DBG(0, "work end, is_host=%d\n", mtk_musb->is_host);
	up(&mtk_musb->musb_lock);

}
Exemple #8
0
/* ================================ */
void connection_work(struct work_struct *data)
{
	struct musb *musb = container_of(to_delayed_work(data), struct musb, connection_work);
	static bool is_on = true;
	bool is_usb_cable = usb_cable_connected();

	os_printk(K_INFO, "%s musb %s, cable %s\n", __func__, (is_on?"ON":"OFF"), (is_usb_cable?"IN":"OUT"));

	if ((is_usb_cable == true) && (is_on == false) && (musb->usb_mode == CABLE_MODE_NORMAL)) {

		is_on = true;

		if (!wake_lock_active(&musb->usb_wakelock))
			wake_lock(&musb->usb_wakelock);

		/* FIXME: Should use usb_udc_start() & usb_gadget_connect(), like usb_udc_softconn_store().
		 * But have no time to think how to handle. However i think it is the correct way.*/
		musb_start(musb);

		os_printk(K_INFO, "%s ----Connect----\n", __func__);
	} else if (((is_usb_cable == false) && (is_on == true)) || (musb->usb_mode != CABLE_MODE_NORMAL)) {

		is_on = false;

		if (wake_lock_active(&musb->usb_wakelock))
			wake_unlock(&musb->usb_wakelock);

		/*FIXME: we should use usb_gadget_disconnect() & usb_udc_stop().  like usb_udc_softconn_store().
		 * But have no time to think how to handle. However i think it is the correct way.*/
		musb_stop(musb);

		os_printk(K_INFO, "%s ----Disconnect----\n", __func__);
	} else {
		/* This if-elseif is to set wakelock when booting with USB cable.
		 * Because battery driver does _NOT_ notify at this codition.*/
		if( (is_usb_cable == true) && !wake_lock_active(&musb->usb_wakelock)) {
			os_printk(K_INFO, "%s Boot wakelock\n", __func__);
			wake_lock(&musb->usb_wakelock);
		} else if( (is_usb_cable == false) && wake_lock_active(&musb->usb_wakelock)) {
			os_printk(K_INFO, "%s Boot unwakelock\n", __func__);
			wake_unlock(&musb->usb_wakelock);
		}

		os_printk(K_INFO, "%s directly return\n", __func__);
	}
}
Exemple #9
0
static int musb_usb_remove(struct udevice *dev)
{
	struct musb_host_data *host = dev_get_priv(dev);
	struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;

	musb_stop(host->host);

	sunxi_usb_phy_exit(0);
#ifdef CONFIG_SUNXI_GEN_SUN6I
	clrbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_GATE_OFFSET_USB0);
#endif
	clrbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_USB0);

	free(host->host);
	host->host = NULL;

	return 0;
}
void mt_usb_disconnect(void)
{
    DBG(0,"[MUSB] USB is ready for disconnect\n");

    if (!mtk_musb || !mtk_musb->is_ready || mtk_musb->is_host || !mtk_musb->power)
        return;

    musb_stop(mtk_musb);

	if (wake_lock_active(&mtk_musb->usb_lock))
		wake_unlock(&mtk_musb->usb_lock);

	if (cable_mode == CABLE_MODE_CHRG_ONLY) {
		musb_sync_with_bat(mtk_musb,USB_SUSPEND);
		mtk_musb->power = false;
		return;
	}
	DBG(0,"USB disconnect\n");
}
Exemple #11
0
static void musb_otg_notifier_work(struct work_struct *data_notifier_work)
{
	struct musb_otg_work *otg_work =
		container_of(data_notifier_work, struct musb_otg_work, work);
	struct musb *musb = otg_work->musb;
	struct device *dev = musb->controller;
	struct musb_hdrc_platform_data *pdata = dev->platform_data;
	struct omap_musb_board_data *data = pdata->board_data;
	enum usb_xceiv_events xceiv_event = otg_work->xceiv_event;
	unsigned long	flags;
#ifdef CONFIG_USB_SAMSUNG_OMAP_NORPM
	int ret = 0;
#endif

	kfree(otg_work);

	switch (xceiv_event) {
	case USB_EVENT_ID:
		dev_info(musb->controller, "ID GND\n");
		musb->xceiv->state = OTG_STATE_A_IDLE;
#ifdef CONFIG_USB_SAMSUNG_OMAP_NORPM
		ret = omap2430_async_resume(musb);
		if (ret < 0)
			return;
#endif
		if (is_otg_enabled(musb)) {
#ifdef CONFIG_USB_GADGET_MUSB_HDRC
			if (musb->gadget_driver) {
				musb_otg_init(musb);
			}
#endif
		} else {
			musb_otg_init(musb);
		}
#ifdef CONFIG_USB_SAMSUNG_OMAP_NORPM
		musb_add_hcd(musb);
#endif
		break;
	case USB_EVENT_VBUS_CHARGER:
		dev_info(musb->controller, "USB/TA Connect\n");
		/*  This event received from ta_connect_irq
		 * when a usb cable is connected. Logic has still
		 * not identified whether this is a usb cable or TA.
		 *  So just break here.
		 */
		break;
	case USB_EVENT_VBUS:
		dev_info(musb->controller, "VBUS Connect\n");
#ifdef CONFIG_USB_SAMSUNG_OMAP_NORPM
		ret = omap2430_async_resume(musb);
		if (ret < 0)
			return;
#endif
#ifdef CONFIG_USB_GADGET_MUSB_HDRC
		if (musb->gadget_driver)
			pm_runtime_get_sync(musb->controller);
#endif
		otg_init(musb->xceiv);
#ifdef CONFIG_USB_SAMSUNG_OMAP_NORPM
		musb_start(musb);
		musb_platform_pullup(musb, 1);
#endif
		break;

	case USB_EVENT_CHARGER:
		dev_info(musb->controller, "Dedicated charger connect\n");
		musb->is_ac_charger = true;
		break;
	case USB_EVENT_HOST_NONE:
#ifdef CONFIG_USB_SAMSUNG_OMAP_NORPM
		dev_info(musb->controller, "USB host Disconnect. ID float\n");
		if (!omap2430_async_resumed(musb)) {
			dev_err(musb->controller, "async suspended. abnormal state.\n");
			return;
		}
		musb_stop(musb);
		musb_remove_hcd(musb);
		if (data->interface_type == MUSB_INTERFACE_UTMI) {
			omap2430_musb_set_vbus(musb, 0);
			if (musb->xceiv->set_vbus)
				otg_set_vbus(musb->xceiv, 0);
		}
		otg_shutdown(musb->xceiv);
		musb_otg_core_reset(musb);
		ret = omap2430_async_suspend(musb);
		if (ret < 0)
			return;
		break;
#endif
	case USB_EVENT_NONE:
		if (musb->is_ac_charger) {
			dev_info(musb->controller,
				"Dedicated charger disconnect\n");
			musb->is_ac_charger = false;
			break;
		}

		dev_info(musb->controller, "VBUS Disconnect\n");
#ifndef CONFIG_USB_SAMSUNG_OMAP_NORPM
		if (pm_runtime_suspended(musb->controller)) {
			dev_err(musb->controller, "runtime pm suspended. abnormal state.\n");
			return;
		}
		spin_lock_irqsave(&musb->lock, flags);
		musb_g_disconnect(musb);
		spin_unlock_irqrestore(&musb->lock, flags);

#ifdef CONFIG_USB_GADGET_MUSB_HDRC
		if (is_otg_enabled(musb) || is_peripheral_enabled(musb))
			if (musb->gadget_driver)
#endif
			{
				pm_runtime_mark_last_busy(musb->controller);
				pm_runtime_put_autosuspend(musb->controller);
			}

		if (data->interface_type == MUSB_INTERFACE_UTMI) {
			omap2430_musb_set_vbus(musb, 0);
			if (musb->xceiv->set_vbus)
				otg_set_vbus(musb->xceiv, 0);
		}
		otg_shutdown(musb->xceiv);
#else
		if (!omap2430_async_resumed(musb)) {
			dev_err(musb->controller, "async suspended. abnormal state.\n");
			return;
		}
		musb_platform_pullup(musb, 0);
		spin_lock_irqsave(&musb->lock, flags);
		musb_stop(musb);
		musb_g_disconnect(musb);
		musb_all_ep_flush(musb);
		spin_unlock_irqrestore(&musb->lock, flags);
		if (data->interface_type == MUSB_INTERFACE_UTMI)
			omap2430_musb_set_vbus(musb, 0);
		otg_shutdown(musb->xceiv);
		musb_otg_core_reset(musb);
		ret = omap2430_async_suspend(musb);
		if (ret < 0)
			return;
#endif
		break;
	default:
		dev_info(musb->controller, "ID float\n");
	}
}
Exemple #12
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);

}
 /* blocking notifier support */
void cpcap_musb_notifier_call(unsigned long event)
{
	struct musb	*musb = g_musb;
	struct device *dev = musb->controller;
	struct musb_hdrc_platform_data *pdata = dev->platform_data;
	struct omap_musb_board_data *data = pdata->board_data;
	static int hostmode;
	u32 val;
	u8 power;

	switch (event) {
	case USB_EVENT_ID:
		DBG(1, "ID GND\n");

		/* configure musb into smartidle with wakeup enabled
		 * smart standby mode.
		 */

		omap_pm_set_max_mpu_wakeup_lat(&pdata->musb_qos_request, 4000);

		musb_writel(musb->mregs, OTG_FORCESTDBY, 0);
		val = musb_readl(musb->mregs, OTG_SYSCONFIG);
		if (cpu_is_omap44xx())
			val |= SMARTIDLEWKUP | SMARTSTDBY | ENABLEWAKEUP;
		else
			val |= SMARTIDLE | SMARTSTDBY | ENABLEWAKEUP;
		musb_writel(musb->mregs, OTG_SYSCONFIG, val);

		if (data->interface_type == MUSB_INTERFACE_UTMI) {
			phy_init();
			otg_init(musb->xceiv);
			/* enable VBUS valid, id groung*/
			__raw_writel(AVALID | VBUSVALID, ctrl_base +
							USBOTGHS_CONTROL);
			val = __raw_readl(phymux_base +
					USBA0_OTG_CE_PAD1_USBA0_OTG_DP);

			val |= DP_WAKEUPENABLE;
			__raw_writel(val, phymux_base +
						USBA0_OTG_CE_PAD1_USBA0_OTG_DP);
		}

		hostmode = 1;
		musb_start(musb);
		musb_set_vbus(musb, 1);

		break;

	case USB_EVENT_VBUS:
		DBG(1, "VBUS Connect\n");

		/* configure musb into smartidle with wakeup enabled
		 * smart standby mode.
		 */
		musb_writel(musb->mregs, OTG_FORCESTDBY, 0);
		val = musb_readl(musb->mregs, OTG_SYSCONFIG);
		if (cpu_is_omap44xx())
			val |= SMARTIDLEWKUP | SMARTSTDBY | ENABLEWAKEUP;
		else
			val |= SMARTIDLE | SMARTSTDBY | ENABLEWAKEUP;
		musb_writel(musb->mregs, OTG_SYSCONFIG, val);

		power = musb_readb(musb->mregs, MUSB_POWER);
		power &= ~MUSB_POWER_SOFTCONN;
		musb_writeb(musb->mregs, MUSB_POWER, power);


		if (data->interface_type == MUSB_INTERFACE_UTMI) {
			phy_init();
			otg_init(musb->xceiv);
			if (!hostmode) {
				/* Enable VBUS Valid, AValid. Clear SESSEND.*/
				__raw_writel(IDDIG | AVALID | VBUSVALID,
					ctrl_base + USBOTGHS_CONTROL);
			}
		}

		break;

	case USB_EVENT_NONE:
		DBG(1, "VBUS Disconnect\n");

		if (data->interface_type == MUSB_INTERFACE_UTMI) {
			/* enable this clock because in suspend interrupt
			 * handler phy clocks are disabled. If phy clocks are
			 * not enabled then DISCONNECT interrupt will not be
			 * reached to mentor
			 */
			otg_set_clk(musb->xceiv, 1);
			__raw_writel(SESSEND | IDDIG, ctrl_base +
							USBOTGHS_CONTROL);
			if (musb->xceiv->set_vbus)
				otg_set_vbus(musb->xceiv, 0);
			otg_shutdown(musb->xceiv);
			phy_shutdown();
		}
		/* configure in force idle/ standby */
		musb_writel(musb->mregs, OTG_FORCESTDBY, 1);
		val = musb_readl(musb->mregs, OTG_SYSCONFIG);
		val &= ~(SMARTIDLEWKUP | SMARTSTDBY | ENABLEWAKEUP);
		val |= FORCEIDLE | FORCESTDBY;
		musb_writel(musb->mregs, OTG_SYSCONFIG, val);

		omap_pm_set_max_mpu_wakeup_lat(&pdata->musb_qos_request, -1);

		if (data->interface_type == MUSB_INTERFACE_UTMI) {
			val = __raw_readl(phymux_base +
					USBA0_OTG_CE_PAD1_USBA0_OTG_DP);

			val &= ~DP_WAKEUPENABLE;
			__raw_writel(val, phymux_base +
						USBA0_OTG_CE_PAD1_USBA0_OTG_DP);
		}

		if (hostmode) {
			musb_stop(musb);
			musb_set_vbus(musb, 0);
		}
		hostmode = 0;
		break;
	default:
		DBG(1, "ID float\n");
	}

}