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); From patchwork Tue Mar 25 18:45:51 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antheas Kapenekakis X-Patchwork-Id: 14029355 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 8A27A1ACEAF; Tue, 25 Mar 2025 18:46:13 +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=1742928375; cv=none; b=ExWPBf1ni/y88dKJL1EKk9Q+MucxNxw6HpQ3+zjqbZLtDTbpE7e09pdepEcrhuFsEuzzxEJG5Z5HXWk21hhJHGmYpkLqgV+KGJqpFGV4LofsMOBks0edPYFMODh+cdFU9SfRjzx6FT79H+vX5J9aiLFs1wMGbTi4puD3txm5O6o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742928375; c=relaxed/simple; bh=xaUGb+diGmllD/MR/PUUhg9ZanRMgEuo/FIr//rXLF8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lf67uccRKkb6HiNgvLIf7793/DHTxiQT3Xg1E0aKi85HtFiWlSdaE/y/RCir9siyAqSHyuwiuWbNeR7OwP7qeCAx/F2PpgFbaF9nnbCMJxhL6W8W5cqLwxszrDehXsGsr+9sUPfQtBHNj89ZeUC23YoanPdpAdA0s13pZpfJd54= 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=V28Hcl4c; 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="V28Hcl4c" Received: from localhost.localdomain (unknown [IPv6:2a05:f6c2:511b:0:cbc0:999f:73ad:33bd]) by linux1587.grserver.gr (Postfix) with ESMTPSA id E97DF2E0932D; Tue, 25 Mar 2025 20:46:08 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1742928370; bh=hChOQ20vCYiy3vvs3LCq5MPJ+0GUXF9+zvDSw0MqvLM=; h=From:To:Subject; b=V28Hcl4ccV9qPYczOA5uIybEpIsf5X5rJS+yRUlnxPikiroWKAEfRepS58odhW6yK Sbr0h6hQTvCS7g18KAt9e33a40CktJ4knKsXf0x9lwKJvRRAVLR37+tqgzAOPMdPv1 m36lMDQqkm1k1tA3r/IBMqQJ+mztHzaSoyOOdR+M= 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 02/11] HID: asus: prevent binding to all HID devices on ROG Date: Tue, 25 Mar 2025 19:45:51 +0100 Message-ID: <20250325184601.10990-3-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: <174292836997.7747.7165150432821297937@linux1587.grserver.gr> X-PPP-Vhost: antheas.dev X-Virus-Scanned: clamav-milter 0.103.11 at linux1587.grserver.gr X-Virus-Status: Clean ROG keyboards are HID compliant and only care about the endpoint that produces vendor events (e.g., fan mode) and has the keyboard backlight. Therefore, handle all of the endpoints of ROG keyboards as compliant, by adding HID_QUIRK_INPUT_PER_APP and, for devices other than the vendor one, by adding QUIRK_HANDLE_GENERIC to stop mutating them. Due to HID_QUIRK_INPUT_PER_APP, rgb register is moved into probe, as the input_* functions are called multiple times (4 for the Z13). Reviewed-by: Luke D. Jones Signed-off-by: Antheas Kapenekakis --- drivers/hid/hid-asus.c | 69 +++++++++++++++++++++++++++++++----------- 1 file changed, 52 insertions(+), 17 deletions(-) diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c index 47f0a7cb46c80..7269ddc690bca 100644 --- a/drivers/hid/hid-asus.c +++ b/drivers/hid/hid-asus.c @@ -47,6 +47,7 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad"); #define T100CHI_MOUSE_REPORT_ID 0x06 #define FEATURE_REPORT_ID 0x0d #define INPUT_REPORT_ID 0x5d +#define HID_USAGE_PAGE_VENDOR 0xff310000 #define FEATURE_KBD_REPORT_ID 0x5a #define FEATURE_KBD_REPORT_SIZE 64 #define FEATURE_KBD_LED_REPORT_ID1 0x5d @@ -84,6 +85,7 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad"); #define QUIRK_MEDION_E1239T BIT(10) #define QUIRK_ROG_NKEY_KEYBOARD BIT(11) #define QUIRK_ROG_CLAYMORE_II_KEYBOARD BIT(12) +#define QUIRK_HANDLE_GENERIC BIT(13) #define I2C_KEYBOARD_QUIRKS (QUIRK_FIX_NOTEBOOK_REPORT | \ QUIRK_NO_INIT_REPORTS | \ @@ -120,7 +122,6 @@ struct asus_drvdata { struct input_dev *tp_kbd_input; struct asus_kbd_leds *kbd_backlight; const struct asus_touchpad_info *tp; - bool enable_backlight; struct power_supply *battery; struct power_supply_desc battery_desc; int battery_capacity; @@ -311,7 +312,7 @@ static int asus_e1239t_event(struct asus_drvdata *drvdat, u8 *data, int size) static int asus_event(struct hid_device *hdev, struct hid_field *field, struct hid_usage *usage, __s32 value) { - if ((usage->hid & HID_USAGE_PAGE) == 0xff310000 && + if ((usage->hid & HID_USAGE_PAGE) == HID_USAGE_PAGE_VENDOR && (usage->hid & HID_USAGE) != 0x00 && (usage->hid & HID_USAGE) != 0xff && !usage->type) { hid_warn(hdev, "Unmapped Asus vendor usagepage code 0x%02x\n", @@ -326,6 +327,10 @@ static int asus_raw_event(struct hid_device *hdev, { struct asus_drvdata *drvdata = hid_get_drvdata(hdev); + /* NOOP on generic HID devices to avoid side effects. */ + if (drvdata->quirks & QUIRK_HANDLE_GENERIC) + return 0; + if (drvdata->battery && data[0] == BATTERY_REPORT_ID) return asus_report_battery(drvdata, data, size); @@ -770,6 +775,10 @@ static int asus_input_configured(struct hid_device *hdev, struct hid_input *hi) struct input_dev *input = hi->input; struct asus_drvdata *drvdata = hid_get_drvdata(hdev); + /* NOOP on generic HID devices to avoid side effects. */ + if (drvdata->quirks & QUIRK_HANDLE_GENERIC) + return 0; + /* T100CHI uses MULTI_INPUT, bind the touchpad to the mouse hid_input */ if (drvdata->quirks & QUIRK_T100CHI && hi->report->id != T100CHI_MOUSE_REPORT_ID) @@ -823,11 +832,6 @@ static int asus_input_configured(struct hid_device *hdev, struct hid_input *hi) drvdata->input = input; - if (drvdata->enable_backlight && - !asus_kbd_wmi_led_control_present(hdev) && - asus_kbd_register_leds(hdev)) - hid_warn(hdev, "Failed to initialize backlight.\n"); - return 0; } @@ -847,6 +851,10 @@ static int asus_input_mapping(struct hid_device *hdev, return -1; } + /* NOOP on generic HID devices to avoid side effects. */ + if (drvdata->quirks & QUIRK_HANDLE_GENERIC) + return 0; + /* * Ignore a bunch of bogus collections in the T100CHI descriptor. * This avoids a bunch of non-functional hid_input devices getting @@ -897,15 +905,6 @@ static int asus_input_mapping(struct hid_device *hdev, return -1; } - /* - * Check and enable backlight only on devices with UsagePage == - * 0xff31 to avoid initializing the keyboard firmware multiple - * times on devices with multiple HID descriptors but same - * PID/VID. - */ - if (drvdata->quirks & QUIRK_USE_KBD_BACKLIGHT) - drvdata->enable_backlight = true; - set_bit(EV_REP, hi->input->evbit); return 1; } @@ -1022,8 +1021,10 @@ static int __maybe_unused asus_reset_resume(struct hid_device *hdev) static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id) { - int ret; + struct hid_report_enum *rep_enum; struct asus_drvdata *drvdata; + struct hid_report *rep; + int ret, is_vendor = 0; drvdata = devm_kzalloc(&hdev->dev, sizeof(*drvdata), GFP_KERNEL); if (drvdata == NULL) { @@ -1107,12 +1108,42 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id) return ret; } + /* Check for vendor for RGB init and handle generic devices properly. */ + rep_enum = &hdev->report_enum[HID_INPUT_REPORT]; + list_for_each_entry(rep, &rep_enum->report_list, list) { + if ((rep->application & HID_USAGE_PAGE) == HID_USAGE_PAGE_VENDOR) + is_vendor = true; + } + + /* + * For ROG keyboards, make them hid compliant by + * creating one input per application. For interfaces other than + * the vendor one, disable hid-asus handlers. + */ + if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD) { + if (!is_vendor) + drvdata->quirks |= QUIRK_HANDLE_GENERIC; + hdev->quirks |= HID_QUIRK_INPUT_PER_APP; + } + ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); if (ret) { hid_err(hdev, "Asus hw start failed: %d\n", ret); return ret; } + if (is_vendor && (drvdata->quirks & QUIRK_USE_KBD_BACKLIGHT) && + !asus_kbd_wmi_led_control_present(hdev) && + asus_kbd_register_leds(hdev)) + hid_warn(hdev, "Failed to initialize backlight.\n"); + + /* + * For ROG keyboards, skip rename for consistency and ->input check as + * some devices do not have inputs. + */ + if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD) + return 0; + if (!drvdata->input) { hid_err(hdev, "Asus input not registered\n"); ret = -ENOMEM; @@ -1163,6 +1194,10 @@ static const __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc, { struct asus_drvdata *drvdata = hid_get_drvdata(hdev); + /* NOOP on generic HID devices to avoid side effects. */ + if (drvdata->quirks & QUIRK_HANDLE_GENERIC) + return rdesc; + if (drvdata->quirks & QUIRK_FIX_NOTEBOOK_REPORT && *rsize >= 56 && rdesc[54] == 0x25 && rdesc[55] == 0x65) { hid_info(hdev, "Fixing up Asus notebook report descriptor\n"); From patchwork Tue Mar 25 18:45:52 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antheas Kapenekakis X-Patchwork-Id: 14029356 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 6DF361F3BA3; Tue, 25 Mar 2025 18:46:15 +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=1742928378; cv=none; b=hNDZimzB6fJyffe6qURz3r5LA9zsWoAJmj+SqsCJy9XpIFBDk0UchmXoWjEkVQ6XyewVgEWOHgKmtdt1bmYaV6BD7cgZOLyLO08AOtiLlzcTbfd5IsKTUfy+Spf0qK8u0N6JojpG3pL7BOCdjljk85xx96RBqgOrWEPjzBmaiAU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742928378; c=relaxed/simple; bh=bzHAFZlqpycd+y3xworuJn4ht3p2an0/1qPK6N/8rAw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KaivsNYWC3AnnkKjBXEXlzwnHJMGaICVD1KCnwoxYK159BjIUsTWkN7rqB9Ay11JU/Uuirf4Fos0KYWhMsyukwJO69cHDCGkMOwYNumfI6Z92rbRJvYr/ejuKbHqUBqg/+v0xGg9X0NyGBVK08JPpWuSlIaiJD+HGEWj25kopQ8= 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=CGZGfSEw; 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="CGZGfSEw" Received: from localhost.localdomain (unknown [IPv6:2a05:f6c2:511b:0:cbc0:999f:73ad:33bd]) by linux1587.grserver.gr (Postfix) with ESMTPSA id 427F62E098AC; Tue, 25 Mar 2025 20:46:11 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1742928372; bh=qO2ABiP2VcZoKwfQCx+dw5dTpRGLGWJaqQilS9O8+jI=; h=From:To:Subject; b=CGZGfSEwZfdFGKq00LWZCseLhDQRKRbtA21jNdwFbViwkkdja3eNbbX2/4qjsoWUb nKwLUg4ok0MadzlrwR0jiA4ihWQUesx5WUQUwrAF776EXvS0bpqaP2sUd1tyKnY5sX tXB+t5hmAF0J9qRUh6UqWbk9YyZZ0HK9bqET4X3Q= 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 03/11] HID: asus: add Z13 folio to generic group for multitouch to work Date: Tue, 25 Mar 2025 19:45:52 +0100 Message-ID: <20250325184601.10990-4-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: <174292837227.7838.820531500827221007@linux1587.grserver.gr> X-PPP-Vhost: antheas.dev X-Virus-Scanned: clamav-milter 0.103.11 at linux1587.grserver.gr X-Virus-Status: Clean The Asus Z13 folio has a multitouch touchpad that needs to bind to the hid-multitouch driver in order to work properly. So bind it to the HID_GROUP_GENERIC group to release the touchpad and move it to the bottom so that the comment applies to it. While at it, change the generic KEYBOARD3 name to Z13_FOLIO. Reviewed-by: Luke D. Jones Signed-off-by: Antheas Kapenekakis --- drivers/hid/hid-asus.c | 6 +++--- drivers/hid/hid-ids.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c index 7269ddc690bca..7f070474ef8b4 100644 --- a/drivers/hid/hid-asus.c +++ b/drivers/hid/hid-asus.c @@ -1313,9 +1313,6 @@ static const struct hid_device_id asus_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD2), QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD }, - { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, - USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD3), - QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD }, { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_ROG_Z13_LIGHTBAR), QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD }, @@ -1345,6 +1342,9 @@ static const struct hid_device_id asus_devices[] = { * Note bind to the HID_GROUP_GENERIC group, so that we only bind to the keyboard * part, while letting hid-multitouch.c handle the touchpad. */ + { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, + USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_ROG_Z13_FOLIO), + QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD }, { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_T101HA_KEYBOARD) }, { } diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 7e400624908e3..b1fe7582324ff 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -209,7 +209,7 @@ #define USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD3 0x1822 #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD 0x1866 #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD2 0x19b6 -#define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD3 0x1a30 +#define USB_DEVICE_ID_ASUSTEK_ROG_Z13_FOLIO 0x1a30 #define USB_DEVICE_ID_ASUSTEK_ROG_Z13_LIGHTBAR 0x18c6 #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY 0x1abe #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY_X 0x1b4c From patchwork Tue Mar 25 18:45:53 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antheas Kapenekakis X-Patchwork-Id: 14029357 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 6DEE11F3B9D; Tue, 25 Mar 2025 18:46:16 +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=1742928378; cv=none; b=IIWqgqrbj/eHuInrCjhMsDBObDdl1pIs3NtzQGWyle4geXvMpcGT3Cg8DY8KyZ94/5sBnnaxWWcrTaP6kZR2qkMyojg3KsxgEpkbk3cSgZO9wNAGR6K9nyFGXnC7OUwgR1uM78k+RJe8BkztrEVKwNeIzbV+3SYi2YcFYPcnH4g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742928378; c=relaxed/simple; bh=McfPLinrI0UIGMPTJCpquK06WbMzxn0Fz1pp5+lKrN4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=S94gY7UviFMmjTIOI1i/xbCGXEImOjV9DmLJxUhaJjDrkT30KT1hekU3yxOmIVIp7bYGamCl5vmwuETYyfSAJYAIrNjMZicj0V37KddYpOtZRI89+LOi/Tiw0ZIwUtU4T+q0cwncPrMvDm/R8vrWJWfmYABMt5nxuBDfk+D5U4Y= 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=Syci9klb; 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="Syci9klb" Received: from localhost.localdomain (unknown [IPv6:2a05:f6c2:511b:0:cbc0:999f:73ad:33bd]) by linux1587.grserver.gr (Postfix) with ESMTPSA id CB0542E098AF; Tue, 25 Mar 2025 20:46:12 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1742928374; bh=3e4rHQpsDEsDnd8v9T2vzddRYWY1i6Z2uoxlKsEJHsM=; h=From:To:Subject; b=Syci9klbEuWsQ0eyIDfAJVf5bxLRD5Z1RASdVKYRreFNJRSlyew8uzE7BIzi4zf1d eapHvWpw+NPaQW83fvTV8kcdmG+ZwvqHpg5BWu2fasa2VpXOK5J8+Wb48Y4VHMyq47 B7iDRzeIc+uBaM6HAY0q9W+bowNsZyMHFAWdjPxs= 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 04/11] platform/x86: asus-wmi: Add support for multiple kbd RGB handlers Date: Tue, 25 Mar 2025 19:45:53 +0100 Message-ID: <20250325184601.10990-5-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: <174292837388.7894.5496627901896805367@linux1587.grserver.gr> X-PPP-Vhost: antheas.dev X-Virus-Scanned: clamav-milter 0.103.11 at linux1587.grserver.gr X-Virus-Status: Clean Some devices, such as the Z13 have multiple AURA devices connected to them by USB. In addition, they might have a WMI interface for RGB. In Windows, Armoury Crate exposes a unified brightness slider for all of them, with 3 brightness levels. Therefore, to be synergistic in Linux, and support existing tooling such as UPower, allow adding listeners to the RGB device of the WMI interface. If WMI does not exist, lazy initialize the interface. Reviewed-by: Luke D. Jones Tested-by: Luke D. Jones Signed-off-by: Antheas Kapenekakis --- drivers/platform/x86/asus-wmi.c | 118 ++++++++++++++++++--- include/linux/platform_data/x86/asus-wmi.h | 16 +++ 2 files changed, 121 insertions(+), 13 deletions(-) diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 38ef778e8c19b..ff1d7ccb3982f 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -254,6 +254,8 @@ struct asus_wmi { int tpd_led_wk; struct led_classdev kbd_led; int kbd_led_wk; + bool kbd_led_avail; + bool kbd_led_registered; struct led_classdev lightbar_led; int lightbar_led_wk; struct led_classdev micmute_led; @@ -1487,6 +1489,53 @@ static void asus_wmi_battery_exit(struct asus_wmi *asus) /* LEDs ***********************************************************************/ +struct asus_hid_ref { + struct list_head listeners; + struct asus_wmi *asus; + spinlock_t lock; +}; + +struct asus_hid_ref asus_ref = { + .listeners = LIST_HEAD_INIT(asus_ref.listeners), + .asus = NULL, + .lock = __SPIN_LOCK_UNLOCKED(asus_ref.lock), +}; + +int asus_hid_register_listener(struct asus_hid_listener *bdev) +{ + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&asus_ref.lock, flags); + list_add_tail(&bdev->list, &asus_ref.listeners); + if (asus_ref.asus) { + if (asus_ref.asus->kbd_led_registered && asus_ref.asus->kbd_led_wk >= 0) + bdev->brightness_set(bdev, asus_ref.asus->kbd_led_wk); + + if (!asus_ref.asus->kbd_led_registered) { + ret = led_classdev_register( + &asus_ref.asus->platform_device->dev, + &asus_ref.asus->kbd_led); + if (!ret) + asus_ref.asus->kbd_led_registered = true; + } + } + spin_unlock_irqrestore(&asus_ref.lock, flags); + + return ret; +} +EXPORT_SYMBOL_GPL(asus_hid_register_listener); + +void asus_hid_unregister_listener(struct asus_hid_listener *bdev) +{ + unsigned long flags; + + spin_lock_irqsave(&asus_ref.lock, flags); + list_del(&bdev->list); + spin_unlock_irqrestore(&asus_ref.lock, flags); +} +EXPORT_SYMBOL_GPL(asus_hid_unregister_listener); + /* * These functions actually update the LED's, and are called from a * workqueue. By doing this as separate work rather than when the LED @@ -1566,6 +1615,7 @@ static int kbd_led_read(struct asus_wmi *asus, int *level, int *env) static void do_kbd_led_set(struct led_classdev *led_cdev, int value) { + struct asus_hid_listener *listener; struct asus_wmi *asus; int max_level; @@ -1573,25 +1623,39 @@ static void do_kbd_led_set(struct led_classdev *led_cdev, int value) max_level = asus->kbd_led.max_brightness; asus->kbd_led_wk = clamp_val(value, 0, max_level); - kbd_led_update(asus); + + if (asus->kbd_led_avail) + kbd_led_update(asus); + + list_for_each_entry(listener, &asus_ref.listeners, list) + listener->brightness_set(listener, asus->kbd_led_wk); } static void kbd_led_set(struct led_classdev *led_cdev, enum led_brightness value) { + unsigned long flags; + /* Prevent disabling keyboard backlight on module unregister */ if (led_cdev->flags & LED_UNREGISTERING) return; + spin_lock_irqsave(&asus_ref.lock, flags); do_kbd_led_set(led_cdev, value); + spin_unlock_irqrestore(&asus_ref.lock, flags); } static void kbd_led_set_by_kbd(struct asus_wmi *asus, enum led_brightness value) { - struct led_classdev *led_cdev = &asus->kbd_led; + struct led_classdev *led_cdev; + unsigned long flags; + + spin_lock_irqsave(&asus_ref.lock, flags); + led_cdev = &asus->kbd_led; do_kbd_led_set(led_cdev, value); led_classdev_notify_brightness_hw_changed(led_cdev, asus->kbd_led_wk); + spin_unlock_irqrestore(&asus_ref.lock, flags); } static enum led_brightness kbd_led_get(struct led_classdev *led_cdev) @@ -1601,6 +1665,9 @@ static enum led_brightness kbd_led_get(struct led_classdev *led_cdev) asus = container_of(led_cdev, struct asus_wmi, kbd_led); + if (!asus->kbd_led_avail) + return asus->kbd_led_wk; + retval = kbd_led_read(asus, &value, NULL); if (retval < 0) return retval; @@ -1716,7 +1783,15 @@ static int camera_led_set(struct led_classdev *led_cdev, static void asus_wmi_led_exit(struct asus_wmi *asus) { - led_classdev_unregister(&asus->kbd_led); + unsigned long flags; + + spin_lock_irqsave(&asus_ref.lock, flags); + asus_ref.asus = NULL; + spin_unlock_irqrestore(&asus_ref.lock, flags); + + if (asus->kbd_led_registered) + led_classdev_unregister(&asus->kbd_led); + led_classdev_unregister(&asus->tpd_led); led_classdev_unregister(&asus->wlan_led); led_classdev_unregister(&asus->lightbar_led); @@ -1730,6 +1805,8 @@ static void asus_wmi_led_exit(struct asus_wmi *asus) static int asus_wmi_led_init(struct asus_wmi *asus) { int rv = 0, num_rgb_groups = 0, led_val; + struct asus_hid_listener *listener; + unsigned long flags; if (asus->kbd_rgb_dev) kbd_rgb_mode_groups[num_rgb_groups++] = &kbd_rgb_mode_group; @@ -1754,23 +1831,38 @@ static int asus_wmi_led_init(struct asus_wmi *asus) goto error; } - if (!kbd_led_read(asus, &led_val, NULL) && !dmi_check_system(asus_use_hid_led_dmi_ids)) { - pr_info("using asus-wmi for asus::kbd_backlight\n"); + asus->kbd_led.name = "asus::kbd_backlight"; + asus->kbd_led.flags = LED_BRIGHT_HW_CHANGED; + asus->kbd_led.brightness_set = kbd_led_set; + asus->kbd_led.brightness_get = kbd_led_get; + asus->kbd_led.max_brightness = 3; + asus->kbd_led_avail = !kbd_led_read(asus, &led_val, NULL); + + if (asus->kbd_led_avail) asus->kbd_led_wk = led_val; - asus->kbd_led.name = "asus::kbd_backlight"; - asus->kbd_led.flags = LED_BRIGHT_HW_CHANGED; - asus->kbd_led.brightness_set = kbd_led_set; - asus->kbd_led.brightness_get = kbd_led_get; - asus->kbd_led.max_brightness = 3; + else + asus->kbd_led_wk = -1; - if (num_rgb_groups != 0) - asus->kbd_led.groups = kbd_rgb_mode_groups; + if (asus->kbd_led_avail && num_rgb_groups != 0) + asus->kbd_led.groups = kbd_rgb_mode_groups; + spin_lock_irqsave(&asus_ref.lock, flags); + if (asus->kbd_led_avail || !list_empty(&asus_ref.listeners)) { rv = led_classdev_register(&asus->platform_device->dev, &asus->kbd_led); - if (rv) + if (rv) { + spin_unlock_irqrestore(&asus_ref.lock, flags); goto error; + } + asus->kbd_led_registered = true; + + if (asus->kbd_led_wk >= 0) { + list_for_each_entry(listener, &asus_ref.listeners, list) + listener->brightness_set(listener, asus->kbd_led_wk); + } } + asus_ref.asus = asus; + spin_unlock_irqrestore(&asus_ref.lock, flags); if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_WIRELESS_LED) && (asus->driver->quirks->wapf > 0)) { diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h index 783e2a336861b..ec8b0c585a63f 100644 --- a/include/linux/platform_data/x86/asus-wmi.h +++ b/include/linux/platform_data/x86/asus-wmi.h @@ -157,14 +157,30 @@ #define ASUS_WMI_DSTS_MAX_BRIGTH_MASK 0x0000FF00 #define ASUS_WMI_DSTS_LIGHTBAR_MASK 0x0000000F +struct asus_hid_listener { + struct list_head list; + void (*brightness_set)(struct asus_hid_listener *listener, int brightness); +}; + #if IS_REACHABLE(CONFIG_ASUS_WMI) int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1, u32 *retval); + +int asus_hid_register_listener(struct asus_hid_listener *cdev); +void asus_hid_unregister_listener(struct asus_hid_listener *cdev); #else static inline int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1, u32 *retval) { return -ENODEV; } + +static inline int asus_hid_register_listener(struct asus_hid_listener *bdev) +{ + return -ENODEV; +} +static inline void asus_hid_unregister_listener(struct asus_hid_listener *bdev) +{ +} #endif /* To be used by both hid-asus and asus-wmi to determine which controls kbd_brightness */ From patchwork Tue Mar 25 18:45:54 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antheas Kapenekakis X-Patchwork-Id: 14029358 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 17A6D1F4176; Tue, 25 Mar 2025 18:46:18 +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=1742928380; cv=none; b=i2wLg8gNSwXFiSLyIAwG7nOyGgh+Y7nyJ6peK863OS1fLeXLdu2nkn+d9uJqf9X4UJfQCkW6qPXpHtfCa9P917XvRpuvLJ3ESbL/V2/ZA0TfiAd+Im48ItIMV66l4I4lFXl4816xCoC+vwr45dqsXdJgZBHOV1B0GpX9BUKmjAo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742928380; c=relaxed/simple; bh=USvcqkAXXrbkecSZaf6Z8XwIVsRjFqhJqsX/QEOmjPw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=DJnqSJb7suG3HwdCScfLUZlTiTcNC3ticWDCii8e5YonTfqQ8clSsAvxX31UzprzjgiY4S0eZSFnwkApvkdLnVtE6lnfXanAAoiBJ0rqzuFWrkyziDtpzgkn3SgDtz+69b0v5iWFm49Eh0/jaoZsJ7YfoEekoCtgqocZ0VKm/EQ= 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=ICOIW9jQ; 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="ICOIW9jQ" Received: from localhost.localdomain (unknown [IPv6:2a05:f6c2:511b:0:cbc0:999f:73ad:33bd]) by linux1587.grserver.gr (Postfix) with ESMTPSA id 5590F2E098B7; Tue, 25 Mar 2025 20:46:14 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1742928376; bh=lRk6fReF1JKeZIlU6Lg/usYtqP8UZJvPLull7cMgH6c=; h=From:To:Subject; b=ICOIW9jQ+Z3Q41k8+xRYmSxYw4du6SC7AYE1ypU5Y3JlHFnfNcScUMWkrSAGiktcX pj70WfaTTbrdWeysMqCrm9rpl3HpZzY5i6s5rccLXL408T98ZltrCIAFXSDOBsG0AS 3yvWlNIU818f50yNTV1kZhzenfTph+lyUq0Ef62A= 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 05/11] HID: asus: listen to the asus-wmi brightness device instead of creating one Date: Tue, 25 Mar 2025 19:45:54 +0100 Message-ID: <20250325184601.10990-6-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: <174292837554.7963.17538415204232690349@linux1587.grserver.gr> X-PPP-Vhost: antheas.dev X-Virus-Scanned: clamav-milter 0.103.11 at linux1587.grserver.gr X-Virus-Status: Clean Some ROG laptops expose multiple interfaces for controlling the keyboard/RGB brightness. This creates a name conflict under asus::kbd_brightness, where the second device ends up being named asus::kbd_brightness_1 and they are both broken. Therefore, register a listener to the asus-wmi brightness device instead of creating a new one. Reviewed-by: Luke D. Jones Signed-off-by: Antheas Kapenekakis --- drivers/hid/hid-asus.c | 64 +++++++----------------------------------- 1 file changed, 10 insertions(+), 54 deletions(-) diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c index 7f070474ef8b4..9497e11577f93 100644 --- a/drivers/hid/hid-asus.c +++ b/drivers/hid/hid-asus.c @@ -97,7 +97,7 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad"); #define TRKID_SGN ((TRKID_MAX + 1) >> 1) struct asus_kbd_leds { - struct led_classdev cdev; + struct asus_hid_listener listener; struct hid_device *hdev; struct work_struct work; unsigned int brightness; @@ -490,11 +490,11 @@ static void asus_schedule_work(struct asus_kbd_leds *led) spin_unlock_irqrestore(&led->lock, flags); } -static void asus_kbd_backlight_set(struct led_classdev *led_cdev, - enum led_brightness brightness) +static void asus_kbd_backlight_set(struct asus_hid_listener *listener, + int brightness) { - struct asus_kbd_leds *led = container_of(led_cdev, struct asus_kbd_leds, - cdev); + struct asus_kbd_leds *led = container_of(listener, struct asus_kbd_leds, + listener); unsigned long flags; spin_lock_irqsave(&led->lock, flags); @@ -504,20 +504,6 @@ static void asus_kbd_backlight_set(struct led_classdev *led_cdev, asus_schedule_work(led); } -static enum led_brightness asus_kbd_backlight_get(struct led_classdev *led_cdev) -{ - struct asus_kbd_leds *led = container_of(led_cdev, struct asus_kbd_leds, - cdev); - enum led_brightness brightness; - unsigned long flags; - - spin_lock_irqsave(&led->lock, flags); - brightness = led->brightness; - spin_unlock_irqrestore(&led->lock, flags); - - return brightness; -} - static void asus_kbd_backlight_work(struct work_struct *work) { struct asus_kbd_leds *led = container_of(work, struct asus_kbd_leds, work); @@ -534,34 +520,6 @@ static void asus_kbd_backlight_work(struct work_struct *work) hid_err(led->hdev, "Asus failed to set keyboard backlight: %d\n", ret); } -/* WMI-based keyboard backlight LED control (via asus-wmi driver) takes - * precedence. We only activate HID-based backlight control when the - * WMI control is not available. - */ -static bool asus_kbd_wmi_led_control_present(struct hid_device *hdev) -{ - struct asus_drvdata *drvdata = hid_get_drvdata(hdev); - u32 value; - int ret; - - if (!IS_ENABLED(CONFIG_ASUS_WMI)) - return false; - - if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD && - dmi_check_system(asus_use_hid_led_dmi_ids)) { - hid_info(hdev, "using HID for asus::kbd_backlight\n"); - return false; - } - - ret = asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS, - ASUS_WMI_DEVID_KBD_BACKLIGHT, 0, &value); - hid_dbg(hdev, "WMI backlight check: rc %d value %x", ret, value); - if (ret) - return false; - - return !!(value & ASUS_WMI_DSTS_PRESENCE_BIT); -} - static int asus_kbd_register_leds(struct hid_device *hdev) { struct asus_drvdata *drvdata = hid_get_drvdata(hdev); @@ -596,14 +554,11 @@ static int asus_kbd_register_leds(struct hid_device *hdev) drvdata->kbd_backlight->removed = false; drvdata->kbd_backlight->brightness = 0; drvdata->kbd_backlight->hdev = hdev; - drvdata->kbd_backlight->cdev.name = "asus::kbd_backlight"; - drvdata->kbd_backlight->cdev.max_brightness = 3; - drvdata->kbd_backlight->cdev.brightness_set = asus_kbd_backlight_set; - drvdata->kbd_backlight->cdev.brightness_get = asus_kbd_backlight_get; + drvdata->kbd_backlight->listener.brightness_set = asus_kbd_backlight_set; INIT_WORK(&drvdata->kbd_backlight->work, asus_kbd_backlight_work); spin_lock_init(&drvdata->kbd_backlight->lock); - ret = devm_led_classdev_register(&hdev->dev, &drvdata->kbd_backlight->cdev); + ret = asus_hid_register_listener(&drvdata->kbd_backlight->listener); if (ret < 0) { /* No need to have this still around */ devm_kfree(&hdev->dev, drvdata->kbd_backlight); @@ -997,7 +952,7 @@ static int __maybe_unused asus_resume(struct hid_device *hdev) { if (drvdata->kbd_backlight) { const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0xba, 0xc5, 0xc4, - drvdata->kbd_backlight->cdev.brightness }; + drvdata->kbd_backlight->brightness }; ret = asus_kbd_set_report(hdev, buf, sizeof(buf)); if (ret < 0) { hid_err(hdev, "Asus failed to set keyboard backlight: %d\n", ret); @@ -1133,7 +1088,6 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id) } if (is_vendor && (drvdata->quirks & QUIRK_USE_KBD_BACKLIGHT) && - !asus_kbd_wmi_led_control_present(hdev) && asus_kbd_register_leds(hdev)) hid_warn(hdev, "Failed to initialize backlight.\n"); @@ -1174,6 +1128,8 @@ static void asus_remove(struct hid_device *hdev) unsigned long flags; if (drvdata->kbd_backlight) { + asus_hid_unregister_listener(&drvdata->kbd_backlight->listener); + spin_lock_irqsave(&drvdata->kbd_backlight->lock, flags); drvdata->kbd_backlight->removed = true; spin_unlock_irqrestore(&drvdata->kbd_backlight->lock, flags); From patchwork Tue Mar 25 18:45:55 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antheas Kapenekakis X-Patchwork-Id: 14029359 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 7E8101F419C; Tue, 25 Mar 2025 18:46:20 +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=1742928382; cv=none; b=ENQiar58wX6Vu2j7qkvimzTjjKyUgrmdgD8KNyoMfolqnmNgFmeNgjW8cknlvKcmOuZo7qRtniXaCGFCbIAElb7UbBN64Tp6rzTKrSEpRPpLL7P+b6sdAKH9hHf3iw7f4HHC2jjJ1HzBn6dqSv3uH2sH7TzK87//yn8YA2xoHAw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742928382; c=relaxed/simple; bh=BygUYtcHC1IOlX6moh+kyyRPEQgYoFGQtll23Vkk43w=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=dzKz76rutQjpcGOZLhs8jlC64eb1VsHY5wdUFZJGaoapiz3j8jw5KWXvljFQTqP5lB7BgSD53G6i59L2MfopLOn6YMUMsMIrxKgHXc3R9bbQAOjrDpbF2Ezr+3nTmL5Ut5NlFcGlz5jZzlVU60/OdLyHx4cdHWENp+uwhBqfsWE= 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=1eUyE8cd; 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="1eUyE8cd" Received: from localhost.localdomain (unknown [IPv6:2a05:f6c2:511b:0:cbc0:999f:73ad:33bd]) by linux1587.grserver.gr (Postfix) with ESMTPSA id 18FD92E098B3; Tue, 25 Mar 2025 20:46:17 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1742928378; bh=KpxnHdWM8D2D/jh5HMKpqy9RmSSrb7wZeUDfWEFML2Y=; h=From:To:Subject; b=1eUyE8cdejY7a9Vu8mX9HP6JmA1BB9OnbmVkiPn/jsmugRIWiOGssFL0/OJmj4gON bWq1erHW4hg0DjgPfsvDnmvOglSgaM4f9dRWegMcSh0zaIERrAaE0Y84El8OTjN1pe CK7U4Zl69CT4GRgMnt6Sf2Jyf2ZABzMSnNI4Eulg= 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 06/11] platform/x86: asus-wmi: remove unused keyboard backlight quirk Date: Tue, 25 Mar 2025 19:45:55 +0100 Message-ID: <20250325184601.10990-7-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: <174292837817.8085.7106803137935381120@linux1587.grserver.gr> X-PPP-Vhost: antheas.dev X-Virus-Scanned: clamav-milter 0.103.11 at linux1587.grserver.gr X-Virus-Status: Clean The quirk for selecting whether keyboard backlight should be controlled by HID or WMI is not needed anymore, so remove it. Reviewed-by: Luke D. Jones Signed-off-by: Antheas Kapenekakis --- include/linux/platform_data/x86/asus-wmi.h | 40 ---------------------- 1 file changed, 40 deletions(-) diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h index ec8b0c585a63f..c513b5a732323 100644 --- a/include/linux/platform_data/x86/asus-wmi.h +++ b/include/linux/platform_data/x86/asus-wmi.h @@ -183,44 +183,4 @@ static inline void asus_hid_unregister_listener(struct asus_hid_listener *bdev) } #endif -/* To be used by both hid-asus and asus-wmi to determine which controls kbd_brightness */ -static const struct dmi_system_id asus_use_hid_led_dmi_ids[] = { - { - .matches = { - DMI_MATCH(DMI_PRODUCT_FAMILY, "ROG Zephyrus"), - }, - }, - { - .matches = { - DMI_MATCH(DMI_PRODUCT_FAMILY, "ROG Strix"), - }, - }, - { - .matches = { - DMI_MATCH(DMI_PRODUCT_FAMILY, "ROG Flow"), - }, - }, - { - .matches = { - DMI_MATCH(DMI_PRODUCT_FAMILY, "ProArt P16"), - }, - }, - { - .matches = { - DMI_MATCH(DMI_BOARD_NAME, "GA403U"), - }, - }, - { - .matches = { - DMI_MATCH(DMI_BOARD_NAME, "GU605M"), - }, - }, - { - .matches = { - DMI_MATCH(DMI_BOARD_NAME, "RC71L"), - }, - }, - { }, -}; - #endif /* __PLATFORM_DATA_X86_ASUS_WMI_H */ From patchwork Tue Mar 25 18:45:56 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antheas Kapenekakis X-Patchwork-Id: 14029360 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 E61271F4617; Tue, 25 Mar 2025 18:46:21 +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=1742928383; cv=none; b=VXKJ2X8nFB1j0jN6CHS03JIzntCW6fQ1Gb8sLcC5vykVFh4UFV0AskXEgS4Zvd6MPEroNzOUHZ0vNgrDmuCksNYNRPv7ZFhbkdRrHbpFX9x/cT7zrmtfJJG/dG76i9m/KNls4RhphCfOvDrX2zQzvAcUYcDhJZoAF2+UiD3jVIg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742928383; c=relaxed/simple; bh=ofdGTVEAizFyb+v62EJLhjDSJukU7zB6uRDywz75jCU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=LBEHS9oN9r8h5HxaOU6nGJ4Bl25a+3YhRBV7DFOrftSdMKPJw5lZwuNDBDWZw9Z6M+kTR+UjgayttDLnsoAlnJ6qh4Kh4Z9wqjXytsTjr9nMeXAXmShDwVFcuR5OGfwdr8PuyiTbdIcOqi+pyNGvGqjOBXKE7E+FaYfcJHLyJ04= 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=iawzJkLS; 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="iawzJkLS" Received: from localhost.localdomain (unknown [IPv6:2a05:f6c2:511b:0:cbc0:999f:73ad:33bd]) by linux1587.grserver.gr (Postfix) with ESMTPSA id A47D42E098A8; Tue, 25 Mar 2025 20:46:18 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1742928379; bh=d4QiFVK4WmmwBkzG9Qr6f4R+trwulmtOg5R193riJSc=; h=From:To:Subject; b=iawzJkLSsNZ8t4TKpfegHpa4stK9sKIwNZw9JzJye5kDfYpYtilSgq8Z3+rw0qWU8 e1gas21LeeQDFqA7PJrVFnyuHDa6qfhu6wIpd/QqJeG3XJ4ukhc6FEUtqyEndQZdkW J9TVlBI2bMQOrXMwE1hFh5cDT9Aq+foV/rlRlBMg= 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 07/11] platform/x86: asus-wmi: add keyboard brightness event handler Date: Tue, 25 Mar 2025 19:45:56 +0100 Message-ID: <20250325184601.10990-8-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: <174292837969.8136.13505508897574718102@linux1587.grserver.gr> X-PPP-Vhost: antheas.dev X-Virus-Scanned: clamav-milter 0.103.11 at linux1587.grserver.gr X-Virus-Status: Clean Currenlty, the keyboard brightness control of Asus WMI keyboards is handled in the kernel, which leads to the shortcut going from brightness 0, to 1, to 2, and 3. However, for HID keyboards it is exposed as a key and handled by the user's desktop environment. For the toggle button, this means that brightness control becomes on/off. In addition, in the absence of a DE, the keyboard brightness does not work. Therefore, expose an event handler for the keyboard brightness control which can then be used by hid-asus. Reviewed-by: Luke D. Jones Tested-by: Luke D. Jones Signed-off-by: Antheas Kapenekakis --- drivers/platform/x86/asus-wmi.c | 41 +++++++++++++++++++++- include/linux/platform_data/x86/asus-wmi.h | 13 +++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index ff1d7ccb3982f..64185e3f55000 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -1536,6 +1536,45 @@ void asus_hid_unregister_listener(struct asus_hid_listener *bdev) } EXPORT_SYMBOL_GPL(asus_hid_unregister_listener); +static void do_kbd_led_set(struct led_classdev *led_cdev, int value); + +int asus_hid_event(enum asus_hid_event event) +{ + unsigned long flags; + int brightness; + + spin_lock_irqsave(&asus_ref.lock, flags); + if (!asus_ref.asus || !asus_ref.asus->kbd_led_registered) { + spin_unlock_irqrestore(&asus_ref.lock, flags); + return -EBUSY; + } + brightness = asus_ref.asus->kbd_led_wk; + + switch (event) { + case ASUS_EV_BRTUP: + brightness += 1; + break; + case ASUS_EV_BRTDOWN: + brightness -= 1; + break; + case ASUS_EV_BRTTOGGLE: + if (brightness >= ASUS_EV_MAX_BRIGHTNESS) + brightness = 0; + else + brightness += 1; + break; + } + + do_kbd_led_set(&asus_ref.asus->kbd_led, brightness); + led_classdev_notify_brightness_hw_changed(&asus_ref.asus->kbd_led, + asus_ref.asus->kbd_led_wk); + + spin_unlock_irqrestore(&asus_ref.lock, flags); + + return 0; +} +EXPORT_SYMBOL_GPL(asus_hid_event); + /* * These functions actually update the LED's, and are called from a * workqueue. By doing this as separate work rather than when the LED @@ -1835,7 +1874,7 @@ static int asus_wmi_led_init(struct asus_wmi *asus) asus->kbd_led.flags = LED_BRIGHT_HW_CHANGED; asus->kbd_led.brightness_set = kbd_led_set; asus->kbd_led.brightness_get = kbd_led_get; - asus->kbd_led.max_brightness = 3; + asus->kbd_led.max_brightness = ASUS_EV_MAX_BRIGHTNESS; asus->kbd_led_avail = !kbd_led_read(asus, &led_val, NULL); if (asus->kbd_led_avail) diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h index c513b5a732323..b051cd089c6d0 100644 --- a/include/linux/platform_data/x86/asus-wmi.h +++ b/include/linux/platform_data/x86/asus-wmi.h @@ -162,11 +162,20 @@ struct asus_hid_listener { void (*brightness_set)(struct asus_hid_listener *listener, int brightness); }; +enum asus_hid_event { + ASUS_EV_BRTUP, + ASUS_EV_BRTDOWN, + ASUS_EV_BRTTOGGLE, +}; + +#define ASUS_EV_MAX_BRIGHTNESS 3 + #if IS_REACHABLE(CONFIG_ASUS_WMI) int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1, u32 *retval); int asus_hid_register_listener(struct asus_hid_listener *cdev); void asus_hid_unregister_listener(struct asus_hid_listener *cdev); +int asus_hid_event(enum asus_hid_event event); #else static inline int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1, u32 *retval) @@ -181,6 +190,10 @@ static inline int asus_hid_register_listener(struct asus_hid_listener *bdev) static inline void asus_hid_unregister_listener(struct asus_hid_listener *bdev) { } +static inline int asus_hid_event(enum asus_hid_event event) +{ + return -ENODEV; +} #endif #endif /* __PLATFORM_DATA_X86_ASUS_WMI_H */ From patchwork Tue Mar 25 18:45:57 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antheas Kapenekakis X-Patchwork-Id: 14029361 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 D29AE1F4CA3; Tue, 25 Mar 2025 18:46:23 +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=1742928385; cv=none; b=jLiX+CKKrXDp9qR7Y1DYstXEtaap44zsVjhngdQZma9G+KOcFHU08iaM5IGXQWHXENHhyHBZtGLxXncDLfqV42QlGR7wUmx/kmr47VZunAWHS7LNhr7f8g/FbaRnBs/LJyALaM5vcJbNVBSQlkVid8Z33b7zmG3P8FBrlW2ck14= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742928385; c=relaxed/simple; bh=W9pJLnhFIf35zkQo9rH4p0zSE24DwlGqtwqFEiB/7SE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=DvR5HwwE46SS8pmsv6WvZlR08VsVhTYZoNBNOYw8GnYwEOhqhu3mUNwtAci26aSWAh9KKor6o174wMCrOEFIDUo0XhGPbDzlWhaG9AcHs/9kr+Hsk2C0MuWdP16ca9VuMmUoUdjDyLgkikDrffW3sjtaph/wAXs2DHIqhYvRP3M= 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=olRXy8MT; 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="olRXy8MT" Received: from localhost.localdomain (unknown [IPv6:2a05:f6c2:511b:0:cbc0:999f:73ad:33bd]) by linux1587.grserver.gr (Postfix) with ESMTPSA id 2DD4D2E098C2; Tue, 25 Mar 2025 20:46:20 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1742928381; bh=y58s2NqoOSS0+r/7Q1xuFckUs2twj7CZeSEpPojWvFk=; h=From:To:Subject; b=olRXy8MTAiED9m6+i/K/xwL+2g2bLuXoMD0D2NBHJVToQlL28Pf1Tdu4aIfG8+6wj o9lh6ZEguB10FricSuXzjyu2Uwfpk/LkLqsnSlQgsPDb7rLPzH1QXMuneOm/pPw7yJ hAq5CSM+6Irr1OpaWhSIb/pegRKJR81C+NcER7A0= 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 08/11] HID: asus: add support for the asus-wmi brightness handler Date: Tue, 25 Mar 2025 19:45:57 +0100 Message-ID: <20250325184601.10990-9-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: <174292838126.8204.16548926258215420829@linux1587.grserver.gr> X-PPP-Vhost: antheas.dev X-Virus-Scanned: clamav-milter 0.103.11 at linux1587.grserver.gr X-Virus-Status: Clean If the asus-wmi brightness handler is available, send the keyboard brightness events to it instead of passing them to userspace. If it is not, fall back to sending them to it. Reviewed-by: Luke D. Jones Tested-by: Luke D. Jones Signed-off-by: Antheas Kapenekakis --- drivers/hid/hid-asus.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c index 9497e11577f93..a4d1160460935 100644 --- a/drivers/hid/hid-asus.c +++ b/drivers/hid/hid-asus.c @@ -319,6 +319,17 @@ static int asus_event(struct hid_device *hdev, struct hid_field *field, usage->hid & HID_USAGE); } + if (usage->type == EV_KEY && value) { + switch (usage->code) { + case KEY_KBDILLUMUP: + return !asus_hid_event(ASUS_EV_BRTUP); + case KEY_KBDILLUMDOWN: + return !asus_hid_event(ASUS_EV_BRTDOWN); + case KEY_KBDILLUMTOGGLE: + return !asus_hid_event(ASUS_EV_BRTTOGGLE); + } + } + return 0; } From patchwork Tue Mar 25 18:45:58 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antheas Kapenekakis X-Patchwork-Id: 14029362 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 63A271F542E; Tue, 25 Mar 2025 18:46:25 +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=1742928387; cv=none; b=e6I/2Z8OeMUJhwJjVbQSVwocfTJoMm1czrp+2Hg252kqatoUTNvqIZOmWonrxMmoXCiTr8lW6rUL/1HozTlrWpOkVSgRnAzsKLm15FNOVgvemJpf9mm9EVZqnAdp0fF8B6UZz0YCA4MAr2aVYwA1FcZLfqLxbQQ7PGNau88Ue2A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742928387; c=relaxed/simple; bh=iMSkhTtPBXoIq2xdGrx/ZZsbsHDbuvf9GWKyLdEZY4k=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kw1WzHPdvFxdwJZ8u2yll2+xqzTvFnLh4n04kJkgUlRpCPzdsWZVPnFxiqgABraaeK7LYGA6GvuCY8xVYF6LCol2aCf7/vMmZnFapJrZ/XX63X0rEiSRunfL0U8iGlY5F8wk8wWK7XUgpcV9VueFhduLCjRTeCdFTv1guS6zsaE= 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=00FXXKjy; 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="00FXXKjy" Received: from localhost.localdomain (unknown [IPv6:2a05:f6c2:511b:0:cbc0:999f:73ad:33bd]) by linux1587.grserver.gr (Postfix) with ESMTPSA id ECFE82E098BB; Tue, 25 Mar 2025 20:46:21 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1742928383; bh=FGURjm1GvbiH64dTQupkFgl8O8EzilafoRnmodC0lZc=; h=From:To:Subject; b=00FXXKjyoxhaQQ1oYSDRkOgoMJ0u2mOEAPlAMme4DgnDq5DM40bhkYo8Q1UgwADO1 yToapxelgrSG/frPR4Rcdn+0QkMf612oUU/zQTSQL8xKh+ZXVWul7JdvQ1CNtaYmWI 3qiB6Tm83fJ2cwcLsbmmSclaFonARKWtxxIGif+I= 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 09/11] HID: asus: add basic RGB support Date: Tue, 25 Mar 2025 19:45:58 +0100 Message-ID: <20250325184601.10990-10-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: <174292838327.8265.11195129856759877496@linux1587.grserver.gr> X-PPP-Vhost: antheas.dev X-Virus-Scanned: clamav-milter 0.103.11 at linux1587.grserver.gr X-Virus-Status: Clean Adds basic RGB support to hid-asus through multi-index. The interface works quite well, but has not gone through much stability testing. Applied on demand, if userspace does not touch the RGB sysfs, not even initialization is done. Ensuring compatibility with existing userspace programs. Signed-off-by: Antheas Kapenekakis --- drivers/hid/Kconfig | 1 + drivers/hid/hid-asus.c | 171 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 156 insertions(+), 16 deletions(-) diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index dfc245867a46a..d324c6ab997de 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -151,6 +151,7 @@ config HID_APPLEIR config HID_ASUS tristate "Asus" depends on USB_HID + depends on LEDS_CLASS_MULTICOLOR depends on LEDS_CLASS depends on ASUS_WMI || ASUS_WMI=n select POWER_SUPPLY diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c index a4d1160460935..c135c9ff87b74 100644 --- a/drivers/hid/hid-asus.c +++ b/drivers/hid/hid-asus.c @@ -23,6 +23,7 @@ /* */ +#include #include #include #include @@ -30,6 +31,7 @@ #include #include /* For to_usb_interface for T100 touchpad intf check */ #include +#include #include #include "hid-ids.h" @@ -52,6 +54,7 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad"); #define FEATURE_KBD_REPORT_SIZE 64 #define FEATURE_KBD_LED_REPORT_ID1 0x5d #define FEATURE_KBD_LED_REPORT_ID2 0x5e +#define FEATURE_KBD_LED_REPORT_SIZE 7 #define SUPPORT_KBD_BACKLIGHT BIT(0) @@ -86,6 +89,7 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad"); #define QUIRK_ROG_NKEY_KEYBOARD BIT(11) #define QUIRK_ROG_CLAYMORE_II_KEYBOARD BIT(12) #define QUIRK_HANDLE_GENERIC BIT(13) +#define QUIRK_ROG_NKEY_RGB BIT(14) #define I2C_KEYBOARD_QUIRKS (QUIRK_FIX_NOTEBOOK_REPORT | \ QUIRK_NO_INIT_REPORTS | \ @@ -98,9 +102,15 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad"); struct asus_kbd_leds { struct asus_hid_listener listener; + struct led_classdev_mc mc_led; + struct mc_subled subled_info[3]; struct hid_device *hdev; struct work_struct work; unsigned int brightness; + u8 rgb_colors[3]; + bool rgb_init; + bool rgb_set; + bool rgb_registered; spinlock_t lock; bool removed; }; @@ -501,23 +511,67 @@ static void asus_schedule_work(struct asus_kbd_leds *led) spin_unlock_irqrestore(&led->lock, flags); } -static void asus_kbd_backlight_set(struct asus_hid_listener *listener, +static void do_asus_kbd_backlight_set(struct asus_kbd_leds *led, int brightness) +{ + unsigned long flags; + + spin_lock_irqsave(&led->lock, flags); + led->brightness = brightness; + spin_unlock_irqrestore(&led->lock, flags); + + asus_schedule_work(led); +} + +static void asus_kbd_listener_set(struct asus_hid_listener *listener, int brightness) { struct asus_kbd_leds *led = container_of(listener, struct asus_kbd_leds, listener); + do_asus_kbd_backlight_set(led, brightness); + if (led->rgb_registered) { + led->mc_led.led_cdev.brightness = brightness; + led_classdev_notify_brightness_hw_changed(&led->mc_led.led_cdev, + brightness); + } +} + +static void asus_kbd_brightness_set(struct led_classdev *led_cdev, + enum led_brightness brightness) +{ + struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(led_cdev); + struct asus_kbd_leds *led = container_of(mc_cdev, struct asus_kbd_leds, + mc_led); unsigned long flags; spin_lock_irqsave(&led->lock, flags); - led->brightness = brightness; + led->rgb_colors[0] = mc_cdev->subled_info[0].intensity; + led->rgb_colors[1] = mc_cdev->subled_info[1].intensity; + led->rgb_colors[2] = mc_cdev->subled_info[2].intensity; + led->rgb_set = true; spin_unlock_irqrestore(&led->lock, flags); - asus_schedule_work(led); + do_asus_kbd_backlight_set(led, brightness); +} + +static enum led_brightness asus_kbd_brightness_get(struct led_classdev *led_cdev) +{ + struct led_classdev_mc *mc_led; + struct asus_kbd_leds *led; + enum led_brightness brightness; + unsigned long flags; + + mc_led = lcdev_to_mccdev(led_cdev); + led = container_of(mc_led, struct asus_kbd_leds, mc_led); + + spin_lock_irqsave(&led->lock, flags); + brightness = led->brightness; + spin_unlock_irqrestore(&led->lock, flags); + + return brightness; } -static void asus_kbd_backlight_work(struct work_struct *work) +static void asus_kbd_backlight_work(struct asus_kbd_leds *led) { - struct asus_kbd_leds *led = container_of(work, struct asus_kbd_leds, work); u8 buf[] = { FEATURE_KBD_REPORT_ID, 0xba, 0xc5, 0xc4, 0x00 }; int ret; unsigned long flags; @@ -531,10 +585,68 @@ static void asus_kbd_backlight_work(struct work_struct *work) hid_err(led->hdev, "Asus failed to set keyboard backlight: %d\n", ret); } +static void asus_kbd_rgb_work(struct asus_kbd_leds *led) +{ + u8 rgb_buf[][FEATURE_KBD_LED_REPORT_SIZE] = { + { FEATURE_KBD_LED_REPORT_ID1, 0xB3 }, /* set mode */ + { FEATURE_KBD_LED_REPORT_ID1, 0xB5 }, /* apply mode */ + { FEATURE_KBD_LED_REPORT_ID1, 0xB4 }, /* save to mem */ + }; + unsigned long flags; + uint8_t colors[3]; + bool rgb_init, rgb_set; + int ret; + + spin_lock_irqsave(&led->lock, flags); + rgb_init = led->rgb_init; + rgb_set = led->rgb_set; + led->rgb_set = false; + colors[0] = led->rgb_colors[0]; + colors[1] = led->rgb_colors[1]; + colors[2] = led->rgb_colors[2]; + spin_unlock_irqrestore(&led->lock, flags); + + if (!rgb_set) + return; + + if (rgb_init) { + ret = asus_kbd_init(led->hdev, FEATURE_KBD_LED_REPORT_ID1); + if (ret < 0) { + hid_err(led->hdev, "Asus failed to init RGB: %d\n", ret); + return; + } + spin_lock_irqsave(&led->lock, flags); + led->rgb_init = false; + spin_unlock_irqrestore(&led->lock, flags); + } + + /* Protocol is: 54b3 zone (0=all) mode (0=solid) RGB */ + rgb_buf[0][4] = colors[0]; + rgb_buf[0][5] = colors[1]; + rgb_buf[0][6] = colors[2]; + + for (size_t i = 0; i < ARRAY_SIZE(rgb_buf); i++) { + ret = asus_kbd_set_report(led->hdev, rgb_buf[i], sizeof(rgb_buf[i])); + if (ret < 0) { + hid_err(led->hdev, "Asus failed to set RGB: %d\n", ret); + return; + } + } +} + +static void asus_kbd_work(struct work_struct *work) +{ + struct asus_kbd_leds *led = container_of(work, struct asus_kbd_leds, + work); + asus_kbd_backlight_work(led); + asus_kbd_rgb_work(led); +} + static int asus_kbd_register_leds(struct hid_device *hdev) { struct asus_drvdata *drvdata = hid_get_drvdata(hdev); unsigned char kbd_func; + struct asus_kbd_leds *leds; int ret; ret = asus_kbd_init(hdev, FEATURE_KBD_REPORT_ID); @@ -562,20 +674,47 @@ static int asus_kbd_register_leds(struct hid_device *hdev) if (!drvdata->kbd_backlight) return -ENOMEM; - drvdata->kbd_backlight->removed = false; - drvdata->kbd_backlight->brightness = 0; - drvdata->kbd_backlight->hdev = hdev; - drvdata->kbd_backlight->listener.brightness_set = asus_kbd_backlight_set; - INIT_WORK(&drvdata->kbd_backlight->work, asus_kbd_backlight_work); + leds = drvdata->kbd_backlight; + leds->removed = false; + leds->brightness = ASUS_EV_MAX_BRIGHTNESS; + leds->hdev = hdev; + leds->listener.brightness_set = asus_kbd_listener_set; + + leds->rgb_colors[0] = 0; + leds->rgb_colors[1] = 0; + leds->rgb_colors[2] = 0; + leds->rgb_init = true; + leds->rgb_set = false; + leds->mc_led.led_cdev.name = devm_kasprintf(&hdev->dev, GFP_KERNEL, + "asus-%s:rgb:peripheral", + strlen(hdev->uniq) ? + hdev->uniq : dev_name(&hdev->dev)); + leds->mc_led.led_cdev.flags = LED_BRIGHT_HW_CHANGED; + leds->mc_led.led_cdev.max_brightness = ASUS_EV_MAX_BRIGHTNESS; + leds->mc_led.led_cdev.brightness_set = asus_kbd_brightness_set; + leds->mc_led.led_cdev.brightness_get = asus_kbd_brightness_get; + leds->mc_led.subled_info = leds->subled_info; + leds->mc_led.num_colors = ARRAY_SIZE(leds->subled_info); + leds->subled_info[0].color_index = LED_COLOR_ID_RED; + leds->subled_info[1].color_index = LED_COLOR_ID_GREEN; + leds->subled_info[2].color_index = LED_COLOR_ID_BLUE; + + INIT_WORK(&drvdata->kbd_backlight->work, asus_kbd_work); spin_lock_init(&drvdata->kbd_backlight->lock); ret = asus_hid_register_listener(&drvdata->kbd_backlight->listener); - if (ret < 0) { - /* No need to have this still around */ - devm_kfree(&hdev->dev, drvdata->kbd_backlight); + /* Asus-wmi might not be accessible so this is not fatal. */ + if (!ret) + hid_warn(hdev, "Asus-wmi brightness listener not registered\n"); + + if (drvdata->quirks & QUIRK_ROG_NKEY_RGB) { + ret = devm_led_classdev_multicolor_register(&hdev->dev, &leds->mc_led); + if (!ret) + leds->rgb_registered = true; + return ret; } - return ret; + return 0; } /* @@ -1282,7 +1421,7 @@ static const struct hid_device_id asus_devices[] = { QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD }, { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_ROG_Z13_LIGHTBAR), - QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD }, + QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD | QUIRK_ROG_NKEY_RGB }, { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY), QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD }, @@ -1311,7 +1450,7 @@ static const struct hid_device_id asus_devices[] = { */ { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_ROG_Z13_FOLIO), - QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD }, + QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD | QUIRK_ROG_NKEY_RGB }, { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_T101HA_KEYBOARD) }, { } From patchwork Tue Mar 25 18:45:59 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antheas Kapenekakis X-Patchwork-Id: 14029363 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 30B8E1F5840; Tue, 25 Mar 2025 18:46:26 +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=1742928388; cv=none; b=SeZXBV7Lai5z/cgoNPWcngqIItXjb+xhcryE8nR4Hjir38/7WKwf8Sdx1vtAf15Yr0r5w8zy5hU6pArNk7+hDSu9ptJcvjMuF88TONXEoIdw9eaP0FEXuUVlYxZgRVgkkgqk4Pmt03ECTwpKsdQ6lUnUcwgiXWFVrsuljPs7yKY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742928388; c=relaxed/simple; bh=taFbeucJn+ckNBISe/bgtmxWdZL30X56uRuLp385a00=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=UD59YD6gxOwOis41406+l6abI5uJP/KJsM23EnxQ7Z54Sp1hMFpZ19UzJOxk+om2TmUWm3QRaXw8bodM76zK83ExtVlz5e4W71Cca20tAlnfiSOTX6MI3IblWzGPhV2QbkMUC1Tp/qnh4zcgvRd5tgs1JBHsCVAw1vmzYTly7tg= 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=42WRz7fy; 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="42WRz7fy" Received: from localhost.localdomain (unknown [IPv6:2a05:f6c2:511b:0:cbc0:999f:73ad:33bd]) by linux1587.grserver.gr (Postfix) with ESMTPSA id AFAC52E098CC; Tue, 25 Mar 2025 20:46:23 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1742928385; bh=D4LvuHsVvzT6ncv5a3kKSTQhMfeftQdCgXF8DdE5Ol4=; h=From:To:Subject; b=42WRz7fyIBMaoUFgmPN/7MK1RxbmvXGw5QRHV+FQkFBW+gEHcNmHNMwl+y9tU0afu 6wrlCSulMSVYU642azHDjd3OWQs+HYZw4ayCvX1KBXSYIxwPouzf2Wmo1SZTbGxQiX o6nBCpkb7dG/Y9fKzxmVlZf1AsELSdU3Rjra3NbU= 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 10/11] HID: asus: add RGB support to the ROG Ally units Date: Tue, 25 Mar 2025 19:45:59 +0100 Message-ID: <20250325184601.10990-11-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: <174292838479.8353.14432007376216030493@linux1587.grserver.gr> X-PPP-Vhost: antheas.dev X-Virus-Scanned: clamav-milter 0.103.11 at linux1587.grserver.gr X-Virus-Status: Clean Apply the RGB quirk to the QOG Ally units to enable basic RGB support. Reviewed-by: Luke D. Jones Signed-off-by: Antheas Kapenekakis --- drivers/hid/hid-asus.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c index c135c9ff87b74..fa8ec237efe26 100644 --- a/drivers/hid/hid-asus.c +++ b/drivers/hid/hid-asus.c @@ -1424,10 +1424,10 @@ static const struct hid_device_id asus_devices[] = { QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD | QUIRK_ROG_NKEY_RGB }, { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY), - QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD }, + QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD | QUIRK_ROG_NKEY_RGB }, { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY_X), - QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD }, + QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD | QUIRK_ROG_NKEY_RGB }, { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD), QUIRK_ROG_CLAYMORE_II_KEYBOARD }, From patchwork Tue Mar 25 18:46:00 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antheas Kapenekakis X-Patchwork-Id: 14029364 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 992611FCFF2; Tue, 25 Mar 2025 18:46:28 +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=1742928390; cv=none; b=RiEsDRvob3xZnmlKcQkTAb4qNiF7PdwOSl/8DWWbKD4cY0pG0y52pHM2tOCvXN7FbMNxT/s/ixytSmqw005/7WYuZtEp0kcyOVdOtq8BWoU3YhV/iAk+IozxNUPn+lTKgkA98R5vEOL50czRIAsg5QGNwxziI/4O6KkdHAAOwr8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742928390; c=relaxed/simple; bh=cnyYgtOi5KNtxZEDgq5Z8kRh7d0LELzKtjDTyWT0K08=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=T4kHtBiGBw/MPDNERHBuGwOLWTwbvlIw3Q6fxrJoZhJM8zpa72o/wWi1yk/22U9DGEMLSe5VlbCCST8SuMOU2yL8LA97wzERT3M12FLRxhUbZO5Br29PsI715RXJTOmuv61yU40LPWa9odH0MlQxw2Eht+zViKaQhx97SC0TrOA= 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=QuxRH2Cq; 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="QuxRH2Cq" Received: from localhost.localdomain (unknown [IPv6:2a05:f6c2:511b:0:cbc0:999f:73ad:33bd]) by linux1587.grserver.gr (Postfix) with ESMTPSA id 4091E2E024F9; Tue, 25 Mar 2025 20:46:25 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1742928386; bh=az0RkbSqa+vM4kpXbq8OEgK4+Zp0D8jSA5cGFeYf7oo=; h=From:To:Subject; b=QuxRH2CqGDrGUpf5qypp6+MVHwQ/aMCEStrdrDLEilZ9gKlVY4coSeT3SWcKTKkSG MhMOHCyECvIALlBw9/FrwoUu7iXGH0D0CU4sN4edFFFo3QqLk3qD4OmBmGbIIcYlbh Xai//HmQqCzxgq3uQcRd4XPzW4Fg5b5TUyXZyiq4= 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 11/11] HID: asus: initialize LED endpoint early for old NKEY keyboards Date: Tue, 25 Mar 2025 19:46:00 +0100 Message-ID: <20250325184601.10990-12-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: <174292838629.8406.5763028106211749699@linux1587.grserver.gr> X-PPP-Vhost: antheas.dev X-Virus-Scanned: clamav-milter 0.103.11 at linux1587.grserver.gr X-Virus-Status: Clean These keyboards have always had initialization in the kernel for 0x5d. At this point, it is hard to verify again and we risk regressions by removing this. Therefore, initialize with 0x5d, and skip RGB initialization if that is enabled. Signed-off-by: Antheas Kapenekakis --- drivers/hid/hid-asus.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c index fa8ec237efe26..d02d0629d03cd 100644 --- a/drivers/hid/hid-asus.c +++ b/drivers/hid/hid-asus.c @@ -90,6 +90,7 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad"); #define QUIRK_ROG_CLAYMORE_II_KEYBOARD BIT(12) #define QUIRK_HANDLE_GENERIC BIT(13) #define QUIRK_ROG_NKEY_RGB BIT(14) +#define QUIRK_ROG_NKEY_LEGACY BIT(15) #define I2C_KEYBOARD_QUIRKS (QUIRK_FIX_NOTEBOOK_REPORT | \ QUIRK_NO_INIT_REPORTS | \ @@ -647,12 +648,25 @@ static int asus_kbd_register_leds(struct hid_device *hdev) struct asus_drvdata *drvdata = hid_get_drvdata(hdev); unsigned char kbd_func; struct asus_kbd_leds *leds; + bool rgb_init = true; int ret; ret = asus_kbd_init(hdev, FEATURE_KBD_REPORT_ID); if (ret < 0) return ret; + if (drvdata->quirks & QUIRK_ROG_NKEY_LEGACY) { + /* + * These keyboards might need 0x5d for shortcuts to work. + * As it has been more than 5 years, it is hard to verify. + */ + ret = asus_kbd_init(hdev, FEATURE_KBD_LED_REPORT_ID1); + if (ret < 0) + return ret; + + rgb_init = false; + } + /* Get keyboard functions */ ret = asus_kbd_get_functions(hdev, &kbd_func, FEATURE_KBD_REPORT_ID); if (ret < 0) @@ -683,7 +697,7 @@ static int asus_kbd_register_leds(struct hid_device *hdev) leds->rgb_colors[0] = 0; leds->rgb_colors[1] = 0; leds->rgb_colors[2] = 0; - leds->rgb_init = true; + leds->rgb_init = rgb_init; leds->rgb_set = false; leds->mc_led.led_cdev.name = devm_kasprintf(&hdev->dev, GFP_KERNEL, "asus-%s:rgb:peripheral", @@ -1415,10 +1429,10 @@ static const struct hid_device_id asus_devices[] = { QUIRK_USE_KBD_BACKLIGHT }, { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD), - QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD }, + QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD | QUIRK_ROG_NKEY_LEGACY }, { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD2), - QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD }, + QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD | QUIRK_ROG_NKEY_LEGACY }, { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_ROG_Z13_LIGHTBAR), QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD | QUIRK_ROG_NKEY_RGB },