« Patching the Linux Kernel to install the Xin-Mo Dual Arcade driver on Ubuntu 13.04 | Main | Using Resque in Symfony 2 with php-resque, php-resque-scheduler and BCCResqueBundle »

Patching the Linux Kernel to install the Xin-Mo Dual Arcade driver on a Raspberry Pi

These are instruction for Raspbian on the Raspberry Pi. I also have instructions for Ubuntu.

The Xin-Mo Dual Arcade is a USB interface for up to two arcade joysticks and 22 buttons. It’s a cool little device if you want to build an arcade controller for your computer or Raspberry Pi. You can get one from Ultracabs.

Unfortunately there is a bug in the Xin-Mo Dual Arcade: the values it sends for the up and left positions of the joysticks are out of range with the values it announces it would send, and Linux therefore ignores these values (it’s its right). Therefore the joystick do nothing in the up and left position.

I wrote a driver to fix that problem, as a patch to the Linux Kernel. A few people asked me for help on how to install it, hence this article.

Cliché Disclaimer: Use these instructions at your own risks. Backup your computer before you start. I am not responsible for any data loss or fried computers caused by following these instructions.

Raspbian

I used NOOBS 1.2.1 and selected Raspbian. Everything here happens in the terminal, make sure you’re logged in as an administrator (typically user pi). If a command that starts with sudo asks for your password (not normally the case on Raspbian), use the password for that administrator user. These instructions were derived from the RPi Kernel Compilation page on the Embedded Linux Wiki.

Observing the problem

First we’re going to install evtest, a tool to test the joystick:

sudo apt-get update
sudo apt-get install evtest

To try it out, connect your joystick and run the program:

evtest

It will list devices and ask you to select your joystick. Find the line that says Xin-Mo Xin-Mo Dual Arcade, type the number next to /dev/input/event (4 in this example) and Enter.

No device specified, trying to scan all of /dev/input/event*
Not running as root, no devices may be available.
Available devices:
/dev/input/event4:  Xin-Mo Xin-Mo Dual Arcade
Select the device event number [0-5]: 4

Now when you move the joysticks and press buttons, it will print lines like these (for a button):

Event: time 1378629038.490828, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90001
Event: time 1378629038.490828, type 1 (EV_KEY), code 288 (BTN_TRIGGER), value 1
Event: time 1378629038.490828, -------------- SYN_REPORT ------------
Event: time 1378629038.618674, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90001
Event: time 1378629038.618674, type 1 (EV_KEY), code 288 (BTN_TRIGGER), value 0
Event: time 1378629038.618674, -------------- SYN_REPORT ------------

or these (for a joystick):

Event: time 1378629075.546079, type 3 (EV_ABS), code 1 (ABS_Y), value 1
Event: time 1378629075.546079, -------------- SYN_REPORT ------------
Event: time 1378629075.740176, type 3 (EV_ABS), code 1 (ABS_Y), value 0
Event: time 1378629075.740176, -------------- SYN_REPORT ------------

and nothing when you move the joysticks up or left.

Fixing the problem

Downloading the sources

First we need to install the programs needed to build the kernel:

sudo apt-get update
sudo apt-get -y dist-upgrade
sudo apt-get -y install gcc make ncurses-dev

Then we can download the source code for the kernel. We’re going to use a ‘tarball’, the rpi-3.6.y one, as proposed at the very end of the Get the kernel source section:

wget 'https://github.com/raspberrypi/linux/archive/rpi-3.6.y.tar.gz'

Extract the sources:

tar xpfvz rpi-3.6.y.tar.gz

You can now find the sources in the linux-rpi-3.6.y directory.

Applying the patch

linux-rpi-3.6.y is the directory where the source code was extracted. Enter it:

cd linux-rpi-3.6.y

Then download the patch using wget:

wget 'http://ithink.ch/blog/files/xin-mo/0001-hid-Add-new-driver-for-non-compliant-Xin-Mo-devices.patch'

and apply it:

patch -p1 < 0001-hid-Add-new-driver-for-non-compliant-Xin-Mo-devices.patch

It should display something like this:

