// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * HWMON driver for ASUS motherboards that provides sensor readouts via WMI
 * interface present in the UEFI of the X370/X470/B450/X399 Ryzen motherboards.
 *
 * Copyright (C) 2018-2019 Ed Brindley <kernel@maidavale.org>
 *
 * WMI interface provides:
 * - CPU Core Voltage,
 * - CPU SOC Voltage,
 * - DRAM Voltage,
 * - VDDP Voltage,
 * - 1.8V PLL Voltage,
 * - +12V Voltage,
 * - +5V Voltage,
 * - 3VSB Voltage,
 * - VBAT Voltage,
 * - AVCC3 Voltage,
 * - SB 1.05V Voltage,
 * - CPU Core Voltage,
 * - CPU SOC Voltage,
 * - DRAM Voltage,
 * - CPU Fan RPM,
 * - Chassis Fan 1 RPM,
 * - Chassis Fan 2 RPM,
 * - Chassis Fan 3 RPM,
 * - HAMP Fan RPM,
 * - Water Pump RPM,
 * - CPU OPT RPM,
 * - Water Flow RPM,
 * - AIO Pump RPM,
 * - CPU Temperature,
 * - CPU Socket Temperature,
 * - Motherboard Temperature,
 * - Chipset Temperature,
 * - Tsensor 1 Temperature,
 * - CPU VRM Temperature,
 * - Water In,
 * - Water Out,
 * - CPU VRM Output Current.
 */

#include <linux/acpi.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/mutex.h>
#include <linux/units.h>
#include <linux/wmi.h>

#define ASUSWMI_MONITORING_GUID		"466747A0-70EC-11DE-8A39-0800200C9A66"
#define ASUSWMI_METHODID_GET_VALUE	0x52574543 /* RWEC */
#define ASUSWMI_METHODID_UPDATE_BUFFER	0x51574543 /* QWEC */
#define ASUSWMI_METHODID_GET_INFO	0x50574543 /* PWEC */
#define ASUSWMI_METHODID_GET_NUMBER	0x50574572 /* PWEr */
#define ASUSWMI_METHODID_GET_VERSION	0x50574574 /* PWEt */

#define ASUS_WMI_MAX_STR_SIZE		32

