For the last few days I’ve been busy figuring out how to support USB host mode on the HTC hero. This may also apply to many other android devices (e.g. the G1, and possibly the Nexus One as I think it may use the same USB host silicon internally). I’ve only tested it on the Hero so far though.
Android supports USB device mode out of the box. However my aim is to use the phone as a mobile USB host. I want to control my Nikon SLR over PTP/USB in order to do fancier shoots, for example timelapses. You can also obviously do loads of other cool things: USB-serial devices, keyboards, webcams, DVB receivers, etc etc.. I knew I’d be able to implement it if I had the docs; sort of a similar situation to this XKCD 🙂
However, (a) there isn’t a USB host mode driver for the phone, and (b) the documentation for the Qualcomm MSM7201A System on a Chip the phone uses is not available, so I was stuck for a while. A month or so ago however, my friend Mark sent me this link. That is a patch to the u-boot project implementing USB for a freescale processor. Interestingly, the register define:
#define FSL_SOC_USB_USBMODE 0x1a8
Matches that in the android USB device mode driver exactly. As do all the other fields. And there are full docs available for the freescale chips such as the MPC5121 available here. They obviously licensed the same USB controller hardware designs. I’m not quite sure whose design it was originally, as Transdimension, Oxford Semiconductor, ARC and finally Synopsys all seem to have something to do with it, and have acquired each other over the last few years.
I also needed to know what USB transceiver hardware it used. From the USB device code, I could see it communicated using the ULPI protocol. And ULPI devices implement VENDORID/DEVICEID fields in their register set. After I dumped those I could see it was an SMSC device. Its actually a USB3316, but again, register level docs are not available (there is a “data brief”, but that is not detailed enough). They are for the closely related USB3320 though!
After a few days of fiddling, I have just this evening got it all working. You can see my original thread on the android kernel list here. My post with the working patch is here. You’d obviously have to get the HTC Hero kernel source (I grabbed it from developer.htc.com), patch it, and compile a custom kernel enabling EHCI/MSM7201 USB host support and disabling both USB Function and USB Gadget support.
The next problem is that as far as I know the hero cannot supply power on the USB bus, and I’m not daring to try enabling the USB bus power hardware registers until I know more about how the charging circuitry is implemented. Therefore, I modified a portable USB hub to have two cables attached: one data with GND/D+/D- for connecting to the phone and one with GND/VBUS for supplying power to the hub itself. I’m powering everything off some rather nifty slimline rechargeable batteries acquired from Maplin.
There is information on other USB/host adapter cables at the openmoko project.
Plugging in my USB keyboard surprisingly works seamlessly – android just “works” with it. USB mice work as well in a sort of confusing manner; I think it treats them as a trackball. I’ve not tried anything else yet, but the idea of attaching 1TB hard disk to it sounds…. amusing 🙂
Here are some pictures. My workspace where I’m resoldering the cables to the USB hub:
The modified hub itself (Its some Saitek “UFO” hub:
And finally, here is it all wired together and running:
My next step will probably be to see how it can coexist with the default gadget driver; implementing USB OTG may be possible, or else I could implement some sort of software switch. Or I might just go ahead and implement some of the PTP camera control software. I’ve already implemented a fairly comprehensive python library, pyptp that I use from my laptop.