This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM335x USBx_DRVVBUS

Is there a way in the USB PHY to force USBx_DRVVBUS signal low in order to power down a USB device.  I have a customer who wants to have a USB device perminately connected, but have it un powered most of the time and only enable it (via USBx_DRVVBUS) when communcation is needed.

The host OS is Linux, but if software support is the only missing piece, they are willing to customize the software side as needed.

Thanks,

Stuart

  • Stuart,

    Please apply the following patch to the SDK6.0 kernel, then you can use the following command to disconnect the device,

    # echo F > /proc/driver/musb_hdrc.0 or 1

    and use the following command to connect the device again.

    # echo f > /proc/driver/musb_hdrc.0 or 1

    Patch:

    commit 7807e588bb255dec1e5dd46237e5ce5fe7747ed1
    Author: Bin Liu <b-liu@ti.com>
    Date:   Tue Apr 22 13:31:41 2014 -0500
    
        usb: musb: procfs: add an entry to force device disconnect
        
        echo f > /proc/driver/musb_hdrc.{0,1}
        
        Signed-off-by: Bin Liu <b-liu@ti.com>
    
    diff --git a/drivers/usb/musb/musb_procfs.c b/drivers/usb/musb/musb_procfs.c
    index 2db7eac..d2cde5e 100644
    --- a/drivers/usb/musb/musb_procfs.c
    +++ b/drivers/usb/musb/musb_procfs.c
    @@ -609,6 +609,8 @@ static int musb_proc_write(struct file *file, const char __user *buffer,
            u8 reg;
            struct musb *musb = (struct musb *)data;
            void __iomem *mbase = musb->mregs;
    +       unsigned long flags;
    +
     
            /* MOD_INC_USE_COUNT; */
     
    @@ -662,6 +664,22 @@ static int musb_proc_write(struct file *file, const char __user *buffer,
                    musb_writeb(mbase, MUSB_DEVCTL, reg);
                    break;
     
    +       case 'f':
    +               reg = musb_readb(musb->mregs, MUSB_DEVCTL);
    +               if ((reg & MUSB_DEVCTL_SESSION) == 0)
    +                       break;
    +
    +               dev_dbg(musb->controller, "force device disconnect\n");
    +               spin_lock_irqsave(&musb->lock, flags);
    +               reg &= ~MUSB_DEVCTL_SESSION;
    +               musb_writeb(musb->mregs, MUSB_DEVCTL, reg);
    +
    +                /* inform stack about disconnect of root hub */
    +               musb->int_usb = MUSB_INTR_DISCONNECT;
    +               musb_interrupt(musb);
    +               spin_unlock_irqrestore(&musb->lock, flags);
    +               break;
    +
            case 'H':
                    if (mbase) {
                            reg = musb_readb(mbase, MUSB_DEVCTL);
    
    
  • Thank you for the quick response.  Just to be sure I understand this correctly, disconnect means that USBx_DRVVBUS will be driven low and connect means that USBx_DRVVBUS will be driven high?

    What AM335x USB register and bit is this patch touching?

    Thanks,

  • Stuart,

    Stuart Baker said:

    Thank you for the quick response.  Just to be sure I understand this correctly, disconnect means that USBx_DRVVBUS will be driven low and connect means that USBx_DRVVBUS will be driven high?

    Correct but not complete. the whole usb system has many variables to flag the states of connect and disconnect which are defined in the USB 2.0 Specs. USBx_DRVVBUS low/high is part of the variables from the hw perspective.

    Simply turning USBx_DRVVBUS low will mess up the Linux USB stack. So what the patch does when forcing disconnect is to turn down USBx_DRVBUS and notify the sw stack to teardown the connection. 

    Stuart Baker said:
    What AM335x USB register and bit is this patch touching?

    The SESSION bit (bit0) of DEVCTL register, which controls USBx_DRVVBUS in host mode.

  • Stuart,

    I just modified the patch above a little bit, which moves the line of spin_lock_irqsave() a few lines up to protect musb_writeb() too.