Disclaimer: This kernel will enable some very early, and rough usb OTG support for your phone. Currently the phone DOES NOT give out power, so you NEED an external power source to be able to use this kernel. This is true for ALL USB devices, even with those that have their own power source, and doesn't requre external bus powering. Solving this limitation is a TODO, but we cannot guarantee anything. There are some other phones that have usb host support the same way this kernel has (eg. they need external power), like the Nexus One, and there is also a community using this, so if you're saying that usb host support has no sense if you need an external power source then you are definitely mistaken.

This kernel is built upon teamhacksung's ICS Build 14 kernel, and will only work with that particular ROM (and later b15 and b16 versions of it). There is also a build for stock JVU (Gingerbread). It is possible to port this to older ROMs too (like CM7, or pre-GB ROMs). Ask your favourite kernel developer to do this for you. I only plan to support the CM9 and the stock Gingerbread version.

The patches are quite device-independent, so they should also work for other similar handsets, like all SGS variants (Captivate, Vibrant, epic, etc.), and also some distant relatives like the Nexus S, or the Galaxy Tab. I do not own these handsets, so you have to ask your favourite kernel developer to port the changesets to the other variants. I have already a build script for Captivate (CM9) and Nexus S (ICS) ports.

I might also try to create kernels for other devices if the following are true:

The kernel source is avialable on github. It is either a kernel for gingerbread (>=2.6.35) or for ICS (>=3.0)

It also contains (or has links to) the initramfs and all the other files needed to create an update.

If creating the update is not straightforward I also need a script to do this for me

After the update is made I need someone with the device to test it for me. If the feedback is positive I'll build versions for that device too, whenever something is changed.

Credits goes to:

The misterious guy at Samsung(?) called chul2 for the original s3c host drivers

This is a very early, and very rough usb host support. Expect crashes, freezes and things that are not working! You will also need external power (probably through a Y-cable or a powered usb hub, see the device connection guide below). Also make sure you are only using USB 2.0 (high-speed) devices. The driver does has some quirks with USB 1.x low-speed and full-speed devices, like mice, keyboards, gamepads and similar things. Read the FAQ for more information about them. And of course it doesn't work with USB 3.0 (super-speed) devices.

USB Y-cable: A special USB cable that has three ends: two USB male-A ends (one data, one power port) and one USB-mini-B male end.

LS: USB 1.0 Low-speed (1.5 Mb/s)

FS: USB 1.1 Full-speed (12 Mb/s)

HS: USB 2.0 High-speed (460 Mb/s)

USB Hub: A device that lets you split the USB signal

Powered USB Hub: A hub that has an external power supply support

Upstream: The direction from the client device to the host device.

Control Transfer: One of the five transfer types used by the USB specification. It is responsible for maintainin the state of the USB devices.

Bulk Transfer: One of the five transfer types used by the USB specification. This is the most used one, used by drives, cameras and most proprietary usb devices.

Interrupt Transfer: One of the five transfer type used by the USB specification. This is mainly used in HID devices, like mice, keyboards and game controllers.

Isochronous Transfer: One of the five transfer types used by the USB specification. This is used in streaming devices, like usb audio and usb video devices, dvb receivers, etc.

Split Transfer: One of the five transfer types used by the USB specification. It is responsible for converting USB 1.x signals into USB 2.0 signals.

How to connect the things:

You will need:

The phone

An OTG-cable (make sure it's not NOKIA branded, as they have square connectors. You can use some sandpaper to smooth those edges though, so they'll fit inside a normal micro-USB base)

Either a powered USB hub (preferably that powers the upstream connection as well)

Or a simple USB hub, with a mini-USB connector and a Y-cable, and some USB power source (in this case the upstream powering works out of the box). You will need a decent usb power source though (5V/750mA at least)

Make sure the HUB support USB 2.0 and IS indeed an USB 2.0 high-speed hub. USB 1.x Full-speed hubs are very instable Even if it's an USB 2.0 hub it might not work. Either try to find another one, or connect the device directly to the phone (check the connection graphical guide below)

And, but not least, some things to connect to the phone.

Here is a short video of me demonstrating how bad my spoken English is (among other things): http://youtu.be/Yqfk7BOd8J4
And here is a graphical connection guide:

Here is another one (from developersdevelopers), showing how to solder a cable for yourselves:

How to install the kernel:

For CM9/ICS versions: Boot to recovery and use CWM to flash the update. DO NOT TRY to flash this to anything else than teamhacksung's ICS ROM. For stock GB versions: Use Odin to flash the new kernel. Make sure you already have a recent GB ROM on your phone.

