SIXAXIS pad over Bluetooth on Ubuntu Precise

Posted: 2012-07-20

Summary

Sony Playstation 3 SIXAXIS pads still don’t work over Bluetooth out of the box in Ubuntu Precise, but might with my repackaged bluez deb. If you prefer to roll your own, running sixpair manually is probably the easiest way to pair if you do it rarely; patches to enable hot-pairing of pads haven’t made it into bluez packages, except Fedora’s and mine. Ubuntu Precise’s bluez also needed a hack to work around an apparent bug that stopped hid-sony from loading, manifesting as /dev/input/js0 appearing but jstest giving no events.

Context

Back in 2007 I bought some PlayStation 3 SIXAXIS pads with a view to using them over Bluetooth for retro gaming on emulators, after seeing the motion tracking and helicopter videos on YouTube that were Linux-driven. OS X’s closed Bluetooth stack made wireless too difficult to bother attempting, so they sat in a box except for the occasional use over USB. On Linux in 2012 (Ubuntu Precise) you might think they’d just work by now.

A Brief History of SIXAXIS on Linux over Bluetooth

Owing to Sony’s “embrace-and-extend”-style use of Bluetooth, two hacks are required to get SIXAXIS working over Bluetooth. One, pairing has to happen while connected over USB. Two, the controller has to be kicked out of the non-standard mode it ends up in after its initial exchange with the host.

The latter (mode) problem is solved, the workaround having made it into a mainline Linux kernel module, hid-sony. In theory the Linux userspace Bluetooth stack, BlueZ, handles an already-paired SIXAXIS just fine in 4.x. Pairing over cables has progressed from being achieved by manually running a special standalone binary to being achieved by a special BlueZ patch that auto-pairs when you plug in. In my opinion BlueZ’s code has always been decent but its support (documentation, maintenance, responsiveness) has always let it down, and the cable-based pairing patch submission is an example, Antonio Ospite’s enthusiasm having been worn away by seeing his clean-up efforts being largely ignored on the linux-bluetooth mailing list. Today it seems you can choose from his various attempts and Fedora’s pairing patch.

Ubuntu

In Ubuntu Precise, sixpair is still the easiest way to pair in my opinion. I did get Fedora’s pairing patch applied and working in Ubuntu Precise (.deb below), but as I only ever use the pads with my laptop and therefore only have to pair once per OS reinstall, I wouldn’t do it again.

After pairing, unplugging and pressing the PlayStation button on the SIXAXIS, I got no events from jstest. The logs said:

Jul 19 19:02:09 jin kernel: [35938.667127] sony 0003:054C:0268.0005: Fixing up Sony Sixaxis report descriptor
Jul 19 19:02:09 jin kernel: [35938.801973] input: Sony PLAYSTATION(R)3 Controller as /devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.2/1-1.2:1.0/input/input16
Jul 19 19:02:09 jin kernel: [35938.802939] sony 0003:054C:0268.0005: input,hiddev0,hidraw1: USB HID v1.11 Joystick [Sony PLAYSTATION(R)3 Controller] on usb-0000:00:1a.0-1.2/input0
Jul 19 19:02:09 jin kernel: [35938.851918] usbcore: registered new interface driver usbhid
Jul 19 19:02:09 jin kernel: [35938.851926] usbhid: USB HID core driver
Jul 19 19:02:55 jin kernel: [35984.370375] usb 1-1.2: USB disconnect, device number 4
Jul 19 19:02:58 jin kernel: [35987.737375] input: PLAYSTATION(R)3 Controller as /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.0/bluetooth/hci0/hci0:11/input17
Jul 19 19:02:58 jin kernel: [35987.738054] generic-bluetooth 0005:0000:0000.0006: input,hidraw0: BLUETOOTH HID v0.00 Joystick [PLAYSTATION(R)3 Controller] on <Bluetooth address deleted>

The “Fixing up Sony Sixaxis report descriptor” message comes from hid-sony.c but didn’t appear for me when connecting over Bluetooth. The cause, though not the root cause, was that the hid-core module only loads hid-blah modules when devices with corresponding registered vendor/product IDs appear. BlueZ passes 0000:0000 when the SIXAXIS connects over Bluetooth meaning that hid-sony never gets called.

I can’t see why this would only affect me but I don’t see any mention of this problem elsewhere. The proper fix would be to make sure vendor/product IDs get copied through to the HID registration, but the linux-bluetooth list’s indifference and unresponsiveness is disheartening and demotivating enough that I can’t even see much point in raising the general bug, so here’s my dirty little hack:

--- ../bluez-4.98-debian-pristine/input/device.c    2011-12-21 22:53:54.000000000 +0000
+++ ../bluez-4.98/input/device.c    2012-07-20 03:43:19.000000000 +0100
@@ -596,8 +596,15 @@
    extract_hid_record(rec, req);
    sdp_record_free(rec);

-   req->vendor = btd_device_get_vendor(idev->device);
-   req->product = btd_device_get_product(idev->device);
+   if (idev->name && strcmp(idev->name, "PLAYSTATION(R)3 Controller") == 0) {
+       req->vendor = 0x054C;
+       req->product = 0x0268;
+       info("Fudged SIXAXIS controller vendor/product IDs to 0x%x/0x%x to trigger hid-sony",
+            req->vendor, req->product);
+   } else {
+       req->vendor = btd_device_get_vendor(idev->device);
+       req->product = btd_device_get_product(idev->device);
+   }
    req->version = btd_device_get_version(idev->device);

    fake_hid = get_fake_hid(req->vendor, req->product);

The impatient-but-trusting might be interested in my repackaged bluez deb, complete with Fedora’s cable-based, hotplug-style pairing and the dirty little patch above. While I promise nothing in terms of support, I’d be interested to know how you get on.

My Ubuntu deb-fu isn’t up to building source packages or PPAs but the monolithic patch (against a freshly unpacked bluez_4.98.orig.tar.gz) which I assembled is available for those who are curious, suspicious and/or want to roll their own.