#define DMI_EXACT_MATCH_ASUS_BOARD_NAME(name) {					\
	.matches = {								\
		DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."),	\
		DMI_EXACT_MATCH(DMI_BOARD_NAME, name),				\
	},									\
}

static const struct dmi_system_id asus_wmi_dmi_table[] = {
	DMI_EXACT_MATCH_ASUS_BOARD_NAME("PRIME X399-A"),
	DMI_EXACT_MATCH_ASUS_BOARD_NAME("PRIME X470-PRO"),
	DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VI EXTREME"),
	DMI_EXACT_MATCH_ASUS_BOARD_NAME("CROSSHAIR VI HERO"),
	DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VI HERO (WI-FI AC)"),
	DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VII HERO"),
	DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VII HERO (WI-FI)"),
	DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX B450-E GAMING"),
	DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX B450-F GAMING"),
	DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX B450-F GAMING II"),
	DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX B450-I GAMING"),
	DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X399-E GAMING"),
	DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X470-F GAMING"),
	DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X470-I GAMING"),
	DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG ZENITH EXTREME"),
	DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG ZENITH EXTREME ALPHA"),
	{}
};
MODULE_DEVICE_TABLE(dmi, asus_wmi_dmi_table);

enum asus_wmi_sensor_class {
	VOLTAGE		= 0x0,
	TEMPERATURE_C	= 0x1,
	FAN_RPM		= 0x2,
	CURRENT		= 0x3,
	WATER_FLOW	= 0x4,
};

enum asus_wmi_location {
	CPU		= 0x0,
	CPU_SOC		= 0x1,
	DRAM		= 0x2,
	MOTHERBOARD	= 0x3,
	CHIPSET		= 0x4,
	AUX		= 0x5,
	VRM		= 0x6,
	COOLER		= 0x7
};

enum asus_wmi_type {
	SIGNED_INT	= 0x0,
	UNSIGNED_INT	= 0x1,
	SCALED		= 0x3,
};

enum asus_wmi_source {
	SIO		= 0x1,
	EC		= 0x2
};

static enum hwmon_sensor_types asus_data_types[] = {
	[VOLTAGE]	= hwmon_in,
	[TEMPERATURE_C]	= hwmon_temp,
	[FAN_RPM]	= hwmon_fan,
	[CURRENT]	= hwmon_curr,
	[WATER_FLOW]	= hwmon_fan,
};

static u32 hwmon_attributes[hwmon_max] = {
	[hwmon_chip]	= HWMON_C_REGISTER_TZ,
	[hwmon_temp]	= HWMON_T_INPUT | HWMON_T_LABEL,
	[hwmon_in]	= HWMON_I_INPUT | HWMON_I_LABEL,
	[hwmon_curr]	= HWMON_C_INPUT | HWMON_C_LABEL,
	[hwmon_fan]	= HWMON_F_INPUT | HWMON_F_LABEL,
};

/**
 * struct asus_wmi_sensor_info - sensor info.
 * @id: sensor id.
 * @data_type: sensor class e.g. voltage, temp etc.
 * @location: sensor location.
 * @name: sensor name.
 * @source: sensor source.
 * @type: sensor type signed, unsigned etc.
 * @cached_value: cached sensor value.
 */
struct asus_wmi_sensor_info {
	u32 id;
	int data_type;
	int location;
	char name[ASUS_WMI_MAX_STR_SIZE];
	int source;
	int type;
	long cached_value;
};

struct asus_wmi_wmi_info {
	unsigned long source_last_updated[3];	/* in jiffies */
	int sensor_count;

	const struct asus_wmi_sensor_info **info[hwmon_max];
	struct asus_wmi_sensor_info **info_by_id;
};

struct asus_wmi_sensors {
	struct asus_wmi_wmi_info wmi;
	/* lock access to internal cache */
	struct mutex lock;
};

/*
 * Universal method for calling WMI method
 */
static int asus_wmi_call_method(u32 method_id, u32 *args, struct acpi_buffer *output)
{
	struct acpi_buffer input = {(acpi_size) sizeof(*args), args };
	acpi_status status;

	status = wmi_evaluate_method(ASUSWMI_MONITORING_GUID, 0,
				     method_id, &input, output);
	if (ACPI_FAILURE(status))
		return -EIO;

	return 0;
}

/*
 * Gets the version of the ASUS sensors interface implemented
 */
static int asus_wmi_get_version(u32 *version)
{
	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
	u32 args[] = {0, 0, 0};
	union acpi_object *obj;
	int err;

	err = asus_wmi_call_method(ASUSWMI_METHODID_GET_VERSION, args, &output);
	if (err)
		return err;

	obj = output.pointer;
	if (!obj)
		return -EIO;

	if (obj->type != ACPI_TYPE_INTEGER) {
		err = -EIO;
		goto out_free_obj;
	}

	err = 0;
	*version = obj->integer.value;

out_free_obj:
	ACPI_FREE(obj);
	return err;
}

/*
 * Gets the number of sensor items
 */
static int asus_wmi_get_item_count(u32 *count)
{
	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
	u32 args[] = {0, 0, 0};
	union acpi_object *obj;
	int err;

	err = asus_wmi_call_method(ASUSWMI_METHODID_GET_NUMBER, args, &output);
	if (err)
		return err;

	obj = output.pointer;
	if (!obj)
		return -EIO;

	if (obj->type != ACPI_TYPE_INTEGER) {
		err = -EIO;
		goto out_free_obj;
	}

	err = 0;
	*count = obj->integer.value;

out_free_obj:
	ACPI_FREE(obj);
	return err;
}

static int asus_wmi_hwmon_add_chan_info(struct hwmon_channel_info *asus_wmi_hwmon_chan,
					struct device *dev, int num,
					enum hwmon_sensor_types type, u32 config)
{
	u32 *cfg;

	cfg = devm_kcalloc(dev, num + 1, sizeof(*cfg), GFP_KERNEL);
	if (!cfg)
		return -ENOMEM;

	asus_wmi_hwmon_chan->type = type;
	asus_wmi_hwmon_chan->config = cfg;
	memset32(cfg, config, num);

	return 0;
}

/*
 * For a given sensor item returns details e.g. type (voltage/temperature/fan speed etc), bank etc
 */
static int asus_wmi_sensor_info(int index, struct asus_wmi_sensor_info *s)
{
	union acpi_object name_obj, data_type_obj, location_obj, source_obj, type_obj;
	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
	u32 args[] = {index, 0};
	union acpi_object *obj;
	int err;

	err = asus_wmi_call_method(ASUSWMI_METHODID_GET_INFO, args, &output);
	if (err)
		return err;

	s->id = index;

	obj = output.pointer;
	if (!obj)
		return -EIO;

	if (obj->type != ACPI_TYPE_PACKAGE) {
		err = -EIO;
		goto out_free_obj;
	}

	if (obj->package.count != 5) {
		err = -EIO;
		goto out_free_obj;
	}

	name_obj = obj->package.elements[0];
	if (name_obj.type != ACPI_TYPE_STRING) {
		err = -EIO;
		goto out_free_obj;
	}

	strncpy(s->name, name_obj.string.pointer, sizeof(s->name) - 1);

	data_type_obj = obj->package.elements[1];
	if (data_type_obj.type != ACPI_TYPE_INTEGER) {
		err = -EIO;
		goto out_free_obj;
	}

	s->data_type = data_type_obj.integer.value;

	location_obj = obj->package.elements[2];
	if (location_obj.type != ACPI_TYPE_INTEGER) {
		err = -EIO;
		goto out_free_obj;
	}

	s->location = location_obj.integer.value;

	source_obj = obj->package.elements[3];
	if (source_obj.type != ACPI_TYPE_INTEGER) {
		err = -EIO;
		goto out_free_obj;
	}

	s->source = source_obj.integer.value;

	type_obj = obj->package.elements[4];
	if (type_obj.type != ACPI_TYPE_INTEGER) {
		err = -EIO;
		goto out_free_obj;
	}

	err = 0;
	s->type = type_obj.integer.value;

out_free_obj:
	ACPI_FREE(obj);
	return err;
}

static int asus_wmi_update_buffer(int source)
{
	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
	u32 args[] = {source, 0};

	return asus_wmi_call_method(ASUSWMI_METHODID_UPDATE_BUFFER, args, &output);
}

static int asus_wmi_get_sensor_value(u8 index, long *value)
{
	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
	u32 args[] = {index, 0};
	union acpi_object *obj;
	int err;

	err = asus_wmi_call_method(ASUSWMI_METHODID_GET_VALUE, args, &output);
	if (err)
		return err;

	obj = output.pointer;
	if (!obj)
		return -EIO;

	if (obj->type != ACPI_TYPE_INTEGER) {
		err = -EIO;
		goto out_free_obj;
	}

	err = 0;
	*value = obj->integer.value;

out_free_obj:
	ACPI_FREE(obj);
	return err;
}

static int asus_wmi_update_values_for_source(u8 source, struct asus_wmi_sensors *sensor_data)
{
	struct asus_wmi_sensor_info *sensor;
	long value = 0;
	int ret;
	int i;

	for (i = 0; i < sensor_data->wmi.sensor_count; i++) {
		sensor = sensor_data->wmi.info_by_id[i];
		if (sensor && sensor->source == source) {
			ret = asus_wmi_get_sensor_value(sensor->id, &value);
			if (ret)
				return ret;

			sensor->cached_value = value;
		}
	}

	return 0;
}

static int asus_wmi_scale_sensor_value(u32 value, int data_type)
{
	/* FAN_RPM and WATER_FLOW don't need scaling */
	switch (data_type) {
	case VOLTAGE:
		/* value in microVolts */
		return DIV_ROUND_CLOSEST(value,  KILO);
	case TEMPERATURE_C:
		/* value in Celsius */
		return value * MILLIDEGREE_PER_DEGREE;
	case CURRENT:
		/* value in Amperes */
		return value * MILLI;
	}
	return value;
}

static int asus_wmi_get_cached_value_or_update(const struct asus_wmi_sensor_info *sensor,
					       struct asus_wmi_sensors *sensor_data,
					       u32 *value)
{
	int ret = 0;

	mutex_lock(&sensor_data->lock);

	if (time_after(jiffies, sensor_data->wmi.source_last_updated[sensor->source] + HZ)) {
		ret = asus_wmi_update_buffer(sensor->source);
		if (ret)
			goto unlock;

		ret = asus_wmi_update_values_for_source(sensor->source, sensor_data);
		if (ret)
			goto unlock;

		sensor_data->wmi.source_last_updated[sensor->source] = jiffies;
	}

	*value = sensor->cached_value;

unlock:
	mutex_unlock(&sensor_data->lock);

	return ret;
}

/* Now follow the functions that implement the hwmon interface */
static int asus_wmi_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
			       u32 attr, int channel, long *val)
{
	const struct asus_wmi_sensor_info *sensor;
	u32 value = 0;
	int ret;

	struct asus_wmi_sensors *sensor_data = dev_get_drvdata(dev);

	sensor = *(sensor_data->wmi.info[type] + channel);

	ret = asus_wmi_get_cached_value_or_update(sensor, sensor_data, &value);
	if (ret)
		return ret;

	*val = asus_wmi_scale_sensor_value(value, sensor->data_type);

	return ret;
}

