usb: musb: ti81xx: auto vbus control across host and device mode
authorAjay Kumar Gupta <ajay.gupta@ti.com>
Thu, 22 Dec 2011 10:32:59 +0000 (16:02 +0530)
committerVaibhav Hiremath <hvaibhav@ti.com>
Mon, 23 Jan 2012 19:14:47 +0000 (00:44 +0530)
Automatically control vbus using timer. Set the session bit periodically in a timer
context when nothing is connected to usb port. If mini-A is connected then Vbus will
get switched on and if mini-B is connected then Vbus will nto be driven.

Kill the timer when a device is attached in host mode or port is connected to external
host and revive the timer as soon as disconnect happens.

Signed-off-by: Ajay Kumar Gupta <ajay.gupta@ti.com>
drivers/usb/musb/musb_core.c
drivers/usb/musb/ti81xx.c

index fb5da83f45fe2d9c1000705aa4053bbd83b2aea8..86cc08d050039bedda47ec8b5b93c7427118bbb7 100644 (file)
@@ -969,7 +969,6 @@ void musb_start(struct musb *musb)
 
        musb->is_active = 0;
        devctl = musb_readb(regs, MUSB_DEVCTL);
-       devctl &= ~MUSB_DEVCTL_SESSION;
 
        if (is_otg_enabled(musb)) {
                /* session started after:
index 5a5e07c8291befa9c4da10e3161226aac41beb86..6f3adcde8981ad6ad9f2d06411b8757cf98e156f 100644 (file)
@@ -594,12 +594,14 @@ static void otg_timer(unsigned long _musb)
                musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
 
                devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
-               if (devctl & MUSB_DEVCTL_BDEVICE) {
-                       musb->xceiv->state = OTG_STATE_B_IDLE;
-                       MUSB_DEV_MODE(musb);
-               } else {
+               if (devctl & MUSB_DEVCTL_HM) {
                        musb->xceiv->state = OTG_STATE_A_IDLE;
                        MUSB_HST_MODE(musb);
+               } else {
+                       musb->xceiv->state = OTG_STATE_B_IDLE;
+                       MUSB_DEV_MODE(musb);
+                       mod_timer(&musb->otg_workaround,
+                                       jiffies + POLL_SECONDS * HZ);
                }
                break;
        case OTG_STATE_A_WAIT_VFALL:
@@ -635,11 +637,14 @@ static void otg_timer(unsigned long _musb)
                 * SRP but clearly it doesn't.
                 */
                devctl = musb_readb(mregs, MUSB_DEVCTL);
-               if (devctl & MUSB_DEVCTL_BDEVICE)
+               if (devctl & MUSB_DEVCTL_HM) {
+                       musb->xceiv->state = OTG_STATE_A_IDLE;
+               } else {
                        mod_timer(&musb->otg_workaround,
                                        jiffies + POLL_SECONDS * HZ);
-               else
-                       musb->xceiv->state = OTG_STATE_A_IDLE;
+                       musb_writeb(musb->mregs, MUSB_DEVCTL, devctl |
+                               MUSB_DEVCTL_SESSION);
+               }
                break;
        default:
                break;