Linux Wii Remote Driver Updates

Linux Bluetooth HID handling has been slightly broken in the kernel since several years. Reconnecting devices caused a kernel oops nearly every time you tried. Two months ago I sat down and rewrote the HIDP session handling and fixed several bugs. The series now got merged and will be part of linux-3.10. If you still encounter bugs please leave me a note.

Based on this I tried recovering my hid-wiimote work. Since the last time I reverse-engineered Nintendo devices, a lot has happened. The most significant change is probably the release of the Wii U. While the Gamepad is still an ongoing target for r/e, other devices were much easier to get working. Motivated by the new hardware I just got, I finally figured out a reliable way for extension hotplugging. This wasn’t supported in the kernel until now and required nasty polling-techniques to work around race-conditions in the proprietary protocol (who designs asynchronous protocols without protocol barriers?). So I rewrote most of the core device handling and moved the input parsers to a module based infrastructure. This allows us to easily extend the hid-wiimote driver to support new devices that are based on the same protocol.

The series is still pending on the linux-input ML but I hope to get basic hotplugging support into linux-3.10. Further support for the built-in speaker device or the Wii U Pro Controller will hopefully follow with 3.11.

The xwiimote user-space stack has already been updated and I will push the changes this weekend.

34 thoughts on “Linux Wii Remote Driver Updates

  1. gralco

    This is awesome David, you are my hero! I have a Wii U Pro Controller and want so badly to use it, thank you so much for working on this. I’m going to have to keep an eye on this blog of yours in case of future updates. Thanks again!

    Reply
    1. David Herrmann Post author

      You’re welcome. The patches will definitely go into linux-3.11, but I don’t think I can get them into linux-3.10. I will send the HID patches out later today so Jiri can review them. But it’s quite likely they go straight in.
      The curious can compile linux-next then to get a sneak preview.

      Reply
      1. gralco

        Is this patch available in the 3.11 RCs? Are you still confident it will be in 3.11 when it is completely released?

      2. gralco

        I am attempting to connect my Wii U Pro Controller using GNOME’s “Bluetooth New Device Setup” tool. I have kernel-3.11.1-200.fc19 (64-bit), I have select “Automatic PIN selection” although after attempting to establish a connection with the device I receive the message “Setting up ‘Nintendo RVL-CNT-01-UC’ failed”. When using my Wiimote’s red visibility button I am able to establish a connection with it. Is my kernel still missing support for the Pro Controller?

      3. David Herrmann Post author

        Sorry for the delay, was on vacation.
        Could you tell me what “bluez” version you are running? It is very likely that your bluetooth stack just lacks support for Pro-Controllers (which is needed to select the correct binary PIN for these devices).

  2. Andreas

    Hi David,
    this is awesome work…
    Do you have some public git-repo for the new rework you’re doing ?
    I’ve seen http://article.gmane.org/gmane.linux.kernel.input/30147 and I’d like to do some testing, but I don’t know, what to base this on ?
    Would you also have some pointers on what the required base is (especially the bluetooth reconnect stuff) would be ?
    I’d like to cherry pick a little for my ubuntu-3.8 kernel…

    Thanks for any pointers and the work on wiimote…
    (looking forward to kmscon as well)

    Cheers,
    Andreas

    Reply
    1. David Herrmann Post author

      freedesktop.org is currently too slow, so I will try tomorrow again. But you will then find it at http://cgit.freedesktop.org/~dvdhrm/linux
      However, the patches on the mailing-list should work, too. I hope Jiri will apply them soon so people can cherry-pick them. They will also be available in linux-next then.
      The bluetooth-HIDP rework is already available in linux-next and in Linus’ 3.10-rc1 tree. So they should be available with the linux-3.10 release in about 2 months.

      Reply
      1. Andreas

        Thanks a lot… This is awesome…
        I’ll try this out as soon as I have the time and motivation…😀

      2. Andreas

        Thanks again for the great work !
        To anyone interessted, this is easy as hell…😀

        I could relatively easily rebase the wiimote-branch to torvalds-git v3.9.0 on Ubuntu 13.10.
        – 1 merge conflict (just used dvdhrm/wiimote over torvalds-HEAD)
        – Patch from https://patchwork.kernel.org/patch/2244921/
        – Deactivate Logitec HID-Drivers in menuconf (some implicite function declaration)
        (to anyone interested: http://mapopa.blogspot.de/2009/01/compiling-2.html for Ubuntu-Kernel-Compile)

        Ubuntu (for paring the -TR 2nd Generation WiiMotes):
        – Patch Bluez-Package: plugins/wiimote.c 78+: g_str_equal(name, “Nintendo RVL-CNT-01-TR”) || (vendor == 0x057e && product == 0x0330) ||

        xwiishow works like a charm…
        Letz see for the x-input-driver now so I can finally rc my xbmc…😀

        Cheers,
        Andreas

      3. David Herrmann Post author

        Thanks for the great feedback! The problem with x-input-drivers is that it is hard to tell how to interpret Wii-Remote input. The only thing supported is button-mappings, but this can be easily achieved via simple mapping-tables+uinput. Therefore, I never bothered maintaining the xf86-input-wiimote driver. Furthermore, interest in this is pretty low.. that’s not exactly the best motivation.

      4. Andreas

        Ok, I found a bug where MotionPlus-Sensor was not initialized on Gen20 Devices (without Plugged In extensions)

        Don’t know, where else to post this patch to…😉

        From 360392764992473ea569fc07697ba4d1bfe72b15 Mon Sep 17 00:00:00 2001
        From: AF
        Date: Mon, 20 May 2013 12:54:32 +0200
        Subject: [PATCH] Fix for Built-in MoptionPlus

        MP did not initialize on Gen20 Devices with no plugged in extensions.
        Manually trigger HotPlug on device Init now to avoid this.

        drivers/hid/hid-wiimote-core.c | 1 +
        1 file changed, 1 insertion(+)

        diff –git a/drivers/hid/hid-wiimote-core.c b/drivers/hid/hid-wiimote-core.c
        index 89118e9..46be2b8 100644
        — a/drivers/hid/hid-wiimote-core.c
        +++ b/drivers/hid/hid-wiimote-core.c
        @@ -1244,6 +1244,7 @@ static void wiimote_init_worker(struct work_struct *work)

        if (wdata->state.devtype == WIIMOTE_DEV_PENDING) {
        wiimote_init_detect(wdata);
        + wiimote_init_hotplug(wdata);
        changed = true;
        }


        1.7.10.4

  3. BlackLotus

    A few months ago when I first tried the Wii U Pro controller with mupen64plus I got regular crashes and hangs and I said to myself I will try it again later on maybe it will all get fixed.Tried it again today the crash only affected mupen64plus this time so here is my dmesg output http://bpaste.net/show/132504/
    I can’t really tell when the problem exactly appears it can range from 20minutes up until 2 hours into the game and I can’t find a relation to anything particular I did at that time.
    Like the dmesg log says the kernel version is 3.11.0-1-09747-gff812d7-dirty and I use the mupen64plus 2.0 stable release.

    Reply
    1. David Herrmann Post author

      It’s a race-condition/deadlock in the force-feedback code. So if you disable force-feedback support (or “rumble”) it will not happen again (given mupen64plus has an option to disable it). I am currently in the US for 2 weeks. I don’t know whether I can prepare a fix before I get home. Thanks a lot for reporting it!

      Reply
      1. BlackLotus

        I hope you had a nice vacation🙂
        Just a few follow up questions:
        1) Was it intentional that up and down are swapped on analog?
        2) How would you add an auto connect function?Once upon a time (I remember it like yesterday) I somehow managed without a problem that my bluetooth keyboard auto connected on boot.Now I need a littlte script that polls frequently for the device.There is a better way I just forgot/something is buggy?
        Thank you for your work and time btw🙂
        Regards,
        BlackLotus

  4. BlackLotus

    My script is simpler as it only checks if a hidd server is running and starts one if necessary (hidd –server –connect is enough to connect to the remote).
    And yes exactly
    Positive is up,negative is down.
    I got 2 additional controlers lying here and both got up negative down positive.Also I got the wii u pro controller config of a mac user, also like my other controllers it’s negative up, positive down.
    Maybe it’s something that’s defined somewhere and I’m totally wrong and the inverse way is the right way somehow, but I thought I should let you know.

    Reply
    1. David Herrmann Post author

      Ouh, but it requires you to trigger the connect on the host, right? With autoreconnect you run the script _once_ to enable it and then never again. Newer bluetoothd (at least since >4.98) have hidd builtin and listen automatically for incoming connections. So a simple click on _any_ button on the remote causes it to connect to your host.

      Anyhow, the axis I might have screwed up. I thought the inverse is right. Considering that every kernel gamepad driver sents the data _totally_ differently, I don’t care that much, but I will try to fix up the kernel documentation for the gamepad API so this doesn’t happen again (assuming you’re correct). Thanks for the hints!

      Btw., the fix for the deadlock is pending on linux-input ML. Will probably take 1 month until it reaches the stable trees, though. (http://www.spinics.net/lists/linux-input/msg27693.html)

      Reply
  5. BlackLotus

    Yeah I was/am kinda too lazy to get this working since the xwiimote tools require bluez version 4 and I didn’t want to cripple my existing setup.
    Thx it doesn’t matter really but some projects want to automaticly recognize as many controllers as possible (for instance retroarch is working hard on this right now) and if one controller is mapped different across all systems I gues it’s not that convenient (depends on the input method you choose I guess).
    Thx again for the driver🙂 and quick responses

    Reply
    1. BlackLotus

      Oh and btw I switched back to bluez4 (this was actually about 2 months ago) because bluez 5 somehow couldn’t auto reconnect to devices (seems to be a known problem found many people reporting this) and bluez4 having most of the programs (blueman and co only work with bluez4) .
      I tested bluez 4.1 and bluez 5.9 maybe I really have to use bluez >4.98 && <5.0
      I will test this maybe in a while:/

      Reply
      1. David Herrmann Post author

        You use bluez-4.1? Wow, that thing is more than 5 years old. Anyhow, I know that bluez-5 hasn’t been integrated into any major distribution except Arch, yet. It will take some time.

        Regarding gamepad-mappings: Every supported gamepad in the linux kernel reports data differently. It’s a mess so we currently require user-space fixups for each and every gamepad. We’re working on that.

      2. blacklotus89

        Yeah I would use bluez5 if it would have a gui I could use.Bluetooth is one of the few things that should work convenient because I use it for game or media systems or mobile use.

        And the xwiimote script you linked doesn’t work with bluez5 does it?

        I used the gamepad with bluez 5 but couldn’t get it to automagicly connect at reboot. I will try it again soon but right now the implementations don’t suffice for me…. after over 5 years!

  6. BlackLotus

    Btw don’t know if I mentioned it but the Wii U Gamepads analog sticks seem to be calibrated weirdly.What I mean by this is as follows:
    Normally when I play games that require a sensitive analog stick (for instance for emulation) it works out of the box and when I press the analog stick half way the character walks and if I press it full the character runs.
    With the Wii U Gamepad my character walks if I press it half way and he walks if I press it completly.
    Sorry for not being able to correctly phrase what I mean,but I hope you get it anyway. (btw if I want to really report bugs is there a specific bug tracker I should use?)

    Reply
    1. David Herrmann Post author

      The Wii-U Gamepad is not supported, yet (work is being done). I guess you’re talking about the Pro-Controller?
      There are 2 patches for the analog sticks on the pro-controller currently being backported. One of them fixes the inverted y-axes, the other one fixes the wrong MAX values. We reported bigger MAX values than the device could actually support. Thus probably causing your issues. So the next 3.11/3.12 stable releases should hopefully fix that.

      Patches available here:
      http://git.kernel.org/cgit/linux/kernel/git/jikos/hid.git/commit/?h=for-3.13/wiimote&id=08072dde333c2f09114a01b0bd32be52ecce195b

      Reply
  7. dothebart

    I want to measure my weight using the balance board in an application (pytrainer)
    but I wouldn’t want to run that as root;
    what would be the best way to implement that? does the Xorg driver allow to do that?
    i’ve got the recent xwiimote source compiled & configured; xwiishow properly displays the input values of the balance board and the wiimotes;
    (btw, the list command could also show the devicetype, not only the address)
    Do I neet to upgrade the bluetooth stack and add the xorg driver in order to continue?
    where would I then continue RTFM howto use the x inputs?
    or should one implement some deamon exposing the input to some unix domain socket the user app then could bind?

    Reply
    1. David Herrmann Post author

      Neither Xorg nor Wayland have come up with a proper input-API for devices beyond standard input devices. Therefore, you either have to try tunneling the balance-board data to your client as a gamepad or joystick (or similar), or you need to use udev to make the balance-board input-device world-readable (chmod o+r /dev/input/eventXYZ). The xf86-input-xwiimote driver has nothing to do with that. It’s only a proof-of-concept to use wiimote-input as mouse-emulation.

      Reply
  8. dothebart

    ok, took me a while to find the s in driverS; now my
    /etc/udev/rules.d/99-wii.rules
    is:
    SUBSYSTEM==”input”, DRIVERS==”wiimote”, MODE:=”660″, GROUP=”games”
    which makes all created nodes to be group read/writeable by ‘games’.
    this seems to be an appropriate solution to get to the real work.

    Reply
  9. gralco

    For some reason the joystick (Wii U Pro controller) takes control of the mouse and forces it to be in the center of the screen and will only move in an ellipse shape whilst using the analog stick. Using QJoyPad doesn’t seem to really work (although it is recognized). Dolphin on the other hand recognizes the controller and is able to map all except for the analog sticks (both).

    I am using Fedora 20 (3.12.5-302.fc20.x86_64)

    Reply
    1. David Herrmann Post author

      That’s because Xorg thinks it’s a mouse even though it’s a gamepad. Please report that to the Xorg (or QJoyPad) developers. I only work on the kernel side. There is no easy way for me to configure the Xorg drivers so they have to deal with it themselves, sorry.

      Reply
    2. Chad

      I too hit this exact issue. The trick is to tell XOrg to ignore the device. I’m running Fedora 3.17.7-200.fc20.x86_64

      Here is what I did:
      1) Edit /usr/share/X11/xorg.conf.d/10-evdev.conf
      2) Add the following before any of the other InputClass sections
      Section “InputClass”
      Identifier “Wii Pro Controller”
      MatchProduct “Nintendo”
      Option “Ignore”
      EndSection

      3) Restart X

      Now the Wii U Pro Controller works as a joystick, and isn’t treated as a mouse. (note, this may interfere with the WiiMote, but since the IR part doesn’t work yet, not a big loss)

      Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s