How to use:

By default host mode is turned off, and won't be activated even if you put in an OTG cable. This is for stability reasons. There is an application on Market called "Usb Host Controller" that allows you to enable host functionality. (It can also be downloaded separately) For best results connect the devices in this order:

Add power to the USB Hub / connect the power part of the Y cable to a source of power

Set Operation Mode in "Usb Host Controller" to OTG

Connect the OTG cable to the USB hub or device

Connect the OTG cable to the phone

If everything is fine, you should see the USB hub inside the USB tab in UHC. Next you might try to connect your peripherals one by one to the hub. You should always check whether they are enumerated or not. (by pressing refresh)

What is working:

USB 2.0 devices seem to work fine. This includes flash drives, and other accessories like Canon DSLRs. This concludes all USB 2.0 devices I have at home.

What does not work:

USB 1.x devices are very quirky (more about this later). USB 1.x devices include almost all HID devices (like keyboard and mice). Some external hubs are failing too. If you cannot connect your hub to the device try with another one, or try connecting the device without an external hub in the middle.

Also you will need to power the devices externally, as the phone doesn't give out power on the OTG connector.

USB device enumeration is also broken with mass storage devices: it will not re-enumerate the partitions and devices avialable after they have been connected. Since the 0.2 version of UHC it has a new function: reloading the partition table of a device. You have to do this manually. This might solve most of the "no partition found" problems, and will also lets you connect other Android devices.

Do I need a hub to get it working?

No, if you only want to connect one device you can connect it straight to the phone (if you provide it with +5V power). This means you can connect the one end of a Y cable to a power source, the other end to your device and the third end to the phone's OTG cable, and it will work. As it seems there are problems with some external hubs, if you can, then connect to the external device without using a hub in the middle.

What is "Usb Host Controller"?

Usb Host Controller is a small app, that let's you enumerate the USB devices that are connected to your phone. It also let's you easily mount and unmount FAT32 based partitions of the flash drives you connect. Besides these globally useful functions it also let's you control how the host mode should be working with.

Does DSLR Controller work?

According to chainfire the latest version (0.85) of DSLR Controller will work on CM9-ICS + Galaxy S and this kernel. On JVU even older versions (0.83) should work too.

Does it work on CM7, stock ROM, other Galaxy S variants, Nexus S, etc?

It currently works on the folloving devices and ROM versions:

Galaxy S i9000

CM9 / ICS

JVU / Gingerbread

Captivate

CM9 / ICS

Nexus S

(official) ICS 4.0.3

For other S5PV210/S5PC110/Hummingbird based devices this can be probably ported easily. I will do this if you ask me and the following things are present:

The kernel source is avialable on github. It is either a kernel for gingerbread (>=2.6.35) or for ICS (>=3.0)

It also contains (or has links to) the initramfs and all the other files needed to create an update.

If creating the update is not straightforward I also need a script to do this for me

After the update is made you will test it for me. If the feedback is positive I'll build versions for that device too, whenever something is changed.

Is there a chance that this will work without having an external power source?

Maybe. In theory the S3C controller has the appropriate functionality, but in practice it might not work (for example there might be missing connections inside the PCB, etc.)

What about USB 1.x devices

USB 1.x devices work since build 3 (the first JVU build), but only if you connect them to the device without a hub involved (you still need external power). They will still not work if you connect them to an USB 2.0 hub. You might connect more USB 1.x devices together if you happen to have an USB 1.x hub, but it needs patience (I managed to connect a mouse a keyboard and an external hard drive at one through an USB 1.x hub, but I had to try it at least 20 times to get them all properly enumerated. After that they worked though)

Since Build 5, you can also choose to disable the USB 2 functionality of the phone. This will increase stability for USB 1.x devices, but will decrease the transfer speed of USB 2 devices, like external drives. If you want to connect USB 1.x devices through an USB 2.0 HUB, you will need to disable USB 2 mode though.

How to debug

The easiest way to debug is the following:

Turn on "Wireless ADB" on your phone. You can use UHC, or any other app that supports this for that.

Next connect to your phone wirelessly from your PC, and use the following commands:

If devices don't get enumreated properly try switching back to client mode, then to OTG mode again, without disconnecting the devices. You might also try simply reconnecting the devices to the USB cable. Also make sure your power source can give out enough power. For debugging purposes I advice you to use the USB port of a computer / notebook as a power source because they can usually give out 1A of current out of one port. Most external chargers can only give out 500mA-600mA, which might not be enough for multiple devices.

