xref: /linux/Documentation/wmi/devices/alienware-wmi.rst (revision 7f71507851fc7764b36a3221839607d3a45c2025)
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 = SYSTEM_DESCRIPTION
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 0x02 returns a *system description* buffer with the following
183structure:
184
185::
186
187 out[0] -> Number of fans
188 out[1] -> Number of sensors
189 out[2] -> 0x00
190 out[3] -> Number of thermal modes
191
192Operation 0x03 list all available fan IDs, sensor IDs and thermal profile
193codes in order, but different models may have different number of fans and
194thermal profiles. These are the known ranges:
195
196* Fan IDs: from 2 up to 4
197* Sensor IDs: 2
198* Thermal profile codes: from 1 up to 7
199
200In total BYTE_1(ARG2) may range from 0x5 up to 0xD depending on the model.
201
202WMI method Thermal_Control([in] uint32 arg2, [out] uint32 argr)
203---------------------------------------------------------------
204
205::
206
207 if BYTE_0(arg2) == 0x01:
208         if is_valid_thermal_profile(BYTE_1(arg2)):
209                 SET_THERMAL_PROFILE(BYTE_1(arg2))
210                 argr = 0
211
212 if BYTE_0(arg2) == 0x02:
213         if is_valid_fan(BYTE_1(arg2)):
214                 SET_FAN_SPEED_MULTIPLIER(BYTE_2(arg2))
215                 argr = 0
216         else:
217                 argr = 0xFFFFFFFF
218
219.. note::
220   While you can manually change the fan speed multiplier with this method,
221   Dell's BIOS tends to overwrite this changes anyway.
222
223These are the known thermal profile codes:
224
225::
226
227 CUSTOM                         0x00
228
229 BALANCED_USTT                  0xA0
230 BALANCED_PERFORMANCE_USTT      0xA1
231 COOL_USTT                      0xA2
232 QUIET_USTT                     0xA3
233 PERFORMANCE_USTT               0xA4
234 LOW_POWER_USTT                 0xA5
235
236 QUIET                          0x96
237 BALANCED                       0x97
238 BALANCED_PERFORMANCE           0x98
239 PERFORMANCE                    0x99
240
241 GMODE                          0xAB
242
243Usually if a model doesn't support the first four profiles they will support
244the User Selectable Thermal Tables (USTT) profiles and vice-versa.
245
246GMODE replaces PERFORMANCE in G-Series laptops.
247
248WMI method GameShiftStatus([in] uint32 arg2, [out] uint32 argr)
249---------------------------------------------------------------
250
251::
252
253 if BYTE_0(arg2) == 0x1:
254         TOGGLE_GAME_SHIFT()
255         argr = GET_GAME_SHIFT_STATUS()
256
257 if BYTE_0(arg2) == 0x2:
258         argr = GET_GAME_SHIFT_STATUS()
259
260Game Shift Status does not change the fan speed profile but it could be some
261sort of CPU/GPU power profile. Benchmarks have not been done.
262
263This method is only present on Dell's G-Series laptops and it's implementation
264implies GMODE thermal profile is available, even if operation 0x03 of
265Thermal_Information does not list it.
266
267G-key on Dell's G-Series laptops also changes Game Shift status, so both are
268directly related.
269
270WMI method GetFanSensors([in] uint32 arg2, [out] uint32 argr)
271-------------------------------------------------------------
272
273::
274
275 if BYTE_0(arg2) == 0x1:
276        if is_valid_fan(BYTE_1(arg2)):
277                argr = 1
278        else:
279                argr = 0
280
281 if BYTE_0(arg2) == 0x2:
282        if is_valid_fan(BYTE_1(arg2)):
283                if BYTE_2(arg2) == 0:
284                        argr == SENSOR_ID
285                else
286                        argr == 0xFFFFFFFF
287        else:
288                argr = 0
289
290Overclocking Methods
291====================
292
293.. warning::
294   These methods have not been tested and are only partially reverse
295   engineered.
296
297WMI method Return_OverclockingReport([out] uint32 argr)
298-------------------------------------------------------
299
300::
301
302 CSMI (0xE3, 0x99)
303 argr = 0
304
305CSMI is an unknown operation.
306
307WMI method Set_OCUIBIOSControl([in] uint32 arg2, [out] uint32 argr)
308-------------------------------------------------------------------
309
310::
311
312 CSMI (0xE3, 0x99)
313 argr = 0
314
315CSMI is an unknown operation.
316
317WMI method Clear_OCFailSafeFlag([out] uint32 argr)
318--------------------------------------------------
319
320::
321
322 CSMI (0xE3, 0x99)
323 argr = 0
324
325CSMI is an unknown operation.
326
327
328WMI method MemoryOCControl([in] uint32 arg2, [out] uint32 argr)
329---------------------------------------------------------------
330
331AWCC supports memory overclocking, but this method is very intricate and has
332not been deciphered yet.
333
334GPIO methods
335============
336
337These methods are probably related to some kind of firmware update system,
338through a GPIO device.
339
340.. warning::
341   These methods have not been tested and are only partially reverse
342   engineered.
343
344WMI method FWUpdateGPIOtoggle([in] uint32 arg2, [out] uint32 argr)
345------------------------------------------------------------------
346
347::
348
349 if BYTE_0(arg2) == 0:
350         if BYTE_1(arg2) == 1:
351                 SET_PIN_A_HIGH()
352         else:
353                 SET_PIN_A_LOW()
354
355 if BYTE_0(arg2) == 1:
356         if BYTE_1(arg2) == 1:
357                 SET_PIN_B_HIGH()
358
359         else:
360                 SET_PIN_B_LOW()
361
362 else:
363         argr = 1
364
365WMI method ReadTotalofGPIOs([out] uint32 argr)
366----------------------------------------------
367
368::
369
370 argr = 0x02
371
372WMI method ReadGPIOpPinStatus([in] uint32 arg2, [out] uint32 argr)
373------------------------------------------------------------------
374
375::
376
377 if BYTE_0(arg2) == 0:
378         argr = PIN_A_STATUS
379
380 if BYTE_0(arg2) == 1:
381         argr = PIN_B_STATUS
382
383Other information Methods
384=========================
385
386WMI method ReadChassisColor([out] uint32 argr)
387----------------------------------------------
388
389::
390
391 argr = CHASSIS_COLOR_ID
392
393Acknowledgements
394================
395
396Kudos to `AlexIII <https://github.com/AlexIII/tcc-g15>`_ for documenting
397and testing available thermal profile codes.
398