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.

OMAP-L138 USB connect/disconnect detection as a device

Other Parts Discussed in Thread: OMAP-L138

I have created a USB gadget HID device driver in Linux running on an OMAP-L138.  The driver uses the MUSB high-speed USB2.0 module and connects to a PC as a peripheral.  The driver works fine.  However, I have not found a way to detect when the OMAP is connected to a host.  The information in sysfs is created when the driver module is loaded and never updated when the host is connected or disconnected.

After some investigation, I have found that the disconnect callback (in struct usb_gadget_driver) is only called when the module is unloaded (and loaded) and that the suspend callback is never called.

Any ideas on what is going on?  How can I detect when the OMAP has been connected or disconnected from the host?

Thanks,

abkirchhoff

P.S.  I have the same problem with the gadget serial driver (g_serial) that comes with Linux kernel.

  • There are different ways to detect connect/disconnect of musb device to a host.

    1. Soon after connect musb device end gets RESET interrupt. The related code is in drivers/usb/musb/musb_core.c , function musb_stage0_irq()

    2. After connect and device enumeration musb device end gets SET_CONFIGURATION interrupt. the related code can be found in respective gadget driver (HID or serial at drivers/usb/gadget/...) and in it's setup() function.

    3. Vbus voltage would be above Vbus valid when connected to a host and Below Session end when not connected to host. This information can be read from musb core's register DEVCTL (bit D4-D3). details of this register can be found at drivers/usb/musb/musb_regs.h [macro MUSB_DEVCTL_VBUS]

    Regards,

    Ajay

  • Ajay,

    Thanks for the reply.  The RESET and SET_CONFIGURATION interrupts work fine and allow me to detect connection.

    However, for disconnect events, I found that the Vbus field in the DEVCTL register was not working correctly for me.  The Vbus field always indicated that Vbus was above VbusValid (value of 3), even though there was no voltage on the Vbus pin.  Also, the disconnect interrupt was never occurring.  Thus, the sysfs mode value (/sys/devices/platform/musb_hdrc/mode) always read as b_peripheral.

    I then checked the CFGCHIP2 register settings.  The settings looked right and I found that the USB0VBUSSENSE bit (bit 16) correctly detected the status of Vbus.  Then, I noticed that the USB0OTGMODE field (bits 14-13) was set to override the USB phy to force peripheral operation.  This was caused by selecting CONFIG_USB_MUSB_PERIPHERAL in my kernel config.  The register setup is done in the devices-da8xx.c file. 

    So I modified the devices-da8xx.c file to not override the USB phy.  With that modification, everything appears to be working.  The Vbus field in DEVCTL updates correctly, the disconnect interrupt occurs, and the sysfs mode value returns to b_idle when the device is disconnected.

    My remaining questions:

    1. Is the USB phy override using USB0OTGMODE field intended to work this way?  It seems odd that a peripheral only device would never be able to detect disconnection.
    2. Is disabling the override and not switching to MUSB_DUAL_ROLE operation a stable configuration?  My device will always act as a peripheral and has a micro-B connector.

    Thanks,

    abkirchhoff