staticvoid ux500_musb_set_vbus(struct musb *musb, int is_on)
{
u8 devctl; unsignedlong timeout = jiffies + msecs_to_jiffies(1000); /* HDRC controls CPEN, but beware current surges during device * connect. They can trigger transient overcurrent conditions * that must be ignored.
*/
devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
if (is_on) { if (musb->xceiv->otg->state == OTG_STATE_A_IDLE) { /* start the session */
devctl |= MUSB_DEVCTL_SESSION;
musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); /* * Wait for the musb to set as A device to enable the * VBUS
*/ while (musb_readb(musb->mregs, MUSB_DEVCTL) & 0x80) {
if (time_after(jiffies, timeout)) {
dev_err(musb->controller, "configured as A device timeout"); break;
}
}
/* NOTE: we're skipping A_WAIT_VFALL -> A_IDLE and jumping * right to B_IDLE...
*/
devctl &= ~MUSB_DEVCTL_SESSION;
MUSB_DEV_MODE(musb);
}
musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
/* * Devctl values will be updated after vbus goes below * session_valid. The time taken depends on the capacitance * on VBUS line. The max discharge time can be upto 1 sec * as per the spec. Typically on our platform, it is 200ms
*/ if (!is_on)
mdelay(200);
if (musb->int_usb || musb->int_tx || musb->int_rx)
retval = musb_interrupt(musb);
spin_unlock_irqrestore(&musb->lock, flags);
return retval;
}
staticint ux500_musb_init(struct musb *musb)
{ int status;
musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); if (IS_ERR_OR_NULL(musb->xceiv)) {
pr_err("HS USB OTG: no transceiver configured\n"); return -EPROBE_DEFER;
}
musb->nb.notifier_call = musb_otg_notifications;
status = usb_register_notifier(musb->xceiv, &musb->nb); if (status < 0) {
dev_dbg(musb->controller, "notification register failed\n"); return status;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.