* [PATCH] ps3 controller clone
@ 2013-12-22 23:26 Andrew Haines
0 siblings, 0 replies; only message in thread
From: Andrew Haines @ 2013-12-22 23:26 UTC (permalink / raw)
To: linux-input
[-- Attachment #1: Type: text/plain, Size: 1200 bytes --]
Hi this is my first kernel patch.
I have a ps3 controller clone that dmesg calls "Gasia Co.,Ltd PS(R)
Gamepad." When I plugged it in it was recognized but did not send any
output. After some searching I found
http://www.spinics.net/lists/linux-input/msg18172.html and changed my
kernel according to the patch on that email which didn't fix the
problem. I installed wireshark and connected the controller to
Windows(VirtualBox) and came up with the solution in the attached patch.
My controller needed the additional
hdev->hid_get_raw_report(hdev, 0xf5, buf, 64, HID_FEATURE_REPORT)
and an interrupt set.
I tried to use the newer hdev->hid_output_raw_report rather than calling
usb_interrupt_msg but I think usbhid->urbout is null in
usbhid_output_raw_report since it gets sent as a SET_REPORT instead of
URB_INTERRUPT out.
I did a little testing and running testrumble just after the controller
is attached does initialize the controller so that the buttons send
output. (Only with the additional hid_get_raw_report(hdev, 0xf5...)
I'm completely new to the kernel and have no idea how to allocate
urbout. I did some searching but I'm not sure where to look.
Regards,
Andrew Haines
[-- Attachment #2: sony-hid-clone.patch --]
[-- Type: text/x-patch, Size: 1858 bytes --]
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 098af2f8..c2bab2b 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -426,16 +426,46 @@ static int sixaxis_usb_output_raw_report(struct hid_device *hid, __u8 *buf,
*/
static int sixaxis_set_operational_usb(struct hid_device *hdev)
{
+ struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
+ struct usb_device *dev = interface_to_usbdev(intf);
+ //struct usbhid_device *usbhid = hdev->driver_data;
int ret;
- char *buf = kmalloc(18, GFP_KERNEL);
+ int transfered;
+ char *buf = kmalloc(65, GFP_KERNEL);
+ unsigned char buf2[] = {
+ 0x01,
+ 0x00, 0xff, 0x00, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x1e, // led flags 1e = all
+ 0xff, 0x27, 0x10, 0x00, 0x32,
+ 0xff, 0x27, 0x10, 0x00, 0x32,
+ 0xff, 0x27, 0x10, 0x00, 0x32,
+ 0xff, 0x27, 0x10, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00
+ };
if (!buf)
return -ENOMEM;
ret = hdev->hid_get_raw_report(hdev, 0xf2, buf, 17, HID_FEATURE_REPORT);
-
+
if (ret < 0)
hid_err(hdev, "can't set operational mode\n");
+ else {
+ /* Some compatible controllers like the Speedlink Strike FX and
+ * Gasia need a write to the Interrupt EP to get operational */
+ hdev->hid_get_raw_report(hdev, 0xf5, buf, 64, HID_FEATURE_REPORT);
+
+ // doesn't work. gets sent as a SET_REPORT Request intstead of a
+ // URB_INTERRUPT out. I guess usbhid->urbout is null
+ //if ( hdev->hid_output_raw_report(hdev, buf2, sizeof(buf2),
+ // HID_OUTPUT_REPORT) < 0 )
+ // hid_err(hdev, "can't set initial interrupt. Cloned controllers may not operate\n");
+
+ if ( usb_interrupt_msg(dev, usb_sndintpipe(dev, 0x02),
+ buf2, sizeof(buf2),
+ &transfered, USB_CTRL_SET_TIMEOUT))
+ hid_err(hdev, "can't set initial interrupt. Cloned controllers may not operate\n");
+ }
kfree(buf);
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2013-12-22 23:33 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-12-22 23:26 [PATCH] ps3 controller clone Andrew Haines
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox