.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * HID driver for Sony / PS2 / PS3 / PS4 BD devices. |
---|
3 | 4 | * |
---|
.. | .. |
---|
13 | 14 | */ |
---|
14 | 15 | |
---|
15 | 16 | /* |
---|
16 | | - * This program is free software; you can redistribute it and/or modify it |
---|
17 | | - * under the terms of the GNU General Public License as published by the Free |
---|
18 | | - * Software Foundation; either version 2 of the License, or (at your option) |
---|
19 | | - * any later version. |
---|
20 | 17 | */ |
---|
21 | 18 | |
---|
22 | 19 | /* |
---|
.. | .. |
---|
58 | 55 | #define FUTUREMAX_DANCE_MAT BIT(13) |
---|
59 | 56 | #define NSG_MR5U_REMOTE_BT BIT(14) |
---|
60 | 57 | #define NSG_MR7U_REMOTE_BT BIT(15) |
---|
| 58 | +#define SHANWAN_GAMEPAD BIT(16) |
---|
61 | 59 | |
---|
62 | 60 | #define SIXAXIS_CONTROLLER (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT) |
---|
63 | 61 | #define MOTION_CONTROLLER (MOTION_CONTROLLER_USB | MOTION_CONTROLLER_BT) |
---|
.. | .. |
---|
1511 | 1509 | */ |
---|
1512 | 1510 | static int sixaxis_set_operational_usb(struct hid_device *hdev) |
---|
1513 | 1511 | { |
---|
| 1512 | + struct sony_sc *sc = hid_get_drvdata(hdev); |
---|
1514 | 1513 | const int buf_size = |
---|
1515 | 1514 | max(SIXAXIS_REPORT_0xF2_SIZE, SIXAXIS_REPORT_0xF5_SIZE); |
---|
1516 | 1515 | u8 *buf; |
---|
.. | .. |
---|
1540 | 1539 | |
---|
1541 | 1540 | /* |
---|
1542 | 1541 | * But the USB interrupt would cause SHANWAN controllers to |
---|
1543 | | - * start rumbling non-stop. |
---|
| 1542 | + * start rumbling non-stop, so skip step 3 for these controllers. |
---|
1544 | 1543 | */ |
---|
1545 | | - if (strcmp(hdev->name, "SHANWAN PS3 GamePad")) { |
---|
1546 | | - ret = hid_hw_output_report(hdev, buf, 1); |
---|
1547 | | - if (ret < 0) { |
---|
1548 | | - hid_info(hdev, "can't set operational mode: step 3, ignoring\n"); |
---|
1549 | | - ret = 0; |
---|
1550 | | - } |
---|
| 1544 | + if (sc->quirks & SHANWAN_GAMEPAD) |
---|
| 1545 | + goto out; |
---|
| 1546 | + |
---|
| 1547 | + ret = hid_hw_output_report(hdev, buf, 1); |
---|
| 1548 | + if (ret < 0) { |
---|
| 1549 | + hid_info(hdev, "can't set operational mode: step 3, ignoring\n"); |
---|
| 1550 | + ret = 0; |
---|
1551 | 1551 | } |
---|
1552 | 1552 | |
---|
1553 | 1553 | out: |
---|
.. | .. |
---|
2118 | 2118 | } |
---|
2119 | 2119 | } |
---|
2120 | 2120 | |
---|
2121 | | - hid_hw_raw_request(sc->hdev, report->report_id, (u8 *)report, |
---|
2122 | | - sizeof(struct sixaxis_output_report), |
---|
2123 | | - HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); |
---|
| 2121 | + /* SHANWAN controllers require output reports via intr channel */ |
---|
| 2122 | + if (sc->quirks & SHANWAN_GAMEPAD) |
---|
| 2123 | + hid_hw_output_report(sc->hdev, (u8 *)report, |
---|
| 2124 | + sizeof(struct sixaxis_output_report)); |
---|
| 2125 | + else |
---|
| 2126 | + hid_hw_raw_request(sc->hdev, report->report_id, (u8 *)report, |
---|
| 2127 | + sizeof(struct sixaxis_output_report), |
---|
| 2128 | + HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); |
---|
2124 | 2129 | } |
---|
2125 | 2130 | |
---|
2126 | 2131 | static void dualshock4_send_output_report(struct sony_sc *sc) |
---|
.. | .. |
---|
2842 | 2847 | if (!strcmp(hdev->name, "FutureMax Dance Mat")) |
---|
2843 | 2848 | quirks |= FUTUREMAX_DANCE_MAT; |
---|
2844 | 2849 | |
---|
| 2850 | + if (!strcmp(hdev->name, "SHANWAN PS3 GamePad")) |
---|
| 2851 | + quirks |= SHANWAN_GAMEPAD; |
---|
| 2852 | + |
---|
2845 | 2853 | sc = devm_kzalloc(&hdev->dev, sizeof(*sc), GFP_KERNEL); |
---|
2846 | 2854 | if (sc == NULL) { |
---|
2847 | 2855 | hid_err(hdev, "can't alloc sony descriptor\n"); |
---|