1.. SPDX-License-Identifier: GPL-2.0-or-later 2 3======================================== 4Bitland MIFS driver (bitland-mifs-wmi) 5======================================== 6 7Introduction 8============ 9 10 11EC WMI interface description 12============================ 13 14The EC WMI interface description can be decoded from the embedded binary MOF (bmof) 15data using the `bmfdec <https://github.com/pali/bmfdec>`_ utility: 16 17:: 18 19 class WMIEvent : __ExtrinsicEvent { 20 }; 21 22 [WMI, Dynamic, Provider("WmiProv"), Locale("MS\\0x40A"), Description("Root WMI HID_EVENT20"), guid("{46c93e13-ee9b-4262-8488-563bca757fef}")] 23 class HID_EVENT20 : WmiEvent { 24 [key, read] string InstanceName; 25 [read] boolean Active; 26 [WmiDataId(1), read, write, Description("Package Data")] uint8 EventDetail[8]; 27 }; 28 29 [WMI, Dynamic, Provider("WmiProv"), Locale("MS\\0x40A"), Description("Root WMI HID_EVENT21"), guid("{fa78e245-2c0f-4ca1-91cf-15f34e474850}")] 30 class HID_EVENT21 : WmiEvent { 31 [key, read] string InstanceName; 32 [read] boolean Active; 33 [WmiDataId(1), read, write, Description("Package Data")] uint8 EventDetail[8]; 34 }; 35 36 [WMI, Dynamic, Provider("WmiProv"), Locale("MS\\0x40A"), Description("Root WMI HID_EVENT22"), guid("{1dceaf0a-4d63-44bb-bd0c-0d6281bfddc5}")] 37 class HID_EVENT22 : WmiEvent { 38 [key, read] string InstanceName; 39 [read] boolean Active; 40 [WmiDataId(1), read, write, Description("Package Data")] uint8 EventDetail[8]; 41 }; 42 43 [WMI, Dynamic, Provider("WmiProv"), Locale("MS\\0x40A"), Description("Root WMI HID_EVENT23"), guid("{3f9e3c26-b077-4f86-91f5-37ff64d8c7ed}")] 44 class HID_EVENT23 : WmiEvent { 45 [key, read] string InstanceName; 46 [read] boolean Active; 47 [WmiDataId(1), read, write, Description("Package Data")] uint8 EventDetail[8]; 48 }; 49 50 [WMI, Dynamic, provider("WmiProv"), Locale("MS\\0x409"), Description("Class used to operate firmware interface"), guid("{b60bfb48-3e5b-49e4-a0e9-8cffe1b3434b}")] 51 class MICommonInterface { 52 [key, read] string InstanceName; 53 [read] boolean Active; 54 55 [WmiMethodId(1), Implemented, read, write, Description("Method used to support system functions.")] void MiInterface([in, Description("WMI Interface")] uint8 InData[32], [out] uint8 OutData[30], [out] uint16 Reserved); 56 }; 57 58Reverse-Engineering the EC WMI interface 59======================================== 60 61The OEM software can be download from `this link <https://iknow.lenovo.com.cn/detail/429447>`_ 62 63Nothing is obfuscated, In this case, `ILSpy <https://github.com/icsharpcode/ILSpy>`_ could be helpful. 64 65WMI Methods (MICommonInterface) 66======================================== 67 68The ``MICommonInterface`` class (GUID: ``{b60bfb48-3e5b-49e4-a0e9-8cffe1b3434b}``) 69is the primary control interface. It uses a 32-byte buffer for both input 70(``InData``) and output (``OutData``). 71 72Method Structure 73---------------- 74 75The data packet follows a standardized format: 76 77+----------+------------------------------------------------------------------+ 78| Byte | Description | 79+==========+==================================================================+ 80| 1 | Method Type: Get (0xFA / 250) or Set (0xFB / 251) | 81+----------+------------------------------------------------------------------+ 82| 3 | Command ID (Method Name) | 83+----------+------------------------------------------------------------------+ 84| 4 - 31 | Arguments (for Set) or Return Data (for Get) | 85+----------+------------------------------------------------------------------+ 86 87 88Command IDs 89----------- 90 91The following Command IDs are used in the third byte of the buffer: 92 93+----------+-----------------------+------------------------------------------+ 94| ID | Name | Values / Description | 95+==========+=======================+==========================================+ 96| 8 | SystemPerMode | 0: Balance, 1: Performance, 2: Quiet, | 97| | | 3: Full-speed | 98+----------+-----------------------+------------------------------------------+ 99| 9 | GPUMode | 0: Hybrid, 1: Discrete, 2: UMA | 100+----------+-----------------------+------------------------------------------+ 101| 10 | KeyboardType | 0: White, 1: Single RGB, 2: Zone RGB | 102+----------+-----------------------+------------------------------------------+ 103| 11 | FnLock | 0: Off, 1: On | 104+----------+-----------------------+------------------------------------------+ 105| 12 | TPLock | 0: Unlock, 1: Lock (Touchpad) | 106+----------+-----------------------+------------------------------------------+ 107| 13 | CPUGPUSYSFanSpeed | Returns 12 bytes of fan data: | 108| | | Bytes 4-5: CPU Fan RPM (Little Endian) | 109| | | Bytes 6-7: GPU Fan RPM (Little Endian) | 110| | | Bytes 10-11: SYS Fan RPM (Little Endian) | 111+----------+-----------------------+------------------------------------------+ 112| 16 | RGBKeyboardMode | 0: Off, 1: Auto Cyclic, 2: Fixed, | 113| | | 3: Custom | 114+----------+-----------------------+------------------------------------------+ 115| 17 | RGBKeyboardColor | Bytes 4, 5, 6: Red, Green, Blue values | 116+----------+-----------------------+------------------------------------------+ 117| 18 | RGBKeyboardBrightness | 0-10: Brightness Levels, 128: Auto | 118+----------+-----------------------+------------------------------------------+ 119| 19 | SystemAcType | 1: Type-C, 2: Circular Hole (DC) | 120+----------+-----------------------+------------------------------------------+ 121| 20 | MaxFanSpeedSwitch | Byte 4: Fan Type (0: CPU/GPU, 1: SYS) | 122| | | Byte 5: State (0: Off, 1: On) | 123+----------+-----------------------+------------------------------------------+ 124| 21 | MaxFanSpeed | Sets manual fan speed duty cycle | 125+----------+-----------------------+------------------------------------------+ 126| 22 | CPUThermometer | Returns CPU Temperature | 127+----------+-----------------------+------------------------------------------+ 128 129WMI Events (HID_EVENT20) 130======================== 131 132The driver listens for events from the ``HID_EVENT20`` class 133(GUID: ``{46c93e13-ee9b-4262-8488-563bca757fef}``). These events are triggered 134by hotkeys or system state changes (e.g., plugging in AC power). 135 136Event Structure 137--------------- 138 139The event data is provided in an 8-byte array (``EventDetail``): 140 141+----------+------------------------------------------------------------------+ 142| Byte | Description | 143+==========+==================================================================+ 144| 0 | Event Type (Always 0x01 for HotKey/Notification) | 145+----------+------------------------------------------------------------------+ 146| 1 | Event ID (Corresponds to the Command IDs above) | 147+----------+------------------------------------------------------------------+ 148| 2 | Value (The new state or value of the feature) | 149+----------+------------------------------------------------------------------+ 150 151Common Event IDs: 152----------------- 153 154Note: reserved event ids are not listed there 155 156+----------+------------------------------------------------------------------+ 157| Event Id | Description | 158+==========+==================================================================+ 159| 4 | AirPlane mode change | 160+----------+------------------------------------------------------------------+ 161| 5 | Keyboard brightness change | 162+----------+------------------------------------------------------------------+ 163| 6 | Touchpad state (enabled/disabled) change | 164+----------+------------------------------------------------------------------+ 165| 7 | FnLock state (enabled/disabled) change | 166+----------+------------------------------------------------------------------+ 167| 8 | Keyboard mode change | 168+----------+------------------------------------------------------------------+ 169| 9 | CapsLock state change | 170+----------+------------------------------------------------------------------+ 171| 13 | NumLock state change | 172+----------+------------------------------------------------------------------+ 173| 14 | ScrollLock state change | 174+----------+------------------------------------------------------------------+ 175| 15 | Performance plan change | 176+----------+------------------------------------------------------------------+ 177| 25 | Display refresh rate change | 178+----------+------------------------------------------------------------------+ 179| 33 | Super key lock state (enabled/disabled) change | 180+----------+------------------------------------------------------------------+ 181| 35 | Open control center key | 182+----------+------------------------------------------------------------------+ 183 184Implementation Details 185====================== 186 187Performance Modes 188----------------- 189Changing the performance mode via Command ID 0x08 (SystemPerMode) affects the 190power limits (PL1/PL2) and fan curves managed by the Embedded Controller (EC). 191Note that the "Full-speed" and "Performance" mode (1, 3) is typically only 192available when the system is connected to a DC power source (not USB-C/PD). 193 194In the driver implementation, switch to performance/full-speed mode without 195DC power connected will throw the EOPNOTSUPP error. 196 197Graphics Switching 198------------------ 199The ``GPUMode`` (0x09) allows switching between Hybrid (Muxless) and Discrete 200(Muxed) graphics. Changing this value usually requires a system reboot to 201take effect in the BIOS/Firmware. 202 203Fan Control 204----------- 205The system supports both automatic EC control and manual overrides. Command ID 2060x14 (``MaxFanSpeedSwitch``) is used to toggle manual control, while ID 0x15 207sets the actual PWM duty cycle. 208