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