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 USB Controller not generating DISCONNECT

Other Parts Discussed in Thread: TWL6030

We are using OMAP4430 and TWL6032A2B4YFFR PMIC.  When USB plug is removed while first connected to a host, sometimes Android does not detect the event and the USB icon remains.  We have found that in the failing case the following registers remain while USB cable is unplugged.

When USB disconnected but icon stuck, PMIC generates an interrupt (IRQ 378) with wrong information, reading the interrupt status registers...

  • STS_HW_CONDITIONS bit-3 reads 1 (Charger is plugged)
  • CONTROLLER_STAT1 bit-2 reads 0 (VBUS is not present)
    In this failure case, battery icon is white with no charging sign, probably due to no VBUS signal is read.

In correct USB disconnected case, STS_HW_CONDITIONS register bit-3 reads 0 (No charger plugged).

-----------------------

Further investigation shows that the OMAP USB OTG controller does not generate a DISCONNECT.  The following is how we expect the sequence to work:

Investigated how VBUS status is propagated from TWL6030 PMIC to OMAP4 USB OTG Controller, below is the summary. Details are in OMAP4 TRM section '23.12 High-Speed USB OTG Controller' and Figure 23-255. High-Speed USB OTG Controller Highlight

  • OMAP4 USB OTG controller uses the ULPI interface mode to connect to PMIC transceiver through an embedded USB-HS OTG PHY.
  • Kernel driver musb-hdrc configures this ULPI access during USB initialization through musb_ulpi_read() and musb_ulpi_write() functions.
  • The core functionality of the OMAP4 USB OTG Controller is provided by the Inventra MUSBMHDRC module (third-party IP from Mentor Graphics).
  • Interrupts are generated by the Inventra MUSBMHDRC module.
  • The embedded PHY does not support the OTG features of USB-OTG standards (that is, ID pin and VBUS detection).
  • VBUS detection is exported to an external companion chip (TWL6030 PMIC).
  • Kernel software retrieves the VBUS status from the TWL6030 (using the I2C interface) and configure the bits inside the control module CONTROL_USBOTGHS_CONTROL register that drive the related USBOTGHS UTMI+ interface signals.

  • Register CONTROL_USBOTGHS_CONTROL is defined in Table 18-194.
  • Bit-3 SESSEND Sets the USBOTGHS signal sessend (BSESSEND). Indicates if VBUS is below the B-Device session end threshold. The threshold is between 0.2V and 0.8V.
    0x0: VBUS voltage is above VB_SESS_END.
    0x1: VBUS voltage is below VB_SESS_END.

  • Bit-2 VBUSVALID Sets the USBOTGHS signal vbusvalid (VBUSVLD). Indicates if VBUS is above the threshold for normal operation. The threshold is between 4.4V and 4.75V.
  • PMIC Kernel driver updates VBUSVALID and SESSEND signals in CONTROL_USBOTGHS_CONTROL register through omap4430_phy_power() function in omap_phy_internal.c
  • OMAP4 TRM Table 23-1179 lists the interrupt line (MA_IRQ_92) that are driven out from the USB OTG controller.
  • MA_IRQ_92, HSUSB_OTG_IRQ, HSUSBOTG, HSUSB OTG controller interrupt
  • USB OTG controller (MUSBMHDRC module) generates interrupts (TX, RX, SUSPEND and DISCONNECT) through OMAP4 interrupt line MA_IRQ_92.
  • When the USB bus is idle for 3 ms, a SUSPEND interrupt is generated by the USB controller.
  • When CONTROL_USBOTGHS_CONTROL register bit-2 (VBUSVALID) is sets, multiple Connect/Reset interrupts are generated and SW enumerates the USB port.
  • When CONTROL_USBOTGHS_CONTROL register bit-3 (SESSEND) is sets, DISCONNECT interrupt is generated and SW disables the USB port.
  • USB OTG controller (MUSBMHDRC module), somehow, updates the following USB stack/context registers and generate interrupts by asserting OMAP4 interrupt line MA_IRQ_92.
  • VBUS and SESSION bits in USB stack 'Device Control Register (DEVCTL)'
  • DISCON and SUSPEND bits in 'Common USB Interrupts Register (INTRUSB)'
  • I couldn't find more details about MUSBMHDRC module and its not clear how this module read CONTROL_USBOTGHS_CONTROL register and generates interrupts.
  • In the USB icon stuck scenario MUSBMHDRC module fails to generate DISCONNECT interrupt after CONTROL_USBOTGHS_CONTROL register updated by PMIC kernel driver. Most of the time it works OK and generates all interrupts correctly.
  • I've seen comments in multiple place in kernel code that USB controller may not detect VBUS disconnect and some other work around has beeen suggested. I would suggest to use PMIC interrupt to detect VBUS signal and send event to android.
  • I also tried to read USB 'Device Control Register (DEVCTL)' in a scheduled thread running at 10sec rate. It works OK when USB is connected but cause exception after USB is disconnected. Probably, when USB is suspended/disconnected its context registers are witched, ...investigating.

Now I notice PMIC register STS_HW_CONDITIONS bit-3 remains always high when USB connect or disconnect, however, VBUS states does changes correctly. It appears STS_HW_CONDITIONS bit-3 is not relevant for USB module DISCONNECT interrupt.

  • USB Connect
  • PMIC irq 378, hw_state 0x3b, vbus_state 0x04, prev_vbus_state 0x00
  • USB Disconnect
  • PMIC irq 378, hw_state 0x3b, vbus_state 0x00, prev_vbus_state 0x04

What could possibly be causing the failing condition.