Ejemplo n.º 1
0
 /* blocking notifier support */
int musb_notifier_call(struct notifier_block *nb,
		unsigned long event, void *unused)
{
	struct musb	*musb = container_of(nb, struct musb, nb);
	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;

	switch (event) {
	case USB_EVENT_ID:
		DBG(1, "ID GND\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);

		if (data->interface_type == MUSB_INTERFACE_UTMI) {
			otg_init(musb->xceiv);
			hostmode = 1;
			musb_enable_vbus(musb);
		}

		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);

		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);

		if (data->interface_type == MUSB_INTERFACE_UTMI) {
			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);
		}
		hostmode = 0;
		/* 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);

		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);
		break;
	default:
		DBG(1, "ID float\n");
		return NOTIFY_DONE;
	}

	return NOTIFY_OK;
}
Ejemplo n.º 2
0
 /* blocking notifier support */
int musb_notifier_call(struct notifier_block *nb,
		unsigned long event, void *unused)
{
	struct musb	*musb = container_of(nb, struct musb, nb);
	struct device *dev = musb->controller;
	struct musb_hdrc_platform_data *pdata = dev->platform_data;
	static int hostmode;

	switch (event) {
	case USB_EVENT_ID:
		DBG(1, "ID GND\n");
		musb->is_active = 1;
		if (omap_readl(0x4A002300)&0x1) {
			omap_writel(0x0, 0x4A002300);
			mdelay(500);
		}
		hostmode = 1;
		musb_enable_vbus(musb);
		break;

	case USB_EVENT_VBUS:
		DBG(1, "VBUS Connect\n");
		wake_lock(&usb_lock);
		musb->is_active = 1;
		if (omap_readl(0x4A002300)&0x1) {
			omap_writel(0x0, 0x4A002300);
			mdelay(400);
		}
		/* hold the L3 constraint as there was performance drop with
		 * ondemand governor
		 */
		if (pdata->set_min_bus_tput)
			pdata->set_min_bus_tput(musb->controller,
					OCP_INITIATOR_AGENT, (200*1000*4));

		if (!hostmode) {
			/* Enable VBUS Valid, BValid, AValid. Clear SESSEND.*/
			omap_writel(0x00000015, 0x4A00233C);
		}
		break;

	case USB_EVENT_NONE:
		DBG(1, "VBUS Disconnect\n");
		omap_writel(0x00000018, 0x4A00233C);

		if (musb->xceiv->set_vbus)
			otg_set_vbus(musb->xceiv, 0);

		/* put the phy in powerdown mode*/
		omap_writel(0x1, 0x4A002300);
		hostmode = 0;
		wake_unlock(&usb_lock);

		/* Release L3 constraint */
		if (pdata->set_min_bus_tput)
			pdata->set_min_bus_tput(musb->controller,
						OCP_INITIATOR_AGENT, -1);
		break;
	default:
		DBG(1, "ID float\n");
		return NOTIFY_DONE;
	}

	return NOTIFY_OK;
}