patching file drivers/hid/Kconfig
Hunk #1 succeeded at 670 with fuzz 2 (offset -73 lines).
patching file drivers/hid/Makefile
Hunk #1 succeeded at 86 (offset -24 lines).
patching file drivers/hid/hid-core.c
Hunk #1 succeeded at 1689 (offset -47 lines).
patching file drivers/hid/hid-ids.h
Hunk #1 succeeded at 808 (offset -79 lines).
patching file drivers/hid/hid-xinmo.c

Building the kernel

First, make sure the build directory is clean:

make mrproper

Then copy the current kernel configuration from your Raspberry Pi:

zcat /proc/config.gz > .config

We need to make the configuration up to date. This step might ask a lot of questions about whether to support some new features. We are going to take the default answer every time except for our Xin-Mo Dual Arcade driver. We want to make sure it’s enabled, since that’s the one we’re going through all this trouble for.

Run

make oldconfig

and when the following question pops up, type m and Enter:

Xin-Mo non-fully compliant devices (HID_XINMO) [N/m/y/?] (NEW)

For the other questions, if any, just type Enter to accept the default.

If you missed the Xin-Mo line or are not sure, you can use the menu config1 to make sure it is enabled. Type

make menuconfig

and navigate to Device Drivers -> HID support -> Special HID drivers -> Xin-Mo non-fully compliant devices and type m to enable it as a module. An <M> should be displayed next to the line:

<M> Xin-Mo non-fully compliant devices

Then select the Exit button until it asks if you want to save your nw configuration, and answer Yes.

When ready (ideally at the end of the evening), type

make ; make modules

Then the actual compilation will begin. It will go on for a long, long, long long, long, long time, so go to sleep.

Installing the new kernel

Copy the new kernel image to the boot partition, under a name different than the existing one:

sudo cp arch/arm/boot/Image /boot/kernel_new.img

Then enable it in the boot config by adding the following line to /boot/config.txt, or changing the kernel=kernel.img if it already exists:

kernel=kernel_new.img

You can do this using the nano text editor:

sudo nano /boot/config.txt

Type the kernel=kernel_new.img line on its own line or modify the existing one, then hit Control-O and the Enter to save, and Control-X to exit.

Now we need to install the modules:

mkdir ~/modules
export MODULES_TEMP=~/modules
make INSTALL_MOD_PATH=${MODULES_TEMP} modules_install

and put the files into place:

cd /lib

sudo cp -R ~/modules/lib/firmware/ .
sudo cp -R ~/modules/lib/modules/ .

Next the instructions recommend to “update your GPU firmware and libraries.” Since I didn’t spend a night recompiling the kernel to write this article, I cannot follow along as I write this, so if you started from a fresh and recent Raspbian installation, you can live dangerously and reboot (remember my disclaimer above, though). Otherwise, try and follow the instructions under Get the firmware.

And then reboot:

sudo reboot

Test the patch

Run evtest again, like above, and enjoy the result:

Event: time 1378634592.175998, type 3 (EV_ABS), code 1 (ABS_Y), value -1
Event: time 1378634592.175998, -------------- SYN_REPORT ------------
Event: time 1378634592.335920, type 3 (EV_ABS), code 1 (ABS_Y), value 0
Event: time 1378634592.335920, -------------- SYN_REPORT ------------
Event: time 1378634593.613888, type 3 (EV_ABS), code 0 (ABS_X), value -1
Event: time 1378634593.613888, -------------- SYN_REPORT ------------
Event: time 1378634593.809001, type 3 (EV_ABS), code 0 (ABS_X), value 0
Event: time 1378634593.809001, -------------- SYN_REPORT ------------
Event: time 1378634595.165686, type 3 (EV_ABS), code 3 (ABS_RX), value -1
Event: time 1378634595.165686, -------------- SYN_REPORT ------------
Event: time 1378634595.325688, type 3 (EV_ABS), code 3 (ABS_RX), value 0
Event: time 1378634595.325688, -------------- SYN_REPORT ------------
Event: time 1378634595.933826, type 3 (EV_ABS), code 2 (ABS_Z), value -1
Event: time 1378634595.933826, -------------- SYN_REPORT ------------
Event: time 1378634596.093610, type 3 (EV_ABS), code 2 (ABS_Z), value 0
Event: time 1378634596.093610, -------------- SYN_REPORT ------------

