xref: /linux/Documentation/wmi/devices/alienware-wmi.rst (revision f164dd0bf4c674bd3ae8cfc119f3cb03f09f9aef)
1.. SPDX-License-Identifier: GPL-2.0-or-later
2
3==============================================
4Dell AWCC WMI interface driver (alienware-wmi)
5==============================================
6
7Introduction
8============
9
10The WMI device WMAX has been implemented for many Alienware and Dell's G-Series
11models. Throughout these models, two implementations have been identified. The
12first one, used by older systems, deals with HDMI, brightness, RGB, amplifier
13and deep sleep control. The second one used by newer systems deals primarily
14with thermal, overclocking, and GPIO control.
15
16It is suspected that the latter is used by Alienware Command Center (AWCC) to
17manage manufacturer predefined thermal profiles. The alienware-wmi driver
18exposes Thermal_Information and Thermal_Control methods through the Platform
19Profile API to mimic AWCC's behavior.
20
21This newer interface, named AWCCMethodFunction has been reverse engineered, as
22Dell has not provided any official documentation. We will try to describe to the
23best of our ability its discovered inner workings.
24
25.. note::
26   The following method description may be incomplete and some operations have
27   different implementations between devices.
28
29WMI interface description
30-------------------------
31
32The WMI interface description can be decoded from the embedded binary MOF (bmof)
33data using the `bmfdec <https://github.com/pali/bmfdec>`_ utility:
34
35::
36
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;
41
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);
70 };
71
72Some of these methods get quite intricate so we will describe them using
73pseudo-code that vaguely resembles the original ASL code.
74
75Methods not described in the following document have unknown behavior.
76
77Argument Structure
78------------------
79
80All input arguments have type **uint32** and their structure is very similar
81between methods. Usually, the first byte corresponds to a specific *operation*
82the method performs, and the subsequent bytes correspond to *arguments* passed
83to this *operation*. For example, if an operation has code 0x01 and requires an
84ID 0xA0, the argument you would pass to the method is 0xA001.
85
86
87Thermal Methods
88===============
89
90WMI method Thermal_Information([in] uint32 arg2, [out] uint32 argr)
91-------------------------------------------------------------------
92
93::
94
95 if BYTE_0(arg2) == 0x01:
96         argr = 1
97
98 if BYTE_0(arg2) == 0x02:
99         argr = UNKNOWN_CONSTANT
100
101 if BYTE_0(arg2) == 0x03:
102         if BYTE_1(arg2) == 0x00:
103                 argr = FAN_ID_0
104
105         if BYTE_1(arg2) == 0x01:
106                 argr = FAN_ID_1
107
108         if BYTE_1(arg2) == 0x02:
109                 argr = FAN_ID_2
110
111         if BYTE_1(arg2) == 0x03:
112                 argr = FAN_ID_3
113
114         if BYTE_1(arg2) == 0x04:
115                 argr = SENSOR_ID_CPU | 0x0100
116
117         if BYTE_1(arg2) == 0x05:
118                 argr = SENSOR_ID_GPU | 0x0100
119
120         if BYTE_1(arg2) == 0x06:
121                 argr = THERMAL_MODE_QUIET_ID
122
123         if BYTE_1(arg2) == 0x07:
124                 argr = THERMAL_MODE_BALANCED_ID
125
126         if BYTE_1(arg2) == 0x08:
127                 argr = THERMAL_MODE_BALANCED_PERFORMANCE_ID
128
129         if BYTE_1(arg2) == 0x09:
130                 argr = THERMAL_MODE_PERFORMANCE_ID
131
132         if BYTE_1(arg2) == 0x0A:
133                 argr = THERMAL_MODE_LOW_POWER_ID
134
135         if BYTE_1(arg2) == 0x0B:
136                 argr = THERMAL_MODE_GMODE_ID
137
138         else:
139                 argr = 0xFFFFFFFF
140
141 if BYTE_0(arg2) == 0x04:
142         if is_valid_sensor(BYTE_1(arg2)):
143                 argr = SENSOR_TEMP_C
144         else:
145                 argr = 0xFFFFFFFF
146
147 if BYTE_0(arg2) == 0x05:
148         if is_valid_fan(BYTE_1(arg2)):
149                 argr = FAN_RPM()
150
151 if BYTE_0(arg2) == 0x06:
152         skip
153
154 if BYTE_0(arg2) == 0x07:
155         argr = 0
156
157 If BYTE_0(arg2) == 0x08:
158         if is_valid_fan(BYTE_1(arg2)):
159                 argr = 0
160         else:
161                 argr = 0xFFFFFFFF
162
163 if BYTE_0(arg2) == 0x09:
164         if is_valid_fan(BYTE_1(arg2)):
165                 argr = FAN_UNKNOWN_STAT_0()
166
167         else:
168                 argr = 0xFFFFFFFF
169
170 if BYTE_0(arg2) == 0x0A:
171         argr = THERMAL_MODE_BALANCED_ID
172
173 if BYTE_0(arg2) == 0x0B:
174         argr = CURRENT_THERMAL_MODE()
175
176 if BYTE_0(arg2) == 0x0C:
177         if is_valid_fan(BYTE_1(arg2)):
178                 argr = FAN_UNKNOWN_STAT_1()
179         else:
180                 argr = 0xFFFFFFFF
181
182Operation 0x03 list all available fan IDs, sensor IDs and thermal profile
183codes in order, but different models may have different number of fans and
184thermal profiles. These are the known ranges:
185
186* Fan IDs: from 2 up to 4
187* Sensor IDs: 2
188* Thermal profile codes: from 1 up to 7
189
190In total BYTE_1(ARG2) may range from 0x5 up to 0xD depending on the model.
191
192WMI method Thermal_Control([in] uint32 arg2, [out] uint32 argr)
193---------------------------------------------------------------
194
195::
196
197 if BYTE_0(arg2) == 0x01:
198         if is_valid_thermal_profile(BYTE_1(arg2)):
199                 SET_THERMAL_PROFILE(BYTE_1(arg2))
200                 argr = 0
201
202 if BYTE_0(arg2) == 0x02:
203         if is_valid_fan(BYTE_1(arg2)):
204                 SET_FAN_SPEED_MULTIPLIER(BYTE_2(arg2))
205                 argr = 0
206         else:
207                 argr = 0xFFFFFFFF
208
209.. note::
210   While you can manually change the fan speed multiplier with this method,
211   Dell's BIOS tends to overwrite this changes anyway.
212
213These are the known thermal profile codes:
214
215::
216
217 CUSTOM                         0x00
218
219 BALANCED_USTT                  0xA0
220 BALANCED_PERFORMANCE_USTT      0xA1
221 COOL_USTT                      0xA2
222 QUIET_USTT                     0xA3
223 PERFORMANCE_USTT               0xA4
224 LOW_POWER_USTT                 0xA5
225
226 QUIET                          0x96
227 BALANCED                       0x97
228 BALANCED_PERFORMANCE           0x98
229 PERFORMANCE                    0x99
230
231 GMODE                          0xAB
232
233Usually if a model doesn't support the first four profiles they will support
234the User Selectable Thermal Tables (USTT) profiles and vice-versa.
235
236GMODE replaces PERFORMANCE in G-Series laptops.
237
238WMI method GameShiftStatus([in] uint32 arg2, [out] uint32 argr)
239---------------------------------------------------------------
240
241::
242
243 if BYTE_0(arg2) == 0x1:
244         TOGGLE_GAME_SHIFT()
245         argr = GET_GAME_SHIFT_STATUS()
246
247 if BYTE_0(arg2) == 0x2:
248         argr = GET_GAME_SHIFT_STATUS()
249
250Game Shift Status does not change the fan speed profile but it could be some
251sort of CPU/GPU power profile. Benchmarks have not been done.
252
253This method is only present on Dell's G-Series laptops and it's implementation
254implies GMODE thermal profile is available, even if operation 0x03 of
255Thermal_Information does not list it.
256
257G-key on Dell's G-Series laptops also changes Game Shift status, so both are
258directly related.
259
260WMI method GetFanSensors([in] uint32 arg2, [out] uint32 argr)
261-------------------------------------------------------------
262
263::
264
265 if BYTE_0(arg2) == 0x1:
266        if is_valid_fan(BYTE_1(arg2)):
267                argr = 1
268        else:
269                argr = 0
270
271 if BYTE_0(arg2) == 0x2:
272        if is_valid_fan(BYTE_1(arg2)):
273                if BYTE_2(arg2) == 0:
274                        argr == SENSOR_ID
275                else
276                        argr == 0xFFFFFFFF
277        else:
278                argr = 0
279
280Overclocking Methods
281====================
282
283.. warning::
284   These methods have not been tested and are only partially reverse
285   engineered.
286
287WMI method Return_OverclockingReport([out] uint32 argr)
288-------------------------------------------------------
289
290::
291
292 CSMI (0xE3, 0x99)
293 argr = 0
294
295CSMI is an unknown operation.
296
297WMI method Set_OCUIBIOSControl([in] uint32 arg2, [out] uint32 argr)
298-------------------------------------------------------------------
299
300::
301
302 CSMI (0xE3, 0x99)
303 argr = 0
304
305CSMI is an unknown operation.
306
307WMI method Clear_OCFailSafeFlag([out] uint32 argr)
308--------------------------------------------------
309
310::
311
312 CSMI (0xE3, 0x99)
313 argr = 0
314
315CSMI is an unknown operation.
316
317
318WMI method MemoryOCControl([in] uint32 arg2, [out] uint32 argr)
319---------------------------------------------------------------
320
321AWCC supports memory overclocking, but this method is very intricate and has
322not been deciphered yet.
323
324GPIO methods
325============
326
327These methods are probably related to some kind of firmware update system,
328through a GPIO device.
329
330.. warning::
331   These methods have not been tested and are only partially reverse
332   engineered.
333
334WMI method FWUpdateGPIOtoggle([in] uint32 arg2, [out] uint32 argr)
335------------------------------------------------------------------
336
337::
338
339 if BYTE_0(arg2) == 0:
340         if BYTE_1(arg2) == 1:
341                 SET_PIN_A_HIGH()
342         else:
343                 SET_PIN_A_LOW()
344
345 if BYTE_0(arg2) == 1:
346         if BYTE_1(arg2) == 1:
347                 SET_PIN_B_HIGH()
348
349         else:
350                 SET_PIN_B_LOW()
351
352 else:
353         argr = 1
354
355WMI method ReadTotalofGPIOs([out] uint32 argr)
356----------------------------------------------
357
358::
359
360 argr = 0x02
361
362WMI method ReadGPIOpPinStatus([in] uint32 arg2, [out] uint32 argr)
363------------------------------------------------------------------
364
365::
366
367 if BYTE_0(arg2) == 0:
368         argr = PIN_A_STATUS
369
370 if BYTE_0(arg2) == 1:
371         argr = PIN_B_STATUS
372
373Other information Methods
374=========================
375
376WMI method ReadChassisColor([out] uint32 argr)
377----------------------------------------------
378
379::
380
381 argr = CHASSIS_COLOR_ID
382
383Acknowledgements
384================
385
386Kudos to `AlexIII <https://github.com/AlexIII/tcc-g15>`_ for documenting
387and testing available thermal profile codes.
388