diff options
Diffstat (limited to 'SOURCES/asus-linux.patch')
-rw-r--r-- | SOURCES/asus-linux.patch | 1328 |
1 files changed, 0 insertions, 1328 deletions
diff --git a/SOURCES/asus-linux.patch b/SOURCES/asus-linux.patch deleted file mode 100644 index 1276952..0000000 --- a/SOURCES/asus-linux.patch +++ /dev/null @@ -1,1328 +0,0 @@ -From 0afaa446a07db0ded4c032511b35485bd12ff80f Mon Sep 17 00:00:00 2001 -From: Jan200101 <sentrycraft123@gmail.com> -Date: Sat, 17 Dec 2022 18:14:04 +0100 -Subject: [PATCH] asus-linux - -Signed-off-by: Jan200101 <sentrycraft123@gmail.com> ---- - .../ABI/testing/sysfs-platform-asus-wmi | 41 ++ - drivers/hid/amd-sfh-hid/amd_sfh_pcie.c | 4 + - drivers/hid/amd-sfh-hid/amd_sfh_pcie.h | 1 + - .../hid_descriptor/amd_sfh_hid_desc.c | 27 + - .../hid_descriptor/amd_sfh_hid_desc.h | 8 + - .../hid_descriptor/amd_sfh_hid_report_desc.h | 19 + - drivers/platform/x86/asus-nb-wmi.c | 14 +- - drivers/platform/x86/asus-wmi.c | 677 ++++++++++-------- - include/linux/platform_data/x86/asus-wmi.h | 10 + - 9 files changed, 503 insertions(+), 298 deletions(-) - -diff --git a/Documentation/ABI/testing/sysfs-platform-asus-wmi b/Documentation/ABI/testing/sysfs-platform-asus-wmi -index 04885738cf15..a77a004a1baa 100644 ---- a/Documentation/ABI/testing/sysfs-platform-asus-wmi -+++ b/Documentation/ABI/testing/sysfs-platform-asus-wmi -@@ -57,3 +57,44 @@ Description: - * 0 - default, - * 1 - overboost, - * 2 - silent -+ -+What: /sys/devices/platform/<platform>/gpu_mux_mode -+Date: Aug 2022 -+KernelVersion: 6.1 -+Contact: "Luke Jones" <luke@ljones.dev> -+Description: -+ Switch the GPU hardware MUX mode. Laptops with this feature can -+ can be toggled to boot with only the dGPU (discrete mode) or in -+ standard Optimus/Hybrid mode. On switch a reboot is required: -+ -+ * 0 - Discrete GPU, -+ * 1 - Optimus/Hybrid, -+ -+What: /sys/devices/platform/<platform>/dgpu_disable -+Date: Aug 2022 -+KernelVersion: 5.17 -+Contact: "Luke Jones" <luke@ljones.dev> -+Description: -+ Disable discrete GPU: -+ * 0 - Enable dGPU, -+ * 1 - Disable dGPU -+ -+What: /sys/devices/platform/<platform>/egpu_enable -+Date: Aug 2022 -+KernelVersion: 5.17 -+Contact: "Luke Jones" <luke@ljones.dev> -+Description: -+ Enable the external GPU paired with ROG X-Flow laptops. -+ Toggling this setting will also trigger ACPI to disable the dGPU: -+ -+ * 0 - Disable, -+ * 1 - Enable -+ -+What: /sys/devices/platform/<platform>/panel_od -+Date: Aug 2022 -+KernelVersion: 5.17 -+Contact: "Luke Jones" <luke@ljones.dev> -+Description: -+ Enable an LCD response-time boost to reduce or remove ghosting: -+ * 0 - Disable, -+ * 1 - Enable -diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c -index 47774b9ab3de..a03f0968e82f 100644 ---- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c -+++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c -@@ -27,6 +27,7 @@ - #define ACEL_EN BIT(0) - #define GYRO_EN BIT(1) - #define MAGNO_EN BIT(2) -+#define KBGUARD_EN BIT(15) - #define HPD_EN BIT(16) - #define ALS_EN BIT(19) - -@@ -233,6 +234,9 @@ int amd_mp2_get_sensor_num(struct amd_mp2_dev *privdata, u8 *sensor_id) - if (HPD_EN & activestatus) - sensor_id[num_of_sensors++] = HPD_IDX; - -+ if (KBGUARD_EN & activestatus) -+ sensor_id[num_of_sensors++] = KBGUARD_IDX; -+ - return num_of_sensors; - } - -diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h -index dfb7cabd82ef..5fa15eed43f3 100644 ---- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h -+++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h -@@ -23,6 +23,7 @@ - #define V2_STATUS 0x2 - - #define HPD_IDX 16 -+#define KBGUARD_IDX 15 - - #define SENSOR_DISCOVERY_STATUS_MASK GENMASK(5, 3) - #define SENSOR_DISCOVERY_STATUS_SHIFT 3 -diff --git a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.c b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.c -index f9a8c02d5a7b..06487eb75dc8 100644 ---- a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.c -+++ b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.c -@@ -57,6 +57,11 @@ static int get_report_descriptor(int sensor_idx, u8 *rep_desc) - memcpy(rep_desc, hpd_report_descriptor, - sizeof(hpd_report_descriptor)); - break; -+ case KBGUARD_IDX: /* kbguard ? */ -+ memset(rep_desc, 0, sizeof(kbguard_report_descriptor)); -+ memcpy(rep_desc, kbguard_report_descriptor, -+ sizeof(kbguard_report_descriptor)); -+ break; - default: - break; - } -@@ -116,6 +121,16 @@ static u32 get_descr_sz(int sensor_idx, int descriptor_name) - return sizeof(struct hpd_feature_report); - } - break; -+ case KBGUARD_IDX: -+ switch (descriptor_name) { -+ case descr_size: -+ return sizeof(kbguard_report_descriptor); -+ case input_size: -+ return sizeof(struct kbguard_input_report); -+ case feature_size: -+ return sizeof(struct kbguard_feature_report); -+ } -+ break; - - default: - break; -@@ -139,6 +154,7 @@ static u8 get_feature_report(int sensor_idx, int report_id, u8 *feature_report) - struct gyro_feature_report gyro_feature; - struct magno_feature_report magno_feature; - struct hpd_feature_report hpd_feature; -+ struct kbguard_feature_report kbguard_feature; - struct als_feature_report als_feature; - u8 report_size = 0; - -@@ -186,6 +202,11 @@ static u8 get_feature_report(int sensor_idx, int report_id, u8 *feature_report) - memcpy(feature_report, &hpd_feature, sizeof(hpd_feature)); - report_size = sizeof(hpd_feature); - break; -+ case KBGUARD_IDX: /* auto disable keyboard when flip out */ -+ get_common_features(&kbguard_feature.common_property, report_id); -+ memcpy(feature_report, &kbguard_feature, sizeof(kbguard_feature)); -+ report_size = sizeof(kbguard_feature); -+ break; - - default: - break; -@@ -211,6 +232,7 @@ static u8 get_input_report(u8 current_index, int sensor_idx, int report_id, - struct accel3_input_report acc_input; - struct gyro_input_report gyro_input; - struct hpd_input_report hpd_input; -+ struct kbguard_input_report kbguard_input; - struct als_input_report als_input; - struct hpd_status hpdstatus; - u8 report_size = 0; -@@ -263,6 +285,11 @@ static u8 get_input_report(u8 current_index, int sensor_idx, int report_id, - report_size = sizeof(hpd_input); - memcpy(input_report, &hpd_input, sizeof(hpd_input)); - break; -+ case KBGUARD_IDX: /* kb guard */ -+ get_common_inputs(&kbguard_input.common_property, report_id); -+ report_size = sizeof(kbguard_input); -+ memcpy(input_report, &kbguard_input, sizeof(kbguard_input)); -+break; - default: - break; - } -diff --git a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h -index ebd55675eb62..2f2ba9a0cfbc 100644 ---- a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h -+++ b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h -@@ -111,4 +111,12 @@ struct hpd_input_report { - u8 human_presence; - } __packed; - -+struct kbguard_feature_report { -+ struct common_feature_property common_property; -+} __packed; -+ -+struct kbguard_input_report { -+ struct common_input_property common_property; -+} __packed; -+ - #endif -diff --git a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h -index 697f2791ea9c..7a62fcec2c73 100644 ---- a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h -+++ b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h -@@ -644,6 +644,25 @@ static const u8 als_report_descriptor[] = { - 0xC0 /* HID end collection */ - }; - -+ -+static const u8 kbguard_report_descriptor[] = { -+0x06, 0x43, 0xFF, // Usage Page (Vendor Defined 0xFF43) -+0x0A, 0x02, 0x02, // Usage (0x0202) -+0xA1, 0x01, // Collection (Application) -+0x85, 0x11, // Report ID (17) -+0x15, 0x00, // Logical Minimum (0) -+0x25, 0x01, // Logical Maximum (1) -+0x35, 0x00, // Physical Minimum (0) -+0x45, 0x01, // Physical Maximum (1) -+0x65, 0x00, // Unit (None) -+0x55, 0x00, // Unit Exponent (0) -+0x75, 0x01, // Report Size (1) -+0x95, 0x98, // Report Count (-104) -+0x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) -+0x91, 0x03, // Output (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) -+0xC1, 0x00, // End Collection -+}; -+ - /* BIOMETRIC PRESENCE*/ - static const u8 hpd_report_descriptor[] = { - 0x05, 0x20, /* Usage page */ -diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c -index d9e7cf6e4a0e..fcfe6dddd645 100644 ---- a/drivers/platform/x86/asus-nb-wmi.c -+++ b/drivers/platform/x86/asus-nb-wmi.c -@@ -504,17 +504,8 @@ static void asus_nb_wmi_quirks(struct asus_wmi_driver *driver) - else - wapf = quirks->wapf; - -- switch (tablet_mode_sw) { -- case 0: -- quirks->tablet_switch_mode = asus_wmi_no_tablet_switch; -- break; -- case 1: -- quirks->tablet_switch_mode = asus_wmi_kbd_dock_devid; -- break; -- case 2: -- quirks->tablet_switch_mode = asus_wmi_lid_flip_devid; -- break; -- } -+ if (tablet_mode_sw != -1) -+ quirks->tablet_switch_mode = tablet_mode_sw; - - if (quirks->i8042_filter) { - ret = i8042_install_filter(quirks->i8042_filter); -@@ -586,6 +577,7 @@ static const struct key_entry asus_nb_wmi_keymap[] = { - { KE_KEY, 0xA5, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + TV + HDMI */ - { KE_KEY, 0xA6, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT + TV + HDMI */ - { KE_KEY, 0xA7, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + CRT + TV + HDMI */ -+ { KE_KEY, 0xAE, { KEY_FN_F5 } }, /* Fn+F5 fan mode on 2020+ */ - { KE_KEY, 0xB3, { KEY_PROG4 } }, /* AURA */ - { KE_KEY, 0xB5, { KEY_CALC } }, - { KE_KEY, 0xC4, { KEY_KBDILLUMUP } }, -diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c -index dce93187e11f..40e911467037 100644 ---- a/drivers/platform/x86/asus-wmi.c -+++ b/drivers/platform/x86/asus-wmi.c -@@ -72,6 +72,7 @@ module_param(fnlock_default, bool, 0444); - - #define ASUS_WMI_FNLOCK_BIOS_DISABLED BIT(0) - -+#define ASUS_GPU_FAN_DESC "gpu_fan" - #define ASUS_FAN_DESC "cpu_fan" - #define ASUS_FAN_MFUN 0x13 - #define ASUS_FAN_SFUN_READ 0x06 -@@ -222,19 +223,25 @@ struct asus_wmi { - struct asus_rfkill gps; - struct asus_rfkill uwb; - -+ int tablet_switch_event_code; -+ u32 tablet_switch_dev_id; -+ - enum fan_type fan_type; -+ enum fan_type gpu_fan_type; - int fan_pwm_mode; -+ int gpu_fan_pwm_mode; - int agfn_pwm; - - bool fan_boost_mode_available; - u8 fan_boost_mode_mask; - u8 fan_boost_mode; - -- bool egpu_enable_available; // 0 = enable -- bool egpu_enable; -- -+ bool egpu_enable_available; - bool dgpu_disable_available; -- bool dgpu_disable; -+ bool gpu_mux_mode_available; -+ -+ bool kbd_rgb_mode_available; -+ bool kbd_rgb_state_available; - - bool throttle_thermal_policy_available; - u8 throttle_thermal_policy_mode; -@@ -250,7 +257,6 @@ struct asus_wmi { - bool battery_rsoc_available; - - bool panel_overdrive_available; -- bool panel_overdrive; - - struct hotplug_slot hotplug_slot; - struct mutex hotplug_lock; -@@ -487,13 +493,28 @@ static bool asus_wmi_dev_is_present(struct asus_wmi *asus, u32 dev_id) - } - - /* Input **********************************************************************/ -+static void asus_wmi_tablet_sw_init(struct asus_wmi *asus, u32 dev_id, int event_code) -+{ -+ struct device *dev = &asus->platform_device->dev; -+ int result; -+ -+ result = asus_wmi_get_devstate_simple(asus, dev_id); -+ if (result >= 0) { -+ input_set_capability(asus->inputdev, EV_SW, SW_TABLET_MODE); -+ input_report_switch(asus->inputdev, SW_TABLET_MODE, result); -+ asus->tablet_switch_dev_id = dev_id; -+ asus->tablet_switch_event_code = event_code; -+ } else if (result == -ENODEV) { -+ dev_err(dev, "This device has tablet-mode-switch quirk but got ENODEV checking it. This is a bug."); -+ } else { -+ dev_err(dev, "Error checking for tablet-mode-switch: %d\n", result); -+ } -+} - - static int asus_wmi_input_init(struct asus_wmi *asus) - { -- struct device *dev; -- int err, result; -- -- dev = &asus->platform_device->dev; -+ struct device *dev = &asus->platform_device->dev; -+ int err; - - asus->inputdev = input_allocate_device(); - if (!asus->inputdev) -@@ -513,39 +534,13 @@ static int asus_wmi_input_init(struct asus_wmi *asus) - case asus_wmi_no_tablet_switch: - break; - case asus_wmi_kbd_dock_devid: -- result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_KBD_DOCK); -- if (result >= 0) { -- input_set_capability(asus->inputdev, EV_SW, SW_TABLET_MODE); -- input_report_switch(asus->inputdev, SW_TABLET_MODE, !result); -- } else if (result != -ENODEV) { -- dev_err(dev, "Error checking for keyboard-dock: %d\n", result); -- } -+ asus_wmi_tablet_sw_init(asus, ASUS_WMI_DEVID_KBD_DOCK, NOTIFY_KBD_DOCK_CHANGE); - break; - case asus_wmi_lid_flip_devid: -- result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_LID_FLIP); -- if (result < 0) -- asus->driver->quirks->tablet_switch_mode = asus_wmi_no_tablet_switch; -- if (result >= 0) { -- input_set_capability(asus->inputdev, EV_SW, SW_TABLET_MODE); -- input_report_switch(asus->inputdev, SW_TABLET_MODE, result); -- } else if (result == -ENODEV) { -- dev_err(dev, "This device has lid_flip quirk but got ENODEV checking it. This is a bug."); -- } else { -- dev_err(dev, "Error checking for lid-flip: %d\n", result); -- } -+ asus_wmi_tablet_sw_init(asus, ASUS_WMI_DEVID_LID_FLIP, NOTIFY_LID_FLIP); - break; - case asus_wmi_lid_flip_rog_devid: -- result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_LID_FLIP_ROG); -- if (result < 0) -- asus->driver->quirks->tablet_switch_mode = asus_wmi_no_tablet_switch; -- if (result >= 0) { -- input_set_capability(asus->inputdev, EV_SW, SW_TABLET_MODE); -- input_report_switch(asus->inputdev, SW_TABLET_MODE, result); -- } else if (result == -ENODEV) { -- dev_err(dev, "This device has lid-flip-rog quirk but got ENODEV checking it. This is a bug."); -- } else { -- dev_err(dev, "Error checking for lid-flip: %d\n", result); -- } -+ asus_wmi_tablet_sw_init(asus, ASUS_WMI_DEVID_LID_FLIP_ROG, NOTIFY_LID_FLIP_ROG); - break; - } - -@@ -570,22 +565,14 @@ static void asus_wmi_input_exit(struct asus_wmi *asus) - - /* Tablet mode ****************************************************************/ - --static void lid_flip_tablet_mode_get_state(struct asus_wmi *asus) -+static void asus_wmi_tablet_mode_get_state(struct asus_wmi *asus) - { - int result; - -- result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_LID_FLIP); -- if (result >= 0) { -- input_report_switch(asus->inputdev, SW_TABLET_MODE, result); -- input_sync(asus->inputdev); -- } --} -- --static void lid_flip_rog_tablet_mode_get_state(struct asus_wmi *asus) --{ -- int result; -+ if (!asus->tablet_switch_dev_id) -+ return; - -- result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_LID_FLIP_ROG); -+ result = asus_wmi_get_devstate_simple(asus, asus->tablet_switch_dev_id); - if (result >= 0) { - input_report_switch(asus->inputdev, SW_TABLET_MODE, result); - input_sync(asus->inputdev); -@@ -593,179 +580,267 @@ static void lid_flip_rog_tablet_mode_get_state(struct asus_wmi *asus) - } - - /* dGPU ********************************************************************/ --static int dgpu_disable_check_present(struct asus_wmi *asus) -+static ssize_t dgpu_disable_show(struct device *dev, -+ struct device_attribute *attr, char *buf) - { -- u32 result; -- int err; -- -- asus->dgpu_disable_available = false; -- -- err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_DGPU, &result); -- if (err) { -- if (err == -ENODEV) -- return 0; -- return err; -- } -+ struct asus_wmi *asus = dev_get_drvdata(dev); -+ int result; - -- if (result & ASUS_WMI_DSTS_PRESENCE_BIT) { -- asus->dgpu_disable_available = true; -- asus->dgpu_disable = result & ASUS_WMI_DSTS_STATUS_BIT; -- } -+ result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_DGPU); -+ if (result < 0) -+ return result; - -- return 0; -+ return sysfs_emit(buf, "%d\n", result); - } - --static int dgpu_disable_write(struct asus_wmi *asus) -+/* -+ * A user may be required to store the value twice, typcial store first, then -+ * rescan PCI bus to activate power, then store a second time to save correctly. -+ * The reason for this is that an extra code path in the ACPI is enabled when -+ * the device and bus are powered. -+ */ -+static ssize_t dgpu_disable_store(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) - { -- u32 retval; -- u8 value; -- int err; -+ int result, err; -+ u32 disable; - -- /* Don't rely on type conversion */ -- value = asus->dgpu_disable ? 1 : 0; -+ struct asus_wmi *asus = dev_get_drvdata(dev); - -- err = asus_wmi_set_devstate(ASUS_WMI_DEVID_DGPU, value, &retval); -+ result = kstrtou32(buf, 10, &disable); -+ if (result) -+ return result; -+ -+ if (disable > 1) -+ return -EINVAL; -+ -+ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_DGPU, disable, &result); - if (err) { - pr_warn("Failed to set dgpu disable: %d\n", err); - return err; - } - -- if (retval > 1) { -- pr_warn("Failed to set dgpu disable (retval): 0x%x\n", retval); -+ if (result > 1) { -+ pr_warn("Failed to set dgpu disable (result): 0x%x\n", result); - return -EIO; - } - - sysfs_notify(&asus->platform_device->dev.kobj, NULL, "dgpu_disable"); - -- return 0; -+ return count; - } -+static DEVICE_ATTR_RW(dgpu_disable); - --static ssize_t dgpu_disable_show(struct device *dev, -+/* eGPU ********************************************************************/ -+static ssize_t egpu_enable_show(struct device *dev, - struct device_attribute *attr, char *buf) - { - struct asus_wmi *asus = dev_get_drvdata(dev); -- u8 mode = asus->dgpu_disable; -+ int result; - -- return sysfs_emit(buf, "%d\n", mode); -+ result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_EGPU); -+ if (result < 0) -+ return result; -+ -+ return sysfs_emit(buf, "%d\n", result); - } - --/* -- * A user may be required to store the value twice, typcial store first, then -- * rescan PCI bus to activate power, then store a second time to save correctly. -- * The reason for this is that an extra code path in the ACPI is enabled when -- * the device and bus are powered. -- */ --static ssize_t dgpu_disable_store(struct device *dev, -+/* The ACPI call to enable the eGPU also disables the internal dGPU */ -+static ssize_t egpu_enable_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) - { -- bool disable; -- int result; -+ int result, err; -+ u32 enable; - - struct asus_wmi *asus = dev_get_drvdata(dev); - -- result = kstrtobool(buf, &disable); -- if (result) -- return result; -+ err = kstrtou32(buf, 10, &enable); -+ if (err) -+ return err; - -- asus->dgpu_disable = disable; -+ if (enable > 1) -+ return -EINVAL; - -- result = dgpu_disable_write(asus); -- if (result) -- return result; -+ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_EGPU, enable, &result); -+ if (err) { -+ pr_warn("Failed to set egpu disable: %d\n", err); -+ return err; -+ } -+ -+ if (result > 1) { -+ pr_warn("Failed to set egpu disable (retval): 0x%x\n", result); -+ return -EIO; -+ } -+ -+ sysfs_notify(&asus->platform_device->dev.kobj, NULL, "egpu_enable"); - - return count; - } -+static DEVICE_ATTR_RW(egpu_enable); - --static DEVICE_ATTR_RW(dgpu_disable); -+/* gpu mux switch *************************************************************/ -+static ssize_t gpu_mux_mode_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct asus_wmi *asus = dev_get_drvdata(dev); -+ int result; - --/* eGPU ********************************************************************/ --static int egpu_enable_check_present(struct asus_wmi *asus) -+ result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_GPU_MUX); -+ if (result < 0) -+ return result; -+ -+ return sysfs_emit(buf, "%d\n", result); -+} -+ -+static ssize_t gpu_mux_mode_store(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) - { -- u32 result; -- int err; -+ struct asus_wmi *asus = dev_get_drvdata(dev); -+ int result, err; -+ u32 optimus; - -- asus->egpu_enable_available = false; -+ err = kstrtou32(buf, 10, &optimus); -+ if (err) -+ return err; - -- err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_EGPU, &result); -+ if (optimus > 1) -+ return -EINVAL; -+ -+ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_GPU_MUX, optimus, &result); - if (err) { -- if (err == -ENODEV) -- return 0; -+ dev_err(dev, "Failed to set GPU MUX mode: %d\n", err); - return err; - } -- -- if (result & ASUS_WMI_DSTS_PRESENCE_BIT) { -- asus->egpu_enable_available = true; -- asus->egpu_enable = result & ASUS_WMI_DSTS_STATUS_BIT; -+ /* !1 is considered a fail by ASUS */ -+ if (result != 1) { -+ dev_warn(dev, "Failed to set GPU MUX mode (result): 0x%x\n", result); -+ return -EIO; - } - -- return 0; -+ sysfs_notify(&asus->platform_device->dev.kobj, NULL, "gpu_mux_mode"); -+ -+ return count; - } -+static DEVICE_ATTR_RW(gpu_mux_mode); - --static int egpu_enable_write(struct asus_wmi *asus) -+/* TUF Laptop Keyboard RGB Modes **********************************************/ -+static ssize_t kbd_rgb_mode_store(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) - { -- u32 retval; -- u8 value; -+ u32 cmd, mode, r, g, b, speed; - int err; - -- /* Don't rely on type conversion */ -- value = asus->egpu_enable ? 1 : 0; -+ if (sscanf(buf, "%d %d %d %d %d %d", &cmd, &mode, &r, &g, &b, &speed) != 6) -+ return -EINVAL; - -- err = asus_wmi_set_devstate(ASUS_WMI_DEVID_EGPU, value, &retval); -+ cmd = !!cmd; - -- if (err) { -- pr_warn("Failed to set egpu disable: %d\n", err); -- return err; -- } -+ /* These are the known usable modes across all TUF/ROG */ -+ if (mode >= 12 || mode == 9) -+ mode = 10; - -- if (retval > 1) { -- pr_warn("Failed to set egpu disable (retval): 0x%x\n", retval); -- return -EIO; -+ switch (speed) { -+ case 0: -+ speed = 0xe1; -+ break; -+ case 1: -+ speed = 0xeb; -+ break; -+ case 2: -+ speed = 0xf5; -+ break; -+ default: -+ speed = 0xeb; - } - -- sysfs_notify(&asus->platform_device->dev.kobj, NULL, "egpu_enable"); -+ err = asus_wmi_evaluate_method3(ASUS_WMI_METHODID_DEVS, ASUS_WMI_DEVID_TUF_RGB_MODE, -+ cmd | (mode << 8) | (r << 16) | (g << 24), b | (speed << 8), NULL); -+ if (err) -+ return err; - -- return 0; -+ return count; - } -+static DEVICE_ATTR_WO(kbd_rgb_mode); - --static ssize_t egpu_enable_show(struct device *dev, -- struct device_attribute *attr, char *buf) -+static ssize_t kbd_rgb_mode_index_show(struct device *device, -+ struct device_attribute *attr, -+ char *buf) - { -- struct asus_wmi *asus = dev_get_drvdata(dev); -- bool mode = asus->egpu_enable; -- -- return sysfs_emit(buf, "%d\n", mode); -+ return sysfs_emit(buf, "%s\n", "cmd mode red green blue speed"); - } -+static DEVICE_ATTR_RO(kbd_rgb_mode_index); - --/* The ACPI call to enable the eGPU also disables the internal dGPU */ --static ssize_t egpu_enable_store(struct device *dev, -- struct device_attribute *attr, -- const char *buf, size_t count) --{ -- bool enable; -- int result; -- -- struct asus_wmi *asus = dev_get_drvdata(dev); -+static struct attribute *kbd_rgb_mode_attrs[] = { -+ &dev_attr_kbd_rgb_mode.attr, -+ &dev_attr_kbd_rgb_mode_index.attr, -+ NULL, -+}; - -- result = kstrtobool(buf, &enable); -- if (result) -- return result; -+static const struct attribute_group kbd_rgb_mode_group = { -+ .attrs = kbd_rgb_mode_attrs, -+}; - -- asus->egpu_enable = enable; -+/* TUF Laptop Keyboard RGB State **********************************************/ -+static ssize_t kbd_rgb_state_store(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ u32 flags, cmd, boot, awake, sleep, keyboard; -+ int err; - -- result = egpu_enable_write(asus); -- if (result) -- return result; -+ if (sscanf(buf, "%d %d %d %d %d", &cmd, &boot, &awake, &sleep, &keyboard) != 5) -+ return -EINVAL; - -- /* Ensure that the kernel status of dgpu is updated */ -- result = dgpu_disable_check_present(asus); -- if (result) -- return result; -+ if (cmd) -+ cmd = BIT(2); -+ -+ flags = 0; -+ if (boot) -+ flags |= BIT(1); -+ if (awake) -+ flags |= BIT(3); -+ if (sleep) -+ flags |= BIT(5); -+ if (keyboard) -+ flags |= BIT(7); -+ -+ /* 0xbd is the required default arg0 for the method. Nothing happens otherwise */ -+ err = asus_wmi_evaluate_method3(ASUS_WMI_METHODID_DEVS, -+ ASUS_WMI_DEVID_TUF_RGB_STATE, 0xbd | cmd << 8 | (flags << 16), 0, NULL); -+ if (err) -+ return err; - - return count; - } -+static DEVICE_ATTR_WO(kbd_rgb_state); - --static DEVICE_ATTR_RW(egpu_enable); -+static ssize_t kbd_rgb_state_index_show(struct device *device, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ return sysfs_emit(buf, "%s\n", "cmd boot awake sleep keyboard"); -+} -+static DEVICE_ATTR_RO(kbd_rgb_state_index); -+ -+static struct attribute *kbd_rgb_state_attrs[] = { -+ &dev_attr_kbd_rgb_state.attr, -+ &dev_attr_kbd_rgb_state_index.attr, -+ NULL, -+}; -+ -+static const struct attribute_group kbd_rgb_state_group = { -+ .attrs = kbd_rgb_state_attrs, -+}; -+ -+const struct attribute_group *kbd_rgb_mode_groups[] = { -+ NULL, -+ NULL, -+ NULL, -+}; - - /* Battery ********************************************************************/ - -@@ -803,7 +878,7 @@ static ssize_t charge_control_end_threshold_show(struct device *device, - struct device_attribute *attr, - char *buf) - { -- return sprintf(buf, "%d\n", charge_end_threshold); -+ return sysfs_emit(buf, "%d\n", charge_end_threshold); - } - - static DEVICE_ATTR_RW(charge_control_end_threshold); -@@ -1085,7 +1160,12 @@ static void asus_wmi_led_exit(struct asus_wmi *asus) - - static int asus_wmi_led_init(struct asus_wmi *asus) - { -- int rv = 0, led_val; -+ int rv = 0, num_rgb_groups = 0, led_val; -+ -+ if (asus->kbd_rgb_mode_available) -+ kbd_rgb_mode_groups[num_rgb_groups++] = &kbd_rgb_mode_group; -+ if (asus->kbd_rgb_state_available) -+ kbd_rgb_mode_groups[num_rgb_groups++] = &kbd_rgb_state_group; - - asus->led_workqueue = create_singlethread_workqueue("led_workqueue"); - if (!asus->led_workqueue) -@@ -1113,6 +1193,9 @@ static int asus_wmi_led_init(struct asus_wmi *asus) - asus->kbd_led.brightness_get = kbd_led_get; - asus->kbd_led.max_brightness = 3; - -+ if (num_rgb_groups != 0) -+ asus->kbd_led.groups = kbd_rgb_mode_groups; -+ - rv = led_classdev_register(&asus->platform_device->dev, - &asus->kbd_led); - if (rv) -@@ -1587,84 +1670,51 @@ static int asus_wmi_rfkill_init(struct asus_wmi *asus) - } - - /* Panel Overdrive ************************************************************/ --static int panel_od_check_present(struct asus_wmi *asus) --{ -- u32 result; -- int err; -- -- asus->panel_overdrive_available = false; -- -- err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_PANEL_OD, &result); -- if (err) { -- if (err == -ENODEV) -- return 0; -- return err; -- } -- -- if (result & ASUS_WMI_DSTS_PRESENCE_BIT) { -- asus->panel_overdrive_available = true; -- asus->panel_overdrive = result & ASUS_WMI_DSTS_STATUS_BIT; -- } -- -- return 0; --} -- --static int panel_od_write(struct asus_wmi *asus) --{ -- u32 retval; -- u8 value; -- int err; -- -- /* Don't rely on type conversion */ -- value = asus->panel_overdrive ? 1 : 0; -- -- err = asus_wmi_set_devstate(ASUS_WMI_DEVID_PANEL_OD, value, &retval); -- -- if (err) { -- pr_warn("Failed to set panel overdrive: %d\n", err); -- return err; -- } -- -- if (retval > 1) { -- pr_warn("Failed to set panel overdrive (retval): 0x%x\n", retval); -- return -EIO; -- } -- -- sysfs_notify(&asus->platform_device->dev.kobj, NULL, "panel_od"); -- -- return 0; --} -- - static ssize_t panel_od_show(struct device *dev, - struct device_attribute *attr, char *buf) - { - struct asus_wmi *asus = dev_get_drvdata(dev); -+ int result; - -- return sysfs_emit(buf, "%d\n", asus->panel_overdrive); -+ result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_PANEL_OD); -+ if (result < 0) -+ return result; -+ -+ return sysfs_emit(buf, "%d\n", result); - } - - static ssize_t panel_od_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) - { -- bool overdrive; -- int result; -+ int result, err; -+ u32 overdrive; - - struct asus_wmi *asus = dev_get_drvdata(dev); - -- result = kstrtobool(buf, &overdrive); -+ result = kstrtou32(buf, 10, &overdrive); - if (result) - return result; - -- asus->panel_overdrive = overdrive; -- result = panel_od_write(asus); -+ if (overdrive > 1) -+ return -EINVAL; - -- if (result) -- return result; -+ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_PANEL_OD, overdrive, &result); -+ -+ if (err) { -+ pr_warn("Failed to set panel overdrive: %d\n", err); -+ return err; -+ } -+ -+ if (result > 1) { -+ pr_warn("Failed to set panel overdrive (result): 0x%x\n", result); -+ return -EIO; -+ } -+ -+ sysfs_notify(&asus->platform_device->dev.kobj, NULL, "panel_od"); - - return count; - } -- - static DEVICE_ATTR_RW(panel_od); - - /* Quirks *********************************************************************/ -@@ -1816,6 +1866,18 @@ static int asus_fan_set_auto(struct asus_wmi *asus) - return -ENXIO; - } - -+ /* -+ * Modern models like the G713 also have GPU fan control (this is not AGFN) -+ */ -+ if (asus->gpu_fan_type == FAN_TYPE_SPEC83) { -+ status = asus_wmi_set_devstate(ASUS_WMI_DEVID_GPU_FAN_CTRL, -+ 0, &retval); -+ if (status) -+ return status; -+ -+ if (retval != 1) -+ return -EIO; -+ } - - return 0; - } -@@ -1853,7 +1915,7 @@ static ssize_t pwm1_show(struct device *dev, - value = -1; - } - -- return sprintf(buf, "%d\n", value); -+ return sysfs_emit(buf, "%d\n", value); - } - - static ssize_t pwm1_store(struct device *dev, -@@ -1913,7 +1975,7 @@ static ssize_t fan1_input_show(struct device *dev, - return -ENXIO; - } - -- return sprintf(buf, "%d\n", value < 0 ? -1 : value*100); -+ return sysfs_emit(buf, "%d\n", value < 0 ? -1 : value * 100); - } - - static ssize_t pwm1_enable_show(struct device *dev, -@@ -1931,7 +1993,7 @@ static ssize_t pwm1_enable_show(struct device *dev, - * in practice on X532FL at least (the bit is always 0) and there's - * also nothing in the DSDT to indicate that this behaviour exists. - */ -- return sprintf(buf, "%d\n", asus->fan_pwm_mode); -+ return sysfs_emit(buf, "%d\n", asus->fan_pwm_mode); - } - - static ssize_t pwm1_enable_store(struct device *dev, -@@ -1999,7 +2061,7 @@ static ssize_t fan1_label_show(struct device *dev, - struct device_attribute *attr, - char *buf) - { -- return sprintf(buf, "%s\n", ASUS_FAN_DESC); -+ return sysfs_emit(buf, "%s\n", ASUS_FAN_DESC); - } - - static ssize_t asus_hwmon_temp1(struct device *dev, -@@ -2018,11 +2080,86 @@ static ssize_t asus_hwmon_temp1(struct device *dev, - deci_kelvin_to_millicelsius(value & 0xFFFF)); - } - -+/* GPU fan on modern ROG laptops */ -+static ssize_t fan2_input_show(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct asus_wmi *asus = dev_get_drvdata(dev); -+ int value; -+ int ret; -+ -+ ret = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_GPU_FAN_CTRL, &value); -+ if (ret < 0) -+ return ret; -+ -+ value &= 0xffff; -+ -+ return sysfs_emit(buf, "%d\n", value < 0 ? -1 : value * 100); -+} -+ -+static ssize_t fan2_label_show(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ return sprintf(buf, "%s\n", ASUS_GPU_FAN_DESC); -+} -+ -+static ssize_t pwm2_enable_show(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct asus_wmi *asus = dev_get_drvdata(dev); -+ -+ return sysfs_emit(buf, "%d\n", asus->gpu_fan_pwm_mode); -+} -+ -+static ssize_t pwm2_enable_store(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ struct asus_wmi *asus = dev_get_drvdata(dev); -+ int state; -+ int value; -+ int ret; -+ u32 retval; -+ -+ ret = kstrtouint(buf, 10, &state); -+ if (ret) -+ return ret; -+ -+ switch (state) { /* standard documented hwmon values */ -+ case ASUS_FAN_CTRL_FULLSPEED: -+ value = 1; -+ break; -+ case ASUS_FAN_CTRL_AUTO: -+ value = 0; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ ret = asus_wmi_set_devstate(ASUS_WMI_DEVID_GPU_FAN_CTRL, -+ value, &retval); -+ if (ret) -+ return ret; -+ -+ if (retval != 1) -+ return -EIO; -+ -+ asus->gpu_fan_pwm_mode = state; -+ return count; -+} -+ - /* Fan1 */ - static DEVICE_ATTR_RW(pwm1); - static DEVICE_ATTR_RW(pwm1_enable); - static DEVICE_ATTR_RO(fan1_input); - static DEVICE_ATTR_RO(fan1_label); -+/* Fan2 - GPU fan */ -+static DEVICE_ATTR_RW(pwm2_enable); -+static DEVICE_ATTR_RO(fan2_input); -+static DEVICE_ATTR_RO(fan2_label); - - /* Temperature */ - static DEVICE_ATTR(temp1_input, S_IRUGO, asus_hwmon_temp1, NULL); -@@ -2030,8 +2167,11 @@ static DEVICE_ATTR(temp1_input, S_IRUGO, asus_hwmon_temp1, NULL); - static struct attribute *hwmon_attributes[] = { - &dev_attr_pwm1.attr, - &dev_attr_pwm1_enable.attr, -+ &dev_attr_pwm2_enable.attr, - &dev_attr_fan1_input.attr, - &dev_attr_fan1_label.attr, -+ &dev_attr_fan2_input.attr, -+ &dev_attr_fan2_label.attr, - - &dev_attr_temp1_input.attr, - NULL -@@ -2040,7 +2180,7 @@ static struct attribute *hwmon_attributes[] = { - static umode_t asus_hwmon_sysfs_is_visible(struct kobject *kobj, - struct attribute *attr, int idx) - { -- struct device *dev = container_of(kobj, struct device, kobj); -+ struct device *dev = kobj_to_dev(kobj); - struct asus_wmi *asus = dev_get_drvdata(dev->parent); - u32 value = ASUS_WMI_UNSUPPORTED_METHOD; - -@@ -2052,6 +2192,11 @@ static umode_t asus_hwmon_sysfs_is_visible(struct kobject *kobj, - || attr == &dev_attr_pwm1_enable.attr) { - if (asus->fan_type == FAN_TYPE_NONE) - return 0; -+ } else if (attr == &dev_attr_fan2_input.attr -+ || attr == &dev_attr_fan2_label.attr -+ || attr == &dev_attr_pwm2_enable.attr) { -+ if (asus->gpu_fan_type == FAN_TYPE_NONE) -+ return 0; - } else if (attr == &dev_attr_temp1_input.attr) { - int err = asus_wmi_get_devstate(asus, - ASUS_WMI_DEVID_THERMAL_CTRL, -@@ -2094,6 +2239,7 @@ static int asus_wmi_hwmon_init(struct asus_wmi *asus) - - static int asus_wmi_fan_init(struct asus_wmi *asus) - { -+ asus->gpu_fan_type = FAN_TYPE_NONE; - asus->fan_type = FAN_TYPE_NONE; - asus->agfn_pwm = -1; - -@@ -2102,6 +2248,10 @@ static int asus_wmi_fan_init(struct asus_wmi *asus) - else if (asus_wmi_has_agfn_fan(asus)) - asus->fan_type = FAN_TYPE_AGFN; - -+ /* Modern models like G713 also have GPU fan control */ -+ if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_GPU_FAN_CTRL)) -+ asus->gpu_fan_type = FAN_TYPE_SPEC83; -+ - if (asus->fan_type == FAN_TYPE_NONE) - return -ENODEV; - -@@ -2192,7 +2342,7 @@ static ssize_t fan_boost_mode_show(struct device *dev, - { - struct asus_wmi *asus = dev_get_drvdata(dev); - -- return scnprintf(buf, PAGE_SIZE, "%d\n", asus->fan_boost_mode); -+ return sysfs_emit(buf, "%d\n", asus->fan_boost_mode); - } - - static ssize_t fan_boost_mode_store(struct device *dev, -@@ -2744,7 +2894,7 @@ static ssize_t throttle_thermal_policy_show(struct device *dev, - struct asus_wmi *asus = dev_get_drvdata(dev); - u8 mode = asus->throttle_thermal_policy_mode; - -- return scnprintf(buf, PAGE_SIZE, "%d\n", mode); -+ return sysfs_emit(buf, "%d\n", mode); - } - - static ssize_t throttle_thermal_policy_store(struct device *dev, -@@ -3096,9 +3246,7 @@ static void asus_wmi_handle_event_code(int code, struct asus_wmi *asus) - { - unsigned int key_value = 1; - bool autorelease = 1; -- int result, orig_code; -- -- orig_code = code; -+ int orig_code = code; - - if (asus->driver->key_filter) { - asus->driver->key_filter(asus->driver, &code, &key_value, -@@ -3141,38 +3289,18 @@ static void asus_wmi_handle_event_code(int code, struct asus_wmi *asus) - return; - } - -- if (asus->driver->quirks->tablet_switch_mode == asus_wmi_kbd_dock_devid && -- code == NOTIFY_KBD_DOCK_CHANGE) { -- result = asus_wmi_get_devstate_simple(asus, -- ASUS_WMI_DEVID_KBD_DOCK); -- if (result >= 0) { -- input_report_switch(asus->inputdev, SW_TABLET_MODE, -- !result); -- input_sync(asus->inputdev); -- } -- return; -- } -- -- if (asus->driver->quirks->tablet_switch_mode == asus_wmi_lid_flip_devid && -- code == NOTIFY_LID_FLIP) { -- lid_flip_tablet_mode_get_state(asus); -- return; -- } -- -- if (asus->driver->quirks->tablet_switch_mode == asus_wmi_lid_flip_rog_devid && -- code == NOTIFY_LID_FLIP_ROG) { -- lid_flip_rog_tablet_mode_get_state(asus); -+ if (code == asus->tablet_switch_event_code) { -+ asus_wmi_tablet_mode_get_state(asus); - return; - } - -- if (asus->fan_boost_mode_available && code == NOTIFY_KBD_FBM) { -- fan_boost_mode_switch_next(asus); -+ if (code == NOTIFY_KBD_FBM || code == NOTIFY_KBD_TTP) { -+ if (asus->fan_boost_mode_available) -+ fan_boost_mode_switch_next(asus); -+ if (asus->throttle_thermal_policy_available) -+ throttle_thermal_policy_switch_next(asus); - return; -- } - -- if (asus->throttle_thermal_policy_available && code == NOTIFY_KBD_TTP) { -- throttle_thermal_policy_switch_next(asus); -- return; - } - - if (is_display_toggle(code) && asus->driver->quirks->no_display_toggle) -@@ -3324,6 +3452,7 @@ static struct attribute *platform_attributes[] = { - &dev_attr_touchpad.attr, - &dev_attr_egpu_enable.attr, - &dev_attr_dgpu_disable.attr, -+ &dev_attr_gpu_mux_mode.attr, - &dev_attr_lid_resume.attr, - &dev_attr_als_enable.attr, - &dev_attr_fan_boost_mode.attr, -@@ -3335,7 +3464,7 @@ static struct attribute *platform_attributes[] = { - static umode_t asus_sysfs_is_visible(struct kobject *kobj, - struct attribute *attr, int idx) - { -- struct device *dev = container_of(kobj, struct device, kobj); -+ struct device *dev = kobj_to_dev(kobj); - struct asus_wmi *asus = dev_get_drvdata(dev); - bool ok = true; - int devid = -1; -@@ -3354,6 +3483,10 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj, - ok = asus->egpu_enable_available; - else if (attr == &dev_attr_dgpu_disable.attr) - ok = asus->dgpu_disable_available; -+ else if (attr == &dev_attr_dgpu_disable.attr) -+ ok = asus->dgpu_disable_available; -+ else if (attr == &dev_attr_gpu_mux_mode.attr) -+ ok = asus->gpu_mux_mode_available; - else if (attr == &dev_attr_fan_boost_mode.attr) - ok = asus->fan_boost_mode_available; - else if (attr == &dev_attr_throttle_thermal_policy.attr) -@@ -3615,13 +3748,12 @@ static int asus_wmi_add(struct platform_device *pdev) - if (err) - goto fail_platform; - -- err = egpu_enable_check_present(asus); -- if (err) -- goto fail_egpu_enable; -- -- err = dgpu_disable_check_present(asus); -- if (err) -- goto fail_dgpu_disable; -+ asus->egpu_enable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_EGPU); -+ asus->dgpu_disable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_DGPU); -+ asus->gpu_mux_mode_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_GPU_MUX); -+ asus->kbd_rgb_mode_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_MODE); -+ asus->kbd_rgb_state_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_STATE); -+ asus->panel_overdrive_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PANEL_OD); - - err = fan_boost_mode_check_present(asus); - if (err) -@@ -3637,10 +3769,6 @@ static int asus_wmi_add(struct platform_device *pdev) - if (err) - goto fail_platform_profile_setup; - -- err = panel_od_check_present(asus); -- if (err) -- goto fail_panel_od; -- - err = asus_wmi_sysfs_init(asus->platform_device); - if (err) - goto fail_sysfs; -@@ -3735,10 +3863,7 @@ static int asus_wmi_add(struct platform_device *pdev) - if (asus->platform_profile_support) - platform_profile_remove(); - fail_fan_boost_mode: --fail_egpu_enable: --fail_dgpu_disable: - fail_platform: --fail_panel_od: - kfree(asus); - return err; - } -@@ -3797,18 +3922,7 @@ static int asus_hotk_resume(struct device *device) - if (asus_wmi_has_fnlock_key(asus)) - asus_wmi_fnlock_update(asus); - -- switch (asus->driver->quirks->tablet_switch_mode) { -- case asus_wmi_no_tablet_switch: -- case asus_wmi_kbd_dock_devid: -- break; -- case asus_wmi_lid_flip_devid: -- lid_flip_tablet_mode_get_state(asus); -- break; -- case asus_wmi_lid_flip_rog_devid: -- lid_flip_rog_tablet_mode_get_state(asus); -- break; -- } -- -+ asus_wmi_tablet_mode_get_state(asus); - return 0; - } - -@@ -3848,18 +3962,7 @@ static int asus_hotk_restore(struct device *device) - if (asus_wmi_has_fnlock_key(asus)) - asus_wmi_fnlock_update(asus); - -- switch (asus->driver->quirks->tablet_switch_mode) { -- case asus_wmi_no_tablet_switch: -- case asus_wmi_kbd_dock_devid: -- break; -- case asus_wmi_lid_flip_devid: -- lid_flip_tablet_mode_get_state(asus); -- break; -- case asus_wmi_lid_flip_rog_devid: -- lid_flip_rog_tablet_mode_get_state(asus); -- break; -- } -- -+ asus_wmi_tablet_mode_get_state(asus); - return 0; - } - -diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h -index 7c96db7f3060..28234dc9fa6a 100644 ---- a/include/linux/platform_data/x86/asus-wmi.h -+++ b/include/linux/platform_data/x86/asus-wmi.h -@@ -79,6 +79,7 @@ - #define ASUS_WMI_DEVID_THERMAL_CTRL 0x00110011 - #define ASUS_WMI_DEVID_FAN_CTRL 0x00110012 /* deprecated */ - #define ASUS_WMI_DEVID_CPU_FAN_CTRL 0x00110013 -+#define ASUS_WMI_DEVID_GPU_FAN_CTRL 0x00110014 - #define ASUS_WMI_DEVID_CPU_FAN_CURVE 0x00110024 - #define ASUS_WMI_DEVID_GPU_FAN_CURVE 0x00110025 - -@@ -100,6 +101,15 @@ - /* dgpu on/off */ - #define ASUS_WMI_DEVID_DGPU 0x00090020 - -+/* gpu mux switch, 0 = dGPU, 1 = Optimus */ -+#define ASUS_WMI_DEVID_GPU_MUX 0x00090016 -+ -+/* TUF laptop RGB modes/colours */ -+#define ASUS_WMI_DEVID_TUF_RGB_MODE 0x00100056 -+ -+/* TUF laptop RGB power/state */ -+#define ASUS_WMI_DEVID_TUF_RGB_STATE 0x00100057 -+ - /* DSTS masks */ - #define ASUS_WMI_DSTS_STATUS_BIT 0x00000001 - #define ASUS_WMI_DSTS_UNKNOWN_BIT 0x00000002 --- -2.38.1 - |