If these instructions helped you, I would appreciate it if you could send me a couple of pictures of your set-up so I can compile them on a web page. Drop me a note on Twitter.

1. Note: We installed the ncurses-dev package earlier required by menuconfig, but if you missed that step, you will get the following error:

 *** Unable to find the ncurses libraries or the
 *** required header files.
 *** 'make menuconfig' requires the ncurses libraries.
 ***
 *** Install ncurses (ncurses-devel) and try again.
 ***

In this case, run

sudo apt-get install ncurses-dev&nbsp;<a class="footnoteBack" href="#ref_1_250_menuconfig">&#8617;</a>

TrackBack

TrackBack URL for this entry: http://ithink.ch/blog/tb.cgi/240.

Make sure JavaScript is enabled before using this URL. If you would like to ping my blog but can't, please do send me an e-mail at os3476 at this domain.

Comments

Hello. 1, 2, 3

Hi, i have had the same issues with my original NES-gamepad which i wanted to connect via a retrobit usb-adapter (like the guy in this post: http://www.raspberrypi.org/phpBB3/viewtopic.php?t=37338&p=435711). Button up/left isn`t working.

I followed your instruction - after one night of compilation i did the final steps - and reboot. The RasbPi wouldn’t start anymore.

After i deleted “kernel=”kernel_new.img” in the boot.txt the Pi worked like before.

Don’t delete the directory with the compiled sources, most likely the problem was with the installation of the new kernel and you can avoid recompiling it.

Did you check the Transfer the Build section in the RPi Kernel Compilation guide and the following ones? Try following those, maybe I made a mistake in my transcription.

I followed the instructions from the wiki, but that also does not work.

hello! I have done all steps. but since no USB device works more.

loading kernel module snd_bcm2835

libkmod: ERROR .. / libkmod / libkmod.c: 554 kmodsearchmoddep: could not open moddep file ‘/ lib/modules/3.6.11/modules.dep.bin

I hope you can help me!

Hi - I have a Xin-Mo dual controller that is exhibiting a different issue and wondering if you can offer any thoughts on this.

Here is what I get for joystick left: Event: time 1388503871.961917, type 3 (EVABS), code 0 (ABSX), value 1 Event: time 1388503871.961940, ——————— SYNREPORT —————— Event: time 1388503872.249944, type 3 (EVABS), code 0 (ABSX), value -1 Event: time 1388503872.249966, ——————— SYNREPORT ——————

And here is what I get for joystick up: Event: time 1388503876.922399, type 3 (EVABS), code 1 (ABSY), value 1 Event: time 1388503876.922422, ——————— SYNREPORT —————— Event: time 1388503877.210413, type 3 (EVABS), code 1 (ABSY), value -1 Event: time 1388503877.210434, ——————— SYNREPORT ——————

Joystick right and down produce no output.

And even weirder, if I unplug the two of the four wires (up and left or down and right) then the opposite two directions produce different output as follows.

Joystick left with joystick right unplugged: Event: time 1388505445.494806, type 3 (EVABS), code 0 (ABSX), value 0 Event: time 1388505445.494828, ——————— SYNREPORT —————— Event: time 1388505445.846858, type 3 (EVABS), code 0 (ABSX), value -1 Event: time 1388505445.846882, ——————— SYNREPORT ——————

Joystick right with joystick left unplugged: Event: time 1388505451.127520, type 3 (EVABS), code 0 (ABSX), value 0 Event: time 1388505451.127544, ——————— SYNREPORT —————— Event: time 1388505454.199906, type 3 (EVABS), code 0 (ABSX), value 1 Event: time 1388505454.199927, ——————— SYNREPORT ——————

Joystick up with joystick down unplugged: Event: time 1388505466.649448, type 3 (EVABS), code 0 (ABSX), value 0 Event: time 1388505466.649470, ——————— SYNREPORT —————— Event: time 1388505493.052595, type 3 (EVABS), code 1 (ABSY), value -1 Event: time 1388505493.052617, ——————— SYNREPORT ——————

Joystick down with joystick up unplugged: Event: time 1388505505.470019, type 3 (EVABS), code 1 (ABSY), value 0 Event: time 1388505505.470041, ——————— SYNREPORT —————— Event: time 1388505505.822069, type 3 (EVABS), code 1 (ABSY), value 1 Event: time 1388505505.822094, ——————— SYNREPORT ——————

This makes absolutely no sense and I can’t figure out what is going on. I bought the controller on eBay and I even had the guy send me a new one thinking mine was defective, but the new one behaves exactly the same way. I have tried your patch but it does not change the behavior in any way. I’m running PiMAME 0.7.10 which has your patch already integrated though I also built my own kernel following your instructions just to be sure I was picking up the patch.

Do you have any idea what is going on here or suggestions for further troubleshooting?

The output I pasted in my previous message got garbled. Summary: With all four wires connected to the joystick, left and up register “1” when that direction is triggered and then register “-1” when released. Right and down do nothing.

If I disconnect one of the X and one of the Y switches, then the remaining switch registers “0” when triggered and “1” when released.

This is very strange and I have no clue what is causing it. I would have guessed a faulty controller but the replacement I received behaves the same way. Any ideas?

Hello, thanks for you efforts with this but I can’t get it to work either. Would it be possible to upload an image of your working SD to try?

Thanks,

John

I don’t know why everyone is saying this doesn’t work. I worked through these steps the first time without issue. I really appreciate this guide, thanks!!

mkdir ~/modules export MODULESTEMP=~/modules make INSTALLMODPATH=${MODULESTEMP} modules_install

I am at this step and when I type “mkdir ~/modules” I am told that there is “no such file or directory”

I ran though this whole guide and my stick still didnt work. Trying again today so ill update later!

Thanks a lot. I follow your instructions and it help me a lot. I needn’t to rebuild the GPU so, it works at first time.

Thanks, it worked for me without any problem, I used the kernel 3.10.y and I didn’t need to rebuild the GPU.

Thanks, it worked for me without any problem, I used the kernel 3.10.y and I didn’t need to rebuild the GPU. i have used the patch in raspicade image.

hi, thanks for your work, i have pimame 0.7 installed and evtest shows below info. means my joystick works but no action in games … what shall I do ? thank you for your help. Testing … (interrupt to exit) Event: time 1394056060.942335, type 3 (EVABS), code 17 (ABSHAT0Y), value -1 Event: time 1394056060.942353, ——————— SYNREPORT —————— Event: time 1394056061.182354, type 3 (EVABS), code 17 (ABSHAT0Y), value 0 Event: time 1394056061.182373, ——————— SYNREPORT —————— Event: time 1394056065.302760, type 3 (EVABS), code 17 (ABSHAT0Y), value 1 Event: time 1394056065.302778, ——————— SYNREPORT —————— Event: time 1394056065.478737, type 3 (EVABS), code 17 (ABSHAT0Y), value 0 Event: time 1394056065.478753, ——————— SYNREPORT —————— Event: time 1394056068.887106, type 3 (EVABS), code 16 (ABSHAT0X), value -1 Event: time 1394056068.887125, ——————— SYNREPORT —————— Event: time 1394056069.159094, type 3 (EVABS), code 16 (ABSHAT0X), value 0 Event: time 1394056069.159110, ——————— SYNREPORT —————— Event: time 1394056071.511360, type 3 (EVABS), code 16 (ABSHAT0X), value 1 Event: time 1394056071.511378, ——————— SYNREPORT —————— Event: time 1394056071.775358, type 3 (EVABS), code 16 (ABSHAT0X), value 0 Event: time 1394056071.775375, ——————— SYNREPORT ——————

regards.

Thanks a lot for your work. It works fine with a moebius linux (based on raspian). I used a Xin-Mo modules recognized as : THT Arcade console 2P USB Player. Everything is now fine with this interface.

Player one pin 11 12 13 14 → Droite Gauche Haut et Bas

Properties: Testing … (interrupt to exit) Event: time 1396163394.891907, type 3 (EVABS), code 0 (ABSX), value > 1 Event: time 1396163394.891907, ——————— SYNREPORT —————— Event: time 1396163395.035925, type 3 (EVABS), code 0 (ABSX), value 0 Event: time 1396163395.035925, ——————— SYNREPORT —————— Event: time 1396163401.148755, type 3 (EVABS), code 0 (ABSX), value -1 Event: time 1396163401.148755, ——————— SYNREPORT —————— Event: time 1396163401.340781, type 3 (EVABS), code 0 (ABSX), value 0 Event: time 1396163401.340781, ——————— SYNREPORT —————— Event: time 1396163431.008814, type 3 (EVABS), code 1 (ABSY), value > 1 Event: time 1396163431.008814, ——————— SYNREPORT —————— Event: time 1396163431.152831, type 3 (EVABS), code 1 (ABSY), value > 0 Event: time 1396163431.152831, ——————— SYNREPORT —————— Event: time 1396163436.033493, type 3 (EVABS), code 1 (ABSY), value -1 Event: time 1396163436.033493, ——————— SYNREPORT —————— Event: time 1396163436.193522, type 3 (EVABS), code 1 (ABSY), value 0 Event: time 1396163436.193522, ——————— SYNREPORT ——————

player 2 pin 1 2 3 4 → Droite Gauche Haut et Bas

Event: time 1396163736.162272, type 3 (EVABS), code 2 (ABSZ), value 1 Event: time 1396163736.162272, ——————— SYNREPORT —————— Event: time 1396163736.306294, type 3 (EVABS), code 2 (ABSZ), value 0 Event: time 1396163736.306294, ——————— SYNREPORT —————— Event: time 1396163755.172854, type 3 (EVABS), code 2 (ABSZ), value -1 Event: time 1396163755.172854, ——————— SYNREPORT —————— Event: time 1396163755.300881, type 3 (EVABS), code 2 (ABSZ), value 0 Event: time 1396163755.300881, ——————— SYNREPORT —————— Event: time 1396163759.061382, type 3 (EVABS), code 3 (ABSRX), value > 1 Event: time 1396163759.061382, ——————— SYNREPORT —————— Event: time 1396163759.189400, type 3 (EVABS), code 3 (ABSRX), value > 0 Event: time 1396163759.189400, ——————— SYNREPORT —————— Event: time 1396163762.485847, type 3 (EVABS), code 3 (ABSRX), value -1 Event: time 1396163762.485847, ——————— SYNREPORT —————— Event: time 1396163762.597871, type 3 (EVABS), code 3 (ABSRX), value 0 Event: time 1396163762.597871, ——————— SYNREPORT ——————

When I am exporting the modules, i get an error. i entered:

make INSTALLMODPATH=${MODULESTEMP} modulesinstall

and I get the message:

make: * No rule to make target ‘modules_install’. Stop

and my modules folder is empty. Any ideas?

I realised I was calling make from the wrong directory. If anyone has this problem make sure to navigate to the Rpi kernel folder you just built. Cheers!

So my first post problem was that i was calling make from the wrong directory.

However now that everything is complete the Pi is no longer recognizing my Xin-mo controller at all. There’s nothing in the inputs folder and when i try modprob joydev i get the error:

libkmod: ERROR ../libkmod/libkmod.c:554 kmod_ search_moddep: could not open moddep file ‘/lib/modules/3.6.11/modules.dep.bin’

How long it take to complie? I now wait 24h and the ACT LED is still on, after some minutes off and turn on afer 1-2 seconds again…. (and all on a black screen). Any clue how long it will take? :/

Thank you sooo much maan, seriously. It´s been a long time since i was as nervous as when I rebooted my PI at the end. But everything worked perfectly!! You are my savior!

Post a comment

Make sure JavaScript is enabled before posting a comment. If you would like to post a comment but can't, please do send me an e-mail at os3476 at this domain.

Do not meddle in the affairs of Coding Ninjas, for they are subtle and quick to anger.