1 .. SPDX-License-Identifier: GPL-2.0-or-later
3 ==============================================
4 Dell AWCC WMI interface driver (alienware-wmi)
5 ==============================================
10 The WMI device WMAX has been implemented for many Alienware and Dell's G-Series
11 models. Throughout these models, two implementations have been identified. The
12 first one, used by older systems, deals with HDMI, brightness, RGB, amplifier
13 and deep sleep control. The second one used by newer systems deals primarily
14 with thermal, overclocking, and GPIO control.
16 It is suspected that the latter is used by Alienware Command Center (AWCC) to
17 manage manufacturer predefined thermal profiles. The alienware-wmi driver
18 exposes Thermal_Information and Thermal_Control methods through the Platform
19 Profile API to mimic AWCC's behavior.
21 This newer interface, named AWCCMethodFunction has been reverse engineered, as
22 Dell has not provided any official documentation. We will try to describe to the
23 best of our ability its discovered inner workings.
26 The following method description may be incomplete and some operations have
27 different implementations between devices.
29 WMI interface description
30 -------------------------
32 The WMI interface description can be decoded from the embedded binary MOF (bmof)
33 data using the `bmfdec <https://github.com/pali/bmfdec>`_ utility:
37 [WMI, Dynamic, Provider("WmiProv"), Locale("MS\\0x409"), Description("WMI Function"), guid("{A70591CE-A997-11DA-B012-B622A1EF5492}")]
38 class AWCCWmiMethodFunction {
39 [key, read] string InstanceName;
40 [read] boolean Active;
42 [WmiMethodId(13), Implemented, read, write, Description("Return Overclocking Report.")] void Return_OverclockingReport([out] uint32 argr);
43 [WmiMethodId(14), Implemented, read, write, Description("Set OCUIBIOS Control.")] void Set_OCUIBIOSControl([in] uint32 arg2, [out] uint32 argr);
44 [WmiMethodId(15), Implemented, read, write, Description("Clear OC FailSafe Flag.")] void Clear_OCFailSafeFlag([out] uint32 argr);
45 [WmiMethodId(19), Implemented, read, write, Description("Get Fan Sensors.")] void GetFanSensors([in] uint32 arg2, [out] uint32 argr);
46 [WmiMethodId(20), Implemented, read, write, Description("Thermal Information.")] void Thermal_Information([in] uint32 arg2, [out] uint32 argr);
47 [WmiMethodId(21), Implemented, read, write, Description("Thermal Control.")] void Thermal_Control([in] uint32 arg2, [out] uint32 argr);
48 [WmiMethodId(23), Implemented, read, write, Description("MemoryOCControl.")] void MemoryOCControl([in] uint32 arg2, [out] uint32 argr);
49 [WmiMethodId(26), Implemented, read, write, Description("System Information.")] void SystemInformation([in] uint32 arg2, [out] uint32 argr);
50 [WmiMethodId(28), Implemented, read, write, Description("Power Information.")] void PowerInformation([in] uint32 arg2, [out] uint32 argr);
51 [WmiMethodId(32), Implemented, read, write, Description("FW Update GPIO toggle.")] void FWUpdateGPIOtoggle([in] uint32 arg2, [out] uint32 argr);
52 [WmiMethodId(33), Implemented, read, write, Description("Read Total of GPIOs.")] void ReadTotalofGPIOs([out] uint32 argr);
53 [WmiMethodId(34), Implemented, read, write, Description("Read GPIO pin Status.")] void ReadGPIOpPinStatus([in] uint32 arg2, [out] uint32 argr);
54 [WmiMethodId(35), Implemented, read, write, Description("Read Chassis Color.")] void ReadChassisColor([out] uint32 argr);
55 [WmiMethodId(36), Implemented, read, write, Description("Read Platform Properties.")] void ReadPlatformProperties([out] uint32 argr);
56 [WmiMethodId(37), Implemented, read, write, Description("Game Shift Status.")] void GameShiftStatus([in] uint32 arg2, [out] uint32 argr);
57 [WmiMethodId(128), Implemented, read, write, Description("Caldera SW installation.")] void CalderaSWInstallation([out] uint32 argr);
58 [WmiMethodId(129), Implemented, read, write, Description("Caldera SW is released.")] void CalderaSWReleased([out] uint32 argr);
59 [WmiMethodId(130), Implemented, read, write, Description("Caldera Connection Status.")] void CalderaConnectionStatus([in] uint32 arg2, [out] uint32 argr);
60 [WmiMethodId(131), Implemented, read, write, Description("Surprise Unplugged Flag Status.")] void SurpriseUnpluggedFlagStatus([out] uint32 argr);
61 [WmiMethodId(132), Implemented, read, write, Description("Clear Surprise Unplugged Flag.")] void ClearSurpriseUnpluggedFlag([out] uint32 argr);
62 [WmiMethodId(133), Implemented, read, write, Description("Cancel Undock Request.")] void CancelUndockRequest([out] uint32 argr);
63 [WmiMethodId(135), Implemented, read, write, Description("Devices in Caldera.")] void DevicesInCaldera([in] uint32 arg2, [out] uint32 argr);
64 [WmiMethodId(136), Implemented, read, write, Description("Notify BIOS for SW ready to disconnect Caldera.")] void NotifyBIOSForSWReadyToDisconnectCaldera([out] uint32 argr);
65 [WmiMethodId(160), Implemented, read, write, Description("Tobii SW installation.")] void TobiiSWinstallation([out] uint32 argr);
66 [WmiMethodId(161), Implemented, read, write, Description("Tobii SW Released.")] void TobiiSWReleased([out] uint32 argr);
67 [WmiMethodId(162), Implemented, read, write, Description("Tobii Camera Power Reset.")] void TobiiCameraPowerReset([out] uint32 argr);
68 [WmiMethodId(163), Implemented, read, write, Description("Tobii Camera Power On.")] void TobiiCameraPowerOn([out] uint32 argr);
69 [WmiMethodId(164), Implemented, read, write, Description("Tobii Camera Power Off.")] void TobiiCameraPowerOff([out] uint32 argr);
72 Some of these methods get quite intricate so we will describe them using
73 pseudo-code that vaguely resembles the original ASL code.
75 Methods not described in the following document have unknown behavior.
80 All input arguments have type **uint32** and their structure is very similar
81 between methods. Usually, the first byte corresponds to a specific *operation*
82 the method performs, and the subsequent bytes correspond to *arguments* passed
83 to this *operation*. For example, if an operation has code 0x01 and requires an
84 ID 0xA0, the argument you would pass to the method is 0xA001.
90 WMI method Thermal_Information([in] uint32 arg2, [out] uint32 argr)
91 -------------------------------------------------------------------
95 if BYTE_0(arg2) == 0x01:
98 if BYTE_0(arg2) == 0x02:
99 argr = SYSTEM_DESCRIPTION
101 if BYTE_0(arg2) == 0x03:
102 if BYTE_1(arg2) == 0x00:
105 if BYTE_1(arg2) == 0x01:
108 if BYTE_1(arg2) == 0x02:
111 if BYTE_1(arg2) == 0x03:
114 if BYTE_1(arg2) == 0x04:
115 argr = SENSOR_ID_CPU | 0x0100
117 if BYTE_1(arg2) == 0x05:
118 argr = SENSOR_ID_GPU | 0x0100
120 if BYTE_1(arg2) == 0x06:
121 argr = THERMAL_MODE_QUIET_ID
123 if BYTE_1(arg2) == 0x07:
124 argr = THERMAL_MODE_BALANCED_ID
126 if BYTE_1(arg2) == 0x08:
127 argr = THERMAL_MODE_BALANCED_PERFORMANCE_ID
129 if BYTE_1(arg2) == 0x09:
130 argr = THERMAL_MODE_PERFORMANCE_ID
132 if BYTE_1(arg2) == 0x0A:
133 argr = THERMAL_MODE_LOW_POWER_ID
135 if BYTE_1(arg2) == 0x0B:
136 argr = THERMAL_MODE_GMODE_ID
141 if BYTE_0(arg2) == 0x04:
142 if is_valid_sensor(BYTE_1(arg2)):
147 if BYTE_0(arg2) == 0x05:
148 if is_valid_fan(BYTE_1(arg2)):
151 if BYTE_0(arg2) == 0x06:
154 if BYTE_0(arg2) == 0x07:
157 If BYTE_0(arg2) == 0x08:
158 if is_valid_fan(BYTE_1(arg2)):
163 if BYTE_0(arg2) == 0x09:
164 if is_valid_fan(BYTE_1(arg2)):
165 argr = FAN_UNKNOWN_STAT_0()
170 if BYTE_0(arg2) == 0x0A:
171 argr = THERMAL_MODE_BALANCED_ID
173 if BYTE_0(arg2) == 0x0B:
174 argr = CURRENT_THERMAL_MODE()
176 if BYTE_0(arg2) == 0x0C:
177 if is_valid_fan(BYTE_1(arg2)):
178 argr = FAN_UNKNOWN_STAT_1()
182 Operation 0x02 returns a *system description* buffer with the following
187 out[0] -> Number of fans
188 out[1] -> Number of sensors
190 out[3] -> Number of thermal modes
192 Operation 0x03 list all available fan IDs, sensor IDs and thermal profile
193 codes in order, but different models may have different number of fans and
194 thermal profiles. These are the known ranges:
196 * Fan IDs: from 2 up to 4
198 * Thermal profile codes: from 1 up to 7
200 In total BYTE_1(ARG2) may range from 0x5 up to 0xD depending on the model.
202 WMI method Thermal_Control([in] uint32 arg2, [out] uint32 argr)
203 ---------------------------------------------------------------
207 if BYTE_0(arg2) == 0x01:
208 if is_valid_thermal_profile(BYTE_1(arg2)):
209 SET_THERMAL_PROFILE(BYTE_1(arg2))
212 if BYTE_0(arg2) == 0x02:
213 if is_valid_fan(BYTE_1(arg2)):
214 SET_FAN_SPEED_MULTIPLIER(BYTE_2(arg2))
220 While you can manually change the fan speed multiplier with this method,
221 Dell's BIOS tends to overwrite this changes anyway.
223 These are the known thermal profile codes:
230 BALANCED_PERFORMANCE_USTT 0xA1
233 PERFORMANCE_USTT 0xA4
238 BALANCED_PERFORMANCE 0x98
243 Usually if a model doesn't support the first four profiles they will support
244 the User Selectable Thermal Tables (USTT) profiles and vice-versa.
246 GMODE replaces PERFORMANCE in G-Series laptops.
248 WMI method GameShiftStatus([in] uint32 arg2, [out] uint32 argr)
249 ---------------------------------------------------------------
253 if BYTE_0(arg2) == 0x1:
255 argr = GET_GAME_SHIFT_STATUS()
257 if BYTE_0(arg2) == 0x2:
258 argr = GET_GAME_SHIFT_STATUS()
260 Game Shift Status does not change the fan speed profile but it could be some
261 sort of CPU/GPU power profile. Benchmarks have not been done.
263 This method is only present on Dell's G-Series laptops and it's implementation
264 implies GMODE thermal profile is available, even if operation 0x03 of
265 Thermal_Information does not list it.
267 G-key on Dell's G-Series laptops also changes Game Shift status, so both are
270 WMI method GetFanSensors([in] uint32 arg2, [out] uint32 argr)
271 -------------------------------------------------------------
275 if BYTE_0(arg2) == 0x1:
276 if is_valid_fan(BYTE_1(arg2)):
281 if BYTE_0(arg2) == 0x2:
282 if is_valid_fan(BYTE_1(arg2)):
283 if BYTE_2(arg2) == 0:
294 These methods have not been tested and are only partially reverse
297 WMI method Return_OverclockingReport([out] uint32 argr)
298 -------------------------------------------------------
305 CSMI is an unknown operation.
307 WMI method Set_OCUIBIOSControl([in] uint32 arg2, [out] uint32 argr)
308 -------------------------------------------------------------------
315 CSMI is an unknown operation.
317 WMI method Clear_OCFailSafeFlag([out] uint32 argr)
318 --------------------------------------------------
325 CSMI is an unknown operation.
328 WMI method MemoryOCControl([in] uint32 arg2, [out] uint32 argr)
329 ---------------------------------------------------------------
331 AWCC supports memory overclocking, but this method is very intricate and has
332 not been deciphered yet.
337 These methods are probably related to some kind of firmware update system,
338 through a GPIO device.
341 These methods have not been tested and are only partially reverse
344 WMI method FWUpdateGPIOtoggle([in] uint32 arg2, [out] uint32 argr)
345 ------------------------------------------------------------------
349 if BYTE_0(arg2) == 0:
350 if BYTE_1(arg2) == 1:
355 if BYTE_0(arg2) == 1:
356 if BYTE_1(arg2) == 1:
365 WMI method ReadTotalofGPIOs([out] uint32 argr)
366 ----------------------------------------------
372 WMI method ReadGPIOpPinStatus([in] uint32 arg2, [out] uint32 argr)
373 ------------------------------------------------------------------
377 if BYTE_0(arg2) == 0:
380 if BYTE_0(arg2) == 1:
383 Other information Methods
384 =========================
386 WMI method ReadChassisColor([out] uint32 argr)
387 ----------------------------------------------
391 argr = CHASSIS_COLOR_ID
396 Kudos to `AlexIII <https://github.com/AlexIII/tcc-g15>`_ for documenting
397 and testing available thermal profile codes.