linux/drivers/hwmon/asus-ec-sensors.c

// SPDX-License-Identifier: GPL-2.0+
/*
 * HWMON driver for ASUS motherboards that publish some sensor values
 * via the embedded controller registers.
 *
 * Copyright (C) 2021 Eugene Shalygin <[email protected]>

 * EC provides:
 * - Chipset temperature
 * - CPU temperature
 * - Motherboard temperature
 * - T_Sensor temperature
 * - VRM temperature
 * - Water In temperature
 * - Water Out temperature
 * - CPU Optional fan RPM
 * - Chipset fan RPM
 * - VRM Heat Sink fan RPM
 * - Water Flow fan RPM
 * - CPU current
 * - CPU core voltage
 */

#include <linux/acpi.h>
#include <linux/bitops.h>
#include <linux/dev_printk.h>
#include <linux/dmi.h>
#include <linux/hwmon.h>
#include <linux/init.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/sort.h>
#include <linux/units.h>

#include <asm/unaligned.h>

static char *mutex_path_override;

/* Writing to this EC register switches EC bank */
#define ASUS_EC_BANK_REGISTER
#define SENSOR_LABEL_LEN

/*
 * Arbitrary set max. allowed bank number. Required for sorting banks and
 * currently is overkill with just 2 banks used at max, but for the sake
 * of alignment let's set it to a higher value.
 */
#define ASUS_EC_MAX_BANK

#define ACPI_LOCK_DELAY_MS

/* ACPI mutex for locking access to the EC for the firmware */
#define ASUS_HW_ACCESS_MUTEX_ASMX

#define ASUS_HW_ACCESS_MUTEX_RMTW_ASMX

#define ASUS_HW_ACCESS_MUTEX_SB_PCI0_SBRG_SIO1_MUT0

#define MAX_IDENTICAL_BOARD_VARIATIONS

/* Moniker for the ACPI global lock (':' is not allowed in ASL identifiers) */
#define ACPI_GLOBAL_LOCK_PSEUDO_PATH

sensor_address;

#define MAKE_SENSOR_ADDRESS(size, bank, index)

static u32 hwmon_attributes[hwmon_max] =;

struct ec_sensor_info {};

#define EC_SENSOR(sensor_label, sensor_type, size, bank, index)

enum ec_sensors {};

#define SENSOR_TEMP_CHIPSET
#define SENSOR_TEMP_CPU
#define SENSOR_TEMP_CPU_PACKAGE
#define SENSOR_TEMP_MB
#define SENSOR_TEMP_T_SENSOR
#define SENSOR_TEMP_VRM
#define SENSOR_IN_CPU_CORE
#define SENSOR_FAN_CPU_OPT
#define SENSOR_FAN_VRM_HS
#define SENSOR_FAN_CHIPSET
#define SENSOR_FAN_WATER_FLOW
#define SENSOR_CURR_CPU
#define SENSOR_TEMP_WATER_IN
#define SENSOR_TEMP_WATER_OUT
#define SENSOR_TEMP_WATER_BLOCK_IN
#define SENSOR_TEMP_WATER_BLOCK_OUT
#define SENSOR_TEMP_T_SENSOR_2
#define SENSOR_TEMP_SENSOR_EXTRA_1
#define SENSOR_TEMP_SENSOR_EXTRA_2
#define SENSOR_TEMP_SENSOR_EXTRA_3

enum board_family {};

/* All the known sensors for ASUS EC controllers */
static const struct ec_sensor_info sensors_family_amd_400[] =;

static const struct ec_sensor_info sensors_family_amd_500[] =;

static const struct ec_sensor_info sensors_family_amd_600[] =;

static const struct ec_sensor_info sensors_family_intel_300[] =;

static const struct ec_sensor_info sensors_family_intel_600[] =;

/* Shortcuts for common combinations */
#define SENSOR_SET_TEMP_CHIPSET_CPU_MB
#define SENSOR_SET_TEMP_WATER
#define SENSOR_SET_WATER_BLOCK

struct ec_board_info {};

static const struct ec_board_info board_info_prime_x470_pro =;

static const struct ec_board_info board_info_prime_x570_pro =;

static const struct ec_board_info board_info_pro_art_x570_creator_wifi =;

static const struct ec_board_info board_info_pro_art_x670E_creator_wifi =;

static const struct ec_board_info board_info_pro_art_b550_creator =;

static const struct ec_board_info board_info_pro_ws_x570_ace =;

static const struct ec_board_info board_info_crosshair_x670e_hero =;

static const struct ec_board_info board_info_crosshair_x670e_gene =;

static const struct ec_board_info board_info_crosshair_viii_dark_hero =;

static const struct ec_board_info board_info_crosshair_viii_hero =;

static const struct ec_board_info board_info_maximus_xi_hero =;

static const struct ec_board_info board_info_crosshair_viii_impact =;

static const struct ec_board_info board_info_strix_b550_e_gaming =;

static const struct ec_board_info board_info_strix_b550_i_gaming =;

static const struct ec_board_info board_info_strix_x570_e_gaming =;

static const struct ec_board_info board_info_strix_x570_e_gaming_wifi_ii =;

static const struct ec_board_info board_info_strix_x570_f_gaming =;

static const struct ec_board_info board_info_strix_x570_i_gaming =;

static const struct ec_board_info board_info_strix_z390_f_gaming =;

static const struct ec_board_info board_info_strix_z690_a_gaming_wifi_d4 =;

static const struct ec_board_info board_info_zenith_ii_extreme =;

#define DMI_EXACT_MATCH_ASUS_BOARD_NAME(name, board_info)

static const struct dmi_system_id dmi_table[] =;

struct ec_sensor {};

struct lock_data {};

/*
 * The next function pairs implement options for locking access to the
 * state and the EC
 */
static bool lock_via_acpi_mutex(struct lock_data *data)
{}

static bool unlock_acpi_mutex(struct lock_data *data)
{}

static bool lock_via_global_acpi_lock(struct lock_data *data)
{}

static bool unlock_global_acpi_lock(struct lock_data *data)
{}

struct ec_sensors_data {};

static u8 register_bank(u16 reg)
{}

static u8 register_index(u16 reg)
{}

static bool is_sensor_data_signed(const struct ec_sensor_info *si)
{}

static const struct ec_sensor_info *
get_sensor_info(const struct ec_sensors_data *state, int index)
{}

static int find_ec_sensor_index(const struct ec_sensors_data *ec,
				enum hwmon_sensor_types type, int channel)
{}

static int bank_compare(const void *a, const void *b)
{}

static void setup_sensor_data(struct ec_sensors_data *ec)
{}

static void fill_ec_registers(struct ec_sensors_data *ec)
{}

static int setup_lock_data(struct device *dev)
{}

static int asus_ec_bank_switch(u8 bank, u8 *old)
{}

static int asus_ec_block_read(const struct device *dev,
			      struct ec_sensors_data *ec)
{}

static inline s32 get_sensor_value(const struct ec_sensor_info *si, u8 *data)
{}

static void update_sensor_values(struct ec_sensors_data *ec, u8 *data)
{}

static int update_ec_sensors(const struct device *dev,
			     struct ec_sensors_data *ec)
{}

static long scale_sensor_value(s32 value, int data_type)
{}

static int get_cached_value_or_update(const struct device *dev,
				      int sensor_index,
				      struct ec_sensors_data *state, s32 *value)
{}

/*
 * Now follow the functions that implement the hwmon interface
 */

static int asus_ec_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
			      u32 attr, int channel, long *val)
{}

static int asus_ec_hwmon_read_string(struct device *dev,
				     enum hwmon_sensor_types type, u32 attr,
				     int channel, const char **str)
{}

static umode_t asus_ec_hwmon_is_visible(const void *drvdata,
					enum hwmon_sensor_types type, u32 attr,
					int channel)
{}

static int
asus_ec_hwmon_add_chan_info(struct hwmon_channel_info *asus_ec_hwmon_chan,
			     struct device *dev, int num,
			     enum hwmon_sensor_types type, u32 config)
{}

static const struct hwmon_ops asus_ec_hwmon_ops =;

static struct hwmon_chip_info asus_ec_chip_info =;

static const struct ec_board_info *get_board_info(void)
{}

static int asus_ec_probe(struct platform_device *pdev)
{}

MODULE_DEVICE_TABLE(dmi, dmi_table);

static struct platform_driver asus_ec_sensors_platform_driver =;

static struct platform_device *asus_ec_sensors_platform_device;

static int __init asus_ec_init(void)
{}

static void __exit asus_ec_exit(void)
{}

module_init();
module_exit(asus_ec_exit);

module_param_named(mutex_path, mutex_path_override, charp, 0);
MODULE_PARM_DESC();

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();