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 [ec_sensor_fan_water_flow] = 408 EC_SENSOR("Water_Flow", hwmon_fan, 2, 0x00, 0xbc), 409 [ec_sensor_temp_water_in] = 410 EC_SENSOR("Water_In", hwmon_temp, 1, 0x01, 0x00), 411 [ec_sensor_temp_water_out] = 412 EC_SENSOR("Water_Out", hwmon_temp, 1, 0x01, 0x01), 413 }; 414 415 /* Shortcuts for common combinations */ 416 #define SENSOR_SET_TEMP_CHIPSET_CPU_MB \ 417 (SENSOR_TEMP_CHIPSET | SENSOR_TEMP_CPU | SENSOR_TEMP_MB) 418 #define SENSOR_SET_TEMP_WATER (SENSOR_TEMP_WATER_IN | SENSOR_TEMP_WATER_OUT) 419 #define SENSOR_SET_WATER_BLOCK \ 420 (SENSOR_TEMP_WATER_BLOCK_IN | SENSOR_TEMP_WATER_BLOCK_OUT) 421 422 struct ec_board_info { 423 unsigned long sensors; 424 /* 425 * Defines which mutex to use for guarding access to the state and the 426 * hardware. Can be either a full path to an AML mutex or the 427 * pseudo-path ACPI_GLOBAL_LOCK_PSEUDO_PATH to use the global ACPI lock, 428 * or left empty to use a regular mutex object, in which case access to 429 * the hardware is not guarded. 430 */ 431 const char *mutex_path; 432 enum board_family family; 433 }; 434 435 static const struct ec_board_info board_info_crosshair_viii_dark_hero = { 436 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 437 SENSOR_TEMP_T_SENSOR | 438 SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER | 439 SENSOR_FAN_CPU_OPT | SENSOR_FAN_WATER_FLOW | 440 SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, 441 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 442 .family = family_amd_500_series, 443 }; 444 445 static const struct ec_board_info board_info_crosshair_viii_hero = { 446 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 447 SENSOR_TEMP_T_SENSOR | 448 SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER | 449 SENSOR_FAN_CPU_OPT | SENSOR_FAN_CHIPSET | 450 SENSOR_FAN_WATER_FLOW | SENSOR_CURR_CPU | 451 SENSOR_IN_CPU_CORE, 452 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 453 .family = family_amd_500_series, 454 }; 455 456 static const struct ec_board_info board_info_crosshair_viii_impact = { 457 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 458 SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | 459 SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU | 460 SENSOR_IN_CPU_CORE, 461 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 462 .family = family_amd_500_series, 463 }; 464 465 static const struct ec_board_info board_info_crosshair_x670e_extreme = { 466 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE | 467 SENSOR_TEMP_MB | SENSOR_TEMP_VRM | 468 SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_WATER_IN | 469 SENSOR_TEMP_WATER_OUT, 470 .mutex_path = ASUS_HW_ACCESS_MUTEX_SB_PCI0_SBRG_SIO1_MUT0, 471 .family = family_amd_600_series, 472 }; 473 474 static const struct ec_board_info board_info_crosshair_x670e_gene = { 475 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE | 476 SENSOR_TEMP_T_SENSOR | 477 SENSOR_TEMP_MB | SENSOR_TEMP_VRM, 478 .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH, 479 .family = family_amd_600_series, 480 }; 481 482 static const struct ec_board_info board_info_crosshair_x670e_hero = { 483 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE | 484 SENSOR_TEMP_MB | SENSOR_TEMP_VRM | 485 SENSOR_SET_TEMP_WATER, 486 .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH, 487 .family = family_amd_600_series, 488 }; 489 490 static const struct ec_board_info board_info_maximus_vi_hero = { 491 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 492 SENSOR_TEMP_T_SENSOR | 493 SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER | 494 SENSOR_FAN_CPU_OPT | SENSOR_FAN_WATER_FLOW, 495 .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH, 496 .family = family_intel_300_series, 497 }; 498 499 static const struct ec_board_info board_info_maximus_x_hero = { 500 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 501 SENSOR_TEMP_T_SENSOR | 502 SENSOR_TEMP_VRM | SENSOR_FAN_CPU_OPT, 503 .mutex_path = ASUS_HW_ACCESS_MUTEX_SB_PCI0_LPCB_SIO1_MUT0, 504 .family = family_intel_300_series, 505 }; 506 507 static const struct ec_board_info board_info_maximus_xi_hero = { 508 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 509 SENSOR_TEMP_T_SENSOR | 510 SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER | 511 SENSOR_FAN_CPU_OPT | SENSOR_FAN_WATER_FLOW, 512 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 513 .family = family_intel_300_series, 514 }; 515 516 static const struct ec_board_info board_info_maximus_z690_formula = { 517 .sensors = SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | 518 SENSOR_SET_TEMP_WATER | SENSOR_FAN_WATER_FLOW, 519 .mutex_path = ASUS_HW_ACCESS_MUTEX_RMTW_ASMX, 520 .family = family_intel_600_series, 521 }; 522 523 static const struct ec_board_info board_info_maximus_z790_extreme = { 524 .sensors = SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | 525 SENSOR_SET_TEMP_WATER | SENSOR_FAN_WATER_FLOW, 526 .mutex_path = ASUS_HW_ACCESS_MUTEX_RMTW_ASMX, 527 .family = family_intel_700_series, 528 }; 529 530 static const struct ec_board_info board_info_prime_x470_pro = { 531 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 532 SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | 533 SENSOR_FAN_CPU_OPT | 534 SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, 535 .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH, 536 .family = family_amd_400_series, 537 }; 538 539 static const struct ec_board_info board_info_prime_x570_pro = { 540 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM | 541 SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET, 542 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 543 .family = family_amd_500_series, 544 }; 545 546 static const struct ec_board_info board_info_prime_x670e_pro_wifi = { 547 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE | 548 SENSOR_TEMP_MB | SENSOR_TEMP_VRM | 549 SENSOR_TEMP_T_SENSOR_ALT1 | SENSOR_FAN_CPU_OPT, 550 .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH, 551 .family = family_amd_600_series, 552 }; 553 554 static const struct ec_board_info board_info_prime_z270_a = { 555 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 556 SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CPU_OPT, 557 .mutex_path = ASUS_HW_ACCESS_MUTEX_SB_PCI0_LPCB_SIO1_MUT0, 558 .family = family_intel_200_series, 559 }; 560 561 static const struct ec_board_info board_info_pro_art_b550_creator = { 562 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 563 SENSOR_TEMP_T_SENSOR | 564 SENSOR_FAN_CPU_OPT, 565 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 566 .family = family_amd_500_series, 567 }; 568 569 static const struct ec_board_info board_info_pro_art_x570_creator_wifi = { 570 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM | 571 SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CPU_OPT | 572 SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, 573 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 574 .family = family_amd_500_series, 575 }; 576 577 static const struct ec_board_info board_info_pro_art_x670E_creator_wifi = { 578 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE | 579 SENSOR_TEMP_MB | SENSOR_TEMP_VRM | 580 SENSOR_TEMP_T_SENSOR, 581 .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH, 582 .family = family_amd_600_series, 583 }; 584 585 static const struct ec_board_info board_info_pro_art_x870E_creator_wifi = { 586 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE | 587 SENSOR_TEMP_MB | SENSOR_TEMP_VRM | 588 SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CPU_OPT, 589 .mutex_path = ASUS_HW_ACCESS_MUTEX_SB_PCI0_SBRG_SIO1_MUT0, 590 .family = family_amd_800_series, 591 }; 592 593 static const struct ec_board_info board_info_pro_ws_trx50_sage_wifi = { 594 /* Board also has a nct6798 */ 595 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE | SENSOR_TEMP_VRME | 596 SENSOR_TEMP_VRMW | SENSOR_FAN_CPU_OPT | SENSOR_FAN_VRME_HS | 597 SENSOR_FAN_VRMW_HS | SENSOR_TEMP_T_SENSOR, 598 .mutex_path = ASUS_HW_ACCESS_MUTEX_RMTW_ASMX, 599 .family = family_amd_trx_50, 600 }; 601 602 static const struct ec_board_info board_info_pro_ws_wrx90e_sage_se = { 603 /* Board also has a nct6798 with 7 more fans and temperatures */ 604 .sensors = SENSOR_TEMP_CPU_PACKAGE | SENSOR_TEMP_T_SENSOR | 605 SENSOR_FAN_CPU_OPT | SENSOR_FAN_USB4 | SENSOR_FAN_M2 | 606 SENSOR_FAN_VRME_HS | SENSOR_FAN_VRMW_HS | 607 SENSOR_TEMP_VRME | SENSOR_TEMP_VRMW, 608 .mutex_path = ASUS_HW_ACCESS_MUTEX_RMTW_ASMX, 609 .family = family_amd_wrx_90, 610 }; 611 612 static const struct ec_board_info board_info_pro_ws_x570_ace = { 613 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM | 614 SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET | 615 SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, 616 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 617 .family = family_amd_500_series, 618 }; 619 620 static const struct ec_board_info board_info_strix_b550_e_gaming = { 621 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 622 SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | 623 SENSOR_FAN_CPU_OPT, 624 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 625 .family = family_amd_500_series, 626 }; 627 628 static const struct ec_board_info board_info_strix_b550_i_gaming = { 629 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 630 SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | 631 SENSOR_FAN_VRM_HS | SENSOR_CURR_CPU | 632 SENSOR_IN_CPU_CORE, 633 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 634 .family = family_amd_500_series, 635 }; 636 637 static const struct ec_board_info board_info_strix_b650e_e_gaming = { 638 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE | 639 SENSOR_TEMP_MB | SENSOR_TEMP_VRM | 640 SENSOR_FAN_CPU_OPT, 641 .mutex_path = ASUS_HW_ACCESS_MUTEX_SB_PCI0_SBRG_SIO1_MUT0, 642 .family = family_amd_600_series, 643 }; 644 645 static const struct ec_board_info board_info_strix_b650e_i_gaming = { 646 .sensors = SENSOR_TEMP_VRM | SENSOR_TEMP_T_SENSOR | 647 SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_IN_CPU_CORE, 648 .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH, 649 .family = family_amd_600_series, 650 }; 651 652 static const struct ec_board_info board_info_strix_b850_e_gaming_wifi = { 653 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE | 654 SENSOR_TEMP_MB | SENSOR_TEMP_VRM | 655 SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CPU_OPT, 656 .mutex_path = ASUS_HW_ACCESS_MUTEX_SB_PCI0_SBRG_SIO1_MUT0, 657 .family = family_amd_800_series, 658 }; 659 660 static const struct ec_board_info board_info_strix_b850_i_gaming_wifi = { 661 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE | 662 SENSOR_TEMP_MB | SENSOR_TEMP_VRM, 663 .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH, 664 .family = family_amd_800_series, 665 }; 666 667 static const struct ec_board_info board_info_strix_x470_f_gaming = { 668 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 669 SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CPU_OPT | 670 SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, 671 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 672 .family = family_amd_400_series, 673 }; 674 675 static const struct ec_board_info board_info_strix_x470_i_gaming = { 676 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 677 SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | 678 SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, 679 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 680 .family = family_amd_400_series, 681 }; 682 683 static const struct ec_board_info board_info_strix_x570_e_gaming = { 684 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 685 SENSOR_TEMP_T_SENSOR | 686 SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU | 687 SENSOR_IN_CPU_CORE, 688 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 689 .family = family_amd_500_series, 690 }; 691 692 static const struct ec_board_info board_info_strix_x570_e_gaming_wifi_ii = { 693 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 694 SENSOR_TEMP_T_SENSOR | SENSOR_CURR_CPU | 695 SENSOR_IN_CPU_CORE, 696 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 697 .family = family_amd_500_series, 698 }; 699 700 static const struct ec_board_info board_info_strix_x570_f_gaming = { 701 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 702 SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET, 703 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 704 .family = family_amd_500_series, 705 }; 706 707 static const struct ec_board_info board_info_strix_x570_i_gaming = { 708 .sensors = SENSOR_TEMP_CHIPSET | SENSOR_TEMP_VRM | 709 SENSOR_TEMP_T_SENSOR | 710 SENSOR_FAN_VRM_HS | SENSOR_FAN_CHIPSET | 711 SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, 712 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 713 .family = family_amd_500_series, 714 }; 715 716 static const struct ec_board_info board_info_strix_x670e_e_gaming_wifi = { 717 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE | 718 SENSOR_TEMP_MB | SENSOR_TEMP_VRM, 719 .mutex_path = ASUS_HW_ACCESS_MUTEX_SB_PCI0_SBRG_SIO1_MUT0, 720 .family = family_amd_600_series, 721 }; 722 723 static const struct ec_board_info board_info_strix_x670e_i_gaming_wifi = { 724 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE | 725 SENSOR_TEMP_MB | SENSOR_TEMP_VRM, 726 .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH, 727 .family = family_amd_600_series, 728 }; 729 730 static const struct ec_board_info board_info_strix_x870_f_gaming_wifi = { 731 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE | 732 SENSOR_TEMP_MB | SENSOR_TEMP_VRM | SENSOR_TEMP_T_SENSOR, 733 .mutex_path = ASUS_HW_ACCESS_MUTEX_SB_PCI0_SBRG_SIO1_MUT0, 734 .family = family_amd_800_series, 735 }; 736 737 static const struct ec_board_info board_info_strix_x870_i_gaming_wifi = { 738 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE | 739 SENSOR_TEMP_MB | SENSOR_TEMP_VRM, 740 .mutex_path = ASUS_HW_ACCESS_MUTEX_SB_PCI0_SBRG_SIO1_MUT0, 741 .family = family_amd_800_series, 742 }; 743 744 static const struct ec_board_info board_info_strix_x870e_e_gaming_wifi = { 745 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE | 746 SENSOR_TEMP_MB | SENSOR_TEMP_VRM | 747 SENSOR_FAN_CPU_OPT, 748 .mutex_path = ASUS_HW_ACCESS_MUTEX_SB_PCI0_SBRG_SIO1_MUT0, 749 .family = family_amd_800_series, 750 }; 751 752 static const struct ec_board_info board_info_strix_x870e_h_gaming_wifi7 = { 753 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE | 754 SENSOR_TEMP_MB | SENSOR_TEMP_VRM | SENSOR_TEMP_T_SENSOR | 755 SENSOR_FAN_CPU_OPT, 756 .mutex_path = ASUS_HW_ACCESS_MUTEX_SB_PCI0_SBRG_SIO1_MUT0, 757 .family = family_amd_800_series, 758 }; 759 760 static const struct ec_board_info board_info_strix_z390_f_gaming = { 761 .sensors = SENSOR_TEMP_CHIPSET | SENSOR_TEMP_VRM | 762 SENSOR_TEMP_T_SENSOR | 763 SENSOR_FAN_CPU_OPT, 764 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 765 .family = family_intel_300_series, 766 }; 767 768 static const struct ec_board_info board_info_strix_z490_f_gaming = { 769 .sensors = SENSOR_TEMP_CHIPSET | 770 SENSOR_TEMP_CPU | 771 SENSOR_TEMP_MB | 772 SENSOR_TEMP_T_SENSOR | 773 SENSOR_TEMP_VRM | 774 SENSOR_FAN_CPU_OPT | 775 SENSOR_FAN_VRM_HS, 776 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 777 .family = family_intel_400_series, 778 }; 779 780 static const struct ec_board_info board_info_strix_z690_a_gaming_wifi_d4 = { 781 .sensors = SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM, 782 .mutex_path = ASUS_HW_ACCESS_MUTEX_RMTW_ASMX, 783 .family = family_intel_600_series, 784 }; 785 786 static const struct ec_board_info board_info_strix_z690_e_gaming_wifi = { 787 .sensors = SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM, 788 .mutex_path = ASUS_HW_ACCESS_MUTEX_RMTW_ASMX, 789 .family = family_intel_600_series, 790 }; 791 792 static const struct ec_board_info board_info_strix_z790_e_gaming_wifi_ii = { 793 .sensors = SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | 794 SENSOR_FAN_CPU_OPT, 795 .mutex_path = ASUS_HW_ACCESS_MUTEX_SB_PC00_LPCB_SIO1_MUT0, 796 .family = family_intel_700_series, 797 }; 798 799 static const struct ec_board_info board_info_strix_z790_h_gaming_wifi = { 800 .sensors = SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM, 801 .mutex_path = ASUS_HW_ACCESS_MUTEX_SB_PC00_LPCB_SIO1_MUT0, 802 .family = family_intel_700_series, 803 }; 804 805 static const struct ec_board_info board_info_strix_z790_i_gaming_wifi = { 806 .sensors = SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_T_SENSOR_2 | 807 SENSOR_TEMP_VRM, 808 .mutex_path = ASUS_HW_ACCESS_MUTEX_SB_PC00_LPCB_SIO1_MUT0, 809 .family = family_intel_700_series, 810 }; 811 812 static const struct ec_board_info board_info_tuf_gaming_x670e_plus = { 813 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE | 814 SENSOR_TEMP_MB | SENSOR_TEMP_VRM | 815 SENSOR_TEMP_WATER_IN | SENSOR_TEMP_WATER_OUT | 816 SENSOR_FAN_CPU_OPT, 817 .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH, 818 .family = family_amd_600_series, 819 }; 820 821 static const struct ec_board_info board_info_zenith_ii_extreme = { 822 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_T_SENSOR | 823 SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER | 824 SENSOR_FAN_CPU_OPT | SENSOR_FAN_CHIPSET | SENSOR_FAN_VRM_HS | 825 SENSOR_FAN_WATER_FLOW | SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE | 826 SENSOR_SET_WATER_BLOCK | 827 SENSOR_TEMP_T_SENSOR_2 | SENSOR_TEMP_SENSOR_EXTRA_1 | 828 SENSOR_TEMP_SENSOR_EXTRA_2 | SENSOR_TEMP_SENSOR_EXTRA_3, 829 .mutex_path = ASUS_HW_ACCESS_MUTEX_SB_PCI0_SBRG_SIO1_MUT0, 830 .family = family_amd_500_series, 831 }; 832 833 #define DMI_EXACT_MATCH_ASUS_BOARD_NAME(name, board_info) \ 834 { \ 835 .matches = { \ 836 DMI_EXACT_MATCH(DMI_BOARD_VENDOR, \ 837 "ASUSTeK COMPUTER INC."), \ 838 DMI_EXACT_MATCH(DMI_BOARD_NAME, name), \ 839 }, \ 840 .driver_data = (void *)board_info, \ 841 } 842 843 static const struct dmi_system_id dmi_table[] = { 844 DMI_EXACT_MATCH_ASUS_BOARD_NAME("MAXIMUS VI HERO", 845 &board_info_maximus_vi_hero), 846 DMI_EXACT_MATCH_ASUS_BOARD_NAME("PRIME X470-PRO", 847 &board_info_prime_x470_pro), 848 DMI_EXACT_MATCH_ASUS_BOARD_NAME("PRIME X570-PRO", 849 &board_info_prime_x570_pro), 850 DMI_EXACT_MATCH_ASUS_BOARD_NAME("PRIME X670E-PRO WIFI", 851 &board_info_prime_x670e_pro_wifi), 852 DMI_EXACT_MATCH_ASUS_BOARD_NAME("PRIME Z270-A", 853 &board_info_prime_z270_a), 854 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ProArt B550-CREATOR", 855 &board_info_pro_art_b550_creator), 856 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ProArt X570-CREATOR WIFI", 857 &board_info_pro_art_x570_creator_wifi), 858 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ProArt X670E-CREATOR WIFI", 859 &board_info_pro_art_x670E_creator_wifi), 860 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ProArt X870E-CREATOR WIFI", 861 &board_info_pro_art_x870E_creator_wifi), 862 DMI_EXACT_MATCH_ASUS_BOARD_NAME("Pro WS TRX50-SAGE WIFI", 863 &board_info_pro_ws_trx50_sage_wifi), 864 DMI_EXACT_MATCH_ASUS_BOARD_NAME("Pro WS TRX50-SAGE WIFI A", 865 &board_info_pro_ws_trx50_sage_wifi), 866 DMI_EXACT_MATCH_ASUS_BOARD_NAME("Pro WS WRX90E-SAGE SE", 867 &board_info_pro_ws_wrx90e_sage_se), 868 DMI_EXACT_MATCH_ASUS_BOARD_NAME("Pro WS X570-ACE", 869 &board_info_pro_ws_x570_ace), 870 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VIII DARK HERO", 871 &board_info_crosshair_viii_dark_hero), 872 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VIII FORMULA", 873 &board_info_crosshair_viii_hero), 874 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VIII HERO", 875 &board_info_crosshair_viii_hero), 876 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VIII HERO (WI-FI)", 877 &board_info_crosshair_viii_hero), 878 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VIII IMPACT", 879 &board_info_crosshair_viii_impact), 880 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR X670E EXTREME", 881 &board_info_crosshair_x670e_extreme), 882 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR X670E GENE", 883 &board_info_crosshair_x670e_gene), 884 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR X670E HERO", 885 &board_info_crosshair_x670e_hero), 886 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG MAXIMUS XI HERO", 887 &board_info_maximus_xi_hero), 888 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG MAXIMUS XI HERO (WI-FI)", 889 &board_info_maximus_xi_hero), 890 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG MAXIMUS X HERO", 891 &board_info_maximus_x_hero), 892 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG MAXIMUS Z690 FORMULA", 893 &board_info_maximus_z690_formula), 894 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG MAXIMUS Z790 EXTREME", 895 &board_info_maximus_z790_extreme), 896 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX B550-E GAMING", 897 &board_info_strix_b550_e_gaming), 898 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX B550-I GAMING", 899 &board_info_strix_b550_i_gaming), 900 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX B650E-E GAMING WIFI", 901 &board_info_strix_b650e_e_gaming), 902 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX B650E-I GAMING WIFI", 903 &board_info_strix_b650e_i_gaming), 904 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX B850-E GAMING WIFI", 905 &board_info_strix_b850_e_gaming_wifi), 906 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX B850-I GAMING WIFI", 907 &board_info_strix_b850_i_gaming_wifi), 908 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X470-F GAMING", 909 &board_info_strix_x470_f_gaming), 910 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X470-I GAMING", 911 &board_info_strix_x470_i_gaming), 912 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X570-E GAMING", 913 &board_info_strix_x570_e_gaming), 914 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X570-E GAMING WIFI II", 915 &board_info_strix_x570_e_gaming_wifi_ii), 916 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X570-F GAMING", 917 &board_info_strix_x570_f_gaming), 918 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X570-I GAMING", 919 &board_info_strix_x570_i_gaming), 920 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X670E-E GAMING WIFI", 921 &board_info_strix_x670e_e_gaming_wifi), 922 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X670E-I GAMING WIFI", 923 &board_info_strix_x670e_i_gaming_wifi), 924 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X870-F GAMING WIFI", 925 &board_info_strix_x870_f_gaming_wifi), 926 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X870-I GAMING WIFI", 927 &board_info_strix_x870_i_gaming_wifi), 928 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X870E-E GAMING WIFI", 929 &board_info_strix_x870e_e_gaming_wifi), 930 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X870E-H GAMING WIFI7", 931 &board_info_strix_x870e_h_gaming_wifi7), 932 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX Z390-F GAMING", 933 &board_info_strix_z390_f_gaming), 934 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX Z490-F GAMING", 935 &board_info_strix_z490_f_gaming), 936 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX Z690-A GAMING WIFI D4", 937 &board_info_strix_z690_a_gaming_wifi_d4), 938 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX Z690-E GAMING WIFI", 939 &board_info_strix_z690_e_gaming_wifi), 940 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX Z790-E GAMING WIFI II", 941 &board_info_strix_z790_e_gaming_wifi_ii), 942 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX Z790-H GAMING WIFI", 943 &board_info_strix_z790_h_gaming_wifi), 944 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX Z790-I GAMING WIFI", 945 &board_info_strix_z790_i_gaming_wifi), 946 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG ZENITH II EXTREME", 947 &board_info_zenith_ii_extreme), 948 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG ZENITH II EXTREME ALPHA", 949 &board_info_zenith_ii_extreme), 950 DMI_EXACT_MATCH_ASUS_BOARD_NAME("TUF GAMING X670E-PLUS", 951 &board_info_tuf_gaming_x670e_plus), 952 DMI_EXACT_MATCH_ASUS_BOARD_NAME("TUF GAMING X670E-PLUS WIFI", 953 &board_info_tuf_gaming_x670e_plus), 954 {}, 955 }; 956 957 struct ec_sensor { 958 unsigned int info_index; 959 s32 cached_value; 960 }; 961 962 struct lock_data { 963 union { 964 acpi_handle aml; 965 /* global lock handle */ 966 u32 glk; 967 } mutex; 968 bool (*lock)(struct lock_data *data); 969 bool (*unlock)(struct lock_data *data); 970 }; 971 972 /* 973 * The next function pairs implement options for locking access to the 974 * state and the EC 975 */ 976 static bool lock_via_acpi_mutex(struct lock_data *data) 977 { 978 /* 979 * ASUS DSDT does not specify that access to the EC has to be guarded, 980 * but firmware does access it via ACPI 981 */ 982 return ACPI_SUCCESS(acpi_acquire_mutex(data->mutex.aml, 983 NULL, ACPI_LOCK_DELAY_MS)); 984 } 985 986 static bool unlock_acpi_mutex(struct lock_data *data) 987 { 988 return ACPI_SUCCESS(acpi_release_mutex(data->mutex.aml, NULL)); 989 } 990 991 static bool lock_via_global_acpi_lock(struct lock_data *data) 992 { 993 return ACPI_SUCCESS(acpi_acquire_global_lock(ACPI_LOCK_DELAY_MS, 994 &data->mutex.glk)); 995 } 996 997 static bool unlock_global_acpi_lock(struct lock_data *data) 998 { 999 return ACPI_SUCCESS(acpi_release_global_lock(data->mutex.glk)); 1000 } 1001 1002 struct ec_sensors_data { 1003 const struct ec_board_info *board_info; 1004 const struct ec_sensor_info *sensors_info; 1005 struct ec_sensor *sensors; 1006 /* EC registers to read from */ 1007 u16 *registers; 1008 u8 *read_buffer; 1009 /* sorted list of unique register banks */ 1010 u8 banks[ASUS_EC_MAX_BANK + 1]; 1011 /* in jiffies */ 1012 unsigned long last_updated; 1013 struct lock_data lock_data; 1014 /* number of board EC sensors */ 1015 u8 nr_sensors; 1016 /* 1017 * number of EC registers to read 1018 * (sensor might span more than 1 register) 1019 */ 1020 u8 nr_registers; 1021 /* number of unique register banks */ 1022 u8 nr_banks; 1023 }; 1024 1025 static u8 register_bank(u16 reg) 1026 { 1027 return reg >> 8; 1028 } 1029 1030 static u8 register_index(u16 reg) 1031 { 1032 return reg & 0x00ff; 1033 } 1034 1035 static bool is_sensor_data_signed(const struct ec_sensor_info *si) 1036 { 1037 /* 1038 * guessed from WMI functions in DSDT code for boards 1039 * of the X470 generation 1040 */ 1041 return si->type == hwmon_temp; 1042 } 1043 1044 static const struct ec_sensor_info * 1045 get_sensor_info(const struct ec_sensors_data *state, int index) 1046 { 1047 return state->sensors_info + state->sensors[index].info_index; 1048 } 1049 1050 static int find_ec_sensor_index(const struct ec_sensors_data *ec, 1051 enum hwmon_sensor_types type, int channel) 1052 { 1053 unsigned int i; 1054 1055 for (i = 0; i < ec->nr_sensors; i++) { 1056 if (get_sensor_info(ec, i)->type == type) { 1057 if (channel == 0) 1058 return i; 1059 channel--; 1060 } 1061 } 1062 return -ENOENT; 1063 } 1064 1065 static int bank_compare(const void *a, const void *b) 1066 { 1067 return *((const s8 *)a) - *((const s8 *)b); 1068 } 1069 1070 static void setup_sensor_data(struct ec_sensors_data *ec) 1071 { 1072 struct ec_sensor *s = ec->sensors; 1073 bool bank_found; 1074 int i, j; 1075 u8 bank; 1076 1077 ec->nr_banks = 0; 1078 ec->nr_registers = 0; 1079 1080 for_each_set_bit(i, &ec->board_info->sensors, 1081 BITS_PER_TYPE(ec->board_info->sensors)) { 1082 s->info_index = i; 1083 s->cached_value = 0; 1084 ec->nr_registers += 1085 ec->sensors_info[s->info_index].addr.components.size; 1086 bank_found = false; 1087 bank = ec->sensors_info[s->info_index].addr.components.bank; 1088 for (j = 0; j < ec->nr_banks; j++) { 1089 if (ec->banks[j] == bank) { 1090 bank_found = true; 1091 break; 1092 } 1093 } 1094 if (!bank_found) { 1095 ec->banks[ec->nr_banks++] = bank; 1096 } 1097 s++; 1098 } 1099 sort(ec->banks, ec->nr_banks, 1, bank_compare, NULL); 1100 } 1101 1102 static void fill_ec_registers(struct ec_sensors_data *ec) 1103 { 1104 const struct ec_sensor_info *si; 1105 unsigned int i, j, register_idx = 0; 1106 1107 for (i = 0; i < ec->nr_sensors; ++i) { 1108 si = get_sensor_info(ec, i); 1109 for (j = 0; j < si->addr.components.size; ++j, ++register_idx) { 1110 ec->registers[register_idx] = 1111 (si->addr.components.bank << 8) + 1112 si->addr.components.index + j; 1113 } 1114 } 1115 } 1116 1117 static int setup_lock_data(struct device *dev) 1118 { 1119 const char *mutex_path; 1120 int status; 1121 struct ec_sensors_data *state = dev_get_drvdata(dev); 1122 1123 mutex_path = mutex_path_override ? 1124 mutex_path_override : state->board_info->mutex_path; 1125 1126 if (!mutex_path || !strlen(mutex_path)) { 1127 dev_err(dev, "Hardware access guard mutex name is empty"); 1128 return -EINVAL; 1129 } 1130 if (!strcmp(mutex_path, ACPI_GLOBAL_LOCK_PSEUDO_PATH)) { 1131 state->lock_data.mutex.glk = 0; 1132 state->lock_data.lock = lock_via_global_acpi_lock; 1133 state->lock_data.unlock = unlock_global_acpi_lock; 1134 } else { 1135 status = acpi_get_handle(NULL, (acpi_string)mutex_path, 1136 &state->lock_data.mutex.aml); 1137 if (ACPI_FAILURE(status)) { 1138 dev_err(dev, 1139 "Failed to get hardware access guard AML mutex '%s': error %d", 1140 mutex_path, status); 1141 return -ENOENT; 1142 } 1143 state->lock_data.lock = lock_via_acpi_mutex; 1144 state->lock_data.unlock = unlock_acpi_mutex; 1145 } 1146 return 0; 1147 } 1148 1149 static int asus_ec_bank_switch(u8 bank, u8 *old) 1150 { 1151 int status = 0; 1152 1153 if (old) { 1154 status = ec_read(ASUS_EC_BANK_REGISTER, old); 1155 } 1156 if (status || (old && (*old == bank))) 1157 return status; 1158 return ec_write(ASUS_EC_BANK_REGISTER, bank); 1159 } 1160 1161 static int asus_ec_block_read(const struct device *dev, 1162 struct ec_sensors_data *ec) 1163 { 1164 int ireg, ibank, status; 1165 u8 bank, reg_bank, prev_bank; 1166 1167 bank = 0; 1168 status = asus_ec_bank_switch(bank, &prev_bank); 1169 if (status) { 1170 dev_warn(dev, "EC bank switch failed"); 1171 return status; 1172 } 1173 1174 if (prev_bank) { 1175 /* oops... somebody else is working with the EC too */ 1176 dev_warn(dev, 1177 "Concurrent access to the ACPI EC detected.\nRace condition possible."); 1178 } 1179 1180 /* read registers minimizing bank switches. */ 1181 for (ibank = 0; ibank < ec->nr_banks; ibank++) { 1182 if (bank != ec->banks[ibank]) { 1183 bank = ec->banks[ibank]; 1184 if (asus_ec_bank_switch(bank, NULL)) { 1185 dev_warn(dev, "EC bank switch to %d failed", 1186 bank); 1187 break; 1188 } 1189 } 1190 for (ireg = 0; ireg < ec->nr_registers; ireg++) { 1191 reg_bank = register_bank(ec->registers[ireg]); 1192 if (reg_bank < bank) { 1193 continue; 1194 } 1195 ec_read(register_index(ec->registers[ireg]), 1196 ec->read_buffer + ireg); 1197 } 1198 } 1199 1200 status = asus_ec_bank_switch(prev_bank, NULL); 1201 return status; 1202 } 1203 1204 static inline s32 get_sensor_value(const struct ec_sensor_info *si, u8 *data) 1205 { 1206 if (is_sensor_data_signed(si)) { 1207 switch (si->addr.components.size) { 1208 case 1: 1209 return (s8)*data; 1210 case 2: 1211 return (s16)get_unaligned_be16(data); 1212 case 4: 1213 return (s32)get_unaligned_be32(data); 1214 default: 1215 return 0; 1216 } 1217 } else { 1218 switch (si->addr.components.size) { 1219 case 1: 1220 return *data; 1221 case 2: 1222 return get_unaligned_be16(data); 1223 case 4: 1224 return get_unaligned_be32(data); 1225 default: 1226 return 0; 1227 } 1228 } 1229 } 1230 1231 static void update_sensor_values(struct ec_sensors_data *ec, u8 *data) 1232 { 1233 const struct ec_sensor_info *si; 1234 struct ec_sensor *s, *sensor_end; 1235 1236 sensor_end = ec->sensors + ec->nr_sensors; 1237 for (s = ec->sensors; s != sensor_end; s++) { 1238 si = ec->sensors_info + s->info_index; 1239 s->cached_value = get_sensor_value(si, data); 1240 data += si->addr.components.size; 1241 } 1242 } 1243 1244 static int update_ec_sensors(const struct device *dev, 1245 struct ec_sensors_data *ec) 1246 { 1247 int status; 1248 1249 if (!ec->lock_data.lock(&ec->lock_data)) { 1250 dev_warn(dev, "Failed to acquire mutex"); 1251 return -EBUSY; 1252 } 1253 1254 status = asus_ec_block_read(dev, ec); 1255 1256 if (!status) { 1257 update_sensor_values(ec, ec->read_buffer); 1258 } 1259 1260 if (!ec->lock_data.unlock(&ec->lock_data)) 1261 dev_err(dev, "Failed to release mutex"); 1262 1263 return status; 1264 } 1265 1266 static long scale_sensor_value(s32 value, int data_type) 1267 { 1268 switch (data_type) { 1269 case hwmon_curr: 1270 case hwmon_temp: 1271 return value * MILLI; 1272 default: 1273 return value; 1274 } 1275 } 1276 1277 static int get_cached_value_or_update(const struct device *dev, 1278 int sensor_index, 1279 struct ec_sensors_data *state, s32 *value) 1280 { 1281 if (time_after(jiffies, state->last_updated + HZ)) { 1282 if (update_ec_sensors(dev, state)) { 1283 dev_err(dev, "update_ec_sensors() failure\n"); 1284 return -EIO; 1285 } 1286 1287 state->last_updated = jiffies; 1288 } 1289 1290 *value = state->sensors[sensor_index].cached_value; 1291 return 0; 1292 } 1293 1294 /* 1295 * Now follow the functions that implement the hwmon interface 1296 */ 1297 1298 static int asus_ec_hwmon_read(struct device *dev, enum hwmon_sensor_types type, 1299 u32 attr, int channel, long *val) 1300 { 1301 int ret; 1302 s32 value = 0; 1303 1304 struct ec_sensors_data *state = dev_get_drvdata(dev); 1305 int sidx = find_ec_sensor_index(state, type, channel); 1306 1307 if (sidx < 0) { 1308 return sidx; 1309 } 1310 1311 ret = get_cached_value_or_update(dev, sidx, state, &value); 1312 if (!ret) { 1313 *val = scale_sensor_value(value, 1314 get_sensor_info(state, sidx)->type); 1315 } 1316 1317 return ret; 1318 } 1319 1320 static int asus_ec_hwmon_read_string(struct device *dev, 1321 enum hwmon_sensor_types type, u32 attr, 1322 int channel, const char **str) 1323 { 1324 struct ec_sensors_data *state = dev_get_drvdata(dev); 1325 int sensor_index = find_ec_sensor_index(state, type, channel); 1326 1327 if (sensor_index < 0) 1328 return sensor_index; 1329 1330 *str = get_sensor_info(state, sensor_index)->label; 1331 1332 return 0; 1333 } 1334 1335 static umode_t asus_ec_hwmon_is_visible(const void *drvdata, 1336 enum hwmon_sensor_types type, u32 attr, 1337 int channel) 1338 { 1339 const struct ec_sensors_data *state = drvdata; 1340 1341 return find_ec_sensor_index(state, type, channel) >= 0 ? S_IRUGO : 0; 1342 } 1343 1344 static int 1345 asus_ec_hwmon_add_chan_info(struct hwmon_channel_info *asus_ec_hwmon_chan, 1346 struct device *dev, int num, 1347 enum hwmon_sensor_types type, u32 config) 1348 { 1349 int i; 1350 u32 *cfg = devm_kcalloc(dev, num + 1, sizeof(*cfg), GFP_KERNEL); 1351 1352 if (!cfg) 1353 return -ENOMEM; 1354 1355 asus_ec_hwmon_chan->type = type; 1356 asus_ec_hwmon_chan->config = cfg; 1357 for (i = 0; i < num; i++, cfg++) 1358 *cfg = config; 1359 1360 return 0; 1361 } 1362 1363 static const struct hwmon_ops asus_ec_hwmon_ops = { 1364 .is_visible = asus_ec_hwmon_is_visible, 1365 .read = asus_ec_hwmon_read, 1366 .read_string = asus_ec_hwmon_read_string, 1367 }; 1368 1369 static struct hwmon_chip_info asus_ec_chip_info = { 1370 .ops = &asus_ec_hwmon_ops, 1371 }; 1372 1373 static const struct ec_board_info *get_board_info(void) 1374 { 1375 const struct dmi_system_id *dmi_entry; 1376 1377 dmi_entry = dmi_first_match(dmi_table); 1378 return dmi_entry ? dmi_entry->driver_data : NULL; 1379 } 1380 1381 static int asus_ec_probe(struct platform_device *pdev) 1382 { 1383 const struct hwmon_channel_info **ptr_asus_ec_ci; 1384 int nr_count[hwmon_max] = { 0 }, nr_types = 0; 1385 struct hwmon_channel_info *asus_ec_hwmon_chan; 1386 const struct ec_board_info *pboard_info; 1387 const struct hwmon_chip_info *chip_info; 1388 struct device *dev = &pdev->dev; 1389 struct ec_sensors_data *ec_data; 1390 const struct ec_sensor_info *si; 1391 enum hwmon_sensor_types type; 1392 struct device *hwdev; 1393 unsigned int i; 1394 int status; 1395 1396 pboard_info = get_board_info(); 1397 if (!pboard_info) 1398 return -ENODEV; 1399 1400 ec_data = devm_kzalloc(dev, sizeof(struct ec_sensors_data), 1401 GFP_KERNEL); 1402 if (!ec_data) 1403 return -ENOMEM; 1404 1405 dev_set_drvdata(dev, ec_data); 1406 ec_data->board_info = pboard_info; 1407 1408 switch (ec_data->board_info->family) { 1409 case family_amd_400_series: 1410 ec_data->sensors_info = sensors_family_amd_400; 1411 break; 1412 case family_amd_500_series: 1413 ec_data->sensors_info = sensors_family_amd_500; 1414 break; 1415 case family_amd_600_series: 1416 ec_data->sensors_info = sensors_family_amd_600; 1417 break; 1418 case family_amd_800_series: 1419 ec_data->sensors_info = sensors_family_amd_800; 1420 break; 1421 case family_amd_trx_50: 1422 ec_data->sensors_info = sensors_family_amd_trx_50; 1423 break; 1424 case family_amd_wrx_90: 1425 ec_data->sensors_info = sensors_family_amd_wrx_90; 1426 break; 1427 case family_intel_200_series: 1428 ec_data->sensors_info = sensors_family_intel_200; 1429 break; 1430 case family_intel_300_series: 1431 ec_data->sensors_info = sensors_family_intel_300; 1432 break; 1433 case family_intel_400_series: 1434 ec_data->sensors_info = sensors_family_intel_400; 1435 break; 1436 case family_intel_600_series: 1437 ec_data->sensors_info = sensors_family_intel_600; 1438 break; 1439 case family_intel_700_series: 1440 ec_data->sensors_info = sensors_family_intel_700; 1441 break; 1442 default: 1443 dev_err(dev, "Unknown board family: %d", 1444 ec_data->board_info->family); 1445 return -EINVAL; 1446 } 1447 1448 ec_data->nr_sensors = hweight_long(ec_data->board_info->sensors); 1449 ec_data->sensors = devm_kcalloc(dev, ec_data->nr_sensors, 1450 sizeof(struct ec_sensor), GFP_KERNEL); 1451 if (!ec_data->sensors) 1452 return -ENOMEM; 1453 1454 status = setup_lock_data(dev); 1455 if (status) { 1456 dev_err(dev, "Failed to setup state/EC locking: %d", status); 1457 return status; 1458 } 1459 1460 setup_sensor_data(ec_data); 1461 ec_data->registers = devm_kcalloc(dev, ec_data->nr_registers, 1462 sizeof(u16), GFP_KERNEL); 1463 ec_data->read_buffer = devm_kcalloc(dev, ec_data->nr_registers, 1464 sizeof(u8), GFP_KERNEL); 1465 1466 if (!ec_data->registers || !ec_data->read_buffer) 1467 return -ENOMEM; 1468 1469 fill_ec_registers(ec_data); 1470 1471 for (i = 0; i < ec_data->nr_sensors; ++i) { 1472 si = get_sensor_info(ec_data, i); 1473 if (!nr_count[si->type]) 1474 ++nr_types; 1475 ++nr_count[si->type]; 1476 } 1477 1478 if (nr_count[hwmon_temp]) 1479 nr_count[hwmon_chip]++, nr_types++; 1480 1481 asus_ec_hwmon_chan = devm_kcalloc( 1482 dev, nr_types, sizeof(*asus_ec_hwmon_chan), GFP_KERNEL); 1483 if (!asus_ec_hwmon_chan) 1484 return -ENOMEM; 1485 1486 ptr_asus_ec_ci = devm_kcalloc(dev, nr_types + 1, 1487 sizeof(*ptr_asus_ec_ci), GFP_KERNEL); 1488 if (!ptr_asus_ec_ci) 1489 return -ENOMEM; 1490 1491 asus_ec_chip_info.info = ptr_asus_ec_ci; 1492 chip_info = &asus_ec_chip_info; 1493 1494 for (type = 0; type < hwmon_max; ++type) { 1495 if (!nr_count[type]) 1496 continue; 1497 1498 asus_ec_hwmon_add_chan_info(asus_ec_hwmon_chan, dev, 1499 nr_count[type], type, 1500 hwmon_attributes[type]); 1501 *ptr_asus_ec_ci++ = asus_ec_hwmon_chan++; 1502 } 1503 1504 dev_info(dev, "board has %d EC sensors that span %d registers", 1505 ec_data->nr_sensors, ec_data->nr_registers); 1506 1507 hwdev = devm_hwmon_device_register_with_info(dev, "asusec", 1508 ec_data, chip_info, NULL); 1509 1510 return PTR_ERR_OR_ZERO(hwdev); 1511 } 1512 1513 MODULE_DEVICE_TABLE(dmi, dmi_table); 1514 1515 static struct platform_driver asus_ec_sensors_platform_driver = { 1516 .driver = { 1517 .name = "asus-ec-sensors", 1518 }, 1519 .probe = asus_ec_probe, 1520 }; 1521 1522 static struct platform_device *asus_ec_sensors_platform_device; 1523 1524 static int __init asus_ec_init(void) 1525 { 1526 asus_ec_sensors_platform_device = 1527 platform_create_bundle(&asus_ec_sensors_platform_driver, 1528 asus_ec_probe, NULL, 0, NULL, 0); 1529 1530 if (IS_ERR(asus_ec_sensors_platform_device)) 1531 return PTR_ERR(asus_ec_sensors_platform_device); 1532 1533 return 0; 1534 } 1535 1536 static void __exit asus_ec_exit(void) 1537 { 1538 platform_device_unregister(asus_ec_sensors_platform_device); 1539 platform_driver_unregister(&asus_ec_sensors_platform_driver); 1540 } 1541 1542 module_init(asus_ec_init); 1543 module_exit(asus_ec_exit); 1544 1545 module_param_named(mutex_path, mutex_path_override, charp, 0); 1546 MODULE_PARM_DESC(mutex_path, 1547 "Override ACPI mutex path used to guard access to hardware"); 1548 1549 MODULE_AUTHOR("Eugene Shalygin <eugene.shalygin@gmail.com>"); 1550 MODULE_DESCRIPTION( 1551 "HWMON driver for sensors accessible via ACPI EC in ASUS motherboards"); 1552 MODULE_LICENSE("GPL"); 1553