aboutsummaryrefslogtreecommitdiff
path: root/SOURCES/asus-linux.patch
diff options
context:
space:
mode:
authorJan200101 <sentrycraft123@gmail.com>2022-12-17 20:33:01 +0100
committerJan200101 <sentrycraft123@gmail.com>2022-12-17 20:33:01 +0100
commitea0842afce28469ea9eb77283e1aa31cf857b30b (patch)
tree0cebe9eb6f50fa5eaa51aa328f3189d2e8d60a91 /SOURCES/asus-linux.patch
parent98b9a029cfa590301cda089365e03ab02b03685c (diff)
downloadkernel-fsync-ea0842afce28469ea9eb77283e1aa31cf857b30b.tar.gz
kernel-fsync-ea0842afce28469ea9eb77283e1aa31cf857b30b.zip
kernel 6.0.13
Diffstat (limited to 'SOURCES/asus-linux.patch')
-rw-r--r--SOURCES/asus-linux.patch2886
1 files changed, 899 insertions, 1987 deletions
diff --git a/SOURCES/asus-linux.patch b/SOURCES/asus-linux.patch
index 947accc..1276952 100644
--- a/SOURCES/asus-linux.patch
+++ b/SOURCES/asus-linux.patch
@@ -1,158 +1,42 @@
-From 170f0da25dac630dacb920d043fb20e12c287520 Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones" <luke@ljones.dev>
-Date: Tue, 9 Aug 2022 14:50:53 +1200
-Subject: [PATCH 01/19] platform/x86: asus-wmi: Convert all attr-show to use
- sysfs_emit
+From 0afaa446a07db0ded4c032511b35485bd12ff80f Mon Sep 17 00:00:00 2001
+From: Jan200101 <sentrycraft123@gmail.com>
+Date: Sat, 17 Dec 2022 18:14:04 +0100
+Subject: [PATCH] asus-linux
-This changes all *_show attributes in asus-wmi.c to use sysfs_emit()
-instead of the older method of writing to the output buffer manually.
-
-Signed-off-by: Luke D. Jones <luke@ljones.dev>
-Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
-Link: https://lore.kernel.org/r/20220809025054.1626339-6-luke@ljones.dev
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
----
- drivers/platform/x86/asus-wmi.c | 14 +++++++-------
- 1 file changed, 7 insertions(+), 7 deletions(-)
-
-diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
-index 89b604e04d7f..b5c977d37bc1 100644
---- a/drivers/platform/x86/asus-wmi.c
-+++ b/drivers/platform/x86/asus-wmi.c
-@@ -771,7 +771,7 @@ static ssize_t charge_control_end_threshold_show(struct device *device,
- struct device_attribute *attr,
- char *buf)
- {
-- return sprintf(buf, "%d\n", charge_end_threshold);
-+ return sysfs_emit(buf, "%d\n", charge_end_threshold);
- }
-
- static DEVICE_ATTR_RW(charge_control_end_threshold);
-@@ -1819,7 +1819,7 @@ static ssize_t pwm1_show(struct device *dev,
- value = -1;
- }
-
-- return sprintf(buf, "%d\n", value);
-+ return sysfs_emit(buf, "%d\n", value);
- }
-
- static ssize_t pwm1_store(struct device *dev,
-@@ -1879,7 +1879,7 @@ static ssize_t fan1_input_show(struct device *dev,
- return -ENXIO;
- }
-
-- return sprintf(buf, "%d\n", value < 0 ? -1 : value*100);
-+ return sysfs_emit(buf, "%d\n", value < 0 ? -1 : value * 100);
- }
-
- static ssize_t pwm1_enable_show(struct device *dev,
-@@ -1897,7 +1897,7 @@ static ssize_t pwm1_enable_show(struct device *dev,
- * in practice on X532FL at least (the bit is always 0) and there's
- * also nothing in the DSDT to indicate that this behaviour exists.
- */
-- return sprintf(buf, "%d\n", asus->fan_pwm_mode);
-+ return sysfs_emit(buf, "%d\n", asus->fan_pwm_mode);
- }
-
- static ssize_t pwm1_enable_store(struct device *dev,
-@@ -1965,7 +1965,7 @@ static ssize_t fan1_label_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
- {
-- return sprintf(buf, "%s\n", ASUS_FAN_DESC);
-+ return sysfs_emit(buf, "%s\n", ASUS_FAN_DESC);
- }
-
- static ssize_t asus_hwmon_temp1(struct device *dev,
-@@ -2158,7 +2158,7 @@ static ssize_t fan_boost_mode_show(struct device *dev,
- {
- struct asus_wmi *asus = dev_get_drvdata(dev);
-
-- return scnprintf(buf, PAGE_SIZE, "%d\n", asus->fan_boost_mode);
-+ return sysfs_emit(buf, "%d\n", asus->fan_boost_mode);
- }
-
- static ssize_t fan_boost_mode_store(struct device *dev,
-@@ -2711,7 +2711,7 @@ static ssize_t throttle_thermal_policy_show(struct device *dev,
- struct asus_wmi *asus = dev_get_drvdata(dev);
- u8 mode = asus->throttle_thermal_policy_mode;
-
-- return scnprintf(buf, PAGE_SIZE, "%d\n", mode);
-+ return sysfs_emit(buf, "%d\n", mode);
- }
-
- static ssize_t throttle_thermal_policy_store(struct device *dev,
---
-2.37.2
-
-From a8f9c36c4bb705af4b6054244ff9669cdd8dcf71 Mon Sep 17 00:00:00 2001
-From: ye xingchen <ye.xingchen@zte.com.cn>
-Date: Thu, 11 Aug 2022 01:32:03 +0000
-Subject: [PATCH 02/19] platform/x86: asus-wmi: Use kobj_to_dev()
-
-Use kobj_to_dev() instead of open-coding it.
-
-Reported-by: Zeal Robot <zealci@zte.com.cn>
-Signed-off-by: ye xingchen <ye.xingchen@zte.com.cn>
-Link: https://lore.kernel.org/r/20220811013203.16010-1-ye.xingchen@zte.com.cn
-Reviewed-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Jan200101 <sentrycraft123@gmail.com>
---
- drivers/platform/x86/asus-wmi.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
-index b5c977d37bc1..e461299d938a 100644
---- a/drivers/platform/x86/asus-wmi.c
-+++ b/drivers/platform/x86/asus-wmi.c
-@@ -2006,7 +2006,7 @@ static struct attribute *hwmon_attributes[] = {
- static umode_t asus_hwmon_sysfs_is_visible(struct kobject *kobj,
- struct attribute *attr, int idx)
- {
-- struct device *dev = container_of(kobj, struct device, kobj);
-+ struct device *dev = kobj_to_dev(kobj);
- struct asus_wmi *asus = dev_get_drvdata(dev->parent);
- u32 value = ASUS_WMI_UNSUPPORTED_METHOD;
-
-@@ -3294,7 +3294,7 @@ static struct attribute *platform_attributes[] = {
- static umode_t asus_sysfs_is_visible(struct kobject *kobj,
- struct attribute *attr, int idx)
- {
-- struct device *dev = container_of(kobj, struct device, kobj);
-+ struct device *dev = kobj_to_dev(kobj);
- struct asus_wmi *asus = dev_get_drvdata(dev);
- bool ok = true;
- int devid = -1;
---
-2.37.2
-
-From 7e64c486e807c8edfbd3a0c8e44ad7a1896dbec8 Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones" <luke@ljones.dev>
-Date: Sat, 13 Aug 2022 10:25:04 +1200
-Subject: [PATCH 03/19] platform/x86: asus-wmi: Document the dgpu_disable sysfs
- attribute
-
-The dgpu_disable attribute was not documented, this adds the
-required documentation.
-
-Fixes: 98829e84dc67 ("asus-wmi: Add dgpu disable method")
-Signed-off-by: Luke D. Jones <luke@ljones.dev>
-Link: https://lore.kernel.org/r/20220812222509.292692-2-luke@ljones.dev
-Reviewed-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
----
- Documentation/ABI/testing/sysfs-platform-asus-wmi | 9 +++++++++
- 1 file changed, 9 insertions(+)
+ .../ABI/testing/sysfs-platform-asus-wmi | 41 ++
+ drivers/hid/amd-sfh-hid/amd_sfh_pcie.c | 4 +
+ drivers/hid/amd-sfh-hid/amd_sfh_pcie.h | 1 +
+ .../hid_descriptor/amd_sfh_hid_desc.c | 27 +
+ .../hid_descriptor/amd_sfh_hid_desc.h | 8 +
+ .../hid_descriptor/amd_sfh_hid_report_desc.h | 19 +
+ drivers/platform/x86/asus-nb-wmi.c | 14 +-
+ drivers/platform/x86/asus-wmi.c | 677 ++++++++++--------
+ include/linux/platform_data/x86/asus-wmi.h | 10 +
+ 9 files changed, 503 insertions(+), 298 deletions(-)
diff --git a/Documentation/ABI/testing/sysfs-platform-asus-wmi b/Documentation/ABI/testing/sysfs-platform-asus-wmi
-index 04885738cf15..0f8f0772d6f3 100644
+index 04885738cf15..a77a004a1baa 100644
--- a/Documentation/ABI/testing/sysfs-platform-asus-wmi
+++ b/Documentation/ABI/testing/sysfs-platform-asus-wmi
-@@ -57,3 +57,12 @@ Description:
+@@ -57,3 +57,44 @@ Description:
* 0 - default,
* 1 - overboost,
* 2 - silent
+
++What: /sys/devices/platform/<platform>/gpu_mux_mode
++Date: Aug 2022
++KernelVersion: 6.1
++Contact: "Luke Jones" <luke@ljones.dev>
++Description:
++ Switch the GPU hardware MUX mode. Laptops with this feature can
++ can be toggled to boot with only the dGPU (discrete mode) or in
++ standard Optimus/Hybrid mode. On switch a reboot is required:
++
++ * 0 - Discrete GPU,
++ * 1 - Optimus/Hybrid,
++
+What: /sys/devices/platform/<platform>/dgpu_disable
+Date: Aug 2022
+KernelVersion: 5.17
@@ -161,35 +45,6 @@ index 04885738cf15..0f8f0772d6f3 100644
+ Disable discrete GPU:
+ * 0 - Enable dGPU,
+ * 1 - Disable dGPU
---
-2.37.2
-
-From 3206376f099d9c74d9938b9c41cfc0b85ea6e1b0 Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones" <luke@ljones.dev>
-Date: Sat, 13 Aug 2022 10:25:05 +1200
-Subject: [PATCH 04/19] platform/x86: asus-wmi: Document the egpu_enable sysfs
- attribute
-
-The egpu_enable attribute was not documented, this adds the
-required documentation.
-
-Fixes: 382b91db8044 ("asus-wmi: Add egpu enable method")
-Signed-off-by: Luke D. Jones <luke@ljones.dev>
-Link: https://lore.kernel.org/r/20220812222509.292692-3-luke@ljones.dev
-Reviewed-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
----
- Documentation/ABI/testing/sysfs-platform-asus-wmi | 11 +++++++++++
- 1 file changed, 11 insertions(+)
-
-diff --git a/Documentation/ABI/testing/sysfs-platform-asus-wmi b/Documentation/ABI/testing/sysfs-platform-asus-wmi
-index 0f8f0772d6f3..ac5ec3a17c51 100644
---- a/Documentation/ABI/testing/sysfs-platform-asus-wmi
-+++ b/Documentation/ABI/testing/sysfs-platform-asus-wmi
-@@ -66,3 +66,14 @@ Description:
- Disable discrete GPU:
- * 0 - Enable dGPU,
- * 1 - Disable dGPU
+
+What: /sys/devices/platform/<platform>/egpu_enable
+Date: Aug 2022
@@ -201,35 +56,6 @@ index 0f8f0772d6f3..ac5ec3a17c51 100644
+
+ * 0 - Disable,
+ * 1 - Enable
---
-2.37.2
-
-From d956c889be804742e39fbb3291b054b3cbf505be Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones" <luke@ljones.dev>
-Date: Sat, 13 Aug 2022 10:25:06 +1200
-Subject: [PATCH 05/19] platform/x86: asus-wmi: Document the panel_od sysfs
- attribute
-
-The panel_od attribute was not documented, this adds the
-required documentation.
-
-Fixes: ca91ea34778f ("asus-wmi: Add panel overdrive functionality")
-Signed-off-by: Luke D. Jones <luke@ljones.dev>
-Link: https://lore.kernel.org/r/20220812222509.292692-4-luke@ljones.dev
-Reviewed-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
----
- Documentation/ABI/testing/sysfs-platform-asus-wmi | 9 +++++++++
- 1 file changed, 9 insertions(+)
-
-diff --git a/Documentation/ABI/testing/sysfs-platform-asus-wmi b/Documentation/ABI/testing/sysfs-platform-asus-wmi
-index ac5ec3a17c51..4d63824713ac 100644
---- a/Documentation/ABI/testing/sysfs-platform-asus-wmi
-+++ b/Documentation/ABI/testing/sysfs-platform-asus-wmi
-@@ -77,3 +77,12 @@ Description:
-
- * 0 - Disable,
- * 1 - Enable
+
+What: /sys/devices/platform/<platform>/panel_od
+Date: Aug 2022
@@ -239,1137 +65,243 @@ index ac5ec3a17c51..4d63824713ac 100644
+ Enable an LCD response-time boost to reduce or remove ghosting:
+ * 0 - Disable,
+ * 1 - Enable
---
-2.37.2
-
-From cdf36fc865f0aff8de5a9afc3654f114c4d04cba Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones" <luke@ljones.dev>
-Date: Sat, 13 Aug 2022 10:25:07 +1200
-Subject: [PATCH 06/19] platform/x86: asus-wmi: Refactor disable_gpu attribute
-
-The settings for these attributes can be read from the device, this
-is now done instead of reading a stored value from module. The stored
-value is also removed.
-
-This means the simpler asus_wmi_dev_is_present() can be used in
-*_check_present() - it is not an error for these methods to be
-missing.
-
-The _write() functions have their bodies shifted in to *_store()
-which simplifies things further.
-
-Signed-off-by: Luke D. Jones <luke@ljones.dev>
-Link: https://lore.kernel.org/r/20220812222509.292692-5-luke@ljones.dev
-Reviewed-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
----
- drivers/platform/x86/asus-wmi.c | 73 +++++++++++----------------------
- 1 file changed, 24 insertions(+), 49 deletions(-)
-
-diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
-index e461299d938a..f58cbda862d2 100644
---- a/drivers/platform/x86/asus-wmi.c
-+++ b/drivers/platform/x86/asus-wmi.c
-@@ -233,7 +233,6 @@ struct asus_wmi {
- bool egpu_enable;
-
- bool dgpu_disable_available;
-- bool dgpu_disable;
-
- bool throttle_thermal_policy_available;
- u8 throttle_thermal_policy_mode;
-@@ -563,47 +562,10 @@ static void lid_flip_tablet_mode_get_state(struct asus_wmi *asus)
- /* dGPU ********************************************************************/
- static int dgpu_disable_check_present(struct asus_wmi *asus)
- {
-- u32 result;
-- int err;
--
- asus->dgpu_disable_available = false;
-
-- err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_DGPU, &result);
-- if (err) {
-- if (err == -ENODEV)
-- return 0;
-- return err;
-- }
--
-- if (result & ASUS_WMI_DSTS_PRESENCE_BIT) {
-+ if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_DGPU))
- asus->dgpu_disable_available = true;
-- asus->dgpu_disable = result & ASUS_WMI_DSTS_STATUS_BIT;
-- }
--
-- return 0;
--}
--
--static int dgpu_disable_write(struct asus_wmi *asus)
--{
-- u32 retval;
-- u8 value;
-- int err;
--
-- /* Don't rely on type conversion */
-- value = asus->dgpu_disable ? 1 : 0;
--
-- err = asus_wmi_set_devstate(ASUS_WMI_DEVID_DGPU, value, &retval);
-- if (err) {
-- pr_warn("Failed to set dgpu disable: %d\n", err);
-- return err;
-- }
--
-- if (retval > 1) {
-- pr_warn("Failed to set dgpu disable (retval): 0x%x\n", retval);
-- return -EIO;
-- }
--
-- sysfs_notify(&asus->platform_device->dev.kobj, NULL, "dgpu_disable");
-
- return 0;
- }
-@@ -612,9 +574,13 @@ static ssize_t dgpu_disable_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- struct asus_wmi *asus = dev_get_drvdata(dev);
-- u8 mode = asus->dgpu_disable;
-+ int result;
-
-- return sysfs_emit(buf, "%d\n", mode);
-+ result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_DGPU);
-+ if (result < 0)
-+ return result;
-+
-+ return sysfs_emit(buf, "%d\n", result);
- }
-
- /*
-@@ -627,24 +593,33 @@ static ssize_t dgpu_disable_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
- {
-- bool disable;
-- int result;
-+ int result, err;
-+ u32 disable;
-
- struct asus_wmi *asus = dev_get_drvdata(dev);
-
-- result = kstrtobool(buf, &disable);
-+ result = kstrtou32(buf, 10, &disable);
- if (result)
- return result;
-
-- asus->dgpu_disable = disable;
-+ if (disable > 1)
-+ return -EINVAL;
-
-- result = dgpu_disable_write(asus);
-- if (result)
-- return result;
-+ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_DGPU, disable, &result);
-+ if (err) {
-+ pr_warn("Failed to set dgpu disable: %d\n", err);
-+ return err;
-+ }
-+
-+ if (result > 1) {
-+ pr_warn("Failed to set dgpu disable (result): 0x%x\n", result);
-+ return -EIO;
-+ }
-+
-+ sysfs_notify(&asus->platform_device->dev.kobj, NULL, "dgpu_disable");
-
- return count;
- }
--
- static DEVICE_ATTR_RW(dgpu_disable);
-
- /* eGPU ********************************************************************/
---
-2.37.2
-
-From 36450e7db0fe55c338f32059382a2d8342cbc9a1 Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones" <luke@ljones.dev>
-Date: Sat, 13 Aug 2022 10:25:08 +1200
-Subject: [PATCH 07/19] platform/x86: asus-wmi: Refactor egpu_enable attribute
-
-The settings for these attributes can be read from the device, this
-is now done instead of reading a stored value from module. The stored
-value is also removed.
-
-This means the simpler asus_wmi_dev_is_present() can be used in
-*_check_present() - it is not an error for these methods to be
-missing.
-
-The _write() functions have their bodies shifted in to *_store()
-which simplifies things further.
-
-Signed-off-by: Luke D. Jones <luke@ljones.dev>
-Link: https://lore.kernel.org/r/20220812222509.292692-6-luke@ljones.dev
-Reviewed-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
----
- drivers/platform/x86/asus-wmi.c | 84 ++++++++++-----------------------
- 1 file changed, 26 insertions(+), 58 deletions(-)
-
-diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
-index f58cbda862d2..c82e7b128444 100644
---- a/drivers/platform/x86/asus-wmi.c
-+++ b/drivers/platform/x86/asus-wmi.c
-@@ -229,9 +229,7 @@ struct asus_wmi {
- u8 fan_boost_mode_mask;
- u8 fan_boost_mode;
-
-- bool egpu_enable_available; // 0 = enable
-- bool egpu_enable;
--
-+ bool egpu_enable_available;
- bool dgpu_disable_available;
-
- bool throttle_thermal_policy_available;
-@@ -625,48 +623,10 @@ static DEVICE_ATTR_RW(dgpu_disable);
- /* eGPU ********************************************************************/
- static int egpu_enable_check_present(struct asus_wmi *asus)
- {
-- u32 result;
-- int err;
--
- asus->egpu_enable_available = false;
-
-- err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_EGPU, &result);
-- if (err) {
-- if (err == -ENODEV)
-- return 0;
-- return err;
-- }
--
-- if (result & ASUS_WMI_DSTS_PRESENCE_BIT) {
-+ if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_EGPU))
- asus->egpu_enable_available = true;
-- asus->egpu_enable = result & ASUS_WMI_DSTS_STATUS_BIT;
-- }
--
-- return 0;
--}
--
--static int egpu_enable_write(struct asus_wmi *asus)
--{
-- u32 retval;
-- u8 value;
-- int err;
--
-- /* Don't rely on type conversion */
-- value = asus->egpu_enable ? 1 : 0;
--
-- err = asus_wmi_set_devstate(ASUS_WMI_DEVID_EGPU, value, &retval);
--
-- if (err) {
-- pr_warn("Failed to set egpu disable: %d\n", err);
-- return err;
-- }
--
-- if (retval > 1) {
-- pr_warn("Failed to set egpu disable (retval): 0x%x\n", retval);
-- return -EIO;
-- }
--
-- sysfs_notify(&asus->platform_device->dev.kobj, NULL, "egpu_enable");
-
- return 0;
- }
-@@ -675,9 +635,13 @@ static ssize_t egpu_enable_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- struct asus_wmi *asus = dev_get_drvdata(dev);
-- bool mode = asus->egpu_enable;
-+ int result;
-
-- return sysfs_emit(buf, "%d\n", mode);
-+ result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_EGPU);
-+ if (result < 0)
-+ return result;
-+
-+ return sysfs_emit(buf, "%d\n", result);
- }
-
- /* The ACPI call to enable the eGPU also disables the internal dGPU */
-@@ -685,29 +649,33 @@ static ssize_t egpu_enable_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
- {
-- bool enable;
-- int result;
-+ int result, err;
-+ u32 enable;
-
- struct asus_wmi *asus = dev_get_drvdata(dev);
-
-- result = kstrtobool(buf, &enable);
-- if (result)
-- return result;
-+ err = kstrtou32(buf, 10, &enable);
-+ if (err)
-+ return err;
-
-- asus->egpu_enable = enable;
-+ if (enable > 1)
-+ return -EINVAL;
-
-- result = egpu_enable_write(asus);
-- if (result)
-- return result;
-+ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_EGPU, enable, &result);
-+ if (err) {
-+ pr_warn("Failed to set egpu disable: %d\n", err);
-+ return err;
-+ }
-
-- /* Ensure that the kernel status of dgpu is updated */
-- result = dgpu_disable_check_present(asus);
-- if (result)
-- return result;
-+ if (result > 1) {
-+ pr_warn("Failed to set egpu disable (retval): 0x%x\n", result);
-+ return -EIO;
-+ }
-+
-+ sysfs_notify(&asus->platform_device->dev.kobj, NULL, "egpu_enable");
-
- return count;
- }
--
- static DEVICE_ATTR_RW(egpu_enable);
-
- /* Battery ********************************************************************/
---
-2.37.2
-
-From ebc443ad379fad80b8fc350f35cc0652b8447995 Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones" <luke@ljones.dev>
-Date: Sat, 13 Aug 2022 10:25:09 +1200
-Subject: [PATCH 08/19] platform/x86: asus-wmi: Refactor panel_od attribute
-
-The settings for these attributes can be read from the device, this
-is now done instead of reading a stored value from module. The stored
-value is also removed.
-
-This means the simpler asus_wmi_dev_is_present() can be used in
-*_check_present() - it is not an error for these methods to be
-missing.
-
-The _write() functions have their bodies shifted in to *_store()
-which simplifies things further.
-
-Signed-off-by: Luke D. Jones <luke@ljones.dev>
-Link: https://lore.kernel.org/r/20220812222509.292692-7-luke@ljones.dev
-Reviewed-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
----
- drivers/platform/x86/asus-wmi.c | 74 +++++++++++----------------------
- 1 file changed, 25 insertions(+), 49 deletions(-)
-
-diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
-index c82e7b128444..2d9d709aa59f 100644
---- a/drivers/platform/x86/asus-wmi.c
-+++ b/drivers/platform/x86/asus-wmi.c
-@@ -246,7 +246,6 @@ struct asus_wmi {
- bool battery_rsoc_available;
-
- bool panel_overdrive_available;
-- bool panel_overdrive;
-
- struct hotplug_slot hotplug_slot;
- struct mutex hotplug_lock;
-@@ -1500,48 +1499,10 @@ static int asus_wmi_rfkill_init(struct asus_wmi *asus)
- /* Panel Overdrive ************************************************************/
- static int panel_od_check_present(struct asus_wmi *asus)
- {
-- u32 result;
-- int err;
--
- asus->panel_overdrive_available = false;
-
-- err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_PANEL_OD, &result);
-- if (err) {
-- if (err == -ENODEV)
-- return 0;
-- return err;
-- }
--
-- if (result & ASUS_WMI_DSTS_PRESENCE_BIT) {
-+ if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PANEL_OD))
- asus->panel_overdrive_available = true;
-- asus->panel_overdrive = result & ASUS_WMI_DSTS_STATUS_BIT;
-- }
--
-- return 0;
--}
--
--static int panel_od_write(struct asus_wmi *asus)
--{
-- u32 retval;
-- u8 value;
-- int err;
--
-- /* Don't rely on type conversion */
-- value = asus->panel_overdrive ? 1 : 0;
--
-- err = asus_wmi_set_devstate(ASUS_WMI_DEVID_PANEL_OD, value, &retval);
--
-- if (err) {
-- pr_warn("Failed to set panel overdrive: %d\n", err);
-- return err;
-- }
--
-- if (retval > 1) {
-- pr_warn("Failed to set panel overdrive (retval): 0x%x\n", retval);
-- return -EIO;
-- }
--
-- sysfs_notify(&asus->platform_device->dev.kobj, NULL, "panel_od");
-
- return 0;
- }
-@@ -1550,32 +1511,47 @@ static ssize_t panel_od_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- struct asus_wmi *asus = dev_get_drvdata(dev);
-+ int result;
-
-- return sysfs_emit(buf, "%d\n", asus->panel_overdrive);
-+ result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_PANEL_OD);
-+ if (result < 0)
-+ return result;
-+
-+ return sysfs_emit(buf, "%d\n", result);
- }
-
- static ssize_t panel_od_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
- {
-- bool overdrive;
-- int result;
-+ int result, err;
-+ u32 overdrive;
-
- struct asus_wmi *asus = dev_get_drvdata(dev);
-
-- result = kstrtobool(buf, &overdrive);
-+ result = kstrtou32(buf, 10, &overdrive);
- if (result)
- return result;
-
-- asus->panel_overdrive = overdrive;
-- result = panel_od_write(asus);
-+ if (overdrive > 1)
-+ return -EINVAL;
-
-- if (result)
-- return result;
-+ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_PANEL_OD, overdrive, &result);
-+
-+ if (err) {
-+ pr_warn("Failed to set panel overdrive: %d\n", err);
-+ return err;
-+ }
-+
-+ if (result > 1) {
-+ pr_warn("Failed to set panel overdrive (result): 0x%x\n", result);
-+ return -EIO;
-+ }
-+
-+ sysfs_notify(&asus->platform_device->dev.kobj, NULL, "panel_od");
-
- return count;
- }
--
- static DEVICE_ATTR_RW(panel_od);
-
- /* Quirks *********************************************************************/
---
-2.37.2
-
-From 3c3b55564afa8b7d952ce2ba90e7f522832ed0f7 Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Mon, 15 Aug 2022 17:05:38 +0200
-Subject: [PATCH 09/19] platform/x86: asus-wmi: Simplify some of the
- *_check_present() helpers
-
-After the recent cleanup patches, some of the *_check_present() helpers
-just propagate the result of asus_wmi_dev_is_present().
-
-Replace these with direct asus_wmi_dev_is_present() calls as a further
-cleanup.
-
-Cc: Luke D. Jones <luke@ljones.dev>
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-Link: https://lore.kernel.org/r/20220815150538.474306-1-hdegoede@redhat.com
----
- drivers/platform/x86/asus-wmi.c | 47 +++------------------------------
- 1 file changed, 3 insertions(+), 44 deletions(-)
-
-diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
-index 2d9d709aa59f..d72491fb218b 100644
---- a/drivers/platform/x86/asus-wmi.c
-+++ b/drivers/platform/x86/asus-wmi.c
-@@ -557,16 +557,6 @@ static void lid_flip_tablet_mode_get_state(struct asus_wmi *asus)
- }
-
- /* dGPU ********************************************************************/
--static int dgpu_disable_check_present(struct asus_wmi *asus)
--{
-- asus->dgpu_disable_available = false;
--
-- if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_DGPU))
-- asus->dgpu_disable_available = true;
--
-- return 0;
--}
--
- static ssize_t dgpu_disable_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
-@@ -620,16 +610,6 @@ static ssize_t dgpu_disable_store(struct device *dev,
- static DEVICE_ATTR_RW(dgpu_disable);
-
- /* eGPU ********************************************************************/
--static int egpu_enable_check_present(struct asus_wmi *asus)
--{
-- asus->egpu_enable_available = false;
--
-- if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_EGPU))
-- asus->egpu_enable_available = true;
--
-- return 0;
--}
--
- static ssize_t egpu_enable_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
-@@ -1497,16 +1477,6 @@ static int asus_wmi_rfkill_init(struct asus_wmi *asus)
- }
-
- /* Panel Overdrive ************************************************************/
--static int panel_od_check_present(struct asus_wmi *asus)
--{
-- asus->panel_overdrive_available = false;
--
-- if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PANEL_OD))
-- asus->panel_overdrive_available = true;
--
-- return 0;
--}
--
- static ssize_t panel_od_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
-@@ -3493,13 +3463,9 @@ static int asus_wmi_add(struct platform_device *pdev)
- if (err)
- goto fail_platform;
-
-- err = egpu_enable_check_present(asus);
-- if (err)
-- goto fail_egpu_enable;
--
-- err = dgpu_disable_check_present(asus);
-- if (err)
-- goto fail_dgpu_disable;
-+ asus->egpu_enable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_EGPU);
-+ asus->dgpu_disable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_DGPU);
-+ asus->panel_overdrive_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PANEL_OD);
-
- err = fan_boost_mode_check_present(asus);
- if (err)
-@@ -3515,10 +3481,6 @@ static int asus_wmi_add(struct platform_device *pdev)
- if (err)
- goto fail_platform_profile_setup;
+diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
+index 47774b9ab3de..a03f0968e82f 100644
+--- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
++++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
+@@ -27,6 +27,7 @@
+ #define ACEL_EN BIT(0)
+ #define GYRO_EN BIT(1)
+ #define MAGNO_EN BIT(2)
++#define KBGUARD_EN BIT(15)
+ #define HPD_EN BIT(16)
+ #define ALS_EN BIT(19)
-- err = panel_od_check_present(asus);
-- if (err)
-- goto fail_panel_od;
--
- err = asus_wmi_sysfs_init(asus->platform_device);
- if (err)
- goto fail_sysfs;
-@@ -3613,10 +3575,7 @@ static int asus_wmi_add(struct platform_device *pdev)
- if (asus->platform_profile_support)
- platform_profile_remove();
- fail_fan_boost_mode:
--fail_egpu_enable:
--fail_dgpu_disable:
- fail_platform:
--fail_panel_od:
- kfree(asus);
- return err;
- }
---
-2.37.2
-
-From 01ef026ab36357a818c7d8324a36dbb8beff6ff5 Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones" <luke@ljones.dev>
-Date: Sat, 13 Aug 2022 21:26:24 +1200
-Subject: [PATCH 10/19] platform/x86: asus-wmi: Support the hardware GPU MUX on
- some laptops
-
-Support the hardware GPU MUX switch available on some models. This
-switch can toggle the MUX between:
-
-- 0, Dedicated mode
-- 1, Optimus mode
-
-Optimus mode is the regular iGPU + dGPU available, while dedicated
-mode switches the system to have only the dGPU available.
-
-Signed-off-by: Luke D. Jones <luke@ljones.dev>
-Link: https://lore.kernel.org/r/20220813092624.6228-1-luke@ljones.dev
-Reviewed-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
----
- .../ABI/testing/sysfs-platform-asus-wmi | 12 +++++
- drivers/platform/x86/asus-wmi.c | 51 +++++++++++++++++++
- include/linux/platform_data/x86/asus-wmi.h | 3 ++
- 3 files changed, 66 insertions(+)
-
-diff --git a/Documentation/ABI/testing/sysfs-platform-asus-wmi b/Documentation/ABI/testing/sysfs-platform-asus-wmi
-index 4d63824713ac..a77a004a1baa 100644
---- a/Documentation/ABI/testing/sysfs-platform-asus-wmi
-+++ b/Documentation/ABI/testing/sysfs-platform-asus-wmi
-@@ -58,6 +58,18 @@ Description:
- * 1 - overboost,
- * 2 - silent
+@@ -233,6 +234,9 @@ int amd_mp2_get_sensor_num(struct amd_mp2_dev *privdata, u8 *sensor_id)
+ if (HPD_EN & activestatus)
+ sensor_id[num_of_sensors++] = HPD_IDX;
-+What: /sys/devices/platform/<platform>/gpu_mux_mode
-+Date: Aug 2022
-+KernelVersion: 6.1
-+Contact: "Luke Jones" <luke@ljones.dev>
-+Description:
-+ Switch the GPU hardware MUX mode. Laptops with this feature can
-+ can be toggled to boot with only the dGPU (discrete mode) or in
-+ standard Optimus/Hybrid mode. On switch a reboot is required:
-+
-+ * 0 - Discrete GPU,
-+ * 1 - Optimus/Hybrid,
++ if (KBGUARD_EN & activestatus)
++ sensor_id[num_of_sensors++] = KBGUARD_IDX;
+
- What: /sys/devices/platform/<platform>/dgpu_disable
- Date: Aug 2022
- KernelVersion: 5.17
-diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
-index d72491fb218b..46d0dd96a351 100644
---- a/drivers/platform/x86/asus-wmi.c
-+++ b/drivers/platform/x86/asus-wmi.c
-@@ -231,6 +231,7 @@ struct asus_wmi {
-
- bool egpu_enable_available;
- bool dgpu_disable_available;
-+ bool gpu_mux_mode_available;
-
- bool throttle_thermal_policy_available;
- u8 throttle_thermal_policy_mode;
-@@ -657,6 +658,52 @@ static ssize_t egpu_enable_store(struct device *dev,
+ return num_of_sensors;
}
- static DEVICE_ATTR_RW(egpu_enable);
-+/* gpu mux switch *************************************************************/
-+static ssize_t gpu_mux_mode_show(struct device *dev,
-+ struct device_attribute *attr, char *buf)
-+{
-+ struct asus_wmi *asus = dev_get_drvdata(dev);
-+ int result;
-+
-+ result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_GPU_MUX);
-+ if (result < 0)
-+ return result;
-+
-+ return sysfs_emit(buf, "%d\n", result);
-+}
-+
-+static ssize_t gpu_mux_mode_store(struct device *dev,
-+ struct device_attribute *attr,
-+ const char *buf, size_t count)
-+{
-+ struct asus_wmi *asus = dev_get_drvdata(dev);
-+ int result, err;
-+ u32 optimus;
-+
-+ err = kstrtou32(buf, 10, &optimus);
-+ if (err)
-+ return err;
-+
-+ if (optimus > 1)
-+ return -EINVAL;
-+
-+ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_GPU_MUX, optimus, &result);
-+ if (err) {
-+ dev_err(dev, "Failed to set GPU MUX mode: %d\n", err);
-+ return err;
-+ }
-+ /* !1 is considered a fail by ASUS */
-+ if (result != 1) {
-+ dev_warn(dev, "Failed to set GPU MUX mode (result): 0x%x\n", result);
-+ return -EIO;
-+ }
-+
-+ sysfs_notify(&asus->platform_device->dev.kobj, NULL, "gpu_mux_mode");
-+
-+ return count;
-+}
-+static DEVICE_ATTR_RW(gpu_mux_mode);
-+
- /* Battery ********************************************************************/
-
- /* The battery maximum charging percentage */
-@@ -3172,6 +3219,7 @@ static struct attribute *platform_attributes[] = {
- &dev_attr_touchpad.attr,
- &dev_attr_egpu_enable.attr,
- &dev_attr_dgpu_disable.attr,
-+ &dev_attr_gpu_mux_mode.attr,
- &dev_attr_lid_resume.attr,
- &dev_attr_als_enable.attr,
- &dev_attr_fan_boost_mode.attr,
-@@ -3202,6 +3250,8 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj,
- ok = asus->egpu_enable_available;
- else if (attr == &dev_attr_dgpu_disable.attr)
- ok = asus->dgpu_disable_available;
-+ else if (attr == &dev_attr_gpu_mux_mode.attr)
-+ ok = asus->gpu_mux_mode_available;
- else if (attr == &dev_attr_fan_boost_mode.attr)
- ok = asus->fan_boost_mode_available;
- else if (attr == &dev_attr_throttle_thermal_policy.attr)
-@@ -3465,6 +3515,7 @@ static int asus_wmi_add(struct platform_device *pdev)
-
- asus->egpu_enable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_EGPU);
- asus->dgpu_disable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_DGPU);
-+ asus->gpu_mux_mode_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_GPU_MUX);
- asus->panel_overdrive_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PANEL_OD);
-
- err = fan_boost_mode_check_present(asus);
-diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
-index 98f2b2f20f3e..70d2347bf6ca 100644
---- a/include/linux/platform_data/x86/asus-wmi.h
-+++ b/include/linux/platform_data/x86/asus-wmi.h
-@@ -99,6 +99,9 @@
- /* dgpu on/off */
- #define ASUS_WMI_DEVID_DGPU 0x00090020
-
-+/* gpu mux switch, 0 = dGPU, 1 = Optimus */
-+#define ASUS_WMI_DEVID_GPU_MUX 0x00090016
-+
- /* DSTS masks */
- #define ASUS_WMI_DSTS_STATUS_BIT 0x00000001
- #define ASUS_WMI_DSTS_UNKNOWN_BIT 0x00000002
---
-2.37.2
-
-From 00aa846955fbfb04f7bc0c26c49febfe5395eca1 Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones" <luke@ljones.dev>
-Date: Sat, 13 Aug 2022 21:27:52 +1200
-Subject: [PATCH 11/19] platform/x86: asus-wmi: Adjust tablet/lidflip handling
- to use enum
-
-Due to multiple types of tablet/lidflip, the existing code for
-handling these events is refactored to use an enum for each type.
-
-Signed-off-by: Luke D. Jones <luke@ljones.dev>
-Link: https://lore.kernel.org/r/20220813092753.6635-1-luke@ljones.dev
-Reviewed-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
----
- drivers/platform/x86/asus-nb-wmi.c | 13 +++-----
- drivers/platform/x86/asus-wmi.c | 49 +++++++++++++++++++++---------
- drivers/platform/x86/asus-wmi.h | 9 ++++--
- 3 files changed, 47 insertions(+), 24 deletions(-)
-
-diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
-index 478dd300b9c9..4672a2b8322e 100644
---- a/drivers/platform/x86/asus-nb-wmi.c
-+++ b/drivers/platform/x86/asus-nb-wmi.c
-@@ -115,12 +115,12 @@ static struct quirk_entry quirk_asus_forceals = {
- };
-
- static struct quirk_entry quirk_asus_use_kbd_dock_devid = {
-- .use_kbd_dock_devid = true,
-+ .tablet_switch_mode = asus_wmi_kbd_dock_devid,
- };
-
- static struct quirk_entry quirk_asus_use_lid_flip_devid = {
- .wmi_backlight_set_devstate = true,
-- .use_lid_flip_devid = true,
-+ .tablet_switch_mode = asus_wmi_lid_flip_devid,
- };
+diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h
+index dfb7cabd82ef..5fa15eed43f3 100644
+--- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h
++++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h
+@@ -23,6 +23,7 @@
+ #define V2_STATUS 0x2
- static int dmi_matched(const struct dmi_system_id *dmi)
-@@ -492,16 +492,13 @@ static void asus_nb_wmi_quirks(struct asus_wmi_driver *driver)
+ #define HPD_IDX 16
++#define KBGUARD_IDX 15
- switch (tablet_mode_sw) {
- case 0:
-- quirks->use_kbd_dock_devid = false;
-- quirks->use_lid_flip_devid = false;
-+ quirks->tablet_switch_mode = asus_wmi_no_tablet_switch;
- break;
- case 1:
-- quirks->use_kbd_dock_devid = true;
-- quirks->use_lid_flip_devid = false;
-+ quirks->tablet_switch_mode = asus_wmi_kbd_dock_devid;
+ #define SENSOR_DISCOVERY_STATUS_MASK GENMASK(5, 3)
+ #define SENSOR_DISCOVERY_STATUS_SHIFT 3
+diff --git a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.c b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.c
+index f9a8c02d5a7b..06487eb75dc8 100644
+--- a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.c
++++ b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.c
+@@ -57,6 +57,11 @@ static int get_report_descriptor(int sensor_idx, u8 *rep_desc)
+ memcpy(rep_desc, hpd_report_descriptor,
+ sizeof(hpd_report_descriptor));
break;
- case 2:
-- quirks->use_kbd_dock_devid = false;
-- quirks->use_lid_flip_devid = true;
-+ quirks->tablet_switch_mode = asus_wmi_lid_flip_devid;
++ case KBGUARD_IDX: /* kbguard ? */
++ memset(rep_desc, 0, sizeof(kbguard_report_descriptor));
++ memcpy(rep_desc, kbguard_report_descriptor,
++ sizeof(kbguard_report_descriptor));
++ break;
+ default:
break;
}
-
-diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
-index 46d0dd96a351..fe2d072e1acc 100644
---- a/drivers/platform/x86/asus-wmi.c
-+++ b/drivers/platform/x86/asus-wmi.c
-@@ -486,8 +486,11 @@ static bool asus_wmi_dev_is_present(struct asus_wmi *asus, u32 dev_id)
-
- static int asus_wmi_input_init(struct asus_wmi *asus)
- {
-+ struct device *dev;
- int err, result;
-
-+ dev = &asus->platform_device->dev;
-+
- asus->inputdev = input_allocate_device();
- if (!asus->inputdev)
- return -ENOMEM;
-@@ -495,35 +498,38 @@ static int asus_wmi_input_init(struct asus_wmi *asus)
- asus->inputdev->name = asus->driver->input_name;
- asus->inputdev->phys = asus->driver->input_phys;
- asus->inputdev->id.bustype = BUS_HOST;
-- asus->inputdev->dev.parent = &asus->platform_device->dev;
-+ asus->inputdev->dev.parent = dev;
- set_bit(EV_REP, asus->inputdev->evbit);
-
- err = sparse_keymap_setup(asus->inputdev, asus->driver->keymap, NULL);
- if (err)
- goto err_free_dev;
-
-- if (asus->driver->quirks->use_kbd_dock_devid) {
-+ switch (asus->driver->quirks->tablet_switch_mode) {
-+ case asus_wmi_no_tablet_switch:
-+ break;
-+ case asus_wmi_kbd_dock_devid:
- result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_KBD_DOCK);
- if (result >= 0) {
- input_set_capability(asus->inputdev, EV_SW, SW_TABLET_MODE);
- input_report_switch(asus->inputdev, SW_TABLET_MODE, !result);
- } else if (result != -ENODEV) {
-- pr_err("Error checking for keyboard-dock: %d\n", result);
-+ dev_err(dev, "Error checking for keyboard-dock: %d\n", result);
- }
-- }
--
-- if (asus->driver->quirks->use_lid_flip_devid) {
-+ break;
-+ case asus_wmi_lid_flip_devid:
- result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_LID_FLIP);
- if (result < 0)
-- asus->driver->quirks->use_lid_flip_devid = 0;
-+ asus->driver->quirks->tablet_switch_mode = asus_wmi_no_tablet_switch;
- if (result >= 0) {
- input_set_capability(asus->inputdev, EV_SW, SW_TABLET_MODE);
- input_report_switch(asus->inputdev, SW_TABLET_MODE, result);
- } else if (result == -ENODEV) {
-- pr_err("This device has lid_flip quirk but got ENODEV checking it. This is a bug.");
-+ dev_err(dev, "This device has lid_flip quirk but got ENODEV checking it. This is a bug.");
- } else {
-- pr_err("Error checking for lid-flip: %d\n", result);
-+ dev_err(dev, "Error checking for lid-flip: %d\n", result);
+@@ -116,6 +121,16 @@ static u32 get_descr_sz(int sensor_idx, int descriptor_name)
+ return sizeof(struct hpd_feature_report);
}
+ break;
++ case KBGUARD_IDX:
++ switch (descriptor_name) {
++ case descr_size:
++ return sizeof(kbguard_report_descriptor);
++ case input_size:
++ return sizeof(struct kbguard_input_report);
++ case feature_size:
++ return sizeof(struct kbguard_feature_report);
++ }
+ break;
- }
-
- err = input_register_device(asus->inputdev);
-@@ -549,8 +555,9 @@ static void asus_wmi_input_exit(struct asus_wmi *asus)
-
- static void lid_flip_tablet_mode_get_state(struct asus_wmi *asus)
- {
-- int result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_LID_FLIP);
-+ int result;
-
-+ result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_LID_FLIP);
- if (result >= 0) {
- input_report_switch(asus->inputdev, SW_TABLET_MODE, result);
- input_sync(asus->inputdev);
-@@ -3044,7 +3051,8 @@ static void asus_wmi_handle_event_code(int code, struct asus_wmi *asus)
- return;
- }
-
-- if (asus->driver->quirks->use_kbd_dock_devid && code == NOTIFY_KBD_DOCK_CHANGE) {
-+ if (asus->driver->quirks->tablet_switch_mode == asus_wmi_kbd_dock_devid &&
-+ code == NOTIFY_KBD_DOCK_CHANGE) {
- result = asus_wmi_get_devstate_simple(asus,
- ASUS_WMI_DEVID_KBD_DOCK);
- if (result >= 0) {
-@@ -3055,7 +3063,8 @@ static void asus_wmi_handle_event_code(int code, struct asus_wmi *asus)
- return;
- }
-- if (asus->driver->quirks->use_lid_flip_devid && code == NOTIFY_LID_FLIP) {
-+ if (asus->driver->quirks->tablet_switch_mode == asus_wmi_lid_flip_devid &&
-+ code == NOTIFY_LID_FLIP) {
- lid_flip_tablet_mode_get_state(asus);
- return;
- }
-@@ -3685,8 +3694,14 @@ static int asus_hotk_resume(struct device *device)
- if (asus_wmi_has_fnlock_key(asus))
- asus_wmi_fnlock_update(asus);
+ default:
+ break;
+@@ -139,6 +154,7 @@ static u8 get_feature_report(int sensor_idx, int report_id, u8 *feature_report)
+ struct gyro_feature_report gyro_feature;
+ struct magno_feature_report magno_feature;
+ struct hpd_feature_report hpd_feature;
++ struct kbguard_feature_report kbguard_feature;
+ struct als_feature_report als_feature;
+ u8 report_size = 0;
-- if (asus->driver->quirks->use_lid_flip_devid)
-+ switch (asus->driver->quirks->tablet_switch_mode) {
-+ case asus_wmi_no_tablet_switch:
-+ case asus_wmi_kbd_dock_devid:
-+ break;
-+ case asus_wmi_lid_flip_devid:
- lid_flip_tablet_mode_get_state(asus);
+@@ -186,6 +202,11 @@ static u8 get_feature_report(int sensor_idx, int report_id, u8 *feature_report)
+ memcpy(feature_report, &hpd_feature, sizeof(hpd_feature));
+ report_size = sizeof(hpd_feature);
+ break;
++ case KBGUARD_IDX: /* auto disable keyboard when flip out */
++ get_common_features(&kbguard_feature.common_property, report_id);
++ memcpy(feature_report, &kbguard_feature, sizeof(kbguard_feature));
++ report_size = sizeof(kbguard_feature);
+ break;
-+ }
- return 0;
- }
-@@ -3727,8 +3742,14 @@ static int asus_hotk_restore(struct device *device)
- if (asus_wmi_has_fnlock_key(asus))
- asus_wmi_fnlock_update(asus);
+ default:
+ break;
+@@ -211,6 +232,7 @@ static u8 get_input_report(u8 current_index, int sensor_idx, int report_id,
+ struct accel3_input_report acc_input;
+ struct gyro_input_report gyro_input;
+ struct hpd_input_report hpd_input;
++ struct kbguard_input_report kbguard_input;
+ struct als_input_report als_input;
+ struct hpd_status hpdstatus;
+ u8 report_size = 0;
+@@ -263,6 +285,11 @@ static u8 get_input_report(u8 current_index, int sensor_idx, int report_id,
+ report_size = sizeof(hpd_input);
+ memcpy(input_report, &hpd_input, sizeof(hpd_input));
+ break;
++ case KBGUARD_IDX: /* kb guard */
++ get_common_inputs(&kbguard_input.common_property, report_id);
++ report_size = sizeof(kbguard_input);
++ memcpy(input_report, &kbguard_input, sizeof(kbguard_input));
++break;
+ default:
+ break;
+ }
+diff --git a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h
+index ebd55675eb62..2f2ba9a0cfbc 100644
+--- a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h
++++ b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h
+@@ -111,4 +111,12 @@ struct hpd_input_report {
+ u8 human_presence;
+ } __packed;
-- if (asus->driver->quirks->use_lid_flip_devid)
-+ switch (asus->driver->quirks->tablet_switch_mode) {
-+ case asus_wmi_no_tablet_switch:
-+ case asus_wmi_kbd_dock_devid:
-+ break;
-+ case asus_wmi_lid_flip_devid:
- lid_flip_tablet_mode_get_state(asus);
-+ break;
-+ }
++struct kbguard_feature_report {
++ struct common_feature_property common_property;
++} __packed;
++
++struct kbguard_input_report {
++ struct common_input_property common_property;
++} __packed;
++
+ #endif
+diff --git a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h
+index 697f2791ea9c..7a62fcec2c73 100644
+--- a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h
++++ b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h
+@@ -644,6 +644,25 @@ static const u8 als_report_descriptor[] = {
+ 0xC0 /* HID end collection */
+ };
- return 0;
- }
-diff --git a/drivers/platform/x86/asus-wmi.h b/drivers/platform/x86/asus-wmi.h
-index b302415bf1d9..413920bad0c6 100644
---- a/drivers/platform/x86/asus-wmi.h
-+++ b/drivers/platform/x86/asus-wmi.h
-@@ -25,6 +25,12 @@ struct module;
- struct key_entry;
- struct asus_wmi;
-
-+enum asus_wmi_tablet_switch_mode {
-+ asus_wmi_no_tablet_switch,
-+ asus_wmi_kbd_dock_devid,
-+ asus_wmi_lid_flip_devid,
++
++static const u8 kbguard_report_descriptor[] = {
++0x06, 0x43, 0xFF, // Usage Page (Vendor Defined 0xFF43)
++0x0A, 0x02, 0x02, // Usage (0x0202)
++0xA1, 0x01, // Collection (Application)
++0x85, 0x11, // Report ID (17)
++0x15, 0x00, // Logical Minimum (0)
++0x25, 0x01, // Logical Maximum (1)
++0x35, 0x00, // Physical Minimum (0)
++0x45, 0x01, // Physical Maximum (1)
++0x65, 0x00, // Unit (None)
++0x55, 0x00, // Unit Exponent (0)
++0x75, 0x01, // Report Size (1)
++0x95, 0x98, // Report Count (-104)
++0x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
++0x91, 0x03, // Output (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
++0xC1, 0x00, // End Collection
+};
+
- struct quirk_entry {
- bool hotplug_wireless;
- bool scalar_panel_brightness;
-@@ -33,8 +39,7 @@ struct quirk_entry {
- bool wmi_backlight_native;
- bool wmi_backlight_set_devstate;
- bool wmi_force_als_set;
-- bool use_kbd_dock_devid;
-- bool use_lid_flip_devid;
-+ enum asus_wmi_tablet_switch_mode tablet_switch_mode;
- int wapf;
- /*
- * For machines with AMD graphic chips, it will send out WMI event
---
-2.37.2
-
-From e397c3c460bf3849384f2f55516d1887617cfca9 Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones" <luke@ljones.dev>
-Date: Sat, 13 Aug 2022 21:27:53 +1200
-Subject: [PATCH 12/19] platform/x86: asus-wmi: Add support for ROG X13 tablet
- mode
-
-Add quirk for ASUS ROG X13 Flow 2-in-1 to enable tablet mode with
-lid flip (all screen rotations).
-
-Signed-off-by: Luke D. Jones <luke@ljones.dev>
-Link: https://lore.kernel.org/r/20220813092753.6635-2-luke@ljones.dev
-Reviewed-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
----
- drivers/platform/x86/asus-nb-wmi.c | 15 +++++++++
- drivers/platform/x86/asus-wmi.c | 37 ++++++++++++++++++++++
- drivers/platform/x86/asus-wmi.h | 1 +
- include/linux/platform_data/x86/asus-wmi.h | 1 +
- 4 files changed, 54 insertions(+)
-
+ /* BIOMETRIC PRESENCE*/
+ static const u8 hpd_report_descriptor[] = {
+ 0x05, 0x20, /* Usage page */
diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
-index 4672a2b8322e..d9e7cf6e4a0e 100644
+index d9e7cf6e4a0e..fcfe6dddd645 100644
--- a/drivers/platform/x86/asus-nb-wmi.c
+++ b/drivers/platform/x86/asus-nb-wmi.c
-@@ -123,6 +123,11 @@ static struct quirk_entry quirk_asus_use_lid_flip_devid = {
- .tablet_switch_mode = asus_wmi_lid_flip_devid,
- };
-
-+static struct quirk_entry quirk_asus_tablet_mode = {
-+ .wmi_backlight_set_devstate = true,
-+ .tablet_switch_mode = asus_wmi_lid_flip_rog_devid,
-+};
-+
- static int dmi_matched(const struct dmi_system_id *dmi)
- {
- pr_info("Identified laptop model '%s'\n", dmi->ident);
-@@ -471,6 +476,15 @@ static const struct dmi_system_id asus_quirks[] = {
- },
- .driver_data = &quirk_asus_use_lid_flip_devid,
- },
-+ {
-+ .callback = dmi_matched,
-+ .ident = "ASUS ROG FLOW X13",
-+ .matches = {
-+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-+ DMI_MATCH(DMI_PRODUCT_NAME, "GV301Q"),
-+ },
-+ .driver_data = &quirk_asus_tablet_mode,
-+ },
- {},
- };
+@@ -504,17 +504,8 @@ static void asus_nb_wmi_quirks(struct asus_wmi_driver *driver)
+ else
+ wapf = quirks->wapf;
-@@ -578,6 +592,7 @@ static const struct key_entry asus_nb_wmi_keymap[] = {
- { KE_KEY, 0xC5, { KEY_KBDILLUMDOWN } },
- { KE_IGNORE, 0xC6, }, /* Ambient Light Sensor notification */
- { KE_KEY, 0xFA, { KEY_PROG2 } }, /* Lid flip action */
-+ { KE_KEY, 0xBD, { KEY_PROG2 } }, /* Lid flip action on ROG xflow laptops */
- { KE_END, 0},
- };
+- switch (tablet_mode_sw) {
+- case 0:
+- quirks->tablet_switch_mode = asus_wmi_no_tablet_switch;
+- break;
+- case 1:
+- quirks->tablet_switch_mode = asus_wmi_kbd_dock_devid;
+- break;
+- case 2:
+- quirks->tablet_switch_mode = asus_wmi_lid_flip_devid;
+- break;
+- }
++ if (tablet_mode_sw != -1)
++ quirks->tablet_switch_mode = tablet_mode_sw;
+ if (quirks->i8042_filter) {
+ ret = i8042_install_filter(quirks->i8042_filter);
+@@ -586,6 +577,7 @@ static const struct key_entry asus_nb_wmi_keymap[] = {
+ { KE_KEY, 0xA5, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + TV + HDMI */
+ { KE_KEY, 0xA6, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT + TV + HDMI */
+ { KE_KEY, 0xA7, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + CRT + TV + HDMI */
++ { KE_KEY, 0xAE, { KEY_FN_F5 } }, /* Fn+F5 fan mode on 2020+ */
+ { KE_KEY, 0xB3, { KEY_PROG4 } }, /* AURA */
+ { KE_KEY, 0xB5, { KEY_CALC } },
+ { KE_KEY, 0xC4, { KEY_KBDILLUMUP } },
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
-index fe2d072e1acc..5352055848d0 100644
+index dce93187e11f..40e911467037 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
-@@ -68,6 +68,7 @@ module_param(fnlock_default, bool, 0444);
- #define NOTIFY_KBD_FBM 0x99
- #define NOTIFY_KBD_TTP 0xae
- #define NOTIFY_LID_FLIP 0xfa
-+#define NOTIFY_LID_FLIP_ROG 0xbd
+@@ -72,6 +72,7 @@ module_param(fnlock_default, bool, 0444);
#define ASUS_WMI_FNLOCK_BIOS_DISABLED BIT(0)
-@@ -530,6 +531,19 @@ static int asus_wmi_input_init(struct asus_wmi *asus)
- dev_err(dev, "Error checking for lid-flip: %d\n", result);
- }
- break;
-+ case asus_wmi_lid_flip_rog_devid:
-+ result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_LID_FLIP_ROG);
-+ if (result < 0)
-+ asus->driver->quirks->tablet_switch_mode = asus_wmi_no_tablet_switch;
-+ if (result >= 0) {
-+ input_set_capability(asus->inputdev, EV_SW, SW_TABLET_MODE);
-+ input_report_switch(asus->inputdev, SW_TABLET_MODE, result);
-+ } else if (result == -ENODEV) {
-+ dev_err(dev, "This device has lid-flip-rog quirk but got ENODEV checking it. This is a bug.");
-+ } else {
-+ dev_err(dev, "Error checking for lid-flip: %d\n", result);
-+ }
-+ break;
- }
-
- err = input_register_device(asus->inputdev);
-@@ -564,6 +578,17 @@ static void lid_flip_tablet_mode_get_state(struct asus_wmi *asus)
- }
- }
++#define ASUS_GPU_FAN_DESC "gpu_fan"
+ #define ASUS_FAN_DESC "cpu_fan"
+ #define ASUS_FAN_MFUN 0x13
+ #define ASUS_FAN_SFUN_READ 0x06
+@@ -222,19 +223,25 @@ struct asus_wmi {
+ struct asus_rfkill gps;
+ struct asus_rfkill uwb;
-+static void lid_flip_rog_tablet_mode_get_state(struct asus_wmi *asus)
-+{
-+ int result;
-+
-+ result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_LID_FLIP_ROG);
-+ if (result >= 0) {
-+ input_report_switch(asus->inputdev, SW_TABLET_MODE, result);
-+ input_sync(asus->inputdev);
-+ }
-+}
++ int tablet_switch_event_code;
++ u32 tablet_switch_dev_id;
+
- /* dGPU ********************************************************************/
- static ssize_t dgpu_disable_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-@@ -3069,6 +3094,12 @@ static void asus_wmi_handle_event_code(int code, struct asus_wmi *asus)
- return;
- }
+ enum fan_type fan_type;
++ enum fan_type gpu_fan_type;
+ int fan_pwm_mode;
++ int gpu_fan_pwm_mode;
+ int agfn_pwm;
-+ if (asus->driver->quirks->tablet_switch_mode == asus_wmi_lid_flip_rog_devid &&
-+ code == NOTIFY_LID_FLIP_ROG) {
-+ lid_flip_rog_tablet_mode_get_state(asus);
-+ return;
-+ }
+ bool fan_boost_mode_available;
+ u8 fan_boost_mode_mask;
+ u8 fan_boost_mode;
+
+- bool egpu_enable_available; // 0 = enable
+- bool egpu_enable;
+-
++ bool egpu_enable_available;
+ bool dgpu_disable_available;
+- bool dgpu_disable;
++ bool gpu_mux_mode_available;
+
- if (asus->fan_boost_mode_available && code == NOTIFY_KBD_FBM) {
- fan_boost_mode_switch_next(asus);
- return;
-@@ -3701,6 +3732,9 @@ static int asus_hotk_resume(struct device *device)
- case asus_wmi_lid_flip_devid:
- lid_flip_tablet_mode_get_state(asus);
- break;
-+ case asus_wmi_lid_flip_rog_devid:
-+ lid_flip_rog_tablet_mode_get_state(asus);
-+ break;
- }
++ bool kbd_rgb_mode_available;
++ bool kbd_rgb_state_available;
- return 0;
-@@ -3749,6 +3783,9 @@ static int asus_hotk_restore(struct device *device)
- case asus_wmi_lid_flip_devid:
- lid_flip_tablet_mode_get_state(asus);
- break;
-+ case asus_wmi_lid_flip_rog_devid:
-+ lid_flip_rog_tablet_mode_get_state(asus);
-+ break;
- }
+ bool throttle_thermal_policy_available;
+ u8 throttle_thermal_policy_mode;
+@@ -250,7 +257,6 @@ struct asus_wmi {
+ bool battery_rsoc_available;
- return 0;
-diff --git a/drivers/platform/x86/asus-wmi.h b/drivers/platform/x86/asus-wmi.h
-index 413920bad0c6..0187f13d2414 100644
---- a/drivers/platform/x86/asus-wmi.h
-+++ b/drivers/platform/x86/asus-wmi.h
-@@ -29,6 +29,7 @@ enum asus_wmi_tablet_switch_mode {
- asus_wmi_no_tablet_switch,
- asus_wmi_kbd_dock_devid,
- asus_wmi_lid_flip_devid,
-+ asus_wmi_lid_flip_rog_devid,
- };
+ bool panel_overdrive_available;
+- bool panel_overdrive;
- struct quirk_entry {
-diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
-index 70d2347bf6ca..6e8a95c10d17 100644
---- a/include/linux/platform_data/x86/asus-wmi.h
-+++ b/include/linux/platform_data/x86/asus-wmi.h
-@@ -65,6 +65,7 @@
- #define ASUS_WMI_DEVID_PANEL_OD 0x00050019
- #define ASUS_WMI_DEVID_CAMERA 0x00060013
- #define ASUS_WMI_DEVID_LID_FLIP 0x00060062
-+#define ASUS_WMI_DEVID_LID_FLIP_ROG 0x00060077
-
- /* Storage */
- #define ASUS_WMI_DEVID_CARDREADER 0x00080013
---
-2.37.2
-
-From c98dc61ee08f833e68337700546e120e2edac7c9 Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Wed, 24 Aug 2022 17:11:44 +0200
-Subject: [PATCH 13/19] platform/x86: asus-wmi: Simplify tablet-mode-switch
- probing
-
-The 3 different tablet-mode-switch initialization paths repeat a lot
-of the same code. Add a helper function for this.
-
-This also makes the error-handling for the kbd_dock_devid case consistent
-with the other 2 cases.
-
-Cc: Luke D. Jones <luke@ljones.dev>
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-Link: https://lore.kernel.org/r/20220824151145.1448010-1-hdegoede@redhat.com
----
- drivers/platform/x86/asus-wmi.c | 55 +++++++++++++--------------------
- 1 file changed, 22 insertions(+), 33 deletions(-)
-
-diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
-index 5352055848d0..d71daa024752 100644
---- a/drivers/platform/x86/asus-wmi.c
-+++ b/drivers/platform/x86/asus-wmi.c
-@@ -484,13 +484,28 @@ static bool asus_wmi_dev_is_present(struct asus_wmi *asus, u32 dev_id)
+ struct hotplug_slot hotplug_slot;
+ struct mutex hotplug_lock;
+@@ -487,13 +493,28 @@ static bool asus_wmi_dev_is_present(struct asus_wmi *asus, u32 dev_id)
}
/* Input **********************************************************************/
@@ -1379,11 +311,11 @@ index 5352055848d0..d71daa024752 100644
+ int result;
+
+ result = asus_wmi_get_devstate_simple(asus, dev_id);
-+ if (result < 0)
-+ asus->driver->quirks->tablet_switch_mode = asus_wmi_no_tablet_switch;
+ if (result >= 0) {
+ input_set_capability(asus->inputdev, EV_SW, SW_TABLET_MODE);
+ input_report_switch(asus->inputdev, SW_TABLET_MODE, result);
++ asus->tablet_switch_dev_id = dev_id;
++ asus->tablet_switch_event_code = event_code;
+ } else if (result == -ENODEV) {
+ dev_err(dev, "This device has tablet-mode-switch quirk but got ENODEV checking it. This is a bug.");
+ } else {
@@ -1402,7 +334,7 @@ index 5352055848d0..d71daa024752 100644
asus->inputdev = input_allocate_device();
if (!asus->inputdev)
-@@ -510,39 +525,13 @@ static int asus_wmi_input_init(struct asus_wmi *asus)
+@@ -513,39 +534,13 @@ static int asus_wmi_input_init(struct asus_wmi *asus)
case asus_wmi_no_tablet_switch:
break;
case asus_wmi_kbd_dock_devid:
@@ -1445,86 +377,7 @@ index 5352055848d0..d71daa024752 100644
break;
}
---
-2.37.2
-
-From 1ea0d3b46798afc35c3185f6058b8bc08525d56c Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Wed, 24 Aug 2022 17:11:45 +0200
-Subject: [PATCH 14/19] platform/x86: asus-wmi: Simplify tablet-mode-switch
- handling
-
-Simplify tablet-mode-switch handling:
-1. The code is the same for all variants, the only difference is the
- dev_id and notify event code. Store the dev_id + code in struct asus_wmi
- and unify the handling
-2. Make the new unified asus_wmi_tablet_mode_get_state() check dev_id has
- been set and make it a no-op when not set. This allows calling it
- unconditionally at resume/restore time
-3. Simplify the tablet_mode_sw module-param handling, this also allows
- selecting the new lid-flip-rog type through the module-param.
-
-Cc: Luke D. Jones <luke@ljones.dev>
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-Link: https://lore.kernel.org/r/20220824151145.1448010-2-hdegoede@redhat.com
----
- drivers/platform/x86/asus-nb-wmi.c | 13 +----
- drivers/platform/x86/asus-wmi.c | 76 ++++++------------------------
- 2 files changed, 16 insertions(+), 73 deletions(-)
-
-diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
-index d9e7cf6e4a0e..cb8af61d684c 100644
---- a/drivers/platform/x86/asus-nb-wmi.c
-+++ b/drivers/platform/x86/asus-nb-wmi.c
-@@ -504,17 +504,8 @@ static void asus_nb_wmi_quirks(struct asus_wmi_driver *driver)
- else
- wapf = quirks->wapf;
-
-- switch (tablet_mode_sw) {
-- case 0:
-- quirks->tablet_switch_mode = asus_wmi_no_tablet_switch;
-- break;
-- case 1:
-- quirks->tablet_switch_mode = asus_wmi_kbd_dock_devid;
-- break;
-- case 2:
-- quirks->tablet_switch_mode = asus_wmi_lid_flip_devid;
-- break;
-- }
-+ if (tablet_mode_sw != -1)
-+ quirks->tablet_switch_mode = tablet_mode_sw;
-
- if (quirks->i8042_filter) {
- ret = i8042_install_filter(quirks->i8042_filter);
-diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
-index d71daa024752..0f9f79f249c7 100644
---- a/drivers/platform/x86/asus-wmi.c
-+++ b/drivers/platform/x86/asus-wmi.c
-@@ -222,6 +222,9 @@ struct asus_wmi {
- struct asus_rfkill gps;
- struct asus_rfkill uwb;
-
-+ int tablet_switch_event_code;
-+ u32 tablet_switch_dev_id;
-+
- enum fan_type fan_type;
- int fan_pwm_mode;
- int agfn_pwm;
-@@ -490,11 +493,11 @@ static void asus_wmi_tablet_sw_init(struct asus_wmi *asus, u32 dev_id, int event
- int result;
-
- result = asus_wmi_get_devstate_simple(asus, dev_id);
-- if (result < 0)
-- asus->driver->quirks->tablet_switch_mode = asus_wmi_no_tablet_switch;
- if (result >= 0) {
- input_set_capability(asus->inputdev, EV_SW, SW_TABLET_MODE);
- input_report_switch(asus->inputdev, SW_TABLET_MODE, result);
-+ asus->tablet_switch_dev_id = dev_id;
-+ asus->tablet_switch_event_code = event_code;
- } else if (result == -ENODEV) {
- dev_err(dev, "This device has tablet-mode-switch quirk but got ENODEV checking it. This is a bug.");
- } else {
-@@ -556,22 +559,14 @@ static void asus_wmi_input_exit(struct asus_wmi *asus)
+@@ -570,22 +565,14 @@ static void asus_wmi_input_exit(struct asus_wmi *asus)
/* Tablet mode ****************************************************************/
@@ -1551,144 +404,246 @@ index d71daa024752..0f9f79f249c7 100644
if (result >= 0) {
input_report_switch(asus->inputdev, SW_TABLET_MODE, result);
input_sync(asus->inputdev);
-@@ -3020,9 +3015,7 @@ static void asus_wmi_handle_event_code(int code, struct asus_wmi *asus)
+@@ -593,179 +580,267 @@ static void lid_flip_rog_tablet_mode_get_state(struct asus_wmi *asus)
+ }
+
+ /* dGPU ********************************************************************/
+-static int dgpu_disable_check_present(struct asus_wmi *asus)
++static ssize_t dgpu_disable_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
{
- unsigned int key_value = 1;
- bool autorelease = 1;
-- int result, orig_code;
+- u32 result;
+- int err;
-
-- orig_code = code;
-+ int orig_code = code;
+- asus->dgpu_disable_available = false;
+-
+- err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_DGPU, &result);
+- if (err) {
+- if (err == -ENODEV)
+- return 0;
+- return err;
+- }
++ struct asus_wmi *asus = dev_get_drvdata(dev);
++ int result;
- if (asus->driver->key_filter) {
- asus->driver->key_filter(asus->driver, &code, &key_value,
-@@ -3065,27 +3058,8 @@ static void asus_wmi_handle_event_code(int code, struct asus_wmi *asus)
- return;
+- if (result & ASUS_WMI_DSTS_PRESENCE_BIT) {
+- asus->dgpu_disable_available = true;
+- asus->dgpu_disable = result & ASUS_WMI_DSTS_STATUS_BIT;
+- }
++ result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_DGPU);
++ if (result < 0)
++ return result;
+
+- return 0;
++ return sysfs_emit(buf, "%d\n", result);
+ }
+
+-static int dgpu_disable_write(struct asus_wmi *asus)
++/*
++ * A user may be required to store the value twice, typcial store first, then
++ * rescan PCI bus to activate power, then store a second time to save correctly.
++ * The reason for this is that an extra code path in the ACPI is enabled when
++ * the device and bus are powered.
++ */
++static ssize_t dgpu_disable_store(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t count)
+ {
+- u32 retval;
+- u8 value;
+- int err;
++ int result, err;
++ u32 disable;
+
+- /* Don't rely on type conversion */
+- value = asus->dgpu_disable ? 1 : 0;
++ struct asus_wmi *asus = dev_get_drvdata(dev);
+
+- err = asus_wmi_set_devstate(ASUS_WMI_DEVID_DGPU, value, &retval);
++ result = kstrtou32(buf, 10, &disable);
++ if (result)
++ return result;
++
++ if (disable > 1)
++ return -EINVAL;
++
++ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_DGPU, disable, &result);
+ if (err) {
+ pr_warn("Failed to set dgpu disable: %d\n", err);
+ return err;
}
-- if (asus->driver->quirks->tablet_switch_mode == asus_wmi_kbd_dock_devid &&
-- code == NOTIFY_KBD_DOCK_CHANGE) {
-- result = asus_wmi_get_devstate_simple(asus,
-- ASUS_WMI_DEVID_KBD_DOCK);
-- if (result >= 0) {
-- input_report_switch(asus->inputdev, SW_TABLET_MODE,
-- !result);
-- input_sync(asus->inputdev);
-- }
-- return;
-- }
--
-- if (asus->driver->quirks->tablet_switch_mode == asus_wmi_lid_flip_devid &&
-- code == NOTIFY_LID_FLIP) {
-- lid_flip_tablet_mode_get_state(asus);
-- return;
-- }
--
-- if (asus->driver->quirks->tablet_switch_mode == asus_wmi_lid_flip_rog_devid &&
-- code == NOTIFY_LID_FLIP_ROG) {
-- lid_flip_rog_tablet_mode_get_state(asus);
-+ if (code == asus->tablet_switch_event_code) {
-+ asus_wmi_tablet_mode_get_state(asus);
- return;
+- if (retval > 1) {
+- pr_warn("Failed to set dgpu disable (retval): 0x%x\n", retval);
++ if (result > 1) {
++ pr_warn("Failed to set dgpu disable (result): 0x%x\n", result);
+ return -EIO;
}
-@@ -3714,18 +3688,7 @@ static int asus_hotk_resume(struct device *device)
- if (asus_wmi_has_fnlock_key(asus))
- asus_wmi_fnlock_update(asus);
+ sysfs_notify(&asus->platform_device->dev.kobj, NULL, "dgpu_disable");
-- switch (asus->driver->quirks->tablet_switch_mode) {
-- case asus_wmi_no_tablet_switch:
-- case asus_wmi_kbd_dock_devid:
-- break;
-- case asus_wmi_lid_flip_devid:
-- lid_flip_tablet_mode_get_state(asus);
-- break;
-- case asus_wmi_lid_flip_rog_devid:
-- lid_flip_rog_tablet_mode_get_state(asus);
-- break;
-- }
--
-+ asus_wmi_tablet_mode_get_state(asus);
- return 0;
+- return 0;
++ return count;
}
++static DEVICE_ATTR_RW(dgpu_disable);
-@@ -3765,18 +3728,7 @@ static int asus_hotk_restore(struct device *device)
- if (asus_wmi_has_fnlock_key(asus))
- asus_wmi_fnlock_update(asus);
+-static ssize_t dgpu_disable_show(struct device *dev,
++/* eGPU ********************************************************************/
++static ssize_t egpu_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+ {
+ struct asus_wmi *asus = dev_get_drvdata(dev);
+- u8 mode = asus->dgpu_disable;
++ int result;
-- switch (asus->driver->quirks->tablet_switch_mode) {
-- case asus_wmi_no_tablet_switch:
-- case asus_wmi_kbd_dock_devid:
-- break;
-- case asus_wmi_lid_flip_devid:
-- lid_flip_tablet_mode_get_state(asus);
-- break;
-- case asus_wmi_lid_flip_rog_devid:
-- lid_flip_rog_tablet_mode_get_state(asus);
-- break;
-- }
--
-+ asus_wmi_tablet_mode_get_state(asus);
- return 0;
+- return sysfs_emit(buf, "%d\n", mode);
++ result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_EGPU);
++ if (result < 0)
++ return result;
++
++ return sysfs_emit(buf, "%d\n", result);
}
---
-2.37.2
-
-From 4e821f67963ae0c4dcceadb561077164da5ac79a Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones" <luke@ljones.dev>
-Date: Fri, 26 Aug 2022 10:32:34 +1200
-Subject: [PATCH 17/19] asus-wmi: Implement TUF laptop keyboard LED modes
-
-Adds support for changing the laptop keyboard LED mode and colour.
-
-The modes are visible effects such as static, rainbow, pulsing,
-colour cycles.
-
-These sysfs attributes are added to asus::kbd_backlight:
-- kbd_rgb_mode
-- kbd_rgb_mode_index
-
-Signed-off-by: Luke D. Jones <luke@ljones.dev>
----
- drivers/platform/x86/asus-wmi.c | 76 +++++++++++++++++++++-
- include/linux/platform_data/x86/asus-wmi.h | 3 +
- 2 files changed, 78 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
-index 0f9f79f249c7..92f16bb9b4ef 100644
---- a/drivers/platform/x86/asus-wmi.c
-+++ b/drivers/platform/x86/asus-wmi.c
-@@ -237,6 +237,8 @@ struct asus_wmi {
- bool dgpu_disable_available;
- bool gpu_mux_mode_available;
+-/*
+- * A user may be required to store the value twice, typcial store first, then
+- * rescan PCI bus to activate power, then store a second time to save correctly.
+- * The reason for this is that an extra code path in the ACPI is enabled when
+- * the device and bus are powered.
+- */
+-static ssize_t dgpu_disable_store(struct device *dev,
++/* The ACPI call to enable the eGPU also disables the internal dGPU */
++static ssize_t egpu_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+ {
+- bool disable;
+- int result;
++ int result, err;
++ u32 enable;
-+ bool kbd_rgb_mode_available;
+ struct asus_wmi *asus = dev_get_drvdata(dev);
+
+- result = kstrtobool(buf, &disable);
+- if (result)
+- return result;
++ err = kstrtou32(buf, 10, &enable);
++ if (err)
++ return err;
+
+- asus->dgpu_disable = disable;
++ if (enable > 1)
++ return -EINVAL;
+
+- result = dgpu_disable_write(asus);
+- if (result)
+- return result;
++ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_EGPU, enable, &result);
++ if (err) {
++ pr_warn("Failed to set egpu disable: %d\n", err);
++ return err;
++ }
+
- bool throttle_thermal_policy_available;
- u8 throttle_thermal_policy_mode;
++ if (result > 1) {
++ pr_warn("Failed to set egpu disable (retval): 0x%x\n", result);
++ return -EIO;
++ }
++
++ sysfs_notify(&asus->platform_device->dev.kobj, NULL, "egpu_enable");
-@@ -720,6 +722,69 @@ static ssize_t gpu_mux_mode_store(struct device *dev,
+ return count;
}
- static DEVICE_ATTR_RW(gpu_mux_mode);
++static DEVICE_ATTR_RW(egpu_enable);
+-static DEVICE_ATTR_RW(dgpu_disable);
++/* gpu mux switch *************************************************************/
++static ssize_t gpu_mux_mode_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct asus_wmi *asus = dev_get_drvdata(dev);
++ int result;
+
+-/* eGPU ********************************************************************/
+-static int egpu_enable_check_present(struct asus_wmi *asus)
++ result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_GPU_MUX);
++ if (result < 0)
++ return result;
++
++ return sysfs_emit(buf, "%d\n", result);
++}
++
++static ssize_t gpu_mux_mode_store(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t count)
+ {
+- u32 result;
+- int err;
++ struct asus_wmi *asus = dev_get_drvdata(dev);
++ int result, err;
++ u32 optimus;
+
+- asus->egpu_enable_available = false;
++ err = kstrtou32(buf, 10, &optimus);
++ if (err)
++ return err;
+
+- err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_EGPU, &result);
++ if (optimus > 1)
++ return -EINVAL;
++
++ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_GPU_MUX, optimus, &result);
+ if (err) {
+- if (err == -ENODEV)
+- return 0;
++ dev_err(dev, "Failed to set GPU MUX mode: %d\n", err);
+ return err;
+ }
+-
+- if (result & ASUS_WMI_DSTS_PRESENCE_BIT) {
+- asus->egpu_enable_available = true;
+- asus->egpu_enable = result & ASUS_WMI_DSTS_STATUS_BIT;
++ /* !1 is considered a fail by ASUS */
++ if (result != 1) {
++ dev_warn(dev, "Failed to set GPU MUX mode (result): 0x%x\n", result);
++ return -EIO;
+ }
+
+- return 0;
++ sysfs_notify(&asus->platform_device->dev.kobj, NULL, "gpu_mux_mode");
++
++ return count;
+ }
++static DEVICE_ATTR_RW(gpu_mux_mode);
+
+-static int egpu_enable_write(struct asus_wmi *asus)
+/* TUF Laptop Keyboard RGB Modes **********************************************/
+static ssize_t kbd_rgb_mode_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
-+{
+ {
+- u32 retval;
+- u8 value;
+ u32 cmd, mode, r, g, b, speed;
-+ int err;
-+
+ int err;
+
+- /* Don't rely on type conversion */
+- value = asus->egpu_enable ? 1 : 0;
+ if (sscanf(buf, "%d %d %d %d %d %d", &cmd, &mode, &r, &g, &b, &speed) != 6)
+ return -EINVAL;
-+
+
+- err = asus_wmi_set_devstate(ASUS_WMI_DEVID_EGPU, value, &retval);
+ cmd = !!cmd;
-+
+
+- if (err) {
+- pr_warn("Failed to set egpu disable: %d\n", err);
+- return err;
+- }
+ /* These are the known usable modes across all TUF/ROG */
+ if (mode >= 12 || mode == 9)
+ mode = 10;
-+
+
+- if (retval > 1) {
+- pr_warn("Failed to set egpu disable (retval): 0x%x\n", retval);
+- return -EIO;
+ switch (speed) {
+ case 0:
+ speed = 0xe1;
@@ -1701,137 +656,56 @@ index 0f9f79f249c7..92f16bb9b4ef 100644
+ break;
+ default:
+ speed = 0xeb;
-+ }
-+
+ }
+
+- sysfs_notify(&asus->platform_device->dev.kobj, NULL, "egpu_enable");
+ err = asus_wmi_evaluate_method3(ASUS_WMI_METHODID_DEVS, ASUS_WMI_DEVID_TUF_RGB_MODE,
+ cmd | (mode << 8) | (r << 16) | (g << 24), b | (speed << 8), NULL);
+ if (err)
+ return err;
-+
+
+- return 0;
+ return count;
-+}
+ }
+static DEVICE_ATTR_WO(kbd_rgb_mode);
-+
+
+-static ssize_t egpu_enable_show(struct device *dev,
+- struct device_attribute *attr, char *buf)
+static ssize_t kbd_rgb_mode_index_show(struct device *device,
+ struct device_attribute *attr,
+ char *buf)
-+{
+ {
+- struct asus_wmi *asus = dev_get_drvdata(dev);
+- bool mode = asus->egpu_enable;
+-
+- return sysfs_emit(buf, "%d\n", mode);
+ return sysfs_emit(buf, "%s\n", "cmd mode red green blue speed");
-+}
+ }
+static DEVICE_ATTR_RO(kbd_rgb_mode_index);
-+
+
+-/* The ACPI call to enable the eGPU also disables the internal dGPU */
+-static ssize_t egpu_enable_store(struct device *dev,
+- struct device_attribute *attr,
+- const char *buf, size_t count)
+-{
+- bool enable;
+- int result;
+-
+- struct asus_wmi *asus = dev_get_drvdata(dev);
+static struct attribute *kbd_rgb_mode_attrs[] = {
+ &dev_attr_kbd_rgb_mode.attr,
+ &dev_attr_kbd_rgb_mode_index.attr,
+ NULL,
+};
-+
+
+- result = kstrtobool(buf, &enable);
+- if (result)
+- return result;
+static const struct attribute_group kbd_rgb_mode_group = {
+ .attrs = kbd_rgb_mode_attrs,
+};
-+
-+const struct attribute_group *kbd_rgb_mode_groups[] = {
-+ NULL,
-+ NULL,
-+};
-+
- /* Battery ********************************************************************/
-
- /* The battery maximum charging percentage */
-@@ -1038,7 +1103,10 @@ static void asus_wmi_led_exit(struct asus_wmi *asus)
-
- static int asus_wmi_led_init(struct asus_wmi *asus)
- {
-- int rv = 0, led_val;
-+ int rv = 0, num_rgb_groups = 0, led_val;
-+
-+ if (asus->kbd_rgb_mode_available)
-+ kbd_rgb_mode_groups[num_rgb_groups++] = &kbd_rgb_mode_group;
-
- asus->led_workqueue = create_singlethread_workqueue("led_workqueue");
- if (!asus->led_workqueue)
-@@ -1066,6 +1134,9 @@ static int asus_wmi_led_init(struct asus_wmi *asus)
- asus->kbd_led.brightness_get = kbd_led_get;
- asus->kbd_led.max_brightness = 3;
-
-+ if (num_rgb_groups != 0)
-+ asus->kbd_led.groups = kbd_rgb_mode_groups;
-+
- rv = led_classdev_register(&asus->platform_device->dev,
- &asus->kbd_led);
- if (rv)
-@@ -3253,6 +3324,8 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj,
- ok = asus->egpu_enable_available;
- else if (attr == &dev_attr_dgpu_disable.attr)
- ok = asus->dgpu_disable_available;
-+ else if (attr == &dev_attr_dgpu_disable.attr)
-+ ok = asus->dgpu_disable_available;
- else if (attr == &dev_attr_gpu_mux_mode.attr)
- ok = asus->gpu_mux_mode_available;
- else if (attr == &dev_attr_fan_boost_mode.attr)
-@@ -3519,6 +3592,7 @@ static int asus_wmi_add(struct platform_device *pdev)
- asus->egpu_enable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_EGPU);
- asus->dgpu_disable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_DGPU);
- asus->gpu_mux_mode_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_GPU_MUX);
-+ asus->kbd_rgb_mode_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_MODE);
- asus->panel_overdrive_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PANEL_OD);
-
- err = fan_boost_mode_check_present(asus);
-diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
-index 6e8a95c10d17..3d861477cb20 100644
---- a/include/linux/platform_data/x86/asus-wmi.h
-+++ b/include/linux/platform_data/x86/asus-wmi.h
-@@ -103,6 +103,9 @@
- /* gpu mux switch, 0 = dGPU, 1 = Optimus */
- #define ASUS_WMI_DEVID_GPU_MUX 0x00090016
-
-+/* TUF laptop RGB modes/colours */
-+#define ASUS_WMI_DEVID_TUF_RGB_MODE 0x00100056
-+
- /* DSTS masks */
- #define ASUS_WMI_DSTS_STATUS_BIT 0x00000001
- #define ASUS_WMI_DSTS_UNKNOWN_BIT 0x00000002
---
-2.37.2
-
-From fa211b90a6ed8973cb50b478a7cb250f5d8d0a12 Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones" <luke@ljones.dev>
-Date: Fri, 26 Aug 2022 10:33:20 +1200
-Subject: [PATCH 18/19] asus-wmi: Implement TUF laptop keyboard power states
-
-Adds support for setting various power states of TUF keyboards.
-These states are combinations of:
-- boot, set if a boot animation is shown on keyboard
-- awake, set if the keyboard LEDs are visible while laptop is on
-- sleep, set if an animation is displayed while the laptop is suspended
-- keyboard (unknown effect)
-
-Adds two sysfs attributes to asus::kbd_backlight:
-- kbd_rgb_state
-- kbd_rgb_state_index
-
-Signed-off-by: Luke D. Jones <luke@ljones.dev>
----
- drivers/platform/x86/asus-wmi.c | 57 ++++++++++++++++++++++
- include/linux/platform_data/x86/asus-wmi.h | 3 ++
- 2 files changed, 60 insertions(+)
-
-diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
-index 92f16bb9b4ef..f608a4467d99 100644
---- a/drivers/platform/x86/asus-wmi.c
-+++ b/drivers/platform/x86/asus-wmi.c
-@@ -238,6 +238,7 @@ struct asus_wmi {
- bool gpu_mux_mode_available;
-
- bool kbd_rgb_mode_available;
-+ bool kbd_rgb_state_available;
-
- bool throttle_thermal_policy_available;
- u8 throttle_thermal_policy_mode;
-@@ -780,9 +781,62 @@ static const struct attribute_group kbd_rgb_mode_group = {
- .attrs = kbd_rgb_mode_attrs,
- };
+- asus->egpu_enable = enable;
+/* TUF Laptop Keyboard RGB State **********************************************/
+static ssize_t kbd_rgb_state_store(struct device *dev,
+ struct device_attribute *attr,
@@ -1839,10 +713,17 @@ index 92f16bb9b4ef..f608a4467d99 100644
+{
+ u32 flags, cmd, boot, awake, sleep, keyboard;
+ int err;
-+
+
+- result = egpu_enable_write(asus);
+- if (result)
+- return result;
+ if (sscanf(buf, "%d %d %d %d %d", &cmd, &boot, &awake, &sleep, &keyboard) != 5)
+ return -EINVAL;
-+
+
+- /* Ensure that the kernel status of dgpu is updated */
+- result = dgpu_disable_check_present(asus);
+- if (result)
+- return result;
+ if (cmd)
+ cmd = BIT(2);
+
@@ -1861,11 +742,12 @@ index 92f16bb9b4ef..f608a4467d99 100644
+ ASUS_WMI_DEVID_TUF_RGB_STATE, 0xbd | cmd << 8 | (flags << 16), 0, NULL);
+ if (err)
+ return err;
-+
-+ return count;
-+}
+
+ return count;
+ }
+static DEVICE_ATTR_WO(kbd_rgb_state);
-+
+
+-static DEVICE_ATTR_RW(egpu_enable);
+static ssize_t kbd_rgb_state_index_show(struct device *device,
+ struct device_attribute *attr,
+ char *buf)
@@ -1884,312 +766,157 @@ index 92f16bb9b4ef..f608a4467d99 100644
+ .attrs = kbd_rgb_state_attrs,
+};
+
- const struct attribute_group *kbd_rgb_mode_groups[] = {
- NULL,
- NULL,
++const struct attribute_group *kbd_rgb_mode_groups[] = {
+ NULL,
- };
++ NULL,
++ NULL,
++};
/* Battery ********************************************************************/
-@@ -1107,6 +1161,8 @@ static int asus_wmi_led_init(struct asus_wmi *asus)
- if (asus->kbd_rgb_mode_available)
- kbd_rgb_mode_groups[num_rgb_groups++] = &kbd_rgb_mode_group;
+@@ -803,7 +878,7 @@ static ssize_t charge_control_end_threshold_show(struct device *device,
+ struct device_attribute *attr,
+ char *buf)
+ {
+- return sprintf(buf, "%d\n", charge_end_threshold);
++ return sysfs_emit(buf, "%d\n", charge_end_threshold);
+ }
+
+ static DEVICE_ATTR_RW(charge_control_end_threshold);
+@@ -1085,7 +1160,12 @@ static void asus_wmi_led_exit(struct asus_wmi *asus)
+
+ static int asus_wmi_led_init(struct asus_wmi *asus)
+ {
+- int rv = 0, led_val;
++ int rv = 0, num_rgb_groups = 0, led_val;
++
++ if (asus->kbd_rgb_mode_available)
++ kbd_rgb_mode_groups[num_rgb_groups++] = &kbd_rgb_mode_group;
+ if (asus->kbd_rgb_state_available)
+ kbd_rgb_mode_groups[num_rgb_groups++] = &kbd_rgb_state_group;
asus->led_workqueue = create_singlethread_workqueue("led_workqueue");
if (!asus->led_workqueue)
-@@ -3593,6 +3649,7 @@ static int asus_wmi_add(struct platform_device *pdev)
- asus->dgpu_disable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_DGPU);
- asus->gpu_mux_mode_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_GPU_MUX);
- asus->kbd_rgb_mode_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_MODE);
-+ asus->kbd_rgb_state_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_STATE);
- asus->panel_overdrive_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PANEL_OD);
-
- err = fan_boost_mode_check_present(asus);
-diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
-index 3d861477cb20..7dd580fdc61c 100644
---- a/include/linux/platform_data/x86/asus-wmi.h
-+++ b/include/linux/platform_data/x86/asus-wmi.h
-@@ -106,6 +106,9 @@
- /* TUF laptop RGB modes/colours */
- #define ASUS_WMI_DEVID_TUF_RGB_MODE 0x00100056
+@@ -1113,6 +1193,9 @@ static int asus_wmi_led_init(struct asus_wmi *asus)
+ asus->kbd_led.brightness_get = kbd_led_get;
+ asus->kbd_led.max_brightness = 3;
-+/* TUF laptop RGB power/state */
-+#define ASUS_WMI_DEVID_TUF_RGB_STATE 0x00100057
++ if (num_rgb_groups != 0)
++ asus->kbd_led.groups = kbd_rgb_mode_groups;
+
- /* DSTS masks */
- #define ASUS_WMI_DSTS_STATUS_BIT 0x00000001
- #define ASUS_WMI_DSTS_UNKNOWN_BIT 0x00000002
---
-2.37.2
-
-From 802dfc514194e5459397f513b202031228b3315a Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones" <luke@ljones.dev>
-Date: Fri, 26 Aug 2022 12:25:12 +1200
-Subject: [PATCH 19/19] HID: amd_sfh: Add keyguard for ASUS ROG X13 tablet
-
-Add support for ROG X13 Flow 2-in-1 to disable the keyboard when
-the lid is flipped.
-
-Signed-off-by: Luke D. Jones <luke@ljones.dev>
----
- drivers/hid/amd-sfh-hid/amd_sfh_pcie.c | 4 +++
- drivers/hid/amd-sfh-hid/amd_sfh_pcie.h | 1 +
- .../hid_descriptor/amd_sfh_hid_desc.c | 27 +++++++++++++++++++
- .../hid_descriptor/amd_sfh_hid_desc.h | 8 ++++++
- .../hid_descriptor/amd_sfh_hid_report_desc.h | 19 +++++++++++++
- 5 files changed, 59 insertions(+)
-
-diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
-index 4b90c86ee5f8..0f4db2ce076e 100644
---- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
-+++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
-@@ -27,6 +27,7 @@
- #define ACEL_EN BIT(0)
- #define GYRO_EN BIT(1)
- #define MAGNO_EN BIT(2)
-+#define KBGUARD_EN BIT(15)
- #define HPD_EN BIT(16)
- #define ALS_EN BIT(19)
+ rv = led_classdev_register(&asus->platform_device->dev,
+ &asus->kbd_led);
+ if (rv)
+@@ -1587,84 +1670,51 @@ static int asus_wmi_rfkill_init(struct asus_wmi *asus)
+ }
-@@ -233,6 +234,9 @@ int amd_mp2_get_sensor_num(struct amd_mp2_dev *privdata, u8 *sensor_id)
- if (HPD_EN & activestatus)
- sensor_id[num_of_sensors++] = HPD_IDX;
+ /* Panel Overdrive ************************************************************/
+-static int panel_od_check_present(struct asus_wmi *asus)
+-{
+- u32 result;
+- int err;
+-
+- asus->panel_overdrive_available = false;
+-
+- err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_PANEL_OD, &result);
+- if (err) {
+- if (err == -ENODEV)
+- return 0;
+- return err;
+- }
+-
+- if (result & ASUS_WMI_DSTS_PRESENCE_BIT) {
+- asus->panel_overdrive_available = true;
+- asus->panel_overdrive = result & ASUS_WMI_DSTS_STATUS_BIT;
+- }
+-
+- return 0;
+-}
+-
+-static int panel_od_write(struct asus_wmi *asus)
+-{
+- u32 retval;
+- u8 value;
+- int err;
+-
+- /* Don't rely on type conversion */
+- value = asus->panel_overdrive ? 1 : 0;
+-
+- err = asus_wmi_set_devstate(ASUS_WMI_DEVID_PANEL_OD, value, &retval);
+-
+- if (err) {
+- pr_warn("Failed to set panel overdrive: %d\n", err);
+- return err;
+- }
+-
+- if (retval > 1) {
+- pr_warn("Failed to set panel overdrive (retval): 0x%x\n", retval);
+- return -EIO;
+- }
+-
+- sysfs_notify(&asus->platform_device->dev.kobj, NULL, "panel_od");
+-
+- return 0;
+-}
+-
+ static ssize_t panel_od_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+ {
+ struct asus_wmi *asus = dev_get_drvdata(dev);
++ int result;
-+ if (KBGUARD_EN & activestatus)
-+ sensor_id[num_of_sensors++] = KBGUARD_IDX;
+- return sysfs_emit(buf, "%d\n", asus->panel_overdrive);
++ result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_PANEL_OD);
++ if (result < 0)
++ return result;
+
- return num_of_sensors;
++ return sysfs_emit(buf, "%d\n", result);
}
-diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h
-index dfb7cabd82ef..5fa15eed43f3 100644
---- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h
-+++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h
-@@ -23,6 +23,7 @@
- #define V2_STATUS 0x2
-
- #define HPD_IDX 16
-+#define KBGUARD_IDX 15
-
- #define SENSOR_DISCOVERY_STATUS_MASK GENMASK(5, 3)
- #define SENSOR_DISCOVERY_STATUS_SHIFT 3
-diff --git a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.c b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.c
-index f9a8c02d5a7b..06487eb75dc8 100644
---- a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.c
-+++ b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.c
-@@ -57,6 +57,11 @@ static int get_report_descriptor(int sensor_idx, u8 *rep_desc)
- memcpy(rep_desc, hpd_report_descriptor,
- sizeof(hpd_report_descriptor));
- break;
-+ case KBGUARD_IDX: /* kbguard ? */
-+ memset(rep_desc, 0, sizeof(kbguard_report_descriptor));
-+ memcpy(rep_desc, kbguard_report_descriptor,
-+ sizeof(kbguard_report_descriptor));
-+ break;
- default:
- break;
- }
-@@ -116,6 +121,16 @@ static u32 get_descr_sz(int sensor_idx, int descriptor_name)
- return sizeof(struct hpd_feature_report);
- }
- break;
-+ case KBGUARD_IDX:
-+ switch (descriptor_name) {
-+ case descr_size:
-+ return sizeof(kbguard_report_descriptor);
-+ case input_size:
-+ return sizeof(struct kbguard_input_report);
-+ case feature_size:
-+ return sizeof(struct kbguard_feature_report);
-+ }
-+ break;
+ static ssize_t panel_od_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+ {
+- bool overdrive;
+- int result;
++ int result, err;
++ u32 overdrive;
- default:
- break;
-@@ -139,6 +154,7 @@ static u8 get_feature_report(int sensor_idx, int report_id, u8 *feature_report)
- struct gyro_feature_report gyro_feature;
- struct magno_feature_report magno_feature;
- struct hpd_feature_report hpd_feature;
-+ struct kbguard_feature_report kbguard_feature;
- struct als_feature_report als_feature;
- u8 report_size = 0;
+ struct asus_wmi *asus = dev_get_drvdata(dev);
-@@ -186,6 +202,11 @@ static u8 get_feature_report(int sensor_idx, int report_id, u8 *feature_report)
- memcpy(feature_report, &hpd_feature, sizeof(hpd_feature));
- report_size = sizeof(hpd_feature);
- break;
-+ case KBGUARD_IDX: /* auto disable keyboard when flip out */
-+ get_common_features(&kbguard_feature.common_property, report_id);
-+ memcpy(feature_report, &kbguard_feature, sizeof(kbguard_feature));
-+ report_size = sizeof(kbguard_feature);
-+ break;
+- result = kstrtobool(buf, &overdrive);
++ result = kstrtou32(buf, 10, &overdrive);
+ if (result)
+ return result;
- default:
- break;
-@@ -211,6 +232,7 @@ static u8 get_input_report(u8 current_index, int sensor_idx, int report_id,
- struct accel3_input_report acc_input;
- struct gyro_input_report gyro_input;
- struct hpd_input_report hpd_input;
-+ struct kbguard_input_report kbguard_input;
- struct als_input_report als_input;
- struct hpd_status hpdstatus;
- u8 report_size = 0;
-@@ -263,6 +285,11 @@ static u8 get_input_report(u8 current_index, int sensor_idx, int report_id,
- report_size = sizeof(hpd_input);
- memcpy(input_report, &hpd_input, sizeof(hpd_input));
- break;
-+ case KBGUARD_IDX: /* kb guard */
-+ get_common_inputs(&kbguard_input.common_property, report_id);
-+ report_size = sizeof(kbguard_input);
-+ memcpy(input_report, &kbguard_input, sizeof(kbguard_input));
-+break;
- default:
- break;
- }
-diff --git a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h
-index ebd55675eb62..2f2ba9a0cfbc 100644
---- a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h
-+++ b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h
-@@ -111,4 +111,12 @@ struct hpd_input_report {
- u8 human_presence;
- } __packed;
+- asus->panel_overdrive = overdrive;
+- result = panel_od_write(asus);
++ if (overdrive > 1)
++ return -EINVAL;
-+struct kbguard_feature_report {
-+ struct common_feature_property common_property;
-+} __packed;
-+
-+struct kbguard_input_report {
-+ struct common_input_property common_property;
-+} __packed;
+- if (result)
+- return result;
++ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_PANEL_OD, overdrive, &result);
+
- #endif
-diff --git a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h
-index 697f2791ea9c..7a62fcec2c73 100644
---- a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h
-+++ b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h
-@@ -644,6 +644,25 @@ static const u8 als_report_descriptor[] = {
- 0xC0 /* HID end collection */
- };
-
++ if (err) {
++ pr_warn("Failed to set panel overdrive: %d\n", err);
++ return err;
++ }
+
-+static const u8 kbguard_report_descriptor[] = {
-+0x06, 0x43, 0xFF, // Usage Page (Vendor Defined 0xFF43)
-+0x0A, 0x02, 0x02, // Usage (0x0202)
-+0xA1, 0x01, // Collection (Application)
-+0x85, 0x11, // Report ID (17)
-+0x15, 0x00, // Logical Minimum (0)
-+0x25, 0x01, // Logical Maximum (1)
-+0x35, 0x00, // Physical Minimum (0)
-+0x45, 0x01, // Physical Maximum (1)
-+0x65, 0x00, // Unit (None)
-+0x55, 0x00, // Unit Exponent (0)
-+0x75, 0x01, // Report Size (1)
-+0x95, 0x98, // Report Count (-104)
-+0x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
-+0x91, 0x03, // Output (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
-+0xC1, 0x00, // End Collection
-+};
++ if (result > 1) {
++ pr_warn("Failed to set panel overdrive (result): 0x%x\n", result);
++ return -EIO;
++ }
+
- /* BIOMETRIC PRESENCE*/
- static const u8 hpd_report_descriptor[] = {
- 0x05, 0x20, /* Usage page */
---
-2.37.2
-
-From 3f73788b14ada783657e5e6303c4e5de5e096be5 Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones" <luke@ljones.dev>
-Date: Fri, 26 Aug 2022 12:32:24 +1200
-Subject: [PATCH 20/21] asus-wmi: Modify behaviour of Fn+F5 fan key
-
-Some more recent TUF laptops have both fan_boost and thermal_throttle.
-The key code for Fn+F5 is also different and unmapped.
-
-This patch adjusts the asus_wmi_handle_event_code() match to match
-for both 0x99 and 0xAE, and run both mode switch functions for
-fan_boost and/or thermal_throttle if either are available.
-
-It is required that both are tried, as in some instances the ACPI
-set-method for one may not have any code body within it even though
-it was returned as supported by the get method.
-
-Signed-off-by: Luke D. Jones <luke@ljones.dev>
----
- drivers/platform/x86/asus-nb-wmi.c | 1 +
- drivers/platform/x86/asus-wmi.c | 11 +++++------
- 2 files changed, 6 insertions(+), 6 deletions(-)
-
-diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
-index cb8af61d684c..fcfe6dddd645 100644
---- a/drivers/platform/x86/asus-nb-wmi.c
-+++ b/drivers/platform/x86/asus-nb-wmi.c
-@@ -577,6 +577,7 @@ static const struct key_entry asus_nb_wmi_keymap[] = {
- { KE_KEY, 0xA5, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + TV + HDMI */
- { KE_KEY, 0xA6, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT + TV + HDMI */
- { KE_KEY, 0xA7, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + CRT + TV + HDMI */
-+ { KE_KEY, 0xAE, { KEY_FN_F5 } }, /* Fn+F5 fan mode on 2020+ */
- { KE_KEY, 0xB3, { KEY_PROG4 } }, /* AURA */
- { KE_KEY, 0xB5, { KEY_CALC } },
- { KE_KEY, 0xC4, { KEY_KBDILLUMUP } },
-diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
-index f608a4467d99..ea45e10302f7 100644
---- a/drivers/platform/x86/asus-wmi.c
-+++ b/drivers/platform/x86/asus-wmi.c
-@@ -3190,14 +3190,13 @@ static void asus_wmi_handle_event_code(int code, struct asus_wmi *asus)
- return;
- }
-
-- if (asus->fan_boost_mode_available && code == NOTIFY_KBD_FBM) {
-- fan_boost_mode_switch_next(asus);
-+ if (code == NOTIFY_KBD_FBM || code == NOTIFY_KBD_TTP) {
-+ if (asus->fan_boost_mode_available)
-+ fan_boost_mode_switch_next(asus);
-+ if (asus->throttle_thermal_policy_available)
-+ throttle_thermal_policy_switch_next(asus);
- return;
-- }
-
-- if (asus->throttle_thermal_policy_available && code == NOTIFY_KBD_TTP) {
-- throttle_thermal_policy_switch_next(asus);
-- return;
- }
-
- if (is_display_toggle(code) && asus->driver->quirks->no_display_toggle)
---
-2.37.2
-
-From fe443cc4ff4e12652af1cdae63cff354a2467b67 Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones" <luke@ljones.dev>
-Date: Fri, 26 Aug 2022 12:34:02 +1200
-Subject: [PATCH 21/21] asus-wmi: Support the GPU fan on TUF laptops
-
-Add support for TUF laptops which have the ability to control
-the GPU fan. This will show as a second fan in hwmon, and has
-the ability to run as boost (fullspeed), or auto.
-
-Signed-off-by: Luke D. Jones <luke@ljones.dev>
----
- drivers/platform/x86/asus-wmi.c | 71 ++++++++++++++++++++++
- include/linux/platform_data/x86/asus-wmi.h | 1 +
- 2 files changed, 72 insertions(+)
-
-diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
-index ea45e10302f7..d05684194f2d 100644
---- a/drivers/platform/x86/asus-wmi.c
-+++ b/drivers/platform/x86/asus-wmi.c
-@@ -226,7 +226,9 @@ struct asus_wmi {
- u32 tablet_switch_dev_id;
++ sysfs_notify(&asus->platform_device->dev.kobj, NULL, "panel_od");
- enum fan_type fan_type;
-+ enum fan_type gpu_fan_type;
- int fan_pwm_mode;
-+ int gpu_fan_pwm_mode;
- int agfn_pwm;
+ return count;
+ }
+-
+ static DEVICE_ATTR_RW(panel_od);
- bool fan_boost_mode_available;
-@@ -1861,6 +1863,18 @@ static int asus_fan_set_auto(struct asus_wmi *asus)
+ /* Quirks *********************************************************************/
+@@ -1816,6 +1866,18 @@ static int asus_fan_set_auto(struct asus_wmi *asus)
return -ENXIO;
}
@@ -2208,11 +935,71 @@ index ea45e10302f7..d05684194f2d 100644
return 0;
}
-@@ -2063,9 +2077,57 @@ static ssize_t asus_hwmon_temp1(struct device *dev,
+@@ -1853,7 +1915,7 @@ static ssize_t pwm1_show(struct device *dev,
+ value = -1;
+ }
+
+- return sprintf(buf, "%d\n", value);
++ return sysfs_emit(buf, "%d\n", value);
+ }
+
+ static ssize_t pwm1_store(struct device *dev,
+@@ -1913,7 +1975,7 @@ static ssize_t fan1_input_show(struct device *dev,
+ return -ENXIO;
+ }
+
+- return sprintf(buf, "%d\n", value < 0 ? -1 : value*100);
++ return sysfs_emit(buf, "%d\n", value < 0 ? -1 : value * 100);
+ }
+
+ static ssize_t pwm1_enable_show(struct device *dev,
+@@ -1931,7 +1993,7 @@ static ssize_t pwm1_enable_show(struct device *dev,
+ * in practice on X532FL at least (the bit is always 0) and there's
+ * also nothing in the DSDT to indicate that this behaviour exists.
+ */
+- return sprintf(buf, "%d\n", asus->fan_pwm_mode);
++ return sysfs_emit(buf, "%d\n", asus->fan_pwm_mode);
+ }
+
+ static ssize_t pwm1_enable_store(struct device *dev,
+@@ -1999,7 +2061,7 @@ static ssize_t fan1_label_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+ {
+- return sprintf(buf, "%s\n", ASUS_FAN_DESC);
++ return sysfs_emit(buf, "%s\n", ASUS_FAN_DESC);
+ }
+
+ static ssize_t asus_hwmon_temp1(struct device *dev,
+@@ -2018,11 +2080,86 @@ static ssize_t asus_hwmon_temp1(struct device *dev,
deci_kelvin_to_millicelsius(value & 0xFFFF));
}
+/* GPU fan on modern ROG laptops */
++static ssize_t fan2_input_show(struct device *dev,
++ struct device_attribute *attr,
++ char *buf)
++{
++ struct asus_wmi *asus = dev_get_drvdata(dev);
++ int value;
++ int ret;
++
++ ret = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_GPU_FAN_CTRL, &value);
++ if (ret < 0)
++ return ret;
++
++ value &= 0xffff;
++
++ return sysfs_emit(buf, "%d\n", value < 0 ? -1 : value * 100);
++}
++
++static ssize_t fan2_label_show(struct device *dev,
++ struct device_attribute *attr,
++ char *buf)
++{
++ return sprintf(buf, "%s\n", ASUS_GPU_FAN_DESC);
++}
++
+static ssize_t pwm2_enable_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
@@ -2262,29 +1049,49 @@ index ea45e10302f7..d05684194f2d 100644
/* Fan1 */
static DEVICE_ATTR_RW(pwm1);
static DEVICE_ATTR_RW(pwm1_enable);
-+static DEVICE_ATTR_RW(pwm2_enable);
static DEVICE_ATTR_RO(fan1_input);
static DEVICE_ATTR_RO(fan1_label);
++/* Fan2 - GPU fan */
++static DEVICE_ATTR_RW(pwm2_enable);
++static DEVICE_ATTR_RO(fan2_input);
++static DEVICE_ATTR_RO(fan2_label);
-@@ -2075,6 +2137,7 @@ static DEVICE_ATTR(temp1_input, S_IRUGO, asus_hwmon_temp1, NULL);
+ /* Temperature */
+ static DEVICE_ATTR(temp1_input, S_IRUGO, asus_hwmon_temp1, NULL);
+@@ -2030,8 +2167,11 @@ static DEVICE_ATTR(temp1_input, S_IRUGO, asus_hwmon_temp1, NULL);
static struct attribute *hwmon_attributes[] = {
&dev_attr_pwm1.attr,
&dev_attr_pwm1_enable.attr,
+ &dev_attr_pwm2_enable.attr,
&dev_attr_fan1_input.attr,
&dev_attr_fan1_label.attr,
++ &dev_attr_fan2_input.attr,
++ &dev_attr_fan2_label.attr,
+
+ &dev_attr_temp1_input.attr,
+ NULL
+@@ -2040,7 +2180,7 @@ static struct attribute *hwmon_attributes[] = {
+ static umode_t asus_hwmon_sysfs_is_visible(struct kobject *kobj,
+ struct attribute *attr, int idx)
+ {
+- struct device *dev = container_of(kobj, struct device, kobj);
++ struct device *dev = kobj_to_dev(kobj);
+ struct asus_wmi *asus = dev_get_drvdata(dev->parent);
+ u32 value = ASUS_WMI_UNSUPPORTED_METHOD;
-@@ -2097,6 +2160,9 @@ static umode_t asus_hwmon_sysfs_is_visible(struct kobject *kobj,
+@@ -2052,6 +2192,11 @@ static umode_t asus_hwmon_sysfs_is_visible(struct kobject *kobj,
|| attr == &dev_attr_pwm1_enable.attr) {
if (asus->fan_type == FAN_TYPE_NONE)
return 0;
-+ } else if (attr == &dev_attr_pwm2_enable.attr) {
++ } else if (attr == &dev_attr_fan2_input.attr
++ || attr == &dev_attr_fan2_label.attr
++ || attr == &dev_attr_pwm2_enable.attr) {
+ if (asus->gpu_fan_type == FAN_TYPE_NONE)
+ return 0;
} else if (attr == &dev_attr_temp1_input.attr) {
int err = asus_wmi_get_devstate(asus,
ASUS_WMI_DEVID_THERMAL_CTRL,
-@@ -2139,6 +2205,7 @@ static int asus_wmi_hwmon_init(struct asus_wmi *asus)
+@@ -2094,6 +2239,7 @@ static int asus_wmi_hwmon_init(struct asus_wmi *asus)
static int asus_wmi_fan_init(struct asus_wmi *asus)
{
@@ -2292,7 +1099,7 @@ index ea45e10302f7..d05684194f2d 100644
asus->fan_type = FAN_TYPE_NONE;
asus->agfn_pwm = -1;
-@@ -2147,6 +2214,10 @@ static int asus_wmi_fan_init(struct asus_wmi *asus)
+@@ -2102,6 +2248,10 @@ static int asus_wmi_fan_init(struct asus_wmi *asus)
else if (asus_wmi_has_agfn_fan(asus))
asus->fan_type = FAN_TYPE_AGFN;
@@ -2303,8 +1110,193 @@ index ea45e10302f7..d05684194f2d 100644
if (asus->fan_type == FAN_TYPE_NONE)
return -ENODEV;
+@@ -2192,7 +2342,7 @@ static ssize_t fan_boost_mode_show(struct device *dev,
+ {
+ struct asus_wmi *asus = dev_get_drvdata(dev);
+
+- return scnprintf(buf, PAGE_SIZE, "%d\n", asus->fan_boost_mode);
++ return sysfs_emit(buf, "%d\n", asus->fan_boost_mode);
+ }
+
+ static ssize_t fan_boost_mode_store(struct device *dev,
+@@ -2744,7 +2894,7 @@ static ssize_t throttle_thermal_policy_show(struct device *dev,
+ struct asus_wmi *asus = dev_get_drvdata(dev);
+ u8 mode = asus->throttle_thermal_policy_mode;
+
+- return scnprintf(buf, PAGE_SIZE, "%d\n", mode);
++ return sysfs_emit(buf, "%d\n", mode);
+ }
+
+ static ssize_t throttle_thermal_policy_store(struct device *dev,
+@@ -3096,9 +3246,7 @@ static void asus_wmi_handle_event_code(int code, struct asus_wmi *asus)
+ {
+ unsigned int key_value = 1;
+ bool autorelease = 1;
+- int result, orig_code;
+-
+- orig_code = code;
++ int orig_code = code;
+
+ if (asus->driver->key_filter) {
+ asus->driver->key_filter(asus->driver, &code, &key_value,
+@@ -3141,38 +3289,18 @@ static void asus_wmi_handle_event_code(int code, struct asus_wmi *asus)
+ return;
+ }
+
+- if (asus->driver->quirks->tablet_switch_mode == asus_wmi_kbd_dock_devid &&
+- code == NOTIFY_KBD_DOCK_CHANGE) {
+- result = asus_wmi_get_devstate_simple(asus,
+- ASUS_WMI_DEVID_KBD_DOCK);
+- if (result >= 0) {
+- input_report_switch(asus->inputdev, SW_TABLET_MODE,
+- !result);
+- input_sync(asus->inputdev);
+- }
+- return;
+- }
+-
+- if (asus->driver->quirks->tablet_switch_mode == asus_wmi_lid_flip_devid &&
+- code == NOTIFY_LID_FLIP) {
+- lid_flip_tablet_mode_get_state(asus);
+- return;
+- }
+-
+- if (asus->driver->quirks->tablet_switch_mode == asus_wmi_lid_flip_rog_devid &&
+- code == NOTIFY_LID_FLIP_ROG) {
+- lid_flip_rog_tablet_mode_get_state(asus);
++ if (code == asus->tablet_switch_event_code) {
++ asus_wmi_tablet_mode_get_state(asus);
+ return;
+ }
+
+- if (asus->fan_boost_mode_available && code == NOTIFY_KBD_FBM) {
+- fan_boost_mode_switch_next(asus);
++ if (code == NOTIFY_KBD_FBM || code == NOTIFY_KBD_TTP) {
++ if (asus->fan_boost_mode_available)
++ fan_boost_mode_switch_next(asus);
++ if (asus->throttle_thermal_policy_available)
++ throttle_thermal_policy_switch_next(asus);
+ return;
+- }
+
+- if (asus->throttle_thermal_policy_available && code == NOTIFY_KBD_TTP) {
+- throttle_thermal_policy_switch_next(asus);
+- return;
+ }
+
+ if (is_display_toggle(code) && asus->driver->quirks->no_display_toggle)
+@@ -3324,6 +3452,7 @@ static struct attribute *platform_attributes[] = {
+ &dev_attr_touchpad.attr,
+ &dev_attr_egpu_enable.attr,
+ &dev_attr_dgpu_disable.attr,
++ &dev_attr_gpu_mux_mode.attr,
+ &dev_attr_lid_resume.attr,
+ &dev_attr_als_enable.attr,
+ &dev_attr_fan_boost_mode.attr,
+@@ -3335,7 +3464,7 @@ static struct attribute *platform_attributes[] = {
+ static umode_t asus_sysfs_is_visible(struct kobject *kobj,
+ struct attribute *attr, int idx)
+ {
+- struct device *dev = container_of(kobj, struct device, kobj);
++ struct device *dev = kobj_to_dev(kobj);
+ struct asus_wmi *asus = dev_get_drvdata(dev);
+ bool ok = true;
+ int devid = -1;
+@@ -3354,6 +3483,10 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj,
+ ok = asus->egpu_enable_available;
+ else if (attr == &dev_attr_dgpu_disable.attr)
+ ok = asus->dgpu_disable_available;
++ else if (attr == &dev_attr_dgpu_disable.attr)
++ ok = asus->dgpu_disable_available;
++ else if (attr == &dev_attr_gpu_mux_mode.attr)
++ ok = asus->gpu_mux_mode_available;
+ else if (attr == &dev_attr_fan_boost_mode.attr)
+ ok = asus->fan_boost_mode_available;
+ else if (attr == &dev_attr_throttle_thermal_policy.attr)
+@@ -3615,13 +3748,12 @@ static int asus_wmi_add(struct platform_device *pdev)
+ if (err)
+ goto fail_platform;
+
+- err = egpu_enable_check_present(asus);
+- if (err)
+- goto fail_egpu_enable;
+-
+- err = dgpu_disable_check_present(asus);
+- if (err)
+- goto fail_dgpu_disable;
++ asus->egpu_enable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_EGPU);
++ asus->dgpu_disable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_DGPU);
++ asus->gpu_mux_mode_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_GPU_MUX);
++ asus->kbd_rgb_mode_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_MODE);
++ asus->kbd_rgb_state_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_STATE);
++ asus->panel_overdrive_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PANEL_OD);
+
+ err = fan_boost_mode_check_present(asus);
+ if (err)
+@@ -3637,10 +3769,6 @@ static int asus_wmi_add(struct platform_device *pdev)
+ if (err)
+ goto fail_platform_profile_setup;
+
+- err = panel_od_check_present(asus);
+- if (err)
+- goto fail_panel_od;
+-
+ err = asus_wmi_sysfs_init(asus->platform_device);
+ if (err)
+ goto fail_sysfs;
+@@ -3735,10 +3863,7 @@ static int asus_wmi_add(struct platform_device *pdev)
+ if (asus->platform_profile_support)
+ platform_profile_remove();
+ fail_fan_boost_mode:
+-fail_egpu_enable:
+-fail_dgpu_disable:
+ fail_platform:
+-fail_panel_od:
+ kfree(asus);
+ return err;
+ }
+@@ -3797,18 +3922,7 @@ static int asus_hotk_resume(struct device *device)
+ if (asus_wmi_has_fnlock_key(asus))
+ asus_wmi_fnlock_update(asus);
+
+- switch (asus->driver->quirks->tablet_switch_mode) {
+- case asus_wmi_no_tablet_switch:
+- case asus_wmi_kbd_dock_devid:
+- break;
+- case asus_wmi_lid_flip_devid:
+- lid_flip_tablet_mode_get_state(asus);
+- break;
+- case asus_wmi_lid_flip_rog_devid:
+- lid_flip_rog_tablet_mode_get_state(asus);
+- break;
+- }
+-
++ asus_wmi_tablet_mode_get_state(asus);
+ return 0;
+ }
+
+@@ -3848,18 +3962,7 @@ static int asus_hotk_restore(struct device *device)
+ if (asus_wmi_has_fnlock_key(asus))
+ asus_wmi_fnlock_update(asus);
+
+- switch (asus->driver->quirks->tablet_switch_mode) {
+- case asus_wmi_no_tablet_switch:
+- case asus_wmi_kbd_dock_devid:
+- break;
+- case asus_wmi_lid_flip_devid:
+- lid_flip_tablet_mode_get_state(asus);
+- break;
+- case asus_wmi_lid_flip_rog_devid:
+- lid_flip_rog_tablet_mode_get_state(asus);
+- break;
+- }
+-
++ asus_wmi_tablet_mode_get_state(asus);
+ return 0;
+ }
+
diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
-index 7dd580fdc61c..28234dc9fa6a 100644
+index 7c96db7f3060..28234dc9fa6a 100644
--- a/include/linux/platform_data/x86/asus-wmi.h
+++ b/include/linux/platform_data/x86/asus-wmi.h
@@ -79,6 +79,7 @@
@@ -2315,102 +1307,22 @@ index 7dd580fdc61c..28234dc9fa6a 100644
#define ASUS_WMI_DEVID_CPU_FAN_CURVE 0x00110024
#define ASUS_WMI_DEVID_GPU_FAN_CURVE 0x00110025
---
-2.37.2
-
-From ded47e7197a4ce9d6c34c0c96c6551ecaca0b6bd Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones" <luke@ljones.dev>
-Date: Fri, 16 Sep 2022 11:17:16 +1200
-Subject: [PATCH] asus-wmi: Expand support of GPU fan to read RPM and label
-
-The previously added patch to add support for pwm change for TUF laptops
-also is usuable for more than TUF. The same method `0x00110014` is
-used to read the fan RPM.
-
-Add two extra attributes for reading fan2 plus fan2 label.
-
-Signed-off-by: Luke D. Jones <luke@ljones.dev>
----
- drivers/platform/x86/asus-wmi.c | 36 +++++++++++++++++++++++++++++++--
- 1 file changed, 34 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
-index ae46af731de9..7fe6ce25da0a 100644
---- a/drivers/platform/x86/asus-wmi.c
-+++ b/drivers/platform/x86/asus-wmi.c
-@@ -72,6 +72,7 @@ module_param(fnlock_default, bool, 0444);
-
- #define ASUS_WMI_FNLOCK_BIOS_DISABLED BIT(0)
-
-+#define ASUS_GPU_FAN_DESC "gpu_fan"
- #define ASUS_FAN_DESC "cpu_fan"
- #define ASUS_FAN_MFUN 0x13
- #define ASUS_FAN_SFUN_READ 0x06
-@@ -2078,6 +2079,30 @@ static ssize_t asus_hwmon_temp1(struct device *dev,
- }
+@@ -100,6 +101,15 @@
+ /* dgpu on/off */
+ #define ASUS_WMI_DEVID_DGPU 0x00090020
- /* GPU fan on modern ROG laptops */
-+static ssize_t fan2_input_show(struct device *dev,
-+ struct device_attribute *attr,
-+ char *buf)
-+{
-+ struct asus_wmi *asus = dev_get_drvdata(dev);
-+ int value;
-+ int ret;
-+
-+ ret = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_GPU_FAN_CTRL, &value);
-+ if (ret < 0)
-+ return ret;
-+
-+ value &= 0xffff;
++/* gpu mux switch, 0 = dGPU, 1 = Optimus */
++#define ASUS_WMI_DEVID_GPU_MUX 0x00090016
+
-+ return sysfs_emit(buf, "%d\n", value < 0 ? -1 : value * 100);
-+}
++/* TUF laptop RGB modes/colours */
++#define ASUS_WMI_DEVID_TUF_RGB_MODE 0x00100056
+
-+static ssize_t fan2_label_show(struct device *dev,
-+ struct device_attribute *attr,
-+ char *buf)
-+{
-+ return sprintf(buf, "%s\n", ASUS_GPU_FAN_DESC);
-+}
++/* TUF laptop RGB power/state */
++#define ASUS_WMI_DEVID_TUF_RGB_STATE 0x00100057
+
- static ssize_t pwm2_enable_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-@@ -2127,9 +2152,12 @@ static ssize_t pwm2_enable_store(struct device *dev,
- /* Fan1 */
- static DEVICE_ATTR_RW(pwm1);
- static DEVICE_ATTR_RW(pwm1_enable);
--static DEVICE_ATTR_RW(pwm2_enable);
- static DEVICE_ATTR_RO(fan1_input);
- static DEVICE_ATTR_RO(fan1_label);
-+/* Fan2 - GPU fan */
-+static DEVICE_ATTR_RW(pwm2_enable);
-+static DEVICE_ATTR_RO(fan2_input);
-+static DEVICE_ATTR_RO(fan2_label);
-
- /* Temperature */
- static DEVICE_ATTR(temp1_input, S_IRUGO, asus_hwmon_temp1, NULL);
-@@ -2140,6 +2168,8 @@ static struct attribute *hwmon_attributes[] = {
- &dev_attr_pwm2_enable.attr,
- &dev_attr_fan1_input.attr,
- &dev_attr_fan1_label.attr,
-+ &dev_attr_fan2_input.attr,
-+ &dev_attr_fan2_label.attr,
-
- &dev_attr_temp1_input.attr,
- NULL
-@@ -2160,7 +2190,9 @@ static umode_t asus_hwmon_sysfs_is_visible(struct kobject *kobj,
- || attr == &dev_attr_pwm1_enable.attr) {
- if (asus->fan_type == FAN_TYPE_NONE)
- return 0;
-- } else if (attr == &dev_attr_pwm2_enable.attr) {
-+ } else if (attr == &dev_attr_fan2_input.attr
-+ || attr == &dev_attr_fan2_label.attr
-+ || attr == &dev_attr_pwm2_enable.attr) {
- if (asus->gpu_fan_type == FAN_TYPE_NONE)
- return 0;
- } else if (attr == &dev_attr_temp1_input.attr) {
+ /* DSTS masks */
+ #define ASUS_WMI_DSTS_STATUS_BIT 0x00000001
+ #define ASUS_WMI_DSTS_UNKNOWN_BIT 0x00000002
--
-2.37.3
+2.38.1