How to power off USB?

  • Hello everyone,


    I want to power off the USB port. Our hardware around the efusA9X-board allows to enable / disable USB vbus via pin 212 of the efusA9X-board (low active). Pin 212 is USBH_A_PWR , GPIO1_IO12 of the device USB_OTG2.


    What I tried is:

    Power off:

    !> echo 'usb1' > /sys/bus/usb/drivers/usb/unbind


    Power on:

    !> echo 'usb1' > /sys/bus/usb/drivers/usb/bind


    At first glance, this seems to work. However, it only puts the connected USB device into suspend mode. It does not disable the VBUS power.


    Then I tried to control pin 212 directly (pin 212 is gpio 12):

    Export pin to have it in /sys/class/gpio:

    !> echo 12  > /sys/class/gpio/export

    Set pin to output:

    !> echo out > /sys/class/gpio/gpio12/direction

    Set pin high (should disable power).

    !> echo 1 > /sys/class/gpio/gpio12/value

    I tried also low:

    !> echo 0 > /sys/class/gpio/gpio12/value


    But nothing happens.


    The USB relevant part of the device-tree is the following:


    In principle, USB devices connected to the port work. But powering off does not work.


    The system is:

    efusA9X, Kernel 5.15.148, Yocto fsimx6-Y2024.04, with MACH=fsimx6sx and Silex driver.


    Do you have any idea what I'm doing wrong? it would be very nice if someone could help to solve this problem.

    Best regards, Habi

  • Hello,


    as you can see from the Device Tree the the VBUS power is controlled via hardware by the USB_OTG_PWR pin, not the GPIO pin:


    https://github.com/FSEmbedded/…oot/dts/efusa9x.dts#L1825

    https://github.com/FSEmbedded/…sa9x.dts#L1200C7-L1200C11

    https://github.com/FSEmbedded/…boot/dts/efusa9x.dts#L513


    The pinmux is not at GPIO, so you cannot control it with the GPIO commands.

    I am nor sure, why the USB_OTG_PWR keeps the power when unloading the driver.

    However, you can try to switch to the GPIO implementation by commenting/uncommenting the respective lines in the device tree I posted.


    Your F&S Support Team

  • Quote

    as you can see from the Device Tree the the VBUS power is controlled via hardware by the USB_OTG_PWR pin, not the GPIO pin:

    Yes, I know. Trying GPIO was just a test out of sheere desperation. My intention is to let the USB hub control the power line.


    In the meantime I tried the command uhubctl -a off -p 1

    It switches the USB power via USBH_A_PWR really off - and "on" by uhubctl -a on -p 1

    I think this proves that the device-tree is correct so far. Unfortuntely, this only works if no USB device is connected. If a USB memory stick is connected uhubctl -a off -p 1 shows in its log that the power has been switched off. However, it does not actually power off. Calling uhubctl without parameters shows that the power is on.

    Option -f to force the power off does not help.


    Do you have any idea how to power off even if a USB device is connected? I'm still trying to avoid the direct control via GPIO.

  • Hello,


    did you test the regulator implementation?


    using the regulator gpio implementation would not mean direct control. The driver would control the USB power with a linux regulator device and not the USB_OTG_PWR pin.

    The USB_OTG_PWR pin is mainly used for OTG use cases where the USB port has to support HOST and DEVICE functionally. This means that the VBUS power is mainly connected to the USB ID state and if it is set to "host" the power will not go down.

    Changes are, that if the driver gets unloaded and the power is driven by a linux regulator, the regulator will get freed and the power will go down.




    Your F&S Support Team

  • I tried your device-tree with the regulator with the following result:


    When unbinding the driver:

    • USB-memory-stick connected: When unbinding the driver via echo 'usb1' > /sys/bus/usb/drivers/usb/unbind the stick enters "suspend mode" but vbus is not switched off via pin 212 USB_A_PWRON. (same as with my device-tree).
    • No USB-memory-stick connected: When unbinding, no power off via pin 212 USB_A_PWRON. (same as with my device-tree).


    Tool uhubctl:

    • USB-memory-stick connected: Doing uhubctl -a off -p 1 does not switch power off. This behavior is different from my device tree. There, the power was switched off briefly and then switched on again. Calling uhubctl without parameters afterwards shows status "power off".
    • No USB-memory-stick connected: Doing uhubctl -a off -p 1 does not switch power off either. With my device tree, the power was switched off (pin 212, USB_A_PWRON).


    Are there any addtional configurations required, e.g. in /sys/bus/usb/devices/usb1/power/...? I changed there nothing, everything is at default.



  • Hello,


    could you test the following command?


    Code
    1. echo "ci_hdrc.1" > /sys/bus/platform/drivers/ci_hdrc/unbind


    i think echo 'usb1' > /sys/bus/usb/drivers/usb/unbind does not unload the whole usb stack. there is still a hub device left, which seems to claim the vbus control.


    Your F&S Support Team

  • Quote

    could you test the following command?


    Code

    echo "ci_hdrc.1" > /sys/bus/platform/drivers/ci_hdrc/unbind

    Thank you for this tip, this command works. USB is powered off.

    And echo "ci_hdrc.1" > /sys/bus/platform/drivers/ci_hdrc/bind powers on again.


    Quote

    Maybe this fixes your uhubctl problem?


    https://github.com/mvp/uhubctl…fter-few-seconds-on-linux


    Greate hint again. The following command also works:

    Power off: uhubctl -a off -p 1 -r 10
    Power on: uhubctl -a on

    The parameter -r 10 repeats the power off 10 times in sequence. Without this repetition, the USB port would be powered on again automatically.


    Thank you very much for your support. :thumbsup: