aboutsummarylogtreecommitdiffstats
path: root/asus-wmi-Add-egpu-enable-method.patch
diff options
context:
space:
mode:
authorScott B2021-09-07 12:20:23 -0700
committerAntoine Viallon2021-10-25 10:18:29 +0200
commit0ffb3488cb9372e9a4bb2128d3bb511affc6b0bc (patch)
tree665e9e96df9519b2144a0b53e99a4385b6890a91 /asus-wmi-Add-egpu-enable-method.patch
parent4db8ad99f1f7d4cb7982111fa99b3b9e5d8bcd00 (diff)
downloadaur-0ffb3488cb9372e9a4bb2128d3bb511affc6b0bc.tar.gz
cleanup; comments
Diffstat (limited to 'asus-wmi-Add-egpu-enable-method.patch')
-rw-r--r--asus-wmi-Add-egpu-enable-method.patch169
1 files changed, 169 insertions, 0 deletions
diff --git a/asus-wmi-Add-egpu-enable-method.patch b/asus-wmi-Add-egpu-enable-method.patch
new file mode 100644
index 000000000000..13804605dc37
--- /dev/null
+++ b/asus-wmi-Add-egpu-enable-method.patch
@@ -0,0 +1,169 @@
+From 49872973ce89a5778cd57094eb2eebba530b1244 Mon Sep 17 00:00:00 2001
+From: "Luke D. Jones" <luke@ljones.dev>
+Date: Sat, 17 Jul 2021 20:13:23 +1200
+Subject: [PATCH 103/103] asus-wmi: Add egpu enable method
+
+The X13 Flow laptops can utilise an external GPU. This requires
+toggling an ACPI method which will first disable the internal
+dGPU, and then enable the eGPU.
+
+Signed-off-by: Luke D. Jones <luke@ljones.dev>
+---
+ drivers/platform/x86/asus-wmi.c | 91 ++++++++++++++++++++++
+ include/linux/platform_data/x86/asus-wmi.h | 3 +
+ 2 files changed, 94 insertions(+)
+
+diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
+index 02762a60d27a..ee5d8656641e 100644
+--- a/drivers/platform/x86/asus-wmi.c
++++ b/drivers/platform/x86/asus-wmi.c
+@@ -210,6 +210,9 @@ struct asus_wmi {
+ u8 fan_boost_mode_mask;
+ u8 fan_boost_mode;
+
++ bool egpu_enable_available; // 0 = enable
++ bool egpu_enable;
++
+ bool dgpu_disable_available;
+ bool dgpu_disable;
+
+@@ -430,6 +433,86 @@ static void lid_flip_tablet_mode_get_state(struct asus_wmi *asus)
+ }
+ }
+
++/* eGPU ********************************************************************/
++static int egpu_enable_check_present(struct asus_wmi *asus)
++{
++ u32 result;
++ int err;
++
++ asus->egpu_enable_available = false;
++
++ err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_EGPU, &result);
++ if (err) {
++ if (err == -ENODEV)
++ return 0;
++ return err;
++ }
++
++ if (result & ASUS_WMI_DSTS_PRESENCE_BIT) {
++ asus->egpu_enable_available = true;
++ asus->egpu_enable = result & ASUS_WMI_DSTS_STATUS_BIT;
++ }
++
++ return 0;
++}
++
++static int egpu_enable_write(struct asus_wmi *asus)
++{
++ int err;
++ u8 value;
++ u32 retval;
++
++ value = asus->egpu_enable;
++
++ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_EGPU, value, &retval);
++
++ if (err) {
++ pr_warn("Failed to set egpu disable: %d\n", err);
++ return err;
++ }
++
++ if (retval > 1 || retval < 0) {
++ pr_warn("Failed to set egpu disable (retval): 0x%x\n", retval);
++ return -EIO;
++ }
++
++ sysfs_notify(&asus->platform_device->dev.kobj, NULL, "egpu_enable");
++
++ return 0;
++}
++
++static ssize_t egpu_enable_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct asus_wmi *asus = dev_get_drvdata(dev);
++ bool mode = asus->egpu_enable;
++
++ return sysfs_emit(buf, "%d\n", mode);
++}
++
++static ssize_t egpu_enable_store(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ int result;
++ bool disable;
++ struct asus_wmi *asus = dev_get_drvdata(dev);
++
++ result = kstrtobool(buf, &disable);
++ if (result == -EINVAL)
++ return result;
++
++ asus->egpu_enable = disable;
++
++ result = egpu_enable_write(asus);
++ if (result != 0)
++ return result;
++
++ return count;
++}
++
++static DEVICE_ATTR_RW(egpu_enable);
++
+ /* dGPU ********************************************************************/
+ static int dgpu_disable_check_present(struct asus_wmi *asus)
+ {
+@@ -2502,6 +2585,7 @@ static struct attribute *platform_attributes[] = {
+ &dev_attr_camera.attr,
+ &dev_attr_cardr.attr,
+ &dev_attr_touchpad.attr,
++ &dev_attr_egpu_enable.attr,
+ &dev_attr_dgpu_disable.attr,
+ &dev_attr_lid_resume.attr,
+ &dev_attr_als_enable.attr,
+@@ -2529,6 +2613,8 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj,
+ devid = ASUS_WMI_DEVID_LID_RESUME;
+ else if (attr == &dev_attr_als_enable.attr)
+ devid = ASUS_WMI_DEVID_ALS_ENABLE;
++ else if (attr == &dev_attr_egpu_enable.attr)
++ ok = asus->egpu_enable_available;
+ else if (attr == &dev_attr_dgpu_disable.attr)
+ ok = asus->dgpu_disable_available;
+ else if (attr == &dev_attr_fan_boost_mode.attr)
+@@ -2792,6 +2878,10 @@ 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;
+@@ -2896,6 +2986,7 @@ static int asus_wmi_add(struct platform_device *pdev)
+ fail_sysfs:
+ fail_throttle_thermal_policy:
+ fail_fan_boost_mode:
++fail_egpu_enable:
+ fail_dgpu_disable:
+ fail_platform:
+ fail_panel_od:
+diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
+index a528f9d0e4b7..17dc5cb6f3f2 100644
+--- a/include/linux/platform_data/x86/asus-wmi.h
++++ b/include/linux/platform_data/x86/asus-wmi.h
+@@ -90,6 +90,9 @@
+ /* Keyboard dock */
+ #define ASUS_WMI_DEVID_KBD_DOCK 0x00120063
+
++/* dgpu on/off */
++#define ASUS_WMI_DEVID_EGPU 0x00090019
++
+ /* dgpu on/off */
+ #define ASUS_WMI_DEVID_DGPU 0x00090020
+
+--
+2.32.0
+