|
1 |
| ---- a/drivers/hid/hid-sony.c 2018-11-15 05:39:31.762572258 +0000 |
2 |
| -+++ b/drivers/hid/hid-sony.c 2018-11-15 05:38:55.762745843 +0000 |
3 |
| -@@ -2067,6 +2067,7 @@ |
| 1 | +From: Martyn Welch < [email protected]> |
| 2 | +To: Jiri Kosina < [email protected]>, |
| 3 | + Benjamin Tissoires < [email protected]> |
| 4 | + |
| 5 | + |
| 6 | + |
| 7 | +Subject: [PATCH] HID: Sony: Add support for Gasia controllers |
| 8 | +Date: Sun, 26 Jan 2020 19:45:13 +0000 |
| 9 | +Message-ID: < [email protected]> (raw) |
| 10 | + |
| 11 | +There seems to be a number of subtly different firmwares for the |
| 12 | +Playstation controllers made by "Gasia Co.,Ltd". Whilst such controllers |
| 13 | +are easily detectable when attached via USB that is not always the case |
| 14 | +via Bluetooth. Some controllers are named "PLAYSTATION(R)3 Controller" |
| 15 | +where as the official Sony controllers are named |
| 16 | +"Sony PLAYSTATION(R)3 Controller", however some versions of firmware use |
| 17 | +the exact name used by the official controllers. The only way I've been |
| 18 | +able to distinguish these versions of the controller (when connected via |
| 19 | +Bluetooth) is that the Bluetooth Class of Device incorrectly reports the |
| 20 | +controller as a keyboard rather than a gamepad. I've so far failed to work |
| 21 | +out how to access this information from a HID driver. |
| 22 | + |
| 23 | +The Gasia controllers need output reports to be configured in the same way |
| 24 | +as the Shanwan controllers. In order to ensure both types of Gasia firmware |
| 25 | +will work, this patch adds a quirk for those devices it can detect and |
| 26 | +reworks `sixaxis_send_output_report()` to attempt `hid_hw_output_report()` |
| 27 | +should `hid_hw_raw_request()` be known to be the wrong option (as is the |
| 28 | +case with the Shanwan controllers) or fails. |
| 29 | + |
| 30 | +This has got all the controllers I have working, with the slight |
| 31 | +anoyance that the Gasia controllers that don't currently get marked with |
| 32 | +a quirk require the call to `hid_hw_raw_request()` to fail before the |
| 33 | +controller finishes initialising (which adds a significant extra delay |
| 34 | +before the controller is ready). |
| 35 | + |
| 36 | +This patch is based on the following patch by Conn O'Griofa: |
| 37 | + |
| 38 | +https://github.com/RetroPie/RetroPie-Setup/pull/2263/commits/017f00f6e15f04b3272ff1abae8742dc4c47b608 |
| 39 | + |
| 40 | +Cc: Conn O'Griofa < [email protected]> |
| 41 | +Signed-off-by: Martyn Welch < [email protected]> |
| 42 | +--- |
| 43 | + drivers/hid/hid-sony.c | 31 +++++++++++++++++++++++++------ |
| 44 | + 1 file changed, 25 insertions(+), 6 deletions(-) |
| 45 | + |
| 46 | +diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c |
| 47 | +index 4c6ed6ef31f1..d1088a85cb59 100644 |
| 48 | +--- a/drivers/hid/hid-sony.c |
| 49 | ++++ b/drivers/hid/hid-sony.c |
| 50 | +@@ -56,6 +56,7 @@ |
| 51 | + #define NSG_MR5U_REMOTE_BT BIT(14) |
| 52 | + #define NSG_MR7U_REMOTE_BT BIT(15) |
| 53 | + #define SHANWAN_GAMEPAD BIT(16) |
| 54 | ++#define GASIA_GAMEPAD BIT(17) |
| 55 | + |
| 56 | + #define SIXAXIS_CONTROLLER (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT) |
| 57 | + #define MOTION_CONTROLLER (MOTION_CONTROLLER_USB | MOTION_CONTROLLER_BT) |
| 58 | +@@ -2067,6 +2068,7 @@ static void sixaxis_send_output_report(struct sony_sc *sc) |
4 | 59 | struct sixaxis_output_report *report =
|
5 | 60 | (struct sixaxis_output_report *)sc->output_report_dmabuf;
|
6 | 61 | int n;
|
7 |
| -+ int ret; |
| 62 | ++ int ret = -1; |
8 | 63 |
|
9 | 64 | /* Initialize the report with default values */
|
10 | 65 | memcpy(report, &default_report, sizeof(struct sixaxis_output_report));
|
11 |
| -@@ -2101,9 +2101,18 @@ |
| 66 | +@@ -2101,14 +2103,23 @@ static void sixaxis_send_output_report(struct sony_sc *sc) |
12 | 67 | }
|
13 | 68 | }
|
14 | 69 |
|
15 |
| -- hid_hw_raw_request(sc->hdev, report->report_id, (u8 *)report, |
| 70 | +- /* SHANWAN controllers require output reports via intr channel */ |
| 71 | +- if (sc->quirks & SHANWAN_GAMEPAD) |
| 72 | +- hid_hw_output_report(sc->hdev, (u8 *)report, |
| 73 | +- sizeof(struct sixaxis_output_report)); |
| 74 | +- else |
| 75 | +- hid_hw_raw_request(sc->hdev, report->report_id, (u8 *)report, |
16 | 76 | + /*
|
17 |
| -+ * Gasia controller workaround |
18 |
| -+ * See: https://bugzilla.kernel.org/show_bug.cgi?id=200009 |
| 77 | ++ * SHANWAN & GASIA controllers require output reports via intr channel. |
| 78 | ++ * Some of the Gasia controllers are basically indistinguishable from |
| 79 | ++ * the official ones and thus try hid_hw_output_report() should |
| 80 | ++ * hid_hw_raw_request() fail. |
19 | 81 | + */
|
20 |
| -+ ret = hid_hw_raw_request(sc->hdev, report->report_id, (u8 *)report, |
21 |
| - sizeof(struct sixaxis_output_report), |
22 |
| - HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); |
23 |
| -+ if (ret < 0) { |
24 |
| -+ hid_err(sc->hdev, "failed to send raw request, attempting fallback\n"); |
25 |
| -+ hid_hw_output_report(sc->hdev, (u8 *)report, |
26 |
| -+ sizeof(struct sixaxis_output_report)); |
27 |
| -+ } |
| 82 | ++ if (!(sc->quirks & (SHANWAN_GAMEPAD | GASIA_GAMEPAD))) |
| 83 | ++ ret = hid_hw_raw_request(sc->hdev, report->report_id, |
| 84 | ++ (u8 *)report, |
| 85 | + sizeof(struct sixaxis_output_report), |
| 86 | + HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); |
| 87 | ++ |
| 88 | ++ if (ret >= 0) |
| 89 | ++ return; |
| 90 | ++ |
| 91 | ++ hid_hw_output_report(sc->hdev, (u8 *)report, |
| 92 | ++ sizeof(struct sixaxis_output_report)); |
28 | 93 | }
|
29 | 94 |
|
30 | 95 | static void dualshock4_send_output_report(struct sony_sc *sc)
|
| 96 | +@@ -2833,6 +2844,14 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) |
| 97 | + if (!strcmp(hdev->name, "SHANWAN PS3 GamePad")) |
| 98 | + quirks |= SHANWAN_GAMEPAD; |
| 99 | + |
| 100 | ++ /* |
| 101 | ++ * Some Gasia controllers are named "PLAYSTATION(R)3 Controller" |
| 102 | ++ * where as the official Sony controllers are named |
| 103 | ++ * "Sony PLAYSTATION(R)3 Controller". |
| 104 | ++ */ |
| 105 | ++ if (!strcmp(hdev->name, "PLAYSTATION(R)3 Controller")) |
| 106 | ++ quirks |= GASIA_GAMEPAD; |
| 107 | ++ |
| 108 | + sc = devm_kzalloc(&hdev->dev, sizeof(*sc), GFP_KERNEL); |
| 109 | + if (sc == NULL) { |
| 110 | + hid_err(hdev, "can't alloc sony descriptor\n"); |
| 111 | +-- |
| 112 | +2.20.1 |
0 commit comments