Coordinate work for Sixaxis support in Linux

Investigation into how Linux on the PS3 might lead to homebrew development.

Moderators: cheriff, emoon

Post Reply
User avatar
ao2
Posts: 28
Joined: Sat Aug 30, 2008 12:26 am

Coordinate work for Sixaxis support in Linux

Post by ao2 »

Hi,

Here’s a summary about what’s needed to integrate the sixaxis support in GNU/Linux systems: http://wiki.ps2dev.org/ps3:linux:sixaxis
Fell free to comment/correct it.

there have been other posts about that in past:
http://forums.ps2dev.org/viewtopic.php?t=7097
http://forums.ps2dev.org/viewtopic.php?t=8274
but I am now aiming to integrate the support in mainline linux/udev/bluez with your collaboration.

Thanks,
Antonio
ps3fanboy
Posts: 66
Joined: Sun Jul 06, 2008 2:03 am

Post by ps3fanboy »

any progress?
User avatar
ao2
Posts: 28
Joined: Sat Aug 30, 2008 12:26 am

Post by ao2 »

ps3fanboy wrote:any progress?
not yet, but now that a first version of Playstation Eye driver has been accepted I can concentrate on this.
speedxl
Posts: 24
Joined: Thu Aug 07, 2008 5:39 am

Post by speedxl »

I think new Yellow Dog Linux has native support for Sixaxis.
ps3fanboy
Posts: 66
Joined: Sun Jul 06, 2008 2:03 am

Post by ps3fanboy »

speedxl wrote:I think new Yellow Dog Linux has native support for Sixaxis.
if that was true, it would have already shown up in the 2.6.27 kernel, wouldn't it?
speedxl
Posts: 24
Joined: Thu Aug 07, 2008 5:39 am

Post by speedxl »

Well if you do not believe me, then i guess you can believe terrasoft.. (well actually they were bought by Fixstars and they released this new version)
as they posted this:

Yellow Dog Linux v6.1 supports:
- Sony PS3.
- Apple PowerPC G4, G5.
- YDL PowerStation.
- IBM System p (JS2x, 510, 520, 540).

Yellow Dog Linux v6.1 offers these updates over v6.0:
- Kernel 2.6.27
- GCC 4.1.2
- Cell SDK 3.1
- Firefox 3.0
- OpenOffice 2.3 (v3.0 coming to YDL.net Enhanced soon!)
- X.org 1.4.999 with xrandr 1.2.2
- Dramatically improved, automated wireless config.
- GUI configuration tool for YDL.net.
- Bluetooth support for the PS3 Sixaxis controller.
- Barcelona Supercomputing Center CellSs.
- ps3vram for fast, temp file storage or swap using PS3 video RAM.

this is the link to the webpage
www.terrasoftsolutions.com/news/2008/2008-11-19.shtml

another link with useful info and resources for development about cell
http://us.fixstars.com/showcase/cellebration/

another comment i read, was that they will shift the development a little more to support cell..

That are good news!
ps3fanboy
Posts: 66
Joined: Sun Jul 06, 2008 2:03 am

Post by ps3fanboy »

that sounds promising ;-)
User avatar
ao2
Posts: 28
Joined: Sat Aug 30, 2008 12:26 am

Post by ao2 »

speedxl wrote: - Bluetooth support for the PS3 Sixaxis controller.
are accelerometer values exposed? If anyone tries it out, please report.

Thanks.
User avatar
tolysz
Posts: 7
Joined: Fri Jan 02, 2009 12:40 am

Post by tolysz »

ao2 wrote:
speedxl wrote: - Bluetooth support for the PS3 Sixaxis controller.
are accelerometer values exposed? If anyone tries it out, please report.

Thanks.
BT is supported only because bluez-utils i.e. the bluetooth stack is supporting it :) so it is the same support like everywhere else.
And I bet USB is not working, as just a few days ago I had submitted a patch fixing it.

But this will give you far superior :) support of sixaxis:
Accelerometers are working fine :)
Just need to dive into PID specification for rumble
and LED :)

