From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: monkaBlyat <54044929+monkaBlyat@users.noreply.github.com> Date: Sun, 18 Aug 2024 10:39:57 +0200 Subject: [ARCHEOLOGY] legacy kernel patch for ds4 controllers > X-Git-Archeology: - Revision 54cc6ea4e2460c31960b7cbef5d27d588534eb77: https://github.com/armbian/build/commit/54cc6ea4e2460c31960b7cbef5d27d588534eb77 > X-Git-Archeology: Date: Sun, 18 Aug 2024 10:39:57 +0200 > X-Git-Archeology: From: monkaBlyat <54044929+monkaBlyat@users.noreply.github.com> > X-Git-Archeology: Subject: legacy kernel patch for ds4 controllers > X-Git-Archeology: --- 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 111111111111..222222222222 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -476,6 +476,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 @@ -2454,6 +2455,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; @@ -2474,26 +2522,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); @@ -2531,6 +2562,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: -- Armbian