It still doesn't work

There are unfortunately a lot of factors that might make the USB Host mode break. These include:

Non-conformant USB devices

Low quality cables

Low quality power soruces (chargers)

Solar flares

Underground nuclear tests

etc.

Try replacing the cables / devices / power sources and hope it will work next time.

Getting USB host mode was not really a priority for developers, and it wasn't also very easy. The kernel that Samsung provided had traces of EHCI and OHCI support, but they all seemed to be dead-ends. There was a working Host driver though on some releases, most notably the EA24 release of the Galaxy Tab. (From it we know that it is actually the same driver that is used on odroid2 and probably SGS2 too). This driver was actually not usable, but a fellow developer "Kevin Hester" fixed it, and posted it on his github account. Unfortunately his solution was based on a very old kernel, which used a lot of junk Samsung kernel stuff and deprecated features. Also he based the whole client-host switching code on the proprietary 30 pin connector, which is only used in Galaxy Tab variants. The above things meant that his code was not as easily portable as he probably thought.

The driver works as following (if you find it inelegant note that the SGS2 does work the same way!):

The client mode gadget driver is always loaded. It is signalled by the FSA, if it sees that a cable is connected or disconnected. The FSA knows whether the cable is an OTG or a simple client one, and sends this information to the client driver.

Next the client driver decides whether it needs to change to host mode or not. If it changes, it deregisters his interrupt requests, and loads up the host driver. The client driver stays in memory, but without the interrupt handler routines it will not interfere with the host drivers working.

The host driver grabs the interrupt handler, and does the enumeration of the devices. It seems the root hub of the driver only does it once, so if anything changes between the phone and the first device (power loss, cable disconnection etc.) the driver won't notice it! (Thiks is why the first device should be a proper external usb hub, as it will re-enumerate devices if they are connected and disconnected. Losing the power supply will hang the host mode still though). EDIT: this is already solved.

The client driver still listens on cable changes by the FSA. For example if a cable is disconnected and the client driver is not in "host" mode, then it will shut down the host driver (it will unload it from the memory).

The client driver can be in 4 modes:

client: only client mode whatever happens

host: always host mode. The client will load the host mode driver the instant the client driver mode changes to host, and will stay so until the mode is changed again to something else

otg: client mode when no cable or a client cable is connected. Will switch to host mode if an otg cable is connected.

auto-host: client mode when no cable is connected. Will switch to host mode if an otg or a simple client cable is connected.

The actual mode can be queried from the file:

Code:

/sys/devices/platform/s3c-usbgadget/opmode

The actual mode can be set by echoing 'c','h','o' or 'a' to the previous file. (Or by using Usb Host Controller, which actually does the same internally)

After connecting external mass storage devices be aware that udev won't create the appropriate nodes inside /dev for them. Usb Host Controller will do this autoamtically, but from the console one needs to do an mknod, befure it can be mounted as a file system.

Build 5 notices

From Build 5 there are more host drivers built in: S3C in HS mode (original), S3C in LS/FS (eg. USB 1) mode, and an initial DWC driver. The latter is included as it uses the same specification, and it seems it might get into the upstream kernel branch too sometimes, meaning if it can be loaded it might actually get decent support later on. It also supports isochronous and split transactions, which the original S3C drivers lack.

The DWC driver does not work currently however, choosing it will usually crash the phone, and force a restart!

To change the driver you have to write 'l','f' or 'd' into the file:

Code:

/sys/devices/platform/s3c-usbgadget/hostdriver

Apart form that there is also a version file there, containing a few informations about the module.

There is also support to turn off charging, while the phone is connected to a charger. You can turn charging on/off inside the file disable_charger, which can be found somewhere in the sysfs (it's location might change between devices)

If you build a kernel that use the above source, please also link to Usb Host Controller and this topic, because without them the modification is not really usable for an end-user! If you do link both, and also drop me a PM, I will add your kernel to this list.

Few questions, Can you point me towards a working OTG cable for i9000?

I don't know. I bought a nokia cable back then, thinking it will be good. It was expensive and didn't even fit. After some polishing it did work fine though (it is recognized as a proper otg cable, it doesn't fall out, etc.)

XDA Developers was founded by developers, for developers. It is now a valuable resource for people who want to make the most of their mobile devices, from customizing the look and feel to adding new functionality.Are you a developer? | Terms of Service