static int asus_wmi_hwmon_read_string(struct device *dev,
				      enum hwmon_sensor_types type, u32 attr,
				      int channel, const char **str)
{
	struct asus_wmi_sensors *sensor_data = dev_get_drvdata(dev);
	const struct asus_wmi_sensor_info *sensor;

	sensor = *(sensor_data->wmi.info[type] + channel);
	*str = sensor->name;

	return 0;
}

static umode_t asus_wmi_hwmon_is_visible(const void *drvdata,
					 enum hwmon_sensor_types type, u32 attr,
					 int channel)
{
	const struct asus_wmi_sensors *sensor_data = drvdata;
	const struct asus_wmi_sensor_info *sensor;

	sensor = *(sensor_data->wmi.info[type] + channel);
	if (sensor)
		return 0444;

	return 0;
}

static const struct hwmon_ops asus_wmi_hwmon_ops = {
	.is_visible = asus_wmi_hwmon_is_visible,
	.read = asus_wmi_hwmon_read,
	.read_string = asus_wmi_hwmon_read_string,
};

static struct hwmon_chip_info asus_wmi_chip_info = {
	.ops = &asus_wmi_hwmon_ops,
	.info = NULL,
};

static int asus_wmi_configure_sensor_setup(struct device *dev,
					   struct asus_wmi_sensors *sensor_data)
{
	const struct hwmon_channel_info **ptr_asus_wmi_ci;
	struct hwmon_channel_info *asus_wmi_hwmon_chan;
	int nr_count[hwmon_max] = {}, nr_types = 0;
	struct asus_wmi_sensor_info *temp_sensor;
	const struct hwmon_chip_info *chip_info;
	enum hwmon_sensor_types type;
	struct device *hwdev;
	int i, idx;
	int err;

