Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix ps4 controllers and clones on rk3588 vendor and legacy kernel #7096

Merged
merged 4 commits into from
Aug 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion config/kernel/linux-rk35xx-legacy.config
Original file line number Diff line number Diff line change
Expand Up @@ -6100,7 +6100,7 @@ CONFIG_MMC_HSQ=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
# CONFIG_LEDS_CLASS_FLASH is not set
# CONFIG_LEDS_CLASS_MULTICOLOR is not set
CONFIG_LEDS_CLASS_MULTICOLOR=m
# CONFIG_LEDS_BRIGHTNESS_HW_CHANGED is not set

#
Expand Down
2 changes: 1 addition & 1 deletion config/kernel/linux-rk35xx-vendor.config
Original file line number Diff line number Diff line change
Expand Up @@ -6953,7 +6953,7 @@ CONFIG_MMC_HSQ=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
# CONFIG_LEDS_CLASS_FLASH is not set
# CONFIG_LEDS_CLASS_MULTICOLOR is not set
CONFIG_LEDS_CLASS_MULTICOLOR=m
# CONFIG_LEDS_BRIGHTNESS_HW_CHANGED is not set

#
Expand Down
111 changes: 111 additions & 0 deletions patch/kernel/rk35xx-legacy/001-hid-sony.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
Signed-off-by: Ivan Mironov <mironov.ivan@gmail.com>
---
drivers/hid/hid-sony.c | 72 ++++++++++++++++++++++++++++++------------
1 file changed, 52 insertions(+), 20 deletions(-)

diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index e3a557dc9ffd..97df12180e45 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -491,6 +491,7 @@ struct motion_output_report_02 {

#define DS4_FEATURE_REPORT_0x02_SIZE 37
#define DS4_FEATURE_REPORT_0x05_SIZE 41
+#define DS4_FEATURE_REPORT_0x12_SIZE 16
#define DS4_FEATURE_REPORT_0x81_SIZE 7
#define DS4_FEATURE_REPORT_0xA3_SIZE 49
#define DS4_INPUT_REPORT_0x11_SIZE 78
@@ -2593,6 +2594,53 @@ static int sony_get_bt_devaddr(struct sony_sc *sc)
return 0;
}

