How to add USB Gamepad support for your Android phone or tablet

IMG_20150411_201153

I was almost at the point to buy a playstation or xbox controller to use with my tablet, since they seem to be supported out-of-the-box. But actually I still have an old USB controller lying around, which would be more than good enough for playing some games. Interestingly my gamepad did in fact work partly, but only the left analog stick and one or two buttons, and the rest did not. My hacker spirit told me that this must be fixable somehow.

So I started hacking around and added support for my old USB gamepad for my android tablet. In this post, I’ll show you how I did it and how you can to add support for any gamepad to your phone or tablet as well!

First of, your tablet or phone needs to be rooted to make the changes needed to support your gamepad. But just about any device is rootable by now, so a quick search will tell you how to root it, if you haven’t done that already.

Prequisites:

  • rooted android device
  • USB-OTG cable (to connect the gamepad)
  • ADB
  • A linux computer
  • evtest (utility program to read raw gamepad input)

Make sure to install evtest and the android debug bridge (adb), which should be available for most linux distributions.

I recommend using ADB wireless to connect to your device, so you can transfer files and type in shell commands while the gamepad is plugged in. I personnally use the open source ADB Manager for that purpose.

And by the way: I am not responsible if you break anything, bla bla. Changing stuff on your android device might as will break it, so proceed with caution. Also, the commands in this how-to are specific to my tablet and gamepad and you have to change them accordingly to your device and hardware.

Finding the keycodes

Android maps all gamepad keys to some internal actions. For example some gamepad key with the number 289 is mapped to the action BUTTON_X for some specific keyboard, gamepad or hair-dryer. Here’s the documentation of the keymap files, which will tell you a lot about how those are composed. Those keylayouts are inside /system/usr/keylayout/Β  on your android device. So all we need to do to make your gamepad compatible with android, is to create a keylayout that tells android what keys of the gamepad mean which action inside android. That means we have find the keycode and axis ids of all the buttons and map them to the android actions.

First plug in your gamepad into your linux computer. After doing so, run dmesg in a terminal to find out the vendor and product id of your gamepad. This will be important later.

In this output, the important part is 07B5:0315, which are the vendor ID 07B5 and the product ID 0315. Your output might look different depending on your kernel version. If you can’t figure out what’s what, you can also run lsusb to get a more readable output.

To find out the key codes you will have to install and use the program evtest

To get the raw keycodes, we have to read the signals directly from /dev/input. As there are many devices inside /dev/input, you will have to try out which device is actually your gamepad. Normally it will be the last event device, in my case thats /dev/input/event18.

Now press some buttons to find out which button has which key code. Pressing a button will yield some output like that:

Write down the keycode for that button, in the case above thats 288 for the A-Button, so we can later put it inside the android configuration. For me the following configuration came out. I wrote down all the Buttons that are mapped to something in android.

Diagram1

Also wiggle the analog sticks first horizontally then vertically to find out the axis of each stick. In my case those where axis 0/1 for X/Y left and 2/5 for X/Y right. Using the documentation from the android website and by looking at the other keylayout files on my tablet, I created a configuration file like this:

Before you put that configuration file on your device you can optionally use the validate keymaps tool from the android sdk to make sure you didn’t make any mistakes creating the configuration.

The configuration should now be saved to a file that includes the vendor ID and product ID of your gamepad. In my case the vendor ID is 07B5 and the product ID is 0315 so the name my configuration file is Vendor_07b5_Product_0315.kl

Android uses the file name to make sure to only load specific configurations for specific USB devices, so make sure those are correct.

Adding the configuration to your device

After saving the key mapping to Vendor_07b5_Product_0315.kl, we need to upload the file back onto the device. We’ll use adb for that. As described earlier, I recommend using ABD wireless so it’s easier to make changes to the configuration while the gamepad is plugged in.

We put the configuration on the sdcard and move it afterwards to the correct position on the device, because we don’t have root access over adb (so we can’t move the configuration directly into the appropriate system folder)

Before you can move the file to the correct location you must remount the /system partition, to make it writable. This may differ from device to device. Check where your /system is mounted using the mount command before. In my case /system is mounted to /dev/block/mmcblk0p20, so I remount that device read-write-able.

