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 <asm/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 MAX_IDENTICAL_BOARD_VARIATIONS 2 58 59 /* Moniker for the ACPI global lock (':' is not allowed in ASL identifiers) */ 60 #define ACPI_GLOBAL_LOCK_PSEUDO_PATH ":GLOBAL_LOCK" 61 62 typedef union { 63 u32 value; 64 struct { 65 u8 index; 66 u8 bank; 67 u8 size; 68 u8 dummy; 69 } components; 70 } sensor_address; 71 72 #define MAKE_SENSOR_ADDRESS(size, bank, index) { \ 73 .value = (size << 16) + (bank << 8) + index \ 74 } 75 76 static u32 hwmon_attributes[hwmon_max] = { 77 [hwmon_chip] = HWMON_C_REGISTER_TZ, 78 [hwmon_temp] = HWMON_T_INPUT | HWMON_T_LABEL, 79 [hwmon_in] = HWMON_I_INPUT | HWMON_I_LABEL, 80 [hwmon_curr] = HWMON_C_INPUT | HWMON_C_LABEL, 81 [hwmon_fan] = HWMON_F_INPUT | HWMON_F_LABEL, 82 }; 83 84 struct ec_sensor_info { 85 char label[SENSOR_LABEL_LEN]; 86 enum hwmon_sensor_types type; 87 sensor_address addr; 88 }; 89 90 #define EC_SENSOR(sensor_label, sensor_type, size, bank, index) { \ 91 .label = sensor_label, .type = sensor_type, \ 92 .addr = MAKE_SENSOR_ADDRESS(size, bank, index), \ 93 } 94 95 enum ec_sensors { 96 /* chipset temperature [℃] */ 97 ec_sensor_temp_chipset, 98 /* CPU temperature [℃] */ 99 ec_sensor_temp_cpu, 100 /* motherboard temperature [℃] */ 101 ec_sensor_temp_mb, 102 /* "T_Sensor" temperature sensor reading [℃] */ 103 ec_sensor_temp_t_sensor, 104 /* VRM temperature [℃] */ 105 ec_sensor_temp_vrm, 106 /* CPU Core voltage [mV] */ 107 ec_sensor_in_cpu_core, 108 /* CPU_Opt fan [RPM] */ 109 ec_sensor_fan_cpu_opt, 110 /* VRM heat sink fan [RPM] */ 111 ec_sensor_fan_vrm_hs, 112 /* Chipset fan [RPM] */ 113 ec_sensor_fan_chipset, 114 /* Water flow sensor reading [RPM] */ 115 ec_sensor_fan_water_flow, 116 /* CPU current [A] */ 117 ec_sensor_curr_cpu, 118 /* "Water_In" temperature sensor reading [℃] */ 119 ec_sensor_temp_water_in, 120 /* "Water_Out" temperature sensor reading [℃] */ 121 ec_sensor_temp_water_out, 122 }; 123 124 #define SENSOR_TEMP_CHIPSET BIT(ec_sensor_temp_chipset) 125 #define SENSOR_TEMP_CPU BIT(ec_sensor_temp_cpu) 126 #define SENSOR_TEMP_MB BIT(ec_sensor_temp_mb) 127 #define SENSOR_TEMP_T_SENSOR BIT(ec_sensor_temp_t_sensor) 128 #define SENSOR_TEMP_VRM BIT(ec_sensor_temp_vrm) 129 #define SENSOR_IN_CPU_CORE BIT(ec_sensor_in_cpu_core) 130 #define SENSOR_FAN_CPU_OPT BIT(ec_sensor_fan_cpu_opt) 131 #define SENSOR_FAN_VRM_HS BIT(ec_sensor_fan_vrm_hs) 132 #define SENSOR_FAN_CHIPSET BIT(ec_sensor_fan_chipset) 133 #define SENSOR_FAN_WATER_FLOW BIT(ec_sensor_fan_water_flow) 134 #define SENSOR_CURR_CPU BIT(ec_sensor_curr_cpu) 135 #define SENSOR_TEMP_WATER_IN BIT(ec_sensor_temp_water_in) 136 #define SENSOR_TEMP_WATER_OUT BIT(ec_sensor_temp_water_out) 137 138 enum board_family { 139 family_unknown, 140 family_amd_400_series, 141 family_amd_500_series, 142 }; 143 144 /* All the known sensors for ASUS EC controllers */ 145 static const struct ec_sensor_info sensors_family_amd_400[] = { 146 [ec_sensor_temp_chipset] = 147 EC_SENSOR("Chipset", hwmon_temp, 1, 0x00, 0x3a), 148 [ec_sensor_temp_cpu] = 149 EC_SENSOR("CPU", hwmon_temp, 1, 0x00, 0x3b), 150 [ec_sensor_temp_mb] = 151 EC_SENSOR("Motherboard", hwmon_temp, 1, 0x00, 0x3c), 152 [ec_sensor_temp_t_sensor] = 153 EC_SENSOR("T_Sensor", hwmon_temp, 1, 0x00, 0x3d), 154 [ec_sensor_temp_vrm] = 155 EC_SENSOR("VRM", hwmon_temp, 1, 0x00, 0x3e), 156 [ec_sensor_in_cpu_core] = 157 EC_SENSOR("CPU Core", hwmon_in, 2, 0x00, 0xa2), 158 [ec_sensor_fan_cpu_opt] = 159 EC_SENSOR("CPU_Opt", hwmon_fan, 2, 0x00, 0xbc), 160 [ec_sensor_fan_vrm_hs] = 161 EC_SENSOR("VRM HS", hwmon_fan, 2, 0x00, 0xb2), 162 [ec_sensor_fan_chipset] = 163 /* no chipset fans in this generation */ 164 EC_SENSOR("Chipset", hwmon_fan, 0, 0x00, 0x00), 165 [ec_sensor_fan_water_flow] = 166 EC_SENSOR("Water_Flow", hwmon_fan, 2, 0x00, 0xb4), 167 [ec_sensor_curr_cpu] = 168 EC_SENSOR("CPU", hwmon_curr, 1, 0x00, 0xf4), 169 [ec_sensor_temp_water_in] = 170 EC_SENSOR("Water_In", hwmon_temp, 1, 0x01, 0x0d), 171 [ec_sensor_temp_water_out] = 172 EC_SENSOR("Water_Out", hwmon_temp, 1, 0x01, 0x0b), 173 }; 174 175 static const struct ec_sensor_info sensors_family_amd_500[] = { 176 [ec_sensor_temp_chipset] = 177 EC_SENSOR("Chipset", hwmon_temp, 1, 0x00, 0x3a), 178 [ec_sensor_temp_cpu] = EC_SENSOR("CPU", hwmon_temp, 1, 0x00, 0x3b), 179 [ec_sensor_temp_mb] = 180 EC_SENSOR("Motherboard", hwmon_temp, 1, 0x00, 0x3c), 181 [ec_sensor_temp_t_sensor] = 182 EC_SENSOR("T_Sensor", hwmon_temp, 1, 0x00, 0x3d), 183 [ec_sensor_temp_vrm] = EC_SENSOR("VRM", hwmon_temp, 1, 0x00, 0x3e), 184 [ec_sensor_in_cpu_core] = 185 EC_SENSOR("CPU Core", hwmon_in, 2, 0x00, 0xa2), 186 [ec_sensor_fan_cpu_opt] = 187 EC_SENSOR("CPU_Opt", hwmon_fan, 2, 0x00, 0xb0), 188 [ec_sensor_fan_vrm_hs] = EC_SENSOR("VRM HS", hwmon_fan, 2, 0x00, 0xb2), 189 [ec_sensor_fan_chipset] = 190 EC_SENSOR("Chipset", hwmon_fan, 2, 0x00, 0xb4), 191 [ec_sensor_fan_water_flow] = 192 EC_SENSOR("Water_Flow", hwmon_fan, 2, 0x00, 0xbc), 193 [ec_sensor_curr_cpu] = EC_SENSOR("CPU", hwmon_curr, 1, 0x00, 0xf4), 194 [ec_sensor_temp_water_in] = 195 EC_SENSOR("Water_In", hwmon_temp, 1, 0x01, 0x00), 196 [ec_sensor_temp_water_out] = 197 EC_SENSOR("Water_Out", hwmon_temp, 1, 0x01, 0x01), 198 }; 199 200 /* Shortcuts for common combinations */ 201 #define SENSOR_SET_TEMP_CHIPSET_CPU_MB \ 202 (SENSOR_TEMP_CHIPSET | SENSOR_TEMP_CPU | SENSOR_TEMP_MB) 203 #define SENSOR_SET_TEMP_WATER (SENSOR_TEMP_WATER_IN | SENSOR_TEMP_WATER_OUT) 204 205 struct ec_board_info { 206 const char *board_names[MAX_IDENTICAL_BOARD_VARIATIONS]; 207 unsigned long sensors; 208 /* 209 * Defines which mutex to use for guarding access to the state and the 210 * hardware. Can be either a full path to an AML mutex or the 211 * pseudo-path ACPI_GLOBAL_LOCK_PSEUDO_PATH to use the global ACPI lock, 212 * or left empty to use a regular mutex object, in which case access to 213 * the hardware is not guarded. 214 */ 215 const char *mutex_path; 216 enum board_family family; 217 }; 218 219 static const struct ec_board_info board_info[] = { 220 { 221 .board_names = {"PRIME X470-PRO"}, 222 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 223 SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | 224 SENSOR_FAN_CPU_OPT | 225 SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, 226 .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH, 227 .family = family_amd_400_series, 228 }, 229 { 230 .board_names = {"PRIME X570-PRO"}, 231 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM | 232 SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET, 233 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 234 .family = family_amd_500_series, 235 }, 236 { 237 .board_names = {"ProArt X570-CREATOR WIFI"}, 238 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM | 239 SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CPU_OPT | 240 SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, 241 }, 242 { 243 .board_names = {"Pro WS X570-ACE"}, 244 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM | 245 SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET | 246 SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, 247 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 248 .family = family_amd_500_series, 249 }, 250 { 251 .board_names = {"ROG CROSSHAIR VIII DARK HERO"}, 252 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 253 SENSOR_TEMP_T_SENSOR | 254 SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER | 255 SENSOR_FAN_CPU_OPT | SENSOR_FAN_WATER_FLOW | 256 SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, 257 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 258 .family = family_amd_500_series, 259 }, 260 { 261 .board_names = {"ROG CROSSHAIR VIII FORMULA"}, 262 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 263 SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | 264 SENSOR_FAN_CPU_OPT | SENSOR_FAN_CHIPSET | 265 SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, 266 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 267 .family = family_amd_500_series, 268 }, 269 { 270 .board_names = { 271 "ROG CROSSHAIR VIII HERO", 272 "ROG CROSSHAIR VIII HERO (WI-FI)", 273 }, 274 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 275 SENSOR_TEMP_T_SENSOR | 276 SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER | 277 SENSOR_FAN_CPU_OPT | SENSOR_FAN_CHIPSET | 278 SENSOR_FAN_WATER_FLOW | SENSOR_CURR_CPU | 279 SENSOR_IN_CPU_CORE, 280 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 281 .family = family_amd_500_series, 282 }, 283 { 284 .board_names = {"ROG CROSSHAIR VIII IMPACT"}, 285 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 286 SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | 287 SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU | 288 SENSOR_IN_CPU_CORE, 289 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 290 .family = family_amd_500_series, 291 }, 292 { 293 .board_names = {"ROG STRIX B550-E GAMING"}, 294 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 295 SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | 296 SENSOR_FAN_CPU_OPT, 297 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 298 .family = family_amd_500_series, 299 }, 300 { 301 .board_names = {"ROG STRIX B550-I GAMING"}, 302 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 303 SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | 304 SENSOR_FAN_VRM_HS | SENSOR_CURR_CPU | 305 SENSOR_IN_CPU_CORE, 306 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 307 .family = family_amd_500_series, 308 }, 309 { 310 .board_names = {"ROG STRIX X570-E GAMING"}, 311 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 312 SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | 313 SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU | 314 SENSOR_IN_CPU_CORE, 315 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 316 .family = family_amd_500_series, 317 }, 318 { 319 .board_names = {"ROG STRIX X570-E GAMING WIFI II"}, 320 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 321 SENSOR_TEMP_T_SENSOR | SENSOR_CURR_CPU | 322 SENSOR_IN_CPU_CORE, 323 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 324 .family = family_amd_500_series, 325 }, 326 { 327 .board_names = {"ROG STRIX X570-F GAMING"}, 328 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | 329 SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET, 330 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 331 .family = family_amd_500_series, 332 }, 333 { 334 .board_names = {"ROG STRIX X570-I GAMING"}, 335 .sensors = SENSOR_TEMP_T_SENSOR | SENSOR_FAN_VRM_HS | 336 SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU | 337 SENSOR_IN_CPU_CORE, 338 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, 339 .family = family_amd_500_series, 340 }, 341 {} 342 }; 343 344 struct ec_sensor { 345 unsigned int info_index; 346 s32 cached_value; 347 }; 348 349 struct lock_data { 350 union { 351 acpi_handle aml; 352 /* global lock handle */ 353 u32 glk; 354 } mutex; 355 bool (*lock)(struct lock_data *data); 356 bool (*unlock)(struct lock_data *data); 357 }; 358 359 /* 360 * The next function pairs implement options for locking access to the 361 * state and the EC 362 */ 363 static bool lock_via_acpi_mutex(struct lock_data *data) 364 { 365 /* 366 * ASUS DSDT does not specify that access to the EC has to be guarded, 367 * but firmware does access it via ACPI 368 */ 369 return ACPI_SUCCESS(acpi_acquire_mutex(data->mutex.aml, 370 NULL, ACPI_LOCK_DELAY_MS)); 371 } 372 373 static bool unlock_acpi_mutex(struct lock_data *data) 374 { 375 return ACPI_SUCCESS(acpi_release_mutex(data->mutex.aml, NULL)); 376 } 377 378 static bool lock_via_global_acpi_lock(struct lock_data *data) 379 { 380 return ACPI_SUCCESS(acpi_acquire_global_lock(ACPI_LOCK_DELAY_MS, 381 &data->mutex.glk)); 382 } 383 384 static bool unlock_global_acpi_lock(struct lock_data *data) 385 { 386 return ACPI_SUCCESS(acpi_release_global_lock(data->mutex.glk)); 387 } 388 389 struct ec_sensors_data { 390 const struct ec_board_info *board_info; 391 const struct ec_sensor_info *sensors_info; 392 struct ec_sensor *sensors; 393 /* EC registers to read from */ 394 u16 *registers; 395 u8 *read_buffer; 396 /* sorted list of unique register banks */ 397 u8 banks[ASUS_EC_MAX_BANK + 1]; 398 /* in jiffies */ 399 unsigned long last_updated; 400 struct lock_data lock_data; 401 /* number of board EC sensors */ 402 u8 nr_sensors; 403 /* 404 * number of EC registers to read 405 * (sensor might span more than 1 register) 406 */ 407 u8 nr_registers; 408 /* number of unique register banks */ 409 u8 nr_banks; 410 }; 411 412 static u8 register_bank(u16 reg) 413 { 414 return reg >> 8; 415 } 416 417 static u8 register_index(u16 reg) 418 { 419 return reg & 0x00ff; 420 } 421 422 static bool is_sensor_data_signed(const struct ec_sensor_info *si) 423 { 424 /* 425 * guessed from WMI functions in DSDT code for boards 426 * of the X470 generation 427 */ 428 return si->type == hwmon_temp; 429 } 430 431 static const struct ec_sensor_info * 432 get_sensor_info(const struct ec_sensors_data *state, int index) 433 { 434 return state->sensors_info + state->sensors[index].info_index; 435 } 436 437 static int find_ec_sensor_index(const struct ec_sensors_data *ec, 438 enum hwmon_sensor_types type, int channel) 439 { 440 unsigned int i; 441 442 for (i = 0; i < ec->nr_sensors; i++) { 443 if (get_sensor_info(ec, i)->type == type) { 444 if (channel == 0) 445 return i; 446 channel--; 447 } 448 } 449 return -ENOENT; 450 } 451 452 static int __init bank_compare(const void *a, const void *b) 453 { 454 return *((const s8 *)a) - *((const s8 *)b); 455 } 456 457 static void __init setup_sensor_data(struct ec_sensors_data *ec) 458 { 459 struct ec_sensor *s = ec->sensors; 460 bool bank_found; 461 int i, j; 462 u8 bank; 463 464 ec->nr_banks = 0; 465 ec->nr_registers = 0; 466 467 for_each_set_bit(i, &ec->board_info->sensors, 468 BITS_PER_TYPE(ec->board_info->sensors)) { 469 s->info_index = i; 470 s->cached_value = 0; 471 ec->nr_registers += 472 ec->sensors_info[s->info_index].addr.components.size; 473 bank_found = false; 474 bank = ec->sensors_info[s->info_index].addr.components.bank; 475 for (j = 0; j < ec->nr_banks; j++) { 476 if (ec->banks[j] == bank) { 477 bank_found = true; 478 break; 479 } 480 } 481 if (!bank_found) { 482 ec->banks[ec->nr_banks++] = bank; 483 } 484 s++; 485 } 486 sort(ec->banks, ec->nr_banks, 1, bank_compare, NULL); 487 } 488 489 static void __init fill_ec_registers(struct ec_sensors_data *ec) 490 { 491 const struct ec_sensor_info *si; 492 unsigned int i, j, register_idx = 0; 493 494 for (i = 0; i < ec->nr_sensors; ++i) { 495 si = get_sensor_info(ec, i); 496 for (j = 0; j < si->addr.components.size; ++j, ++register_idx) { 497 ec->registers[register_idx] = 498 (si->addr.components.bank << 8) + 499 si->addr.components.index + j; 500 } 501 } 502 } 503 504 static int __init setup_lock_data(struct device *dev) 505 { 506 const char *mutex_path; 507 int status; 508 struct ec_sensors_data *state = dev_get_drvdata(dev); 509 510 mutex_path = mutex_path_override ? 511 mutex_path_override : state->board_info->mutex_path; 512 513 if (!mutex_path || !strlen(mutex_path)) { 514 dev_err(dev, "Hardware access guard mutex name is empty"); 515 return -EINVAL; 516 } 517 if (!strcmp(mutex_path, ACPI_GLOBAL_LOCK_PSEUDO_PATH)) { 518 state->lock_data.mutex.glk = 0; 519 state->lock_data.lock = lock_via_global_acpi_lock; 520 state->lock_data.unlock = unlock_global_acpi_lock; 521 } else { 522 status = acpi_get_handle(NULL, (acpi_string)mutex_path, 523 &state->lock_data.mutex.aml); 524 if (ACPI_FAILURE(status)) { 525 dev_err(dev, 526 "Failed to get hardware access guard AML mutex '%s': error %d", 527 mutex_path, status); 528 return -ENOENT; 529 } 530 state->lock_data.lock = lock_via_acpi_mutex; 531 state->lock_data.unlock = unlock_acpi_mutex; 532 } 533 return 0; 534 } 535 536 static int asus_ec_bank_switch(u8 bank, u8 *old) 537 { 538 int status = 0; 539 540 if (old) { 541 status = ec_read(ASUS_EC_BANK_REGISTER, old); 542 } 543 if (status || (old && (*old == bank))) 544 return status; 545 return ec_write(ASUS_EC_BANK_REGISTER, bank); 546 } 547 548 static int asus_ec_block_read(const struct device *dev, 549 struct ec_sensors_data *ec) 550 { 551 int ireg, ibank, status; 552 u8 bank, reg_bank, prev_bank; 553 554 bank = 0; 555 status = asus_ec_bank_switch(bank, &prev_bank); 556 if (status) { 557 dev_warn(dev, "EC bank switch failed"); 558 return status; 559 } 560 561 if (prev_bank) { 562 /* oops... somebody else is working with the EC too */ 563 dev_warn(dev, 564 "Concurrent access to the ACPI EC detected.\nRace condition possible."); 565 } 566 567 /* read registers minimizing bank switches. */ 568 for (ibank = 0; ibank < ec->nr_banks; ibank++) { 569 if (bank != ec->banks[ibank]) { 570 bank = ec->banks[ibank]; 571 if (asus_ec_bank_switch(bank, NULL)) { 572 dev_warn(dev, "EC bank switch to %d failed", 573 bank); 574 break; 575 } 576 } 577 for (ireg = 0; ireg < ec->nr_registers; ireg++) { 578 reg_bank = register_bank(ec->registers[ireg]); 579 if (reg_bank < bank) { 580 continue; 581 } 582 ec_read(register_index(ec->registers[ireg]), 583 ec->read_buffer + ireg); 584 } 585 } 586 587 status = asus_ec_bank_switch(prev_bank, NULL); 588 return status; 589 } 590 591 static inline s32 get_sensor_value(const struct ec_sensor_info *si, u8 *data) 592 { 593 if (is_sensor_data_signed(si)) { 594 switch (si->addr.components.size) { 595 case 1: 596 return (s8)*data; 597 case 2: 598 return (s16)get_unaligned_be16(data); 599 case 4: 600 return (s32)get_unaligned_be32(data); 601 default: 602 return 0; 603 } 604 } else { 605 switch (si->addr.components.size) { 606 case 1: 607 return *data; 608 case 2: 609 return get_unaligned_be16(data); 610 case 4: 611 return get_unaligned_be32(data); 612 default: 613 return 0; 614 } 615 } 616 } 617 618 static void update_sensor_values(struct ec_sensors_data *ec, u8 *data) 619 { 620 const struct ec_sensor_info *si; 621 struct ec_sensor *s, *sensor_end; 622 623 sensor_end = ec->sensors + ec->nr_sensors; 624 for (s = ec->sensors; s != sensor_end; s++) { 625 si = ec->sensors_info + s->info_index; 626 s->cached_value = get_sensor_value(si, data); 627 data += si->addr.components.size; 628 } 629 } 630 631 static int update_ec_sensors(const struct device *dev, 632 struct ec_sensors_data *ec) 633 { 634 int status; 635 636 if (!ec->lock_data.lock(&ec->lock_data)) { 637 dev_warn(dev, "Failed to acquire mutex"); 638 return -EBUSY; 639 } 640 641 status = asus_ec_block_read(dev, ec); 642 643 if (!status) { 644 update_sensor_values(ec, ec->read_buffer); 645 } 646 647 if (!ec->lock_data.unlock(&ec->lock_data)) 648 dev_err(dev, "Failed to release mutex"); 649 650 return status; 651 } 652 653 static long scale_sensor_value(s32 value, int data_type) 654 { 655 switch (data_type) { 656 case hwmon_curr: 657 case hwmon_temp: 658 return value * MILLI; 659 default: 660 return value; 661 } 662 } 663 664 static int get_cached_value_or_update(const struct device *dev, 665 int sensor_index, 666 struct ec_sensors_data *state, s32 *value) 667 { 668 if (time_after(jiffies, state->last_updated + HZ)) { 669 if (update_ec_sensors(dev, state)) { 670 dev_err(dev, "update_ec_sensors() failure\n"); 671 return -EIO; 672 } 673 674 state->last_updated = jiffies; 675 } 676 677 *value = state->sensors[sensor_index].cached_value; 678 return 0; 679 } 680 681 /* 682 * Now follow the functions that implement the hwmon interface 683 */ 684 685 static int asus_ec_hwmon_read(struct device *dev, enum hwmon_sensor_types type, 686 u32 attr, int channel, long *val) 687 { 688 int ret; 689 s32 value = 0; 690 691 struct ec_sensors_data *state = dev_get_drvdata(dev); 692 int sidx = find_ec_sensor_index(state, type, channel); 693 694 if (sidx < 0) { 695 return sidx; 696 } 697 698 ret = get_cached_value_or_update(dev, sidx, state, &value); 699 if (!ret) { 700 *val = scale_sensor_value(value, 701 get_sensor_info(state, sidx)->type); 702 } 703 704 return ret; 705 } 706 707 static int asus_ec_hwmon_read_string(struct device *dev, 708 enum hwmon_sensor_types type, u32 attr, 709 int channel, const char **str) 710 { 711 struct ec_sensors_data *state = dev_get_drvdata(dev); 712 int sensor_index = find_ec_sensor_index(state, type, channel); 713 *str = get_sensor_info(state, sensor_index)->label; 714 715 return 0; 716 } 717 718 static umode_t asus_ec_hwmon_is_visible(const void *drvdata, 719 enum hwmon_sensor_types type, u32 attr, 720 int channel) 721 { 722 const struct ec_sensors_data *state = drvdata; 723 724 return find_ec_sensor_index(state, type, channel) >= 0 ? S_IRUGO : 0; 725 } 726 727 static int __init 728 asus_ec_hwmon_add_chan_info(struct hwmon_channel_info *asus_ec_hwmon_chan, 729 struct device *dev, int num, 730 enum hwmon_sensor_types type, u32 config) 731 { 732 int i; 733 u32 *cfg = devm_kcalloc(dev, num + 1, sizeof(*cfg), GFP_KERNEL); 734 735 if (!cfg) 736 return -ENOMEM; 737 738 asus_ec_hwmon_chan->type = type; 739 asus_ec_hwmon_chan->config = cfg; 740 for (i = 0; i < num; i++, cfg++) 741 *cfg = config; 742 743 return 0; 744 } 745 746 static const struct hwmon_ops asus_ec_hwmon_ops = { 747 .is_visible = asus_ec_hwmon_is_visible, 748 .read = asus_ec_hwmon_read, 749 .read_string = asus_ec_hwmon_read_string, 750 }; 751 752 static struct hwmon_chip_info asus_ec_chip_info = { 753 .ops = &asus_ec_hwmon_ops, 754 }; 755 756 static const struct ec_board_info * __init get_board_info(void) 757 { 758 const char *dmi_board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR); 759 const char *dmi_board_name = dmi_get_system_info(DMI_BOARD_NAME); 760 const struct ec_board_info *board; 761 762 if (!dmi_board_vendor || !dmi_board_name || 763 strcasecmp(dmi_board_vendor, "ASUSTeK COMPUTER INC.")) 764 return NULL; 765 766 for (board = board_info; board->sensors; board++) { 767 if (match_string(board->board_names, 768 MAX_IDENTICAL_BOARD_VARIATIONS, 769 dmi_board_name) >= 0) 770 return board; 771 } 772 773 return NULL; 774 } 775 776 static int __init asus_ec_probe(struct platform_device *pdev) 777 { 778 const struct hwmon_channel_info **ptr_asus_ec_ci; 779 int nr_count[hwmon_max] = { 0 }, nr_types = 0; 780 struct hwmon_channel_info *asus_ec_hwmon_chan; 781 const struct ec_board_info *pboard_info; 782 const struct hwmon_chip_info *chip_info; 783 struct device *dev = &pdev->dev; 784 struct ec_sensors_data *ec_data; 785 const struct ec_sensor_info *si; 786 enum hwmon_sensor_types type; 787 struct device *hwdev; 788 unsigned int i; 789 int status; 790 791 pboard_info = get_board_info(); 792 if (!pboard_info) 793 return -ENODEV; 794 795 ec_data = devm_kzalloc(dev, sizeof(struct ec_sensors_data), 796 GFP_KERNEL); 797 if (!ec_data) 798 return -ENOMEM; 799 800 dev_set_drvdata(dev, ec_data); 801 ec_data->board_info = pboard_info; 802 803 switch (ec_data->board_info->family) { 804 case family_amd_400_series: 805 ec_data->sensors_info = sensors_family_amd_400; 806 break; 807 case family_amd_500_series: 808 ec_data->sensors_info = sensors_family_amd_500; 809 break; 810 default: 811 dev_err(dev, "Unknown board family: %d", 812 ec_data->board_info->family); 813 return -EINVAL; 814 } 815 816 ec_data->nr_sensors = hweight_long(ec_data->board_info->sensors); 817 ec_data->sensors = devm_kcalloc(dev, ec_data->nr_sensors, 818 sizeof(struct ec_sensor), GFP_KERNEL); 819 820 status = setup_lock_data(dev); 821 if (status) { 822 dev_err(dev, "Failed to setup state/EC locking: %d", status); 823 return status; 824 } 825 826 setup_sensor_data(ec_data); 827 ec_data->registers = devm_kcalloc(dev, ec_data->nr_registers, 828 sizeof(u16), GFP_KERNEL); 829 ec_data->read_buffer = devm_kcalloc(dev, ec_data->nr_registers, 830 sizeof(u8), GFP_KERNEL); 831 832 if (!ec_data->registers || !ec_data->read_buffer) 833 return -ENOMEM; 834 835 fill_ec_registers(ec_data); 836 837 for (i = 0; i < ec_data->nr_sensors; ++i) { 838 si = get_sensor_info(ec_data, i); 839 if (!nr_count[si->type]) 840 ++nr_types; 841 ++nr_count[si->type]; 842 } 843 844 if (nr_count[hwmon_temp]) 845 nr_count[hwmon_chip]++, nr_types++; 846 847 asus_ec_hwmon_chan = devm_kcalloc( 848 dev, nr_types, sizeof(*asus_ec_hwmon_chan), GFP_KERNEL); 849 if (!asus_ec_hwmon_chan) 850 return -ENOMEM; 851 852 ptr_asus_ec_ci = devm_kcalloc(dev, nr_types + 1, 853 sizeof(*ptr_asus_ec_ci), GFP_KERNEL); 854 if (!ptr_asus_ec_ci) 855 return -ENOMEM; 856 857 asus_ec_chip_info.info = ptr_asus_ec_ci; 858 chip_info = &asus_ec_chip_info; 859 860 for (type = 0; type < hwmon_max; ++type) { 861 if (!nr_count[type]) 862 continue; 863 864 asus_ec_hwmon_add_chan_info(asus_ec_hwmon_chan, dev, 865 nr_count[type], type, 866 hwmon_attributes[type]); 867 *ptr_asus_ec_ci++ = asus_ec_hwmon_chan++; 868 } 869 870 dev_info(dev, "board has %d EC sensors that span %d registers", 871 ec_data->nr_sensors, ec_data->nr_registers); 872 873 hwdev = devm_hwmon_device_register_with_info(dev, "asusec", 874 ec_data, chip_info, NULL); 875 876 return PTR_ERR_OR_ZERO(hwdev); 877 } 878 879 880 static const struct acpi_device_id acpi_ec_ids[] = { 881 /* Embedded Controller Device */ 882 { "PNP0C09", 0 }, 883 {} 884 }; 885 886 static struct platform_driver asus_ec_sensors_platform_driver = { 887 .driver = { 888 .name = "asus-ec-sensors", 889 .acpi_match_table = acpi_ec_ids, 890 }, 891 }; 892 893 MODULE_DEVICE_TABLE(acpi, acpi_ec_ids); 894 /* 895 * we use module_platform_driver_probe() rather than module_platform_driver() 896 * because the probe function (and its dependants) are marked with __init, which 897 * means we can't put it into the .probe member of the platform_driver struct 898 * above, and we can't mark the asus_ec_sensors_platform_driver object as __init 899 * because the object is referenced from the module exit code. 900 */ 901 module_platform_driver_probe(asus_ec_sensors_platform_driver, asus_ec_probe); 902 903 module_param_named(mutex_path, mutex_path_override, charp, 0); 904 MODULE_PARM_DESC(mutex_path, 905 "Override ACPI mutex path used to guard access to hardware"); 906 907 MODULE_AUTHOR("Eugene Shalygin <eugene.shalygin@gmail.com>"); 908 MODULE_DESCRIPTION( 909 "HWMON driver for sensors accessible via ACPI EC in ASUS motherboards"); 910 MODULE_LICENSE("GPL"); 911