	temp_sensor = devm_kcalloc(dev, 1, sizeof(*temp_sensor), GFP_KERNEL);
	if (!temp_sensor)
		return -ENOMEM;

	for (i = 0; i < sensor_data->wmi.sensor_count; i++) {
		err = asus_wmi_sensor_info(i, temp_sensor);
		if (err)
			return err;

		switch (temp_sensor->data_type) {
		case TEMPERATURE_C:
		case VOLTAGE:
		case CURRENT:
		case FAN_RPM:
		case WATER_FLOW:
			type = asus_data_types[temp_sensor->data_type];
			if (!nr_count[type])
				nr_types++;
			nr_count[type]++;
			break;
		}
	}

	if (nr_count[hwmon_temp])
		nr_count[hwmon_chip]++, nr_types++;

	asus_wmi_hwmon_chan = devm_kcalloc(dev, nr_types,
					   sizeof(*asus_wmi_hwmon_chan),
					   GFP_KERNEL);
	if (!asus_wmi_hwmon_chan)
		return -ENOMEM;

	ptr_asus_wmi_ci = devm_kcalloc(dev, nr_types + 1,
				       sizeof(*ptr_asus_wmi_ci), GFP_KERNEL);
	if (!ptr_asus_wmi_ci)
		return -ENOMEM;

