6AJ USB DRD
 USB DRD (Dual Role Device)
DRD is dual role device, where DWC3 USB controller can be switched to "host-mode" or "device-mode" at runtime.
The USB mode can be set either manually through sysfs entries or automatically based on usb-id pin when the usb cable (type-A for host, type-B for device) is connected to usb1 or usb2 ports.
 How does DRD work?
The host stack, device stack and the gadget module must all be initialized first.
- Configure the DRD capable port to host mode first (by default host mode get initialized during kernel boot).
- After the kernel has booted, mount debugfs and switch to device mode (echo "device" > /mnt/xx/mode), and insert the gadget module.
- If the host cable (mini/micro A-Receptacle, ID pin Ground) is connected to DRD capable portX, the port should switch to host mode. As part of this, if the previous mode was device, the device stack is removed and host stack gets initialized.
- If the device cable (mini/micro B-cable, ID pin Float) is connected to DRD capable portX, the port should switch to device mode. As part of this, if the previous mode was host, the host stack is removed and device stack gets initialized.
 Build instructions
- Revert the default Android configuration patch, so USB3 port will be in host mode by default.
git revert 1603b05dd5ea33e8be254d71060d2a6ff1327041 --no-edit
- Apply the patch to enable dual role configs
- The xhci modules, usb2/3 phy modules, palmas driver modules are made as built-in into kernel.
- Build the kernel and usb gadgets as modules (g_zero.ko, g_mass_storage.ko etc).
- Install the modules to system/lib/modules
 DRD Testing performed on TI's J6 EVM.
- The J6 EVM has usb1 (usb3.0 compatible) and usb2 (usb2.0 only) ports, DRD can be tested by connecting usb1 and usb2 ports back to back with host-A type device-B type usb cables.
- Remove any usb cable/adapter connected to usb1 or usb2 port. Boot the kernel. By default, both usb1 and usb2 ports are set to host mode, and must be switched to device mode. Mount the debugfs node first to switch this.
# mount -t debugfs debugfs /mnt # echo "device" > /mnt/48890000-dwc3/mode # echo "device" > /mnt/488d0000-dwc3/mode
- After above initialization, use the following commands to switch between "host" and "device" modes manually
To switch usb1 port to host mode
# echo "host" > /mnt/48890000-dwc3/mode
To switch usb1 port to device mode
# echo "device" > /mnt/48890000-dwc3/mode
To switch usb2 port to host mode
# echo "host" > /mnt/488d0000-dwc3/mode
To switch usb2 port to device mode
# echo "device" > /mnt/488d000-dwc3/mode
- Load the usb gadget modules for usb1 and usb2 ports respectively.
# insmod /lib/modules/3.8.13-xxx/kernel/drivers/usb/gadget/libcomposite.ko # insmod /lib/modules/3.8.13-xxx/kernel/drivers/usb/gadget/g_zero.ko (for usb1 port) # insmod /lib/modules/3.8.13-xxx/kernel/drivers/usb/gadget/g_mass_storage.ko file=/dev/ram0 stall=0 (for usb2 port)
The g_zero gadget is loaded to usb1, and g_mass_storage to usb2.
To view the current mode of usb1 or usb2
# cat /mnt/48890000-dwc3/mode # cat /mnt/488d0000-dwc3/mode
- Now connect the type-A cable (micro-A receptacle) to usb1 port, the dyanmic usb-id pin is detected and usb1 port is configured to host mode automatically.
- Reverse the cable, connect type-A receptacle to usb2 port (host-mode) and type-B cable to usb1 port (device mode). Now the usb2 becomes host dynamically.