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