platform/x86: asus-wmi: add support for Vivobook GPU MUX
authorLuke D. Jones <luke@ljones.dev>
Thu, 4 Apr 2024 00:16:45 +0000 (13:16 +1300)
committerHans de Goede <hdegoede@redhat.com>
Mon, 8 Apr 2024 16:30:26 +0000 (18:30 +0200)
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>
Link: https://lore.kernel.org/r/20240404001652.86207-3-luke@ljones.dev
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
drivers/platform/x86/asus-wmi.c
include/linux/platform_data/x86/asus-wmi.h

index e8fbd7f9d343c1e30c8528cf36641eea772ff449..51e4df0810466635be2cc0a2ba7ec3d4790a3389 100644 (file)
@@ -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;
index 9cadce10ad9ac5b4607dac23bb3cf0619acd2068..b48b024dd8445c79b48586a7fdde55158d774b05 100644 (file)
 
 /* 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