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.

How to programmatically control the VBUS to power on (Set to VbusValid) and off (Set to VbusEnd) ?

Other Parts Discussed in Thread: TPS65950

 

Hi experts,

We are now using the LogcPD OMAP35x_SOM-LV_DevKit. On this board the USB PHY is the tps65950. We have a problem as stated below.

Basically the problem is that we can not programmatically  power on and off the VBUS of the MUSB port (once it is powered on, can not be powered off).

1) We have done the reset for the MUSB controller which is a must, so that it can correctly detect the ID state:

- Use the I2C interface of the tps65950 to reset the PHY

- Use the I2C interface to enable the ULPI ID pull-up The code used is as this:

    omapUsbUlpiRegWrite(USB_ULPI_FUNCTION_CTL + USB_ULPI_SET_ADJ,

                        ULPI_FUNC_CTRL_RESET);

    omapUsbUlpiRegWrite(USB_ULPI_OTG_CTL + USB_ULPI_SET_ADJ,

                        ULPI_OTG_CTL_ID_PULL_UP);

2) We got a problem of powering off VBUS. We want to have control of the VBUS to manually power it on or off, even there is a B-device connected (and I think this is why OTG provides SRP for, to allow B-device to ask the A-device to power on VBUS). 

We've tried the following ways:

2.1) Clear the DEVCTL register SESSION bit (while an external device is connected). But once we do so, the MUSB controller becomes not working, the DEVCTL register can not report correct states; Even we set the SESSION bit back,the DEVCTL register keeps the value 0x99, which is not the state (should be A-device in host mode, but it indicates B-device in Device mode). 

2.2) Use the I2C interface to access the ULPI registers directly, to clear the DRVVBUS bit of the OTG_CONTROL register. However, even the I2C access returns, if we read back the VBUS state, it still indicate that the VBUS is in its VBUSValid state (either using I2C access or using the DEVCTL VBUS field). This indicates we can not control the VBUS through the ULPI DRVVBUS bit.

2.3) I also tried to use the DISCHARG_VBUS bit of the ULPI OTG_CONTROL register, but I still get back it as VBUSValid.

So my question seems to be:

How can I correctly power on and off the VBUS while still keeping the ID pin state detection correct?

 

Thanks,

Cory

  • Hi,

    I'd like to restate my problem so that you could understand my problem.

    1. The Core requirement for me is to set VBUS off and on for the MUSB port when it is working as host.

    2. The initially approach I tried is:

    - Clear the DEVCTL register SESSION bit to put the VBUS off (but actually it didn't work, the VBUS is still on seen from the USB bus analyzer and I still read back the VBUS state as VbusValid).  

    - Set the DEVCTL register SESSION bit to put the VBUS on (this, of course, works as the VBUS didn't go off in the above step)

    One note is that when I do the above operations, I kept a USB device attached to the port (meaning I want to simulate a host power on and off VBUS dynamically).

    3. The strange issue I met with the above approach is:

    Once I did the "Clear the DEVCTL register SESSION bit " operation and then "Set the DEVCTL register SESSION bit ", the DEVCTL register keeps the value 0x99 (indicating it is B-device and in Device mode, and VBUSValid), although (it should be indicating A-device and in Host mode and VbusValid, since I have a USB device attached on the port).

    4.  With some suggestions I tried to written some initialization code according to the following URL (since e are using a private OS, not Linux.)

    http://lxr.linux.no/linux+v2.6.36/drivers/usb/otg/twl4030-usb.c

    The code snips is attached in case some one may need to check if I did something wrong.

    0116.PhyInit.txt

    The main initialization function is omapUsbUlpiInit() which I have "#if 1...#else...#endif" to choose different initialization method.

     

    void omapUsbUlpiInit(void)

        {

    #if 1

        omapUsbLdoInit();

     

        omapUsbPhyPower(TRUE);

     

        omapUsbPhyI2CAccess(TRUE);

     

        omapUsbPhyReset();

     

        omapUsbPhySetModeUlpi();

     

        omapUsbPhyI2CAccess(FALSE);

    #else

        omapUsbPhyReset();

    #endif

        }

     

    With the "#if 1", I could not initialize the MUSB to detect any devices.

    With the "#if 1" changed to "#if 0", I could initialize the MUSB to detect USB devices, but once I tried to power off and power on the VBUS using the DEVCTL regsiter SESSION bit, I encountered the problem as described in #3 above.

    I thought this to be a simple problem that could just be as easy as to set/clear a register bit to power on and off VBUS, but it actually didn't turn out to be that way. What can go wrong with me?

    Thanks,

    Cory

     

  • Hi,

    I'd like to restate my problem so that you could understand my problem.

    1. The Core requirement for me is to set VBUS off and on for the MUSB port when it is working as host.

    2. The initially approach I tried is:

    - Clear the DEVCTL register SESSION bit to put the VBUS off (but actually it didn't work, the VBUS is still on seen from the USB bus analyzer and I still read back the VBUS state as VbusValid).  

    - Set the DEVCTL register SESSION bit to put the VBUS on (this, of course, works as the VBUS didn't go off in the above step)

    One note is that when I do the above operations, I kept a USB device attached to the port (meaning I want to simulate a host power on and off VBUS dynamically).

    3. The strange issue I met with the above approach is:

    Once I did the "Clear the DEVCTL register SESSION bit " operation and then "Set the DEVCTL register SESSION bit ", the DEVCTL register keeps the value 0x99 (indicating it is B-device and in Device mode, and VBUSValid), although (it should be indicating A-device and in Host mode and VbusValid, since I have a USB device attached on the port).

    4.  With some suggestions I tried to written some initialization code according to the following URL (since e are using a private OS, not Linux.)

    http://lxr.linux.no/linux+v2.6.36/drivers/usb/otg/twl4030-usb.c

    The code snips is attached in case some one may need to check if I did something wrong.

    0116.PhyInit.txt

    The main initialization function is omapUsbUlpiInit() which I have "#if 1...#else...#endif" to choose different initialization method.

     

    void omapUsbUlpiInit(void)

        {

    #if 1

        omapUsbLdoInit();

     

        omapUsbPhyPower(TRUE);

     

        omapUsbPhyI2CAccess(TRUE);

     

        omapUsbPhyReset();

     

        omapUsbPhySetModeUlpi();

     

        omapUsbPhyI2CAccess(FALSE);

    #else

        omapUsbPhyReset();

    #endif

        }

     

    With the "#if 1", I could not initialize the MUSB to detect any devices.

    With the "#if 1" changed to "#if 0", I could initialize the MUSB to detect USB devices, but once I tried to power off and power on the VBUS using the DEVCTL regsiter SESSION bit, I encountered the problem as described in #3 above.

    I thought this to be a simple problem that could just be as easy as to set/clear a register bit to power on and off VBUS, but it actually didn't turn out to be that way. What can go wrong with me?

    Thanks,

    Cory