1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * HWMON driver for ASUS motherboards that publish some sensor values 4 * via the embedded controller registers. 5 * 6 * Copyright (C) 2021 Eugene Shalygin <eugene.shalygin@gmail.com> 7 8 * EC provides: 9 * - Chipset temperature 10 * - CPU temperature 11 * - Motherboard temperature 12 * - T_Sensor temperature 13 * - VRM temperature 14 * - Water In temperature 15 * - Water Out temperature 16 * - CPU Optional fan RPM 17 * - Chipset fan RPM 18 * - VRM Heat Sink fan RPM 19 * - Water Flow fan RPM 20 * - CPU current 21 * - CPU core voltage 22 */ 23 24 #include <linux/acpi.h> 25 #include <linux/bitops.h> 26 #include <linux/dev_printk.h> 27 #include <linux/dmi.h> 28 #include <linux/hwmon.h> 29 #include <linux/init.h> 30 #include <linux/jiffies.h> 31 #include <linux/kernel.h> 32 #include <linux/module.h> 33 #include <linux/platform_device.h> 34 #include <linux/sort.h> 35 #include <linux/units.h> 36 37 #include <linux/unaligned.h> 38 39 static char *mutex_path_override; 40 41 /* Writing to this EC register switches EC bank */ 42 #define ASUS_EC_BANK_REGISTER 0xff 43 #define SENSOR_LABEL_LEN 16 44 45 /* 46 * Arbitrary set max. allowed bank number. Required for sorting banks and 47 * currently is overkill with just 2 banks used at max, but for the sake 48 * of alignment let's set it to a higher value. 49 */ 50 #define ASUS_EC_MAX_BANK 3 51 52 #define ACPI_LOCK_DELAY_MS 800 53 54 /* ACPI mutex for locking access to the EC for the firmware */ 55 #define ASUS_HW_ACCESS_MUTEX_ASMX "\\AMW0.ASMX" 56 57 #define ASUS_HW_ACCESS_MUTEX_RMTW_ASMX "\\RMTW.ASMX" 58 59 #define ASUS_HW_ACCESS_MUTEX_SB_PC00_LPCB_SIO1_MUT0 "\\_SB.PC00.LPCB.SIO1.MUT0" 60 61 #define ASUS_HW_ACCESS_MUTEX_SB_PCI0_SBRG_SIO1_MUT0 "\\_SB_.PCI0.SBRG.SIO1.MUT0" 62 63 #define ASUS_HW_ACCESS_MUTEX_SB_PCI0_LPCB_SIO1_MUT0 "\\_SB_.PCI0.LPCB.SIO1.MUT0" 64 65 #define MAX_IDENTICAL_BOARD_VARIATIONS 3 66 67 /* Moniker for the ACPI global lock (':' is not allowed in ASL identifiers) */ 68 #define ACPI_GLOBAL_LOCK_PSEUDO_PATH ":GLOBAL_LOCK" 69 70 typedef union { 71 u32 value; 72 struct { 73 u8 index; 74 u8 bank; 75 u8 size; 76 u8 dummy; 77 } components; 78 } sensor_address; 79 80 #define MAKE_SENSOR_ADDRESS(size, bank, index) { \ 81 .value = (size << 16) + (bank << 8) + index \ 82 } 83 84 static u32 hwmon_attributes[hwmon_max] = { 85 [hwmon_chip] = HWMON_C_REGISTER_TZ, 86 [hwmon_temp] = HWMON_T_INPUT | HWMON_T_LABEL, 87 [hwmon_in] = HWMON_I_INPUT | HWMON_I_LABEL, 88 [hwmon_curr] = HWMON_C_INPUT | HWMON_C_LABEL, 89 [hwmon_fan] = HWMON_F_INPUT | HWMON_F_LABEL, 90 }; 91 92 struct ec_sensor_info { 93 char label[SENSOR_LABEL_LEN]; 94 enum hwmon_sensor_types type; 95 sensor_address addr; 96 }; 97 98 #define EC_SENSOR(sensor_label, sensor_type, size, bank, index) { \ 99 .label = sensor_label, .type = sensor_type, \ 100 .addr = MAKE_SENSOR_ADDRESS(size, bank, index), \ 101 } 102 103 enum ec_sensors { 104 /* chipset temperature [℃] */ 105 ec_sensor_temp_chipset, 106 /* CPU temperature [℃] */ 107 ec_sensor_temp_cpu, 108 /* CPU package temperature [℃] */ 109 ec_sensor_temp_cpu_package, 110 /* motherboard temperature [℃] */ 111 ec_sensor_temp_mb, 112 /* "T_Sensor" temperature sensor reading [℃] */ 113 ec_sensor_temp_t_sensor, 114 /* like ec_sensor_temp_t_sensor, but at an alternate address [℃] */ 115 ec_sensor_temp_t_sensor_alt1, 116 /* VRM temperature [℃] */ 117 ec_sensor_temp_vrm, 118 /* VRM east (right) temperature [℃] */ 119 ec_sensor_temp_vrme, 120 /* VRM west (left) temperature [℃] */ 121 ec_sensor_temp_vrmw, 122 /* CPU Core voltage [mV] */ 123 ec_sensor_in_cpu_core, 124 /* CPU_Opt fan [RPM] */ 125 ec_sensor_fan_cpu_opt, 126 /* VRM heat sink fan [RPM] */ 127 ec_sensor_fan_vrm_hs, 128 /* VRM east (right) heat sink fan [RPM] */ 129 ec_sensor_fan_vrme_hs, 130 /* VRM west (left) heat sink fan [RPM] */ 131 ec_sensor_fan_vrmw_hs, 132 /* Chipset fan [RPM] */ 133 ec_sensor_fan_chipset, 134 /* Water flow sensor reading [RPM] */ 135 ec_sensor_fan_water_flow, 136 /* USB4 fan [RPM] */ 137 ec_sensor_fan_usb4, 138 /* M.2 fan [RPM] */ 139 ec_sensor_fan_m2, 140 /* CPU current [A] */ 141 ec_sensor_curr_cpu, 142 /* "Water_In" temperature sensor reading [℃] */ 143 ec_sensor_temp_water_in, 144 /* "Water_Out" temperature sensor reading [℃] */ 145 ec_sensor_temp_water_out, 146 /* "Water_Block_In" temperature sensor reading [℃] */ 147 ec_sensor_temp_water_block_in, 148 /* "Water_Block_Out" temperature sensor reading [℃] */ 149 ec_sensor_temp_water_block_out, 150 /* "T_sensor_2" temperature sensor reading [℃] */ 151 ec_sensor_temp_t_sensor_2, 152 /* "Extra_1" temperature sensor reading [℃] */ 153 ec_sensor_temp_sensor_extra_1, 154 /* "Extra_2" temperature sensor reading [℃] */ 155 ec_sensor_temp_sensor_extra_2, 156 /* "Extra_3" temperature sensor reading [℃] */ 157 ec_sensor_temp_sensor_extra_3, 158 }; 159 160 #define SENSOR_TEMP_CHIPSET BIT(ec_sensor_temp_chipset) 161 #define SENSOR_TEMP_CPU BIT(ec_sensor_temp_cpu) 162 #define SENSOR_TEMP_CPU_PACKAGE BIT(ec_sensor_temp_cpu_package) 163 #define SENSOR_TEMP_MB BIT(ec_sensor_temp_mb) 164 #define SENSOR_TEMP_T_SENSOR BIT(ec_sensor_temp_t_sensor) 165 #define SENSOR_TEMP_T_SENSOR_ALT1 BIT(ec_sensor_temp_t_sensor_alt1) 166 #define SENSOR_TEMP_VRM BIT(ec_sensor_temp_vrm) 167 #define SENSOR_TEMP_VRME BIT(ec_sensor_temp_vrme) 168 #define SENSOR_TEMP_VRMW BIT(ec_sensor_temp_vrmw) 169 #define SENSOR_IN_CPU_CORE BIT(ec_sensor_in_cpu_core) 170 #define SENSOR_FAN_CPU_OPT BIT(ec_sensor_fan_cpu_opt) 171 #define SENSOR_FAN_VRM_HS BIT(ec_sensor_fan_vrm_hs) 172 #define SENSOR_FAN_VRME_HS BIT(ec_sensor_fan_vrme_hs) 173 #define SENSOR_FAN_VRMW_HS BIT(ec_sensor_fan_vrmw_hs) 174 #define SENSOR_FAN_CHIPSET BIT(ec_sensor_fan_chipset) 175 #define SENSOR_FAN_WATER_FLOW BIT(ec_sensor_fan_water_flow) 176 #define SENSOR_FAN_USB4 BIT(ec_sensor_fan_usb4) 177 #define SENSOR_FAN_M2 BIT(ec_sensor_fan_m2) 178 #define SENSOR_CURR_CPU BIT(ec_sensor_curr_cpu) 179 #define SENSOR_TEMP_WATER_IN BIT(ec_sensor_temp_water_in) 180 #define SENSOR_TEMP_WATER_OUT BIT(ec_sensor_temp_water_out) 181 #define SENSOR_TEMP_WATER_BLOCK_IN BIT(ec_sensor_temp_water_block_in) 182 #define SENSOR_TEMP_WATER_BLOCK_OUT BIT(ec_sensor_temp_water_block_out) 183 #define SENSOR_TEMP_T_SENSOR_2 BIT(ec_sensor_temp_t_sensor_2) 184 #define SENSOR_TEMP_SENSOR_EXTRA_1 BIT(ec_sensor_temp_sensor_extra_1) 185 #define SENSOR_TEMP_SENSOR_EXTRA_2 BIT(ec_sensor_temp_sensor_extra_2) 186 #define SENSOR_TEMP_SENSOR_EXTRA_3 BIT(ec_sensor_temp_sensor_extra_3) 187 188 enum board_family { 189 family_unknown, 190 family_amd_400_series, 191 family_amd_500_series, 192 family_amd_600_series, 193 family_amd_800_series, 194 family_amd_trx_50, 195 family_amd_wrx_90, 196 family_intel_200_series, 197 family_intel_300_series, 198 family_intel_400_series, 199 family_intel_600_series, 200 family_intel_700_series 201 }; 202 203 /* 204 * All the known sensors for ASUS EC controllers. These arrays have to be sorted 205 * by the full ((bank << 8) + index) register index (see asus_ec_block_read() as 206 * to why). 207 */ 208 static const struct ec_sensor_info sensors_family_amd_400[] = { 209 [ec_sensor_temp_chipset] = 210 EC_SENSOR("Chipset", hwmon_temp, 1, 0x00, 0x3a), 211 [ec_sensor_temp_cpu] = 212 EC_SENSOR("CPU", hwmon_temp, 1, 0x00, 0x3b), 213 [ec_sensor_temp_mb] = 214 EC_SENSOR("Motherboard", hwmon_temp, 1, 0x00, 0x3c), 215 [ec_sensor_temp_t_sensor] = 216 EC_SENSOR("T_Sensor", hwmon_temp, 1, 0x00, 0x3d), 217 [ec_sensor_temp_vrm] = 218 EC_SENSOR("VRM", hwmon_temp, 1, 0x00, 0x3e), 219 [ec_sensor_in_cpu_core] = 220 EC_SENSOR("CPU Core", hwmon_in, 2, 0x00, 0xa2), 221 [ec_sensor_fan_vrm_hs] = 222 EC_SENSOR("VRM HS", hwmon_fan, 2, 0x00, 0xb2), 223 [ec_sensor_fan_cpu_opt] = 224 EC_SENSOR("CPU_Opt", hwmon_fan, 2, 0x00, 0xbc), 225 [ec_sensor_fan_chipset] = 226 /* no chipset fans in this generation */ 227 EC_SENSOR("Chipset", hwmon_fan, 0, 0x00, 0x00), 228 [ec_sensor_fan_water_flow] = 229 EC_SENSOR("Water_Flow", hwmon_fan, 2, 0x00, 0xb4), 230 [ec_sensor_curr_cpu] = 231 EC_SENSOR("CPU", hwmon_curr, 1, 0x00, 0xf4), 232 [ec_sensor_temp_water_out] = 233 EC_SENSOR("Water_Out", hwmon_temp, 1, 0x01, 0x0b), 234 [ec_sensor_temp_water_in] = 235 EC_SENSOR("Water_In", hwmon_temp, 1, 0x01, 0x0d), 236 }; 237 238 static const struct ec_sensor_info sensors_family_amd_500[] = { 239 [ec_sensor_temp_chipset] = 240 EC_SENSOR("Chipset", hwmon_temp, 1, 0x00, 0x3a), 241 [ec_sensor_temp_cpu] = EC_SENSOR("CPU", hwmon_temp, 1, 0x00, 0x3b), 242 [ec_sensor_temp_mb] = 243 EC_SENSOR("Motherboard", hwmon_temp, 1, 0x00, 0x3c), 244 [ec_sensor_temp_t_sensor] = 245 EC_SENSOR("T_Sensor", hwmon_temp, 1, 0x00, 0x3d), 246 [ec_sensor_temp_vrm] = EC_SENSOR("VRM", hwmon_temp, 1, 0x00, 0x3e), 247 [ec_sensor_in_cpu_core] = 248 EC_SENSOR("CPU Core", hwmon_in, 2, 0x00, 0xa2), 249 [ec_sensor_fan_cpu_opt] = 250 EC_SENSOR("CPU_Opt", hwmon_fan, 2, 0x00, 0xb0), 251 [ec_sensor_fan_vrm_hs] = EC_SENSOR("VRM HS", hwmon_fan, 2, 0x00, 0xb2), 252 [ec_sensor_fan_chipset] = 253 EC_SENSOR("Chipset", hwmon_fan, 2, 0x00, 0xb4), 254 [ec_sensor_fan_water_flow] = 255 EC_SENSOR("Water_Flow", hwmon_fan, 2, 0x00, 0xbc), 256 [ec_sensor_curr_cpu] = EC_SENSOR("CPU", hwmon_curr, 1, 0x00, 0xf4), 257 [ec_sensor_temp_water_in] = 258 EC_SENSOR("Water_In", hwmon_temp, 1, 0x01, 0x00), 259 [ec_sensor_temp_water_out] = 260 EC_SENSOR("Water_Out", hwmon_temp, 1, 0x01, 0x01), 261 [ec_sensor_temp_water_block_in] = 262 EC_SENSOR("Water_Block_In", hwmon_temp, 1, 0x01, 0x02), 263 [ec_sensor_temp_water_block_out] = 264 EC_SENSOR("Water_Block_Out", hwmon_temp, 1, 0x01, 0x03), 265 [ec_sensor_temp_sensor_extra_1] = 266 EC_SENSOR("Extra_1", hwmon_temp, 1, 0x01, 0x09), 267 [ec_sensor_temp_t_sensor_2] = 268 EC_SENSOR("T_sensor_2", hwmon_temp, 1, 0x01, 0x0a), 269 [ec_sensor_temp_sensor_extra_2] = 270 EC_SENSOR("Extra_2", hwmon_temp, 1, 0x01, 0x0b), 271 [ec_sensor_temp_sensor_extra_3] = 272 EC_SENSOR("Extra_3", hwmon_temp, 1, 0x01, 0x0c), 273 }; 274 275 static const struct ec_sensor_info sensors_family_amd_600[] = { 276 [ec_sensor_temp_cpu] = EC_SENSOR("CPU", hwmon_temp, 1, 0x00, 0x30), 277 [ec_sensor_temp_cpu_package] = 278 EC_SENSOR("CPU Package", hwmon_temp, 1, 0x00, 0x31), 279 [ec_sensor_temp_mb] = 280 EC_SENSOR("Motherboard", hwmon_temp, 1, 0x00, 0x32), 281 [ec_sensor_temp_vrm] = 282 EC_SENSOR("VRM", hwmon_temp, 1, 0x00, 0x33), 283 [ec_sensor_temp_t_sensor] = 284 EC_SENSOR("T_Sensor", hwmon_temp, 1, 0x00, 0x36), 285 [ec_sensor_temp_t_sensor_alt1] = 286 EC_SENSOR("T_Sensor", hwmon_temp, 1, 0x00, 0x37), 287 [ec_sensor_fan_cpu_opt] = 288 EC_SENSOR("CPU_Opt", hwmon_fan, 2, 0x00, 0xb0), 289 [ec_sensor_temp_water_in] = 290 EC_SENSOR("Water_In", hwmon_temp, 1, 0x01, 0x00), 291 [ec_sensor_temp_water_out] = 292 EC_SENSOR("Water_Out", hwmon_temp, 1, 0x01, 0x01), 293 }; 294 295 static const struct ec_sensor_info sensors_family_amd_800[] = { 296 [ec_sensor_temp_cpu] = EC_SENSOR("CPU", hwmon_temp, 1, 0x00, 0x30), 297 [ec_sensor_temp_cpu_package] = 298 EC_SENSOR("CPU Package", hwmon_temp, 1, 0x00, 0x31), 299 [ec_sensor_temp_mb] = 300 EC_SENSOR("Motherboard", hwmon_temp, 1, 0x00, 0x32), 301 [ec_sensor_temp_vrm] = 302 EC_SENSOR("VRM", hwmon_temp, 1, 0x00, 0x33), 303 [ec_sensor_temp_t_sensor] = 304 EC_SENSOR("T_Sensor", hwmon_temp, 1, 0x00, 0x36), 305 [ec_sensor_fan_cpu_opt] = 306 EC_SENSOR("CPU_Opt", hwmon_fan, 2, 0x00, 0xb0), 307 }; 308 309 static const struct ec_sensor_info sensors_family_amd_trx_50[] = { 310 [ec_sensor_temp_cpu] = EC_SENSOR("CPU", hwmon_temp, 1, 0x00, 0x30), 311 [ec_sensor_temp_cpu_package] = 312 EC_SENSOR("CPU Package", hwmon_temp, 1, 0x00, 0x31), 313 [ec_sensor_temp_vrme] = EC_SENSOR("VRM_E", hwmon_temp, 1, 0x00, 0x33), 314 [ec_sensor_temp_vrmw] = EC_SENSOR("VRM_W", hwmon_temp, 1, 0x00, 0x34), 315 [ec_sensor_fan_cpu_opt] = EC_SENSOR("CPU_Opt", hwmon_fan, 2, 0x00, 0xb0), 316 [ec_sensor_fan_vrmw_hs] = EC_SENSOR("VRM_E HS", hwmon_fan, 2, 0x00, 0xb4), 317 [ec_sensor_fan_vrme_hs] = EC_SENSOR("VRM_W HS", hwmon_fan, 2, 0x00, 0xbc), 318 [ec_sensor_temp_t_sensor] = 319 EC_SENSOR("T_Sensor", hwmon_temp, 1, 0x01, 0x04), 320 }; 321 322 static const struct ec_sensor_info sensors_family_amd_wrx_90[] = { 323 [ec_sensor_temp_cpu_package] = 324 EC_SENSOR("CPU Package", hwmon_temp, 1, 0x00, 0x31), 325 [ec_sensor_temp_vrme] = EC_SENSOR("VRM_E", hwmon_temp, 1, 0x00, 0x33), 326 [ec_sensor_temp_vrmw] = EC_SENSOR("VRM_W", hwmon_temp, 1, 0x00, 0x34), 327 [ec_sensor_fan_cpu_opt] = 328 EC_SENSOR("CPU_Opt", hwmon_fan, 2, 0x00, 0xb0), 329 [ec_sensor_fan_vrmw_hs] = 330 EC_SENSOR("VRMW HS", hwmon_fan, 2, 0x00, 0xb4), 331 [ec_sensor_fan_usb4] = EC_SENSOR("USB4", hwmon_fan, 2, 0x00, 0xb6), 332 [ec_sensor_fan_vrme_hs] = 333 EC_SENSOR("VRME HS", hwmon_fan, 2, 0x00, 0xbc), 334 [ec_sensor_fan_m2] = EC_SENSOR("M.2", hwmon_fan, 2, 0x00, 0xbe), 335 [ec_sensor_temp_t_sensor] = 336 EC_SENSOR("T_Sensor", hwmon_temp, 1, 0x01, 0x04), 337 }; 338 339 static const struct ec_sensor_info sensors_family_intel_200[] = { 340 [ec_sensor_temp_chipset] = 341 EC_SENSOR("Chipset", hwmon_temp, 1, 0x00, 0x3a), 342 [ec_sensor_temp_cpu] = EC_SENSOR("CPU", hwmon_temp, 1, 0x00, 0x3b), 343 [ec_sensor_temp_mb] = 344 EC_SENSOR("Motherboard", hwmon_temp, 1, 0x00, 0x3c), 345 [ec_sensor_temp_t_sensor] = 346 EC_SENSOR("T_Sensor", hwmon_temp, 1, 0x00, 0x3d), 347 [ec_sensor_fan_cpu_opt] = 348 EC_SENSOR("CPU_Opt", hwmon_fan, 2, 0x00, 0xbc), 349 }; 350 351 static const struct ec_sensor_info sensors_family_intel_300[] = { 352 [ec_sensor_temp_chipset] = 353 EC_SENSOR("Chipset", hwmon_temp, 1, 0x00, 0x3a), 354 [ec_sensor_temp_cpu] = EC_SENSOR("CPU", hwmon_temp, 1, 0x00, 0x3b), 355 [ec_sensor_temp_mb] = 356 EC_SENSOR("Motherboard", hwmon_temp, 1, 0x00, 0x3c), 357 [ec_sensor_temp_t_sensor] = 358 EC_SENSOR("T_Sensor", hwmon_temp, 1, 0x00, 0x3d), 359 [ec_sensor_temp_vrm] = EC_SENSOR("VRM", hwmon_temp, 1, 0x00, 0x3e), 360 [ec_sensor_fan_cpu_opt] = 361 EC_SENSOR("CPU_Opt", hwmon_fan, 2, 0x00, 0xb0), 362 [ec_sensor_fan_vrm_hs] = EC_SENSOR("VRM HS", hwmon_fan, 2, 0x00, 0xb2), 363 [ec_sensor_fan_water_flow] = 364 EC_SENSOR("Water_Flow", hwmon_fan, 2, 0x00, 0xbc), 365 [ec_sensor_temp_water_in] = 366 EC_SENSOR("Water_In", hwmon_temp, 1, 0x01, 0x00), 367 [ec_sensor_temp_water_out] = 368 EC_SENSOR("Water_Out", hwmon_temp, 1, 0x01, 0x01), 369 }; 370 371 static const struct ec_sensor_info sensors_family_intel_400[] = { 372 [ec_sensor_temp_chipset] = 373 EC_SENSOR("Chipset", hwmon_temp, 1, 0x00, 0x3a), 374 [ec_sensor_temp_cpu] = EC_SENSOR("CPU", hwmon_temp, 1, 0x00, 0x3b), 375 [ec_sensor_temp_mb] = 376 EC_SENSOR("Motherboard", hwmon_temp, 1, 0x00, 0x3c), 377 [ec_sensor_temp_t_sensor] = 378 EC_SENSOR("T_Sensor", hwmon_temp, 1, 0x00, 0x3d), 379 [ec_sensor_temp_vrm] = EC_SENSOR("VRM", hwmon_temp, 1, 0x00, 0x3e), 380 [ec_sensor_fan_cpu_opt] = 381 EC_SENSOR("CPU_Opt", hwmon_fan, 2, 0x00, 0xb0), 382 [ec_sensor_fan_vrm_hs] = EC_SENSOR("VRM HS", hwmon_fan, 2, 0x00, 0xb2), 383 }; 384 385 static const struct ec_sensor_info sensors_family_intel_600[] = { 386 [ec_sensor_temp_t_sensor] = 387 EC_SENSOR("T_Sensor", hwmon_temp, 1, 0x00, 0x3d), 388 [ec_sensor_temp_vrm] = EC_SENSOR("VRM", hwmon_temp, 1, 0x00, 0x3e), 389 [ec_sensor_fan_water_flow] = 390 EC_SENSOR("Water_Flow", hwmon_fan, 2, 0x00, 0xbe), 391 [ec_sensor_temp_water_in] = 392 EC_SENSOR("Water_In", hwmon_temp, 1, 0x01, 0x00), 393 [ec_sensor_temp_water_out] = 394 EC_SENSOR("Water_Out", hwmon_temp, 1, 0x01, 0x01), 395 [ec_sensor_temp_water_block_in] = 396 EC_SENSOR("Water_Block_In", hwmon_temp, 1, 0x01, 0x02), 397 }; 398 399 static const struct ec_sensor_info sensors_family_intel_700[] = { 400 [ec_sensor_temp_t_sensor] = 401 EC_SENSOR("T_Sensor", hwmon_temp, 1, 0x01, 0x09), 402 [ec_sensor_temp_t_sensor_2] = 403 EC_SENSOR("T_Sensor 2", hwmon_temp, 1, 0x01, 0x05), 404 [ec_sensor_temp_vrm] = EC_SENSOR("VRM", hwmon_temp, 1, 0x00, 0x33), 405 [ec_sensor_fan_cpu_opt] = 406 EC_SENSOR("CPU_Opt", hwmon_fan, 2, 0x00, 0xb0), 407 }; 408 409 /* Shortcuts for common combinations */ 410 #define SENSOR_SET_TEMP_CHIPSET_CPU_MB \ 411 (SENSOR_TEMP_CHIPSET | SENSOR_TEMP_CPU | SENSOR_TEMP_MB) 412 #define SENSOR_SET_TEMP_WATER (SENSOR_TEMP_WATER_IN | SENSOR_TEMP_WATER_OUT) 413 #define SENSOR_SET_WATER_BLOCK \ 414 (SENSOR_TEMP_WATER_BLOCK_IN | SENSOR_TEMP_WATER_BLOCK_OUT) 415 416 struct ec_board_info { 417 unsigned long sensors; 418 /* 419 * Defines which mutex to use for guarding access to the state and the 420 * hardware. Can be either a full path to an AML mutex or the 421 * pseudo-path ACPI_GLOBAL_LOCK_PSEUDO_PATH to use the global ACPI lock, 422 * or left empty to use a regular mutex object, in which case access to 423 * the hardware is not guarded. 424 */ 425 const char *mutex_path; 426 enum board_family family; 427 }; 428 429 static const struct ec_board_info board_info_crosshair_viii_dark_hero = { 430 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 431 SENSOR_TEMP_T_SENSOR | 432 SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER | 433 SENSOR_FAN_CPU_OPT | SENSOR_FAN_WATER_FLOW | 434 SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, 435 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 436 .family = family_amd_500_series, 437 }; 438 439 static const struct ec_board_info board_info_crosshair_viii_hero = { 440 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 441 SENSOR_TEMP_T_SENSOR | 442 SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER | 443 SENSOR_FAN_CPU_OPT | SENSOR_FAN_CHIPSET | 444 SENSOR_FAN_WATER_FLOW | SENSOR_CURR_CPU | 445 SENSOR_IN_CPU_CORE, 446 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 447 .family = family_amd_500_series, 448 }; 449 450 static const struct ec_board_info board_info_crosshair_viii_impact = { 451 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 452 SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | 453 SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU | 454 SENSOR_IN_CPU_CORE, 455 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 456 .family = family_amd_500_series, 457 }; 458 459 static const struct ec_board_info board_info_crosshair_x670e_extreme = { 460 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE | 461 SENSOR_TEMP_MB | SENSOR_TEMP_VRM | 462 SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_WATER_IN | 463 SENSOR_TEMP_WATER_OUT, 464 .mutex_path = ASUS_HW_ACCESS_MUTEX_SB_PCI0_SBRG_SIO1_MUT0, 465 .family = family_amd_600_series, 466 }; 467 468 static const struct ec_board_info board_info_crosshair_x670e_gene = { 469 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE | 470 SENSOR_TEMP_T_SENSOR | 471 SENSOR_TEMP_MB | SENSOR_TEMP_VRM, 472 .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH, 473 .family = family_amd_600_series, 474 }; 475 476 static const struct ec_board_info board_info_crosshair_x670e_hero = { 477 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE | 478 SENSOR_TEMP_MB | SENSOR_TEMP_VRM | 479 SENSOR_SET_TEMP_WATER, 480 .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH, 481 .family = family_amd_600_series, 482 }; 483 484 static const struct ec_board_info board_info_maximus_vi_hero = { 485 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 486 SENSOR_TEMP_T_SENSOR | 487 SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER | 488 SENSOR_FAN_CPU_OPT | SENSOR_FAN_WATER_FLOW, 489 .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH, 490 .family = family_intel_300_series, 491 }; 492 493 static const struct ec_board_info board_info_maximus_x_hero = { 494 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 495 SENSOR_TEMP_T_SENSOR | 496 SENSOR_TEMP_VRM | SENSOR_FAN_CPU_OPT, 497 .mutex_path = ASUS_HW_ACCESS_MUTEX_SB_PCI0_LPCB_SIO1_MUT0, 498 .family = family_intel_300_series, 499 }; 500 501 static const struct ec_board_info board_info_maximus_xi_hero = { 502 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 503 SENSOR_TEMP_T_SENSOR | 504 SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER | 505 SENSOR_FAN_CPU_OPT | SENSOR_FAN_WATER_FLOW, 506 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 507 .family = family_intel_300_series, 508 }; 509 510 static const struct ec_board_info board_info_maximus_z690_formula = { 511 .sensors = SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | 512 SENSOR_SET_TEMP_WATER | SENSOR_FAN_WATER_FLOW, 513 .mutex_path = ASUS_HW_ACCESS_MUTEX_RMTW_ASMX, 514 .family = family_intel_600_series, 515 }; 516 517 static const struct ec_board_info board_info_prime_x470_pro = { 518 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 519 SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | 520 SENSOR_FAN_CPU_OPT | 521 SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, 522 .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH, 523 .family = family_amd_400_series, 524 }; 525 526 static const struct ec_board_info board_info_prime_x570_pro = { 527 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM | 528 SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET, 529 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 530 .family = family_amd_500_series, 531 }; 532 533 static const struct ec_board_info board_info_prime_x670e_pro_wifi = { 534 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE | 535 SENSOR_TEMP_MB | SENSOR_TEMP_VRM | 536 SENSOR_TEMP_T_SENSOR_ALT1 | SENSOR_FAN_CPU_OPT, 537 .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH, 538 .family = family_amd_600_series, 539 }; 540 541 static const struct ec_board_info board_info_prime_z270_a = { 542 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 543 SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CPU_OPT, 544 .mutex_path = ASUS_HW_ACCESS_MUTEX_SB_PCI0_LPCB_SIO1_MUT0, 545 .family = family_intel_200_series, 546 }; 547 548 static const struct ec_board_info board_info_pro_art_b550_creator = { 549 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 550 SENSOR_TEMP_T_SENSOR | 551 SENSOR_FAN_CPU_OPT, 552 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 553 .family = family_amd_500_series, 554 }; 555 556 static const struct ec_board_info board_info_pro_art_x570_creator_wifi = { 557 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM | 558 SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CPU_OPT | 559 SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, 560 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 561 .family = family_amd_500_series, 562 }; 563 564 static const struct ec_board_info board_info_pro_art_x670E_creator_wifi = { 565 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE | 566 SENSOR_TEMP_MB | SENSOR_TEMP_VRM | 567 SENSOR_TEMP_T_SENSOR, 568 .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH, 569 .family = family_amd_600_series, 570 }; 571 572 static const struct ec_board_info board_info_pro_art_x870E_creator_wifi = { 573 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE | 574 SENSOR_TEMP_MB | SENSOR_TEMP_VRM | 575 SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CPU_OPT, 576 .mutex_path = ASUS_HW_ACCESS_MUTEX_SB_PCI0_SBRG_SIO1_MUT0, 577 .family = family_amd_800_series, 578 }; 579 580 static const struct ec_board_info board_info_pro_ws_trx50_sage_wifi = { 581 /* Board also has a nct6798 */ 582 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE | SENSOR_TEMP_VRME | 583 SENSOR_TEMP_VRMW | SENSOR_FAN_CPU_OPT | SENSOR_FAN_VRME_HS | 584 SENSOR_FAN_VRMW_HS | SENSOR_TEMP_T_SENSOR, 585 .mutex_path = ASUS_HW_ACCESS_MUTEX_RMTW_ASMX, 586 .family = family_amd_trx_50, 587 }; 588 589 static const struct ec_board_info board_info_pro_ws_wrx90e_sage_se = { 590 /* Board also has a nct6798 with 7 more fans and temperatures */ 591 .sensors = SENSOR_TEMP_CPU_PACKAGE | SENSOR_TEMP_T_SENSOR | 592 SENSOR_FAN_CPU_OPT | SENSOR_FAN_USB4 | SENSOR_FAN_M2 | 593 SENSOR_FAN_VRME_HS | SENSOR_FAN_VRMW_HS | 594 SENSOR_TEMP_VRME | SENSOR_TEMP_VRMW, 595 .mutex_path = ASUS_HW_ACCESS_MUTEX_RMTW_ASMX, 596 .family = family_amd_wrx_90, 597 }; 598 599 static const struct ec_board_info board_info_pro_ws_x570_ace = { 600 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM | 601 SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET | 602 SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, 603 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 604 .family = family_amd_500_series, 605 }; 606 607 static const struct ec_board_info board_info_strix_b550_e_gaming = { 608 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 609 SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | 610 SENSOR_FAN_CPU_OPT, 611 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 612 .family = family_amd_500_series, 613 }; 614 615 static const struct ec_board_info board_info_strix_b550_i_gaming = { 616 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 617 SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | 618 SENSOR_FAN_VRM_HS | SENSOR_CURR_CPU | 619 SENSOR_IN_CPU_CORE, 620 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 621 .family = family_amd_500_series, 622 }; 623 624 static const struct ec_board_info board_info_strix_b650e_i_gaming = { 625 .sensors = SENSOR_TEMP_VRM | SENSOR_TEMP_T_SENSOR | 626 SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_IN_CPU_CORE, 627 .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH, 628 .family = family_amd_600_series, 629 }; 630 631 static const struct ec_board_info board_info_strix_b850_i_gaming_wifi = { 632 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE | 633 SENSOR_TEMP_MB | SENSOR_TEMP_VRM, 634 .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH, 635 .family = family_amd_800_series, 636 }; 637 638 static const struct ec_board_info board_info_strix_x470_f_gaming = { 639 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 640 SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CPU_OPT | 641 SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, 642 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 643 .family = family_amd_400_series, 644 }; 645 646 static const struct ec_board_info board_info_strix_x470_i_gaming = { 647 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 648 SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | 649 SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, 650 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 651 .family = family_amd_400_series, 652 }; 653 654 static const struct ec_board_info board_info_strix_x570_e_gaming = { 655 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 656 SENSOR_TEMP_T_SENSOR | 657 SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU | 658 SENSOR_IN_CPU_CORE, 659 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 660 .family = family_amd_500_series, 661 }; 662 663 static const struct ec_board_info board_info_strix_x570_e_gaming_wifi_ii = { 664 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 665 SENSOR_TEMP_T_SENSOR | SENSOR_CURR_CPU | 666 SENSOR_IN_CPU_CORE, 667 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 668 .family = family_amd_500_series, 669 }; 670 671 static const struct ec_board_info board_info_strix_x570_f_gaming = { 672 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 673 SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET, 674 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 675 .family = family_amd_500_series, 676 }; 677 678 static const struct ec_board_info board_info_strix_x570_i_gaming = { 679 .sensors = SENSOR_TEMP_CHIPSET | SENSOR_TEMP_VRM | 680 SENSOR_TEMP_T_SENSOR | 681 SENSOR_FAN_VRM_HS | SENSOR_FAN_CHIPSET | 682 SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, 683 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 684 .family = family_amd_500_series, 685 }; 686 687 static const struct ec_board_info board_info_strix_x670e_e_gaming_wifi = { 688 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE | 689 SENSOR_TEMP_MB | SENSOR_TEMP_VRM, 690 .mutex_path = ASUS_HW_ACCESS_MUTEX_SB_PCI0_SBRG_SIO1_MUT0, 691 .family = family_amd_600_series, 692 }; 693 694 static const struct ec_board_info board_info_strix_x670e_i_gaming_wifi = { 695 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE | 696 SENSOR_TEMP_MB | SENSOR_TEMP_VRM, 697 .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH, 698 .family = family_amd_600_series, 699 }; 700 701 static const struct ec_board_info board_info_strix_x870_f_gaming_wifi = { 702 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE | 703 SENSOR_TEMP_MB | SENSOR_TEMP_VRM | SENSOR_TEMP_T_SENSOR, 704 .mutex_path = ASUS_HW_ACCESS_MUTEX_SB_PCI0_SBRG_SIO1_MUT0, 705 .family = family_amd_800_series, 706 }; 707 708 static const struct ec_board_info board_info_strix_x870_i_gaming_wifi = { 709 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE | 710 SENSOR_TEMP_MB | SENSOR_TEMP_VRM, 711 .mutex_path = ASUS_HW_ACCESS_MUTEX_SB_PCI0_SBRG_SIO1_MUT0, 712 .family = family_amd_800_series, 713 }; 714 715 static const struct ec_board_info board_info_strix_x870e_e_gaming_wifi = { 716 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE | 717 SENSOR_TEMP_MB | SENSOR_TEMP_VRM | 718 SENSOR_FAN_CPU_OPT, 719 .mutex_path = ASUS_HW_ACCESS_MUTEX_SB_PCI0_SBRG_SIO1_MUT0, 720 .family = family_amd_800_series, 721 }; 722 723 static const struct ec_board_info board_info_strix_x870e_h_gaming_wifi7 = { 724 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE | 725 SENSOR_TEMP_MB | SENSOR_TEMP_VRM | SENSOR_TEMP_T_SENSOR | 726 SENSOR_FAN_CPU_OPT, 727 .mutex_path = ASUS_HW_ACCESS_MUTEX_SB_PCI0_SBRG_SIO1_MUT0, 728 .family = family_amd_800_series, 729 }; 730 731 static const struct ec_board_info board_info_strix_z390_f_gaming = { 732 .sensors = SENSOR_TEMP_CHIPSET | SENSOR_TEMP_VRM | 733 SENSOR_TEMP_T_SENSOR | 734 SENSOR_FAN_CPU_OPT, 735 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 736 .family = family_intel_300_series, 737 }; 738 739 static const struct ec_board_info board_info_strix_z490_f_gaming = { 740 .sensors = SENSOR_TEMP_CHIPSET | 741 SENSOR_TEMP_CPU | 742 SENSOR_TEMP_MB | 743 SENSOR_TEMP_T_SENSOR | 744 SENSOR_TEMP_VRM | 745 SENSOR_FAN_CPU_OPT | 746 SENSOR_FAN_VRM_HS, 747 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 748 .family = family_intel_400_series, 749 }; 750 751 static const struct ec_board_info board_info_strix_z690_a_gaming_wifi_d4 = { 752 .sensors = SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM, 753 .mutex_path = ASUS_HW_ACCESS_MUTEX_RMTW_ASMX, 754 .family = family_intel_600_series, 755 }; 756 757 static const struct ec_board_info board_info_strix_z690_e_gaming_wifi = { 758 .sensors = SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM, 759 .mutex_path = ASUS_HW_ACCESS_MUTEX_RMTW_ASMX, 760 .family = family_intel_600_series, 761 }; 762 763 static const struct ec_board_info board_info_strix_z790_e_gaming_wifi_ii = { 764 .sensors = SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | 765 SENSOR_FAN_CPU_OPT, 766 .mutex_path = ASUS_HW_ACCESS_MUTEX_SB_PC00_LPCB_SIO1_MUT0, 767 .family = family_intel_700_series, 768 }; 769 770 static const struct ec_board_info board_info_strix_z790_h_gaming_wifi = { 771 .sensors = SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM, 772 .mutex_path = ASUS_HW_ACCESS_MUTEX_SB_PC00_LPCB_SIO1_MUT0, 773 .family = family_intel_700_series, 774 }; 775 776 static const struct ec_board_info board_info_strix_z790_i_gaming_wifi = { 777 .sensors = SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_T_SENSOR_2 | 778 SENSOR_TEMP_VRM, 779 .mutex_path = ASUS_HW_ACCESS_MUTEX_SB_PC00_LPCB_SIO1_MUT0, 780 .family = family_intel_700_series, 781 }; 782 783 static const struct ec_board_info board_info_tuf_gaming_x670e_plus = { 784 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE | 785 SENSOR_TEMP_MB | SENSOR_TEMP_VRM | 786 SENSOR_TEMP_WATER_IN | SENSOR_TEMP_WATER_OUT | 787 SENSOR_FAN_CPU_OPT, 788 .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH, 789 .family = family_amd_600_series, 790 }; 791 792 static const struct ec_board_info board_info_zenith_ii_extreme = { 793 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_T_SENSOR | 794 SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER | 795 SENSOR_FAN_CPU_OPT | SENSOR_FAN_CHIPSET | SENSOR_FAN_VRM_HS | 796 SENSOR_FAN_WATER_FLOW | SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE | 797 SENSOR_SET_WATER_BLOCK | 798 SENSOR_TEMP_T_SENSOR_2 | SENSOR_TEMP_SENSOR_EXTRA_1 | 799 SENSOR_TEMP_SENSOR_EXTRA_2 | SENSOR_TEMP_SENSOR_EXTRA_3, 800 .mutex_path = ASUS_HW_ACCESS_MUTEX_SB_PCI0_SBRG_SIO1_MUT0, 801 .family = family_amd_500_series, 802 }; 803 804 #define DMI_EXACT_MATCH_ASUS_BOARD_NAME(name, board_info) \ 805 { \ 806 .matches = { \ 807 DMI_EXACT_MATCH(DMI_BOARD_VENDOR, \ 808 "ASUSTeK COMPUTER INC."), \ 809 DMI_EXACT_MATCH(DMI_BOARD_NAME, name), \ 810 }, \ 811 .driver_data = (void *)board_info, \ 812 } 813 814 static const struct dmi_system_id dmi_table[] = { 815 DMI_EXACT_MATCH_ASUS_BOARD_NAME("MAXIMUS VI HERO", 816 &board_info_maximus_vi_hero), 817 DMI_EXACT_MATCH_ASUS_BOARD_NAME("PRIME X470-PRO", 818 &board_info_prime_x470_pro), 819 DMI_EXACT_MATCH_ASUS_BOARD_NAME("PRIME X570-PRO", 820 &board_info_prime_x570_pro), 821 DMI_EXACT_MATCH_ASUS_BOARD_NAME("PRIME X670E-PRO WIFI", 822 &board_info_prime_x670e_pro_wifi), 823 DMI_EXACT_MATCH_ASUS_BOARD_NAME("PRIME Z270-A", 824 &board_info_prime_z270_a), 825 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ProArt B550-CREATOR", 826 &board_info_pro_art_b550_creator), 827 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ProArt X570-CREATOR WIFI", 828 &board_info_pro_art_x570_creator_wifi), 829 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ProArt X670E-CREATOR WIFI", 830 &board_info_pro_art_x670E_creator_wifi), 831 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ProArt X870E-CREATOR WIFI", 832 &board_info_pro_art_x870E_creator_wifi), 833 DMI_EXACT_MATCH_ASUS_BOARD_NAME("Pro WS TRX50-SAGE WIFI", 834 &board_info_pro_ws_trx50_sage_wifi), 835 DMI_EXACT_MATCH_ASUS_BOARD_NAME("Pro WS TRX50-SAGE WIFI A", 836 &board_info_pro_ws_trx50_sage_wifi), 837 DMI_EXACT_MATCH_ASUS_BOARD_NAME("Pro WS WRX90E-SAGE SE", 838 &board_info_pro_ws_wrx90e_sage_se), 839 DMI_EXACT_MATCH_ASUS_BOARD_NAME("Pro WS X570-ACE", 840 &board_info_pro_ws_x570_ace), 841 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VIII DARK HERO", 842 &board_info_crosshair_viii_dark_hero), 843 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VIII FORMULA", 844 &board_info_crosshair_viii_hero), 845 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VIII HERO", 846 &board_info_crosshair_viii_hero), 847 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VIII HERO (WI-FI)", 848 &board_info_crosshair_viii_hero), 849 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VIII IMPACT", 850 &board_info_crosshair_viii_impact), 851 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR X670E EXTREME", 852 &board_info_crosshair_x670e_extreme), 853 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR X670E GENE", 854 &board_info_crosshair_x670e_gene), 855 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR X670E HERO", 856 &board_info_crosshair_x670e_hero), 857 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG MAXIMUS XI HERO", 858 &board_info_maximus_xi_hero), 859 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG MAXIMUS XI HERO (WI-FI)", 860 &board_info_maximus_xi_hero), 861 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG MAXIMUS X HERO", 862 &board_info_maximus_x_hero), 863 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG MAXIMUS Z690 FORMULA", 864 &board_info_maximus_z690_formula), 865 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX B550-E GAMING", 866 &board_info_strix_b550_e_gaming), 867 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX B550-I GAMING", 868 &board_info_strix_b550_i_gaming), 869 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX B650E-I GAMING WIFI", 870 &board_info_strix_b650e_i_gaming), 871 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX B850-I GAMING WIFI", 872 &board_info_strix_b850_i_gaming_wifi), 873 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X470-F GAMING", 874 &board_info_strix_x470_f_gaming), 875 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X470-I GAMING", 876 &board_info_strix_x470_i_gaming), 877 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X570-E GAMING", 878 &board_info_strix_x570_e_gaming), 879 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X570-E GAMING WIFI II", 880 &board_info_strix_x570_e_gaming_wifi_ii), 881 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X570-F GAMING", 882 &board_info_strix_x570_f_gaming), 883 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X570-I GAMING", 884 &board_info_strix_x570_i_gaming), 885 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X670E-E GAMING WIFI", 886 &board_info_strix_x670e_e_gaming_wifi), 887 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X670E-I GAMING WIFI", 888 &board_info_strix_x670e_i_gaming_wifi), 889 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X870-F GAMING WIFI", 890 &board_info_strix_x870_f_gaming_wifi), 891 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X870-I GAMING WIFI", 892 &board_info_strix_x870_i_gaming_wifi), 893 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X870E-E GAMING WIFI", 894 &board_info_strix_x870e_e_gaming_wifi), 895 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X870E-H GAMING WIFI7", 896 &board_info_strix_x870e_h_gaming_wifi7), 897 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX Z390-F GAMING", 898 &board_info_strix_z390_f_gaming), 899 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX Z490-F GAMING", 900 &board_info_strix_z490_f_gaming), 901 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX Z690-A GAMING WIFI D4", 902 &board_info_strix_z690_a_gaming_wifi_d4), 903 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX Z690-E GAMING WIFI", 904 &board_info_strix_z690_e_gaming_wifi), 905 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX Z790-E GAMING WIFI II", 906 &board_info_strix_z790_e_gaming_wifi_ii), 907 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX Z790-H GAMING WIFI", 908 &board_info_strix_z790_h_gaming_wifi), 909 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX Z790-I GAMING WIFI", 910 &board_info_strix_z790_i_gaming_wifi), 911 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG ZENITH II EXTREME", 912 &board_info_zenith_ii_extreme), 913 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG ZENITH II EXTREME ALPHA", 914 &board_info_zenith_ii_extreme), 915 DMI_EXACT_MATCH_ASUS_BOARD_NAME("TUF GAMING X670E-PLUS", 916 &board_info_tuf_gaming_x670e_plus), 917 DMI_EXACT_MATCH_ASUS_BOARD_NAME("TUF GAMING X670E-PLUS WIFI", 918 &board_info_tuf_gaming_x670e_plus), 919 {}, 920 }; 921 922 struct ec_sensor { 923 unsigned int info_index; 924 s32 cached_value; 925 }; 926 927 struct lock_data { 928 union { 929 acpi_handle aml; 930 /* global lock handle */ 931 u32 glk; 932 } mutex; 933 bool (*lock)(struct lock_data *data); 934 bool (*unlock)(struct lock_data *data); 935 }; 936 937 /* 938 * The next function pairs implement options for locking access to the 939 * state and the EC 940 */ 941 static bool lock_via_acpi_mutex(struct lock_data *data) 942 { 943 /* 944 * ASUS DSDT does not specify that access to the EC has to be guarded, 945 * but firmware does access it via ACPI 946 */ 947 return ACPI_SUCCESS(acpi_acquire_mutex(data->mutex.aml, 948 NULL, ACPI_LOCK_DELAY_MS)); 949 } 950 951 static bool unlock_acpi_mutex(struct lock_data *data) 952 { 953 return ACPI_SUCCESS(acpi_release_mutex(data->mutex.aml, NULL)); 954 } 955 956 static bool lock_via_global_acpi_lock(struct lock_data *data) 957 { 958 return ACPI_SUCCESS(acpi_acquire_global_lock(ACPI_LOCK_DELAY_MS, 959 &data->mutex.glk)); 960 } 961 962 static bool unlock_global_acpi_lock(struct lock_data *data) 963 { 964 return ACPI_SUCCESS(acpi_release_global_lock(data->mutex.glk)); 965 } 966 967 struct ec_sensors_data { 968 const struct ec_board_info *board_info; 969 const struct ec_sensor_info *sensors_info; 970 struct ec_sensor *sensors; 971 /* EC registers to read from */ 972 u16 *registers; 973 u8 *read_buffer; 974 /* sorted list of unique register banks */ 975 u8 banks[ASUS_EC_MAX_BANK + 1]; 976 /* in jiffies */ 977 unsigned long last_updated; 978 struct lock_data lock_data; 979 /* number of board EC sensors */ 980 u8 nr_sensors; 981 /* 982 * number of EC registers to read 983 * (sensor might span more than 1 register) 984 */ 985 u8 nr_registers; 986 /* number of unique register banks */ 987 u8 nr_banks; 988 }; 989 990 static u8 register_bank(u16 reg) 991 { 992 return reg >> 8; 993 } 994 995 static u8 register_index(u16 reg) 996 { 997 return reg & 0x00ff; 998 } 999 1000 static bool is_sensor_data_signed(const struct ec_sensor_info *si) 1001 { 1002 /* 1003 * guessed from WMI functions in DSDT code for boards 1004 * of the X470 generation 1005 */ 1006 return si->type == hwmon_temp; 1007 } 1008 1009 static const struct ec_sensor_info * 1010 get_sensor_info(const struct ec_sensors_data *state, int index) 1011 { 1012 return state->sensors_info + state->sensors[index].info_index; 1013 } 1014 1015 static int find_ec_sensor_index(const struct ec_sensors_data *ec, 1016 enum hwmon_sensor_types type, int channel) 1017 { 1018 unsigned int i; 1019 1020 for (i = 0; i < ec->nr_sensors; i++) { 1021 if (get_sensor_info(ec, i)->type == type) { 1022 if (channel == 0) 1023 return i; 1024 channel--; 1025 } 1026 } 1027 return -ENOENT; 1028 } 1029 1030 static int bank_compare(const void *a, const void *b) 1031 { 1032 return *((const s8 *)a) - *((const s8 *)b); 1033 } 1034 1035 static void setup_sensor_data(struct ec_sensors_data *ec) 1036 { 1037 struct ec_sensor *s = ec->sensors; 1038 bool bank_found; 1039 int i, j; 1040 u8 bank; 1041 1042 ec->nr_banks = 0; 1043 ec->nr_registers = 0; 1044 1045 for_each_set_bit(i, &ec->board_info->sensors, 1046 BITS_PER_TYPE(ec->board_info->sensors)) { 1047 s->info_index = i; 1048 s->cached_value = 0; 1049 ec->nr_registers += 1050 ec->sensors_info[s->info_index].addr.components.size; 1051 bank_found = false; 1052 bank = ec->sensors_info[s->info_index].addr.components.bank; 1053 for (j = 0; j < ec->nr_banks; j++) { 1054 if (ec->banks[j] == bank) { 1055 bank_found = true; 1056 break; 1057 } 1058 } 1059 if (!bank_found) { 1060 ec->banks[ec->nr_banks++] = bank; 1061 } 1062 s++; 1063 } 1064 sort(ec->banks, ec->nr_banks, 1, bank_compare, NULL); 1065 } 1066 1067 static void fill_ec_registers(struct ec_sensors_data *ec) 1068 { 1069 const struct ec_sensor_info *si; 1070 unsigned int i, j, register_idx = 0; 1071 1072 for (i = 0; i < ec->nr_sensors; ++i) { 1073 si = get_sensor_info(ec, i); 1074 for (j = 0; j < si->addr.components.size; ++j, ++register_idx) { 1075 ec->registers[register_idx] = 1076 (si->addr.components.bank << 8) + 1077 si->addr.components.index + j; 1078 } 1079 } 1080 } 1081 1082 static int setup_lock_data(struct device *dev) 1083 { 1084 const char *mutex_path; 1085 int status; 1086 struct ec_sensors_data *state = dev_get_drvdata(dev); 1087 1088 mutex_path = mutex_path_override ? 1089 mutex_path_override : state->board_info->mutex_path; 1090 1091 if (!mutex_path || !strlen(mutex_path)) { 1092 dev_err(dev, "Hardware access guard mutex name is empty"); 1093 return -EINVAL; 1094 } 1095 if (!strcmp(mutex_path, ACPI_GLOBAL_LOCK_PSEUDO_PATH)) { 1096 state->lock_data.mutex.glk = 0; 1097 state->lock_data.lock = lock_via_global_acpi_lock; 1098 state->lock_data.unlock = unlock_global_acpi_lock; 1099 } else { 1100 status = acpi_get_handle(NULL, (acpi_string)mutex_path, 1101 &state->lock_data.mutex.aml); 1102 if (ACPI_FAILURE(status)) { 1103 dev_err(dev, 1104 "Failed to get hardware access guard AML mutex '%s': error %d", 1105 mutex_path, status); 1106 return -ENOENT; 1107 } 1108 state->lock_data.lock = lock_via_acpi_mutex; 1109 state->lock_data.unlock = unlock_acpi_mutex; 1110 } 1111 return 0; 1112 } 1113 1114 static int asus_ec_bank_switch(u8 bank, u8 *old) 1115 { 1116 int status = 0; 1117 1118 if (old) { 1119 status = ec_read(ASUS_EC_BANK_REGISTER, old); 1120 } 1121 if (status || (old && (*old == bank))) 1122 return status; 1123 return ec_write(ASUS_EC_BANK_REGISTER, bank); 1124 } 1125 1126 static int asus_ec_block_read(const struct device *dev, 1127 struct ec_sensors_data *ec) 1128 { 1129 int ireg, ibank, status; 1130 u8 bank, reg_bank, prev_bank; 1131 1132 bank = 0; 1133 status = asus_ec_bank_switch(bank, &prev_bank); 1134 if (status) { 1135 dev_warn(dev, "EC bank switch failed"); 1136 return status; 1137 } 1138 1139 if (prev_bank) { 1140 /* oops... somebody else is working with the EC too */ 1141 dev_warn(dev, 1142 "Concurrent access to the ACPI EC detected.\nRace condition possible."); 1143 } 1144 1145 /* read registers minimizing bank switches. */ 1146 for (ibank = 0; ibank < ec->nr_banks; ibank++) { 1147 if (bank != ec->banks[ibank]) { 1148 bank = ec->banks[ibank]; 1149 if (asus_ec_bank_switch(bank, NULL)) { 1150 dev_warn(dev, "EC bank switch to %d failed", 1151 bank); 1152 break; 1153 } 1154 } 1155 for (ireg = 0; ireg < ec->nr_registers; ireg++) { 1156 reg_bank = register_bank(ec->registers[ireg]); 1157 if (reg_bank < bank) { 1158 continue; 1159 } 1160 ec_read(register_index(ec->registers[ireg]), 1161 ec->read_buffer + ireg); 1162 } 1163 } 1164 1165 status = asus_ec_bank_switch(prev_bank, NULL); 1166 return status; 1167 } 1168 1169 static inline s32 get_sensor_value(const struct ec_sensor_info *si, u8 *data) 1170 { 1171 if (is_sensor_data_signed(si)) { 1172 switch (si->addr.components.size) { 1173 case 1: 1174 return (s8)*data; 1175 case 2: 1176 return (s16)get_unaligned_be16(data); 1177 case 4: 1178 return (s32)get_unaligned_be32(data); 1179 default: 1180 return 0; 1181 } 1182 } else { 1183 switch (si->addr.components.size) { 1184 case 1: 1185 return *data; 1186 case 2: 1187 return get_unaligned_be16(data); 1188 case 4: 1189 return get_unaligned_be32(data); 1190 default: 1191 return 0; 1192 } 1193 } 1194 } 1195 1196 static void update_sensor_values(struct ec_sensors_data *ec, u8 *data) 1197 { 1198 const struct ec_sensor_info *si; 1199 struct ec_sensor *s, *sensor_end; 1200 1201 sensor_end = ec->sensors + ec->nr_sensors; 1202 for (s = ec->sensors; s != sensor_end; s++) { 1203 si = ec->sensors_info + s->info_index; 1204 s->cached_value = get_sensor_value(si, data); 1205 data += si->addr.components.size; 1206 } 1207 } 1208 1209 static int update_ec_sensors(const struct device *dev, 1210 struct ec_sensors_data *ec) 1211 { 1212 int status; 1213 1214 if (!ec->lock_data.lock(&ec->lock_data)) { 1215 dev_warn(dev, "Failed to acquire mutex"); 1216 return -EBUSY; 1217 } 1218 1219 status = asus_ec_block_read(dev, ec); 1220 1221 if (!status) { 1222 update_sensor_values(ec, ec->read_buffer); 1223 } 1224 1225 if (!ec->lock_data.unlock(&ec->lock_data)) 1226 dev_err(dev, "Failed to release mutex"); 1227 1228 return status; 1229 } 1230 1231 static long scale_sensor_value(s32 value, int data_type) 1232 { 1233 switch (data_type) { 1234 case hwmon_curr: 1235 case hwmon_temp: 1236 return value * MILLI; 1237 default: 1238 return value; 1239 } 1240 } 1241 1242 static int get_cached_value_or_update(const struct device *dev, 1243 int sensor_index, 1244 struct ec_sensors_data *state, s32 *value) 1245 { 1246 if (time_after(jiffies, state->last_updated + HZ)) { 1247 if (update_ec_sensors(dev, state)) { 1248 dev_err(dev, "update_ec_sensors() failure\n"); 1249 return -EIO; 1250 } 1251 1252 state->last_updated = jiffies; 1253 } 1254 1255 *value = state->sensors[sensor_index].cached_value; 1256 return 0; 1257 } 1258 1259 /* 1260 * Now follow the functions that implement the hwmon interface 1261 */ 1262 1263 static int asus_ec_hwmon_read(struct device *dev, enum hwmon_sensor_types type, 1264 u32 attr, int channel, long *val) 1265 { 1266 int ret; 1267 s32 value = 0; 1268 1269 struct ec_sensors_data *state = dev_get_drvdata(dev); 1270 int sidx = find_ec_sensor_index(state, type, channel); 1271 1272 if (sidx < 0) { 1273 return sidx; 1274 } 1275 1276 ret = get_cached_value_or_update(dev, sidx, state, &value); 1277 if (!ret) { 1278 *val = scale_sensor_value(value, 1279 get_sensor_info(state, sidx)->type); 1280 } 1281 1282 return ret; 1283 } 1284 1285 static int asus_ec_hwmon_read_string(struct device *dev, 1286 enum hwmon_sensor_types type, u32 attr, 1287 int channel, const char **str) 1288 { 1289 struct ec_sensors_data *state = dev_get_drvdata(dev); 1290 int sensor_index = find_ec_sensor_index(state, type, channel); 1291 1292 if (sensor_index < 0) 1293 return sensor_index; 1294 1295 *str = get_sensor_info(state, sensor_index)->label; 1296 1297 return 0; 1298 } 1299 1300 static umode_t asus_ec_hwmon_is_visible(const void *drvdata, 1301 enum hwmon_sensor_types type, u32 attr, 1302 int channel) 1303 { 1304 const struct ec_sensors_data *state = drvdata; 1305 1306 return find_ec_sensor_index(state, type, channel) >= 0 ? S_IRUGO : 0; 1307 } 1308 1309 static int 1310 asus_ec_hwmon_add_chan_info(struct hwmon_channel_info *asus_ec_hwmon_chan, 1311 struct device *dev, int num, 1312 enum hwmon_sensor_types type, u32 config) 1313 { 1314 int i; 1315 u32 *cfg = devm_kcalloc(dev, num + 1, sizeof(*cfg), GFP_KERNEL); 1316 1317 if (!cfg) 1318 return -ENOMEM; 1319 1320 asus_ec_hwmon_chan->type = type; 1321 asus_ec_hwmon_chan->config = cfg; 1322 for (i = 0; i < num; i++, cfg++) 1323 *cfg = config; 1324 1325 return 0; 1326 } 1327 1328 static const struct hwmon_ops asus_ec_hwmon_ops = { 1329 .is_visible = asus_ec_hwmon_is_visible, 1330 .read = asus_ec_hwmon_read, 1331 .read_string = asus_ec_hwmon_read_string, 1332 }; 1333 1334 static struct hwmon_chip_info asus_ec_chip_info = { 1335 .ops = &asus_ec_hwmon_ops, 1336 }; 1337 1338 static const struct ec_board_info *get_board_info(void) 1339 { 1340 const struct dmi_system_id *dmi_entry; 1341 1342 dmi_entry = dmi_first_match(dmi_table); 1343 return dmi_entry ? dmi_entry->driver_data : NULL; 1344 } 1345 1346 static int asus_ec_probe(struct platform_device *pdev) 1347 { 1348 const struct hwmon_channel_info **ptr_asus_ec_ci; 1349 int nr_count[hwmon_max] = { 0 }, nr_types = 0; 1350 struct hwmon_channel_info *asus_ec_hwmon_chan; 1351 const struct ec_board_info *pboard_info; 1352 const struct hwmon_chip_info *chip_info; 1353 struct device *dev = &pdev->dev; 1354 struct ec_sensors_data *ec_data; 1355 const struct ec_sensor_info *si; 1356 enum hwmon_sensor_types type; 1357 struct device *hwdev; 1358 unsigned int i; 1359 int status; 1360 1361 pboard_info = get_board_info(); 1362 if (!pboard_info) 1363 return -ENODEV; 1364 1365 ec_data = devm_kzalloc(dev, sizeof(struct ec_sensors_data), 1366 GFP_KERNEL); 1367 if (!ec_data) 1368 return -ENOMEM; 1369 1370 dev_set_drvdata(dev, ec_data); 1371 ec_data->board_info = pboard_info; 1372 1373 switch (ec_data->board_info->family) { 1374 case family_amd_400_series: 1375 ec_data->sensors_info = sensors_family_amd_400; 1376 break; 1377 case family_amd_500_series: 1378 ec_data->sensors_info = sensors_family_amd_500; 1379 break; 1380 case family_amd_600_series: 1381 ec_data->sensors_info = sensors_family_amd_600; 1382 break; 1383 case family_amd_800_series: 1384 ec_data->sensors_info = sensors_family_amd_800; 1385 break; 1386 case family_amd_trx_50: 1387 ec_data->sensors_info = sensors_family_amd_trx_50; 1388 break; 1389 case family_amd_wrx_90: 1390 ec_data->sensors_info = sensors_family_amd_wrx_90; 1391 break; 1392 case family_intel_200_series: 1393 ec_data->sensors_info = sensors_family_intel_200; 1394 break; 1395 case family_intel_300_series: 1396 ec_data->sensors_info = sensors_family_intel_300; 1397 break; 1398 case family_intel_400_series: 1399 ec_data->sensors_info = sensors_family_intel_400; 1400 break; 1401 case family_intel_600_series: 1402 ec_data->sensors_info = sensors_family_intel_600; 1403 break; 1404 case family_intel_700_series: 1405 ec_data->sensors_info = sensors_family_intel_700; 1406 break; 1407 default: 1408 dev_err(dev, "Unknown board family: %d", 1409 ec_data->board_info->family); 1410 return -EINVAL; 1411 } 1412 1413 ec_data->nr_sensors = hweight_long(ec_data->board_info->sensors); 1414 ec_data->sensors = devm_kcalloc(dev, ec_data->nr_sensors, 1415 sizeof(struct ec_sensor), GFP_KERNEL); 1416 if (!ec_data->sensors) 1417 return -ENOMEM; 1418 1419 status = setup_lock_data(dev); 1420 if (status) { 1421 dev_err(dev, "Failed to setup state/EC locking: %d", status); 1422 return status; 1423 } 1424 1425 setup_sensor_data(ec_data); 1426 ec_data->registers = devm_kcalloc(dev, ec_data->nr_registers, 1427 sizeof(u16), GFP_KERNEL); 1428 ec_data->read_buffer = devm_kcalloc(dev, ec_data->nr_registers, 1429 sizeof(u8), GFP_KERNEL); 1430 1431 if (!ec_data->registers || !ec_data->read_buffer) 1432 return -ENOMEM; 1433 1434 fill_ec_registers(ec_data); 1435 1436 for (i = 0; i < ec_data->nr_sensors; ++i) { 1437 si = get_sensor_info(ec_data, i); 1438 if (!nr_count[si->type]) 1439 ++nr_types; 1440 ++nr_count[si->type]; 1441 } 1442 1443 if (nr_count[hwmon_temp]) 1444 nr_count[hwmon_chip]++, nr_types++; 1445 1446 asus_ec_hwmon_chan = devm_kcalloc( 1447 dev, nr_types, sizeof(*asus_ec_hwmon_chan), GFP_KERNEL); 1448 if (!asus_ec_hwmon_chan) 1449 return -ENOMEM; 1450 1451 ptr_asus_ec_ci = devm_kcalloc(dev, nr_types + 1, 1452 sizeof(*ptr_asus_ec_ci), GFP_KERNEL); 1453 if (!ptr_asus_ec_ci) 1454 return -ENOMEM; 1455 1456 asus_ec_chip_info.info = ptr_asus_ec_ci; 1457 chip_info = &asus_ec_chip_info; 1458 1459 for (type = 0; type < hwmon_max; ++type) { 1460 if (!nr_count[type]) 1461 continue; 1462 1463 asus_ec_hwmon_add_chan_info(asus_ec_hwmon_chan, dev, 1464 nr_count[type], type, 1465 hwmon_attributes[type]); 1466 *ptr_asus_ec_ci++ = asus_ec_hwmon_chan++; 1467 } 1468 1469 dev_info(dev, "board has %d EC sensors that span %d registers", 1470 ec_data->nr_sensors, ec_data->nr_registers); 1471 1472 hwdev = devm_hwmon_device_register_with_info(dev, "asusec", 1473 ec_data, chip_info, NULL); 1474 1475 return PTR_ERR_OR_ZERO(hwdev); 1476 } 1477 1478 MODULE_DEVICE_TABLE(dmi, dmi_table); 1479 1480 static struct platform_driver asus_ec_sensors_platform_driver = { 1481 .driver = { 1482 .name = "asus-ec-sensors", 1483 }, 1484 .probe = asus_ec_probe, 1485 }; 1486 1487 static struct platform_device *asus_ec_sensors_platform_device; 1488 1489 static int __init asus_ec_init(void) 1490 { 1491 asus_ec_sensors_platform_device = 1492 platform_create_bundle(&asus_ec_sensors_platform_driver, 1493 asus_ec_probe, NULL, 0, NULL, 0); 1494 1495 if (IS_ERR(asus_ec_sensors_platform_device)) 1496 return PTR_ERR(asus_ec_sensors_platform_device); 1497 1498 return 0; 1499 } 1500 1501 static void __exit asus_ec_exit(void) 1502 { 1503 platform_device_unregister(asus_ec_sensors_platform_device); 1504 platform_driver_unregister(&asus_ec_sensors_platform_driver); 1505 } 1506 1507 module_init(asus_ec_init); 1508 module_exit(asus_ec_exit); 1509 1510 module_param_named(mutex_path, mutex_path_override, charp, 0); 1511 MODULE_PARM_DESC(mutex_path, 1512 "Override ACPI mutex path used to guard access to hardware"); 1513 1514 MODULE_AUTHOR("Eugene Shalygin <eugene.shalygin@gmail.com>"); 1515 MODULE_DESCRIPTION( 1516 "HWMON driver for sensors accessible via ACPI EC in ASUS motherboards"); 1517 MODULE_LICENSE("GPL"); 1518