+static int sony_get_usb_ds4_devaddr(struct sony_sc *sc)
+{
+ u8 *buf = NULL;
+ int ret;
+
+ buf = kmalloc(max(DS4_FEATURE_REPORT_0x12_SIZE, DS4_FEATURE_REPORT_0x81_SIZE), GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ /*
+ * The MAC address of a DS4 controller connected via USB can be
+ * retrieved with feature report 0x81. The address begins at
+ * offset 1.
+ */
+ ret = hid_hw_raw_request(sc->hdev, 0x81, buf,
+ DS4_FEATURE_REPORT_0x81_SIZE, HID_FEATURE_REPORT,
+ HID_REQ_GET_REPORT);
+ if (ret == DS4_FEATURE_REPORT_0x81_SIZE) {
+ memcpy(sc->mac_address, &buf[1], sizeof(sc->mac_address));
+ goto out_free;
+ }
+ dbg_hid("%s: hid_hw_raw_request(..., 0x81, ...) returned %d\n", __func__, ret);
+
+ /*
+ * Some variants do not implement feature report 0x81 at all.
+ * Fortunately, feature report 0x12 also contains the MAC address of
+ * a controller.
+ */
+ ret = hid_hw_raw_request(sc->hdev, 0x12, buf,
+ DS4_FEATURE_REPORT_0x12_SIZE, HID_FEATURE_REPORT,
+ HID_REQ_GET_REPORT);
+ if (ret == DS4_FEATURE_REPORT_0x12_SIZE) {
+ memcpy(sc->mac_address, &buf[1], sizeof(sc->mac_address));
+ goto out_free;
+ }
+ dbg_hid("%s: hid_hw_raw_request(..., 0x12, ...) returned %d\n", __func__, ret);
+
+ hid_err(sc->hdev, "failed to retrieve feature reports 0x81 and 0x12 with the DualShock 4 MAC address\n");
+ ret = ret < 0 ? ret : -EINVAL;
+
+out_free:
+
+ kfree(buf);
+
+ return ret;
+}
+
static int sony_check_add(struct sony_sc *sc)
{
u8 *buf = NULL;
@@ -2613,26 +2661,9 @@ static int sony_check_add(struct sony_sc *sc)
return 0;
}
} else if (sc->quirks & (DUALSHOCK4_CONTROLLER_USB | DUALSHOCK4_DONGLE)) {
- buf = kmalloc(DS4_FEATURE_REPORT_0x81_SIZE, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- /*
- * The MAC address of a DS4 controller connected via USB can be
- * retrieved with feature report 0x81. The address begins at
- * offset 1.
- */
- ret = hid_hw_raw_request(sc->hdev, 0x81, buf,
- DS4_FEATURE_REPORT_0x81_SIZE, HID_FEATURE_REPORT,
- HID_REQ_GET_REPORT);
-
- if (ret != DS4_FEATURE_REPORT_0x81_SIZE) {
- hid_err(sc->hdev, "failed to retrieve feature report 0x81 with the DualShock 4 MAC address\n");
- ret = ret < 0 ? ret : -EINVAL;
- goto out_free;
- }
-
- memcpy(sc->mac_address, &buf[1], sizeof(sc->mac_address));
+ ret = sony_get_usb_ds4_devaddr(sc);
+ if (ret < 0)
+ return ret;

snprintf(sc->hdev->uniq, sizeof(sc->hdev->uniq),
"%pMR", sc->mac_address);
@@ -2670,6 +2701,7 @@ static int sony_check_add(struct sony_sc *sc)
return 0;
}

+ dbg_hid("%s: retrieved MAC address: %s\n", __func__, sc->hdev->uniq);
ret = sony_check_add_dev_list(sc);

out_free:
--
2.29.2
111 changes: 111 additions & 0 deletions patch/kernel/rk35xx-vendor-6.1/001-hid-sony.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
Signed-off-by: Ivan Mironov <mironov.ivan@gmail.com>
---
drivers/hid/hid-sony.c | 72 ++++++++++++++++++++++++++++++------------
1 file changed, 52 insertions(+), 20 deletions(-)

diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index e3a557dc9ffd..97df12180e45 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -491,6 +491,7 @@ struct motion_output_report_02 {

#define DS4_FEATURE_REPORT_0x02_SIZE 37
#define DS4_FEATURE_REPORT_0x05_SIZE 41
+#define DS4_FEATURE_REPORT_0x12_SIZE 16
#define DS4_FEATURE_REPORT_0x81_SIZE 7
#define DS4_FEATURE_REPORT_0xA3_SIZE 49
#define DS4_INPUT_REPORT_0x11_SIZE 78
@@ -2593,6 +2594,53 @@ static int sony_get_bt_devaddr(struct sony_sc *sc)
return 0;
}

+static int sony_get_usb_ds4_devaddr(struct sony_sc *sc)
+{
+ u8 *buf = NULL;
+ int ret;
+
+ buf = kmalloc(max(DS4_FEATURE_REPORT_0x12_SIZE, DS4_FEATURE_REPORT_0x81_SIZE), GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ /*
+ * The MAC address of a DS4 controller connected via USB can be
+ * retrieved with feature report 0x81. The address begins at
+ * offset 1.
+ */
+ ret = hid_hw_raw_request(sc->hdev, 0x81, buf,
+ DS4_FEATURE_REPORT_0x81_SIZE, HID_FEATURE_REPORT,
+ HID_REQ_GET_REPORT);
+ if (ret == DS4_FEATURE_REPORT_0x81_SIZE) {
+ memcpy(sc->mac_address, &buf[1], sizeof(sc->mac_address));
+ goto out_free;
+ }
+ dbg_hid("%s: hid_hw_raw_request(..., 0x81, ...) returned %d\n", __func__, ret);
+
+ /*
+ * Some variants do not implement feature report 0x81 at all.
+ * Fortunately, feature report 0x12 also contains the MAC address of
+ * a controller.
+ */
+ ret = hid_hw_raw_request(sc->hdev, 0x12, buf,
+ DS4_FEATURE_REPORT_0x12_SIZE, HID_FEATURE_REPORT,
+ HID_REQ_GET_REPORT);
+ if (ret == DS4_FEATURE_REPORT_0x12_SIZE) {
+ memcpy(sc->mac_address, &buf[1], sizeof(sc->mac_address));
+ goto out_free;
+ }
+ dbg_hid("%s: hid_hw_raw_request(..., 0x12, ...) returned %d\n", __func__, ret);
+
+ hid_err(sc->hdev, "failed to retrieve feature reports 0x81 and 0x12 with the DualShock 4 MAC address\n");
+ ret = ret < 0 ? ret : -EINVAL;
+
+out_free:
+
+ kfree(buf);
+
+ return ret;
+}
+
static int sony_check_add(struct sony_sc *sc)
{
u8 *buf = NULL;
@@ -2613,26 +2661,9 @@ static int sony_check_add(struct sony_sc *sc)
return 0;
}
} else if (sc->quirks & (DUALSHOCK4_CONTROLLER_USB | DUALSHOCK4_DONGLE)) {
- buf = kmalloc(DS4_FEATURE_REPORT_0x81_SIZE, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- /*
- * The MAC address of a DS4 controller connected via USB can be
- * retrieved with feature report 0x81. The address begins at
- * offset 1.
- */
- ret = hid_hw_raw_request(sc->hdev, 0x81, buf,
- DS4_FEATURE_REPORT_0x81_SIZE, HID_FEATURE_REPORT,
- HID_REQ_GET_REPORT);
-
- if (ret != DS4_FEATURE_REPORT_0x81_SIZE) {
- hid_err(sc->hdev, "failed to retrieve feature report 0x81 with the DualShock 4 MAC address\n");
- ret = ret < 0 ? ret : -EINVAL;
- goto out_free;
- }
-
- memcpy(sc->mac_address, &buf[1], sizeof(sc->mac_address));
+ ret = sony_get_usb_ds4_devaddr(sc);
+ if (ret < 0)
+ return ret;

snprintf(sc->hdev->uniq, sizeof(sc->hdev->uniq),
"%pMR", sc->mac_address);
@@ -2670,6 +2701,7 @@ static int sony_check_add(struct sony_sc *sc)
return 0;
}

+ dbg_hid("%s: retrieved MAC address: %s\n", __func__, sc->hdev->uniq);
ret = sony_check_add_dev_list(sc);

out_free:
--
2.29.2
Loading