aboutsummaryrefslogtreecommitdiff
path: root/SOURCES/asus-linux.patch
diff options
context:
space:
mode:
Diffstat (limited to 'SOURCES/asus-linux.patch')
-rw-r--r--SOURCES/asus-linux.patch3890
1 files changed, 1023 insertions, 2867 deletions
diff --git a/SOURCES/asus-linux.patch b/SOURCES/asus-linux.patch
index 99985c0..d7817b7 100644
--- a/SOURCES/asus-linux.patch
+++ b/SOURCES/asus-linux.patch
@@ -1,1927 +1,140 @@
-From a120838990cea1397e9bacb303b41ab83fa76d8c Mon Sep 17 00:00:00 2001
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Luke D. Jones" <luke@ljones.dev>
Date: Sun, 10 Mar 2024 15:14:37 +1300
-Subject: [PATCH v4 1/9] platform/x86: asus-wmi: add support for 2024 ROG
- Mini-LED
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
+Subject: [PATCH] asus-linux
-Support the 2024 mini-led backlight and adjust the related functions
-to select the relevant dev-id. Also add `available_mini_led_mode` to the
-platform sysfs since the available mini-led levels can be different.
-
-Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
-signed-off-by: Luke D. Jones <luke@ljones.dev>
----
- .../ABI/testing/sysfs-platform-asus-wmi | 8 ++
- drivers/platform/x86/asus-wmi.c | 96 +++++++++++++++++--
- include/linux/platform_data/x86/asus-wmi.h | 1 +
- 3 files changed, 95 insertions(+), 10 deletions(-)
-
-diff --git a/Documentation/ABI/testing/sysfs-platform-asus-wmi b/Documentation/ABI/testing/sysfs-platform-asus-wmi
-index 8a7e25bde085..ef1ac1a20a71 100644
---- a/Documentation/ABI/testing/sysfs-platform-asus-wmi
-+++ b/Documentation/ABI/testing/sysfs-platform-asus-wmi
-@@ -126,6 +126,14 @@ Description:
- Change the mini-LED mode:
- * 0 - Single-zone,
- * 1 - Multi-zone
-+ * 2 - Multi-zone strong (available on newer generation mini-led)
-+
-+What: /sys/devices/platform/<platform>/available_mini_led_mode
-+Date: Apr 2024
-+KernelVersion: 6.10
-+Contact: "Luke Jones" <luke@ljones.dev>
-+Description:
-+ List the available mini-led modes.
-
- What: /sys/devices/platform/<platform>/ppt_pl1_spl
- Date: Jun 2023
-diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
-index 3f07bbf809ef..aa2a3b402e33 100644
---- a/drivers/platform/x86/asus-wmi.c
-+++ b/drivers/platform/x86/asus-wmi.c
-@@ -126,6 +126,17 @@ module_param(fnlock_default, bool, 0444);
- #define ASUS_SCREENPAD_BRIGHT_MAX 255
- #define ASUS_SCREENPAD_BRIGHT_DEFAULT 60
-
-+#define ASUS_MINI_LED_MODE_MASK 0x03
-+/* Standard modes for devices with only on/off */
-+#define ASUS_MINI_LED_OFF 0x00
-+#define ASUS_MINI_LED_ON 0x01
-+/* New mode on some devices, define here to clarify remapping later */
-+#define ASUS_MINI_LED_STRONG_MODE 0x02
-+/* New modes for devices with 3 mini-led mode types */
-+#define ASUS_MINI_LED_2024_WEAK 0x00
-+#define ASUS_MINI_LED_2024_STRONG 0x01
-+#define ASUS_MINI_LED_2024_OFF 0x02
-+
- /* Controls the power state of the USB0 hub on ROG Ally which input is on */
- #define ASUS_USB0_PWR_EC0_CSEE "\\_SB.PCI0.SBRG.EC0.CSEE"
- /* 300ms so far seems to produce a reliable result on AC and battery */
-@@ -288,7 +299,7 @@ struct asus_wmi {
- bool battery_rsoc_available;
-
- bool panel_overdrive_available;
-- bool mini_led_mode_available;
-+ u32 mini_led_dev_id;
-
- struct hotplug_slot hotplug_slot;
- struct mutex hotplug_lock;
-@@ -2108,13 +2119,33 @@ static ssize_t mini_led_mode_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- struct asus_wmi *asus = dev_get_drvdata(dev);
-- int result;
-+ u32 value;
-+ int err;
-
-- result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_MINI_LED_MODE);
-- if (result < 0)
-- return result;
-+ err = asus_wmi_get_devstate(asus, asus->mini_led_dev_id, &value);
-+ if (err < 0)
-+ return err;
-+ value = value & ASUS_MINI_LED_MODE_MASK;
-
-- return sysfs_emit(buf, "%d\n", result);
-+ /*
-+ * Remap the mode values to match previous generation mini-led. The last gen
-+ * WMI 0 == off, while on this version WMI 2 ==off (flipped).
-+ */
-+ if (asus->mini_led_dev_id == ASUS_WMI_DEVID_MINI_LED_MODE2) {
-+ switch (value) {
-+ case ASUS_MINI_LED_2024_WEAK:
-+ value = ASUS_MINI_LED_ON;
-+ break;
-+ case ASUS_MINI_LED_2024_STRONG:
-+ value = ASUS_MINI_LED_STRONG_MODE;
-+ break;
-+ case ASUS_MINI_LED_2024_OFF:
-+ value = ASUS_MINI_LED_OFF;
-+ break;
-+ }
-+ }
-+
-+ return sysfs_emit(buf, "%d\n", value);
- }
-
- static ssize_t mini_led_mode_store(struct device *dev,
-@@ -2130,11 +2161,32 @@ static ssize_t mini_led_mode_store(struct device *dev,
- if (result)
- return result;
-
-- if (mode > 1)
-+ if (asus->mini_led_dev_id == ASUS_WMI_DEVID_MINI_LED_MODE &&
-+ mode > ASUS_MINI_LED_ON)
-+ return -EINVAL;
-+ if (asus->mini_led_dev_id == ASUS_WMI_DEVID_MINI_LED_MODE2 &&
-+ mode > ASUS_MINI_LED_STRONG_MODE)
- return -EINVAL;
-
-- err = asus_wmi_set_devstate(ASUS_WMI_DEVID_MINI_LED_MODE, mode, &result);
-+ /*
-+ * Remap the mode values so expected behaviour is the same as the last
-+ * generation of mini-LED with 0 == off, 1 == on.
-+ */
-+ if (asus->mini_led_dev_id == ASUS_WMI_DEVID_MINI_LED_MODE2) {
-+ switch (mode) {
-+ case ASUS_MINI_LED_OFF:
-+ mode = ASUS_MINI_LED_2024_OFF;
-+ break;
-+ case ASUS_MINI_LED_ON:
-+ mode = ASUS_MINI_LED_2024_WEAK;
-+ break;
-+ case ASUS_MINI_LED_STRONG_MODE:
-+ mode = ASUS_MINI_LED_2024_STRONG;
-+ break;
-+ }
-+ }
-
-+ err = asus_wmi_set_devstate(asus->mini_led_dev_id, mode, &result);
- if (err) {
- pr_warn("Failed to set mini-LED: %d\n", err);
- return err;
-@@ -2151,6 +2203,23 @@ static ssize_t mini_led_mode_store(struct device *dev,
- }
- static DEVICE_ATTR_RW(mini_led_mode);
-
-+static ssize_t available_mini_led_mode_show(struct device *dev,
-+ struct device_attribute *attr, char *buf)
-+{
-+ struct asus_wmi *asus = dev_get_drvdata(dev);
-+
-+ switch (asus->mini_led_dev_id) {
-+ case ASUS_WMI_DEVID_MINI_LED_MODE:
-+ return sysfs_emit(buf, "0 1\n");
-+ case ASUS_WMI_DEVID_MINI_LED_MODE2:
-+ return sysfs_emit(buf, "0 1 2\n");
-+ }
-+
-+ return sysfs_emit(buf, "0\n");
-+}
-+
-+static DEVICE_ATTR_RO(available_mini_led_mode);
-+
- /* Quirks *********************************************************************/
-
- static void asus_wmi_set_xusb2pr(struct asus_wmi *asus)
-@@ -4139,6 +4208,7 @@ static struct attribute *platform_attributes[] = {
- &dev_attr_nv_temp_target.attr,
- &dev_attr_panel_od.attr,
- &dev_attr_mini_led_mode.attr,
-+ &dev_attr_available_mini_led_mode.attr,
- NULL
- };
-
-@@ -4191,7 +4261,9 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj,
- else if (attr == &dev_attr_panel_od.attr)
- ok = asus->panel_overdrive_available;
- else if (attr == &dev_attr_mini_led_mode.attr)
-- ok = asus->mini_led_mode_available;
-+ ok = asus->mini_led_dev_id != 0;
-+ else if (attr == &dev_attr_available_mini_led_mode.attr)
-+ ok = asus->mini_led_dev_id != 0;
-
- if (devid != -1)
- ok = !(asus_wmi_get_devstate_simple(asus, devid) < 0);
-@@ -4444,10 +4516,14 @@ static int asus_wmi_add(struct platform_device *pdev)
- asus->nv_dyn_boost_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_NV_DYN_BOOST);
- asus->nv_temp_tgt_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_NV_THERM_TARGET);
- asus->panel_overdrive_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PANEL_OD);
-- asus->mini_led_mode_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_MINI_LED_MODE);
- asus->ally_mcu_usb_switch = acpi_has_method(NULL, ASUS_USB0_PWR_EC0_CSEE)
- && dmi_match(DMI_BOARD_NAME, "RC71L");
-
-+ if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_MINI_LED_MODE))
-+ asus->mini_led_dev_id = ASUS_WMI_DEVID_MINI_LED_MODE;
-+ else if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_MINI_LED_MODE2))
-+ asus->mini_led_dev_id = ASUS_WMI_DEVID_MINI_LED_MODE2;
-+
- err = fan_boost_mode_check_present(asus);
- if (err)
- goto fail_fan_boost_mode;
-diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
-index ab1c7deff118..9cadce10ad9a 100644
---- a/include/linux/platform_data/x86/asus-wmi.h
-+++ b/include/linux/platform_data/x86/asus-wmi.h
-@@ -71,6 +71,7 @@
- #define ASUS_WMI_DEVID_LID_FLIP 0x00060062
- #define ASUS_WMI_DEVID_LID_FLIP_ROG 0x00060077
- #define ASUS_WMI_DEVID_MINI_LED_MODE 0x0005001E
-+#define ASUS_WMI_DEVID_MINI_LED_MODE2 0x0005002E
-
- /* Storage */
- #define ASUS_WMI_DEVID_CARDREADER 0x00080013
---
-2.44.0
-
-From b54d273cb1fddcf9ae2618447e23b9f62730e15f Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones" <luke@ljones.dev>
-Date: Sun, 10 Mar 2024 17:10:05 +1300
-Subject: [PATCH v4 2/9] platform/x86: asus-wmi: add support for Vivobook GPU
- MUX
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Add support for the Vivobook dgpu MUX available on the ASUS Viviobook
-and some of the other ranges (Zen).
-
-This MUX functions exactly the same as the existing ROG MUX support so
-the existing functionality now detects which MUX is available and uses
-that for control.
-
-Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
-Signed-off-by: Luke D. Jones <luke@ljones.dev>
----
- drivers/platform/x86/asus-wmi.c | 22 +++++++++++++---------
- include/linux/platform_data/x86/asus-wmi.h | 1 +
- 2 files changed, 14 insertions(+), 9 deletions(-)
-
-diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
-index aa2a3b402e33..1ab4380e9771 100644
---- a/drivers/platform/x86/asus-wmi.c
-+++ b/drivers/platform/x86/asus-wmi.c
-@@ -270,7 +270,7 @@ struct asus_wmi {
- bool egpu_enable_available;
- bool egpu_connect_available;
- bool dgpu_disable_available;
-- bool gpu_mux_mode_available;
-+ u32 gpu_mux_dev;
-
- /* Tunables provided by ASUS for gaming laptops */
- bool ppt_pl2_sppt_available;
-@@ -693,8 +693,8 @@ static ssize_t dgpu_disable_store(struct device *dev,
- if (disable > 1)
- return -EINVAL;
-
-- if (asus->gpu_mux_mode_available) {
-- result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_GPU_MUX);
-+ if (asus->gpu_mux_dev) {
-+ result = asus_wmi_get_devstate_simple(asus, asus->gpu_mux_dev);
- if (result < 0)
- /* An error here may signal greater failure of GPU handling */
- return result;
-@@ -759,8 +759,8 @@ static ssize_t egpu_enable_store(struct device *dev,
- return err;
- }
-
-- if (asus->gpu_mux_mode_available) {
-- result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_GPU_MUX);
-+ if (asus->gpu_mux_dev) {
-+ result = asus_wmi_get_devstate_simple(asus, asus->gpu_mux_dev);
- if (result < 0) {
- /* An error here may signal greater failure of GPU handling */
- pr_warn("Failed to get gpu mux status: %d\n", result);
-@@ -813,7 +813,7 @@ static ssize_t gpu_mux_mode_show(struct device *dev,
- struct asus_wmi *asus = dev_get_drvdata(dev);
- int result;
-
-- result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_GPU_MUX);
-+ result = asus_wmi_get_devstate_simple(asus, asus->gpu_mux_dev);
- if (result < 0)
- return result;
-
-@@ -859,7 +859,7 @@ static ssize_t gpu_mux_mode_store(struct device *dev,
- }
- }
-
-- err = asus_wmi_set_devstate(ASUS_WMI_DEVID_GPU_MUX, optimus, &result);
-+ err = asus_wmi_set_devstate(asus->gpu_mux_dev, optimus, &result);
- if (err) {
- dev_err(dev, "Failed to set GPU MUX mode: %d\n", err);
- return err;
-@@ -4239,7 +4239,7 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj,
- 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;
-+ ok = asus->gpu_mux_dev != 0;
- else if (attr == &dev_attr_fan_boost_mode.attr)
- ok = asus->fan_boost_mode_available;
- else if (attr == &dev_attr_throttle_thermal_policy.attr)
-@@ -4505,7 +4505,6 @@ static int asus_wmi_add(struct platform_device *pdev)
- asus->egpu_enable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_EGPU);
- asus->egpu_connect_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_EGPU_CONNECTED);
- 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->ppt_pl2_sppt_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PPT_PL2_SPPT);
-@@ -4524,6 +4523,11 @@ static int asus_wmi_add(struct platform_device *pdev)
- else if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_MINI_LED_MODE2))
- asus->mini_led_dev_id = ASUS_WMI_DEVID_MINI_LED_MODE2;
-
-+ if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_GPU_MUX))
-+ asus->gpu_mux_dev = ASUS_WMI_DEVID_GPU_MUX;
-+ else if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_GPU_MUX_VIVO))
-+ asus->gpu_mux_dev = ASUS_WMI_DEVID_GPU_MUX_VIVO;
-+
- err = fan_boost_mode_check_present(asus);
- if (err)
- goto fail_fan_boost_mode;
-diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
-index 9cadce10ad9a..b48b024dd844 100644
---- a/include/linux/platform_data/x86/asus-wmi.h
-+++ b/include/linux/platform_data/x86/asus-wmi.h
-@@ -128,6 +128,7 @@
-
- /* gpu mux switch, 0 = dGPU, 1 = Optimus */
- #define ASUS_WMI_DEVID_GPU_MUX 0x00090016
-+#define ASUS_WMI_DEVID_GPU_MUX_VIVO 0x00090026
-
- /* TUF laptop RGB modes/colours */
- #define ASUS_WMI_DEVID_TUF_RGB_MODE 0x00100056
---
-2.44.0
-
-From 3baa8b981e24bb1ae4e468085e89241a0439d259 Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones" <luke@ljones.dev>
-Date: Sun, 10 Mar 2024 17:20:02 +1300
-Subject: [PATCH v4 3/9] platform/x86: asus-wmi: add support variant of TUF RGB
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Adds support for a second TUF RGB wmi call that some versions of the TUF
-laptop come with. Also adjusts existing support to select whichever is
-available.
-
-Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
-Signed-off-by: Luke D. Jones <luke@ljones.dev>
----
- drivers/platform/x86/asus-wmi.c | 13 +++++++++----
- include/linux/platform_data/x86/asus-wmi.h | 1 +
- 2 files changed, 10 insertions(+), 4 deletions(-)
-
-diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
-index 1ab4380e9771..6896d056d227 100644
---- a/drivers/platform/x86/asus-wmi.c
-+++ b/drivers/platform/x86/asus-wmi.c
-@@ -281,7 +281,7 @@ struct asus_wmi {
- bool nv_dyn_boost_available;
- bool nv_temp_tgt_available;
-
-- bool kbd_rgb_mode_available;
-+ u32 kbd_rgb_dev;
- bool kbd_rgb_state_available;
-
- bool throttle_thermal_policy_available;
-@@ -881,6 +881,7 @@ static ssize_t kbd_rgb_mode_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
- {
-+ struct asus_wmi *asus = dev_get_drvdata(dev);
- u32 cmd, mode, r, g, b, speed;
- int err;
-
-@@ -917,7 +918,7 @@ static ssize_t kbd_rgb_mode_store(struct device *dev,
- speed = 0xeb;
- }
-
-- err = asus_wmi_evaluate_method3(ASUS_WMI_METHODID_DEVS, ASUS_WMI_DEVID_TUF_RGB_MODE,
-+ err = asus_wmi_evaluate_method3(ASUS_WMI_METHODID_DEVS, asus->kbd_rgb_dev,
- cmd | (mode << 8) | (r << 16) | (g << 24), b | (speed << 8), NULL);
- if (err)
- return err;
-@@ -1560,7 +1561,7 @@ static int asus_wmi_led_init(struct asus_wmi *asus)
- {
- int rv = 0, num_rgb_groups = 0, led_val;
-
-- if (asus->kbd_rgb_mode_available)
-+ if (asus->kbd_rgb_dev)
- 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;
-@@ -4505,7 +4506,6 @@ static int asus_wmi_add(struct platform_device *pdev)
- asus->egpu_enable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_EGPU);
- asus->egpu_connect_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_EGPU_CONNECTED);
- asus->dgpu_disable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_DGPU);
-- 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->ppt_pl2_sppt_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PPT_PL2_SPPT);
- asus->ppt_pl1_spl_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PPT_PL1_SPL);
-@@ -4528,6 +4528,11 @@ static int asus_wmi_add(struct platform_device *pdev)
- else if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_GPU_MUX_VIVO))
- asus->gpu_mux_dev = ASUS_WMI_DEVID_GPU_MUX_VIVO;
-
-+ if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_MODE))
-+ asus->kbd_rgb_dev = ASUS_WMI_DEVID_TUF_RGB_MODE;
-+ else if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_MODE2))
-+ asus->kbd_rgb_dev = ASUS_WMI_DEVID_TUF_RGB_MODE2;
-+
- err = fan_boost_mode_check_present(asus);
- if (err)
- goto fail_fan_boost_mode;
-diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
-index b48b024dd844..3e9a01467c67 100644
---- a/include/linux/platform_data/x86/asus-wmi.h
-+++ b/include/linux/platform_data/x86/asus-wmi.h
-@@ -132,6 +132,7 @@
-
- /* TUF laptop RGB modes/colours */
- #define ASUS_WMI_DEVID_TUF_RGB_MODE 0x00100056
-+#define ASUS_WMI_DEVID_TUF_RGB_MODE2 0x0010005A
-
- /* TUF laptop RGB power/state */
- #define ASUS_WMI_DEVID_TUF_RGB_STATE 0x00100057
---
-2.44.0
-
-From 37f3b097a3f245ab8a12befd37e2d76ed6ebf85f Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones" <luke@ljones.dev>
-Date: Sun, 10 Mar 2024 19:03:11 +1300
-Subject: [PATCH v4 4/9] platform/x86: asus-wmi: support toggling POST sound
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Add support for toggling the BIOS POST sound on some ASUS laptops.
-
-Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
-Signed-off-by: Luke D. Jones <luke@ljones.dev>
+Signed-off-by: Jan200101 <sentrycraft123@gmail.com>
---
- .../ABI/testing/sysfs-platform-asus-wmi | 9 ++++
- drivers/platform/x86/asus-wmi.c | 51 +++++++++++++++++++
- include/linux/platform_data/x86/asus-wmi.h | 3 ++
- 3 files changed, 63 insertions(+)
+ .../ABI/testing/sysfs-platform-asus-wmi | 23 +-
+ drivers/hid/hid-asus.c | 7 +
+ drivers/hid/hid-ids.h | 1 +
+ drivers/platform/x86/Kconfig | 14 +
+ drivers/platform/x86/Makefile | 1 +
+ drivers/platform/x86/asus-bios.c | 983 ++++++++++++++++++
+ drivers/platform/x86/asus-bios.h | 288 +++++
+ drivers/platform/x86/asus-wmi.c | 754 +++++++-------
+ include/linux/platform_data/x86/asus-wmi.h | 65 ++
+ 9 files changed, 1735 insertions(+), 401 deletions(-)
+ create mode 100644 drivers/platform/x86/asus-bios.c
+ create mode 100644 drivers/platform/x86/asus-bios.h
diff --git a/Documentation/ABI/testing/sysfs-platform-asus-wmi b/Documentation/ABI/testing/sysfs-platform-asus-wmi
-index ef1ac1a20a71..72933527d2e4 100644
+index 28144371a0f1..984a04f32fd0 100644
--- a/Documentation/ABI/testing/sysfs-platform-asus-wmi
+++ b/Documentation/ABI/testing/sysfs-platform-asus-wmi
-@@ -194,3 +194,12 @@ Contact: "Luke Jones" <luke@ljones.dev>
+@@ -142,8 +142,8 @@ Contact: "Luke Jones" <luke@ljones.dev>
Description:
- Set the target temperature limit of the Nvidia dGPU:
- * min=75, max=87
-+
-+What: /sys/devices/platform/<platform>/boot_sound
-+Date: Apr 2024
-+KernelVersion: 6.10
-+Contact: "Luke Jones" <luke@ljones.dev>
-+Description:
-+ Set if the BIOS POST sound is played on boot.
-+ * 0 - False,
-+ * 1 - True
-diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
-index 6896d056d227..6c353b8e8da9 100644
---- a/drivers/platform/x86/asus-wmi.c
-+++ b/drivers/platform/x86/asus-wmi.c
-@@ -2115,6 +2115,54 @@ static ssize_t panel_od_store(struct device *dev,
- }
- static DEVICE_ATTR_RW(panel_od);
-
-+/* Bootup sound ***************************************************************/
-+
-+static ssize_t boot_sound_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_BOOT_SOUND);
-+ if (result < 0)
-+ return result;
-+
-+ return sysfs_emit(buf, "%d\n", result);
-+}
-+
-+static ssize_t boot_sound_store(struct device *dev,
-+ struct device_attribute *attr,
-+ const char *buf, size_t count)
-+{
-+ int result, err;
-+ u32 snd;
-+
-+ struct asus_wmi *asus = dev_get_drvdata(dev);
-+
-+ result = kstrtou32(buf, 10, &snd);
-+ if (result)
-+ return result;
-+
-+ if (snd > 1)
-+ return -EINVAL;
-+
-+ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_BOOT_SOUND, snd, &result);
-+ if (err) {
-+ pr_warn("Failed to set boot sound: %d\n", err);
-+ return err;
-+ }
-+
-+ if (result > 1) {
-+ pr_warn("Failed to set panel boot sound (result): 0x%x\n", result);
-+ return -EIO;
-+ }
-+
-+ sysfs_notify(&asus->platform_device->dev.kobj, NULL, "boot_sound");
-+
-+ return count;
-+}
-+static DEVICE_ATTR_RW(boot_sound);
-+
- /* Mini-LED mode **************************************************************/
- static ssize_t mini_led_mode_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-@@ -4207,6 +4255,7 @@ static struct attribute *platform_attributes[] = {
- &dev_attr_ppt_platform_sppt.attr,
- &dev_attr_nv_dynamic_boost.attr,
- &dev_attr_nv_temp_target.attr,
-+ &dev_attr_boot_sound.attr,
- &dev_attr_panel_od.attr,
- &dev_attr_mini_led_mode.attr,
- &dev_attr_available_mini_led_mode.attr,
-@@ -4259,6 +4308,8 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj,
- ok = asus->nv_dyn_boost_available;
- else if (attr == &dev_attr_nv_temp_target.attr)
- ok = asus->nv_temp_tgt_available;
-+ else if (attr == &dev_attr_boot_sound.attr)
-+ devid = ASUS_WMI_DEVID_BOOT_SOUND;
- else if (attr == &dev_attr_panel_od.attr)
- ok = asus->panel_overdrive_available;
- else if (attr == &dev_attr_mini_led_mode.attr)
-diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
-index 3e9a01467c67..3eb5cd6773ad 100644
---- a/include/linux/platform_data/x86/asus-wmi.h
-+++ b/include/linux/platform_data/x86/asus-wmi.h
-@@ -137,6 +137,9 @@
- /* TUF laptop RGB power/state */
- #define ASUS_WMI_DEVID_TUF_RGB_STATE 0x00100057
-
-+/* Bootup sound control */
-+#define ASUS_WMI_DEVID_BOOT_SOUND 0x00130022
-+
- /* DSTS masks */
- #define ASUS_WMI_DSTS_STATUS_BIT 0x00000001
- #define ASUS_WMI_DSTS_UNKNOWN_BIT 0x00000002
---
-2.44.0
-
-From eea03ef05c38fe9bfd8653b13b870bb8f96fe41d Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones" <luke@ljones.dev>
-Date: Mon, 11 Mar 2024 12:15:46 +1300
-Subject: [PATCH v4 5/9] platform/x86: asus-wmi: store a min default for ppt
- options
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Laptops with any of the ppt or nv tunables default to the minimum setting
-on boot so we can safely assume a stored value is correct.
-
-This patch adds storing of those values in the local struct, and enables
-reading of those values back. To prevent creating a series of byte holes
-in the struct the "<name>_available" bool is removed and
-`asus_sysfs_is_visible()` uses the `ASUS_WMI_DEVID_<name>` directly.
-
-Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
-Signed-off-by: Luke D. Jones <luke@ljones.dev>
----
- drivers/platform/x86/asus-wmi.c | 127 +++++++++++++++++++++++++-------
- 1 file changed, 99 insertions(+), 28 deletions(-)
-
-diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
-index 6c353b8e8da9..f13606fc62e6 100644
---- a/drivers/platform/x86/asus-wmi.c
-+++ b/drivers/platform/x86/asus-wmi.c
-@@ -273,13 +273,13 @@ struct asus_wmi {
- u32 gpu_mux_dev;
-
- /* Tunables provided by ASUS for gaming laptops */
-- bool ppt_pl2_sppt_available;
-- bool ppt_pl1_spl_available;
-- bool ppt_apu_sppt_available;
-- bool ppt_plat_sppt_available;
-- bool ppt_fppt_available;
-- bool nv_dyn_boost_available;
-- bool nv_temp_tgt_available;
-+ u32 ppt_pl2_sppt;
-+ u32 ppt_pl1_spl;
-+ u32 ppt_apu_sppt;
-+ u32 ppt_platform_sppt;
-+ u32 ppt_fppt;
-+ u32 nv_dynamic_boost;
-+ u32 nv_temp_target;
-
- u32 kbd_rgb_dev;
- bool kbd_rgb_state_available;
-@@ -1031,11 +1031,21 @@ static ssize_t ppt_pl2_sppt_store(struct device *dev,
- return -EIO;
- }
-
-+ asus->ppt_pl2_sppt = value;
- sysfs_notify(&asus->platform_device->dev.kobj, NULL, "ppt_pl2_sppt");
-
- return count;
- }
--static DEVICE_ATTR_WO(ppt_pl2_sppt);
-+
-+static ssize_t ppt_pl2_sppt_show(struct device *dev,
-+ struct device_attribute *attr,
-+ char *buf)
-+{
-+ struct asus_wmi *asus = dev_get_drvdata(dev);
-+
-+ return sysfs_emit(buf, "%u\n", asus->ppt_pl2_sppt);
-+}
-+static DEVICE_ATTR_RW(ppt_pl2_sppt);
-
- /* Tunable: PPT, Intel=PL1, AMD=SPL ******************************************/
- static ssize_t ppt_pl1_spl_store(struct device *dev,
-@@ -1065,11 +1075,20 @@ static ssize_t ppt_pl1_spl_store(struct device *dev,
- return -EIO;
- }
-
-+ asus->ppt_pl1_spl = value;
- sysfs_notify(&asus->platform_device->dev.kobj, NULL, "ppt_pl1_spl");
-
- return count;
- }
--static DEVICE_ATTR_WO(ppt_pl1_spl);
-+static ssize_t ppt_pl1_spl_show(struct device *dev,
-+ struct device_attribute *attr,
-+ char *buf)
-+{
-+ struct asus_wmi *asus = dev_get_drvdata(dev);
-+
-+ return sysfs_emit(buf, "%u\n", asus->ppt_pl1_spl);
-+}
-+static DEVICE_ATTR_RW(ppt_pl1_spl);
-
- /* Tunable: PPT APU FPPT ******************************************************/
- static ssize_t ppt_fppt_store(struct device *dev,
-@@ -1099,11 +1118,21 @@ static ssize_t ppt_fppt_store(struct device *dev,
- return -EIO;
- }
-
-+ asus->ppt_fppt = value;
- sysfs_notify(&asus->platform_device->dev.kobj, NULL, "ppt_fpu_sppt");
-
- return count;
- }
--static DEVICE_ATTR_WO(ppt_fppt);
-+
-+static ssize_t ppt_fppt_show(struct device *dev,
-+ struct device_attribute *attr,
-+ char *buf)
-+{
-+ struct asus_wmi *asus = dev_get_drvdata(dev);
-+
-+ return sysfs_emit(buf, "%u\n", asus->ppt_fppt);
-+}
-+static DEVICE_ATTR_RW(ppt_fppt);
-
- /* Tunable: PPT APU SPPT *****************************************************/
- static ssize_t ppt_apu_sppt_store(struct device *dev,
-@@ -1133,11 +1162,21 @@ static ssize_t ppt_apu_sppt_store(struct device *dev,
- return -EIO;
- }
-
-+ asus->ppt_apu_sppt = value;
- sysfs_notify(&asus->platform_device->dev.kobj, NULL, "ppt_apu_sppt");
-
- return count;
- }
--static DEVICE_ATTR_WO(ppt_apu_sppt);
-+
-+static ssize_t ppt_apu_sppt_show(struct device *dev,
-+ struct device_attribute *attr,
-+ char *buf)
-+{
-+ struct asus_wmi *asus = dev_get_drvdata(dev);
-+
-+ return sysfs_emit(buf, "%u\n", asus->ppt_apu_sppt);
-+}
-+static DEVICE_ATTR_RW(ppt_apu_sppt);
-
- /* Tunable: PPT platform SPPT ************************************************/
- static ssize_t ppt_platform_sppt_store(struct device *dev,
-@@ -1167,11 +1206,21 @@ static ssize_t ppt_platform_sppt_store(struct device *dev,
- return -EIO;
- }
-
-+ asus->ppt_platform_sppt = value;
- sysfs_notify(&asus->platform_device->dev.kobj, NULL, "ppt_platform_sppt");
-
- return count;
- }
--static DEVICE_ATTR_WO(ppt_platform_sppt);
-+
-+static ssize_t ppt_platform_sppt_show(struct device *dev,
-+ struct device_attribute *attr,
-+ char *buf)
-+{
-+ struct asus_wmi *asus = dev_get_drvdata(dev);
-+
-+ return sysfs_emit(buf, "%u\n", asus->ppt_platform_sppt);
-+}
-+static DEVICE_ATTR_RW(ppt_platform_sppt);
-
- /* Tunable: NVIDIA dynamic boost *********************************************/
- static ssize_t nv_dynamic_boost_store(struct device *dev,
-@@ -1201,11 +1250,21 @@ static ssize_t nv_dynamic_boost_store(struct device *dev,
- return -EIO;
- }
-
-+ asus->nv_dynamic_boost = value;
- sysfs_notify(&asus->platform_device->dev.kobj, NULL, "nv_dynamic_boost");
-
- return count;
- }
--static DEVICE_ATTR_WO(nv_dynamic_boost);
-+
-+static ssize_t nv_dynamic_boost_show(struct device *dev,
-+ struct device_attribute *attr,
-+ char *buf)
-+{
-+ struct asus_wmi *asus = dev_get_drvdata(dev);
-+
-+ return sysfs_emit(buf, "%u\n", asus->nv_dynamic_boost);
-+}
-+static DEVICE_ATTR_RW(nv_dynamic_boost);
-
- /* Tunable: NVIDIA temperature target ****************************************/
- static ssize_t nv_temp_target_store(struct device *dev,
-@@ -1235,11 +1294,21 @@ static ssize_t nv_temp_target_store(struct device *dev,
- return -EIO;
- }
-
-+ asus->nv_temp_target = value;
- sysfs_notify(&asus->platform_device->dev.kobj, NULL, "nv_temp_target");
-
- return count;
- }
--static DEVICE_ATTR_WO(nv_temp_target);
-+
-+static ssize_t nv_temp_target_show(struct device *dev,
-+ struct device_attribute *attr,
-+ char *buf)
-+{
-+ struct asus_wmi *asus = dev_get_drvdata(dev);
-+
-+ return sysfs_emit(buf, "%u\n", asus->nv_temp_target);
-+}
-+static DEVICE_ATTR_RW(nv_temp_target);
-
- /* Battery ********************************************************************/
-
-@@ -4295,19 +4364,19 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj,
- else if (attr == &dev_attr_throttle_thermal_policy.attr)
- ok = asus->throttle_thermal_policy_available;
- else if (attr == &dev_attr_ppt_pl2_sppt.attr)
-- ok = asus->ppt_pl2_sppt_available;
-+ devid = ASUS_WMI_DEVID_PPT_PL2_SPPT;
- else if (attr == &dev_attr_ppt_pl1_spl.attr)
-- ok = asus->ppt_pl1_spl_available;
-+ devid = ASUS_WMI_DEVID_PPT_PL1_SPL;
- else if (attr == &dev_attr_ppt_fppt.attr)
-- ok = asus->ppt_fppt_available;
-+ devid = ASUS_WMI_DEVID_PPT_FPPT;
- else if (attr == &dev_attr_ppt_apu_sppt.attr)
-- ok = asus->ppt_apu_sppt_available;
-+ devid = ASUS_WMI_DEVID_PPT_APU_SPPT;
- else if (attr == &dev_attr_ppt_platform_sppt.attr)
-- ok = asus->ppt_plat_sppt_available;
-+ devid = ASUS_WMI_DEVID_PPT_PLAT_SPPT;
- else if (attr == &dev_attr_nv_dynamic_boost.attr)
-- ok = asus->nv_dyn_boost_available;
-+ devid = ASUS_WMI_DEVID_NV_DYN_BOOST;
- else if (attr == &dev_attr_nv_temp_target.attr)
-- ok = asus->nv_temp_tgt_available;
-+ devid = ASUS_WMI_DEVID_NV_THERM_TARGET;
- else if (attr == &dev_attr_boot_sound.attr)
- devid = ASUS_WMI_DEVID_BOOT_SOUND;
- else if (attr == &dev_attr_panel_od.attr)
-@@ -4553,18 +4622,20 @@ static int asus_wmi_add(struct platform_device *pdev)
- if (err)
- goto fail_platform;
-
-+ /* ensure defaults for tunables */
-+ asus->ppt_pl2_sppt = 5;
-+ asus->ppt_pl1_spl = 5;
-+ asus->ppt_apu_sppt = 5;
-+ asus->ppt_platform_sppt = 5;
-+ asus->ppt_fppt = 5;
-+ asus->nv_dynamic_boost = 5;
-+ asus->nv_temp_target = 75;
-+
- asus->charge_mode_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_CHARGE_MODE);
- asus->egpu_enable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_EGPU);
- asus->egpu_connect_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_EGPU_CONNECTED);
- asus->dgpu_disable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_DGPU);
- asus->kbd_rgb_state_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_STATE);
-- asus->ppt_pl2_sppt_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PPT_PL2_SPPT);
-- asus->ppt_pl1_spl_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PPT_PL1_SPL);
-- asus->ppt_fppt_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PPT_FPPT);
-- asus->ppt_apu_sppt_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PPT_APU_SPPT);
-- asus->ppt_plat_sppt_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PPT_PLAT_SPPT);
-- asus->nv_dyn_boost_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_NV_DYN_BOOST);
-- asus->nv_temp_tgt_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_NV_THERM_TARGET);
- asus->panel_overdrive_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PANEL_OD);
- asus->ally_mcu_usb_switch = acpi_has_method(NULL, ASUS_USB0_PWR_EC0_CSEE)
- && dmi_match(DMI_BOARD_NAME, "RC71L");
---
-2.44.0
-
-From 43355f0d9ba2d6e9ef791c0fe5efbbff872d05ac Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones" <luke@ljones.dev>
-Date: Mon, 25 Mar 2024 16:20:57 +1300
-Subject: [PATCH v4 6/9] platform/x86: asus-wmi: adjust formatting of
- ppt-<name>() functions
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Shift the call to dev_get_drvdata() up to top of the function block
-in all of the ppt_<name>() functions as part of a minor cleanup.
-
-Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
-Signed-off-by: Luke D. Jones <luke@ljones.dev>
----
- drivers/platform/x86/asus-wmi.c | 21 +++++++--------------
- 1 file changed, 7 insertions(+), 14 deletions(-)
-
-diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
-index f13606fc62e6..976e26c82f80 100644
---- a/drivers/platform/x86/asus-wmi.c
-+++ b/drivers/platform/x86/asus-wmi.c
-@@ -1008,11 +1008,10 @@ static ssize_t ppt_pl2_sppt_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 value;
-
-- struct asus_wmi *asus = dev_get_drvdata(dev);
--
- result = kstrtou32(buf, 10, &value);
- if (result)
- return result;
-@@ -1052,11 +1051,10 @@ static ssize_t ppt_pl1_spl_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 value;
-
-- struct asus_wmi *asus = dev_get_drvdata(dev);
--
- result = kstrtou32(buf, 10, &value);
- if (result)
- return result;
-@@ -1095,11 +1093,10 @@ static ssize_t ppt_fppt_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 value;
-
-- struct asus_wmi *asus = dev_get_drvdata(dev);
--
- result = kstrtou32(buf, 10, &value);
- if (result)
- return result;
-@@ -1139,11 +1136,10 @@ static ssize_t ppt_apu_sppt_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 value;
-
-- struct asus_wmi *asus = dev_get_drvdata(dev);
--
- result = kstrtou32(buf, 10, &value);
- if (result)
- return result;
-@@ -1183,11 +1179,10 @@ static ssize_t ppt_platform_sppt_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 value;
-
-- struct asus_wmi *asus = dev_get_drvdata(dev);
--
- result = kstrtou32(buf, 10, &value);
- if (result)
- return result;
-@@ -1227,11 +1222,10 @@ static ssize_t nv_dynamic_boost_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 value;
-
-- struct asus_wmi *asus = dev_get_drvdata(dev);
--
- result = kstrtou32(buf, 10, &value);
- if (result)
- return result;
-@@ -1271,11 +1265,10 @@ static ssize_t nv_temp_target_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 value;
-
-- struct asus_wmi *asus = dev_get_drvdata(dev);
--
- result = kstrtou32(buf, 10, &value);
- if (result)
- return result;
---
-2.44.0
-
-From 4f772c2affe17d50c791d61c72662df81b18884a Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones" <luke@ljones.dev>
-Date: Mon, 25 Mar 2024 11:14:28 +1300
-Subject: [PATCH v4 7/9] platform/x86: asus-wmi: ROG Ally increase wait time,
- allow MCU powersave
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The previous work to allow the MCU to be resumed correctly after sleep
-and resume tried to take the shortest possible time. However as work
-continues in various other parts of the s2idle subsystems it has shown
-that it wasn't entirely reliable.
-
-If the MCU disable/enable call is done correctly the MCU fully removes
-its USB endpoints, and this shows as a full USB device reconnection on
-resume. When we tried to short this as much as possible sometimes the
-MCU doesn't get to complete what it needs to do before going to low-power
-and this affected the reconnection.
-
-Through trial it is found that the minimum time required is approx 1200ms
-to allow a proper disconnect and disable, and the same amount of time on
-resume is required to prevent a rapid disconnect/reconnect happening on
-seemingly random occasions. To be safe the time is now 1500ms for msleep.
-
-Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
-Signed-off-by: Luke D. Jones <luke@ljones.dev>
----
- drivers/platform/x86/asus-wmi.c | 12 ++----------
- 1 file changed, 2 insertions(+), 10 deletions(-)
-
-diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
-index 976e26c82f80..ab98f91e573c 100644
---- a/drivers/platform/x86/asus-wmi.c
-+++ b/drivers/platform/x86/asus-wmi.c
-@@ -140,7 +140,7 @@ module_param(fnlock_default, bool, 0444);
- /* Controls the power state of the USB0 hub on ROG Ally which input is on */
- #define ASUS_USB0_PWR_EC0_CSEE "\\_SB.PCI0.SBRG.EC0.CSEE"
- /* 300ms so far seems to produce a reliable result on AC and battery */
--#define ASUS_USB0_PWR_EC0_CSEE_WAIT 300
-+#define ASUS_USB0_PWR_EC0_CSEE_WAIT 1500
-
- static const char * const ashs_ids[] = { "ATK4001", "ATK4002", NULL };
-
-@@ -4829,6 +4829,7 @@ static int asus_hotk_resume_early(struct device *device)
- struct asus_wmi *asus = dev_get_drvdata(device);
-
- if (asus->ally_mcu_usb_switch) {
-+ /* sleep required to prevent USB0 being yanked then reappearing rapidly */
- if (ACPI_FAILURE(acpi_execute_simple_method(NULL, ASUS_USB0_PWR_EC0_CSEE, 0xB8)))
- dev_err(device, "ROG Ally MCU failed to connect USB dev\n");
- else
-@@ -4840,17 +4841,8 @@ static int asus_hotk_resume_early(struct device *device)
- static int asus_hotk_prepare(struct device *device)
- {
- struct asus_wmi *asus = dev_get_drvdata(device);
-- int result, err;
-
- if (asus->ally_mcu_usb_switch) {
-- /* When powersave is enabled it causes many issues with resume of USB hub */
-- result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_MCU_POWERSAVE);
-- if (result == 1) {
-- dev_warn(device, "MCU powersave enabled, disabling to prevent resume issues");
-- err = asus_wmi_set_devstate(ASUS_WMI_DEVID_MCU_POWERSAVE, 0, &result);
-- if (err || result != 1)
-- dev_err(device, "Failed to set MCU powersave mode: %d\n", err);
-- }
- /* sleep required to ensure USB0 is disabled before sleep continues */
- if (ACPI_FAILURE(acpi_execute_simple_method(NULL, ASUS_USB0_PWR_EC0_CSEE, 0xB7)))
- dev_err(device, "ROG Ally MCU failed to disconnect USB dev\n");
---
-2.44.0
-
-From 67529648f99081e63e66c831d2644181ca314c86 Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones" <luke@ljones.dev>
-Date: Mon, 25 Mar 2024 16:43:12 +1300
-Subject: [PATCH v4 8/9] platform/x86: asus-wmi: Add support for MCU powersave
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Add support for an MCU powersave WMI call. This is intended to set the
-MCU in to a low-power mode when sleeping. This mode can cut sleep power
-use by around half.
-
-Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
-Signed-off-by: Luke D. Jones <luke@ljones.dev>
----
- .../ABI/testing/sysfs-platform-asus-wmi | 9 ++++
- drivers/platform/x86/asus-wmi.c | 50 +++++++++++++++++++
- 2 files changed, 59 insertions(+)
-
-diff --git a/Documentation/ABI/testing/sysfs-platform-asus-wmi b/Documentation/ABI/testing/sysfs-platform-asus-wmi
-index 72933527d2e4..28144371a0f1 100644
---- a/Documentation/ABI/testing/sysfs-platform-asus-wmi
-+++ b/Documentation/ABI/testing/sysfs-platform-asus-wmi
-@@ -203,3 +203,12 @@ Description:
- Set if the BIOS POST sound is played on boot.
- * 0 - False,
- * 1 - True
-+
-+What: /sys/devices/platform/<platform>/mcu_powersave
-+Date: Apr 2024
-+KernelVersion: 6.10
-+Contact: "Luke Jones" <luke@ljones.dev>
-+Description:
-+ Set if the MCU can go in to low-power mode on system sleep
-+ * 0 - False,
-+ * 1 - True
-diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
-index ab98f91e573c..d06d9e0c498c 100644
---- a/drivers/platform/x86/asus-wmi.c
-+++ b/drivers/platform/x86/asus-wmi.c
-@@ -1303,6 +1303,53 @@ static ssize_t nv_temp_target_show(struct device *dev,
- }
- static DEVICE_ATTR_RW(nv_temp_target);
-
-+/* Ally MCU Powersave ********************************************************/
-+static ssize_t mcu_powersave_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_MCU_POWERSAVE);
-+ if (result < 0)
-+ return result;
-+
-+ return sysfs_emit(buf, "%d\n", result);
-+}
-+
-+static ssize_t mcu_powersave_store(struct device *dev,
-+ struct device_attribute *attr,
-+ const char *buf, size_t count)
-+{
-+ int result, err;
-+ u32 enable;
-+
-+ struct asus_wmi *asus = dev_get_drvdata(dev);
-+
-+ result = kstrtou32(buf, 10, &enable);
-+ if (result)
-+ return result;
-+
-+ if (enable > 1)
-+ return -EINVAL;
-+
-+ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_MCU_POWERSAVE, enable, &result);
-+ if (err) {
-+ pr_warn("Failed to set MCU powersave: %d\n", err);
-+ return err;
-+ }
-+
-+ if (result > 1) {
-+ pr_warn("Failed to set MCU powersave (result): 0x%x\n", result);
-+ return -EIO;
-+ }
-+
-+ sysfs_notify(&asus->platform_device->dev.kobj, NULL, "mcu_powersave");
-+
-+ return count;
-+}
-+static DEVICE_ATTR_RW(mcu_powersave);
-+
- /* Battery ********************************************************************/
-
- /* The battery maximum charging percentage */
-@@ -4317,6 +4364,7 @@ static struct attribute *platform_attributes[] = {
- &dev_attr_ppt_platform_sppt.attr,
- &dev_attr_nv_dynamic_boost.attr,
- &dev_attr_nv_temp_target.attr,
-+ &dev_attr_mcu_powersave.attr,
- &dev_attr_boot_sound.attr,
- &dev_attr_panel_od.attr,
- &dev_attr_mini_led_mode.attr,
-@@ -4370,6 +4418,8 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj,
- devid = ASUS_WMI_DEVID_NV_DYN_BOOST;
- else if (attr == &dev_attr_nv_temp_target.attr)
- devid = ASUS_WMI_DEVID_NV_THERM_TARGET;
-+ else if (attr == &dev_attr_mcu_powersave.attr)
-+ devid = ASUS_WMI_DEVID_MCU_POWERSAVE;
- else if (attr == &dev_attr_boot_sound.attr)
- devid = ASUS_WMI_DEVID_BOOT_SOUND;
- else if (attr == &dev_attr_panel_od.attr)
---
-2.44.0
-
-From fb8027a2ca91fff199a21300ca2d2afaf264e1d3 Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones" <luke@ljones.dev>
-Date: Mon, 25 Mar 2024 17:14:00 +1300
-Subject: [PATCH v4 9/9] platform/x86: asus-wmi: cleanup main struct to avoid
- some holes
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Reorganises some attr-available calls to remove a few unrequired
-booleans in the main driver struct which combined with some
-reorganisation prevents a series of large holes seen with pahole.
-
-Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
-Signed-off-by: Luke D. Jones <luke@ljones.dev>
----
- drivers/platform/x86/asus-wmi.c | 17 ++++++-----------
- 1 file changed, 6 insertions(+), 11 deletions(-)
-
-diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
-index d06d9e0c498c..2d2b4eca7fd8 100644
---- a/drivers/platform/x86/asus-wmi.c
-+++ b/drivers/platform/x86/asus-wmi.c
-@@ -254,6 +254,9 @@ struct asus_wmi {
- u32 tablet_switch_dev_id;
- bool tablet_switch_inverted;
-
-+ /* The ROG Ally device requires the MCU USB device be disconnected before suspend */
-+ bool ally_mcu_usb_switch;
-+
- enum fan_type fan_type;
- enum fan_type gpu_fan_type;
- enum fan_type mid_fan_type;
-@@ -266,9 +269,7 @@ struct asus_wmi {
- u8 fan_boost_mode_mask;
- u8 fan_boost_mode;
-
-- bool charge_mode_available;
- bool egpu_enable_available;
-- bool egpu_connect_available;
- bool dgpu_disable_available;
- u32 gpu_mux_dev;
-
-@@ -309,9 +310,6 @@ struct asus_wmi {
-
- bool fnlock_locked;
-
-- /* The ROG Ally device requires the MCU USB device be disconnected before suspend */
-- bool ally_mcu_usb_switch;
+ Set the Package Power Target total of CPU: PL1 on Intel, SPL on AMD.
+ Shown on Intel+Nvidia or AMD+Nvidia based systems:
-
- struct asus_wmi_debug debug;
-
- struct asus_wmi_driver *driver;
-@@ -4391,11 +4389,11 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj,
- else if (attr == &dev_attr_als_enable.attr)
- devid = ASUS_WMI_DEVID_ALS_ENABLE;
- else if (attr == &dev_attr_charge_mode.attr)
-- ok = asus->charge_mode_available;
-+ devid = ASUS_WMI_DEVID_CHARGE_MODE;
- else if (attr == &dev_attr_egpu_enable.attr)
- ok = asus->egpu_enable_available;
- else if (attr == &dev_attr_egpu_connected.attr)
-- ok = asus->egpu_connect_available;
-+ devid = ASUS_WMI_DEVID_EGPU_CONNECTED;
- else if (attr == &dev_attr_dgpu_disable.attr)
- ok = asus->dgpu_disable_available;
- else if (attr == &dev_attr_gpu_mux_mode.attr)
-@@ -4423,7 +4421,7 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj,
- else if (attr == &dev_attr_boot_sound.attr)
- devid = ASUS_WMI_DEVID_BOOT_SOUND;
- else if (attr == &dev_attr_panel_od.attr)
-- ok = asus->panel_overdrive_available;
-+ devid = ASUS_WMI_DEVID_PANEL_OD;
- else if (attr == &dev_attr_mini_led_mode.attr)
- ok = asus->mini_led_dev_id != 0;
- else if (attr == &dev_attr_available_mini_led_mode.attr)
-@@ -4674,12 +4672,9 @@ static int asus_wmi_add(struct platform_device *pdev)
- asus->nv_dynamic_boost = 5;
- asus->nv_temp_target = 75;
-
-- asus->charge_mode_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_CHARGE_MODE);
- asus->egpu_enable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_EGPU);
-- asus->egpu_connect_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_EGPU_CONNECTED);
- asus->dgpu_disable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_DGPU);
- 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);
- asus->ally_mcu_usb_switch = acpi_has_method(NULL, ASUS_USB0_PWR_EC0_CSEE)
- && dmi_match(DMI_BOARD_NAME, "RC71L");
-
---
-2.44.0
-
-From 8cab59d3fb33f17e3b3fa4937c5d4bf0b59e6b12 Mon Sep 17 00:00:00 2001
-From: Mohamed Ghanmi <mohamed.ghanmi@supcom.tn>
-Date: Fri, 12 Apr 2024 00:56:39 +0100
-Subject: [PATCH] platform/x86: asus-wmi: add support for vivobook fan profiles
-
-Add support for vivobook fan profiles wmi call on the ASUS VIVOBOOK
-to adjust power limits.
-
-These fan profiles have a different device id than the ROG series.
-and different order. This reorders the existing modes and adds a new
-full speed mode available on these laptops.
-
-As part of keeping the patch clean the throttle_thermal_policy_available
-boolean stored in the driver struct is removed and
-throttle_thermal_policy_dev is used in place (as on init it is zeroed).
-
-Signed-off-by: Mohamed Ghanmi <mohamed.ghanmi@supcom.tn>
-Co-developed-by: Luke D. Jones <luke@ljones.dev>
-Signed-off-by: Luke D. Jones <luke@ljones.dev>
----
- drivers/platform/x86/asus-wmi.c | 100 +++++++++++----------
- include/linux/platform_data/x86/asus-wmi.h | 1 +
- 2 files changed, 55 insertions(+), 46 deletions(-)
-
-diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
-index 2d2b4eca7fd8..439d330fb80b 100644
---- a/drivers/platform/x86/asus-wmi.c
-+++ b/drivers/platform/x86/asus-wmi.c
-@@ -97,6 +97,11 @@ module_param(fnlock_default, bool, 0444);
- #define ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST 1
- #define ASUS_THROTTLE_THERMAL_POLICY_SILENT 2
-
-+#define ASUS_THROTTLE_THERMAL_POLICY_DEFAULT_VIVO 0
-+#define ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST_VIVO 2
-+#define ASUS_THROTTLE_THERMAL_POLICY_SILENT_VIVO 1
-+#define ASUS_THROTTLE_THERMAL_POLICY_FULLSPEED 3
-+
- #define USB_INTEL_XUSB2PR 0xD0
- #define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31
-
-@@ -285,8 +290,8 @@ struct asus_wmi {
- u32 kbd_rgb_dev;
- bool kbd_rgb_state_available;
-
-- bool throttle_thermal_policy_available;
- u8 throttle_thermal_policy_mode;
-+ u32 throttle_thermal_policy_dev;
-
- bool cpu_fan_curve_available;
- bool gpu_fan_curve_available;
-@@ -3153,7 +3158,7 @@ static int fan_curve_get_factory_default(struct asus_wmi *asus, u32 fan_dev)
- int err, fan_idx;
- u8 mode = 0;
-
-- if (asus->throttle_thermal_policy_available)
-+ if (asus->throttle_thermal_policy_dev)
- mode = asus->throttle_thermal_policy_mode;
- /* DEVID_<C/G>PU_FAN_CURVE is switched for OVERBOOST vs SILENT */
- if (mode == 2)
-@@ -3360,7 +3365,7 @@ static ssize_t fan_curve_enable_store(struct device *dev,
- * For machines with throttle this is the only way to reset fans
- * to default mode of operation (does not erase curve data).
- */
-- if (asus->throttle_thermal_policy_available) {
-+ if (asus->throttle_thermal_policy_dev) {
- err = throttle_thermal_policy_write(asus);
- if (err)
- return err;
-@@ -3577,8 +3582,8 @@ static const struct attribute_group asus_fan_curve_attr_group = {
- __ATTRIBUTE_GROUPS(asus_fan_curve_attr);
-
- /*
-- * Must be initialised after throttle_thermal_policy_check_present() as
-- * we check the status of throttle_thermal_policy_available during init.
-+ * Must be initialised after throttle_thermal_policy_dev is set as
-+ * we check the status of throttle_thermal_policy_dev during init.
- */
- static int asus_wmi_custom_fan_curve_init(struct asus_wmi *asus)
- {
-@@ -3619,38 +3624,31 @@ static int asus_wmi_custom_fan_curve_init(struct asus_wmi *asus)
- }
+- * min=5, max=250
++ * min/max varies, read *_min/*_max sysfs entries
++ * -1 resets to default
- /* Throttle thermal policy ****************************************************/
--
--static int throttle_thermal_policy_check_present(struct asus_wmi *asus)
--{
-- u32 result;
-- int err;
--
-- asus->throttle_thermal_policy_available = false;
--
-- err = asus_wmi_get_devstate(asus,
-- ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY,
-- &result);
-- if (err) {
-- if (err == -ENODEV)
-- return 0;
-- return err;
-- }
--
-- if (result & ASUS_WMI_DSTS_PRESENCE_BIT)
-- asus->throttle_thermal_policy_available = true;
--
-- return 0;
--}
+ What: /sys/devices/platform/<platform>/ppt_pl2_sppt
+ Date: Jun 2023
+@@ -152,8 +152,8 @@ Contact: "Luke Jones" <luke@ljones.dev>
+ Description:
+ Set the Slow Package Power Tracking Limit of CPU: PL2 on Intel, SPPT,
+ on AMD. Shown on Intel+Nvidia or AMD+Nvidia based systems:
-
- static int throttle_thermal_policy_write(struct asus_wmi *asus)
- {
-- int err;
-- u8 value;
-+ u8 value = asus->throttle_thermal_policy_mode;
- u32 retval;
-+ bool vivo;
-+ int err;
-
-- value = asus->throttle_thermal_policy_mode;
-+ vivo = asus->throttle_thermal_policy_dev == ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY_VIVO;
-+ if (vivo) {
-+ switch (value) {
-+ case ASUS_THROTTLE_THERMAL_POLICY_DEFAULT:
-+ value = ASUS_THROTTLE_THERMAL_POLICY_DEFAULT_VIVO;
-+ break;
-+ case ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST:
-+ value = ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST_VIVO;
-+ break;
-+ case ASUS_THROTTLE_THERMAL_POLICY_SILENT:
-+ value = ASUS_THROTTLE_THERMAL_POLICY_SILENT_VIVO;
-+ break;
-+ default:
-+ break;
-+ }
-+ }
-
-- err = asus_wmi_set_devstate(ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY,
-+ err = asus_wmi_set_devstate(asus->throttle_thermal_policy_dev,
- value, &retval);
-
- sysfs_notify(&asus->platform_device->dev.kobj, NULL,
-@@ -3680,7 +3678,7 @@ static int throttle_thermal_policy_write(struct asus_wmi *asus)
-
- static int throttle_thermal_policy_set_default(struct asus_wmi *asus)
- {
-- if (!asus->throttle_thermal_policy_available)
-+ if (!asus->throttle_thermal_policy_dev)
- return 0;
-
- asus->throttle_thermal_policy_mode = ASUS_THROTTLE_THERMAL_POLICY_DEFAULT;
-@@ -3690,9 +3688,14 @@ static int throttle_thermal_policy_set_default(struct asus_wmi *asus)
- static int throttle_thermal_policy_switch_next(struct asus_wmi *asus)
- {
- u8 new_mode = asus->throttle_thermal_policy_mode + 1;
-+ bool vivo;
- int err;
-
-- if (new_mode > ASUS_THROTTLE_THERMAL_POLICY_SILENT)
-+ vivo = asus->throttle_thermal_policy_dev == ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY_VIVO;
-+ if (!vivo && new_mode > ASUS_THROTTLE_THERMAL_POLICY_SILENT)
-+ new_mode = ASUS_THROTTLE_THERMAL_POLICY_DEFAULT;
-+
-+ if (vivo && new_mode > ASUS_THROTTLE_THERMAL_POLICY_FULLSPEED)
- new_mode = ASUS_THROTTLE_THERMAL_POLICY_DEFAULT;
-
- asus->throttle_thermal_policy_mode = new_mode;
-@@ -3725,13 +3728,17 @@ static ssize_t throttle_thermal_policy_store(struct device *dev,
- struct asus_wmi *asus = dev_get_drvdata(dev);
- u8 new_mode;
- int result;
-+ bool vivo;
- int err;
-
- result = kstrtou8(buf, 10, &new_mode);
- if (result < 0)
- return result;
-
-- if (new_mode > ASUS_THROTTLE_THERMAL_POLICY_SILENT)
-+ vivo = asus->throttle_thermal_policy_dev == ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY_VIVO;
-+ if (vivo && new_mode > ASUS_THROTTLE_THERMAL_POLICY_FULLSPEED)
-+ return -EINVAL;
-+ else if (!vivo && new_mode > ASUS_THROTTLE_THERMAL_POLICY_SILENT)
- return -EINVAL;
-
- asus->throttle_thermal_policy_mode = new_mode;
-@@ -3748,7 +3755,10 @@ static ssize_t throttle_thermal_policy_store(struct device *dev,
- return count;
- }
-
--// Throttle thermal policy: 0 - default, 1 - overboost, 2 - silent
-+/*
-+ * Throttle thermal policy: 0 - default, 1 - overboost, 2 - silent
-+ * VIVOBOOK: 3 - fans full speed
-+ */
- static DEVICE_ATTR_RW(throttle_thermal_policy);
+- * min=5, max=250
++ * min/max varies, read *_min/*_max sysfs entries
++ * -1 resets to default
- /* Platform profile ***********************************************************/
-@@ -3814,7 +3824,7 @@ static int platform_profile_setup(struct asus_wmi *asus)
- * Not an error if a component platform_profile relies on is unavailable
- * so early return, skipping the setup of platform_profile.
- */
-- if (!asus->throttle_thermal_policy_available)
-+ if (!asus->throttle_thermal_policy_dev)
- return 0;
+ What: /sys/devices/platform/<platform>/ppt_fppt
+ Date: Jun 2023
+@@ -161,7 +161,8 @@ KernelVersion: 6.5
+ Contact: "Luke Jones" <luke@ljones.dev>
+ Description:
+ Set the Fast Package Power Tracking Limit of CPU. AMD+Nvidia only:
+- * min=5, max=250
++ * min/max varies, read *_min/*_max sysfs entries
++ * -1 resets to default
- dev_info(dev, "Using throttle_thermal_policy for platform_profile support\n");
-@@ -4229,7 +4239,7 @@ static void asus_wmi_handle_event_code(int code, struct asus_wmi *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)
-+ if (asus->throttle_thermal_policy_dev)
- throttle_thermal_policy_switch_next(asus);
- return;
+ What: /sys/devices/platform/<platform>/ppt_apu_sppt
+ Date: Jun 2023
+@@ -169,7 +170,8 @@ KernelVersion: 6.5
+ Contact: "Luke Jones" <luke@ljones.dev>
+ Description:
+ Set the APU SPPT limit. Shown on full AMD systems only:
+- * min=5, max=130
++ * min/max varies, read *_min/*_max sysfs entries
++ * -1 resets to default
-@@ -4401,7 +4411,7 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj,
- else if (attr == &dev_attr_fan_boost_mode.attr)
- ok = asus->fan_boost_mode_available;
- else if (attr == &dev_attr_throttle_thermal_policy.attr)
-- ok = asus->throttle_thermal_policy_available;
-+ ok = asus->throttle_thermal_policy_dev != 0;
- else if (attr == &dev_attr_ppt_pl2_sppt.attr)
- devid = ASUS_WMI_DEVID_PPT_PL2_SPPT;
- else if (attr == &dev_attr_ppt_pl1_spl.attr)
-@@ -4693,16 +4703,15 @@ static int asus_wmi_add(struct platform_device *pdev)
- else if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_MODE2))
- asus->kbd_rgb_dev = ASUS_WMI_DEVID_TUF_RGB_MODE2;
+ What: /sys/devices/platform/<platform>/ppt_platform_sppt
+ Date: Jun 2023
+@@ -177,7 +179,8 @@ KernelVersion: 6.5
+ Contact: "Luke Jones" <luke@ljones.dev>
+ Description:
+ Set the platform SPPT limit. Shown on full AMD systems only:
+- * min=5, max=130
++ * min/max varies, read *_min/*_max sysfs entries
++ * -1 resets to default
-+ if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY))
-+ asus->throttle_thermal_policy_dev = ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY;
-+ else if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY_VIVO))
-+ asus->throttle_thermal_policy_dev = ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY_VIVO;
-+
- err = fan_boost_mode_check_present(asus);
- if (err)
- goto fail_fan_boost_mode;
+ What: /sys/devices/platform/<platform>/nv_dynamic_boost
+ Date: Jun 2023
+@@ -185,7 +188,8 @@ KernelVersion: 6.5
+ Contact: "Luke Jones" <luke@ljones.dev>
+ Description:
+ Set the dynamic boost limit of the Nvidia dGPU:
+- * min=5, max=25
++ * min/max varies, read *_min/*_max sysfs entries
++ * -1 resets to default
-- err = throttle_thermal_policy_check_present(asus);
-- if (err)
-- goto fail_throttle_thermal_policy;
-- else
-- throttle_thermal_policy_set_default(asus);
--
- err = platform_profile_setup(asus);
- if (err)
- goto fail_platform_profile_setup;
-@@ -4797,7 +4806,6 @@ static int asus_wmi_add(struct platform_device *pdev)
- fail_input:
- asus_wmi_sysfs_exit(asus->platform_device);
- fail_sysfs:
--fail_throttle_thermal_policy:
- fail_custom_fan_curve:
- fail_platform_profile_setup:
- if (asus->platform_profile_support)
-diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
-index 3eb5cd6773ad..982a637744ec 100644
---- a/include/linux/platform_data/x86/asus-wmi.h
-+++ b/include/linux/platform_data/x86/asus-wmi.h
-@@ -64,6 +64,7 @@
- #define ASUS_WMI_DEVID_SCREENPAD_LIGHT 0x00050032
- #define ASUS_WMI_DEVID_FAN_BOOST_MODE 0x00110018
- #define ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY 0x00120075
-+#define ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY_VIVO 0x00110019
+ What: /sys/devices/platform/<platform>/nv_temp_target
+ Date: Jun 2023
+@@ -193,7 +197,8 @@ KernelVersion: 6.5
+ Contact: "Luke Jones" <luke@ljones.dev>
+ Description:
+ Set the target temperature limit of the Nvidia dGPU:
+- * min=75, max=87
++ * min/max varies, read *_min/*_max sysfs entries
++ * -1 resets to default
- /* Misc */
- #define ASUS_WMI_DEVID_PANEL_OD 0x00050019
---
-2.44.0
-
-From de9b01c3b8869451d4cf44ab0baf55440e804fc6 Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones" <luke@ljones.dev>
-Date: Sat, 2 Dec 2023 17:47:59 +1300
-Subject: [PATCH 2/4] HID: asus: make asus_kbd_init() generic, remove
- rog_nkey_led_init()
-
-Some of the n-key stuff is old and outdated, so
-make asus_kbd_init() generic to use with other
-report ID and remove rog_nkey_led_init().
-
-Signed-off-by: Luke D. Jones <luke@ljones.dev>
----
- drivers/hid/hid-asus.c | 70 +++++++++++-------------------------------
- 1 file changed, 18 insertions(+), 52 deletions(-)
-
+ What: /sys/devices/platform/<platform>/boot_sound
+ Date: Apr 2024
diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
-index 855972a4470f..cdd998a761fe 100644
+index 37e6d25593c2..af57a5f03193 100644
--- a/drivers/hid/hid-asus.c
+++ b/drivers/hid/hid-asus.c
-@@ -386,9 +386,9 @@ static int asus_kbd_set_report(struct hid_device *hdev, const u8 *buf, size_t bu
- return ret;
- }
-
--static int asus_kbd_init(struct hid_device *hdev)
-+static int asus_kbd_init(struct hid_device *hdev, u8 report_id)
- {
-- const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x41, 0x53, 0x55, 0x53, 0x20, 0x54,
-+ const u8 buf[] = { report_id, 0x41, 0x53, 0x55, 0x53, 0x20, 0x54,
- 0x65, 0x63, 0x68, 0x2e, 0x49, 0x6e, 0x63, 0x2e, 0x00 };
- int ret;
-
-@@ -400,9 +400,10 @@ static int asus_kbd_init(struct hid_device *hdev)
- }
-
- static int asus_kbd_get_functions(struct hid_device *hdev,
-- unsigned char *kbd_func)
-+ unsigned char *kbd_func,
-+ u8 report_id)
- {
-- const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x05, 0x20, 0x31, 0x00, 0x08 };
-+ const u8 buf[] = { report_id, 0x05, 0x20, 0x31, 0x00, 0x08 };
- u8 *readbuf;
- int ret;
-
-@@ -431,51 +432,6 @@ static int asus_kbd_get_functions(struct hid_device *hdev,
- return ret;
- }
-
--static int rog_nkey_led_init(struct hid_device *hdev)
--{
-- const u8 buf_init_start[] = { FEATURE_KBD_LED_REPORT_ID1, 0xB9 };
-- u8 buf_init2[] = { FEATURE_KBD_LED_REPORT_ID1, 0x41, 0x53, 0x55, 0x53, 0x20,
-- 0x54, 0x65, 0x63, 0x68, 0x2e, 0x49, 0x6e, 0x63, 0x2e, 0x00 };
-- u8 buf_init3[] = { FEATURE_KBD_LED_REPORT_ID1,
-- 0x05, 0x20, 0x31, 0x00, 0x08 };
-- int ret;
--
-- hid_info(hdev, "Asus initialise N-KEY Device");
-- /* The first message is an init start */
-- ret = asus_kbd_set_report(hdev, buf_init_start, sizeof(buf_init_start));
-- if (ret < 0) {
-- hid_warn(hdev, "Asus failed to send init start command: %d\n", ret);
-- return ret;
-- }
-- /* Followed by a string */
-- ret = asus_kbd_set_report(hdev, buf_init2, sizeof(buf_init2));
-- if (ret < 0) {
-- hid_warn(hdev, "Asus failed to send init command 1.0: %d\n", ret);
-- return ret;
-- }
-- /* Followed by a string */
-- ret = asus_kbd_set_report(hdev, buf_init3, sizeof(buf_init3));
-- if (ret < 0) {
-- hid_warn(hdev, "Asus failed to send init command 1.1: %d\n", ret);
-- return ret;
-- }
--
-- /* begin second report ID with same data */
-- buf_init2[0] = FEATURE_KBD_LED_REPORT_ID2;
-- buf_init3[0] = FEATURE_KBD_LED_REPORT_ID2;
--
-- ret = asus_kbd_set_report(hdev, buf_init2, sizeof(buf_init2));
-- if (ret < 0) {
-- hid_warn(hdev, "Asus failed to send init command 2.0: %d\n", ret);
-- return ret;
-- }
-- ret = asus_kbd_set_report(hdev, buf_init3, sizeof(buf_init3));
-- if (ret < 0)
-- hid_warn(hdev, "Asus failed to send init command 2.1: %d\n", ret);
--
-- return ret;
--}
--
- static void asus_schedule_work(struct asus_kbd_leds *led)
+@@ -492,12 +492,19 @@ static void asus_kbd_backlight_work(struct work_struct *work)
+ */
+ static bool asus_kbd_wmi_led_control_present(struct hid_device *hdev)
{
- unsigned long flags;
-@@ -558,17 +514,27 @@ static int asus_kbd_register_leds(struct hid_device *hdev)
++ struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
+ u32 value;
int ret;
- if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD) {
-- ret = rog_nkey_led_init(hdev);
-+ /* Initialize keyboard */
-+ ret = asus_kbd_init(hdev, FEATURE_KBD_REPORT_ID);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* The LED endpoint is initialised in two HID */
-+ ret = asus_kbd_init(hdev, FEATURE_KBD_LED_REPORT_ID1);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = asus_kbd_init(hdev, FEATURE_KBD_LED_REPORT_ID2);
- if (ret < 0)
- return ret;
- } else {
- /* Initialize keyboard */
-- ret = asus_kbd_init(hdev);
-+ ret = asus_kbd_init(hdev, FEATURE_KBD_REPORT_ID);
- if (ret < 0)
- return ret;
-
- /* Get keyboard functions */
-- ret = asus_kbd_get_functions(hdev, &kbd_func);
-+ ret = asus_kbd_get_functions(hdev, &kbd_func, FEATURE_KBD_REPORT_ID);
- if (ret < 0)
- return ret;
-
---
-2.44.0
-
-From fe9fe2bbb769c5ffe0d096d9732029f900c65872 Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones" <luke@ljones.dev>
-Date: Wed, 29 Nov 2023 22:18:11 +1300
-Subject: [PATCH 3/4] HID: asus: add ROG Ally N-Key ID and keycodes
-
----
- drivers/hid/hid-asus.c | 7 +++++++
- drivers/hid/hid-ids.h | 1 +
- 2 files changed, 8 insertions(+)
-
-diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
-index cdd998a761fe..3a1a6024d299 100644
---- a/drivers/hid/hid-asus.c
-+++ b/drivers/hid/hid-asus.c
-@@ -847,6 +847,10 @@ static int asus_input_mapping(struct hid_device *hdev,
- case 0xb3: asus_map_key_clear(KEY_PROG3); break; /* Fn+Left next aura */
- case 0x6a: asus_map_key_clear(KEY_F13); break; /* Screenpad toggle */
- case 0x4b: asus_map_key_clear(KEY_F14); break; /* Arrows/Pg-Up/Dn toggle */
-+ case 0xa5: asus_map_key_clear(KEY_F15); break; /* ROG Ally left back */
-+ case 0xa6: asus_map_key_clear(KEY_F16); break; /* ROG Ally QAM button */
-+ case 0xa7: asus_map_key_clear(KEY_F17); break; /* ROG Ally ROG long-press */
-+ case 0xa8: asus_map_key_clear(KEY_F18); break; /* ROG Ally ROG long-press-release */
-
+ if (!IS_ENABLED(CONFIG_ASUS_WMI))
+ return false;
- default:
---
-2.44.0
-
-From d9a40306ea83c8799634b6ee8b497d3801967831 Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones" <luke@ljones.dev>
-Date: Tue, 2 Apr 2024 15:13:23 +1300
-Subject: [PATCH 4/4] HID: asus: add ROG Z13 lightbar
-
-Add init of the lightbar which is a small panel on the back of the ASUS
-ROG Z13 and uses the same MCU as keyboards.
-
-Signed-off-by: Luke D. Jones <luke@ljones.dev>
----
- drivers/hid/hid-asus.c | 3 +++
- drivers/hid/hid-ids.h | 1 +
- 2 files changed, 4 insertions(+)
-
-diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
-index 3a1a6024d299..de0c13babc03 100644
---- a/drivers/hid/hid-asus.c
-+++ b/drivers/hid/hid-asus.c
-@@ -1274,6 +1274,9 @@
- USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD3),
- QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD },
- { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
-+ USB_DEVICE_ID_ASUSTEK_ROG_Z13_LIGHTBAR),
-+ QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD },
-+ { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
- USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD),
- QUIRK_ROG_CLAYMORE_II_KEYBOARD },
- { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
++ if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD &&
++ dmi_check_system(asus_use_hid_led_dmi_ids)) {
++ hid_info(hdev, "using HID for asus::kbd_backlight\n");
++ return false;
++ }
++
+ ret = asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS,
+ ASUS_WMI_DEVID_KBD_BACKLIGHT, 0, &value);
+ hid_dbg(hdev, "WMI backlight check: rc %d value %x", ret, value);
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
-index f1e508a7ef06..94501dbdd463 100644
+index 72d56ee7ce1b..8291699ec56c 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
-@@ -208,6 +208,7 @@
- #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD 0x1866
+@@ -209,6 +209,7 @@
#define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD2 0x19b6
#define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD3 0x1a30
-+#define USB_DEVICE_ID_ASUSTEK_ROG_Z13_LIGHTBAR 0x18c6
+ #define USB_DEVICE_ID_ASUSTEK_ROG_Z13_LIGHTBAR 0x18c6
++#define USB_DEVICE_ID_ASUSTEK_ROG_RAIKIRI_PAD 0x1abb
+ #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY 0x1abe
#define USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD 0x196b
#define USB_DEVICE_ID_ASUSTEK_FX503VD_KEYBOARD 0x1869
-
---
-2.44.0
-
-From f6690cfd476029bc67f3161705587497dabb6b8e Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones" <luke@ljones.dev>
-Date: Tue, 21 May 2024 18:17:17 +1200
-Subject: [PATCH 1/8] platform/x86: asus-wmi: add debug print in more key
- places
-
-Add more verbose debug print in the WMI method calls. This helps a lot
-with debugging various issues working with regular users as the WMI
-methods can be traced now.
-
-Signed-off-by: Luke D. Jones <luke@ljones.dev>
----
- drivers/platform/x86/asus-wmi.c | 58 +++++++++++++++++++++++++++------
- 1 file changed, 48 insertions(+), 10 deletions(-)
-
-diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
-index 799d928c7d3d..4c129881ce28 100644
---- a/drivers/platform/x86/asus-wmi.c
-+++ b/drivers/platform/x86/asus-wmi.c
-@@ -334,20 +334,29 @@ static int asus_wmi_evaluate_method3(u32 method_id,
- status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, 0, method_id,
- &input, &output);
-
-- if (ACPI_FAILURE(status))
-+ pr_debug("%s called (0x%08x) with args: 0x%08x, 0x%08x, 0x%08x\n",
-+ __func__, method_id, arg0, arg1, arg2);
-+ if (ACPI_FAILURE(status)) {
-+ pr_debug("%s, (0x%08x), arg 0x%08x failed: %d\n",
-+ __func__, method_id, arg0, -EIO);
- return -EIO;
-+ }
-
- obj = (union acpi_object *)output.pointer;
- if (obj && obj->type == ACPI_TYPE_INTEGER)
- tmp = (u32) obj->integer.value;
-
-+ pr_debug("Result: 0x%08x\n", tmp);
- if (retval)
- *retval = tmp;
-
- kfree(obj);
-
-- if (tmp == ASUS_WMI_UNSUPPORTED_METHOD)
-+ if (tmp == ASUS_WMI_UNSUPPORTED_METHOD) {
-+ pr_debug("%s, (0x%08x), arg 0x%08x failed: %d\n",
-+ __func__, method_id, arg0, -ENODEV);
- return -ENODEV;
-+ }
-
- return 0;
- }
-@@ -377,20 +386,29 @@ static int asus_wmi_evaluate_method5(u32 method_id,
- status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, 0, method_id,
- &input, &output);
-
-- if (ACPI_FAILURE(status))
-+ pr_debug("%s called (0x%08x) with args: 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
-+ __func__, method_id, arg0, arg1, arg2, arg3, arg4);
-+ if (ACPI_FAILURE(status)) {
-+ pr_debug("%s, (0x%08x), arg 0x%08x failed: %d\n",
-+ __func__, method_id, arg0, -EIO);
- return -EIO;
-+ }
-
- obj = (union acpi_object *)output.pointer;
- if (obj && obj->type == ACPI_TYPE_INTEGER)
- tmp = (u32) obj->integer.value;
-
-+ pr_debug("Result: %x\n", tmp);
- if (retval)
- *retval = tmp;
-
- kfree(obj);
-
-- if (tmp == ASUS_WMI_UNSUPPORTED_METHOD)
-+ if (tmp == ASUS_WMI_UNSUPPORTED_METHOD) {
-+ pr_debug("%s, (0x%08x), arg 0x%08x failed: %d\n",
-+ __func__, method_id, arg0, -ENODEV);
- return -ENODEV;
-+ }
-
- return 0;
- }
-@@ -416,8 +434,13 @@ static int asus_wmi_evaluate_method_buf(u32 method_id,
- status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, 0, method_id,
- &input, &output);
-
-- if (ACPI_FAILURE(status))
-+ pr_debug("%s called (0x%08x) with args: 0x%08x, 0x%08x\n",
-+ __func__, method_id, arg0, arg1);
-+ if (ACPI_FAILURE(status)) {
-+ pr_debug("%s, (0x%08x), arg 0x%08x failed: %d\n",
-+ __func__, method_id, arg0, -EIO);
- return -EIO;
-+ }
-
- obj = (union acpi_object *)output.pointer;
-
-@@ -453,8 +476,11 @@ static int asus_wmi_evaluate_method_buf(u32 method_id,
-
- kfree(obj);
-
-- if (err)
-+ if (err) {
-+ pr_debug("%s, (0x%08x), arg 0x%08x failed: %d\n",
-+ __func__, method_id, arg0, err);
- return err;
-+ }
-
- return 0;
- }
-@@ -542,6 +568,7 @@ static bool asus_wmi_dev_is_present(struct asus_wmi *asus, u32 dev_id)
- {
- u32 retval;
- int status = asus_wmi_get_devstate(asus, dev_id, &retval);
-+ pr_debug("%s called (0x%08x), retval: 0x%08x\n", __func__, dev_id, retval);
-
- return status == 0 && (retval & ASUS_WMI_DSTS_PRESENCE_BIT);
- }
-@@ -3559,18 +3586,27 @@ static int asus_wmi_custom_fan_curve_init(struct asus_wmi *asus)
-
- err = fan_curve_check_present(asus, &asus->cpu_fan_curve_available,
- ASUS_WMI_DEVID_CPU_FAN_CURVE);
-- if (err)
-+ if (err) {
-+ pr_err("%s, checked 0x%08x, failed: %d\n",
-+ __func__, ASUS_WMI_DEVID_CPU_FAN_CURVE, err);
- return err;
-+ }
-
- err = fan_curve_check_present(asus, &asus->gpu_fan_curve_available,
- ASUS_WMI_DEVID_GPU_FAN_CURVE);
-- if (err)
-+ if (err) {
-+ pr_err("%s, checked 0x%08x, failed: %d\n",
-+ __func__, ASUS_WMI_DEVID_GPU_FAN_CURVE, err);
- return err;
-+ }
-
- err = fan_curve_check_present(asus, &asus->mid_fan_curve_available,
- ASUS_WMI_DEVID_MID_FAN_CURVE);
-- if (err)
-+ if (err) {
-+ pr_err("%s, checked 0x%08x, failed: %d\n",
-+ __func__, ASUS_WMI_DEVID_MID_FAN_CURVE, err);
- return err;
-+ }
-
- if (!asus->cpu_fan_curve_available
- && !asus->gpu_fan_curve_available
-@@ -4398,8 +4434,10 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj,
- else if (attr == &dev_attr_available_mini_led_mode.attr)
- ok = asus->mini_led_dev_id != 0;
-
-- if (devid != -1)
-+ if (devid != -1) {
- ok = !(asus_wmi_get_devstate_simple(asus, devid) < 0);
-+ pr_debug("%s called 0x%08x, ok: %x\n", __func__, devid, ok);
-+ }
-
- return ok ? attr->mode : 0;
- }
---
-2.45.1
-
-From 7a08b0a6a1b47ad7c3e84a14f433c5909ec13679 Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones" <luke@ljones.dev>
-Date: Fri, 24 May 2024 10:54:36 +1200
-Subject: [PATCH 2/8] platform/x86: asus-wmi: don't fail if platform_profile
- already registered
-
-On some newer laptops it appears that an AMD driver can register a
-platform_profile handler. If this happens then the asus_wmi driver would
-error with -EEXIST when trying to register its own handler.
-
-We can safely continue loading the driver instead of bombing out.
-
-Signed-off-by: Luke D. Jones <luke@ljones.dev>
----
- drivers/platform/x86/asus-wmi.c | 9 +++++++--
- 1 file changed, 7 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
-index 4c129881ce28..7d87ff68f418 100644
---- a/drivers/platform/x86/asus-wmi.c
-+++ b/drivers/platform/x86/asus-wmi.c
-@@ -3836,8 +3836,13 @@ static int platform_profile_setup(struct asus_wmi *asus)
- asus->platform_profile_handler.choices);
-
- err = platform_profile_register(&asus->platform_profile_handler);
-- if (err)
-+ if (err == -EEXIST) {
-+ pr_warn("%s, a platform_profile handler is already registered\n", __func__);
-+ return 0;
-+ } else if (err) {
-+ pr_err("%s, failed at platform_profile_register: %d\n", __func__, err);
- return err;
-+ }
-
- asus->platform_profile_support = true;
- return 0;
-@@ -4662,7 +4662,7 @@
- goto fail_fan_boost_mode;
-
- err = platform_profile_setup(asus);
-- if (err)
-+ if (err && err != -EEXIST)
- goto fail_platform_profile_setup;
-
- err = asus_wmi_sysfs_init(asus->platform_device);
---
-2.45.1
-
-From 2ebd194c3d390abdb67e61941f3b71fe149620eb Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones" <luke@ljones.dev>
-Date: Thu, 30 May 2024 13:20:11 +1200
-Subject: [PATCH 3/8] asus-bios: refactor existing tunings in to asus-bios
- module
-
-Signed-off-by: Luke D. Jones <luke@ljones.dev>
----
- drivers/platform/x86/Kconfig | 14 +
- drivers/platform/x86/Makefile | 1 +
- drivers/platform/x86/asus-bios.c | 654 +++++++++++++++++++++
- drivers/platform/x86/asus-bios.h | 234 ++++++++
- drivers/platform/x86/asus-wmi.c | 18 +-
- include/linux/platform_data/x86/asus-wmi.h | 10 +
- 6 files changed, 930 insertions(+), 1 deletion(-)
- create mode 100644 drivers/platform/x86/asus-bios.c
- create mode 100644 drivers/platform/x86/asus-bios.h
-
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
-index 0ec952b5d03e..296b5c9bfbb0 100644
+index 665fa9524986..b4a5a5bec7f3 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
-@@ -264,6 +264,18 @@ config ASUS_WIRELESS
+@@ -265,6 +265,18 @@ config ASUS_WIRELESS
If you choose to compile this driver as a module the module will be
called asus-wireless.
@@ -1940,7 +153,7 @@ index 0ec952b5d03e..296b5c9bfbb0 100644
config ASUS_WMI
tristate "ASUS WMI Driver"
depends on ACPI_WMI
-@@ -275,6 +287,8 @@ config ASUS_WMI
+@@ -276,6 +288,8 @@ config ASUS_WMI
depends on HOTPLUG_PCI
depends on ACPI_VIDEO || ACPI_VIDEO = n
depends on SERIO_I8042 || SERIO_I8042 = n
@@ -1963,10 +176,10 @@ index e1b142947067..d9b5b3f3b241 100644
obj-$(CONFIG_ASUS_TF103C_DOCK) += asus-tf103c-dock.o
diff --git a/drivers/platform/x86/asus-bios.c b/drivers/platform/x86/asus-bios.c
new file mode 100644
-index 000000000000..c245a48c4072
+index 000000000000..bd4c408fd062
--- /dev/null
+++ b/drivers/platform/x86/asus-bios.c
-@@ -0,0 +1,654 @@
+@@ -0,0 +1,983 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Asus BIOS attributes driver
@@ -2011,6 +224,18 @@ index 000000000000..c245a48c4072
+#define ASUS_MINI_LED_2024_STRONG 0x01
+#define ASUS_MINI_LED_2024_OFF 0x02
+
++enum cpu_core_type {
++ CPU_CORE_PERF = 0,
++ CPU_CORE_POWER,
++};
++
++enum cpu_core_value {
++ CPU_CORE_DEFAULT = 0,
++ CPU_CORE_MIN,
++ CPU_CORE_MAX,
++ CPU_CORE_CURRENT,
++};
++
+/* Default limits for tunables available on ASUS ROG laptops */
+#define PPT_CPU_LIMIT_MIN 5
+#define PPT_CPU_LIMIT_MAX 150
@@ -2022,6 +247,7 @@ index 000000000000..c245a48c4072
+#define NVIDIA_BOOST_MAX 25
+#define NVIDIA_TEMP_MIN 75
+#define NVIDIA_TEMP_MAX 87
++#define NVIDIA_GPU_POWER_MAX 70
+
+/* Tunables provided by ASUS for gaming laptops */
+struct rog_tunables {
@@ -2044,6 +270,10 @@ index 000000000000..c245a48c4072
+ u32 nv_temp_default;
+ u32 nv_temp_max;
+ u32 nv_temp_target;
++
++ u32 min_perf_cores;
++ u32 max_perf_cores;
++ u32 max_power_cores;
+};
+
+static const struct class *fw_attr_class;
@@ -2095,7 +325,8 @@ index 000000000000..c245a48c4072
+static struct kobj_attribute pending_reboot = __ATTR_RO(pending_reboot);
+
+static bool asus_bios_requires_reboot(struct kobj_attribute *attr) {
-+ return !strcmp(attr->attr.name, "gpu_mux_mode");
++ return !strcmp(attr->attr.name, "gpu_mux_mode") ||
++ !strcmp(attr->attr.name, "panel_hd_mode");
+}
+
+/*
@@ -2392,6 +623,299 @@ index 000000000000..c245a48c4072
+WMI_SHOW_INT(egpu_enable_current_value, "%d\n", ASUS_WMI_DEVID_EGPU);
+ATTR_GROUP_BOOL_CUSTOM(egpu_enable, "egpu_enable", "Enable the eGPU (also disables dGPU)");
+
++/* Device memory available to APU */
++
++static ssize_t apu_mem_current_value_show(struct kobject *kobj,
++ struct kobj_attribute *attr, char *buf)
++{
++ int err;
++ u32 mem;
++
++ err = asus_wmi_get_devstate_dsts(ASUS_WMI_DEVID_APU_MEM, &mem);
++ if (err)
++ return err;
++
++ switch (mem) {
++ case 256:
++ mem = 0;
++ break;
++ case 258:
++ mem = 1;
++ break;
++ case 259:
++ mem = 2;
++ break;
++ case 260:
++ mem = 3;
++ break;
++ case 261:
++ mem = 4;
++ break;
++ case 262:
++ /* This is out of order and looks wrong but is correct */
++ mem = 8;
++ break;
++ case 263:
++ mem = 5;
++ break;
++ case 264:
++ mem = 6;
++ break;
++ case 265:
++ mem = 7;
++ break;
++ default:
++ mem = 4;
++ break;
++ }
++
++ return sysfs_emit(buf, "%d\n", mem);
++}
++
++static ssize_t apu_mem_current_value_store(struct kobject *kobj,
++ struct kobj_attribute *attr,
++ const char *buf, size_t count)
++{
++ int result, err;
++ u32 requested, mem;
++
++ result = kstrtou32(buf, 10, &requested);
++ if (result)
++ return result;
++
++ switch (requested) {
++ case 0:
++ mem = 0;
++ break;
++ case 1:
++ mem = 258;
++ break;
++ case 2:
++ mem = 259;
++ break;
++ case 3:
++ mem = 260;
++ break;
++ case 4:
++ mem = 261;
++ break;
++ case 5:
++ mem = 263;
++ break;
++ case 6:
++ mem = 264;
++ break;
++ case 7:
++ mem = 265;
++ break;
++ case 8:
++ /* This is outof order and looks wrong but is correct */
++ mem = 262;
++ break;
++ default:
++ return -EIO;
++ }
++
++ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_APU_MEM, mem, &result);
++ if (err) {
++ pr_warn("Failed to set apu_mem: %d\n", err);
++ return err;
++ }
++
++ pr_info("APU memory changed to %dGB, reboot required\n", requested);
++ sysfs_notify(kobj, NULL, attr->attr.name);
++
++ asus_set_reboot_and_signal_event();
++
++ return count;
++}
++
++static ssize_t apu_mem_possible_values_show(struct kobject *kobj,
++ struct kobj_attribute *attr, char *buf)
++{
++ return sysfs_emit(buf, "0;1;2;3;4;5;6;7;8\n");
++}
++ATTR_GROUP_ENUM_CUSTOM(apu_mem, "apu_mem", "Set the available system memory for the APU to use");
++
++static int asus_bios_set_max_cores(void)
++{
++ u32 cores;
++ int err;
++
++ asus_bios.rog_tunables->min_perf_cores = 4;
++ asus_bios.rog_tunables->max_perf_cores = 4;
++ asus_bios.rog_tunables->max_power_cores = 8;
++
++ err = asus_wmi_get_devstate_dsts(ASUS_WMI_DEVID_CORES_MAX, &cores);
++ if (err)
++ return err;
++
++ cores &= ~ASUS_WMI_DSTS_PRESENCE_BIT;
++ asus_bios.rog_tunables->max_power_cores = (cores & 0xff00) >> 8;
++ asus_bios.rog_tunables->max_perf_cores = cores & 0xff;
++
++ return 0;
++}
++
++static ssize_t cores_value_show(struct kobject *kobj,
++ struct kobj_attribute *attr, char *buf,
++ enum cpu_core_type core_type,
++ enum cpu_core_value core_value)
++{
++ u32 cores;
++ int err;
++
++ switch (core_value) {
++ case CPU_CORE_DEFAULT:
++ case CPU_CORE_MAX:
++ if (core_type == CPU_CORE_PERF)
++ return sysfs_emit(buf, "%d\n", asus_bios.rog_tunables->max_perf_cores);
++ else
++ return sysfs_emit(buf, "%d\n", asus_bios.rog_tunables->max_power_cores);
++ case CPU_CORE_MIN:
++ if (core_type == CPU_CORE_PERF)
++ return sysfs_emit(buf, "%d\n", asus_bios.rog_tunables->min_perf_cores);
++ else
++ return sysfs_emit(buf, "%d\n", 0);
++ default:
++ break;
++ }
++
++ err = asus_wmi_get_devstate_dsts(ASUS_WMI_DEVID_CORES, &cores);
++ if (err)
++ return err;
++
++ cores &= ~ASUS_WMI_DSTS_PRESENCE_BIT;
++ if (core_type == CPU_CORE_PERF)
++ cores &= 0xff;
++ else
++ cores = (cores & 0xff00) >> 8;
++ return sysfs_emit(buf, "%d\n", cores);
++}
++
++static ssize_t cores_current_value_store(struct kobject *kobj,
++ struct kobj_attribute *attr, const char *buf,
++ enum cpu_core_type core_type)
++{
++ int result, err;
++ u32 cores, currentv, min, max;
++
++ result = kstrtou32(buf, 10, &cores);
++ if (result)
++ return result;
++
++ if (core_type == CPU_CORE_PERF) {
++ min = asus_bios.rog_tunables->min_perf_cores;
++ max = asus_bios.rog_tunables->max_perf_cores;
++ } else {
++ min = 0;
++ max = asus_bios.rog_tunables->max_power_cores;
++ }
++ if (cores < min || cores > max)
++ return -EINVAL;
++
++ err = asus_wmi_get_devstate_dsts(ASUS_WMI_DEVID_CORES, &currentv);
++ if (err)
++ return err;
++
++ if (core_type == CPU_CORE_PERF)
++ cores |= (currentv & 0xff00);
++ else
++ cores |= currentv & 0xff;
++
++ if (cores == currentv)
++ return 0;
++
++ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_CORES, cores, &result);
++ if (err) {
++ pr_warn("Failed to set perfromance core count: %d\n", err);
++ return err;
++ }
++
++ if (result > 1) {
++ pr_warn("Failed to set performance core count (result): 0x%x\n", result);
++ return -EIO;
++ }
++
++ pr_info("CPU core count changed, reboot required\n");
++ sysfs_notify(kobj, NULL, attr->attr.name);
++ asus_set_reboot_and_signal_event();
++
++ return 0;
++}
++
++static ssize_t cores_performance_min_value_show(struct kobject *kobj,
++ struct kobj_attribute *attr, char *buf)
++{
++ return cores_value_show(kobj, attr, buf, CPU_CORE_PERF, CPU_CORE_MIN);
++}
++
++static ssize_t cores_performance_max_value_show(struct kobject *kobj,
++ struct kobj_attribute *attr, char *buf)
++{
++ return cores_value_show(kobj, attr, buf, CPU_CORE_PERF, CPU_CORE_MAX);
++}
++
++static ssize_t cores_performance_default_value_show(struct kobject *kobj,
++ struct kobj_attribute *attr, char *buf)
++{
++ return cores_value_show(kobj, attr, buf, CPU_CORE_PERF, CPU_CORE_DEFAULT);
++}
++
++static ssize_t cores_performance_current_value_show(struct kobject *kobj,
++ struct kobj_attribute *attr, char *buf)
++{
++ return cores_value_show(kobj, attr, buf, CPU_CORE_PERF, CPU_CORE_CURRENT);
++}
++
++static ssize_t cores_performance_current_value_store(struct kobject *kobj,
++ struct kobj_attribute *attr,
++ const char *buf, size_t count)
++{
++ int err = cores_current_value_store(kobj, attr, buf, CPU_CORE_PERF);
++ if (err)
++ return err;
++
++ return count;
++}
++ATTR_GROUP_CORES_RW(cores_performance, "cores_performance", ASUS_WMI_DEVID_CORES, "Set the max available performance cores");
++
++static ssize_t cores_efficiency_min_value_show(struct kobject *kobj,
++ struct kobj_attribute *attr, char *buf)
++{
++ return cores_value_show(kobj, attr, buf, CPU_CORE_POWER, CPU_CORE_MIN);
++}
++
++static ssize_t cores_efficiency_max_value_show(struct kobject *kobj,
++ struct kobj_attribute *attr, char *buf)
++{
++ return cores_value_show(kobj, attr, buf, CPU_CORE_POWER, CPU_CORE_MAX);
++}
++
++static ssize_t cores_efficiency_default_value_show(struct kobject *kobj,
++ struct kobj_attribute *attr, char *buf)
++{
++ return cores_value_show(kobj, attr, buf, CPU_CORE_POWER, CPU_CORE_DEFAULT);
++}
++
++static ssize_t cores_efficiency_current_value_show(struct kobject *kobj,
++ struct kobj_attribute *attr, char *buf)
++{
++ return cores_value_show(kobj, attr, buf, CPU_CORE_POWER, CPU_CORE_CURRENT);
++}
++
++static ssize_t cores_efficiency_current_value_store(struct kobject *kobj,
++ struct kobj_attribute *attr,
++ const char *buf, size_t count)
++{
++ int err = cores_current_value_store(kobj, attr, buf, CPU_CORE_POWER);
++ if (err)
++ return err;
++
++ return count;
++}
++ATTR_GROUP_CORES_RW(cores_efficiency, "cores_efficiency", ASUS_WMI_DEVID_CORES, "Set the max available efficiency cores");
++
+/* Simple attribute creation */
+ATTR_GROUP_ENUM_INT_RW(thermal_policy, "thermal_policy", ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY, 0, 3, "0;1;2", "Fan stuff todo");
+ATTR_GROUP_PPT_RW(ppt_pl1_spl, "ppt_pl1_spl", ASUS_WMI_DEVID_PPT_PL1_SPL,
@@ -2409,11 +933,15 @@ index 000000000000..c245a48c4072
+ nv_boost_default, 5, nv_boost_max, 1, "Set the Nvidia dynamic boost limit");
+ATTR_GROUP_PPT_RW(nv_temp_target, "nv_temp_target", ASUS_WMI_DEVID_NV_THERM_TARGET,
+ nv_temp_default, 75, nv_temp_max, 1, "Set the Nvidia max thermal limit");
++ATTR_GROUP_INT_VALUE_ONLY_RO(dgpu_base_tgp, "dgpu_base_tgp", ASUS_WMI_DEVID_DGPU_BASE_TGP, "Read the base TGP value")
++ATTR_GROUP_INT_RW(dgpu_tgp, "dgpu_tgp", ASUS_WMI_DEVID_DGPU_SET_TGP,
++ 70, 0, NVIDIA_GPU_POWER_MAX, 1, "Set the additional TGP on top of the base TGP");
+
+ATTR_GROUP_ENUM_INT_RO(charge_mode, "charge_mode", ASUS_WMI_DEVID_CHARGE_MODE, 0, 0, "0;1;2", "Show the current mode of charging");
+ATTR_GROUP_BOOL_RW(boot_sound, "boot_sound", ASUS_WMI_DEVID_BOOT_SOUND, "Set the boot POST sound");
+ATTR_GROUP_BOOL_RW(mcu_powersave, "mcu_powersave", ASUS_WMI_DEVID_MCU_POWERSAVE, "Set MCU powersaving mode");
+ATTR_GROUP_BOOL_RW(panel_od, "panel_overdrive", ASUS_WMI_DEVID_PANEL_OD, "Set the panel refresh overdrive");
++ATTR_GROUP_BOOL_RW(panel_hd_mode, "panel_hd_mode", ASUS_WMI_DEVID_PANEL_HD, "Set the panel HD mode to UHD<0> or FHD<1>");
+ATTR_GROUP_BOOL_RO(egpu_connected, "egpu_connected", ASUS_WMI_DEVID_EGPU_CONNECTED, "Show the eGPU connection status");
+
+static int asus_fw_attr_add(void)
@@ -2476,8 +1004,14 @@ index 000000000000..c245a48c4072
+ if (asus_wmi_is_present(ASUS_WMI_DEVID_EGPU_CONNECTED))
+ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &egpu_connected_attr_group);
+
++ if (asus_wmi_is_present(ASUS_WMI_DEVID_CORES_MAX) && !asus_bios_set_max_cores()){
++ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &cores_performance_attr_group);
++ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &cores_efficiency_attr_group);
++ }
++
+ if (asus_wmi_is_present(ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY))
+ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &thermal_policy_attr_group);
++
+ if (asus_wmi_is_present(ASUS_WMI_DEVID_PPT_PL1_SPL))
+ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &ppt_pl1_spl_attr_group);
+ if (asus_wmi_is_present(ASUS_WMI_DEVID_PPT_PL2_SPPT))
@@ -2493,6 +1027,12 @@ index 000000000000..c245a48c4072
+ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &nv_dynamic_boost_attr_group);
+ if (asus_wmi_is_present(ASUS_WMI_DEVID_NV_THERM_TARGET))
+ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &nv_temp_target_attr_group);
++ if (asus_wmi_is_present(ASUS_WMI_DEVID_DGPU_BASE_TGP))
++ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &dgpu_base_tgp_attr_group);
++ if (asus_wmi_is_present(ASUS_WMI_DEVID_DGPU_SET_TGP))
++ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &dgpu_tgp_attr_group);
++ if (asus_wmi_is_present(ASUS_WMI_DEVID_APU_MEM))
++ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &apu_mem_attr_group);
+
+ if (asus_wmi_is_present(ASUS_WMI_DEVID_CHARGE_MODE))
+ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &charge_mode_attr_group);
@@ -2502,6 +1042,8 @@ index 000000000000..c245a48c4072
+ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &mcu_powersave_attr_group);
+ if (asus_wmi_is_present(ASUS_WMI_DEVID_PANEL_OD))
+ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &panel_od_attr_group);
++ if (asus_wmi_is_present(ASUS_WMI_DEVID_PANEL_HD))
++ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &panel_hd_mode_attr_group);
+
+ return 0;
+
@@ -2623,10 +1165,10 @@ index 000000000000..c245a48c4072
+module_exit(asus_fw_exit);
diff --git a/drivers/platform/x86/asus-bios.h b/drivers/platform/x86/asus-bios.h
new file mode 100644
-index 000000000000..acae11698a07
+index 000000000000..7016ec14efc1
--- /dev/null
+++ b/drivers/platform/x86/asus-bios.h
-@@ -0,0 +1,234 @@
+@@ -0,0 +1,288 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Definitions for kernel modules using asus-bios driver
@@ -2741,6 +1283,22 @@ index 000000000000..acae11698a07
+static struct kobj_attribute attr_##_attrname##_##_prop = \
+ __ASUS_ATTR_RO(_attrname, _prop);
+
++/* Requires current_value show&|store */
++#define __ATTR_GROUP_INT_VALUE_ONLY(_attrname, _fsname, _dispname) \
++__ATTR_SHOW_FMT(display_name, _attrname, "%s\n", _dispname); \
++static struct kobj_attribute attr_##_attrname##_type = \
++ __ASUS_ATTR_RO_AS(type, int_type_show); \
++static struct attribute *_attrname##_attrs[] = { \
++ &attr_##_attrname##_current_value.attr, \
++ &attr_##_attrname##_display_name.attr, \
++ &attr_##_attrname##_type.attr, \
++ NULL \
++}; \
++static const struct attribute_group _attrname##_attr_group = { \
++ .name = _fsname, \
++ .attrs = _attrname##_attrs \
++};
++
+/* Int style min/max range, base macro. Requires current_value show&|store */
+#define __ATTR_GROUP_INT(_attrname, _fsname, _default, \
+ _min, _max, _incstep, _dispname)\
@@ -2784,6 +1342,15 @@ index 000000000000..acae11698a07
+ .attrs = _attrname##_attrs \
+};
+
++#define ATTR_GROUP_INT_VALUE_ONLY_RO(_attrname, _fsname, _wmi, _dispname) \
++__ATTR_CURRENT_INT_RO(_attrname, _wmi); \
++__ATTR_GROUP_INT_VALUE_ONLY(_attrname, _fsname, _dispname);
++
++#define ATTR_GROUP_INT_RW(_attrname, _fsname, _wmi, _default, _min, \
++ _max, _incstep, _dispname) \
++__ATTR_CURRENT_INT_RW(_attrname, _min, _max, _wmi); \
++__ATTR_GROUP_INT(_attrname, _fsname, _default, _min, _max, _incstep, _dispname);
++
+#define ATTR_GROUP_BOOL_RO(_attrname, _fsname, _wmi, _dispname) \
+__ATTR_CURRENT_INT_RO(_attrname, _wmi); \
+__ATTR_GROUP_ENUM(_attrname, _fsname, "0;1", _dispname);
@@ -2834,15 +1401,18 @@ index 000000000000..acae11698a07
+ .attrs = _attrname##_attrs \
+};
+
-+/* ROG PPT attributes need a little different in setup */
-+#define ATTR_GROUP_PPT_RW(_attrname, _fsname, _wmi, _default, \
-+ _min, _max, _incstep, _dispname) \
-+__ROG_TUNABLE_RW(_attrname, _min, _max, _wmi); \
-+__ROG_TUNABLE_SHOW(default_value, _attrname, _default); \
-+__ATTR_SHOW_FMT(min_value, _attrname, "%d\n", _min); \
-+__ROG_TUNABLE_SHOW(max_value, _attrname, _max); \
-+__ATTR_SHOW_FMT(scalar_increment, _attrname, "%d\n", _incstep); \
++/* CPU core attributes need a little different in setup */
++#define ATTR_GROUP_CORES_RW(_attrname, _fsname, _wmi, _dispname)\
++__ATTR_SHOW_FMT(scalar_increment, _attrname, "%d\n", 1); \
+__ATTR_SHOW_FMT(display_name, _attrname, "%s\n", _dispname); \
++static struct kobj_attribute attr_##_attrname##_current_value = \
++ __ASUS_ATTR_RW(_attrname, current_value); \
++static struct kobj_attribute attr_##_attrname##_default_value = \
++ __ASUS_ATTR_RO(_attrname, default_value); \
++static struct kobj_attribute attr_##_attrname##_min_value = \
++ __ASUS_ATTR_RO(_attrname, min_value); \
++static struct kobj_attribute attr_##_attrname##_max_value = \
++ __ASUS_ATTR_RO(_attrname, max_value); \
+static struct kobj_attribute attr_##_attrname##_type = \
+ __ASUS_ATTR_RO_AS(type, int_type_show); \
+static struct attribute *_attrname##_attrs[] = { \
@@ -2860,656 +1430,15 @@ index 000000000000..acae11698a07
+ .attrs = _attrname##_attrs \
+};
+
-+#endif /* _ASUS_BIOSCFG_H_ */
-diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
-index 7d87ff68f418..a6f2e5325a60 100644
---- a/drivers/platform/x86/asus-wmi.c
-+++ b/drivers/platform/x86/asus-wmi.c
-@@ -529,12 +529,28 @@ static int asus_wmi_get_devstate(struct asus_wmi *asus, u32 dev_id, u32 *retval)
- return 0;
- }
-
--static int asus_wmi_set_devstate(u32 dev_id, u32 ctrl_param,
-+int asus_wmi_get_devstate_dsts(u32 dev_id, u32 *retval)
-+{
-+ int err;
-+
-+ err = asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS, dev_id, 0, retval);
-+ if (err)
-+ return err;
-+
-+ if (*retval == ~0)
-+ return -ENODEV;
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL_GPL(asus_wmi_get_devstate_dsts);
-+
-+int asus_wmi_set_devstate(u32 dev_id, u32 ctrl_param,
- u32 *retval)
- {
- return asus_wmi_evaluate_method(ASUS_WMI_METHODID_DEVS, dev_id,
- ctrl_param, retval);
- }
-+EXPORT_SYMBOL_GPL(asus_wmi_set_devstate);
-
- /* Helper for special devices with magic return codes */
- static int asus_wmi_get_devstate_bits(struct asus_wmi *asus,
-diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
-index 6ba0015e4386..525cb7c803fe 100644
---- a/include/linux/platform_data/x86/asus-wmi.h
-+++ b/include/linux/platform_data/x86/asus-wmi.h
-@@ -152,8 +152,18 @@
- #define ASUS_WMI_DSTS_LIGHTBAR_MASK 0x0000000F
-
- #if IS_REACHABLE(CONFIG_ASUS_WMI)
-+int asus_wmi_get_devstate_dsts(u32 dev_id, u32 *retval);
-+int asus_wmi_set_devstate(u32 dev_id, u32 ctrl_param, u32 *retval);
- int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1, u32 *retval);
- #else
-+static int asus_wmi_get_devstate_dsts(u32 dev_id, u32 *retval)
-+{
-+ return -ENODEV;
-+}
-+static int asus_wmi_set_devstate(u32 dev_id, u32 ctrl_param, u32 *retval)
-+{
-+ return -ENODEV;
-+}
- static inline int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1,
- u32 *retval)
- {
---
-2.45.1
-
-From 4a50aed36c4c202688226653511af52f5a4915e1 Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones" <luke@ljones.dev>
-Date: Sun, 2 Jun 2024 13:44:22 +1200
-Subject: [PATCH 4/8] asus-bios: add panel-hd control
-
-Signed-off-by: Luke D. Jones <luke@ljones.dev>
----
- drivers/platform/x86/asus-bios.c | 6 +++++-
- include/linux/platform_data/x86/asus-wmi.h | 1 +
- 2 files changed, 6 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/platform/x86/asus-bios.c b/drivers/platform/x86/asus-bios.c
-index c245a48c4072..9af7a8da9c05 100644
---- a/drivers/platform/x86/asus-bios.c
-+++ b/drivers/platform/x86/asus-bios.c
-@@ -126,7 +126,8 @@ static ssize_t pending_reboot_show(struct kobject *kobj,
- static struct kobj_attribute pending_reboot = __ATTR_RO(pending_reboot);
-
- static bool asus_bios_requires_reboot(struct kobj_attribute *attr) {
-- return !strcmp(attr->attr.name, "gpu_mux_mode");
-+ return !strcmp(attr->attr.name, "gpu_mux_mode") ||
-+ !strcmp(attr->attr.name, "panel_hd_mode");
- }
-
- /*
-@@ -445,6 +446,7 @@ ATTR_GROUP_ENUM_INT_RO(charge_mode, "charge_mode", ASUS_WMI_DEVID_CHARGE_MODE, 0
- ATTR_GROUP_BOOL_RW(boot_sound, "boot_sound", ASUS_WMI_DEVID_BOOT_SOUND, "Set the boot POST sound");
- ATTR_GROUP_BOOL_RW(mcu_powersave, "mcu_powersave", ASUS_WMI_DEVID_MCU_POWERSAVE, "Set MCU powersaving mode");
- ATTR_GROUP_BOOL_RW(panel_od, "panel_overdrive", ASUS_WMI_DEVID_PANEL_OD, "Set the panel refresh overdrive");
-+ATTR_GROUP_BOOL_RW(panel_hd_mode, "panel_hd_mode", ASUS_WMI_DEVID_PANEL_HD, "Set the panel HD mode to UHD<0> or FHD<1>");
- ATTR_GROUP_BOOL_RO(egpu_connected, "egpu_connected", ASUS_WMI_DEVID_EGPU_CONNECTED, "Show the eGPU connection status");
-
- static int asus_fw_attr_add(void)
-@@ -533,6 +535,8 @@ static int asus_fw_attr_add(void)
- sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &mcu_powersave_attr_group);
- if (asus_wmi_is_present(ASUS_WMI_DEVID_PANEL_OD))
- sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &panel_od_attr_group);
-+ if (asus_wmi_is_present(ASUS_WMI_DEVID_PANEL_HD))
-+ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &panel_hd_mode_attr_group);
-
- return 0;
-
-diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
-index 525cb7c803fe..c93068afc2b6 100644
---- a/include/linux/platform_data/x86/asus-wmi.h
-+++ b/include/linux/platform_data/x86/asus-wmi.h
-@@ -68,6 +68,7 @@
- #define ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY_VIVO 0x00110019
-
- /* Misc */
-+#define ASUS_WMI_DEVID_PANEL_HD 0x0005001C
- #define ASUS_WMI_DEVID_PANEL_OD 0x00050019
- #define ASUS_WMI_DEVID_CAMERA 0x00060013
- #define ASUS_WMI_DEVID_LID_FLIP 0x00060062
---
-2.45.1
-
-From 59d69aba37bc9ca2a22a2c44d8a5dd8600d2a35c Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones" <luke@ljones.dev>
-Date: Sun, 2 Jun 2024 14:32:15 +1200
-Subject: [PATCH 5/8] asus-bios: add dgpu tgp control
-
-Signed-off-by: Luke D. Jones <luke@ljones.dev>
----
- drivers/platform/x86/asus-bios.c | 8 +++++++
- drivers/platform/x86/asus-bios.h | 25 ++++++++++++++++++++++
- include/linux/platform_data/x86/asus-wmi.h | 3 +++
- 3 files changed, 36 insertions(+)
-
-diff --git a/drivers/platform/x86/asus-bios.c b/drivers/platform/x86/asus-bios.c
-index 9af7a8da9c05..d453f02a22fd 100644
---- a/drivers/platform/x86/asus-bios.c
-+++ b/drivers/platform/x86/asus-bios.c
-@@ -53,6 +53,7 @@ MODULE_ALIAS("wmi:"ASUS_NB_WMI_EVENT_GUID);
- #define NVIDIA_BOOST_MAX 25
- #define NVIDIA_TEMP_MIN 75
- #define NVIDIA_TEMP_MAX 87
-+#define NVIDIA_GPU_POWER_MAX 70
-
- /* Tunables provided by ASUS for gaming laptops */
- struct rog_tunables {
-@@ -441,6 +442,9 @@ ATTR_GROUP_PPT_RW(nv_dynamic_boost, "nv_dynamic_boost", ASUS_WMI_DEVID_NV_DYN_BO
- nv_boost_default, 5, nv_boost_max, 1, "Set the Nvidia dynamic boost limit");
- ATTR_GROUP_PPT_RW(nv_temp_target, "nv_temp_target", ASUS_WMI_DEVID_NV_THERM_TARGET,
- nv_temp_default, 75, nv_temp_max, 1, "Set the Nvidia max thermal limit");
-+ATTR_GROUP_INT_VALUE_ONLY_RO(dgpu_base_tgp, "dgpu_base_tgp", ASUS_WMI_DEVID_DGPU_BASE_TGP, "Read the base TGP value")
-+ATTR_GROUP_INT_RW(dgpu_tgp, "dgpu_tgp", ASUS_WMI_DEVID_DGPU_SET_TGP,
-+ 70, 0, NVIDIA_GPU_POWER_MAX, 1, "Set the additional TGP on top of the base TGP");
-
- ATTR_GROUP_ENUM_INT_RO(charge_mode, "charge_mode", ASUS_WMI_DEVID_CHARGE_MODE, 0, 0, "0;1;2", "Show the current mode of charging");
- ATTR_GROUP_BOOL_RW(boot_sound, "boot_sound", ASUS_WMI_DEVID_BOOT_SOUND, "Set the boot POST sound");
-@@ -526,6 +530,10 @@ static int asus_fw_attr_add(void)
- sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &nv_dynamic_boost_attr_group);
- if (asus_wmi_is_present(ASUS_WMI_DEVID_NV_THERM_TARGET))
- sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &nv_temp_target_attr_group);
-+ if (asus_wmi_is_present(ASUS_WMI_DEVID_DGPU_BASE_TGP))
-+ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &dgpu_base_tgp_attr_group);
-+ if (asus_wmi_is_present(ASUS_WMI_DEVID_DGPU_SET_TGP))
-+ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &dgpu_tgp_attr_group);
-
- if (asus_wmi_is_present(ASUS_WMI_DEVID_CHARGE_MODE))
- sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &charge_mode_attr_group);
-diff --git a/drivers/platform/x86/asus-bios.h b/drivers/platform/x86/asus-bios.h
-index acae11698a07..7c4176ab757a 100644
---- a/drivers/platform/x86/asus-bios.h
-+++ b/drivers/platform/x86/asus-bios.h
-@@ -112,6 +112,22 @@ static ssize_t _attrname##_##_prop##_show(struct kobject *kobj, \
- static struct kobj_attribute attr_##_attrname##_##_prop = \
- __ASUS_ATTR_RO(_attrname, _prop);
-
-+/* Requires current_value show&|store */
-+#define __ATTR_GROUP_INT_VALUE_ONLY(_attrname, _fsname, _dispname) \
-+__ATTR_SHOW_FMT(display_name, _attrname, "%s\n", _dispname); \
-+static struct kobj_attribute attr_##_attrname##_type = \
-+ __ASUS_ATTR_RO_AS(type, int_type_show); \
-+static struct attribute *_attrname##_attrs[] = { \
-+ &attr_##_attrname##_current_value.attr, \
-+ &attr_##_attrname##_display_name.attr, \
-+ &attr_##_attrname##_type.attr, \
-+ NULL \
-+}; \
-+static const struct attribute_group _attrname##_attr_group = { \
-+ .name = _fsname, \
-+ .attrs = _attrname##_attrs \
-+};
-+
- /* Int style min/max range, base macro. Requires current_value show&|store */
- #define __ATTR_GROUP_INT(_attrname, _fsname, _default, \
- _min, _max, _incstep, _dispname)\
-@@ -155,6 +171,15 @@ static const struct attribute_group _attrname##_attr_group = { \
- .attrs = _attrname##_attrs \
- };
-
-+#define ATTR_GROUP_INT_VALUE_ONLY_RO(_attrname, _fsname, _wmi, _dispname) \
-+__ATTR_CURRENT_INT_RO(_attrname, _wmi); \
-+__ATTR_GROUP_INT_VALUE_ONLY(_attrname, _fsname, _dispname);
-+
-+#define ATTR_GROUP_INT_RW(_attrname, _fsname, _wmi, _default, _min, \
-+ _max, _incstep, _dispname) \
-+__ATTR_CURRENT_INT_RW(_attrname, _min, _max, _wmi); \
-+__ATTR_GROUP_INT(_attrname, _fsname, _default, _min, _max, _incstep, _dispname);
-+
- #define ATTR_GROUP_BOOL_RO(_attrname, _fsname, _wmi, _dispname) \
- __ATTR_CURRENT_INT_RO(_attrname, _wmi); \
- __ATTR_GROUP_ENUM(_attrname, _fsname, "0;1", _dispname);
-diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
-index c93068afc2b6..71f3f1d67479 100644
---- a/include/linux/platform_data/x86/asus-wmi.h
-+++ b/include/linux/platform_data/x86/asus-wmi.h
-@@ -128,6 +128,9 @@
- /* dgpu on/off */
- #define ASUS_WMI_DEVID_DGPU 0x00090020
-
-+#define ASUS_WMI_DEVID_DGPU_BASE_TGP 0x00120099
-+#define ASUS_WMI_DEVID_DGPU_SET_TGP 0x00120098
-+
- /* gpu mux switch, 0 = dGPU, 1 = Optimus */
- #define ASUS_WMI_DEVID_GPU_MUX 0x00090016
- #define ASUS_WMI_DEVID_GPU_MUX_VIVO 0x00090026
---
-2.45.1
-
-From ae58c8b2e60a5feff3cf833d7f572414758d06c2 Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones" <luke@ljones.dev>
-Date: Sun, 2 Jun 2024 14:44:31 +1200
-Subject: [PATCH 6/8] asus-bios: add apu-mem
-
-Signed-off-by: Luke D. Jones <luke@ljones.dev>
----
- drivers/platform/x86/asus-bios.c | 116 +++++++++++++++++++++
- include/linux/platform_data/x86/asus-wmi.h | 1 +
- 2 files changed, 117 insertions(+)
-
-diff --git a/drivers/platform/x86/asus-bios.c b/drivers/platform/x86/asus-bios.c
-index d453f02a22fd..bcb053b57102 100644
---- a/drivers/platform/x86/asus-bios.c
-+++ b/drivers/platform/x86/asus-bios.c
-@@ -425,6 +425,120 @@ static ssize_t egpu_enable_current_value_store(struct kobject *kobj,
- WMI_SHOW_INT(egpu_enable_current_value, "%d\n", ASUS_WMI_DEVID_EGPU);
- ATTR_GROUP_BOOL_CUSTOM(egpu_enable, "egpu_enable", "Enable the eGPU (also disables dGPU)");
-
-+/* Device memory available to APU */
-+
-+static ssize_t apu_mem_current_value_show(struct kobject *kobj,
-+ struct kobj_attribute *attr, char *buf)
-+{
-+ int err;
-+ u32 mem;
-+
-+ err = asus_wmi_get_devstate_dsts(ASUS_WMI_DEVID_APU_MEM, &mem);
-+ if (err)
-+ return err;
-+
-+ switch (mem) {
-+ case 256:
-+ mem = 0;
-+ break;
-+ case 258:
-+ mem = 1;
-+ break;
-+ case 259:
-+ mem = 2;
-+ break;
-+ case 260:
-+ mem = 3;
-+ break;
-+ case 261:
-+ mem = 4;
-+ break;
-+ case 262:
-+ /* This is out of order and looks wrong but is correct */
-+ mem = 8;
-+ break;
-+ case 263:
-+ mem = 5;
-+ break;
-+ case 264:
-+ mem = 6;
-+ break;
-+ case 265:
-+ mem = 7;
-+ break;
-+ default:
-+ mem = 4;
-+ break;
-+ }
-+
-+ return sysfs_emit(buf, "%d\n", mem);
-+}
-+
-+static ssize_t apu_mem_current_value_store(struct kobject *kobj,
-+ struct kobj_attribute *attr,
-+ const char *buf, size_t count)
-+{
-+ int result, err;
-+ u32 requested, mem;
-+
-+ result = kstrtou32(buf, 10, &requested);
-+ if (result)
-+ return result;
-+
-+ switch (requested) {
-+ case 0:
-+ mem = 0;
-+ break;
-+ case 1:
-+ mem = 258;
-+ break;
-+ case 2:
-+ mem = 259;
-+ break;
-+ case 3:
-+ mem = 260;
-+ break;
-+ case 4:
-+ mem = 261;
-+ break;
-+ case 5:
-+ mem = 263;
-+ break;
-+ case 6:
-+ mem = 264;
-+ break;
-+ case 7:
-+ mem = 265;
-+ break;
-+ case 8:
-+ /* This is outof order and looks wrong but is correct */
-+ mem = 262;
-+ break;
-+ default:
-+ return -EIO;
-+ }
-+
-+ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_APU_MEM, mem, &result);
-+ if (err) {
-+ pr_warn("Failed to set apu_mem: %d\n", err);
-+ return err;
-+ }
-+
-+ pr_info("APU memory changed to %dGB, reboot required\n", requested);
-+ sysfs_notify(kobj, NULL, attr->attr.name);
-+
-+ asus_set_reboot_and_signal_event();
-+
-+ return count;
-+}
-+
-+static ssize_t apu_mem_possible_values_show(struct kobject *kobj,
-+ struct kobj_attribute *attr, char *buf)
-+{
-+ return sysfs_emit(buf, "0;1;2;3;4;5;6;7;8\n");
-+}
-+ATTR_GROUP_ENUM_CUSTOM(apu_mem, "apu_mem", "Set the available system memory for the APU to use");
-+
- /* Simple attribute creation */
- ATTR_GROUP_ENUM_INT_RW(thermal_policy, "thermal_policy", ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY, 0, 3, "0;1;2", "Fan stuff todo");
- ATTR_GROUP_PPT_RW(ppt_pl1_spl, "ppt_pl1_spl", ASUS_WMI_DEVID_PPT_PL1_SPL,
-@@ -534,6 +648,8 @@ static int asus_fw_attr_add(void)
- sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &dgpu_base_tgp_attr_group);
- if (asus_wmi_is_present(ASUS_WMI_DEVID_DGPU_SET_TGP))
- sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &dgpu_tgp_attr_group);
-+ if (asus_wmi_is_present(ASUS_WMI_DEVID_APU_MEM))
-+ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &apu_mem_attr_group);
-
- if (asus_wmi_is_present(ASUS_WMI_DEVID_CHARGE_MODE))
- sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &charge_mode_attr_group);
-diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
-index 71f3f1d67479..da0e423ecb06 100644
---- a/include/linux/platform_data/x86/asus-wmi.h
-+++ b/include/linux/platform_data/x86/asus-wmi.h
-@@ -130,6 +130,7 @@
-
- #define ASUS_WMI_DEVID_DGPU_BASE_TGP 0x00120099
- #define ASUS_WMI_DEVID_DGPU_SET_TGP 0x00120098
-+#define ASUS_WMI_DEVID_APU_MEM 0x000600C1
-
- /* gpu mux switch, 0 = dGPU, 1 = Optimus */
- #define ASUS_WMI_DEVID_GPU_MUX 0x00090016
---
-2.45.1
-
-From f7e8fe2458a3f8aa091e5e282b67f2a78f5cc1c4 Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones" <luke@ljones.dev>
-Date: Sun, 2 Jun 2024 16:21:32 +1200
-Subject: [PATCH 7/8] asus-bios: add core count control
-
-Signed-off-by: Luke D. Jones <luke@ljones.dev>
----
- drivers/platform/x86/asus-bios.c | 201 +++++++++++++++++++++
- drivers/platform/x86/asus-bios.h | 29 +++
- include/linux/platform_data/x86/asus-wmi.h | 4 +
- 3 files changed, 234 insertions(+)
-
-diff --git a/drivers/platform/x86/asus-bios.c b/drivers/platform/x86/asus-bios.c
-index bcb053b57102..bd4c408fd062 100644
---- a/drivers/platform/x86/asus-bios.c
-+++ b/drivers/platform/x86/asus-bios.c
-@@ -42,6 +42,18 @@ MODULE_ALIAS("wmi:"ASUS_NB_WMI_EVENT_GUID);
- #define ASUS_MINI_LED_2024_STRONG 0x01
- #define ASUS_MINI_LED_2024_OFF 0x02
-
-+enum cpu_core_type {
-+ CPU_CORE_PERF = 0,
-+ CPU_CORE_POWER,
-+};
-+
-+enum cpu_core_value {
-+ CPU_CORE_DEFAULT = 0,
-+ CPU_CORE_MIN,
-+ CPU_CORE_MAX,
-+ CPU_CORE_CURRENT,
-+};
-+
- /* Default limits for tunables available on ASUS ROG laptops */
- #define PPT_CPU_LIMIT_MIN 5
- #define PPT_CPU_LIMIT_MAX 150
-@@ -76,6 +88,10 @@ struct rog_tunables {
- u32 nv_temp_default;
- u32 nv_temp_max;
- u32 nv_temp_target;
-+
-+ u32 min_perf_cores;
-+ u32 max_perf_cores;
-+ u32 max_power_cores;
- };
-
- static const struct class *fw_attr_class;
-@@ -539,6 +555,185 @@ static ssize_t apu_mem_possible_values_show(struct kobject *kobj,
- }
- ATTR_GROUP_ENUM_CUSTOM(apu_mem, "apu_mem", "Set the available system memory for the APU to use");
-
-+static int asus_bios_set_max_cores(void)
-+{
-+ u32 cores;
-+ int err;
-+
-+ asus_bios.rog_tunables->min_perf_cores = 4;
-+ asus_bios.rog_tunables->max_perf_cores = 4;
-+ asus_bios.rog_tunables->max_power_cores = 8;
-+
-+ err = asus_wmi_get_devstate_dsts(ASUS_WMI_DEVID_CORES_MAX, &cores);
-+ if (err)
-+ return err;
-+
-+ cores &= ~ASUS_WMI_DSTS_PRESENCE_BIT;
-+ asus_bios.rog_tunables->max_power_cores = (cores & 0xff00) >> 8;
-+ asus_bios.rog_tunables->max_perf_cores = cores & 0xff;
-+
-+ return 0;
-+}
-+
-+static ssize_t cores_value_show(struct kobject *kobj,
-+ struct kobj_attribute *attr, char *buf,
-+ enum cpu_core_type core_type,
-+ enum cpu_core_value core_value)
-+{
-+ u32 cores;
-+ int err;
-+
-+ switch (core_value) {
-+ case CPU_CORE_DEFAULT:
-+ case CPU_CORE_MAX:
-+ if (core_type == CPU_CORE_PERF)
-+ return sysfs_emit(buf, "%d\n", asus_bios.rog_tunables->max_perf_cores);
-+ else
-+ return sysfs_emit(buf, "%d\n", asus_bios.rog_tunables->max_power_cores);
-+ case CPU_CORE_MIN:
-+ if (core_type == CPU_CORE_PERF)
-+ return sysfs_emit(buf, "%d\n", asus_bios.rog_tunables->min_perf_cores);
-+ else
-+ return sysfs_emit(buf, "%d\n", 0);
-+ default:
-+ break;
-+ }
-+
-+ err = asus_wmi_get_devstate_dsts(ASUS_WMI_DEVID_CORES, &cores);
-+ if (err)
-+ return err;
-+
-+ cores &= ~ASUS_WMI_DSTS_PRESENCE_BIT;
-+ if (core_type == CPU_CORE_PERF)
-+ cores &= 0xff;
-+ else
-+ cores = (cores & 0xff00) >> 8;
-+ return sysfs_emit(buf, "%d\n", cores);
-+}
-+
-+static ssize_t cores_current_value_store(struct kobject *kobj,
-+ struct kobj_attribute *attr, const char *buf,
-+ enum cpu_core_type core_type)
-+{
-+ int result, err;
-+ u32 cores, currentv, min, max;
-+
-+ result = kstrtou32(buf, 10, &cores);
-+ if (result)
-+ return result;
-+
-+ if (core_type == CPU_CORE_PERF) {
-+ min = asus_bios.rog_tunables->min_perf_cores;
-+ max = asus_bios.rog_tunables->max_perf_cores;
-+ } else {
-+ min = 0;
-+ max = asus_bios.rog_tunables->max_power_cores;
-+ }
-+ if (cores < min || cores > max)
-+ return -EINVAL;
-+
-+ err = asus_wmi_get_devstate_dsts(ASUS_WMI_DEVID_CORES, &currentv);
-+ if (err)
-+ return err;
-+
-+ if (core_type == CPU_CORE_PERF)
-+ cores |= (currentv & 0xff00);
-+ else
-+ cores |= currentv & 0xff;
-+
-+ if (cores == currentv)
-+ return 0;
-+
-+ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_CORES, cores, &result);
-+ if (err) {
-+ pr_warn("Failed to set perfromance core count: %d\n", err);
-+ return err;
-+ }
-+
-+ if (result > 1) {
-+ pr_warn("Failed to set performance core count (result): 0x%x\n", result);
-+ return -EIO;
-+ }
-+
-+ pr_info("CPU core count changed, reboot required\n");
-+ sysfs_notify(kobj, NULL, attr->attr.name);
-+ asus_set_reboot_and_signal_event();
-+
-+ return 0;
-+}
-+
-+static ssize_t cores_performance_min_value_show(struct kobject *kobj,
-+ struct kobj_attribute *attr, char *buf)
-+{
-+ return cores_value_show(kobj, attr, buf, CPU_CORE_PERF, CPU_CORE_MIN);
-+}
-+
-+static ssize_t cores_performance_max_value_show(struct kobject *kobj,
-+ struct kobj_attribute *attr, char *buf)
-+{
-+ return cores_value_show(kobj, attr, buf, CPU_CORE_PERF, CPU_CORE_MAX);
-+}
-+
-+static ssize_t cores_performance_default_value_show(struct kobject *kobj,
-+ struct kobj_attribute *attr, char *buf)
-+{
-+ return cores_value_show(kobj, attr, buf, CPU_CORE_PERF, CPU_CORE_DEFAULT);
-+}
-+
-+static ssize_t cores_performance_current_value_show(struct kobject *kobj,
-+ struct kobj_attribute *attr, char *buf)
-+{
-+ return cores_value_show(kobj, attr, buf, CPU_CORE_PERF, CPU_CORE_CURRENT);
-+}
-+
-+static ssize_t cores_performance_current_value_store(struct kobject *kobj,
-+ struct kobj_attribute *attr,
-+ const char *buf, size_t count)
-+{
-+ int err = cores_current_value_store(kobj, attr, buf, CPU_CORE_PERF);
-+ if (err)
-+ return err;
-+
-+ return count;
-+}
-+ATTR_GROUP_CORES_RW(cores_performance, "cores_performance", ASUS_WMI_DEVID_CORES, "Set the max available performance cores");
-+
-+static ssize_t cores_efficiency_min_value_show(struct kobject *kobj,
-+ struct kobj_attribute *attr, char *buf)
-+{
-+ return cores_value_show(kobj, attr, buf, CPU_CORE_POWER, CPU_CORE_MIN);
-+}
-+
-+static ssize_t cores_efficiency_max_value_show(struct kobject *kobj,
-+ struct kobj_attribute *attr, char *buf)
-+{
-+ return cores_value_show(kobj, attr, buf, CPU_CORE_POWER, CPU_CORE_MAX);
-+}
-+
-+static ssize_t cores_efficiency_default_value_show(struct kobject *kobj,
-+ struct kobj_attribute *attr, char *buf)
-+{
-+ return cores_value_show(kobj, attr, buf, CPU_CORE_POWER, CPU_CORE_DEFAULT);
-+}
-+
-+static ssize_t cores_efficiency_current_value_show(struct kobject *kobj,
-+ struct kobj_attribute *attr, char *buf)
-+{
-+ return cores_value_show(kobj, attr, buf, CPU_CORE_POWER, CPU_CORE_CURRENT);
-+}
-+
-+static ssize_t cores_efficiency_current_value_store(struct kobject *kobj,
-+ struct kobj_attribute *attr,
-+ const char *buf, size_t count)
-+{
-+ int err = cores_current_value_store(kobj, attr, buf, CPU_CORE_POWER);
-+ if (err)
-+ return err;
-+
-+ return count;
-+}
-+ATTR_GROUP_CORES_RW(cores_efficiency, "cores_efficiency", ASUS_WMI_DEVID_CORES, "Set the max available efficiency cores");
-+
- /* Simple attribute creation */
- ATTR_GROUP_ENUM_INT_RW(thermal_policy, "thermal_policy", ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY, 0, 3, "0;1;2", "Fan stuff todo");
- ATTR_GROUP_PPT_RW(ppt_pl1_spl, "ppt_pl1_spl", ASUS_WMI_DEVID_PPT_PL1_SPL,
-@@ -627,8 +822,14 @@ static int asus_fw_attr_add(void)
- if (asus_wmi_is_present(ASUS_WMI_DEVID_EGPU_CONNECTED))
- sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &egpu_connected_attr_group);
-
-+ if (asus_wmi_is_present(ASUS_WMI_DEVID_CORES_MAX) && !asus_bios_set_max_cores()){
-+ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &cores_performance_attr_group);
-+ sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &cores_efficiency_attr_group);
-+ }
-+
- if (asus_wmi_is_present(ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY))
- sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &thermal_policy_attr_group);
-+
- if (asus_wmi_is_present(ASUS_WMI_DEVID_PPT_PL1_SPL))
- sysfs_create_group(&asus_bios.fw_attr_kset->kobj, &ppt_pl1_spl_attr_group);
- if (asus_wmi_is_present(ASUS_WMI_DEVID_PPT_PL2_SPPT))
-diff --git a/drivers/platform/x86/asus-bios.h b/drivers/platform/x86/asus-bios.h
-index 7c4176ab757a..7016ec14efc1 100644
---- a/drivers/platform/x86/asus-bios.h
-+++ b/drivers/platform/x86/asus-bios.h
-@@ -230,6 +230,35 @@ static const struct attribute_group _attrname##_attr_group = { \
- .attrs = _attrname##_attrs \
- };
-
-+/* CPU core attributes need a little different in setup */
-+#define ATTR_GROUP_CORES_RW(_attrname, _fsname, _wmi, _dispname)\
-+__ATTR_SHOW_FMT(scalar_increment, _attrname, "%d\n", 1); \
++/* ROG PPT attributes need a little different in setup */
++#define ATTR_GROUP_PPT_RW(_attrname, _fsname, _wmi, _default, \
++ _min, _max, _incstep, _dispname) \
++__ROG_TUNABLE_RW(_attrname, _min, _max, _wmi); \
++__ROG_TUNABLE_SHOW(default_value, _attrname, _default); \
++__ATTR_SHOW_FMT(min_value, _attrname, "%d\n", _min); \
++__ROG_TUNABLE_SHOW(max_value, _attrname, _max); \
++__ATTR_SHOW_FMT(scalar_increment, _attrname, "%d\n", _incstep); \
+__ATTR_SHOW_FMT(display_name, _attrname, "%s\n", _dispname); \
-+static struct kobj_attribute attr_##_attrname##_current_value = \
-+ __ASUS_ATTR_RW(_attrname, current_value); \
-+static struct kobj_attribute attr_##_attrname##_default_value = \
-+ __ASUS_ATTR_RO(_attrname, default_value); \
-+static struct kobj_attribute attr_##_attrname##_min_value = \
-+ __ASUS_ATTR_RO(_attrname, min_value); \
-+static struct kobj_attribute attr_##_attrname##_max_value = \
-+ __ASUS_ATTR_RO(_attrname, max_value); \
+static struct kobj_attribute attr_##_attrname##_type = \
+ __ASUS_ATTR_RO_AS(type, int_type_show); \
+static struct attribute *_attrname##_attrs[] = { \
@@ -3527,315 +1456,24 @@ index 7c4176ab757a..7016ec14efc1 100644
+ .attrs = _attrname##_attrs \
+};
+
- /* ROG PPT attributes need a little different in setup */
- #define ATTR_GROUP_PPT_RW(_attrname, _fsname, _wmi, _default, \
- _min, _max, _incstep, _dispname) \
-diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
-index da0e423ecb06..9756e595d2cd 100644
---- a/include/linux/platform_data/x86/asus-wmi.h
-+++ b/include/linux/platform_data/x86/asus-wmi.h
-@@ -128,6 +128,10 @@
- /* dgpu on/off */
- #define ASUS_WMI_DEVID_DGPU 0x00090020
-
-+/* Intel E-core and P-core configuration in a format 0x0[E]0[P] */
-+#define ASUS_WMI_DEVID_CORES 0x001200D2
-+ /* Maximum Intel E-core and P-core availability */
-+#define ASUS_WMI_DEVID_CORES_MAX 0x001200D3
- #define ASUS_WMI_DEVID_DGPU_BASE_TGP 0x00120099
- #define ASUS_WMI_DEVID_DGPU_SET_TGP 0x00120098
- #define ASUS_WMI_DEVID_APU_MEM 0x000600C1
---
-2.45.1
-
-From 59cb165cde465df5380b809ecea6737d85405dac Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones" <luke@ljones.dev>
-Date: Mon, 13 May 2024 19:20:04 +1200
-Subject: [PATCH v2 1/3] hid-asus: use hid for brightness control on keyboard
-
-On almost all ASUS ROG series laptops the MCU used for the USB keyboard
-also has a HID packet used for setting the brightness. This is usually
-the same as the WMI method. But in some laptops the WMI method either
-is missing or doesn't work, so we should default to the HID control.
-
-Signed-off-by: Luke D. Jones <luke@ljones.dev>
----
- drivers/hid/hid-asus.c | 7 ++++
- drivers/platform/x86/asus-wmi.c | 3 +-
- include/linux/platform_data/x86/asus-wmi.h | 45 ++++++++++++++++++++++
- 3 files changed, 54 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
-index 02de2bf4f790..0ed3708ef7e2 100644
---- a/drivers/hid/hid-asus.c
-+++ b/drivers/hid/hid-asus.c
-@@ -492,12 +492,19 @@ static void asus_kbd_backlight_work(struct work_struct *work)
- */
- static bool asus_kbd_wmi_led_control_present(struct hid_device *hdev)
- {
-+ struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
- u32 value;
- int ret;
-
- if (!IS_ENABLED(CONFIG_ASUS_WMI))
- return false;
-
-+ if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD &&
-+ dmi_check_system(asus_use_hid_led_dmi_ids)) {
-+ hid_info(hdev, "using HID for asus::kbd_backlight\n");
-+ return false;
-+ }
-+
- ret = asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS,
- ASUS_WMI_DEVID_KBD_BACKLIGHT, 0, &value);
- hid_dbg(hdev, "WMI backlight check: rc %d value %x", ret, value);
++#endif /* _ASUS_BIOSCFG_H_ */
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
-index 3f9b6285c9a6..799d928c7d3d 100644
+index bc9c5db38324..9c80aa073758 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
-@@ -1681,7 +1681,8 @@ static int asus_wmi_led_init(struct asus_wmi *asus)
- goto error;
- }
-
-- if (!kbd_led_read(asus, &led_val, NULL)) {
-+ if (!kbd_led_read(asus, &led_val, NULL) && !dmi_check_system(asus_use_hid_led_dmi_ids)) {
-+ pr_info("using asus-wmi for asus::kbd_backlight\n");
- asus->kbd_led_wk = led_val;
- asus->kbd_led.name = "asus::kbd_backlight";
- asus->kbd_led.flags = LED_BRIGHT_HW_CHANGED;
-diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
-index 3eb5cd6773ad..96c780efa0d7 100644
---- a/include/linux/platform_data/x86/asus-wmi.h
-+++ b/include/linux/platform_data/x86/asus-wmi.h
-@@ -4,6 +4,7 @@
-
- #include <linux/errno.h>
- #include <linux/types.h>
-+#include <linux/dmi.h>
-
- /* WMI Methods */
- #define ASUS_WMI_METHODID_SPEC 0x43455053 /* BIOS SPECification */
-@@ -160,4 +161,48 @@ static inline int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1,
- }
- #endif
+@@ -97,6 +97,11 @@ module_param(fnlock_default, bool, 0444);
+ #define ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST 1
+ #define ASUS_THROTTLE_THERMAL_POLICY_SILENT 2
-+/* To be used by both hid-asus and asus-wmi to determine which controls kbd_brightness */
-+#if IS_ENABLED(CONFIG_ASUS_WMI)
-+bool asus_use_hid_led(void);
-+#else
-+static inline bool asus_use_hid_led(void)
-+{
-+ return true;
-+}
-+#endif
-+
-+static const struct dmi_system_id asus_use_hid_led_dmi_ids[] = {
-+ {
-+ .matches = {
-+ DMI_MATCH(DMI_PRODUCT_FAMILY, "ROG Zephyrus"),
-+ },
-+ },
-+ {
-+ .matches = {
-+ DMI_MATCH(DMI_PRODUCT_FAMILY, "ROG Strix"),
-+ },
-+ },
-+ {
-+ .matches = {
-+ DMI_MATCH(DMI_PRODUCT_FAMILY, "ROG Flow"),
-+ },
-+ },
-+ {
-+ .matches = {
-+ DMI_MATCH(DMI_BOARD_NAME, "GA403U"),
-+ },
-+ },
-+ {
-+ .matches = {
-+ DMI_MATCH(DMI_BOARD_NAME, "GU605M"),
-+ },
-+ },
-+ {
-+ .matches = {
-+ DMI_MATCH(DMI_BOARD_NAME, "RC71L"),
-+ },
-+ },
-+ NULL,
-+};
++#define ASUS_THROTTLE_THERMAL_POLICY_DEFAULT_VIVO 0
++#define ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST_VIVO 2
++#define ASUS_THROTTLE_THERMAL_POLICY_SILENT_VIVO 1
++#define ASUS_THROTTLE_THERMAL_POLICY_FULLSPEED 3
+
- #endif /* __PLATFORM_DATA_X86_ASUS_WMI_H */
---
-2.45.2
-
-From 671da604738dd6dd01903585e8e8a55d49ab06e9 Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones" <luke@ljones.dev>
-Date: Fri, 7 Jun 2024 15:58:01 +1200
-Subject: [PATCH v2 3/3] Input: xpad - add support for ASUS ROG RAIKIRI PRO
-
-Add the VID/PID for ASUS ROG RAIKIRI PRO to
-xpad_device and the VID to xpad_table.
-
-Signed-off-by: Luke D. Jones <luke@ljones.dev>
----
- drivers/hid/hid-ids.h | 1 +
- drivers/input/joystick/xpad.c | 1 +
- 2 files changed, 2 insertions(+)
-
-diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
-index 61d2a21affa2..31c522fa4e87 100644
---- a/drivers/hid/hid-ids.h
-+++ b/drivers/hid/hid-ids.h
-@@ -209,6 +209,7 @@
- #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD2 0x19b6
- #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD3 0x1a30
- #define USB_DEVICE_ID_ASUSTEK_ROG_Z13_LIGHTBAR 0x18c6
-+#define USB_DEVICE_ID_ASUSTEK_ROG_RAIKIRI_PAD 0x1abb
- #define USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD 0x196b
- #define USB_DEVICE_ID_ASUSTEK_FX503VD_KEYBOARD 0x1869
-
---
-2.45.2
-
-/* Default limits for tunables available on ASUS ROG laptops */
-#define PPT_CPU_LIMIT_MIN 5
-#define PPT_CPU_LIMIT_MAX 150
-#define PPT_CPU_LIMIT_DEFAULT 80
-#define PPT_PLATFORM_MIN 5
-#define PPT_PLATFORM_MAX 100
-#define PPT_PLATFORM_DEFAULT 80
-#define NVIDIA_BOOST_MIN 5
-#define NVIDIA_BOOST_MAX 25
-#define NVIDIA_TEMP_MIN 75
-
-/* Tunables provided by ASUS for gaming laptops */
-struct rog_tunables {
- u32 cpu_default;
- u32 cpu_max;
-
- u32 platform_default;
- u32 platform_max;
-
- u32 ppt_pl1_spl; // total
- u32 ppt_pl2_sppt; // total
- u32 ppt_apu_sppt; // cpu
- u32 ppt_platform_sppt; // cpu
- u32 ppt_fppt; // total
-
- u32 nv_boost_default;
- u32 nv_boost_max;
- u32 nv_dynamic_boost;
-
- u32 nv_temp_default;
- u32 nv_temp_max;
- u32 nv_temp_target;
-};
-
-
-From 74b729c160f95f0bec8d7af3efc94514195b23e3 Mon Sep 17 00:00:00 2001
-From: "Luke D. Jones" <luke@ljones.dev>
-Date: Sat, 25 May 2024 17:31:07 +1200
-Subject: [PATCH 3/9] platform/x86: asus-wmi: add macros and expose min/max
- sysfs for ppt tunables
-
-In most cases the safe min and max values of the various PPT tunables are
-known for various ASUS ROG (and other) laptop models. We can match the
-DMI string for these and expose min/max sysfs points, plus set some sane
-default values.
-
-As part of the addition of the min/max and defaults, to reduce the amount
-of code copy/paste and introduce some sanity a group of macros were added
-specific to the PPT and NV tunables. The code becomes much cleaner and
-easier to read.
-
-This makes the PPT functions much more usable and safe.
-
-Signed-off-by: Luke D. Jones <luke@ljones.dev>
----
- .../ABI/testing/sysfs-platform-asus-wmi | 23 +-
- drivers/platform/x86/asus-wmi.c | 561 ++++++++----------
- 2 files changed, 245 insertions(+), 339 deletions(-)
-
-diff --git a/Documentation/ABI/testing/sysfs-platform-asus-wmi b/Documentation/ABI/testing/sysfs-platform-asus-wmi
-index 28144371a0f1..984a04f32fd0 100644
---- a/Documentation/ABI/testing/sysfs-platform-asus-wmi
-+++ b/Documentation/ABI/testing/sysfs-platform-asus-wmi
-@@ -142,8 +142,8 @@ Contact: "Luke Jones" <luke@ljones.dev>
- Description:
- Set the Package Power Target total of CPU: PL1 on Intel, SPL on AMD.
- Shown on Intel+Nvidia or AMD+Nvidia based systems:
--
-- * min=5, max=250
-+ * min/max varies, read *_min/*_max sysfs entries
-+ * -1 resets to default
-
- What: /sys/devices/platform/<platform>/ppt_pl2_sppt
- Date: Jun 2023
-@@ -152,8 +152,8 @@ Contact: "Luke Jones" <luke@ljones.dev>
- Description:
- Set the Slow Package Power Tracking Limit of CPU: PL2 on Intel, SPPT,
- on AMD. Shown on Intel+Nvidia or AMD+Nvidia based systems:
--
-- * min=5, max=250
-+ * min/max varies, read *_min/*_max sysfs entries
-+ * -1 resets to default
-
- What: /sys/devices/platform/<platform>/ppt_fppt
- Date: Jun 2023
-@@ -161,7 +161,8 @@ KernelVersion: 6.5
- Contact: "Luke Jones" <luke@ljones.dev>
- Description:
- Set the Fast Package Power Tracking Limit of CPU. AMD+Nvidia only:
-- * min=5, max=250
-+ * min/max varies, read *_min/*_max sysfs entries
-+ * -1 resets to default
-
- What: /sys/devices/platform/<platform>/ppt_apu_sppt
- Date: Jun 2023
-@@ -169,7 +170,8 @@ KernelVersion: 6.5
- Contact: "Luke Jones" <luke@ljones.dev>
- Description:
- Set the APU SPPT limit. Shown on full AMD systems only:
-- * min=5, max=130
-+ * min/max varies, read *_min/*_max sysfs entries
-+ * -1 resets to default
-
- What: /sys/devices/platform/<platform>/ppt_platform_sppt
- Date: Jun 2023
-@@ -177,7 +179,8 @@ KernelVersion: 6.5
- Contact: "Luke Jones" <luke@ljones.dev>
- Description:
- Set the platform SPPT limit. Shown on full AMD systems only:
-- * min=5, max=130
-+ * min/max varies, read *_min/*_max sysfs entries
-+ * -1 resets to default
-
- What: /sys/devices/platform/<platform>/nv_dynamic_boost
- Date: Jun 2023
-@@ -185,7 +188,8 @@ KernelVersion: 6.5
- Contact: "Luke Jones" <luke@ljones.dev>
- Description:
- Set the dynamic boost limit of the Nvidia dGPU:
-- * min=5, max=25
-+ * min/max varies, read *_min/*_max sysfs entries
-+ * -1 resets to default
-
- What: /sys/devices/platform/<platform>/nv_temp_target
- Date: Jun 2023
-@@ -193,7 +197,8 @@ KernelVersion: 6.5
- Contact: "Luke Jones" <luke@ljones.dev>
- Description:
- Set the target temperature limit of the Nvidia dGPU:
-- * min=75, max=87
-+ * min/max varies, read *_min/*_max sysfs entries
-+ * -1 resets to default
+ #define USB_INTEL_XUSB2PR 0xD0
+ #define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31
- What: /sys/devices/platform/<platform>/boot_sound
- Date: Apr 2024
-diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
-index 999cd658ec8b..d016acb23789 100644
---- a/drivers/platform/x86/asus-wmi.c
-+++ b/drivers/platform/x86/asus-wmi.c
-@@ -112,11 +112,13 @@ module_param(fnlock_default, bool, 0444);
+@@ -112,11 +117,13 @@ module_param(fnlock_default, bool, 0444);
/* Mask to determine if setting temperature or percentage */
#define FAN_CURVE_PWM_MASK 0x04
@@ -3854,7 +1492,7 @@ index 999cd658ec8b..d016acb23789 100644
#define NVIDIA_BOOST_MIN 5
#define NVIDIA_BOOST_MAX 25
#define NVIDIA_TEMP_MIN 75
-@@ -219,6 +221,29 @@ struct fan_curve_data {
+@@ -219,6 +226,29 @@ struct fan_curve_data {
u8 percents[FAN_CURVE_POINTS];
};
@@ -3884,7 +1522,7 @@ index 999cd658ec8b..d016acb23789 100644
struct asus_wmi {
int dsts_id;
int spec;
-@@ -273,14 +298,7 @@ struct asus_wmi {
+@@ -273,20 +303,13 @@ struct asus_wmi {
bool dgpu_disable_available;
u32 gpu_mux_dev;
@@ -3900,7 +1538,144 @@ index 999cd658ec8b..d016acb23789 100644
u32 kbd_rgb_dev;
bool kbd_rgb_state_available;
-@@ -652,6 +670,98 @@ static void asus_wmi_input_exit(struct asus_wmi *asus)
+
+- bool throttle_thermal_policy_available;
+ u8 throttle_thermal_policy_mode;
++ u32 throttle_thermal_policy_dev;
+
+ bool cpu_fan_curve_available;
+ bool gpu_fan_curve_available;
+@@ -334,20 +357,29 @@ static int asus_wmi_evaluate_method3(u32 method_id,
+ status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, 0, method_id,
+ &input, &output);
+
+- if (ACPI_FAILURE(status))
++ pr_debug("%s called (0x%08x) with args: 0x%08x, 0x%08x, 0x%08x\n",
++ __func__, method_id, arg0, arg1, arg2);
++ if (ACPI_FAILURE(status)) {
++ pr_debug("%s, (0x%08x), arg 0x%08x failed: %d\n",
++ __func__, method_id, arg0, -EIO);
+ return -EIO;
++ }
+
+ obj = (union acpi_object *)output.pointer;
+ if (obj && obj->type == ACPI_TYPE_INTEGER)
+ tmp = (u32) obj->integer.value;
+
++ pr_debug("Result: 0x%08x\n", tmp);
+ if (retval)
+ *retval = tmp;
+
+ kfree(obj);
+
+- if (tmp == ASUS_WMI_UNSUPPORTED_METHOD)
++ if (tmp == ASUS_WMI_UNSUPPORTED_METHOD) {
++ pr_debug("%s, (0x%08x), arg 0x%08x failed: %d\n",
++ __func__, method_id, arg0, -ENODEV);
+ return -ENODEV;
++ }
+
+ return 0;
+ }
+@@ -377,20 +409,29 @@ static int asus_wmi_evaluate_method5(u32 method_id,
+ status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, 0, method_id,
+ &input, &output);
+
+- if (ACPI_FAILURE(status))
++ pr_debug("%s called (0x%08x) with args: 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
++ __func__, method_id, arg0, arg1, arg2, arg3, arg4);
++ if (ACPI_FAILURE(status)) {
++ pr_debug("%s, (0x%08x), arg 0x%08x failed: %d\n",
++ __func__, method_id, arg0, -EIO);
+ return -EIO;
++ }
+
+ obj = (union acpi_object *)output.pointer;
+ if (obj && obj->type == ACPI_TYPE_INTEGER)
+ tmp = (u32) obj->integer.value;
+
++ pr_debug("Result: %x\n", tmp);
+ if (retval)
+ *retval = tmp;
+
+ kfree(obj);
+
+- if (tmp == ASUS_WMI_UNSUPPORTED_METHOD)
++ if (tmp == ASUS_WMI_UNSUPPORTED_METHOD) {
++ pr_debug("%s, (0x%08x), arg 0x%08x failed: %d\n",
++ __func__, method_id, arg0, -ENODEV);
+ return -ENODEV;
++ }
+
+ return 0;
+ }
+@@ -416,8 +457,13 @@ static int asus_wmi_evaluate_method_buf(u32 method_id,
+ status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, 0, method_id,
+ &input, &output);
+
+- if (ACPI_FAILURE(status))
++ pr_debug("%s called (0x%08x) with args: 0x%08x, 0x%08x\n",
++ __func__, method_id, arg0, arg1);
++ if (ACPI_FAILURE(status)) {
++ pr_debug("%s, (0x%08x), arg 0x%08x failed: %d\n",
++ __func__, method_id, arg0, -EIO);
+ return -EIO;
++ }
+
+ obj = (union acpi_object *)output.pointer;
+
+@@ -453,8 +499,11 @@ static int asus_wmi_evaluate_method_buf(u32 method_id,
+
+ kfree(obj);
+
+- if (err)
++ if (err) {
++ pr_debug("%s, (0x%08x), arg 0x%08x failed: %d\n",
++ __func__, method_id, arg0, err);
+ return err;
++ }
+
+ return 0;
+ }
+@@ -503,12 +552,28 @@ static int asus_wmi_get_devstate(struct asus_wmi *asus, u32 dev_id, u32 *retval)
+ return 0;
+ }
+
+-static int asus_wmi_set_devstate(u32 dev_id, u32 ctrl_param,
++int asus_wmi_get_devstate_dsts(u32 dev_id, u32 *retval)
++{
++ int err;
++
++ err = asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS, dev_id, 0, retval);
++ if (err)
++ return err;
++
++ if (*retval == ~0)
++ return -ENODEV;
++
++ return 0;
++}
++EXPORT_SYMBOL_GPL(asus_wmi_get_devstate_dsts);
++
++int asus_wmi_set_devstate(u32 dev_id, u32 ctrl_param,
+ u32 *retval)
+ {
+ return asus_wmi_evaluate_method(ASUS_WMI_METHODID_DEVS, dev_id,
+ ctrl_param, retval);
+ }
++EXPORT_SYMBOL_GPL(asus_wmi_set_devstate);
+
+ /* Helper for special devices with magic return codes */
+ static int asus_wmi_get_devstate_bits(struct asus_wmi *asus,
+@@ -542,6 +607,7 @@ static bool asus_wmi_dev_is_present(struct asus_wmi *asus, u32 dev_id)
+ {
+ u32 retval;
+ int status = asus_wmi_get_devstate(asus, dev_id, &retval);
++ pr_debug("%s called (0x%08x), retval: 0x%08x\n", __func__, dev_id, retval);
+
+ return status == 0 && (retval & ASUS_WMI_DSTS_PRESENCE_BIT);
+ }
+@@ -625,6 +691,98 @@ static void asus_wmi_input_exit(struct asus_wmi *asus)
asus->inputdev = NULL;
}
@@ -3999,7 +1774,7 @@ index 999cd658ec8b..d016acb23789 100644
/* Tablet mode ****************************************************************/
static void asus_wmi_tablet_mode_get_state(struct asus_wmi *asus)
-@@ -1018,306 +1128,6 @@ static const struct attribute_group *kbd_rgb_mode_groups[] = {
+@@ -995,306 +1153,6 @@ static const struct attribute_group *kbd_rgb_mode_groups[] = {
NULL,
};
@@ -4306,7 +2081,238 @@ index 999cd658ec8b..d016acb23789 100644
/* Ally MCU Powersave ********************************************************/
static ssize_t mcu_powersave_show(struct device *dev,
struct device_attribute *attr, char *buf)
-@@ -4367,13 +4177,27 @@ static struct attribute *platform_attributes[] = {
+@@ -1685,7 +1544,8 @@ static int asus_wmi_led_init(struct asus_wmi *asus)
+ goto error;
+ }
+
+- if (!kbd_led_read(asus, &led_val, NULL)) {
++ if (!kbd_led_read(asus, &led_val, NULL) && !dmi_check_system(asus_use_hid_led_dmi_ids)) {
++ pr_info("using asus-wmi for asus::kbd_backlight\n");
+ asus->kbd_led_wk = led_val;
+ asus->kbd_led.name = "asus::kbd_backlight";
+ asus->kbd_led.flags = LED_BRIGHT_HW_CHANGED;
+@@ -2312,10 +2172,10 @@ static ssize_t mini_led_mode_store(struct device *dev,
+ return result;
+
+ if (asus->mini_led_dev_id == ASUS_WMI_DEVID_MINI_LED_MODE &&
+- mode > ASUS_MINI_LED_ON)
++ mode > ASUS_MINI_LED_ON)
+ return -EINVAL;
+ if (asus->mini_led_dev_id == ASUS_WMI_DEVID_MINI_LED_MODE2 &&
+- mode > ASUS_MINI_LED_STRONG_MODE)
++ mode > ASUS_MINI_LED_STRONG_MODE)
+ return -EINVAL;
+
+ /*
+@@ -3127,7 +2987,7 @@ static int fan_curve_get_factory_default(struct asus_wmi *asus, u32 fan_dev)
+ int err, fan_idx;
+ u8 mode = 0;
+
+- if (asus->throttle_thermal_policy_available)
++ if (asus->throttle_thermal_policy_dev)
+ mode = asus->throttle_thermal_policy_mode;
+ /* DEVID_<C/G>PU_FAN_CURVE is switched for OVERBOOST vs SILENT */
+ if (mode == 2)
+@@ -3334,7 +3194,7 @@ static ssize_t fan_curve_enable_store(struct device *dev,
+ * For machines with throttle this is the only way to reset fans
+ * to default mode of operation (does not erase curve data).
+ */
+- if (asus->throttle_thermal_policy_available) {
++ if (asus->throttle_thermal_policy_dev) {
+ err = throttle_thermal_policy_write(asus);
+ if (err)
+ return err;
+@@ -3551,8 +3411,8 @@ static const struct attribute_group asus_fan_curve_attr_group = {
+ __ATTRIBUTE_GROUPS(asus_fan_curve_attr);
+
+ /*
+- * Must be initialised after throttle_thermal_policy_check_present() as
+- * we check the status of throttle_thermal_policy_available during init.
++ * Must be initialised after throttle_thermal_policy_dev is set as
++ * we check the status of throttle_thermal_policy_dev during init.
+ */
+ static int asus_wmi_custom_fan_curve_init(struct asus_wmi *asus)
+ {
+@@ -3562,18 +3422,27 @@ static int asus_wmi_custom_fan_curve_init(struct asus_wmi *asus)
+
+ err = fan_curve_check_present(asus, &asus->cpu_fan_curve_available,
+ ASUS_WMI_DEVID_CPU_FAN_CURVE);
+- if (err)
++ if (err) {
++ pr_err("%s, checked 0x%08x, failed: %d\n",
++ __func__, ASUS_WMI_DEVID_CPU_FAN_CURVE, err);
+ return err;
++ }
+
+ err = fan_curve_check_present(asus, &asus->gpu_fan_curve_available,
+ ASUS_WMI_DEVID_GPU_FAN_CURVE);
+- if (err)
++ if (err) {
++ pr_err("%s, checked 0x%08x, failed: %d\n",
++ __func__, ASUS_WMI_DEVID_GPU_FAN_CURVE, err);
+ return err;
++ }
+
+ err = fan_curve_check_present(asus, &asus->mid_fan_curve_available,
+ ASUS_WMI_DEVID_MID_FAN_CURVE);
+- if (err)
++ if (err) {
++ pr_err("%s, checked 0x%08x, failed: %d\n",
++ __func__, ASUS_WMI_DEVID_MID_FAN_CURVE, err);
+ return err;
++ }
+
+ if (!asus->cpu_fan_curve_available
+ && !asus->gpu_fan_curve_available
+@@ -3593,38 +3462,31 @@ static int asus_wmi_custom_fan_curve_init(struct asus_wmi *asus)
+ }
+
+ /* Throttle thermal policy ****************************************************/
+-
+-static int throttle_thermal_policy_check_present(struct asus_wmi *asus)
+-{
+- u32 result;
+- int err;
+-
+- asus->throttle_thermal_policy_available = false;
+-
+- err = asus_wmi_get_devstate(asus,
+- ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY,
+- &result);
+- if (err) {
+- if (err == -ENODEV)
+- return 0;
+- return err;
+- }
+-
+- if (result & ASUS_WMI_DSTS_PRESENCE_BIT)
+- asus->throttle_thermal_policy_available = true;
+-
+- return 0;
+-}
+-
+ static int throttle_thermal_policy_write(struct asus_wmi *asus)
+ {
+- int err;
+- u8 value;
++ u8 value = asus->throttle_thermal_policy_mode;
+ u32 retval;
++ bool vivo;
++ int err;
+
+- value = asus->throttle_thermal_policy_mode;
++ vivo = asus->throttle_thermal_policy_dev == ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY_VIVO;
++ if (vivo) {
++ switch (value) {
++ case ASUS_THROTTLE_THERMAL_POLICY_DEFAULT:
++ value = ASUS_THROTTLE_THERMAL_POLICY_DEFAULT_VIVO;
++ break;
++ case ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST:
++ value = ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST_VIVO;
++ break;
++ case ASUS_THROTTLE_THERMAL_POLICY_SILENT:
++ value = ASUS_THROTTLE_THERMAL_POLICY_SILENT_VIVO;
++ break;
++ default:
++ break;
++ }
++ }
+
+- err = asus_wmi_set_devstate(ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY,
++ err = asus_wmi_set_devstate(asus->throttle_thermal_policy_dev,
+ value, &retval);
+
+ sysfs_notify(&asus->platform_device->dev.kobj, NULL,
+@@ -3654,7 +3516,7 @@ static int throttle_thermal_policy_write(struct asus_wmi *asus)
+
+ static int throttle_thermal_policy_set_default(struct asus_wmi *asus)
+ {
+- if (!asus->throttle_thermal_policy_available)
++ if (!asus->throttle_thermal_policy_dev)
+ return 0;
+
+ asus->throttle_thermal_policy_mode = ASUS_THROTTLE_THERMAL_POLICY_DEFAULT;
+@@ -3664,9 +3526,14 @@ static int throttle_thermal_policy_set_default(struct asus_wmi *asus)
+ static int throttle_thermal_policy_switch_next(struct asus_wmi *asus)
+ {
+ u8 new_mode = asus->throttle_thermal_policy_mode + 1;
++ bool vivo;
+ int err;
+
+- if (new_mode > ASUS_THROTTLE_THERMAL_POLICY_SILENT)
++ vivo = asus->throttle_thermal_policy_dev == ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY_VIVO;
++ if (!vivo && new_mode > ASUS_THROTTLE_THERMAL_POLICY_SILENT)
++ new_mode = ASUS_THROTTLE_THERMAL_POLICY_DEFAULT;
++
++ if (vivo && new_mode > ASUS_THROTTLE_THERMAL_POLICY_FULLSPEED)
+ new_mode = ASUS_THROTTLE_THERMAL_POLICY_DEFAULT;
+
+ asus->throttle_thermal_policy_mode = new_mode;
+@@ -3699,13 +3566,17 @@ static ssize_t throttle_thermal_policy_store(struct device *dev,
+ struct asus_wmi *asus = dev_get_drvdata(dev);
+ u8 new_mode;
+ int result;
++ bool vivo;
+ int err;
+
+ result = kstrtou8(buf, 10, &new_mode);
+ if (result < 0)
+ return result;
+
+- if (new_mode > ASUS_THROTTLE_THERMAL_POLICY_SILENT)
++ vivo = asus->throttle_thermal_policy_dev == ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY_VIVO;
++ if (vivo && new_mode > ASUS_THROTTLE_THERMAL_POLICY_FULLSPEED)
++ return -EINVAL;
++ else if (!vivo && new_mode > ASUS_THROTTLE_THERMAL_POLICY_SILENT)
+ return -EINVAL;
+
+ asus->throttle_thermal_policy_mode = new_mode;
+@@ -3722,7 +3593,10 @@ static ssize_t throttle_thermal_policy_store(struct device *dev,
+ return count;
+ }
+
+-// Throttle thermal policy: 0 - default, 1 - overboost, 2 - silent
++/*
++ * Throttle thermal policy: 0 - default, 1 - overboost, 2 - silent
++ * VIVOBOOK: 3 - fans full speed
++ */
+ static DEVICE_ATTR_RW(throttle_thermal_policy);
+
+ /* Platform profile ***********************************************************/
+@@ -3788,7 +3662,7 @@ static int platform_profile_setup(struct asus_wmi *asus)
+ * Not an error if a component platform_profile relies on is unavailable
+ * so early return, skipping the setup of platform_profile.
+ */
+- if (!asus->throttle_thermal_policy_available)
++ if (!asus->throttle_thermal_policy_dev)
+ return 0;
+
+ dev_info(dev, "Using throttle_thermal_policy for platform_profile support\n");
+@@ -3803,8 +3677,13 @@ static int platform_profile_setup(struct asus_wmi *asus)
+ asus->platform_profile_handler.choices);
+
+ err = platform_profile_register(&asus->platform_profile_handler);
+- if (err)
++ if (err == -EEXIST) {
++ pr_warn("%s, a platform_profile handler is already registered\n", __func__);
++ return 0;
++ } else if (err) {
++ pr_err("%s, failed at platform_profile_register: %d\n", __func__, err);
+ return err;
++ }
+
+ asus->platform_profile_support = true;
+ return 0;
+@@ -4203,7 +4082,7 @@ static void asus_wmi_handle_event_code(int code, struct asus_wmi *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)
++ if (asus->throttle_thermal_policy_dev)
+ throttle_thermal_policy_switch_next(asus);
+ return;
+
+@@ -4329,13 +4208,27 @@ static struct attribute *platform_attributes[] = {
&dev_attr_als_enable.attr,
&dev_attr_fan_boost_mode.attr,
&dev_attr_throttle_thermal_policy.attr,
@@ -4335,11 +2341,13 @@ index 999cd658ec8b..d016acb23789 100644
&dev_attr_mcu_powersave.attr,
&dev_attr_boot_sound.attr,
&dev_attr_panel_od.attr,
-@@ -4294,19 +4294,33 @@
+@@ -4375,20 +4268,34 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj,
+ else if (attr == &dev_attr_fan_boost_mode.attr)
ok = asus->fan_boost_mode_available;
else if (attr == &dev_attr_throttle_thermal_policy.attr)
- ok = asus->throttle_thermal_policy_dev != 0;
+- ok = asus->throttle_thermal_policy_available;
- else if (attr == &dev_attr_ppt_pl2_sppt.attr)
++ ok = asus->throttle_thermal_policy_dev != 0;
+ else if (attr == &dev_attr_ppt_pl2_sppt.attr
+ || attr == &dev_attr_ppt_pl2_sppt_min.attr
+ || attr == &dev_attr_ppt_pl2_sppt_max.attr)
@@ -4376,7 +2384,19 @@ index 999cd658ec8b..d016acb23789 100644
devid = ASUS_WMI_DEVID_NV_THERM_TARGET;
else if (attr == &dev_attr_mcu_powersave.attr)
devid = ASUS_WMI_DEVID_MCU_POWERSAVE;
-@@ -4652,6 +4490,77 @@ static void asus_wmi_debugfs_init(struct asus_wmi *asus)
+@@ -4401,8 +4308,10 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj,
+ else if (attr == &dev_attr_available_mini_led_mode.attr)
+ ok = asus->mini_led_dev_id != 0;
+
+- if (devid != -1)
++ if (devid != -1) {
+ ok = !(asus_wmi_get_devstate_simple(asus, devid) < 0);
++ pr_debug("%s called 0x%08x, ok: %x\n", __func__, devid, ok);
++ }
+
+ return ok ? attr->mode : 0;
+ }
+@@ -4612,6 +4521,77 @@ static void asus_wmi_debugfs_init(struct asus_wmi *asus)
/* Init / exit ****************************************************************/
@@ -4454,7 +2474,7 @@ index 999cd658ec8b..d016acb23789 100644
static int asus_wmi_add(struct platform_device *pdev)
{
struct platform_driver *pdrv = to_platform_driver(pdev->dev.driver);
-@@ -4677,15 +4586,7 @@ static int asus_wmi_add(struct platform_device *pdev)
+@@ -4637,15 +4617,7 @@ static int asus_wmi_add(struct platform_device *pdev)
if (err)
goto fail_platform;
@@ -4471,6 +2491,142 @@ index 999cd658ec8b..d016acb23789 100644
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->kbd_rgb_state_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_STATE);
---
-2.45.1
-
+@@ -4667,18 +4639,17 @@ static int asus_wmi_add(struct platform_device *pdev)
+ else if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_MODE2))
+ asus->kbd_rgb_dev = ASUS_WMI_DEVID_TUF_RGB_MODE2;
+
++ if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY))
++ asus->throttle_thermal_policy_dev = ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY;
++ else if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY_VIVO))
++ asus->throttle_thermal_policy_dev = ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY_VIVO;
++
+ err = fan_boost_mode_check_present(asus);
+ if (err)
+ goto fail_fan_boost_mode;
+
+- err = throttle_thermal_policy_check_present(asus);
+- if (err)
+- goto fail_throttle_thermal_policy;
+- else
+- throttle_thermal_policy_set_default(asus);
+-
+ err = platform_profile_setup(asus);
+- if (err)
++ if (err && err != -EEXIST)
+ goto fail_platform_profile_setup;
+
+ err = asus_wmi_sysfs_init(asus->platform_device);
+@@ -4771,7 +4742,6 @@ static int asus_wmi_add(struct platform_device *pdev)
+ fail_input:
+ asus_wmi_sysfs_exit(asus->platform_device);
+ fail_sysfs:
+-fail_throttle_thermal_policy:
+ fail_custom_fan_curve:
+ fail_platform_profile_setup:
+ if (asus->platform_profile_support)
+diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
+index 3eb5cd6773ad..870f4bb57100 100644
+--- a/include/linux/platform_data/x86/asus-wmi.h
++++ b/include/linux/platform_data/x86/asus-wmi.h
+@@ -4,6 +4,7 @@
+
+ #include <linux/errno.h>
+ #include <linux/types.h>
++#include <linux/dmi.h>
+
+ /* WMI Methods */
+ #define ASUS_WMI_METHODID_SPEC 0x43455053 /* BIOS SPECification */
+@@ -64,8 +65,10 @@
+ #define ASUS_WMI_DEVID_SCREENPAD_LIGHT 0x00050032
+ #define ASUS_WMI_DEVID_FAN_BOOST_MODE 0x00110018
+ #define ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY 0x00120075
++#define ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY_VIVO 0x00110019
+
+ /* Misc */
++#define ASUS_WMI_DEVID_PANEL_HD 0x0005001C
+ #define ASUS_WMI_DEVID_PANEL_OD 0x00050019
+ #define ASUS_WMI_DEVID_CAMERA 0x00060013
+ #define ASUS_WMI_DEVID_LID_FLIP 0x00060062
+@@ -126,6 +129,14 @@
+ /* dgpu on/off */
+ #define ASUS_WMI_DEVID_DGPU 0x00090020
+
++/* Intel E-core and P-core configuration in a format 0x0[E]0[P] */
++#define ASUS_WMI_DEVID_CORES 0x001200D2
++ /* Maximum Intel E-core and P-core availability */
++#define ASUS_WMI_DEVID_CORES_MAX 0x001200D3
++#define ASUS_WMI_DEVID_DGPU_BASE_TGP 0x00120099
++#define ASUS_WMI_DEVID_DGPU_SET_TGP 0x00120098
++#define ASUS_WMI_DEVID_APU_MEM 0x000600C1
++
+ /* gpu mux switch, 0 = dGPU, 1 = Optimus */
+ #define ASUS_WMI_DEVID_GPU_MUX 0x00090016
+ #define ASUS_WMI_DEVID_GPU_MUX_VIVO 0x00090026
+@@ -151,8 +162,18 @@
+ #define ASUS_WMI_DSTS_LIGHTBAR_MASK 0x0000000F
+
+ #if IS_REACHABLE(CONFIG_ASUS_WMI)
++int asus_wmi_get_devstate_dsts(u32 dev_id, u32 *retval);
++int asus_wmi_set_devstate(u32 dev_id, u32 ctrl_param, u32 *retval);
+ int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1, u32 *retval);
+ #else
++static int asus_wmi_get_devstate_dsts(u32 dev_id, u32 *retval)
++{
++ return -ENODEV;
++}
++static int asus_wmi_set_devstate(u32 dev_id, u32 ctrl_param, u32 *retval)
++{
++ return -ENODEV;
++}
+ static inline int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1,
+ u32 *retval)
+ {
+@@ -160,4 +181,48 @@ static inline int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1,
+ }
+ #endif
+
++/* To be used by both hid-asus and asus-wmi to determine which controls kbd_brightness */
++#if IS_ENABLED(CONFIG_ASUS_WMI)
++bool asus_use_hid_led(void);
++#else
++static inline bool asus_use_hid_led(void)
++{
++ return true;
++}
++#endif
++
++static const struct dmi_system_id asus_use_hid_led_dmi_ids[] = {
++ {
++ .matches = {
++ DMI_MATCH(DMI_PRODUCT_FAMILY, "ROG Zephyrus"),
++ },
++ },
++ {
++ .matches = {
++ DMI_MATCH(DMI_PRODUCT_FAMILY, "ROG Strix"),
++ },
++ },
++ {
++ .matches = {
++ DMI_MATCH(DMI_PRODUCT_FAMILY, "ROG Flow"),
++ },
++ },
++ {
++ .matches = {
++ DMI_MATCH(DMI_BOARD_NAME, "GA403U"),
++ },
++ },
++ {
++ .matches = {
++ DMI_MATCH(DMI_BOARD_NAME, "GU605M"),
++ },
++ },
++ {
++ .matches = {
++ DMI_MATCH(DMI_BOARD_NAME, "RC71L"),
++ },
++ },
++ NULL,
++};
++
+ #endif /* __PLATFORM_DATA_X86_ASUS_WMI_H */