	asus_wmi_chip_info.info = ptr_asus_wmi_ci;
	chip_info = &asus_wmi_chip_info;

	sensor_data->wmi.info_by_id = devm_kcalloc(dev, sensor_data->wmi.sensor_count,
						   sizeof(*sensor_data->wmi.info_by_id),
						   GFP_KERNEL);

	if (!sensor_data->wmi.info_by_id)
		return -ENOMEM;

	for (type = 0; type < hwmon_max; type++) {
		if (!nr_count[type])
			continue;

		err = asus_wmi_hwmon_add_chan_info(asus_wmi_hwmon_chan, dev,
						   nr_count[type], type,
						   hwmon_attributes[type]);
		if (err)
			return err;

		*ptr_asus_wmi_ci++ = asus_wmi_hwmon_chan++;

		sensor_data->wmi.info[type] = devm_kcalloc(dev,
							   nr_count[type],
							   sizeof(*sensor_data->wmi.info),
							   GFP_KERNEL);
		if (!sensor_data->wmi.info[type])
			return -ENOMEM;
	}

	for (i = sensor_data->wmi.sensor_count - 1; i >= 0; i--) {
		temp_sensor = devm_kzalloc(dev, sizeof(*temp_sensor), GFP_KERNEL);
		if (!temp_sensor)
			return -ENOMEM;

		err = asus_wmi_sensor_info(i, temp_sensor);
		if (err)
			continue;

		switch (temp_sensor->data_type) {
		case TEMPERATURE_C:
		case VOLTAGE:
		case CURRENT:
		case FAN_RPM:
		case WATER_FLOW:
			type = asus_data_types[temp_sensor->data_type];
			idx = --nr_count[type];
			*(sensor_data->wmi.info[type] + idx) = temp_sensor;
			sensor_data->wmi.info_by_id[i] = temp_sensor;
			break;
		}
	}

	dev_dbg(dev, "board has %d sensors",
		sensor_data->wmi.sensor_count);

	hwdev = devm_hwmon_device_register_with_info(dev, "asus_wmi_sensors",
						     sensor_data, chip_info, NULL);

	return PTR_ERR_OR_ZERO(hwdev);
}

static int asus_wmi_probe(struct wmi_device *wdev, const void *context)
{
	struct asus_wmi_sensors *sensor_data;
	struct device *dev = &wdev->dev;
	u32 version = 0;

	if (!dmi_check_system(asus_wmi_dmi_table))
		return -ENODEV;

	sensor_data = devm_kzalloc(dev, sizeof(*sensor_data), GFP_KERNEL);
	if (!sensor_data)
		return -ENOMEM;

	if (asus_wmi_get_version(&version))
		return -ENODEV;

	if (asus_wmi_get_item_count(&sensor_data->wmi.sensor_count))
		return -ENODEV;

	if (sensor_data->wmi.sensor_count  <= 0 || version < 2) {
		dev_info(dev, "version: %u with %d sensors is unsupported\n",
			 version, sensor_data->wmi.sensor_count);

		return -ENODEV;
	}

	mutex_init(&sensor_data->lock);

	dev_set_drvdata(dev, sensor_data);

	return asus_wmi_configure_sensor_setup(dev, sensor_data);
}

static const struct wmi_device_id asus_wmi_id_table[] = {
	{ ASUSWMI_MONITORING_GUID, NULL },
	{ }
};

static struct wmi_driver asus_sensors_wmi_driver = {
	.driver = {
		.name = "asus_wmi_sensors",
	},
	.id_table = asus_wmi_id_table,
	.probe = asus_wmi_probe,
};
module_wmi_driver(asus_sensors_wmi_driver);

MODULE_AUTHOR("Ed Brindley <kernel@maidavale.org>");
MODULE_DESCRIPTION("Asus WMI Sensors Driver");
MODULE_LICENSE("GPL");
