USB OTG Driver (i.MX31)
General notes
The OTG stack is based upon three drivers - the transceiver driver, the ohci driver and the gadget driver. The transceiver driver is responsible for deciding which mode is used (peripheral, host). Either the transceiver driver decides which mode is used by checking the cable or the loaded driver decides which mode is used. In this case, it will be the driver who chooses the mode, since I had troubles getting the automatic mode to work. I guess you would have to add the isp1504 driver (which is build when you select the option "Support for OTG Peripheral Port on Freescale controller") and you'd have to check OTG Support in the USB Gadget section of the kernel configuration. With the isp1504 driver loaded it was ok to use the gadgets, but a usb stick was never detected by the driver. I therefore chose to use the "manual" mode.
This document will describe how to build the kernel for this "driver selects mode" task. the later parts will deal with the gadgets and a simple configuration for them.
Using a USB stick and the Ethernet Gadget alternately
Use the Kernel Config settings described below to compile the kernel, these can be found in Device Drivers -> USB Support.
* Support for Host-Side USB -> Y * USB Device Filesystem -> Y * USB device class devices -> Y * USB selective suspend/resume and wakeup -> Y * EHCI HCD (USB 2.0) support -> M * Support for Freescale controller -> Y * Support for Host 1 port on Freescale controller -> Y * Support for OTG Host Port on Freescale controller -> Y * OTG Transceiver -> Philips ISP1504 * Full Speed ISO Transactions -> Y * Root Hub Transaction Translators -> Y * USB Mass Storage Support -> M * USB Gadget Support * Support for USB Gadgets -> M * Ethernet Gadget -> M (g_ether) * RNDIS Support -> Y * File-backed storage gadget -> M (g_file_storage) * Serial gadget -> M (g_serial)
All other options are N
Compile the kernel with the described settings and run the following commands:
* modprobe g_ether
Now, connect the device to the host PC, it will detect a new ethernet interface. Windows won't find drivers for it, a Linux installation will (most likely) automatically name it usb0. Please see the section about the Gadgets for information on how to configure the interface in Linux. We will now continue to unload this module and let the device become a host for a usb stick. Disconnect the cable now.
* modprobe -r g_ether * modprobe ehci_hcd
Now, connect the usb stick and you will see a number of messages appearing about a new SCSI device. We will now disconnect the cable and let the OTG port become the Ethernet interface again.
* modprobe -r ehci_hcd * modprobe -r usb-storage * modprobe g_ether
Testing USB OTG Gadgets
Check for the modules
Run the command modprobe -l and check for the following modules:
* g_file_storage * g_serial * g_ether * usb-storage * arcotg_udc * ehci-hcd
If one of these modules is missing, the specific option was not selected in the kernel configuration
Testing the file backed storage gadget
Run the following commands:
* modprobe g_file_storage file=/dev/ram0
Now plug the cable into the PC. In case you are using Windows XP or Vista you should see a message popping up that a new drive was found. The Linux console will print the message: "g_file_storage gadget: high speed config #1".
Open the device manager in Windows (Start->Run->compmgmt.msc). Under Drives you will see the entry "Linux File-Stor Gadget USB Device". Open Disk Management. Windows will ask you to initialize the device. Just press OK and you will see a new 16 MB Device. If you partition and format that device and assign a drive letter to it, Windows will show it in the Explorer.
Unload the module using modprobe -r g_file_storage
Testing the Ethernet Gadget
Disconnect the cable, reboot the device, then run the following commands
* modprobe g_ether
Plug the cable in. Windows should pop up a message stating it requires drivers for a ethernet interface (RNDIS). If you have a linux installation running, plug in the cable and run the following commands:
* On the target: ifconfig usb0 10.0.0.2 up * On the Linux system: ifconfig usb0 10.0.0.3 up * On the Linux system: ping 10.0.0.2
If the target responds to pings, everyting is ok. If there is no response, you might want to check your firewall settings for ICMP traffic.
Testing the serial gadget
Disconnect the cable, reboot the device, then run the following commands
* modprobe g_serial
Documentation about the serial gadget can be found in linux/Documentation/gadget_serial.txt.
Getting a USB stick to work
Make sure no usb related module are loaded, then run the following commands
* modprobe ehci-hcd // Do not load arcotg_udc or isp1504_arc before this, otherwise it will fail ?!? * Plug in the USB Stick, you see some messages appearing * mkdir /mnt/usbstick * mount /dev/sda1 /mnt/usbstick * ls /mnt/usbstick
You should now see a directory listing of the contents of the usb stick.
In case the device draws too much power from the port, the driver will print a message saying so. If no messages appear after connecting the usb stick, check that you have selected the "Support for OTG Host Port on Freescale Controller" option.