Thread (15 messages) 15 messages, 7 authors, 2015-03-19

Re: [PATCH] HID: sony: Enable Gasia third-party PS3 controllers

From: Benjamin Tissoires <hidden>
Date: 2015-02-07 15:56:53
Also in: lkml

Hi Lauri,

On Sat, Feb 7, 2015 at 8:48 AM, Lauri Kasanen [off-list ref] wrote:
quoted hunk ↗ jump to hunk
Without this, my "Gasia Co.,Ltd PS(R) Gamepad" would not send
any events. Now everything works including the leds.

Based on work by Andrew Haines and Antonio Ospite.

cc: Antonio Ospite <redacted>
cc: Andrew Haines <redacted>
Signed-off-by: Lauri Kasanen <redacted>
---
 drivers/hid/hid-sony.c | 26 ++++++++++++++++++++++++--
 1 file changed, 24 insertions(+), 2 deletions(-)

Antonio's original approach was not enough; it enabled the events,
but only for a few seconds, then the controller timed out and sent
no more. Andrew's did more than was necessary. This is a combination
of the two, against Linus' git.
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 31e9d25..de93386 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -36,6 +36,7 @@
 #include <linux/list.h>
 #include <linux/idr.h>
 #include <linux/input/mt.h>
+#include <linux/usb/input.h>
Please don't.
HID should be transport agnostic, so please refrain from directly call usb.
quoted hunk ↗ jump to hunk
 #include "hid-ids.h"
@@ -1130,8 +1131,12 @@ static void sony_input_configured(struct hid_device *hdev,
  */
 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);
        int ret;
-       char *buf = kmalloc(18, GFP_KERNEL);
+       char *buf = kmalloc(65, GFP_KERNEL);
18 or 65 should be retrieved by the description of the device, not hardcoded.
quoted hunk ↗ jump to hunk
+       unsigned char buf2[] = { 0x00 };
+       int transfered;

        if (!buf)
                return -ENOMEM;
@@ -1140,7 +1145,24 @@ static int sixaxis_set_operational_usb(struct hid_device *hdev)
                                 HID_REQ_GET_REPORT);

        if (ret < 0)
-               hid_err(hdev, "can't set operational mode\n");
+               hid_err(hdev, "can't set operational mode on the control EP\n");
+
+       /*
+        * Some compatible controllers like the Speedlink Strike FX and
+        * Gasia need another query plus an USB interrupt to get operational.
+        */
+       ret = hid_hw_raw_request(hdev, 0xf5, buf, 64, HID_FEATURE_REPORT,
+                                HID_REQ_GET_REPORT);
0xf5 should not be hardcoded. You have to retrieve it from the
description of the device or at least put a special case for your
specific game controller.
+
+       if (ret < 0)
+               hid_err(hdev, "can't set operational mode on the interrupt EP\n");
+
+       ret = usb_interrupt_msg(dev, usb_sndintpipe(dev, 0x02),
+                               buf2, sizeof(buf2),
+                               &transfered, USB_CTRL_SET_TIMEOUT);
Can't you simply use a hid_hw_output_report request instead of hard
coding the device specific endpoint?
And I'd also prefer it to be guarded against your specific controller.


Cheers,
Benjamin
+
+       if (ret < 0)
+               hid_err(hdev, "can't set operational mode on the interrupt EP\n");

        kfree(buf);

--
1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help