// 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;

	for (i = 0; i < sensor_data->wmi.sensor_count; i++) {
		struct asus_wmi_sensor_info sensor;

		err = asus_wmi_sensor_info(i, &sensor);
		if (err)
			return err;

		switch (sensor.data_type) {
		case TEMPERATURE_C:
		case VOLTAGE:
		case CURRENT:
		case FAN_RPM:
		case WATER_FLOW:
			type = asus_data_types[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");
