From patchwork Tue Mar 25 18:45:50 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antheas Kapenekakis X-Patchwork-Id: 14029354 X-Patchwork-Delegate: jikos@jikos.cz Received: from linux1587.grserver.gr (linux1587.grserver.gr [185.138.42.100]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 172541C84DC; Tue, 25 Mar 2025 18:46:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.138.42.100 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742928374; cv=none; b=XFPFNhRwvNPtvrOtsCwfxRSxOgtp3MTMgATLg6z+CFgXyuRJqDPpg/4YqlWNiPuB+zYBGgUxzgxGXMZQejWbugn/mLIkgCfkmoxfg/NFDG3slYsH7KqL6pQAVhcoSEfhpff/ZYRXiz7IETqULDzMxNJe8VeFeTltfke87/ax+AE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742928374; c=relaxed/simple; bh=nhiyNprR0xjJJPSwHwXIZk8iwN05gFggWPfMJpblSg4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=HCVSLcTlc/4LS2chmz5wOp+clrmYIANmmto7EI22MdxruVtmbnzZc5JuDkic1vF2dYT9Sgz0AKIw+++H0ZO0haA0hnSbqeeC2UEaL4p8iu8E4d+sAhcil45o/iSIahdnpIe033qtbBMtAAsTs++QooO27kmwQvG5VkQo6AjyhDM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=antheas.dev; spf=pass smtp.mailfrom=antheas.dev; dkim=pass (1024-bit key) header.d=antheas.dev header.i=@antheas.dev header.b=mLSnaQyV; arc=none smtp.client-ip=185.138.42.100 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=antheas.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=antheas.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=antheas.dev header.i=@antheas.dev header.b="mLSnaQyV" Received: from localhost.localdomain (unknown [IPv6:2a05:f6c2:511b:0:cbc0:999f:73ad:33bd]) by linux1587.grserver.gr (Postfix) with ESMTPSA id 3417F2E098A9; Tue, 25 Mar 2025 20:46:07 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1742928368; bh=jnGvGlRg9TymxteDZtauv13MU2dJb3BpwtGx9FIxm+M=; h=From:To:Subject; b=mLSnaQyVvhQT24sdox+V9De0tiWaX0eNyO1107KwYFWFV153/LYZAJrtAu/TRwncw r1YE2gmfRmjWzEEyOKkIMkSBsL8285havEHheq2v2iuEx+9c5WMEos9Xxzyv7pFsnq hN/VE/KOrOrOggpKAY3dylQzMeMN2MfZx7rIYipI= Authentication-Results: linux1587.grserver.gr; spf=pass (sender IP is 2a05:f6c2:511b:0:cbc0:999f:73ad:33bd) smtp.mailfrom=lkml@antheas.dev smtp.helo=localhost.localdomain Received-SPF: pass (linux1587.grserver.gr: connection is authenticated) From: Antheas Kapenekakis To: platform-driver-x86@vger.kernel.org, linux-input@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Jiri Kosina , Benjamin Tissoires , Corentin Chary , "Luke D . Jones" , Hans de Goede , =?utf-8?q?Ilpo_J=C3=A4rvinen?= , Antheas Kapenekakis Subject: [PATCH v5 01/11] HID: asus: refactor init sequence per spec Date: Tue, 25 Mar 2025 19:45:50 +0100 Message-ID: <20250325184601.10990-2-lkml@antheas.dev> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250325184601.10990-1-lkml@antheas.dev> References: <20250325184601.10990-1-lkml@antheas.dev> Precedence: bulk X-Mailing-List: linux-input@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-PPP-Message-ID: <174292836822.7689.11693787244428044615@linux1587.grserver.gr> X-PPP-Vhost: antheas.dev X-Virus-Scanned: clamav-milter 0.103.11 at linux1587.grserver.gr X-Virus-Status: Clean Currently, asus_kbd_init() uses a reverse engineered init sequence from Windows, which contains the handshakes from multiple programs. Keep the main one, which is 0x5a (meant for brightness drivers). In addition, perform a get_response and check if the response is the same. To avoid regressions, print an error if the response does not match instead of rejecting device. Then, refactor asus_kbd_get_functions() to use the same ID it is called with, instead of hardcoding it to 0x5a so that it may be used for 0x0d in the future. Signed-off-by: Antheas Kapenekakis --- drivers/hid/hid-asus.c | 78 +++++++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 36 deletions(-) diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c index 46e3e42f9eb5f..47f0a7cb46c80 100644 --- a/drivers/hid/hid-asus.c +++ b/drivers/hid/hid-asus.c @@ -48,7 +48,7 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad"); #define FEATURE_REPORT_ID 0x0d #define INPUT_REPORT_ID 0x5d #define FEATURE_KBD_REPORT_ID 0x5a -#define FEATURE_KBD_REPORT_SIZE 16 +#define FEATURE_KBD_REPORT_SIZE 64 #define FEATURE_KBD_LED_REPORT_ID1 0x5d #define FEATURE_KBD_LED_REPORT_ID2 0x5e @@ -388,14 +388,37 @@ static int asus_kbd_set_report(struct hid_device *hdev, const u8 *buf, size_t bu static int asus_kbd_init(struct hid_device *hdev, u8 report_id) { - const u8 buf[] = { report_id, 0x41, 0x53, 0x55, 0x53, 0x20, 0x54, - 0x65, 0x63, 0x68, 0x2e, 0x49, 0x6e, 0x63, 0x2e, 0x00 }; + /* + * The handshake is first sent as a set_report, then retrieved + * from a get_report. They should be equal. + */ + const u8 buf[] = { report_id, 0x41, 0x53, 0x55, 0x53, 0x20, + 0x54, 0x65, 0x63, 0x68, 0x2e, 0x49, 0x6e, 0x63, 0x2e, 0x00 }; + u8 *readbuf; int ret; ret = asus_kbd_set_report(hdev, buf, sizeof(buf)); - if (ret < 0) - hid_err(hdev, "Asus failed to send init command: %d\n", ret); + if (ret < 0) { + hid_err(hdev, "Asus failed to send handshake: %d\n", ret); + return ret; + } + readbuf = kzalloc(FEATURE_KBD_REPORT_SIZE, GFP_KERNEL); + if (!readbuf) + return -ENOMEM; + + ret = hid_hw_raw_request(hdev, report_id, readbuf, + FEATURE_KBD_REPORT_SIZE, HID_FEATURE_REPORT, + HID_REQ_GET_REPORT); + if (ret < 0) { + hid_err(hdev, "Asus failed to receive handshake ack: %d\n", ret); + } else if (memcmp(readbuf, buf, sizeof(buf)) != 0) { + hid_warn(hdev, "Asus handshake returned invalid response: %*ph\n", + FEATURE_KBD_REPORT_SIZE, readbuf); + // Do not return error if handshake is wrong to avoid regressions + } + + kfree(readbuf); return ret; } @@ -417,7 +440,7 @@ static int asus_kbd_get_functions(struct hid_device *hdev, if (!readbuf) return -ENOMEM; - ret = hid_hw_raw_request(hdev, FEATURE_KBD_REPORT_ID, readbuf, + ret = hid_hw_raw_request(hdev, report_id, readbuf, FEATURE_KBD_REPORT_SIZE, HID_FEATURE_REPORT, HID_REQ_GET_REPORT); if (ret < 0) { @@ -540,42 +563,25 @@ static int asus_kbd_register_leds(struct hid_device *hdev) unsigned char kbd_func; int ret; - if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD) { - /* Initialize keyboard */ - ret = asus_kbd_init(hdev, FEATURE_KBD_REPORT_ID); - if (ret < 0) - return ret; - - /* The LED endpoint is initialised in two HID */ - ret = asus_kbd_init(hdev, FEATURE_KBD_LED_REPORT_ID1); - if (ret < 0) - return ret; - - ret = asus_kbd_init(hdev, FEATURE_KBD_LED_REPORT_ID2); - if (ret < 0) - return ret; + ret = asus_kbd_init(hdev, FEATURE_KBD_REPORT_ID); + if (ret < 0) + return ret; - if (dmi_match(DMI_PRODUCT_FAMILY, "ProArt P16")) { - ret = asus_kbd_disable_oobe(hdev); - if (ret < 0) - return ret; - } - } else { - /* Initialize keyboard */ - ret = asus_kbd_init(hdev, FEATURE_KBD_REPORT_ID); - if (ret < 0) - return ret; + /* Get keyboard functions */ + ret = asus_kbd_get_functions(hdev, &kbd_func, FEATURE_KBD_REPORT_ID); + if (ret < 0) + return ret; - /* Get keyboard functions */ - ret = asus_kbd_get_functions(hdev, &kbd_func, FEATURE_KBD_REPORT_ID); + if (dmi_match(DMI_PRODUCT_FAMILY, "ProArt P16")) { + ret = asus_kbd_disable_oobe(hdev); if (ret < 0) return ret; - - /* Check for backlight support */ - if (!(kbd_func & SUPPORT_KBD_BACKLIGHT)) - return -ENODEV; } + /* Check for backlight support */ + if (!(kbd_func & SUPPORT_KBD_BACKLIGHT)) + return -ENODEV; + drvdata->kbd_backlight = devm_kzalloc(&hdev->dev, sizeof(struct asus_kbd_leds), GFP_KERNEL);