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 500 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_PCI0_SBRG_SIO1_MUT0 "\\_SB_.PCI0.SBRG.SIO1.MUT0" 60 61 #define MAX_IDENTICAL_BOARD_VARIATIONS 3 62 63 /* Moniker for the ACPI global lock (':' is not allowed in ASL identifiers) */ 64 #define ACPI_GLOBAL_LOCK_PSEUDO_PATH ":GLOBAL_LOCK" 65 66 typedef union { 67 u32 value; 68 struct { 69 u8 index; 70 u8 bank; 71 u8 size; 72 u8 dummy; 73 } components; 74 } sensor_address; 75 76 #define MAKE_SENSOR_ADDRESS(size, bank, index) { \ 77 .value = (size << 16) + (bank << 8) + index \ 78 } 79 80 static u32 hwmon_attributes[hwmon_max] = { 81 [hwmon_chip] = HWMON_C_REGISTER_TZ, 82 [hwmon_temp] = HWMON_T_INPUT | HWMON_T_LABEL, 83 [hwmon_in] = HWMON_I_INPUT | HWMON_I_LABEL, 84 [hwmon_curr] = HWMON_C_INPUT | HWMON_C_LABEL, 85 [hwmon_fan] = HWMON_F_INPUT | HWMON_F_LABEL, 86 }; 87 88 struct ec_sensor_info { 89 char label[SENSOR_LABEL_LEN]; 90 enum hwmon_sensor_types type; 91 sensor_address addr; 92 }; 93 94 #define EC_SENSOR(sensor_label, sensor_type, size, bank, index) { \ 95 .label = sensor_label, .type = sensor_type, \ 96 .addr = MAKE_SENSOR_ADDRESS(size, bank, index), \ 97 } 98 99 enum ec_sensors { 100 /* chipset temperature [℃] */ 101 ec_sensor_temp_chipset, 102 /* CPU temperature [℃] */ 103 ec_sensor_temp_cpu, 104 /* CPU package temperature [℃] */ 105 ec_sensor_temp_cpu_package, 106 /* motherboard temperature [℃] */ 107 ec_sensor_temp_mb, 108 /* "T_Sensor" temperature sensor reading [℃] */ 109 ec_sensor_temp_t_sensor, 110 /* VRM temperature [℃] */ 111 ec_sensor_temp_vrm, 112 /* CPU Core voltage [mV] */ 113 ec_sensor_in_cpu_core, 114 /* CPU_Opt fan [RPM] */ 115 ec_sensor_fan_cpu_opt, 116 /* VRM heat sink fan [RPM] */ 117 ec_sensor_fan_vrm_hs, 118 /* Chipset fan [RPM] */ 119 ec_sensor_fan_chipset, 120 /* Water flow sensor reading [RPM] */ 121 ec_sensor_fan_water_flow, 122 /* CPU current [A] */ 123 ec_sensor_curr_cpu, 124 /* "Water_In" temperature sensor reading [℃] */ 125 ec_sensor_temp_water_in, 126 /* "Water_Out" temperature sensor reading [℃] */ 127 ec_sensor_temp_water_out, 128 /* "Water_Block_In" temperature sensor reading [℃] */ 129 ec_sensor_temp_water_block_in, 130 /* "Water_Block_Out" temperature sensor reading [℃] */ 131 ec_sensor_temp_water_block_out, 132 /* "T_sensor_2" temperature sensor reading [℃] */ 133 ec_sensor_temp_t_sensor_2, 134 /* "Extra_1" temperature sensor reading [℃] */ 135 ec_sensor_temp_sensor_extra_1, 136 /* "Extra_2" temperature sensor reading [℃] */ 137 ec_sensor_temp_sensor_extra_2, 138 /* "Extra_3" temperature sensor reading [℃] */ 139 ec_sensor_temp_sensor_extra_3, 140 }; 141 142 #define SENSOR_TEMP_CHIPSET BIT(ec_sensor_temp_chipset) 143 #define SENSOR_TEMP_CPU BIT(ec_sensor_temp_cpu) 144 #define SENSOR_TEMP_CPU_PACKAGE BIT(ec_sensor_temp_cpu_package) 145 #define SENSOR_TEMP_MB BIT(ec_sensor_temp_mb) 146 #define SENSOR_TEMP_T_SENSOR BIT(ec_sensor_temp_t_sensor) 147 #define SENSOR_TEMP_VRM BIT(ec_sensor_temp_vrm) 148 #define SENSOR_IN_CPU_CORE BIT(ec_sensor_in_cpu_core) 149 #define SENSOR_FAN_CPU_OPT BIT(ec_sensor_fan_cpu_opt) 150 #define SENSOR_FAN_VRM_HS BIT(ec_sensor_fan_vrm_hs) 151 #define SENSOR_FAN_CHIPSET BIT(ec_sensor_fan_chipset) 152 #define SENSOR_FAN_WATER_FLOW BIT(ec_sensor_fan_water_flow) 153 #define SENSOR_CURR_CPU BIT(ec_sensor_curr_cpu) 154 #define SENSOR_TEMP_WATER_IN BIT(ec_sensor_temp_water_in) 155 #define SENSOR_TEMP_WATER_OUT BIT(ec_sensor_temp_water_out) 156 #define SENSOR_TEMP_WATER_BLOCK_IN BIT(ec_sensor_temp_water_block_in) 157 #define SENSOR_TEMP_WATER_BLOCK_OUT BIT(ec_sensor_temp_water_block_out) 158 #define SENSOR_TEMP_T_SENSOR_2 BIT(ec_sensor_temp_t_sensor_2) 159 #define SENSOR_TEMP_SENSOR_EXTRA_1 BIT(ec_sensor_temp_sensor_extra_1) 160 #define SENSOR_TEMP_SENSOR_EXTRA_2 BIT(ec_sensor_temp_sensor_extra_2) 161 #define SENSOR_TEMP_SENSOR_EXTRA_3 BIT(ec_sensor_temp_sensor_extra_3) 162 163 enum board_family { 164 family_unknown, 165 family_amd_400_series, 166 family_amd_500_series, 167 family_amd_600_series, 168 family_amd_800_series, 169 family_intel_300_series, 170 family_intel_400_series, 171 family_intel_600_series 172 }; 173 174 /* 175 * All the known sensors for ASUS EC controllers. These arrays have to be sorted 176 * by the full ((bank << 8) + index) register index (see asus_ec_block_read() as 177 * to why). 178 */ 179 static const struct ec_sensor_info sensors_family_amd_400[] = { 180 [ec_sensor_temp_chipset] = 181 EC_SENSOR("Chipset", hwmon_temp, 1, 0x00, 0x3a), 182 [ec_sensor_temp_cpu] = 183 EC_SENSOR("CPU", hwmon_temp, 1, 0x00, 0x3b), 184 [ec_sensor_temp_mb] = 185 EC_SENSOR("Motherboard", hwmon_temp, 1, 0x00, 0x3c), 186 [ec_sensor_temp_t_sensor] = 187 EC_SENSOR("T_Sensor", hwmon_temp, 1, 0x00, 0x3d), 188 [ec_sensor_temp_vrm] = 189 EC_SENSOR("VRM", hwmon_temp, 1, 0x00, 0x3e), 190 [ec_sensor_in_cpu_core] = 191 EC_SENSOR("CPU Core", hwmon_in, 2, 0x00, 0xa2), 192 [ec_sensor_fan_vrm_hs] = 193 EC_SENSOR("VRM HS", hwmon_fan, 2, 0x00, 0xb2), 194 [ec_sensor_fan_cpu_opt] = 195 EC_SENSOR("CPU_Opt", hwmon_fan, 2, 0x00, 0xbc), 196 [ec_sensor_fan_chipset] = 197 /* no chipset fans in this generation */ 198 EC_SENSOR("Chipset", hwmon_fan, 0, 0x00, 0x00), 199 [ec_sensor_fan_water_flow] = 200 EC_SENSOR("Water_Flow", hwmon_fan, 2, 0x00, 0xb4), 201 [ec_sensor_curr_cpu] = 202 EC_SENSOR("CPU", hwmon_curr, 1, 0x00, 0xf4), 203 [ec_sensor_temp_water_out] = 204 EC_SENSOR("Water_Out", hwmon_temp, 1, 0x01, 0x0b), 205 [ec_sensor_temp_water_in] = 206 EC_SENSOR("Water_In", hwmon_temp, 1, 0x01, 0x0d), 207 }; 208 209 static const struct ec_sensor_info sensors_family_amd_500[] = { 210 [ec_sensor_temp_chipset] = 211 EC_SENSOR("Chipset", hwmon_temp, 1, 0x00, 0x3a), 212 [ec_sensor_temp_cpu] = 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] = EC_SENSOR("VRM", hwmon_temp, 1, 0x00, 0x3e), 218 [ec_sensor_in_cpu_core] = 219 EC_SENSOR("CPU Core", hwmon_in, 2, 0x00, 0xa2), 220 [ec_sensor_fan_cpu_opt] = 221 EC_SENSOR("CPU_Opt", hwmon_fan, 2, 0x00, 0xb0), 222 [ec_sensor_fan_vrm_hs] = EC_SENSOR("VRM HS", hwmon_fan, 2, 0x00, 0xb2), 223 [ec_sensor_fan_chipset] = 224 EC_SENSOR("Chipset", hwmon_fan, 2, 0x00, 0xb4), 225 [ec_sensor_fan_water_flow] = 226 EC_SENSOR("Water_Flow", hwmon_fan, 2, 0x00, 0xbc), 227 [ec_sensor_curr_cpu] = EC_SENSOR("CPU", hwmon_curr, 1, 0x00, 0xf4), 228 [ec_sensor_temp_water_in] = 229 EC_SENSOR("Water_In", hwmon_temp, 1, 0x01, 0x00), 230 [ec_sensor_temp_water_out] = 231 EC_SENSOR("Water_Out", hwmon_temp, 1, 0x01, 0x01), 232 [ec_sensor_temp_water_block_in] = 233 EC_SENSOR("Water_Block_In", hwmon_temp, 1, 0x01, 0x02), 234 [ec_sensor_temp_water_block_out] = 235 EC_SENSOR("Water_Block_Out", hwmon_temp, 1, 0x01, 0x03), 236 [ec_sensor_temp_sensor_extra_1] = 237 EC_SENSOR("Extra_1", hwmon_temp, 1, 0x01, 0x09), 238 [ec_sensor_temp_t_sensor_2] = 239 EC_SENSOR("T_sensor_2", hwmon_temp, 1, 0x01, 0x0a), 240 [ec_sensor_temp_sensor_extra_2] = 241 EC_SENSOR("Extra_2", hwmon_temp, 1, 0x01, 0x0b), 242 [ec_sensor_temp_sensor_extra_3] = 243 EC_SENSOR("Extra_3", hwmon_temp, 1, 0x01, 0x0c), 244 }; 245 246 static const struct ec_sensor_info sensors_family_amd_600[] = { 247 [ec_sensor_temp_cpu] = EC_SENSOR("CPU", hwmon_temp, 1, 0x00, 0x30), 248 [ec_sensor_temp_cpu_package] = 249 EC_SENSOR("CPU Package", hwmon_temp, 1, 0x00, 0x31), 250 [ec_sensor_temp_mb] = 251 EC_SENSOR("Motherboard", hwmon_temp, 1, 0x00, 0x32), 252 [ec_sensor_temp_vrm] = 253 EC_SENSOR("VRM", hwmon_temp, 1, 0x00, 0x33), 254 [ec_sensor_temp_t_sensor] = 255 EC_SENSOR("T_Sensor", hwmon_temp, 1, 0x00, 0x36), 256 [ec_sensor_fan_cpu_opt] = 257 EC_SENSOR("CPU_Opt", hwmon_fan, 2, 0x00, 0xb0), 258 [ec_sensor_temp_water_in] = 259 EC_SENSOR("Water_In", hwmon_temp, 1, 0x01, 0x00), 260 [ec_sensor_temp_water_out] = 261 EC_SENSOR("Water_Out", hwmon_temp, 1, 0x01, 0x01), 262 }; 263 264 static const struct ec_sensor_info sensors_family_amd_800[] = { 265 [ec_sensor_temp_cpu] = EC_SENSOR("CPU", hwmon_temp, 1, 0x00, 0x30), 266 [ec_sensor_temp_cpu_package] = 267 EC_SENSOR("CPU Package", hwmon_temp, 1, 0x00, 0x31), 268 [ec_sensor_temp_mb] = 269 EC_SENSOR("Motherboard", hwmon_temp, 1, 0x00, 0x32), 270 [ec_sensor_temp_vrm] = 271 EC_SENSOR("VRM", hwmon_temp, 1, 0x00, 0x33), 272 [ec_sensor_temp_t_sensor] = 273 EC_SENSOR("T_Sensor", hwmon_temp, 1, 0x00, 0x36), 274 [ec_sensor_fan_cpu_opt] = 275 EC_SENSOR("CPU_Opt", hwmon_fan, 2, 0x00, 0xb0), 276 }; 277 278 static const struct ec_sensor_info sensors_family_intel_300[] = { 279 [ec_sensor_temp_chipset] = 280 EC_SENSOR("Chipset", hwmon_temp, 1, 0x00, 0x3a), 281 [ec_sensor_temp_cpu] = EC_SENSOR("CPU", hwmon_temp, 1, 0x00, 0x3b), 282 [ec_sensor_temp_mb] = 283 EC_SENSOR("Motherboard", hwmon_temp, 1, 0x00, 0x3c), 284 [ec_sensor_temp_t_sensor] = 285 EC_SENSOR("T_Sensor", hwmon_temp, 1, 0x00, 0x3d), 286 [ec_sensor_temp_vrm] = EC_SENSOR("VRM", hwmon_temp, 1, 0x00, 0x3e), 287 [ec_sensor_fan_cpu_opt] = 288 EC_SENSOR("CPU_Opt", hwmon_fan, 2, 0x00, 0xb0), 289 [ec_sensor_fan_vrm_hs] = EC_SENSOR("VRM HS", hwmon_fan, 2, 0x00, 0xb2), 290 [ec_sensor_fan_water_flow] = 291 EC_SENSOR("Water_Flow", hwmon_fan, 2, 0x00, 0xbc), 292 [ec_sensor_temp_water_in] = 293 EC_SENSOR("Water_In", hwmon_temp, 1, 0x01, 0x00), 294 [ec_sensor_temp_water_out] = 295 EC_SENSOR("Water_Out", hwmon_temp, 1, 0x01, 0x01), 296 }; 297 298 static const struct ec_sensor_info sensors_family_intel_400[] = { 299 [ec_sensor_temp_chipset] = 300 EC_SENSOR("Chipset", hwmon_temp, 1, 0x00, 0x3a), 301 [ec_sensor_temp_cpu] = EC_SENSOR("CPU", hwmon_temp, 1, 0x00, 0x3b), 302 [ec_sensor_temp_mb] = 303 EC_SENSOR("Motherboard", hwmon_temp, 1, 0x00, 0x3c), 304 [ec_sensor_temp_t_sensor] = 305 EC_SENSOR("T_Sensor", hwmon_temp, 1, 0x00, 0x3d), 306 [ec_sensor_temp_vrm] = EC_SENSOR("VRM", hwmon_temp, 1, 0x00, 0x3e), 307 [ec_sensor_fan_cpu_opt] = 308 EC_SENSOR("CPU_Opt", hwmon_fan, 2, 0x00, 0xb0), 309 [ec_sensor_fan_vrm_hs] = EC_SENSOR("VRM HS", hwmon_fan, 2, 0x00, 0xb2), 310 }; 311 312 static const struct ec_sensor_info sensors_family_intel_600[] = { 313 [ec_sensor_temp_t_sensor] = 314 EC_SENSOR("T_Sensor", hwmon_temp, 1, 0x00, 0x3d), 315 [ec_sensor_temp_vrm] = EC_SENSOR("VRM", hwmon_temp, 1, 0x00, 0x3e), 316 [ec_sensor_fan_water_flow] = 317 EC_SENSOR("Water_Flow", hwmon_fan, 2, 0x00, 0xbe), 318 [ec_sensor_temp_water_in] = 319 EC_SENSOR("Water_In", hwmon_temp, 1, 0x01, 0x00), 320 [ec_sensor_temp_water_out] = 321 EC_SENSOR("Water_Out", hwmon_temp, 1, 0x01, 0x01), 322 [ec_sensor_temp_water_block_in] = 323 EC_SENSOR("Water_Block_In", hwmon_temp, 1, 0x01, 0x02), 324 }; 325 326 /* Shortcuts for common combinations */ 327 #define SENSOR_SET_TEMP_CHIPSET_CPU_MB \ 328 (SENSOR_TEMP_CHIPSET | SENSOR_TEMP_CPU | SENSOR_TEMP_MB) 329 #define SENSOR_SET_TEMP_WATER (SENSOR_TEMP_WATER_IN | SENSOR_TEMP_WATER_OUT) 330 #define SENSOR_SET_WATER_BLOCK \ 331 (SENSOR_TEMP_WATER_BLOCK_IN | SENSOR_TEMP_WATER_BLOCK_OUT) 332 333 struct ec_board_info { 334 unsigned long sensors; 335 /* 336 * Defines which mutex to use for guarding access to the state and the 337 * hardware. Can be either a full path to an AML mutex or the 338 * pseudo-path ACPI_GLOBAL_LOCK_PSEUDO_PATH to use the global ACPI lock, 339 * or left empty to use a regular mutex object, in which case access to 340 * the hardware is not guarded. 341 */ 342 const char *mutex_path; 343 enum board_family family; 344 }; 345 346 static const struct ec_board_info board_info_maximus_vi_hero = { 347 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 348 SENSOR_TEMP_T_SENSOR | 349 SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER | 350 SENSOR_FAN_CPU_OPT | SENSOR_FAN_WATER_FLOW, 351 .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH, 352 .family = family_intel_300_series, 353 }; 354 355 static const struct ec_board_info board_info_prime_x470_pro = { 356 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 357 SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | 358 SENSOR_FAN_CPU_OPT | 359 SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, 360 .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH, 361 .family = family_amd_400_series, 362 }; 363 364 static const struct ec_board_info board_info_prime_x570_pro = { 365 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM | 366 SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET, 367 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 368 .family = family_amd_500_series, 369 }; 370 371 static const struct ec_board_info board_info_prime_x670e_pro_wifi = { 372 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE | 373 SENSOR_TEMP_MB | SENSOR_TEMP_VRM | 374 SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CPU_OPT, 375 .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH, 376 .family = family_amd_600_series, 377 }; 378 379 static const struct ec_board_info board_info_pro_art_x570_creator_wifi = { 380 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM | 381 SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CPU_OPT | 382 SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, 383 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 384 .family = family_amd_500_series, 385 }; 386 387 static const struct ec_board_info board_info_pro_art_x670E_creator_wifi = { 388 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE | 389 SENSOR_TEMP_MB | SENSOR_TEMP_VRM | 390 SENSOR_TEMP_T_SENSOR, 391 .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH, 392 .family = family_amd_600_series, 393 }; 394 395 static const struct ec_board_info board_info_pro_art_x870E_creator_wifi = { 396 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE | 397 SENSOR_TEMP_MB | SENSOR_TEMP_VRM | 398 SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CPU_OPT, 399 .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH, 400 .family = family_amd_800_series, 401 }; 402 403 static const struct ec_board_info board_info_pro_art_b550_creator = { 404 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 405 SENSOR_TEMP_T_SENSOR | 406 SENSOR_FAN_CPU_OPT, 407 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 408 .family = family_amd_500_series, 409 }; 410 411 static const struct ec_board_info board_info_pro_ws_x570_ace = { 412 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM | 413 SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET | 414 SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, 415 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 416 .family = family_amd_500_series, 417 }; 418 419 static const struct ec_board_info board_info_crosshair_x670e_hero = { 420 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE | 421 SENSOR_TEMP_MB | SENSOR_TEMP_VRM | 422 SENSOR_SET_TEMP_WATER, 423 .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH, 424 .family = family_amd_600_series, 425 }; 426 427 static const struct ec_board_info board_info_crosshair_x670e_gene = { 428 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE | 429 SENSOR_TEMP_T_SENSOR | 430 SENSOR_TEMP_MB | SENSOR_TEMP_VRM, 431 .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH, 432 .family = family_amd_600_series, 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_maximus_xi_hero = { 457 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 458 SENSOR_TEMP_T_SENSOR | 459 SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER | 460 SENSOR_FAN_CPU_OPT | SENSOR_FAN_WATER_FLOW, 461 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 462 .family = family_intel_300_series, 463 }; 464 465 static const struct ec_board_info board_info_maximus_z690_formula = { 466 .sensors = SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | 467 SENSOR_SET_TEMP_WATER | SENSOR_FAN_WATER_FLOW, 468 .mutex_path = ASUS_HW_ACCESS_MUTEX_RMTW_ASMX, 469 .family = family_intel_600_series, 470 }; 471 472 static const struct ec_board_info board_info_crosshair_viii_impact = { 473 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 474 SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | 475 SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU | 476 SENSOR_IN_CPU_CORE, 477 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 478 .family = family_amd_500_series, 479 }; 480 481 static const struct ec_board_info board_info_strix_b550_e_gaming = { 482 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 483 SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | 484 SENSOR_FAN_CPU_OPT, 485 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 486 .family = family_amd_500_series, 487 }; 488 489 static const struct ec_board_info board_info_strix_b550_i_gaming = { 490 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 491 SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | 492 SENSOR_FAN_VRM_HS | SENSOR_CURR_CPU | 493 SENSOR_IN_CPU_CORE, 494 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 495 .family = family_amd_500_series, 496 }; 497 498 static const struct ec_board_info board_info_strix_x570_e_gaming = { 499 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 500 SENSOR_TEMP_T_SENSOR | 501 SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU | 502 SENSOR_IN_CPU_CORE, 503 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 504 .family = family_amd_500_series, 505 }; 506 507 static const struct ec_board_info board_info_strix_x570_e_gaming_wifi_ii = { 508 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 509 SENSOR_TEMP_T_SENSOR | SENSOR_CURR_CPU | 510 SENSOR_IN_CPU_CORE, 511 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 512 .family = family_amd_500_series, 513 }; 514 515 static const struct ec_board_info board_info_strix_x570_f_gaming = { 516 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 517 SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET, 518 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 519 .family = family_amd_500_series, 520 }; 521 522 static const struct ec_board_info board_info_strix_x570_i_gaming = { 523 .sensors = SENSOR_TEMP_CHIPSET | SENSOR_TEMP_VRM | 524 SENSOR_TEMP_T_SENSOR | 525 SENSOR_FAN_VRM_HS | SENSOR_FAN_CHIPSET | 526 SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, 527 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 528 .family = family_amd_500_series, 529 }; 530 531 static const struct ec_board_info board_info_strix_z390_f_gaming = { 532 .sensors = SENSOR_TEMP_CHIPSET | SENSOR_TEMP_VRM | 533 SENSOR_TEMP_T_SENSOR | 534 SENSOR_FAN_CPU_OPT, 535 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 536 .family = family_intel_300_series, 537 }; 538 539 static const struct ec_board_info board_info_strix_z490_f_gaming = { 540 .sensors = SENSOR_TEMP_CHIPSET | 541 SENSOR_TEMP_CPU | 542 SENSOR_TEMP_MB | 543 SENSOR_TEMP_T_SENSOR | 544 SENSOR_TEMP_VRM | 545 SENSOR_FAN_CPU_OPT | 546 SENSOR_FAN_VRM_HS, 547 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 548 .family = family_intel_400_series, 549 }; 550 551 static const struct ec_board_info board_info_strix_z690_a_gaming_wifi_d4 = { 552 .sensors = SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM, 553 .mutex_path = ASUS_HW_ACCESS_MUTEX_RMTW_ASMX, 554 .family = family_intel_600_series, 555 }; 556 557 static const struct ec_board_info board_info_zenith_ii_extreme = { 558 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_T_SENSOR | 559 SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER | 560 SENSOR_FAN_CPU_OPT | SENSOR_FAN_CHIPSET | SENSOR_FAN_VRM_HS | 561 SENSOR_FAN_WATER_FLOW | SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE | 562 SENSOR_SET_WATER_BLOCK | 563 SENSOR_TEMP_T_SENSOR_2 | SENSOR_TEMP_SENSOR_EXTRA_1 | 564 SENSOR_TEMP_SENSOR_EXTRA_2 | SENSOR_TEMP_SENSOR_EXTRA_3, 565 .mutex_path = ASUS_HW_ACCESS_MUTEX_SB_PCI0_SBRG_SIO1_MUT0, 566 .family = family_amd_500_series, 567 }; 568 569 static const struct ec_board_info board_info_tuf_gaming_x670e_plus = { 570 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE | 571 SENSOR_TEMP_MB | SENSOR_TEMP_VRM | 572 SENSOR_TEMP_WATER_IN | SENSOR_TEMP_WATER_OUT | 573 SENSOR_FAN_CPU_OPT, 574 .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH, 575 .family = family_amd_600_series, 576 }; 577 578 #define DMI_EXACT_MATCH_ASUS_BOARD_NAME(name, board_info) \ 579 { \ 580 .matches = { \ 581 DMI_EXACT_MATCH(DMI_BOARD_VENDOR, \ 582 "ASUSTeK COMPUTER INC."), \ 583 DMI_EXACT_MATCH(DMI_BOARD_NAME, name), \ 584 }, \ 585 .driver_data = (void *)board_info, \ 586 } 587 588 static const struct dmi_system_id dmi_table[] = { 589 DMI_EXACT_MATCH_ASUS_BOARD_NAME("MAXIMUS VI HERO", 590 &board_info_maximus_vi_hero), 591 DMI_EXACT_MATCH_ASUS_BOARD_NAME("PRIME X470-PRO", 592 &board_info_prime_x470_pro), 593 DMI_EXACT_MATCH_ASUS_BOARD_NAME("PRIME X570-PRO", 594 &board_info_prime_x570_pro), 595 DMI_EXACT_MATCH_ASUS_BOARD_NAME("PRIME X670E-PRO WIFI", 596 &board_info_prime_x670e_pro_wifi), 597 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ProArt X570-CREATOR WIFI", 598 &board_info_pro_art_x570_creator_wifi), 599 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ProArt X670E-CREATOR WIFI", 600 &board_info_pro_art_x670E_creator_wifi), 601 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ProArt X870E-CREATOR WIFI", 602 &board_info_pro_art_x870E_creator_wifi), 603 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ProArt B550-CREATOR", 604 &board_info_pro_art_b550_creator), 605 DMI_EXACT_MATCH_ASUS_BOARD_NAME("Pro WS X570-ACE", 606 &board_info_pro_ws_x570_ace), 607 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VIII DARK HERO", 608 &board_info_crosshair_viii_dark_hero), 609 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VIII FORMULA", 610 &board_info_crosshair_viii_hero), 611 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VIII HERO", 612 &board_info_crosshair_viii_hero), 613 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VIII HERO (WI-FI)", 614 &board_info_crosshair_viii_hero), 615 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR X670E HERO", 616 &board_info_crosshair_x670e_hero), 617 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR X670E GENE", 618 &board_info_crosshair_x670e_gene), 619 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG MAXIMUS XI HERO", 620 &board_info_maximus_xi_hero), 621 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG MAXIMUS XI HERO (WI-FI)", 622 &board_info_maximus_xi_hero), 623 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG MAXIMUS Z690 FORMULA", 624 &board_info_maximus_z690_formula), 625 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VIII IMPACT", 626 &board_info_crosshair_viii_impact), 627 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX B550-E GAMING", 628 &board_info_strix_b550_e_gaming), 629 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX B550-I GAMING", 630 &board_info_strix_b550_i_gaming), 631 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X570-E GAMING", 632 &board_info_strix_x570_e_gaming), 633 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X570-E GAMING WIFI II", 634 &board_info_strix_x570_e_gaming_wifi_ii), 635 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X570-F GAMING", 636 &board_info_strix_x570_f_gaming), 637 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X570-I GAMING", 638 &board_info_strix_x570_i_gaming), 639 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX Z390-F GAMING", 640 &board_info_strix_z390_f_gaming), 641 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX Z490-F GAMING", 642 &board_info_strix_z490_f_gaming), 643 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX Z690-A GAMING WIFI D4", 644 &board_info_strix_z690_a_gaming_wifi_d4), 645 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG ZENITH II EXTREME", 646 &board_info_zenith_ii_extreme), 647 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG ZENITH II EXTREME ALPHA", 648 &board_info_zenith_ii_extreme), 649 DMI_EXACT_MATCH_ASUS_BOARD_NAME("TUF GAMING X670E-PLUS", 650 &board_info_tuf_gaming_x670e_plus), 651 {}, 652 }; 653 654 struct ec_sensor { 655 unsigned int info_index; 656 s32 cached_value; 657 }; 658 659 struct lock_data { 660 union { 661 acpi_handle aml; 662 /* global lock handle */ 663 u32 glk; 664 } mutex; 665 bool (*lock)(struct lock_data *data); 666 bool (*unlock)(struct lock_data *data); 667 }; 668 669 /* 670 * The next function pairs implement options for locking access to the 671 * state and the EC 672 */ 673 static bool lock_via_acpi_mutex(struct lock_data *data) 674 { 675 /* 676 * ASUS DSDT does not specify that access to the EC has to be guarded, 677 * but firmware does access it via ACPI 678 */ 679 return ACPI_SUCCESS(acpi_acquire_mutex(data->mutex.aml, 680 NULL, ACPI_LOCK_DELAY_MS)); 681 } 682 683 static bool unlock_acpi_mutex(struct lock_data *data) 684 { 685 return ACPI_SUCCESS(acpi_release_mutex(data->mutex.aml, NULL)); 686 } 687 688 static bool lock_via_global_acpi_lock(struct lock_data *data) 689 { 690 return ACPI_SUCCESS(acpi_acquire_global_lock(ACPI_LOCK_DELAY_MS, 691 &data->mutex.glk)); 692 } 693 694 static bool unlock_global_acpi_lock(struct lock_data *data) 695 { 696 return ACPI_SUCCESS(acpi_release_global_lock(data->mutex.glk)); 697 } 698 699 struct ec_sensors_data { 700 const struct ec_board_info *board_info; 701 const struct ec_sensor_info *sensors_info; 702 struct ec_sensor *sensors; 703 /* EC registers to read from */ 704 u16 *registers; 705 u8 *read_buffer; 706 /* sorted list of unique register banks */ 707 u8 banks[ASUS_EC_MAX_BANK + 1]; 708 /* in jiffies */ 709 unsigned long last_updated; 710 struct lock_data lock_data; 711 /* number of board EC sensors */ 712 u8 nr_sensors; 713 /* 714 * number of EC registers to read 715 * (sensor might span more than 1 register) 716 */ 717 u8 nr_registers; 718 /* number of unique register banks */ 719 u8 nr_banks; 720 }; 721 722 static u8 register_bank(u16 reg) 723 { 724 return reg >> 8; 725 } 726 727 static u8 register_index(u16 reg) 728 { 729 return reg & 0x00ff; 730 } 731 732 static bool is_sensor_data_signed(const struct ec_sensor_info *si) 733 { 734 /* 735 * guessed from WMI functions in DSDT code for boards 736 * of the X470 generation 737 */ 738 return si->type == hwmon_temp; 739 } 740 741 static const struct ec_sensor_info * 742 get_sensor_info(const struct ec_sensors_data *state, int index) 743 { 744 return state->sensors_info + state->sensors[index].info_index; 745 } 746 747 static int find_ec_sensor_index(const struct ec_sensors_data *ec, 748 enum hwmon_sensor_types type, int channel) 749 { 750 unsigned int i; 751 752 for (i = 0; i < ec->nr_sensors; i++) { 753 if (get_sensor_info(ec, i)->type == type) { 754 if (channel == 0) 755 return i; 756 channel--; 757 } 758 } 759 return -ENOENT; 760 } 761 762 static int bank_compare(const void *a, const void *b) 763 { 764 return *((const s8 *)a) - *((const s8 *)b); 765 } 766 767 static void setup_sensor_data(struct ec_sensors_data *ec) 768 { 769 struct ec_sensor *s = ec->sensors; 770 bool bank_found; 771 int i, j; 772 u8 bank; 773 774 ec->nr_banks = 0; 775 ec->nr_registers = 0; 776 777 for_each_set_bit(i, &ec->board_info->sensors, 778 BITS_PER_TYPE(ec->board_info->sensors)) { 779 s->info_index = i; 780 s->cached_value = 0; 781 ec->nr_registers += 782 ec->sensors_info[s->info_index].addr.components.size; 783 bank_found = false; 784 bank = ec->sensors_info[s->info_index].addr.components.bank; 785 for (j = 0; j < ec->nr_banks; j++) { 786 if (ec->banks[j] == bank) { 787 bank_found = true; 788 break; 789 } 790 } 791 if (!bank_found) { 792 ec->banks[ec->nr_banks++] = bank; 793 } 794 s++; 795 } 796 sort(ec->banks, ec->nr_banks, 1, bank_compare, NULL); 797 } 798 799 static void fill_ec_registers(struct ec_sensors_data *ec) 800 { 801 const struct ec_sensor_info *si; 802 unsigned int i, j, register_idx = 0; 803 804 for (i = 0; i < ec->nr_sensors; ++i) { 805 si = get_sensor_info(ec, i); 806 for (j = 0; j < si->addr.components.size; ++j, ++register_idx) { 807 ec->registers[register_idx] = 808 (si->addr.components.bank << 8) + 809 si->addr.components.index + j; 810 } 811 } 812 } 813 814 static int setup_lock_data(struct device *dev) 815 { 816 const char *mutex_path; 817 int status; 818 struct ec_sensors_data *state = dev_get_drvdata(dev); 819 820 mutex_path = mutex_path_override ? 821 mutex_path_override : state->board_info->mutex_path; 822 823 if (!mutex_path || !strlen(mutex_path)) { 824 dev_err(dev, "Hardware access guard mutex name is empty"); 825 return -EINVAL; 826 } 827 if (!strcmp(mutex_path, ACPI_GLOBAL_LOCK_PSEUDO_PATH)) { 828 state->lock_data.mutex.glk = 0; 829 state->lock_data.lock = lock_via_global_acpi_lock; 830 state->lock_data.unlock = unlock_global_acpi_lock; 831 } else { 832 status = acpi_get_handle(NULL, (acpi_string)mutex_path, 833 &state->lock_data.mutex.aml); 834 if (ACPI_FAILURE(status)) { 835 dev_err(dev, 836 "Failed to get hardware access guard AML mutex '%s': error %d", 837 mutex_path, status); 838 return -ENOENT; 839 } 840 state->lock_data.lock = lock_via_acpi_mutex; 841 state->lock_data.unlock = unlock_acpi_mutex; 842 } 843 return 0; 844 } 845 846 static int asus_ec_bank_switch(u8 bank, u8 *old) 847 { 848 int status = 0; 849 850 if (old) { 851 status = ec_read(ASUS_EC_BANK_REGISTER, old); 852 } 853 if (status || (old && (*old == bank))) 854 return status; 855 return ec_write(ASUS_EC_BANK_REGISTER, bank); 856 } 857 858 static int asus_ec_block_read(const struct device *dev, 859 struct ec_sensors_data *ec) 860 { 861 int ireg, ibank, status; 862 u8 bank, reg_bank, prev_bank; 863 864 bank = 0; 865 status = asus_ec_bank_switch(bank, &prev_bank); 866 if (status) { 867 dev_warn(dev, "EC bank switch failed"); 868 return status; 869 } 870 871 if (prev_bank) { 872 /* oops... somebody else is working with the EC too */ 873 dev_warn(dev, 874 "Concurrent access to the ACPI EC detected.\nRace condition possible."); 875 } 876 877 /* read registers minimizing bank switches. */ 878 for (ibank = 0; ibank < ec->nr_banks; ibank++) { 879 if (bank != ec->banks[ibank]) { 880 bank = ec->banks[ibank]; 881 if (asus_ec_bank_switch(bank, NULL)) { 882 dev_warn(dev, "EC bank switch to %d failed", 883 bank); 884 break; 885 } 886 } 887 for (ireg = 0; ireg < ec->nr_registers; ireg++) { 888 reg_bank = register_bank(ec->registers[ireg]); 889 if (reg_bank < bank) { 890 continue; 891 } 892 ec_read(register_index(ec->registers[ireg]), 893 ec->read_buffer + ireg); 894 } 895 } 896 897 status = asus_ec_bank_switch(prev_bank, NULL); 898 return status; 899 } 900 901 static inline s32 get_sensor_value(const struct ec_sensor_info *si, u8 *data) 902 { 903 if (is_sensor_data_signed(si)) { 904 switch (si->addr.components.size) { 905 case 1: 906 return (s8)*data; 907 case 2: 908 return (s16)get_unaligned_be16(data); 909 case 4: 910 return (s32)get_unaligned_be32(data); 911 default: 912 return 0; 913 } 914 } else { 915 switch (si->addr.components.size) { 916 case 1: 917 return *data; 918 case 2: 919 return get_unaligned_be16(data); 920 case 4: 921 return get_unaligned_be32(data); 922 default: 923 return 0; 924 } 925 } 926 } 927 928 static void update_sensor_values(struct ec_sensors_data *ec, u8 *data) 929 { 930 const struct ec_sensor_info *si; 931 struct ec_sensor *s, *sensor_end; 932 933 sensor_end = ec->sensors + ec->nr_sensors; 934 for (s = ec->sensors; s != sensor_end; s++) { 935 si = ec->sensors_info + s->info_index; 936 s->cached_value = get_sensor_value(si, data); 937 data += si->addr.components.size; 938 } 939 } 940 941 static int update_ec_sensors(const struct device *dev, 942 struct ec_sensors_data *ec) 943 { 944 int status; 945 946 if (!ec->lock_data.lock(&ec->lock_data)) { 947 dev_warn(dev, "Failed to acquire mutex"); 948 return -EBUSY; 949 } 950 951 status = asus_ec_block_read(dev, ec); 952 953 if (!status) { 954 update_sensor_values(ec, ec->read_buffer); 955 } 956 957 if (!ec->lock_data.unlock(&ec->lock_data)) 958 dev_err(dev, "Failed to release mutex"); 959 960 return status; 961 } 962 963 static long scale_sensor_value(s32 value, int data_type) 964 { 965 switch (data_type) { 966 case hwmon_curr: 967 case hwmon_temp: 968 return value * MILLI; 969 default: 970 return value; 971 } 972 } 973 974 static int get_cached_value_or_update(const struct device *dev, 975 int sensor_index, 976 struct ec_sensors_data *state, s32 *value) 977 { 978 if (time_after(jiffies, state->last_updated + HZ)) { 979 if (update_ec_sensors(dev, state)) { 980 dev_err(dev, "update_ec_sensors() failure\n"); 981 return -EIO; 982 } 983 984 state->last_updated = jiffies; 985 } 986 987 *value = state->sensors[sensor_index].cached_value; 988 return 0; 989 } 990 991 /* 992 * Now follow the functions that implement the hwmon interface 993 */ 994 995 static int asus_ec_hwmon_read(struct device *dev, enum hwmon_sensor_types type, 996 u32 attr, int channel, long *val) 997 { 998 int ret; 999 s32 value = 0; 1000 1001 struct ec_sensors_data *state = dev_get_drvdata(dev); 1002 int sidx = find_ec_sensor_index(state, type, channel); 1003 1004 if (sidx < 0) { 1005 return sidx; 1006 } 1007 1008 ret = get_cached_value_or_update(dev, sidx, state, &value); 1009 if (!ret) { 1010 *val = scale_sensor_value(value, 1011 get_sensor_info(state, sidx)->type); 1012 } 1013 1014 return ret; 1015 } 1016 1017 static int asus_ec_hwmon_read_string(struct device *dev, 1018 enum hwmon_sensor_types type, u32 attr, 1019 int channel, const char **str) 1020 { 1021 struct ec_sensors_data *state = dev_get_drvdata(dev); 1022 int sensor_index = find_ec_sensor_index(state, type, channel); 1023 1024 if (sensor_index < 0) 1025 return sensor_index; 1026 1027 *str = get_sensor_info(state, sensor_index)->label; 1028 1029 return 0; 1030 } 1031 1032 static umode_t asus_ec_hwmon_is_visible(const void *drvdata, 1033 enum hwmon_sensor_types type, u32 attr, 1034 int channel) 1035 { 1036 const struct ec_sensors_data *state = drvdata; 1037 1038 return find_ec_sensor_index(state, type, channel) >= 0 ? S_IRUGO : 0; 1039 } 1040 1041 static int 1042 asus_ec_hwmon_add_chan_info(struct hwmon_channel_info *asus_ec_hwmon_chan, 1043 struct device *dev, int num, 1044 enum hwmon_sensor_types type, u32 config) 1045 { 1046 int i; 1047 u32 *cfg = devm_kcalloc(dev, num + 1, sizeof(*cfg), GFP_KERNEL); 1048 1049 if (!cfg) 1050 return -ENOMEM; 1051 1052 asus_ec_hwmon_chan->type = type; 1053 asus_ec_hwmon_chan->config = cfg; 1054 for (i = 0; i < num; i++, cfg++) 1055 *cfg = config; 1056 1057 return 0; 1058 } 1059 1060 static const struct hwmon_ops asus_ec_hwmon_ops = { 1061 .is_visible = asus_ec_hwmon_is_visible, 1062 .read = asus_ec_hwmon_read, 1063 .read_string = asus_ec_hwmon_read_string, 1064 }; 1065 1066 static struct hwmon_chip_info asus_ec_chip_info = { 1067 .ops = &asus_ec_hwmon_ops, 1068 }; 1069 1070 static const struct ec_board_info *get_board_info(void) 1071 { 1072 const struct dmi_system_id *dmi_entry; 1073 1074 dmi_entry = dmi_first_match(dmi_table); 1075 return dmi_entry ? dmi_entry->driver_data : NULL; 1076 } 1077 1078 static int asus_ec_probe(struct platform_device *pdev) 1079 { 1080 const struct hwmon_channel_info **ptr_asus_ec_ci; 1081 int nr_count[hwmon_max] = { 0 }, nr_types = 0; 1082 struct hwmon_channel_info *asus_ec_hwmon_chan; 1083 const struct ec_board_info *pboard_info; 1084 const struct hwmon_chip_info *chip_info; 1085 struct device *dev = &pdev->dev; 1086 struct ec_sensors_data *ec_data; 1087 const struct ec_sensor_info *si; 1088 enum hwmon_sensor_types type; 1089 struct device *hwdev; 1090 unsigned int i; 1091 int status; 1092 1093 pboard_info = get_board_info(); 1094 if (!pboard_info) 1095 return -ENODEV; 1096 1097 ec_data = devm_kzalloc(dev, sizeof(struct ec_sensors_data), 1098 GFP_KERNEL); 1099 if (!ec_data) 1100 return -ENOMEM; 1101 1102 dev_set_drvdata(dev, ec_data); 1103 ec_data->board_info = pboard_info; 1104 1105 switch (ec_data->board_info->family) { 1106 case family_amd_400_series: 1107 ec_data->sensors_info = sensors_family_amd_400; 1108 break; 1109 case family_amd_500_series: 1110 ec_data->sensors_info = sensors_family_amd_500; 1111 break; 1112 case family_amd_600_series: 1113 ec_data->sensors_info = sensors_family_amd_600; 1114 break; 1115 case family_amd_800_series: 1116 ec_data->sensors_info = sensors_family_amd_800; 1117 break; 1118 case family_intel_300_series: 1119 ec_data->sensors_info = sensors_family_intel_300; 1120 break; 1121 case family_intel_400_series: 1122 ec_data->sensors_info = sensors_family_intel_400; 1123 break; 1124 case family_intel_600_series: 1125 ec_data->sensors_info = sensors_family_intel_600; 1126 break; 1127 default: 1128 dev_err(dev, "Unknown board family: %d", 1129 ec_data->board_info->family); 1130 return -EINVAL; 1131 } 1132 1133 ec_data->nr_sensors = hweight_long(ec_data->board_info->sensors); 1134 ec_data->sensors = devm_kcalloc(dev, ec_data->nr_sensors, 1135 sizeof(struct ec_sensor), GFP_KERNEL); 1136 if (!ec_data->sensors) 1137 return -ENOMEM; 1138 1139 status = setup_lock_data(dev); 1140 if (status) { 1141 dev_err(dev, "Failed to setup state/EC locking: %d", status); 1142 return status; 1143 } 1144 1145 setup_sensor_data(ec_data); 1146 ec_data->registers = devm_kcalloc(dev, ec_data->nr_registers, 1147 sizeof(u16), GFP_KERNEL); 1148 ec_data->read_buffer = devm_kcalloc(dev, ec_data->nr_registers, 1149 sizeof(u8), GFP_KERNEL); 1150 1151 if (!ec_data->registers || !ec_data->read_buffer) 1152 return -ENOMEM; 1153 1154 fill_ec_registers(ec_data); 1155 1156 for (i = 0; i < ec_data->nr_sensors; ++i) { 1157 si = get_sensor_info(ec_data, i); 1158 if (!nr_count[si->type]) 1159 ++nr_types; 1160 ++nr_count[si->type]; 1161 } 1162 1163 if (nr_count[hwmon_temp]) 1164 nr_count[hwmon_chip]++, nr_types++; 1165 1166 asus_ec_hwmon_chan = devm_kcalloc( 1167 dev, nr_types, sizeof(*asus_ec_hwmon_chan), GFP_KERNEL); 1168 if (!asus_ec_hwmon_chan) 1169 return -ENOMEM; 1170 1171 ptr_asus_ec_ci = devm_kcalloc(dev, nr_types + 1, 1172 sizeof(*ptr_asus_ec_ci), GFP_KERNEL); 1173 if (!ptr_asus_ec_ci) 1174 return -ENOMEM; 1175 1176 asus_ec_chip_info.info = ptr_asus_ec_ci; 1177 chip_info = &asus_ec_chip_info; 1178 1179 for (type = 0; type < hwmon_max; ++type) { 1180 if (!nr_count[type]) 1181 continue; 1182 1183 asus_ec_hwmon_add_chan_info(asus_ec_hwmon_chan, dev, 1184 nr_count[type], type, 1185 hwmon_attributes[type]); 1186 *ptr_asus_ec_ci++ = asus_ec_hwmon_chan++; 1187 } 1188 1189 dev_info(dev, "board has %d EC sensors that span %d registers", 1190 ec_data->nr_sensors, ec_data->nr_registers); 1191 1192 hwdev = devm_hwmon_device_register_with_info(dev, "asusec", 1193 ec_data, chip_info, NULL); 1194 1195 return PTR_ERR_OR_ZERO(hwdev); 1196 } 1197 1198 MODULE_DEVICE_TABLE(dmi, dmi_table); 1199 1200 static struct platform_driver asus_ec_sensors_platform_driver = { 1201 .driver = { 1202 .name = "asus-ec-sensors", 1203 }, 1204 .probe = asus_ec_probe, 1205 }; 1206 1207 static struct platform_device *asus_ec_sensors_platform_device; 1208 1209 static int __init asus_ec_init(void) 1210 { 1211 asus_ec_sensors_platform_device = 1212 platform_create_bundle(&asus_ec_sensors_platform_driver, 1213 asus_ec_probe, NULL, 0, NULL, 0); 1214 1215 if (IS_ERR(asus_ec_sensors_platform_device)) 1216 return PTR_ERR(asus_ec_sensors_platform_device); 1217 1218 return 0; 1219 } 1220 1221 static void __exit asus_ec_exit(void) 1222 { 1223 platform_device_unregister(asus_ec_sensors_platform_device); 1224 platform_driver_unregister(&asus_ec_sensors_platform_driver); 1225 } 1226 1227 module_init(asus_ec_init); 1228 module_exit(asus_ec_exit); 1229 1230 module_param_named(mutex_path, mutex_path_override, charp, 0); 1231 MODULE_PARM_DESC(mutex_path, 1232 "Override ACPI mutex path used to guard access to hardware"); 1233 1234 MODULE_AUTHOR("Eugene Shalygin <eugene.shalygin@gmail.com>"); 1235 MODULE_DESCRIPTION( 1236 "HWMON driver for sensors accessible via ACPI EC in ASUS motherboards"); 1237 MODULE_LICENSE("GPL"); 1238