[PATCH 2/5] platform/x86: bitland-mifs-wmi: support MIFS v2 perf-mode mapping
wolf109909 <[email protected]> Wed, 29 Jul 2026 01:53:38 +0800
| Newsgroups | org.kernel.vger.platform-driver-x86,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
From: Yuming Sun <[email protected]> The MIFS v2 firmware found on e.g. the Xiaomi Book Pro 14 2026 (Intel Panther Lake, SSDT device "WMID" with _UID "MIFS") implements only a reduced WMAA command set and reports the performance mode as raw QFAN embedded-controller codes { 2, 3, 4, 9, 10 } instead of the v1 0..3 enumeration. With the v1 mapping, profile_get() returns -EINVAL for most firmware states ("platform_profile: Failed to get profile for handler bitland-mifs-wmi", also reported on REDMI Book Pro 14 2025) and profile_set() writes values the firmware treats as no-ops, so power-profiles-daemon can neither read nor switch the profile; selecting "performance" fails outright and wedges the daemon. Detect the variant at probe time by querying the current mode: values outside the v1 enumeration mean v2 firmware. Map the v2 codes to platform profiles (2=quiet, 3=balanced, 4=speed, 9/10=extreme) and skip the v1-only AC-type capability probe, which does not exist on v2 and now fails the call after the status-word check. Values verified against the laptop's SSDT WMAA method and by observing the EC QFAN register while switching modes. Signed-off-by: Yuming Sun <[email protected]> --- drivers/platform/x86/bitland-mifs-wmi.c | 79 +++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/drivers/platform/x86/bitland-mifs-wmi.c b/drivers/platform/x86/bitland-mifs-wmi.c index 12426d11..342dd7e1 100644 --- a/drivers/platform/x86/bitland-mifs-wmi.c +++ b/drivers/platform/x86/bitland-mifs-wmi.c @@ -73,6 +73,21 @@ enum bitland_mifs_power_profile { WMI_PP_FULL_SPEED = 3, }; +/* + * MIFS v2 firmware (e.g. Xiaomi Book Pro 14 2026, SSDT "WMID" with UID + * "MIFS") implements a reduced WMAA command set (only function groups + * 0x0800/0x0a00/0x0c00/0x1000) and reports the performance mode as raw + * QFAN EC codes instead of the v1 0..3 enumeration. Codes 9 and 10 are + * the SMM-backed "extreme" modes. + */ +enum bitland_mifs_v2_power_profile { + WMI_V2_PP_QUIET = 2, + WMI_V2_PP_BALANCED = 3, + WMI_V2_PP_SPEED = 4, + WMI_V2_PP_EXTREME = 9, + WMI_V2_PP_EXTREME2 = 10, +}; + enum bitland_mifs_event_id { WMI_EVENT_RESERVED_1 = 1, WMI_EVENT_RESERVED_2 = 2, @@ -172,6 +187,7 @@ struct bitland_mifs_wmi_data { struct device *pp_dev; enum platform_profile_option saved_profile; bool profile_valid; + bool is_v2; /* MIFS v2 firmware: QFAN perf-mode codes */ }; static int bitland_mifs_wmi_call(struct bitland_mifs_wmi_data *data, @@ -217,6 +233,27 @@ static int laptop_profile_get(struct device *dev, if (ret) return ret; + if (data->is_v2) { + switch (result.data[0]) { + case WMI_V2_PP_QUIET: + *profile = PLATFORM_PROFILE_LOW_POWER; + break; + case WMI_V2_PP_BALANCED: + *profile = PLATFORM_PROFILE_BALANCED; + break; + case WMI_V2_PP_SPEED: + *profile = PLATFORM_PROFILE_BALANCED_PERFORMANCE; + break; + case WMI_V2_PP_EXTREME: + case WMI_V2_PP_EXTREME2: + *profile = PLATFORM_PROFILE_PERFORMANCE; + break; + default: + return -EINVAL; + } + return 0; + } + switch (result.data[0]) { case WMI_PP_BALANCED: *profile = PLATFORM_PROFILE_BALANCED; @@ -272,6 +309,28 @@ static int laptop_profile_set(struct device *dev, int ret; u8 val; + if (data->is_v2) { + switch (profile) { + case PLATFORM_PROFILE_LOW_POWER: + val = WMI_V2_PP_QUIET; + break; + case PLATFORM_PROFILE_BALANCED: + val = WMI_V2_PP_BALANCED; + break; + case PLATFORM_PROFILE_BALANCED_PERFORMANCE: + val = WMI_V2_PP_SPEED; + break; + case PLATFORM_PROFILE_PERFORMANCE: + val = WMI_V2_PP_EXTREME; + break; + default: + return -EOPNOTSUPP; + } + input.payload[0] = val; + + return bitland_mifs_wmi_call(data, &input, NULL); + } + switch (profile) { case PLATFORM_PROFILE_LOW_POWER: val = WMI_PP_QUIET; @@ -705,6 +764,26 @@ static int bitland_mifs_wmi_probe(struct wmi_device *wdev, const void *context) dev_set_drvdata(&wdev->dev, drv_data); + if (dev_type == BITLAND_WMI_CONTROL) { + /* + * Firmware variant detection: v1 firmware reports the perf mode + * as 0..3 (enum bitland_mifs_power_profile); anything else means + * the reduced MIFS v2 command set with raw QFAN codes. + */ + struct bitland_mifs_input probe_in = { + .operation = WMI_METHOD_GET, + .function = WMI_FN_SYSTEM_PER_MODE, + }; + struct bitland_mifs_output probe_out; + + if (!bitland_mifs_wmi_call(drv_data, &probe_in, &probe_out) && + probe_out.data[0] > WMI_PP_FULL_SPEED) { + drv_data->is_v2 = true; + dev_info(&wdev->dev, + "MIFS v2 firmware detected (QFAN mode codes)\n"); + } + } + if (dev_type == BITLAND_WMI_EVENT) { /* Register input device for hotkeys */ drv_data->input_dev = devm_input_allocate_device(&wdev->dev); -- 2.55.0