1b64c1a15SArmin Wolf.. SPDX-License-Identifier: GPL-2.0-or-later 2b64c1a15SArmin Wolf 3b64c1a15SArmin Wolf============================================ 4b64c1a15SArmin WolfDell DDV WMI interface driver (dell-wmi-ddv) 5b64c1a15SArmin Wolf============================================ 6b64c1a15SArmin Wolf 7b64c1a15SArmin WolfIntroduction 8b64c1a15SArmin Wolf============ 9b64c1a15SArmin Wolf 10b64c1a15SArmin WolfMany Dell notebooks made after ~2020 support a WMI-based interface for 11b64c1a15SArmin Wolfretrieving various system data like battery temperature, ePPID, diagostic data 12b64c1a15SArmin Wolfand fan/thermal sensor data. 13b64c1a15SArmin Wolf 14b64c1a15SArmin WolfThis interface is likely used by the `Dell Data Vault` software on Windows, 15b64c1a15SArmin Wolfso it was called `DDV`. Currently the ``dell-wmi-ddv`` driver supports 16b64c1a15SArmin Wolfversion 2 and 3 of the interface, with support for new interface versions 17b64c1a15SArmin Wolfeasily added. 18b64c1a15SArmin Wolf 19b64c1a15SArmin Wolf.. warning:: The interface is regarded as internal by Dell, so no vendor 20b64c1a15SArmin Wolf documentation is available. All knowledge was thus obtained by 21b64c1a15SArmin Wolf trial-and-error, please keep that in mind. 22b64c1a15SArmin Wolf 23b64c1a15SArmin WolfDell ePPID (electronic Piece Part Identification) 24b64c1a15SArmin Wolf================================================= 25b64c1a15SArmin Wolf 26b64c1a15SArmin WolfThe Dell ePPID is used to uniquely identify components in Dell machines, 27b64c1a15SArmin Wolfincluding batteries. It has a form similar to `CC-PPPPPP-MMMMM-YMD-SSSS-FFF` 28b64c1a15SArmin Wolfand contains the following information: 29b64c1a15SArmin Wolf 30b64c1a15SArmin Wolf* Country code of origin (CC). 31b64c1a15SArmin Wolf* Part number with the first character being a filling number (PPPPPP). 32b64c1a15SArmin Wolf* Manufacture Identification (MMMMM). 33b64c1a15SArmin Wolf* Manufacturing Year/Month/Date (YMD) in base 36, with Y being the last digit 34b64c1a15SArmin Wolf of the year. 35b64c1a15SArmin Wolf* Manufacture Sequence Number (SSSS). 36b64c1a15SArmin Wolf* Optional Firmware Version/Revision (FFF). 37b64c1a15SArmin Wolf 38b64c1a15SArmin WolfThe `eppidtool <https://pypi.org/project/eppidtool>`_ python utility can be used 39b64c1a15SArmin Wolfto decode and display this information. 40b64c1a15SArmin Wolf 41b64c1a15SArmin WolfAll information regarding the Dell ePPID was gathered using Dell support 42b64c1a15SArmin Wolfdocumentation and `this website <https://telcontar.net/KBK/Dell/date_codes>`_. 43b64c1a15SArmin Wolf 44b64c1a15SArmin WolfWMI interface description 45b64c1a15SArmin Wolf========================= 46b64c1a15SArmin Wolf 47b64c1a15SArmin WolfThe WMI interface description can be decoded from the embedded binary MOF (bmof) 48b64c1a15SArmin Wolfdata using the `bmfdec <https://github.com/pali/bmfdec>`_ utility: 49b64c1a15SArmin Wolf 50b64c1a15SArmin Wolf:: 51b64c1a15SArmin Wolf 52b64c1a15SArmin Wolf [WMI, Dynamic, Provider("WmiProv"), Locale("MS\\0x409"), Description("WMI Function"), guid("{8A42EA14-4F2A-FD45-6422-0087F7A7E608}")] 53b64c1a15SArmin Wolf class DDVWmiMethodFunction { 54b64c1a15SArmin Wolf [key, read] string InstanceName; 55b64c1a15SArmin Wolf [read] boolean Active; 56b64c1a15SArmin Wolf 57b64c1a15SArmin Wolf [WmiMethodId(1), Implemented, read, write, Description("Return Battery Design Capacity.")] void BatteryDesignCapacity([in] uint32 arg2, [out] uint32 argr); 58b64c1a15SArmin Wolf [WmiMethodId(2), Implemented, read, write, Description("Return Battery Full Charge Capacity.")] void BatteryFullChargeCapacity([in] uint32 arg2, [out] uint32 argr); 59b64c1a15SArmin Wolf [WmiMethodId(3), Implemented, read, write, Description("Return Battery Manufacture Name.")] void BatteryManufactureName([in] uint32 arg2, [out] string argr); 60b64c1a15SArmin Wolf [WmiMethodId(4), Implemented, read, write, Description("Return Battery Manufacture Date.")] void BatteryManufactureDate([in] uint32 arg2, [out] uint32 argr); 61b64c1a15SArmin Wolf [WmiMethodId(5), Implemented, read, write, Description("Return Battery Serial Number.")] void BatterySerialNumber([in] uint32 arg2, [out] uint32 argr); 62b64c1a15SArmin Wolf [WmiMethodId(6), Implemented, read, write, Description("Return Battery Chemistry Value.")] void BatteryChemistryValue([in] uint32 arg2, [out] string argr); 63b64c1a15SArmin Wolf [WmiMethodId(7), Implemented, read, write, Description("Return Battery Temperature.")] void BatteryTemperature([in] uint32 arg2, [out] uint32 argr); 64b64c1a15SArmin Wolf [WmiMethodId(8), Implemented, read, write, Description("Return Battery Current.")] void BatteryCurrent([in] uint32 arg2, [out] uint32 argr); 65b64c1a15SArmin Wolf [WmiMethodId(9), Implemented, read, write, Description("Return Battery Voltage.")] void BatteryVoltage([in] uint32 arg2, [out] uint32 argr); 66b64c1a15SArmin Wolf [WmiMethodId(10), Implemented, read, write, Description("Return Battery Manufacture Access(MA code).")] void BatteryManufactureAceess([in] uint32 arg2, [out] uint32 argr); 67b64c1a15SArmin Wolf [WmiMethodId(11), Implemented, read, write, Description("Return Battery Relative State-Of-Charge.")] void BatteryRelativeStateOfCharge([in] uint32 arg2, [out] uint32 argr); 68b64c1a15SArmin Wolf [WmiMethodId(12), Implemented, read, write, Description("Return Battery Cycle Count")] void BatteryCycleCount([in] uint32 arg2, [out] uint32 argr); 69b64c1a15SArmin Wolf [WmiMethodId(13), Implemented, read, write, Description("Return Battery ePPID")] void BatteryePPID([in] uint32 arg2, [out] string argr); 70b64c1a15SArmin Wolf [WmiMethodId(14), Implemented, read, write, Description("Return Battery Raw Analytics Start")] void BatteryeRawAnalyticsStart([in] uint32 arg2, [out] uint32 argr); 71b64c1a15SArmin Wolf [WmiMethodId(15), Implemented, read, write, Description("Return Battery Raw Analytics")] void BatteryeRawAnalytics([in] uint32 arg2, [out] uint32 RawSize, [out, WmiSizeIs("RawSize") : ToInstance] uint8 RawData[]); 72b64c1a15SArmin Wolf [WmiMethodId(16), Implemented, read, write, Description("Return Battery Design Voltage.")] void BatteryDesignVoltage([in] uint32 arg2, [out] uint32 argr); 73b64c1a15SArmin Wolf [WmiMethodId(17), Implemented, read, write, Description("Return Battery Raw Analytics A Block")] void BatteryeRawAnalyticsABlock([in] uint32 arg2, [out] uint32 RawSize, [out, WmiSizeIs("RawSize") : ToInstance] uint8 RawData[]); 74b64c1a15SArmin Wolf [WmiMethodId(18), Implemented, read, write, Description("Return Version.")] void ReturnVersion([in] uint32 arg2, [out] uint32 argr); 75b64c1a15SArmin Wolf [WmiMethodId(32), Implemented, read, write, Description("Return Fan Sensor Information")] void FanSensorInformation([in] uint32 arg2, [out] uint32 RawSize, [out, WmiSizeIs("RawSize") : ToInstance] uint8 RawData[]); 76b64c1a15SArmin Wolf [WmiMethodId(34), Implemented, read, write, Description("Return Thermal Sensor Information")] void ThermalSensorInformation([in] uint32 arg2, [out] uint32 RawSize, [out, WmiSizeIs("RawSize") : ToInstance] uint8 RawData[]); 77b64c1a15SArmin Wolf }; 78b64c1a15SArmin Wolf 79b64c1a15SArmin WolfEach WMI method takes an ACPI buffer containing a 32-bit index as input argument, 80b64c1a15SArmin Wolfwith the first 8 bit being used to specify the battery when using battery-related 81b64c1a15SArmin WolfWMI methods. Other WMI methods may ignore this argument or interpret it 82b64c1a15SArmin Wolfdifferently. The WMI method output format varies: 83b64c1a15SArmin Wolf 84b64c1a15SArmin Wolf* if the function has only a single output, then an ACPI object 85b64c1a15SArmin Wolf of the corresponding type is returned 86b64c1a15SArmin Wolf* if the function has multiple outputs, when an ACPI package 87b64c1a15SArmin Wolf containing the outputs in the same order is returned 88b64c1a15SArmin Wolf 89b64c1a15SArmin WolfThe format of the output should be thoroughly checked, since many methods can 90b64c1a15SArmin Wolfreturn malformed data in case of an error. 91b64c1a15SArmin Wolf 92b64c1a15SArmin WolfThe data format of many battery-related methods seems to be based on the 93b64c1a15SArmin Wolf`Smart Battery Data Specification`, so unknown battery-related methods are 94b64c1a15SArmin Wolflikely to follow this standard in some way. 95b64c1a15SArmin Wolf 96b64c1a15SArmin WolfWMI method GetBatteryDesignCapacity() 97b64c1a15SArmin Wolf------------------------------------- 98b64c1a15SArmin Wolf 99b64c1a15SArmin WolfReturns the design capacity of the battery in mAh as an u16. 100b64c1a15SArmin Wolf 101b64c1a15SArmin WolfWMI method BatteryFullCharge() 102b64c1a15SArmin Wolf------------------------------ 103b64c1a15SArmin Wolf 104b64c1a15SArmin WolfReturns the full charge capacity of the battery in mAh as an u16. 105b64c1a15SArmin Wolf 106b64c1a15SArmin WolfWMI method BatteryManufactureName() 107b64c1a15SArmin Wolf----------------------------------- 108b64c1a15SArmin Wolf 109b64c1a15SArmin WolfReturns the manufacture name of the battery as an ASCII string. 110b64c1a15SArmin Wolf 111b64c1a15SArmin WolfWMI method BatteryManufactureDate() 112b64c1a15SArmin Wolf----------------------------------- 113b64c1a15SArmin Wolf 114b64c1a15SArmin WolfReturns the manufacture date of the battery as an u16. 115b64c1a15SArmin WolfThe date is encoded in the following manner: 116b64c1a15SArmin Wolf 117b64c1a15SArmin Wolf- bits 0 to 4 contain the manufacture day. 118b64c1a15SArmin Wolf- bits 5 to 8 contain the manufacture month. 119b64c1a15SArmin Wolf- bits 9 to 15 contain the manufacture year biased by 1980. 120b64c1a15SArmin Wolf 121b64c1a15SArmin Wolf.. note:: 122b64c1a15SArmin Wolf The data format needs to be verified on more machines. 123b64c1a15SArmin Wolf 124b64c1a15SArmin WolfWMI method BatterySerialNumber() 125b64c1a15SArmin Wolf-------------------------------- 126b64c1a15SArmin Wolf 127b64c1a15SArmin WolfReturns the serial number of the battery as an u16. 128b64c1a15SArmin Wolf 129b64c1a15SArmin WolfWMI method BatteryChemistryValue() 130b64c1a15SArmin Wolf---------------------------------- 131b64c1a15SArmin Wolf 132b64c1a15SArmin WolfReturns the chemistry of the battery as an ASCII string. 133b64c1a15SArmin WolfKnown values are: 134b64c1a15SArmin Wolf 135b64c1a15SArmin Wolf- "Li-I" for Li-Ion 136b64c1a15SArmin Wolf 137b64c1a15SArmin WolfWMI method BatteryTemperature() 138b64c1a15SArmin Wolf------------------------------- 139b64c1a15SArmin Wolf 140b64c1a15SArmin WolfReturns the temperature of the battery in tenth degree kelvin as an u16. 141b64c1a15SArmin Wolf 142b64c1a15SArmin WolfWMI method BatteryCurrent() 143b64c1a15SArmin Wolf--------------------------- 144b64c1a15SArmin Wolf 145b64c1a15SArmin WolfReturns the current flow of the battery in mA as an s16. 146b64c1a15SArmin WolfNegative values indicate discharging. 147b64c1a15SArmin Wolf 148b64c1a15SArmin WolfWMI method BatteryVoltage() 149b64c1a15SArmin Wolf--------------------------- 150b64c1a15SArmin Wolf 151b64c1a15SArmin WolfReturns the voltage flow of the battery in mV as an u16. 152b64c1a15SArmin Wolf 153b64c1a15SArmin WolfWMI method BatteryManufactureAccess() 154b64c1a15SArmin Wolf------------------------------------- 155b64c1a15SArmin Wolf 156b64c1a15SArmin WolfReturns a manufacture-defined value as an u16. 157b64c1a15SArmin Wolf 158b64c1a15SArmin WolfWMI method BatteryRelativeStateOfCharge() 159b64c1a15SArmin Wolf----------------------------------------- 160b64c1a15SArmin Wolf 161b64c1a15SArmin WolfReturns the capacity of the battery in percent as an u16. 162b64c1a15SArmin Wolf 163b64c1a15SArmin WolfWMI method BatteryCycleCount() 164b64c1a15SArmin Wolf------------------------------ 165b64c1a15SArmin Wolf 166b64c1a15SArmin WolfReturns the cycle count of the battery as an u16. 167b64c1a15SArmin Wolf 168b64c1a15SArmin WolfWMI method BatteryePPID() 169b64c1a15SArmin Wolf------------------------- 170b64c1a15SArmin Wolf 171b64c1a15SArmin WolfReturns the ePPID of the battery as an ASCII string. 172b64c1a15SArmin Wolf 173b64c1a15SArmin WolfWMI method BatteryeRawAnalyticsStart() 174b64c1a15SArmin Wolf-------------------------------------- 175b64c1a15SArmin Wolf 176b64c1a15SArmin WolfPerforms an analysis of the battery and returns a status code: 177b64c1a15SArmin Wolf 178b64c1a15SArmin Wolf- ``0x0``: Success 179b64c1a15SArmin Wolf- ``0x1``: Interface not supported 180b64c1a15SArmin Wolf- ``0xfffffffe``: Error/Timeout 181b64c1a15SArmin Wolf 182b64c1a15SArmin Wolf.. note:: 183b64c1a15SArmin Wolf The meaning of this method is still largely unknown. 184b64c1a15SArmin Wolf 185b64c1a15SArmin WolfWMI method BatteryeRawAnalytics() 186b64c1a15SArmin Wolf--------------------------------- 187b64c1a15SArmin Wolf 188*d56b699dSBjorn HelgaasReturns a buffer usually containing 12 blocks of analytics data. 189b64c1a15SArmin WolfThose blocks contain: 190b64c1a15SArmin Wolf 191b64c1a15SArmin Wolf- a block number starting with 0 (u8) 192b64c1a15SArmin Wolf- 31 bytes of unknown data 193b64c1a15SArmin Wolf 194b64c1a15SArmin Wolf.. note:: 195b64c1a15SArmin Wolf The meaning of this method is still largely unknown. 196b64c1a15SArmin Wolf 197b64c1a15SArmin WolfWMI method BatteryDesignVoltage() 198b64c1a15SArmin Wolf--------------------------------- 199b64c1a15SArmin Wolf 200b64c1a15SArmin WolfReturns the design voltage of the battery in mV as an u16. 201b64c1a15SArmin Wolf 202b64c1a15SArmin WolfWMI method BatteryeRawAnalyticsABlock() 203b64c1a15SArmin Wolf--------------------------------------- 204b64c1a15SArmin Wolf 205b64c1a15SArmin WolfReturns a single block of analytics data, with the second byte 206b64c1a15SArmin Wolfof the index being used for selecting the block number. 207b64c1a15SArmin Wolf 208b64c1a15SArmin Wolf*Supported since WMI interface version 3!* 209b64c1a15SArmin Wolf 210b64c1a15SArmin Wolf.. note:: 211b64c1a15SArmin Wolf The meaning of this method is still largely unknown. 212b64c1a15SArmin Wolf 213b64c1a15SArmin WolfWMI method ReturnVersion() 214b64c1a15SArmin Wolf-------------------------- 215b64c1a15SArmin Wolf 216b64c1a15SArmin WolfReturns the WMI interface version as an u32. 217b64c1a15SArmin Wolf 218b64c1a15SArmin WolfWMI method FanSensorInformation() 219b64c1a15SArmin Wolf--------------------------------- 220*d56b699dSBjorn Helgaas 221b64c1a15SArmin WolfReturns a buffer containing fan sensor entries, terminated 222b64c1a15SArmin Wolfwith a single ``0xff``. 223b64c1a15SArmin WolfThose entries contain: 224b64c1a15SArmin Wolf 225b64c1a15SArmin Wolf- fan type (u8) 226b64c1a15SArmin Wolf- fan speed in RPM (little endian u16) 227b64c1a15SArmin Wolf 228b64c1a15SArmin WolfWMI method ThermalSensorInformation() 229b64c1a15SArmin Wolf------------------------------------- 230b64c1a15SArmin Wolf 231b64c1a15SArmin WolfReturns a buffer containing thermal sensor entries, terminated 232b64c1a15SArmin Wolfwith a single ``0xff``. 233b64c1a15SArmin WolfThose entries contain: 234b64c1a15SArmin Wolf 235b64c1a15SArmin Wolf- thermal type (u8) 236b64c1a15SArmin Wolf- current temperature (s8) 237b64c1a15SArmin Wolf- min. temperature (s8) 238b64c1a15SArmin Wolf- max. temperature (s8) 239b64c1a15SArmin Wolf- unknown field (u8) 240b64c1a15SArmin Wolf 241b64c1a15SArmin Wolf.. note:: 242b64c1a15SArmin Wolf TODO: Find out what the meaning of the last byte is. 243b64c1a15SArmin Wolf 244b64c1a15SArmin WolfACPI battery matching algorithm 245b64c1a15SArmin Wolf=============================== 246b64c1a15SArmin Wolf 247b64c1a15SArmin WolfThe algorithm used to match ACPI batteries to indices is based on information 248b64c1a15SArmin Wolfwhich was found inside the logging messages of the OEM software. 249b64c1a15SArmin Wolf 250b64c1a15SArmin WolfBasically for each new ACPI battery, the serial numbers of the batteries behind 251b64c1a15SArmin Wolfindices 1 till 3 are compared with the serial number of the ACPI battery. 252b64c1a15SArmin WolfSince the serial number of the ACPI battery can either be encoded as a normal 253b64c1a15SArmin Wolfinteger or as a hexadecimal value, both cases need to be checked. The first 254b64c1a15SArmin Wolfindex with a matching serial number is then selected. 255b64c1a15SArmin Wolf 256b64c1a15SArmin WolfA serial number of 0 indicates that the corresponding index is not associated 257b64c1a15SArmin Wolfwith an actual battery, or that the associated battery is not present. 258b64c1a15SArmin Wolf 259b64c1a15SArmin WolfSome machines like the Dell Inspiron 3505 only support a single battery and thus 260b64c1a15SArmin Wolfignore the battery index. Because of this the driver depends on the ACPI battery 261b64c1a15SArmin Wolfhook mechanism to discover batteries. 262b64c1a15SArmin Wolf 263b64c1a15SArmin Wolf.. note:: 264b64c1a15SArmin Wolf The ACPI battery matching algorithm currently used inside the driver is 265b64c1a15SArmin Wolf outdated and does not match the algorithm described above. The reasons for 266b64c1a15SArmin Wolf this are differences in the handling of the ToHexString() ACPI opcode between 267b64c1a15SArmin Wolf Linux and Windows, which distorts the serial number of ACPI batteries on many 268b64c1a15SArmin Wolf machines. Until this issue is resolved, the driver cannot use the above 269b64c1a15SArmin Wolf algorithm. 270b64c1a15SArmin Wolf 271b64c1a15SArmin WolfReverse-Engineering the DDV WMI interface 272b64c1a15SArmin Wolf========================================= 273b64c1a15SArmin Wolf 274b64c1a15SArmin Wolf1. Find a supported Dell notebook, usually made after ~2020. 275b64c1a15SArmin Wolf2. Dump the ACPI tables and search for the WMI device (usually called "ADDV"). 276b64c1a15SArmin Wolf3. Decode the corresponding bmof data and look at the ASL code. 277b64c1a15SArmin Wolf4. Try to deduce the meaning of a certain WMI method by comparing the control 278b64c1a15SArmin Wolf flow with other ACPI methods (_BIX or _BIF for battery related methods 279b64c1a15SArmin Wolf for example). 280b64c1a15SArmin Wolf5. Use the built-in UEFI diagostics to view sensor types/values for fan/thermal 281b64c1a15SArmin Wolf related methods (sometimes overwriting static ACPI data fields can be used 282b64c1a15SArmin Wolf to test different sensor type values, since on some machines this data is 283b64c1a15SArmin Wolf not reinitialized upon a warm reset). 284b64c1a15SArmin Wolf 285b64c1a15SArmin WolfAlternatively: 286b64c1a15SArmin Wolf 287b64c1a15SArmin Wolf1. Load the ``dell-wmi-ddv`` driver, use the ``force`` module param 288b64c1a15SArmin Wolf if necessary. 289b64c1a15SArmin Wolf2. Use the debugfs interface to access the raw fan/thermal sensor buffer data. 290b64c1a15SArmin Wolf3. Compare the data with the built-in UEFI diagnostics. 291b64c1a15SArmin Wolf 292b64c1a15SArmin WolfIn case the DDV WMI interface version available on your Dell notebook is not 293b64c1a15SArmin Wolfsupported or you are seeing unknown fan/thermal sensors, please submit a 294b64c1a15SArmin Wolfbugreport on `bugzilla <https://bugzilla.kernel.org>`_ so they can be added 295b64c1a15SArmin Wolfto the ``dell-wmi-ddv`` driver. 296b64c1a15SArmin Wolf 297See Documentation/admin-guide/reporting-issues.rst for further information. 298