Also make sure to allow the adb shell to become root on your tablet once you have entered the su command.

Now we can copy the key layout from the sdcard into the keylayout folder:

And really important, you have to change the permissions of the file to 644 or android will not load it after the gamepad was plugged in!

Now you can connect your gamepad to the android device and play some games to check if everything worked out. If something went wrong, you can always upload a new version of you keymap to the sdcard, move it to the system folder, change the permissions and replug your gamepad to make more tests.

Once you have tested that everything works, make sure to remount the /system partition back to read-only.

And now I can finally play GTA: San Andreas on my tablet using my really old cheapo USB Gamepad, which is incredibly better than the touch controls. Great.

 

 

18 thoughts on “How to add USB Gamepad support for your Android phone or tablet

  1. I tried to follow your tutorial but it wouldn’t work for me. The terminal was scrolling too fast for me too see and write down inputs. Could I get a tad bit of help please

    • Hi Jeremy!

      You’re probably dealing with a gamepad that does not have so called dead-zones. Dead-zones are the ranges of analog input that should not be used. So your analog sticks are probably sending information, even though there are centered, because they will always wiggle just a little bit.

      So you could filter out all the signals from the output by piping it into grep like so:

      evtest /dev/input/event18 | grep -v -P “(ABS|EV_SYN)”

      The -v switch tells grep not to print anything that matches, and the -P “(ABS|EV_SYN)” means look for lines that contain the word ABS which means analog stick output and also dont print the sync events.

      By the way, I found out that just running evtest without any parameters and then specifying the correct /dev/input/event device in the command line interface will tell you almost everything you need to make this work.

      I hope that helps.

  2. Do i need rooted mobile ?
    i hae galaxy s5 internation exynos version and i wana connect xbox 360 wired official controller which by default doesnt work

  3. Hey, I really appreciate your post here. It’s very informative.

    I’m running into some issues with getting my controller working. When I plug the controller into my android device it does not show in /dev/input/*

    Any clue about that? The controller should show an it appears in lsusb, and has the correct kernel drivers.

    Can I email you about this? Do you have an irc channel you frequent where we can chat?

    • Hey Mike,

      Sorry but I wouldn’t know how to help you; Everything I wrote here I learned as I went. So maybe there is the “correct” kernel driver in the sense that the device is recognized as USB-Human Interface Device, but there are no drivers to map any of the input from USB to /dev/input signals. This is mere speculation at this point, however. You should ask someone with deeper linux experience than me about it i guess.

  4. So my problem is I got a fake ps3 controller :l and the worse part is I cannot use it on my note 3 so my problem is every single button works correctly only the left and right sticks are bad so is there a way to make it fast without going threw all this thing and if it is needed cant i just use windows pc? thnx

  5. I know this is an old post, but you did some great hacking here!
    Managed to get my wireless Speedlink XEOX working (albeit only in DirectInput mode) to play Minecraft on my Android. Thanks a lot man!

  6. And yet another Question πŸ™‚
    I have a very rare & odd Gamecontrolelr that lookse like a R/C Remote Control, very cool for simulators…
    The Problem is: it is very “uncalibrated”.
    So the Joystick Testers on Android report -0.4 … -0.6 instead of -1.0 … 1.0 !
    Is there an option to “calibrate” the gamecontroller ?
    (In windows you do that in noi time)
    So an option to set min/max/center values ?
    (If so probably an extension to the axis command).

    Greetings,

    Nils

  7. Great information you have here. It will be a nice project to develop an APP to automate the process, will try to build it at my spare time.

    Thanks!!

  8. What i don’t understood is actually how you are not actually much more well-liked than you may be now. You are very intelligent. You realize therefore significantly relating to this subject, made me personally consider it from so many varied angles. Its like men and women aren’t fascinated unless it’s one thing to accomplish with Lady gaga! Your own stuffs nice. Always maintain it up!

  9. I’d like to thank you for the efforts you’ve put in penning this
    blog. I am hoping to view the same high-grade content by you later on as well.
    In truth, your creative writing abilities has inspired me to get my own, personal blog now
    πŸ˜‰

Leave a Reply

Your email address will not be published. Required fields are marked *