|
| 1 | +.. SPDX-License-Identifier: GPL-2.0-or-later |
| 2 | +
|
| 3 | +======================================== |
| 4 | +Bitland MIFS driver (bitland-mifs-wmi) |
| 5 | +======================================== |
| 6 | + |
| 7 | +Introduction |
| 8 | +============ |
| 9 | + |
| 10 | + |
| 11 | +EC WMI interface description |
| 12 | +============================ |
| 13 | + |
| 14 | +The EC WMI interface description can be decoded from the embedded binary MOF (bmof) |
| 15 | +data 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 | + |
| 58 | +Reverse-Engineering the EC WMI interface |
| 59 | +======================================== |
| 60 | + |
| 61 | +The OEM software can be download from `this link <https://iknow.lenovo.com.cn/detail/429447>`_ |
| 62 | + |
| 63 | +Nothing is obfuscated, In this case, `ILSpy <https://github.com/icsharpcode/ILSpy>`_ could be helpful. |
| 64 | + |
| 65 | +WMI Methods (MICommonInterface) |
| 66 | +======================================== |
| 67 | + |
| 68 | +The ``MICommonInterface`` class (GUID: ``{b60bfb48-3e5b-49e4-a0e9-8cffe1b3434b}``) |
| 69 | +is the primary control interface. It uses a 32-byte buffer for both input |
| 70 | +(``InData``) and output (``OutData``). |
| 71 | + |
| 72 | +Method Structure |
| 73 | +---------------- |
| 74 | + |
| 75 | +The 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 | + |
| 88 | +Command IDs |
| 89 | +----------- |
| 90 | + |
| 91 | +The 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 | + |
| 129 | +WMI Events (HID_EVENT20) |
| 130 | +======================== |
| 131 | + |
| 132 | +The driver listens for events from the ``HID_EVENT20`` class |
| 133 | +(GUID: ``{46c93e13-ee9b-4262-8488-563bca757fef}``). These events are triggered |
| 134 | +by hotkeys or system state changes (e.g., plugging in AC power). |
| 135 | + |
| 136 | +Event Structure |
| 137 | +--------------- |
| 138 | + |
| 139 | +The 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 | + |
| 151 | +Common Event IDs: |
| 152 | +----------------- |
| 153 | + |
| 154 | +Note: 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 | + |
| 184 | +Implementation Details |
| 185 | +====================== |
| 186 | + |
| 187 | +Performance Modes |
| 188 | +----------------- |
| 189 | +Changing the performance mode via Command ID 0x08 (SystemPerMode) affects the |
| 190 | +power limits (PL1/PL2) and fan curves managed by the Embedded Controller (EC). |
| 191 | +Note that the "Full-speed" and "Performance" mode (1, 3) is typically only |
| 192 | +available when the system is connected to a DC power source (not USB-C/PD). |
| 193 | + |
| 194 | +In the driver implementation, switch to performance/full-speed mode without |
| 195 | +DC power connected will throw the EOPNOTSUPP error. |
| 196 | + |
| 197 | +Graphics Switching |
| 198 | +------------------ |
| 199 | +The ``GPUMode`` (0x09) allows switching between Hybrid (Muxless) and Discrete |
| 200 | +(Muxed) graphics. Changing this value usually requires a system reboot to |
| 201 | +take effect in the BIOS/Firmware. |
| 202 | + |
| 203 | +Fan Control |
| 204 | +----------- |
| 205 | +The system supports both automatic EC control and manual overrides. Command ID |
| 206 | +0x14 (``MaxFanSpeedSwitch``) is used to toggle manual control, while ID 0x15 |
| 207 | +sets the actual PWM duty cycle. |
0 commit comments