From nobody Sat Feb 7 17:55:15 2026 Received: from out-189.mta0.migadu.com (out-189.mta0.migadu.com [91.218.175.189]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 80EFA273D9F for ; Fri, 2 Jan 2026 23:43:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.189 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767397434; cv=none; b=cfxhgZeNQMSSWtTKE2PvX9qJ7cGJCNuLiZmcbscfPfy+IIJi2AFh8i3kc6DuUIAzE29eYNFBBgK/g8UGH8hzz4bI4SJxyh5vxLHglFSm8JEJeDHPq4WnfTZUtHhsbjwctBOQ/65F/9wxddpsO8x3hw0CxwD7W/f1dIpFlVh+DvQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767397434; c=relaxed/simple; bh=XCQHYdq3spbZE86t6SluvclGO9w1CrqV32bMnR1uFeI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qy9QHKGmM3gRHtMnPUimT5Gqr1+ikuPd8CNlu/+CRLs6F0DpohRdHYUiiOe3UIfwft1I+xGHFfi6pZSjEQSzhxxoMUZRDGoeUN0+rrkE8EC+EIUPNsm3rrEUdF5PGAxZEkRnM8lYyG30ciT3YBD7l3LiGs7ViHQEjgkvhNp8L4w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=sEWtepCP; arc=none smtp.client-ip=91.218.175.189 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="sEWtepCP" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1767397430; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=3m20kD7PwGCTH43gt8FUGu7YcWOl9a9RmHjQnwvr5Pg=; b=sEWtepCP/UAgdTBdCD0AwLCaHtknIVGafNjOXU6IZzzWcr6LXRB4EOV6Tx6lId6TQLZucM EOItxAbZA5NxtceCbCoipjEF/Vdt7zq6Wg53FsDigPD8gEM7LGRp2RwNtJD41UIx/rKf6l MIQMzzKUNnOKHad22yeQiRf+wrgWpNs= From: Denis Benato To: linux-kernel@vger.kernel.org Cc: platform-driver-x86@vger.kernel.org, "Hans de Goede" , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , "Luke D . Jones" , "Mateusz Schyboll" , "Denis Benato" , Denis Benato Subject: [PATCH v4 1/3] platform/x86: asus-wmi: explicitly mark more code with CONFIG_ASUS_WMI_DEPRECATED_ATTRS Date: Sat, 3 Jan 2026 00:43:42 +0100 Message-ID: <20260102234344.366227-2-denis.benato@linux.dev> In-Reply-To: <20260102234344.366227-1-denis.benato@linux.dev> References: <20260102234344.366227-1-denis.benato@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Be more explicit in code that will be excluded when compiling with CONFIG_ASUS_WMI_DEPRECATED_ATTRS disabled. Signed-off-by: Denis Benato --- drivers/platform/x86/asus-wmi.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wm= i.c index 4aec7ec69250..a49447eff4f4 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -302,7 +302,11 @@ struct asus_wmi { u32 nv_temp_target; =20 u32 kbd_rgb_dev; + +#if IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS) bool kbd_rgb_state_available; +#endif /* IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS) */ + bool oobe_state_available; =20 u8 throttle_thermal_policy_mode; @@ -1060,6 +1064,7 @@ static const struct attribute_group kbd_rgb_mode_grou= p =3D { }; =20 /* TUF Laptop Keyboard RGB State *****************************************= *****/ +#if IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS) static ssize_t kbd_rgb_state_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -1106,6 +1111,8 @@ static const struct attribute_group kbd_rgb_state_gro= up =3D { .attrs =3D kbd_rgb_state_attrs, }; =20 +#endif /* IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS) */ + static const struct attribute_group *kbd_rgb_mode_groups[] =3D { NULL, NULL, @@ -1861,8 +1868,11 @@ static int asus_wmi_led_init(struct asus_wmi *asus) =20 if (asus->kbd_rgb_dev) kbd_rgb_mode_groups[num_rgb_groups++] =3D &kbd_rgb_mode_group; + +#if IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS) if (asus->kbd_rgb_state_available) kbd_rgb_mode_groups[num_rgb_groups++] =3D &kbd_rgb_state_group; +#endif /* IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS) */ =20 asus->led_workqueue =3D create_singlethread_workqueue("led_workqueue"); if (!asus->led_workqueue) --=20 2.52.0 From nobody Sat Feb 7 17:55:15 2026 Received: from out-185.mta0.migadu.com (out-185.mta0.migadu.com [91.218.175.185]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4DCCB287258 for ; Fri, 2 Jan 2026 23:43:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.185 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767397435; cv=none; b=tS8m9JCDjw9jz8tyC/byx1qM5dtohNowd4EQWwQFxqQ/ysVIEk+aQdo1YRaF6Cf1FPMtQQYBrzCHAg/hIKKvP2mYPHltkcF6feSfY3PXI8+JPnxvzGDObELtLlbbJwF4/Q5qRKlV04vL0pPGnxP2r0mzheU844wKwnHb/hHrnH0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767397435; c=relaxed/simple; bh=Wwye0FsDRVXWDOz++6Ke8qWHyTppsRDMifFkqC+YIVY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=HKaXRd3he3Ycou4TjUTnYbmNxRuLzciaM56EhInPEfXuqUTO1XenSanMkGQmC5szX5TyvXqhY2piIuv/krGmHhEJcl3hdlqFu6lV0YRtT8dMJ8dNpVKx9RQtVwkMLpWL2PqRjovwvp6kJkht87z/z/nzF35sKP1XQHzFi7+iojE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=EhRWJ088; arc=none smtp.client-ip=91.218.175.185 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="EhRWJ088" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1767397431; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=73Qdq6BpDKBize+/jsCa+St3KAGenr/DhYHuWo7BcQQ=; b=EhRWJ088qycASBhzmPgTsnLExUFIitHrv1VR8jDbPbxDWhRjfapMjjUhM3Gp8phZv5VX4U mm3kY4V1sfh9mELterh/KIYzMVUcm3G2tv6fj6fYGdULMmxjwWDbsAEd0zAEQCPjY+yyw1 TrdJERi3Z70xaUQMgd8Ymet/0zNY82k= From: Denis Benato To: linux-kernel@vger.kernel.org Cc: platform-driver-x86@vger.kernel.org, "Hans de Goede" , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , "Luke D . Jones" , "Mateusz Schyboll" , "Denis Benato" , Denis Benato Subject: [PATCH v4 2/3] platform/x86: asus-wmi: fix sending OOBE at probe Date: Sat, 3 Jan 2026 00:43:43 +0100 Message-ID: <20260102234344.366227-3-denis.benato@linux.dev> In-Reply-To: <20260102234344.366227-1-denis.benato@linux.dev> References: <20260102234344.366227-1-denis.benato@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Disabling OOBE is an important step to be able to fully control the hardware in TUF laptops that requires this command, but the command has been incorrectly tied to deprecated attributes: restore sending the OOBE exit command. Fixes: c683651b6791 ("platform/x86: asus-wmi: deprecate bios features") Signed-off-by: Denis Benato --- drivers/platform/x86/asus-wmi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wm= i.c index a49447eff4f4..8dfdde7877a8 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -4899,7 +4899,6 @@ static int asus_wmi_add(struct platform_device *pdev) asus->egpu_enable_available =3D asus_wmi_dev_is_present(asus, ASUS_WMI_DE= VID_EGPU); asus->dgpu_disable_available =3D asus_wmi_dev_is_present(asus, ASUS_WMI_D= EVID_DGPU); asus->kbd_rgb_state_available =3D asus_wmi_dev_is_present(asus, ASUS_WMI_= DEVID_TUF_RGB_STATE); - asus->oobe_state_available =3D asus_wmi_dev_is_present(asus, ASUS_WMI_DEV= ID_OOBE); =20 if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_MINI_LED_MODE)) asus->mini_led_dev_id =3D ASUS_WMI_DEVID_MINI_LED_MODE; @@ -4912,6 +4911,8 @@ static int asus_wmi_add(struct platform_device *pdev) asus->gpu_mux_dev =3D ASUS_WMI_DEVID_GPU_MUX_VIVO; #endif /* IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS) */ =20 + asus->oobe_state_available =3D asus_wmi_dev_is_present(asus, ASUS_WMI_DEV= ID_OOBE); + if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY)) asus->throttle_thermal_policy_dev =3D ASUS_WMI_DEVID_THROTTLE_THERMAL_PO= LICY; else if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_THROTTLE_THERMAL_PO= LICY_VIVO)) --=20 2.52.0 From nobody Sat Feb 7 17:55:15 2026 Received: from out-177.mta0.migadu.com (out-177.mta0.migadu.com [91.218.175.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7DBB22C3278 for ; Fri, 2 Jan 2026 23:43:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.177 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767397437; cv=none; b=AF7+aa3wY/EnmZHkZlVtPgetm0C46tD1VIMjhp6njBz6GwMsCnq7YaLk7KYc3nYpB0owLVkGSyA1OcEO197IKOuUmC+IBzt41bB91cU1k9qQPOyAcWVzXKF9xFNRUNXcjH15TexUQAvFHkMoJYdPSzWeLlMm9SV54Q0vo1LkT30= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767397437; c=relaxed/simple; bh=dZyqR0X89n8KiHLqRhb2/H8+mw5z7cyEfy4PEfDs2YU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=TbwzhXfHEplAskbK2sf6GIbDujWGlsxZYIwpv3jvc0u8wkmfLKfzkSWCSfuTDz/9Cmjt/c4Mi5oRu5//JZZ8euSGoI0+Cw9sAsiT9RY38meLY3FGhiRQTrTb/oqEoMr/ZtjDV3clab+0JnnUlXwANN/9bWDtdMaa/829qlmHwP8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=QYt4/5Y7; arc=none smtp.client-ip=91.218.175.177 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="QYt4/5Y7" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1767397432; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=HhnRwdCDSPTCFckFhr9hNr7XtyCqrMeKhgfemsuFaNQ=; b=QYt4/5Y7nRW1l2cTk4y1KgBEu0I0bgfwq1KIyp7Wx/J+nYiutytXFTXXpMUKYqjRaVUPWN WyHECtb/pH0SfoIYD3cgZ5BVHaAYaD4SJHVObGUKSbl45Sxu7onQ8g8X3PC8phv4+hGoHx UjrVfciO13hxaYNQ5KNR7XI3BzIu1YI= From: Denis Benato To: linux-kernel@vger.kernel.org Cc: platform-driver-x86@vger.kernel.org, "Hans de Goede" , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , "Luke D . Jones" , "Mateusz Schyboll" , "Denis Benato" , Denis Benato , =?UTF-8?q?Merthan=20Karaka=C5=9F?= Subject: [PATCH v4 3/3] platform/x86: asus-armoury: add keyboard control firmware attributes Date: Sat, 3 Jan 2026 00:43:44 +0100 Message-ID: <20260102234344.366227-4-denis.benato@linux.dev> In-Reply-To: <20260102234344.366227-1-denis.benato@linux.dev> References: <20260102234344.366227-1-denis.benato@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Implement keyboard status firmware attributes in asus-armoury after deprecating those attribute(s) in asus-wmi to avoid losing the ability to control LEDs status. Signed-off-by: Denis Benato Tested-by: Merthan Karaka=C5=9F --- drivers/platform/x86/asus-armoury.c | 253 +++++++++++++++++++++ include/linux/platform_data/x86/asus-wmi.h | 18 ++ 2 files changed, 271 insertions(+) diff --git a/drivers/platform/x86/asus-armoury.c b/drivers/platform/x86/asu= s-armoury.c index 9c1a9ad42bc4..be803faa1ece 100644 --- a/drivers/platform/x86/asus-armoury.c +++ b/drivers/platform/x86/asus-armoury.c @@ -76,10 +76,22 @@ struct rog_tunables { u32 nv_tgp; }; =20 +struct asus_armoury_kbd_status { + bool boot; + bool awake; + bool sleep; + bool shutdown; +}; + struct asus_armoury_priv { struct device *fw_attr_dev; struct kset *fw_attr_kset; =20 + struct mutex keyboard_mutex; + + /* Current TUF keyboard RGB state tracking */ + struct asus_armoury_kbd_status *kbd_state; + /* * Mutex to protect eGPU activation/deactivation * sequences and dGPU connection status: @@ -97,6 +109,7 @@ struct asus_armoury_priv { =20 static struct asus_armoury_priv asus_armoury =3D { .egpu_mutex =3D __MUTEX_INITIALIZER(asus_armoury.egpu_mutex), + .keyboard_mutex =3D __MUTEX_INITIALIZER(asus_armoury.keyboard_mutex), }; =20 struct fw_attrs_group { @@ -433,6 +446,164 @@ static ssize_t mini_led_mode_possible_values_show(str= uct kobject *kobj, } ASUS_ATTR_GROUP_ENUM(mini_led_mode, "mini_led_mode", "Set the mini-LED bac= klight mode"); =20 +/* Keyboard power management *********************************************= *****/ + +static int armoury_kbd_state(struct kobj_attribute *attr, + const struct asus_armoury_kbd_status *status) +{ + u32 kbd_state =3D ASUS_WMI_DEVID_TUF_RGB_STATE_EN | ASUS_WMI_DEVID_TUF_RG= B_STATE_CMD; + + kbd_state |=3D FIELD_PREP(ASUS_WMI_DEVID_TUF_RGB_STATE_BOOT, status->boot= ? 1 : 0); + kbd_state |=3D FIELD_PREP(ASUS_WMI_DEVID_TUF_RGB_STATE_AWAKE, status->awa= ke ? 1 : 0); + kbd_state |=3D FIELD_PREP(ASUS_WMI_DEVID_TUF_RGB_STATE_SLEEP, status->sle= ep ? 1 : 0); + kbd_state |=3D FIELD_PREP(ASUS_WMI_DEVID_TUF_RGB_STATE_SHUTDOWN, status->= shutdown ? 1 : 0); + + return armoury_set_devstate(attr, kbd_state, NULL, ASUS_WMI_DEVID_TUF_RGB= _STATE); +} + +enum asus_armoury_kbd_state_field { + ASUS_ARMOURY_KBD_STATE_BOOT, + ASUS_ARMOURY_KBD_STATE_AWAKE, + ASUS_ARMOURY_KBD_STATE_SLEEP, + ASUS_ARMOURY_KBD_STATE_SHUTDOWN, +}; + +static ssize_t armoury_kbd_state_write(struct kobject *kobj, struct kobj_a= ttribute *attr, + const char *buf, size_t count, + enum asus_armoury_kbd_state_field field) +{ + struct asus_armoury_kbd_status kbd_status; + bool enable; + ssize_t err; + + err =3D kstrtobool(buf, &enable); + if (err) + return err; + + scoped_guard(mutex, &asus_armoury.keyboard_mutex) { + memcpy(&kbd_status, asus_armoury.kbd_state, sizeof(kbd_status)); + + switch (field) { + case ASUS_ARMOURY_KBD_STATE_BOOT: + kbd_status.boot =3D enable; + break; + case ASUS_ARMOURY_KBD_STATE_AWAKE: + kbd_status.awake =3D enable; + break; + case ASUS_ARMOURY_KBD_STATE_SLEEP: + kbd_status.sleep =3D enable; + break; + case ASUS_ARMOURY_KBD_STATE_SHUTDOWN: + kbd_status.shutdown =3D enable; + break; + default: + return -EINVAL; + } + + err =3D armoury_kbd_state(attr, &kbd_status); + if (err) + return err; + + memcpy(asus_armoury.kbd_state, &kbd_status, sizeof(kbd_status)); + } + + sysfs_notify(kobj, NULL, attr->attr.name); + + return count; +} + +static ssize_t armoury_kbd_state_read(struct kobject *kobj, struct kobj_at= tribute *attr, + char *buf, enum asus_armoury_kbd_state_field field) +{ + bool *field_ptr, field_enabled; + + switch (field) { + case ASUS_ARMOURY_KBD_STATE_AWAKE: + field_ptr =3D &asus_armoury.kbd_state->awake; + break; + case ASUS_ARMOURY_KBD_STATE_SLEEP: + field_ptr =3D &asus_armoury.kbd_state->sleep; + break; + case ASUS_ARMOURY_KBD_STATE_BOOT: + field_ptr =3D &asus_armoury.kbd_state->boot; + break; + case ASUS_ARMOURY_KBD_STATE_SHUTDOWN: + field_ptr =3D &asus_armoury.kbd_state->shutdown; + break; + default: + return -EINVAL; + } + + scoped_guard(mutex, &asus_armoury.keyboard_mutex) + field_enabled =3D *field_ptr; + + return sysfs_emit(buf, field_enabled ? "1\n" : "0\n"); +} + +static ssize_t kbd_leds_sleep_current_value_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count) +{ + return armoury_kbd_state_write(kobj, attr, buf, count, ASUS_ARMOURY_KBD_S= TATE_SLEEP); +} + +static ssize_t kbd_leds_sleep_current_value_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return armoury_kbd_state_read(kobj, attr, buf, ASUS_ARMOURY_KBD_STATE_SLE= EP); +} + +ASUS_ATTR_GROUP_BOOL(kbd_leds_sleep, "kbd_leds_sleep", + "Keyboard backlight while system is sleeping"); + +static ssize_t kbd_leds_boot_current_value_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count) +{ + return armoury_kbd_state_write(kobj, attr, buf, count, ASUS_ARMOURY_KBD_S= TATE_BOOT); +} + +static ssize_t kbd_leds_boot_current_value_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return armoury_kbd_state_read(kobj, attr, buf, ASUS_ARMOURY_KBD_STATE_BOO= T); +} + +ASUS_ATTR_GROUP_BOOL(kbd_leds_boot, "kbd_leds_boot", + "Keyboard backlight while system is booting"); + +static ssize_t kbd_leds_awake_current_value_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count) +{ + return armoury_kbd_state_write(kobj, attr, buf, count, ASUS_ARMOURY_KBD_S= TATE_AWAKE); +} + +static ssize_t kbd_leds_awake_current_value_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return armoury_kbd_state_read(kobj, attr, buf, ASUS_ARMOURY_KBD_STATE_AWA= KE); +} + +ASUS_ATTR_GROUP_BOOL(kbd_leds_awake, "kbd_leds_awake", + "Keyboard backlight while system is awake"); + +static ssize_t kbd_leds_shutdown_current_value_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count) +{ + return armoury_kbd_state_write(kobj, attr, buf, count, ASUS_ARMOURY_KBD_S= TATE_SHUTDOWN); +} + +static ssize_t kbd_leds_shutdown_current_value_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return armoury_kbd_state_read(kobj, attr, buf, ASUS_ARMOURY_KBD_STATE_SHU= TDOWN); +} + +ASUS_ATTR_GROUP_BOOL(kbd_leds_shutdown, "kbd_leds_shutdown", + "Keyboard backlight while system is shutdown"); + static ssize_t gpu_mux_mode_current_value_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) @@ -867,6 +1038,32 @@ static bool has_valid_limit(const char *name, const s= truct power_limits *limits) return limit_value > 0; } =20 +static struct asus_armoury_kbd_status *asus_init_kbd_state(void) +{ + u32 kbd_status; + int err; + + err =3D armoury_get_devstate(NULL, &kbd_status, ASUS_WMI_DEVID_TUF_RGB_ST= ATE); + if (err) { + pr_debug("ACPI does not support keyboard power control: %d\n", err); + return ERR_PTR(-ENODEV); + } + + struct asus_armoury_kbd_status *kbd_state __free(kfree) =3D + kzalloc(sizeof(*kbd_state), GFP_KERNEL); + if (!kbd_state) + return ERR_PTR(-ENODEV); + + /* + * By default leds are off for all states (to spare power) + * except for when laptop is awake, where leds color and + * brightness are controllable by userspace. + */ + kbd_state->awake =3D true; + + return_ptr(kbd_state); +} + static int asus_fw_attr_add(void) { const struct rog_tunables *const ac_rog_tunables =3D @@ -955,8 +1152,64 @@ static int asus_fw_attr_add(void) } } =20 + asus_armoury.kbd_state =3D NULL; + if (armoury_has_devstate(ASUS_WMI_DEVID_TUF_RGB_STATE)) { + asus_armoury.kbd_state =3D asus_init_kbd_state(); + if (IS_ERR(asus_armoury.kbd_state)) { + asus_armoury.kbd_state =3D NULL; + err =3D PTR_ERR(asus_armoury.kbd_state); + pr_err("Failed to get keyboard status: %d\n", err); + goto err_remove_groups; + } + + err =3D sysfs_create_group(&asus_armoury.fw_attr_kset->kobj, &kbd_leds_s= leep_attr_group); + if (err) { + pr_err("Failed to create sysfs-group for keyboard backlight sleep state= : %d\n", err); + goto err_kbd_state; + } + + err =3D sysfs_create_group(&asus_armoury.fw_attr_kset->kobj, &kbd_leds_b= oot_attr_group); + if (err) { + pr_err("Failed to create sysfs-group for keyboard backlight boot state:= %d\n", err); + goto err_remove_kbd_sleep_attr; + } + + err =3D sysfs_create_group(&asus_armoury.fw_attr_kset->kobj, &kbd_leds_a= wake_attr_group); + if (err) { + pr_err("Failed to create sysfs-group for keyboard backlight awake state= : %d\n", err); + goto err_remove_kbd_boot_attr; + } + + err =3D sysfs_create_group(&asus_armoury.fw_attr_kset->kobj, &kbd_leds_s= hutdown_attr_group); + if (err) { + pr_err("Failed to create sysfs-group for keyboard backlight shutdown st= ate: %d\n", err); + goto err_remove_kbd_awake_attr; + } + + /* + * The attribute is write-only and for the state to be coherent + * a default state has to written: userspace is expected to + * modify it based on user preference. + */ + err =3D armoury_kbd_state(&attr_kbd_leds_awake_current_value, asus_armou= ry.kbd_state); + if (err) { + pr_err("Failed to initialize keyboard backlight states: %d\n", err); + goto err_remove_kbd_shutdown_attr; + } + } + return 0; =20 +err_remove_kbd_shutdown_attr: + sysfs_remove_group(&asus_armoury.fw_attr_kset->kobj, &kbd_leds_shutdown_a= ttr_group); +err_remove_kbd_awake_attr: + sysfs_remove_group(&asus_armoury.fw_attr_kset->kobj, &kbd_leds_awake_attr= _group); +err_remove_kbd_boot_attr: + sysfs_remove_group(&asus_armoury.fw_attr_kset->kobj, &kbd_leds_boot_attr_= group); +err_remove_kbd_sleep_attr: + sysfs_remove_group(&asus_armoury.fw_attr_kset->kobj, &kbd_leds_sleep_attr= _group); +err_kbd_state: + kfree(asus_armoury.kbd_state); err_remove_groups: while (i--) { if (armoury_has_devstate(armoury_attr_groups[i].wmi_devid)) diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/pla= tform_data/x86/asus-wmi.h index 419491d4abca..275933e0d79e 100644 --- a/include/linux/platform_data/x86/asus-wmi.h +++ b/include/linux/platform_data/x86/asus-wmi.h @@ -2,6 +2,7 @@ #ifndef __PLATFORM_DATA_X86_ASUS_WMI_H #define __PLATFORM_DATA_X86_ASUS_WMI_H =20 +#include #include #include =20 @@ -153,6 +154,23 @@ /* TUF laptop RGB power/state */ #define ASUS_WMI_DEVID_TUF_RGB_STATE 0x00100057 =20 +#define ASUS_WMI_DEVID_TUF_RGB_STATE_EN 0xBD + +#define ASUS_WMI_DEVID_TUF_RGB_STATE_CMD BIT(10) + +/* + * Flags for TUF RGB state to be used with ASUS_WMI_DEVID_TUF_RGB_STATE: + * flags | ASUS_WMI_DEVID_TUF_RGB_STATE_CMD | ASUS_WMI_DEVID_TUF_RGB_STATE= _EN + * + * where ASUS_WMI_DEVID_TUF_RGB_STATE_EN is required for the method call + * to not be discarded, ASUS_WMI_DEVID_TUF_RGB_STATE_EN specifies this is + * a command and flags is a combination of one or more of the following fl= ags. + */ +#define ASUS_WMI_DEVID_TUF_RGB_STATE_BOOT GENMASK(17, 17) +#define ASUS_WMI_DEVID_TUF_RGB_STATE_AWAKE GENMASK(19, 19) +#define ASUS_WMI_DEVID_TUF_RGB_STATE_SLEEP GENMASK(21, 21) +#define ASUS_WMI_DEVID_TUF_RGB_STATE_SHUTDOWN GENMASK(23, 23) + /* Bootup sound control */ #define ASUS_WMI_DEVID_BOOT_SOUND 0x00130022 =20 --=20 2.52.0