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);