All of lore.kernel.org
 help / color / mirror / Atom feed
* [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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.