And the best part is: I have written it :)
http://forums.ps2dev.org/viewtopic.php?t=11488

Worst case scenario: I've seen it working so with a little bit of feedback
YOU may se it working too :)
Last edited by tolysz on Mon Jan 05, 2009 1:46 am, edited 1 time in total.
User avatar
ao2
Posts: 28
Joined: Sat Aug 30, 2008 12:26 am

Post by ao2 »

tolysz wrote:
ao2 wrote:
speedxl wrote: - Bluetooth support for the PS3 Sixaxis controller.
are accelerometer values exposed? If anyone tries it out, please report.

Thanks.
BT is supported only because bluez-utils i.e. the bluetooth stack is supporting it :) so it is the same support like everywhere else.

But this will give you far superior :) support of sixaxis:
Accelerometers are working fine :)
Just need to dive into PID specification for rumble
and LED :)

And the best part is: I have written it :)
http://forums.ps2dev.org/viewtopic.php?t=11488

Worst case scenario: I've seen it working so with a little bit of feedback
YOU may se it working too :)
tolysz, have you asked linux-input for feedback?
I don't know if your approach will be accepted mainline, you are remapping the descriptor, while other joypad drivers I've seen around just _decode_ it and generate input events.

What about asking to linux-input what is the way to go before putting further effort in this?

About setting the joypad _fully_ operational for bluetooth, I thougth we can use a sysfs custom interface, and a udev rule that set the BT controller address for the joypad, something like this (for older kernels):

Code: Select all

diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 27fe4d8..4787465 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -676,14 +676,127 @@ static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid)
 }
 
 /*
+ * Show and set the master bdaddr for PS3 controller, without disconnecting
+ * the device.
+ */
+static ssize_t show_sixaxis_master_bdaddr(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	int ret;
+	unsigned char *mbuf = kzalloc(9, GFP_KERNEL);
+	struct usb_device *udev = to_usb_device(dev);
+	int len = 18; /* "00:00:00:00:00:00\n" */
+	/*
+	 * FIXME, ifnum should be obtained with something like:
+	 *
+	 * struct usb_interface *intf = to_usb_interface(dev);
+	 * int ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
+	 *
+	 * but I must be doing something wrong because this doesn't work, so:
+	 */
+	int ifnum = 0;
+
+	if (!mbuf)
+		return -ENOMEM;
+
+	ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+				 HID_REQ_GET_REPORT,
+				 USB_DIR_IN | USB_TYPE_CLASS |
+				 USB_RECIP_INTERFACE,
+				 &#40;3 << 8&#41; | 0xf5, ifnum, mbuf, 8,
+				 USB_CTRL_GET_TIMEOUT&#41;;
+	if &#40;ret < 0&#41; &#123;
+		err_hid&#40;"%s failed&#58; %d\n", __func__, ret&#41;;
+		printk&#40;KERN_DEBUG "%02x&#58;%02x&#58;%02x&#58;%02x&#58;%02x&#58;%02x\n",
+			mbuf&#91;2&#93;, mbuf&#91;3&#93;, mbuf&#91;4&#93;, mbuf&#91;5&#93;, mbuf&#91;6&#93;, mbuf&#91;7&#93;&#41;;
+
+		kfree&#40;mbuf&#41;;
+		return -EINVAL;
+	&#125;
+
+	ret = snprintf&#40;buf, len, "%02x&#58;%02x&#58;%02x&#58;%02x&#58;%02x&#58;%02x\n",
+			mbuf&#91;2&#93;, mbuf&#91;3&#93;, mbuf&#91;4&#93;, mbuf&#91;5&#93;, mbuf&#91;6&#93;, mbuf&#91;7&#93;&#41;;
+
+	kfree&#40;mbuf&#41;;
+
+	return ret;
+&#125;
+
+static ssize_t store_sixaxis_master_bdaddr&#40;struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count&#41;
+&#123;
+	int ret;
+	int mac&#91;6&#93;;
+	unsigned char *mbuf = kzalloc&#40;9, GFP_KERNEL&#41;;
+	struct usb_device *udev = to_usb_device&#40;dev&#41;;
+	/*
+	 * FIXME, ifnum should be obtained with something like&#58;
+	 *
+	 * struct usb_interface *intf = to_usb_interface&#40;dev&#41;;
+	 * int ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
+	 *
+	 * but I must be doing something wrong because this doesn't work, so&#58;
+	 */
+	int ifnum = 0;
+
+	ret = sscanf&#40;buf, "%02x&#58;%02x&#58;%02x&#58;%02x&#58;%02x&#58;%02x",
+			&mac&#91;0&#93;, &mac&#91;1&#93;, &mac&#91;2&#93;, &mac&#91;3&#93;, &mac&#91;4&#93;, &mac&#91;5&#93;&#41;;
+	if &#40;ret != 6&#41; &#123;
+		printk&#40;KERN_DEBUG "%s&#58; failed, ret&#58; %d\n", __func__, ret&#41;;
+		return -EINVAL;
+	&#125;
+
+	mbuf&#91;0&#93; = 0x01;
+	mbuf&#91;1&#93; = 0x00;
+	mbuf&#91;2&#93; = mac&#91;0&#93;;
+	mbuf&#91;3&#93; = mac&#91;1&#93;;
+	mbuf&#91;4&#93; = mac&#91;2&#93;;
+	mbuf&#91;5&#93; = mac&#91;3&#93;;
+	mbuf&#91;6&#93; = mac&#91;4&#93;;
+	mbuf&#91;7&#93; = mac&#91;5&#93;;
+
+	printk&#40;KERN_DEBUG "%s&#58; %02x&#58;%02x&#58;%02x&#58;%02x&#58;%02x&#58;%02x\n", __func__,
+		mbuf&#91;2&#93;, mbuf&#91;3&#93;, mbuf&#91;4&#93;, mbuf&#91;5&#93;, mbuf&#91;6&#93;, mbuf&#91;7&#93;&#41;;
+
+	ret = usb_control_msg&#40;udev, usb_sndctrlpipe&#40;udev, 0&#41;,
+				 HID_REQ_SET_REPORT,
+				 USB_DIR_OUT | USB_TYPE_CLASS |
+				 USB_RECIP_INTERFACE,
+				 &#40;3 << 8&#41; | 0xf5, ifnum, mbuf, 8,
+				 USB_CTRL_GET_TIMEOUT&#41;;
+
+	kfree&#40;mbuf&#41;;
+
+	if &#40;ret < 0&#41; &#123;
+		err_hid&#40;"%s failed&#58; %d\n", __func__, ret&#41;;
+		return ret;
+	&#125;
+
+	return count;
+&#125;
+
+static DEVICE_ATTR&#40;sixaxis_master_bdaddr, S_IWUSR|S_IRUGO,
+		show_sixaxis_master_bdaddr, store_sixaxis_master_bdaddr&#41;;
+
+static struct attribute *sixaxis_attributes&#91;&#93; = &#123;
+	&dev_attr_sixaxis_master_bdaddr.attr,
+	NULL
+&#125;;
+
+static const struct attribute_group sixaxis_attr_group = &#123;
+	.attrs = sixaxis_attributes,
+&#125;;
+
+/*
  * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller
  * to "operational".  Without this, the ps3 controller will not report any
  * events.
  */
+
 static void hid_fixup_sony_ps3_controller&#40;struct usb_device *dev, int ifnum&#41;
 &#123;
 	int result;
-	char *buf = kmalloc&#40;18, GFP_KERNEL&#41;;
+	unsigned char *buf = kmalloc&#40;18, GFP_KERNEL&#41;;
 
 	if &#40;!buf&#41;
 		return;
@@ -697,6 +810,9 @@ static void hid_fixup_sony_ps3_controller&#40;struct usb_device *dev, int ifnum&#41;
 
 	if &#40;result < 0&#41;
 		err_hid&#40;"%s failed&#58; %d\n", __func__, result&#41;;
+	else
+		printk&#40;KERN_INFO "Sony PS3 Controller bdaddr&#58; %02x&#58;%02x&#58;%02x&#58;%02x&#58;%02x&#58;%02x\n",
+				buf&#91;4&#93;, buf&#91;5&#93;, buf&#91;6&#93;, buf&#91;7&#93;, buf&#91;8&#93;, buf&#91;9&#93;&#41;;
 
 	kfree&#40;buf&#41;;
 &#125;
@@ -951,6 +1067,10 @@ static void hid_disconnect&#40;struct usb_interface *intf&#41;
 	del_timer_sync&#40;&usbhid->io_retry&#41;;
 	cancel_work_sync&#40;&usbhid->reset_work&#41;;
 
+	if &#40;hid->quirks & HID_QUIRK_SONY_PS3_CONTROLLER&#41;
+		sysfs_remove_group&#40;&interface_to_usbdev&#40;intf&#41;->dev.kobj,
+				&sixaxis_attr_group&#41;;
+
 	if &#40;hid->claimed & HID_CLAIMED_INPUT&#41;
 		hidinput_disconnect&#40;hid&#41;;
 	if &#40;hid->claimed & HID_CLAIMED_HIDDEV&#41;
@@ -1003,10 +1123,19 @@ static int hid_probe&#40;struct usb_interface *intf, const struct usb_device_id *id&#41;
 	if &#40;&#40;hid->claimed & HID_CLAIMED_INPUT&#41;&#41;
 		hid_ff_init&#40;hid&#41;;
 
-	if &#40;hid->quirks & HID_QUIRK_SONY_PS3_CONTROLLER&#41;
+	if &#40;hid->quirks & HID_QUIRK_SONY_PS3_CONTROLLER&#41; &#123;
 		hid_fixup_sony_ps3_controller&#40;interface_to_usbdev&#40;intf&#41;,
 			intf->cur_altsetting->desc.bInterfaceNumber&#41;;
 
+		/* Register sysfs hooks */
+		i = sysfs_create_group&#40;&interface_to_usbdev&#40;intf&#41;->dev.kobj,
+				&sixaxis_attr_group&#41;;
+		if &#40;i < 0&#41;&#123;
+			printk&#40;KERN_DEBUG "%s&#58; cannot register sixaxis sysfs hooks\n",
+					__func__&#41;;
+		&#125;
+	&#125;
+
 	printk&#40;KERN_INFO&#41;;
 
 	if &#40;hid->claimed & HID_CLAIMED_INPUT&#41;
If we want to discuss all this on linux-input, please tell me and I'll subcribe.

Regards, ao2
User avatar
tolysz
Posts: 7
Joined: Fri Jan 02, 2009 12:40 am

Post by tolysz »

ao2 wrote: tolysz, have you asked linux-input for feedback?
I don't know if your approach will be accepted mainline, you are remapping the descriptor, while other joypad drivers I've seen around just _decode_ it and generate input events.

What about asking to linux-input what is the way to go before putting further effort in this?

About setting the joypad _fully_ operational for bluetooth, I thougth we can use a sysfs custom interface, and a udev rule that set the BT controller address for the joypad, something like this (for older kernels):

If we want to discuss all this on linux-input, please tell me and I'll subcribe.

Regards, ao2
I just need to wait for regression tests :) as I do not want to make silly posts on: linux-input; linux-bluetooth; linux-usb; (as Linus might see it :p)

I have patched all devices using that code so I am covered :) However regression is very important.

My solution is very general, it will apply to any device, even not a native HID one. Only if we had a fake driver and some user land. It would speed-up development as you would just design a descriptor.

I was thinking about sysfs myself - but you know - it is to much for one patch and is dangerous.

I wanted to be able to remap descriptor "on line" almost on per application basis :) using sysfs of course :)

I have written this driver overnight - it works for me :) but is it working for you?

And that code of yours seams to: just embeding sixpair.c :) as rest is already in mainline. and does not support DS3 :( [as this guy requires BT equivalent of make operational]


Happy Hacking


BTW. Yesterday, I had something similar but much less mature as yours is, but I decided to make only small changes with big implications and left it out.
Post Reply