Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * HWMON driver for ASUS motherboards that publish some sensor values
0004  * via the embedded controller registers.
0005  *
0006  * Copyright (C) 2021 Eugene Shalygin <eugene.shalygin@gmail.com>
0007 
0008  * EC provides:
0009  * - Chipset temperature
0010  * - CPU temperature
0011  * - Motherboard temperature
0012  * - T_Sensor temperature
0013  * - VRM temperature
0014  * - Water In temperature
0015  * - Water Out temperature
0016  * - CPU Optional fan RPM
0017  * - Chipset fan RPM
0018  * - VRM Heat Sink fan RPM
0019  * - Water Flow fan RPM
0020  * - CPU current
0021  * - CPU core voltage
0022  */
0023 
0024 #include <linux/acpi.h>
0025 #include <linux/bitops.h>
0026 #include <linux/dev_printk.h>
0027 #include <linux/dmi.h>
0028 #include <linux/hwmon.h>
0029 #include <linux/init.h>
0030 #include <linux/jiffies.h>
0031 #include <linux/kernel.h>
0032 #include <linux/module.h>
0033 #include <linux/platform_device.h>
0034 #include <linux/sort.h>
0035 #include <linux/units.h>
0036 
0037 #include <asm/unaligned.h>
0038 
0039 static char *mutex_path_override;
0040 
0041 /* Writing to this EC register switches EC bank */
0042 #define ASUS_EC_BANK_REGISTER   0xff
0043 #define SENSOR_LABEL_LEN    16
0044 
0045 /*
0046  * Arbitrary set max. allowed bank number. Required for sorting banks and
0047  * currently is overkill with just 2 banks used at max, but for the sake
0048  * of alignment let's set it to a higher value.
0049  */
0050 #define ASUS_EC_MAX_BANK    3
0051 
0052 #define ACPI_LOCK_DELAY_MS  500
0053 
0054 /* ACPI mutex for locking access to the EC for the firmware */
0055 #define ASUS_HW_ACCESS_MUTEX_ASMX   "\\AMW0.ASMX"
0056 
0057 #define ASUS_HW_ACCESS_MUTEX_RMTW_ASMX  "\\RMTW.ASMX"
0058 
0059 #define ASUS_HW_ACCESS_MUTEX_SB_PCI0_SBRG_SIO1_MUT0 "\\_SB_.PCI0.SBRG.SIO1.MUT0"
0060 
0061 #define MAX_IDENTICAL_BOARD_VARIATIONS  3
0062 
0063 /* Moniker for the ACPI global lock (':' is not allowed in ASL identifiers) */
0064 #define ACPI_GLOBAL_LOCK_PSEUDO_PATH    ":GLOBAL_LOCK"
0065 
0066 typedef union {
0067     u32 value;
0068     struct {
0069         u8 index;
0070         u8 bank;
0071         u8 size;
0072         u8 dummy;
0073     } components;
0074 } sensor_address;
0075 
0076 #define MAKE_SENSOR_ADDRESS(size, bank, index) {                               \
0077         .value = (size << 16) + (bank << 8) + index                    \
0078     }
0079 
0080 static u32 hwmon_attributes[hwmon_max] = {
0081     [hwmon_chip] = HWMON_C_REGISTER_TZ,
0082     [hwmon_temp] = HWMON_T_INPUT | HWMON_T_LABEL,
0083     [hwmon_in] = HWMON_I_INPUT | HWMON_I_LABEL,
0084     [hwmon_curr] = HWMON_C_INPUT | HWMON_C_LABEL,
0085     [hwmon_fan] = HWMON_F_INPUT | HWMON_F_LABEL,
0086 };
0087 
0088 struct ec_sensor_info {
0089     char label[SENSOR_LABEL_LEN];
0090     enum hwmon_sensor_types type;
0091     sensor_address addr;
0092 };
0093 
0094 #define EC_SENSOR(sensor_label, sensor_type, size, bank, index) {              \
0095         .label = sensor_label, .type = sensor_type,                    \
0096         .addr = MAKE_SENSOR_ADDRESS(size, bank, index),                \
0097     }
0098 
0099 enum ec_sensors {
0100     /* chipset temperature [℃] */
0101     ec_sensor_temp_chipset,
0102     /* CPU temperature [℃] */
0103     ec_sensor_temp_cpu,
0104     /* motherboard temperature [℃] */
0105     ec_sensor_temp_mb,
0106     /* "T_Sensor" temperature sensor reading [℃] */
0107     ec_sensor_temp_t_sensor,
0108     /* VRM temperature [℃] */
0109     ec_sensor_temp_vrm,
0110     /* CPU Core voltage [mV] */
0111     ec_sensor_in_cpu_core,
0112     /* CPU_Opt fan [RPM] */
0113     ec_sensor_fan_cpu_opt,
0114     /* VRM heat sink fan [RPM] */
0115     ec_sensor_fan_vrm_hs,
0116     /* Chipset fan [RPM] */
0117     ec_sensor_fan_chipset,
0118     /* Water flow sensor reading [RPM] */
0119     ec_sensor_fan_water_flow,
0120     /* CPU current [A] */
0121     ec_sensor_curr_cpu,
0122     /* "Water_In" temperature sensor reading [℃] */
0123     ec_sensor_temp_water_in,
0124     /* "Water_Out" temperature sensor reading [℃] */
0125     ec_sensor_temp_water_out,
0126     /* "Water_Block_In" temperature sensor reading [℃] */
0127     ec_sensor_temp_water_block_in,
0128     /* "Water_Block_Out" temperature sensor reading [℃] */
0129     ec_sensor_temp_water_block_out,
0130     /* "T_sensor_2" temperature sensor reading [℃] */
0131     ec_sensor_temp_t_sensor_2,
0132     /* "Extra_1" temperature sensor reading [℃] */
0133     ec_sensor_temp_sensor_extra_1,
0134     /* "Extra_2" temperature sensor reading [℃] */
0135     ec_sensor_temp_sensor_extra_2,
0136     /* "Extra_3" temperature sensor reading [℃] */
0137     ec_sensor_temp_sensor_extra_3,
0138 };
0139 
0140 #define SENSOR_TEMP_CHIPSET BIT(ec_sensor_temp_chipset)
0141 #define SENSOR_TEMP_CPU BIT(ec_sensor_temp_cpu)
0142 #define SENSOR_TEMP_MB BIT(ec_sensor_temp_mb)
0143 #define SENSOR_TEMP_T_SENSOR BIT(ec_sensor_temp_t_sensor)
0144 #define SENSOR_TEMP_VRM BIT(ec_sensor_temp_vrm)
0145 #define SENSOR_IN_CPU_CORE BIT(ec_sensor_in_cpu_core)
0146 #define SENSOR_FAN_CPU_OPT BIT(ec_sensor_fan_cpu_opt)
0147 #define SENSOR_FAN_VRM_HS BIT(ec_sensor_fan_vrm_hs)
0148 #define SENSOR_FAN_CHIPSET BIT(ec_sensor_fan_chipset)
0149 #define SENSOR_FAN_WATER_FLOW BIT(ec_sensor_fan_water_flow)
0150 #define SENSOR_CURR_CPU BIT(ec_sensor_curr_cpu)
0151 #define SENSOR_TEMP_WATER_IN BIT(ec_sensor_temp_water_in)
0152 #define SENSOR_TEMP_WATER_OUT BIT(ec_sensor_temp_water_out)
0153 #define SENSOR_TEMP_WATER_BLOCK_IN BIT(ec_sensor_temp_water_block_in)
0154 #define SENSOR_TEMP_WATER_BLOCK_OUT BIT(ec_sensor_temp_water_block_out)
0155 #define SENSOR_TEMP_T_SENSOR_2 BIT(ec_sensor_temp_t_sensor_2)
0156 #define SENSOR_TEMP_SENSOR_EXTRA_1 BIT(ec_sensor_temp_sensor_extra_1)
0157 #define SENSOR_TEMP_SENSOR_EXTRA_2 BIT(ec_sensor_temp_sensor_extra_2)
0158 #define SENSOR_TEMP_SENSOR_EXTRA_3 BIT(ec_sensor_temp_sensor_extra_3)
0159 
0160 enum board_family {
0161     family_unknown,
0162     family_amd_400_series,
0163     family_amd_500_series,
0164     family_intel_300_series,
0165     family_intel_600_series
0166 };
0167 
0168 /* All the known sensors for ASUS EC controllers */
0169 static const struct ec_sensor_info sensors_family_amd_400[] = {
0170     [ec_sensor_temp_chipset] =
0171         EC_SENSOR("Chipset", hwmon_temp, 1, 0x00, 0x3a),
0172     [ec_sensor_temp_cpu] =
0173         EC_SENSOR("CPU", hwmon_temp, 1, 0x00, 0x3b),
0174     [ec_sensor_temp_mb] =
0175         EC_SENSOR("Motherboard", hwmon_temp, 1, 0x00, 0x3c),
0176     [ec_sensor_temp_t_sensor] =
0177         EC_SENSOR("T_Sensor", hwmon_temp, 1, 0x00, 0x3d),
0178     [ec_sensor_temp_vrm] =
0179         EC_SENSOR("VRM", hwmon_temp, 1, 0x00, 0x3e),
0180     [ec_sensor_in_cpu_core] =
0181         EC_SENSOR("CPU Core", hwmon_in, 2, 0x00, 0xa2),
0182     [ec_sensor_fan_cpu_opt] =
0183         EC_SENSOR("CPU_Opt", hwmon_fan, 2, 0x00, 0xbc),
0184     [ec_sensor_fan_vrm_hs] =
0185         EC_SENSOR("VRM HS", hwmon_fan, 2, 0x00, 0xb2),
0186     [ec_sensor_fan_chipset] =
0187         /* no chipset fans in this generation */
0188         EC_SENSOR("Chipset", hwmon_fan, 0, 0x00, 0x00),
0189     [ec_sensor_fan_water_flow] =
0190         EC_SENSOR("Water_Flow", hwmon_fan, 2, 0x00, 0xb4),
0191     [ec_sensor_curr_cpu] =
0192         EC_SENSOR("CPU", hwmon_curr, 1, 0x00, 0xf4),
0193     [ec_sensor_temp_water_in] =
0194         EC_SENSOR("Water_In", hwmon_temp, 1, 0x01, 0x0d),
0195     [ec_sensor_temp_water_out] =
0196         EC_SENSOR("Water_Out", hwmon_temp, 1, 0x01, 0x0b),
0197 };
0198 
0199 static const struct ec_sensor_info sensors_family_amd_500[] = {
0200     [ec_sensor_temp_chipset] =
0201         EC_SENSOR("Chipset", hwmon_temp, 1, 0x00, 0x3a),
0202     [ec_sensor_temp_cpu] = EC_SENSOR("CPU", hwmon_temp, 1, 0x00, 0x3b),
0203     [ec_sensor_temp_mb] =
0204         EC_SENSOR("Motherboard", hwmon_temp, 1, 0x00, 0x3c),
0205     [ec_sensor_temp_t_sensor] =
0206         EC_SENSOR("T_Sensor", hwmon_temp, 1, 0x00, 0x3d),
0207     [ec_sensor_temp_vrm] = EC_SENSOR("VRM", hwmon_temp, 1, 0x00, 0x3e),
0208     [ec_sensor_in_cpu_core] =
0209         EC_SENSOR("CPU Core", hwmon_in, 2, 0x00, 0xa2),
0210     [ec_sensor_fan_cpu_opt] =
0211         EC_SENSOR("CPU_Opt", hwmon_fan, 2, 0x00, 0xb0),
0212     [ec_sensor_fan_vrm_hs] = EC_SENSOR("VRM HS", hwmon_fan, 2, 0x00, 0xb2),
0213     [ec_sensor_fan_chipset] =
0214         EC_SENSOR("Chipset", hwmon_fan, 2, 0x00, 0xb4),
0215     [ec_sensor_fan_water_flow] =
0216         EC_SENSOR("Water_Flow", hwmon_fan, 2, 0x00, 0xbc),
0217     [ec_sensor_curr_cpu] = EC_SENSOR("CPU", hwmon_curr, 1, 0x00, 0xf4),
0218     [ec_sensor_temp_water_in] =
0219         EC_SENSOR("Water_In", hwmon_temp, 1, 0x01, 0x00),
0220     [ec_sensor_temp_water_out] =
0221         EC_SENSOR("Water_Out", hwmon_temp, 1, 0x01, 0x01),
0222     [ec_sensor_temp_water_block_in] =
0223         EC_SENSOR("Water_Block_In", hwmon_temp, 1, 0x01, 0x02),
0224     [ec_sensor_temp_water_block_out] =
0225         EC_SENSOR("Water_Block_Out", hwmon_temp, 1, 0x01, 0x03),
0226     [ec_sensor_temp_sensor_extra_1] =
0227         EC_SENSOR("Extra_1", hwmon_temp, 1, 0x01, 0x09),
0228     [ec_sensor_temp_t_sensor_2] =
0229         EC_SENSOR("T_sensor_2", hwmon_temp, 1, 0x01, 0x0a),
0230     [ec_sensor_temp_sensor_extra_2] =
0231         EC_SENSOR("Extra_2", hwmon_temp, 1, 0x01, 0x0b),
0232     [ec_sensor_temp_sensor_extra_3] =
0233         EC_SENSOR("Extra_3", hwmon_temp, 1, 0x01, 0x0c),
0234 };
0235 
0236 static const struct ec_sensor_info sensors_family_intel_300[] = {
0237     [ec_sensor_temp_chipset] =
0238         EC_SENSOR("Chipset", hwmon_temp, 1, 0x00, 0x3a),
0239     [ec_sensor_temp_cpu] = EC_SENSOR("CPU", hwmon_temp, 1, 0x00, 0x3b),
0240     [ec_sensor_temp_mb] =
0241         EC_SENSOR("Motherboard", hwmon_temp, 1, 0x00, 0x3c),
0242     [ec_sensor_temp_t_sensor] =
0243         EC_SENSOR("T_Sensor", hwmon_temp, 1, 0x00, 0x3d),
0244     [ec_sensor_temp_vrm] = EC_SENSOR("VRM", hwmon_temp, 1, 0x00, 0x3e),
0245     [ec_sensor_fan_cpu_opt] =
0246         EC_SENSOR("CPU_Opt", hwmon_fan, 2, 0x00, 0xb0),
0247     [ec_sensor_fan_vrm_hs] = EC_SENSOR("VRM HS", hwmon_fan, 2, 0x00, 0xb2),
0248     [ec_sensor_fan_water_flow] =
0249         EC_SENSOR("Water_Flow", hwmon_fan, 2, 0x00, 0xbc),
0250     [ec_sensor_temp_water_in] =
0251         EC_SENSOR("Water_In", hwmon_temp, 1, 0x01, 0x00),
0252     [ec_sensor_temp_water_out] =
0253         EC_SENSOR("Water_Out", hwmon_temp, 1, 0x01, 0x01),
0254 };
0255 
0256 static const struct ec_sensor_info sensors_family_intel_600[] = {
0257     [ec_sensor_temp_t_sensor] =
0258         EC_SENSOR("T_Sensor", hwmon_temp, 1, 0x00, 0x3d),
0259     [ec_sensor_temp_vrm] = EC_SENSOR("VRM", hwmon_temp, 1, 0x00, 0x3e),
0260 };
0261 
0262 /* Shortcuts for common combinations */
0263 #define SENSOR_SET_TEMP_CHIPSET_CPU_MB                                         \
0264     (SENSOR_TEMP_CHIPSET | SENSOR_TEMP_CPU | SENSOR_TEMP_MB)
0265 #define SENSOR_SET_TEMP_WATER (SENSOR_TEMP_WATER_IN | SENSOR_TEMP_WATER_OUT)
0266 #define SENSOR_SET_WATER_BLOCK                                                 \
0267     (SENSOR_TEMP_WATER_BLOCK_IN | SENSOR_TEMP_WATER_BLOCK_OUT)
0268 
0269 struct ec_board_info {
0270     unsigned long sensors;
0271     /*
0272      * Defines which mutex to use for guarding access to the state and the
0273      * hardware. Can be either a full path to an AML mutex or the
0274      * pseudo-path ACPI_GLOBAL_LOCK_PSEUDO_PATH to use the global ACPI lock,
0275      * or left empty to use a regular mutex object, in which case access to
0276      * the hardware is not guarded.
0277      */
0278     const char *mutex_path;
0279     enum board_family family;
0280 };
0281 
0282 static const struct ec_board_info board_info_prime_x470_pro = {
0283     .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
0284         SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM |
0285         SENSOR_FAN_CPU_OPT |
0286         SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE,
0287     .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH,
0288     .family = family_amd_400_series,
0289 };
0290 
0291 static const struct ec_board_info board_info_prime_x570_pro = {
0292     .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM |
0293         SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET,
0294     .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
0295     .family = family_amd_500_series,
0296 };
0297 
0298 static const struct ec_board_info board_info_pro_art_x570_creator_wifi = {
0299     .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM |
0300         SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CPU_OPT |
0301         SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE,
0302     .family = family_amd_500_series,
0303 };
0304 
0305 static const struct ec_board_info board_info_pro_ws_x570_ace = {
0306     .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM |
0307         SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET |
0308         SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE,
0309     .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
0310     .family = family_amd_500_series,
0311 };
0312 
0313 static const struct ec_board_info board_info_crosshair_viii_dark_hero = {
0314     .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
0315         SENSOR_TEMP_T_SENSOR |
0316         SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER |
0317         SENSOR_FAN_CPU_OPT | SENSOR_FAN_WATER_FLOW |
0318         SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE,
0319     .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
0320     .family = family_amd_500_series,
0321 };
0322 
0323 static const struct ec_board_info board_info_crosshair_viii_hero = {
0324     .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
0325         SENSOR_TEMP_T_SENSOR |
0326         SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER |
0327         SENSOR_FAN_CPU_OPT | SENSOR_FAN_CHIPSET |
0328         SENSOR_FAN_WATER_FLOW | SENSOR_CURR_CPU |
0329         SENSOR_IN_CPU_CORE,
0330     .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
0331     .family = family_amd_500_series,
0332 };
0333 
0334 static const struct ec_board_info board_info_maximus_xi_hero = {
0335     .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
0336         SENSOR_TEMP_T_SENSOR |
0337         SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER |
0338         SENSOR_FAN_CPU_OPT | SENSOR_FAN_WATER_FLOW,
0339     .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
0340     .family = family_intel_300_series,
0341 };
0342 
0343 static const struct ec_board_info board_info_crosshair_viii_impact = {
0344     .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
0345         SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM |
0346         SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU |
0347         SENSOR_IN_CPU_CORE,
0348     .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
0349     .family = family_amd_500_series,
0350 };
0351 
0352 static const struct ec_board_info board_info_strix_b550_e_gaming = {
0353     .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
0354         SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM |
0355         SENSOR_FAN_CPU_OPT,
0356     .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
0357     .family = family_amd_500_series,
0358 };
0359 
0360 static const struct ec_board_info board_info_strix_b550_i_gaming = {
0361     .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
0362         SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM |
0363         SENSOR_FAN_VRM_HS | SENSOR_CURR_CPU |
0364         SENSOR_IN_CPU_CORE,
0365     .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
0366     .family = family_amd_500_series,
0367 };
0368 
0369 static const struct ec_board_info board_info_strix_x570_e_gaming = {
0370     .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
0371         SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM |
0372         SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU |
0373         SENSOR_IN_CPU_CORE,
0374     .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
0375     .family = family_amd_500_series,
0376 };
0377 
0378 static const struct ec_board_info board_info_strix_x570_e_gaming_wifi_ii = {
0379     .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
0380         SENSOR_TEMP_T_SENSOR | SENSOR_CURR_CPU |
0381         SENSOR_IN_CPU_CORE,
0382     .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
0383     .family = family_amd_500_series,
0384 };
0385 
0386 static const struct ec_board_info board_info_strix_x570_f_gaming = {
0387     .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
0388         SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET,
0389     .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
0390     .family = family_amd_500_series,
0391 };
0392 
0393 static const struct ec_board_info board_info_strix_x570_i_gaming = {
0394     .sensors = SENSOR_TEMP_CHIPSET | SENSOR_TEMP_VRM |
0395         SENSOR_TEMP_T_SENSOR |
0396         SENSOR_FAN_VRM_HS | SENSOR_FAN_CHIPSET |
0397         SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE,
0398     .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
0399     .family = family_amd_500_series,
0400 };
0401 
0402 static const struct ec_board_info board_info_strix_z690_a_gaming_wifi_d4 = {
0403     .sensors = SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM,
0404     .mutex_path = ASUS_HW_ACCESS_MUTEX_RMTW_ASMX,
0405     .family = family_intel_600_series,
0406 };
0407 
0408 static const struct ec_board_info board_info_zenith_ii_extreme = {
0409     .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_T_SENSOR |
0410         SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER |
0411         SENSOR_FAN_CPU_OPT | SENSOR_FAN_CHIPSET | SENSOR_FAN_VRM_HS |
0412         SENSOR_FAN_WATER_FLOW | SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE |
0413         SENSOR_SET_WATER_BLOCK |
0414         SENSOR_TEMP_T_SENSOR_2 | SENSOR_TEMP_SENSOR_EXTRA_1 |
0415         SENSOR_TEMP_SENSOR_EXTRA_2 | SENSOR_TEMP_SENSOR_EXTRA_3,
0416     .mutex_path = ASUS_HW_ACCESS_MUTEX_SB_PCI0_SBRG_SIO1_MUT0,
0417     .family = family_amd_500_series,
0418 };
0419 
0420 #define DMI_EXACT_MATCH_ASUS_BOARD_NAME(name, board_info)                      \
0421     {                                                                      \
0422         .matches = {                                                   \
0423             DMI_EXACT_MATCH(DMI_BOARD_VENDOR,                      \
0424                     "ASUSTeK COMPUTER INC."),              \
0425             DMI_EXACT_MATCH(DMI_BOARD_NAME, name),                 \
0426         },                                                             \
0427         .driver_data = (void *)board_info,                              \
0428     }
0429 
0430 static const struct dmi_system_id dmi_table[] = {
0431     DMI_EXACT_MATCH_ASUS_BOARD_NAME("PRIME X470-PRO",
0432                     &board_info_prime_x470_pro),
0433     DMI_EXACT_MATCH_ASUS_BOARD_NAME("PRIME X570-PRO",
0434                     &board_info_prime_x570_pro),
0435     DMI_EXACT_MATCH_ASUS_BOARD_NAME("ProArt X570-CREATOR WIFI",
0436                     &board_info_pro_art_x570_creator_wifi),
0437     DMI_EXACT_MATCH_ASUS_BOARD_NAME("Pro WS X570-ACE",
0438                     &board_info_pro_ws_x570_ace),
0439     DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VIII DARK HERO",
0440                     &board_info_crosshair_viii_dark_hero),
0441     DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VIII FORMULA",
0442                     &board_info_crosshair_viii_hero),
0443     DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VIII HERO",
0444                     &board_info_crosshair_viii_hero),
0445     DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VIII HERO (WI-FI)",
0446                     &board_info_crosshair_viii_hero),
0447     DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG MAXIMUS XI HERO",
0448                     &board_info_maximus_xi_hero),
0449     DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG MAXIMUS XI HERO (WI-FI)",
0450                     &board_info_maximus_xi_hero),
0451     DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VIII IMPACT",
0452                     &board_info_crosshair_viii_impact),
0453     DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX B550-E GAMING",
0454                     &board_info_strix_b550_e_gaming),
0455     DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX B550-I GAMING",
0456                     &board_info_strix_b550_i_gaming),
0457     DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X570-E GAMING",
0458                     &board_info_strix_x570_e_gaming),
0459     DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X570-E GAMING WIFI II",
0460                     &board_info_strix_x570_e_gaming_wifi_ii),
0461     DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X570-F GAMING",
0462                     &board_info_strix_x570_f_gaming),
0463     DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X570-I GAMING",
0464                     &board_info_strix_x570_i_gaming),
0465     DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX Z690-A GAMING WIFI D4",
0466                     &board_info_strix_z690_a_gaming_wifi_d4),
0467     DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG ZENITH II EXTREME",
0468                     &board_info_zenith_ii_extreme),
0469     {},
0470 };
0471 
0472 struct ec_sensor {
0473     unsigned int info_index;
0474     s32 cached_value;
0475 };
0476 
0477 struct lock_data {
0478     union {
0479         acpi_handle aml;
0480         /* global lock handle */
0481         u32 glk;
0482     } mutex;
0483     bool (*lock)(struct lock_data *data);
0484     bool (*unlock)(struct lock_data *data);
0485 };
0486 
0487 /*
0488  * The next function pairs implement options for locking access to the
0489  * state and the EC
0490  */
0491 static bool lock_via_acpi_mutex(struct lock_data *data)
0492 {
0493     /*
0494      * ASUS DSDT does not specify that access to the EC has to be guarded,
0495      * but firmware does access it via ACPI
0496      */
0497     return ACPI_SUCCESS(acpi_acquire_mutex(data->mutex.aml,
0498                            NULL, ACPI_LOCK_DELAY_MS));
0499 }
0500 
0501 static bool unlock_acpi_mutex(struct lock_data *data)
0502 {
0503     return ACPI_SUCCESS(acpi_release_mutex(data->mutex.aml, NULL));
0504 }
0505 
0506 static bool lock_via_global_acpi_lock(struct lock_data *data)
0507 {
0508     return ACPI_SUCCESS(acpi_acquire_global_lock(ACPI_LOCK_DELAY_MS,
0509                              &data->mutex.glk));
0510 }
0511 
0512 static bool unlock_global_acpi_lock(struct lock_data *data)
0513 {
0514     return ACPI_SUCCESS(acpi_release_global_lock(data->mutex.glk));
0515 }
0516 
0517 struct ec_sensors_data {
0518     const struct ec_board_info *board_info;
0519     const struct ec_sensor_info *sensors_info;
0520     struct ec_sensor *sensors;
0521     /* EC registers to read from */
0522     u16 *registers;
0523     u8 *read_buffer;
0524     /* sorted list of unique register banks */
0525     u8 banks[ASUS_EC_MAX_BANK + 1];
0526     /* in jiffies */
0527     unsigned long last_updated;
0528     struct lock_data lock_data;
0529     /* number of board EC sensors */
0530     u8 nr_sensors;
0531     /*
0532      * number of EC registers to read
0533      * (sensor might span more than 1 register)
0534      */
0535     u8 nr_registers;
0536     /* number of unique register banks */
0537     u8 nr_banks;
0538 };
0539 
0540 static u8 register_bank(u16 reg)
0541 {
0542     return reg >> 8;
0543 }
0544 
0545 static u8 register_index(u16 reg)
0546 {
0547     return reg & 0x00ff;
0548 }
0549 
0550 static bool is_sensor_data_signed(const struct ec_sensor_info *si)
0551 {
0552     /*
0553      * guessed from WMI functions in DSDT code for boards
0554      * of the X470 generation
0555      */
0556     return si->type == hwmon_temp;
0557 }
0558 
0559 static const struct ec_sensor_info *
0560 get_sensor_info(const struct ec_sensors_data *state, int index)
0561 {
0562     return state->sensors_info + state->sensors[index].info_index;
0563 }
0564 
0565 static int find_ec_sensor_index(const struct ec_sensors_data *ec,
0566                 enum hwmon_sensor_types type, int channel)
0567 {
0568     unsigned int i;
0569 
0570     for (i = 0; i < ec->nr_sensors; i++) {
0571         if (get_sensor_info(ec, i)->type == type) {
0572             if (channel == 0)
0573                 return i;
0574             channel--;
0575         }
0576     }
0577     return -ENOENT;
0578 }
0579 
0580 static int bank_compare(const void *a, const void *b)
0581 {
0582     return *((const s8 *)a) - *((const s8 *)b);
0583 }
0584 
0585 static void setup_sensor_data(struct ec_sensors_data *ec)
0586 {
0587     struct ec_sensor *s = ec->sensors;
0588     bool bank_found;
0589     int i, j;
0590     u8 bank;
0591 
0592     ec->nr_banks = 0;
0593     ec->nr_registers = 0;
0594 
0595     for_each_set_bit(i, &ec->board_info->sensors,
0596              BITS_PER_TYPE(ec->board_info->sensors)) {
0597         s->info_index = i;
0598         s->cached_value = 0;
0599         ec->nr_registers +=
0600             ec->sensors_info[s->info_index].addr.components.size;
0601         bank_found = false;
0602         bank = ec->sensors_info[s->info_index].addr.components.bank;
0603         for (j = 0; j < ec->nr_banks; j++) {
0604             if (ec->banks[j] == bank) {
0605                 bank_found = true;
0606                 break;
0607             }
0608         }
0609         if (!bank_found) {
0610             ec->banks[ec->nr_banks++] = bank;
0611         }
0612         s++;
0613     }
0614     sort(ec->banks, ec->nr_banks, 1, bank_compare, NULL);
0615 }
0616 
0617 static void fill_ec_registers(struct ec_sensors_data *ec)
0618 {
0619     const struct ec_sensor_info *si;
0620     unsigned int i, j, register_idx = 0;
0621 
0622     for (i = 0; i < ec->nr_sensors; ++i) {
0623         si = get_sensor_info(ec, i);
0624         for (j = 0; j < si->addr.components.size; ++j, ++register_idx) {
0625             ec->registers[register_idx] =
0626                 (si->addr.components.bank << 8) +
0627                 si->addr.components.index + j;
0628         }
0629     }
0630 }
0631 
0632 static int setup_lock_data(struct device *dev)
0633 {
0634     const char *mutex_path;
0635     int status;
0636     struct ec_sensors_data *state = dev_get_drvdata(dev);
0637 
0638     mutex_path = mutex_path_override ?
0639         mutex_path_override : state->board_info->mutex_path;
0640 
0641     if (!mutex_path || !strlen(mutex_path)) {
0642         dev_err(dev, "Hardware access guard mutex name is empty");
0643         return -EINVAL;
0644     }
0645     if (!strcmp(mutex_path, ACPI_GLOBAL_LOCK_PSEUDO_PATH)) {
0646         state->lock_data.mutex.glk = 0;
0647         state->lock_data.lock = lock_via_global_acpi_lock;
0648         state->lock_data.unlock = unlock_global_acpi_lock;
0649     } else {
0650         status = acpi_get_handle(NULL, (acpi_string)mutex_path,
0651                      &state->lock_data.mutex.aml);
0652         if (ACPI_FAILURE(status)) {
0653             dev_err(dev,
0654                 "Failed to get hardware access guard AML mutex '%s': error %d",
0655                 mutex_path, status);
0656             return -ENOENT;
0657         }
0658         state->lock_data.lock = lock_via_acpi_mutex;
0659         state->lock_data.unlock = unlock_acpi_mutex;
0660     }
0661     return 0;
0662 }
0663 
0664 static int asus_ec_bank_switch(u8 bank, u8 *old)
0665 {
0666     int status = 0;
0667 
0668     if (old) {
0669         status = ec_read(ASUS_EC_BANK_REGISTER, old);
0670     }
0671     if (status || (old && (*old == bank)))
0672         return status;
0673     return ec_write(ASUS_EC_BANK_REGISTER, bank);
0674 }
0675 
0676 static int asus_ec_block_read(const struct device *dev,
0677                   struct ec_sensors_data *ec)
0678 {
0679     int ireg, ibank, status;
0680     u8 bank, reg_bank, prev_bank;
0681 
0682     bank = 0;
0683     status = asus_ec_bank_switch(bank, &prev_bank);
0684     if (status) {
0685         dev_warn(dev, "EC bank switch failed");
0686         return status;
0687     }
0688 
0689     if (prev_bank) {
0690         /* oops... somebody else is working with the EC too */
0691         dev_warn(dev,
0692             "Concurrent access to the ACPI EC detected.\nRace condition possible.");
0693     }
0694 
0695     /* read registers minimizing bank switches. */
0696     for (ibank = 0; ibank < ec->nr_banks; ibank++) {
0697         if (bank != ec->banks[ibank]) {
0698             bank = ec->banks[ibank];
0699             if (asus_ec_bank_switch(bank, NULL)) {
0700                 dev_warn(dev, "EC bank switch to %d failed",
0701                      bank);
0702                 break;
0703             }
0704         }
0705         for (ireg = 0; ireg < ec->nr_registers; ireg++) {
0706             reg_bank = register_bank(ec->registers[ireg]);
0707             if (reg_bank < bank) {
0708                 continue;
0709             }
0710             ec_read(register_index(ec->registers[ireg]),
0711                 ec->read_buffer + ireg);
0712         }
0713     }
0714 
0715     status = asus_ec_bank_switch(prev_bank, NULL);
0716     return status;
0717 }
0718 
0719 static inline s32 get_sensor_value(const struct ec_sensor_info *si, u8 *data)
0720 {
0721     if (is_sensor_data_signed(si)) {
0722         switch (si->addr.components.size) {
0723         case 1:
0724             return (s8)*data;
0725         case 2:
0726             return (s16)get_unaligned_be16(data);
0727         case 4:
0728             return (s32)get_unaligned_be32(data);
0729         default:
0730             return 0;
0731         }
0732     } else {
0733         switch (si->addr.components.size) {
0734         case 1:
0735             return *data;
0736         case 2:
0737             return get_unaligned_be16(data);
0738         case 4:
0739             return get_unaligned_be32(data);
0740         default:
0741             return 0;
0742         }
0743     }
0744 }
0745 
0746 static void update_sensor_values(struct ec_sensors_data *ec, u8 *data)
0747 {
0748     const struct ec_sensor_info *si;
0749     struct ec_sensor *s, *sensor_end;
0750 
0751     sensor_end = ec->sensors + ec->nr_sensors;
0752     for (s = ec->sensors; s != sensor_end; s++) {
0753         si = ec->sensors_info + s->info_index;
0754         s->cached_value = get_sensor_value(si, data);
0755         data += si->addr.components.size;
0756     }
0757 }
0758 
0759 static int update_ec_sensors(const struct device *dev,
0760                  struct ec_sensors_data *ec)
0761 {
0762     int status;
0763 
0764     if (!ec->lock_data.lock(&ec->lock_data)) {
0765         dev_warn(dev, "Failed to acquire mutex");
0766         return -EBUSY;
0767     }
0768 
0769     status = asus_ec_block_read(dev, ec);
0770 
0771     if (!status) {
0772         update_sensor_values(ec, ec->read_buffer);
0773     }
0774 
0775     if (!ec->lock_data.unlock(&ec->lock_data))
0776         dev_err(dev, "Failed to release mutex");
0777 
0778     return status;
0779 }
0780 
0781 static long scale_sensor_value(s32 value, int data_type)
0782 {
0783     switch (data_type) {
0784     case hwmon_curr:
0785     case hwmon_temp:
0786         return value * MILLI;
0787     default:
0788         return value;
0789     }
0790 }
0791 
0792 static int get_cached_value_or_update(const struct device *dev,
0793                       int sensor_index,
0794                       struct ec_sensors_data *state, s32 *value)
0795 {
0796     if (time_after(jiffies, state->last_updated + HZ)) {
0797         if (update_ec_sensors(dev, state)) {
0798             dev_err(dev, "update_ec_sensors() failure\n");
0799             return -EIO;
0800         }
0801 
0802         state->last_updated = jiffies;
0803     }
0804 
0805     *value = state->sensors[sensor_index].cached_value;
0806     return 0;
0807 }
0808 
0809 /*
0810  * Now follow the functions that implement the hwmon interface
0811  */
0812 
0813 static int asus_ec_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
0814                   u32 attr, int channel, long *val)
0815 {
0816     int ret;
0817     s32 value = 0;
0818 
0819     struct ec_sensors_data *state = dev_get_drvdata(dev);
0820     int sidx = find_ec_sensor_index(state, type, channel);
0821 
0822     if (sidx < 0) {
0823         return sidx;
0824     }
0825 
0826     ret = get_cached_value_or_update(dev, sidx, state, &value);
0827     if (!ret) {
0828         *val = scale_sensor_value(value,
0829                       get_sensor_info(state, sidx)->type);
0830     }
0831 
0832     return ret;
0833 }
0834 
0835 static int asus_ec_hwmon_read_string(struct device *dev,
0836                      enum hwmon_sensor_types type, u32 attr,
0837                      int channel, const char **str)
0838 {
0839     struct ec_sensors_data *state = dev_get_drvdata(dev);
0840     int sensor_index = find_ec_sensor_index(state, type, channel);
0841     *str = get_sensor_info(state, sensor_index)->label;
0842 
0843     return 0;
0844 }
0845 
0846 static umode_t asus_ec_hwmon_is_visible(const void *drvdata,
0847                     enum hwmon_sensor_types type, u32 attr,
0848                     int channel)
0849 {
0850     const struct ec_sensors_data *state = drvdata;
0851 
0852     return find_ec_sensor_index(state, type, channel) >= 0 ? S_IRUGO : 0;
0853 }
0854 
0855 static int
0856 asus_ec_hwmon_add_chan_info(struct hwmon_channel_info *asus_ec_hwmon_chan,
0857                  struct device *dev, int num,
0858                  enum hwmon_sensor_types type, u32 config)
0859 {
0860     int i;
0861     u32 *cfg = devm_kcalloc(dev, num + 1, sizeof(*cfg), GFP_KERNEL);
0862 
0863     if (!cfg)
0864         return -ENOMEM;
0865 
0866     asus_ec_hwmon_chan->type = type;
0867     asus_ec_hwmon_chan->config = cfg;
0868     for (i = 0; i < num; i++, cfg++)
0869         *cfg = config;
0870 
0871     return 0;
0872 }
0873 
0874 static const struct hwmon_ops asus_ec_hwmon_ops = {
0875     .is_visible = asus_ec_hwmon_is_visible,
0876     .read = asus_ec_hwmon_read,
0877     .read_string = asus_ec_hwmon_read_string,
0878 };
0879 
0880 static struct hwmon_chip_info asus_ec_chip_info = {
0881     .ops = &asus_ec_hwmon_ops,
0882 };
0883 
0884 static const struct ec_board_info *get_board_info(void)
0885 {
0886     const struct dmi_system_id *dmi_entry;
0887 
0888     dmi_entry = dmi_first_match(dmi_table);
0889     return dmi_entry ? dmi_entry->driver_data : NULL;
0890 }
0891 
0892 static int asus_ec_probe(struct platform_device *pdev)
0893 {
0894     const struct hwmon_channel_info **ptr_asus_ec_ci;
0895     int nr_count[hwmon_max] = { 0 }, nr_types = 0;
0896     struct hwmon_channel_info *asus_ec_hwmon_chan;
0897     const struct ec_board_info *pboard_info;
0898     const struct hwmon_chip_info *chip_info;
0899     struct device *dev = &pdev->dev;
0900     struct ec_sensors_data *ec_data;
0901     const struct ec_sensor_info *si;
0902     enum hwmon_sensor_types type;
0903     struct device *hwdev;
0904     unsigned int i;
0905     int status;
0906 
0907     pboard_info = get_board_info();
0908     if (!pboard_info)
0909         return -ENODEV;
0910 
0911     ec_data = devm_kzalloc(dev, sizeof(struct ec_sensors_data),
0912                    GFP_KERNEL);
0913     if (!ec_data)
0914         return -ENOMEM;
0915 
0916     dev_set_drvdata(dev, ec_data);
0917     ec_data->board_info = pboard_info;
0918 
0919     switch (ec_data->board_info->family) {
0920     case family_amd_400_series:
0921         ec_data->sensors_info = sensors_family_amd_400;
0922         break;
0923     case family_amd_500_series:
0924         ec_data->sensors_info = sensors_family_amd_500;
0925         break;
0926     case family_intel_300_series:
0927         ec_data->sensors_info = sensors_family_intel_300;
0928         break;
0929     case family_intel_600_series:
0930         ec_data->sensors_info = sensors_family_intel_600;
0931         break;
0932     default:
0933         dev_err(dev, "Unknown board family: %d",
0934             ec_data->board_info->family);
0935         return -EINVAL;
0936     }
0937 
0938     ec_data->nr_sensors = hweight_long(ec_data->board_info->sensors);
0939     ec_data->sensors = devm_kcalloc(dev, ec_data->nr_sensors,
0940                     sizeof(struct ec_sensor), GFP_KERNEL);
0941 
0942     status = setup_lock_data(dev);
0943     if (status) {
0944         dev_err(dev, "Failed to setup state/EC locking: %d", status);
0945         return status;
0946     }
0947 
0948     setup_sensor_data(ec_data);
0949     ec_data->registers = devm_kcalloc(dev, ec_data->nr_registers,
0950                       sizeof(u16), GFP_KERNEL);
0951     ec_data->read_buffer = devm_kcalloc(dev, ec_data->nr_registers,
0952                         sizeof(u8), GFP_KERNEL);
0953 
0954     if (!ec_data->registers || !ec_data->read_buffer)
0955         return -ENOMEM;
0956 
0957     fill_ec_registers(ec_data);
0958 
0959     for (i = 0; i < ec_data->nr_sensors; ++i) {
0960         si = get_sensor_info(ec_data, i);
0961         if (!nr_count[si->type])
0962             ++nr_types;
0963         ++nr_count[si->type];
0964     }
0965 
0966     if (nr_count[hwmon_temp])
0967         nr_count[hwmon_chip]++, nr_types++;
0968 
0969     asus_ec_hwmon_chan = devm_kcalloc(
0970         dev, nr_types, sizeof(*asus_ec_hwmon_chan), GFP_KERNEL);
0971     if (!asus_ec_hwmon_chan)
0972         return -ENOMEM;
0973 
0974     ptr_asus_ec_ci = devm_kcalloc(dev, nr_types + 1,
0975                        sizeof(*ptr_asus_ec_ci), GFP_KERNEL);
0976     if (!ptr_asus_ec_ci)
0977         return -ENOMEM;
0978 
0979     asus_ec_chip_info.info = ptr_asus_ec_ci;
0980     chip_info = &asus_ec_chip_info;
0981 
0982     for (type = 0; type < hwmon_max; ++type) {
0983         if (!nr_count[type])
0984             continue;
0985 
0986         asus_ec_hwmon_add_chan_info(asus_ec_hwmon_chan, dev,
0987                          nr_count[type], type,
0988                          hwmon_attributes[type]);
0989         *ptr_asus_ec_ci++ = asus_ec_hwmon_chan++;
0990     }
0991 
0992     dev_info(dev, "board has %d EC sensors that span %d registers",
0993          ec_data->nr_sensors, ec_data->nr_registers);
0994 
0995     hwdev = devm_hwmon_device_register_with_info(dev, "asusec",
0996                              ec_data, chip_info, NULL);
0997 
0998     return PTR_ERR_OR_ZERO(hwdev);
0999 }
1000 
1001 MODULE_DEVICE_TABLE(dmi, dmi_table);
1002 
1003 static struct platform_driver asus_ec_sensors_platform_driver = {
1004     .driver = {
1005         .name   = "asus-ec-sensors",
1006     },
1007     .probe = asus_ec_probe,
1008 };
1009 
1010 static struct platform_device *asus_ec_sensors_platform_device;
1011 
1012 static int __init asus_ec_init(void)
1013 {
1014     asus_ec_sensors_platform_device =
1015         platform_create_bundle(&asus_ec_sensors_platform_driver,
1016                        asus_ec_probe, NULL, 0, NULL, 0);
1017 
1018     if (IS_ERR(asus_ec_sensors_platform_device))
1019         return PTR_ERR(asus_ec_sensors_platform_device);
1020 
1021     return 0;
1022 }
1023 
1024 static void __exit asus_ec_exit(void)
1025 {
1026     platform_device_unregister(asus_ec_sensors_platform_device);
1027     platform_driver_unregister(&asus_ec_sensors_platform_driver);
1028 }
1029 
1030 module_init(asus_ec_init);
1031 module_exit(asus_ec_exit);
1032 
1033 module_param_named(mutex_path, mutex_path_override, charp, 0);
1034 MODULE_PARM_DESC(mutex_path,
1035          "Override ACPI mutex path used to guard access to hardware");
1036 
1037 MODULE_AUTHOR("Eugene Shalygin <eugene.shalygin@gmail.com>");
1038 MODULE_DESCRIPTION(
1039     "HWMON driver for sensors accessible via ACPI EC in ASUS motherboards");
1040 MODULE_LICENSE("GPL");