// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  Copyright (C) 2021 Thomas Weißschuh <thomas@weissschuh.net>
 */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/acpi.h>
#include <linux/dmi.h>
#include <linux/hwmon.h>
#include <linux/module.h>
#include <linux/wmi.h>

#define GIGABYTE_WMI_GUID	"DEADBEEF-2001-0000-00A0-C90629100000"
#define NUM_TEMPERATURE_SENSORS	6

static bool force_load;
module_param(force_load, bool, 0444);
MODULE_PARM_DESC(force_load, "Force loading on unknown platform");

static u8 usable_sensors_mask;

enum gigabyte_wmi_commandtype {
	GIGABYTE_WMI_BUILD_DATE_QUERY       =   0x1,
	GIGABYTE_WMI_MAINBOARD_TYPE_QUERY   =   0x2,
	GIGABYTE_WMI_FIRMWARE_VERSION_QUERY =   0x4,
	GIGABYTE_WMI_MAINBOARD_NAME_QUERY   =   0x5,
	GIGABYTE_WMI_TEMPERATURE_QUERY      = 0x125,
};

struct gigabyte_wmi_args {
	u32 arg1;
};

static int gigabyte_wmi_perform_query(struct wmi_device *wdev,
				      enum gigabyte_wmi_commandtype command,
				      struct gigabyte_wmi_args *args, struct acpi_buffer *out)
{
	const struct acpi_buffer in = {
		.length = sizeof(*args),
		.pointer = args,
	};

	acpi_status ret = wmidev_evaluate_method(wdev, 0x0, command, &in, out);

	if (ACPI_FAILURE(ret))
		return -EIO;

	return 0;
}

static int gigabyte_wmi_query_integer(struct wmi_device *wdev,
				      enum gigabyte_wmi_commandtype command,
				      struct gigabyte_wmi_args *args, u64 *res)
{
	union acpi_object *obj;
	struct acpi_buffer result = { ACPI_ALLOCATE_BUFFER, NULL };
	int ret;

	ret = gigabyte_wmi_perform_query(wdev, command, args, &result);
	if (ret)
		return ret;
	obj = result.pointer;
	if (obj && obj->type == ACPI_TYPE_INTEGER)
		*res = obj->integer.value;
	else
		ret = -EIO;
	kfree(result.pointer);
	return ret;
}

static int gigabyte_wmi_temperature(struct wmi_device *wdev, u8 sensor, long *res)
{
	struct gigabyte_wmi_args args = {
		.arg1 = sensor,
	};
	u64 temp;
	acpi_status ret;

	ret = gigabyte_wmi_query_integer(wdev, GIGABYTE_WMI_TEMPERATURE_QUERY, &args, &temp);
	if (ret == 0) {
		if (temp == 0)
			return -ENODEV;
		*res = (s8)temp * 1000; // value is a signed 8-bit integer
	}
	return ret;
}

static int gigabyte_wmi_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
				   u32 attr, int channel, long *val)
{
	struct wmi_device *wdev = dev_get_drvdata(dev);

	return gigabyte_wmi_temperature(wdev, channel, val);
}

static umode_t gigabyte_wmi_hwmon_is_visible(const void *data, enum hwmon_sensor_types type,
					     u32 attr, int channel)
{
	return usable_sensors_mask & BIT(channel) ? 0444  : 0;
}

static const struct hwmon_channel_info *gigabyte_wmi_hwmon_info[] = {
	HWMON_CHANNEL_INFO(temp,
			   HWMON_T_INPUT,
			   HWMON_T_INPUT,
			   HWMON_T_INPUT,
			   HWMON_T_INPUT,
			   HWMON_T_INPUT,
			   HWMON_T_INPUT),
	NULL
};

static const struct hwmon_ops gigabyte_wmi_hwmon_ops = {
	.read = gigabyte_wmi_hwmon_read,
	.is_visible = gigabyte_wmi_hwmon_is_visible,
};

static const struct hwmon_chip_info gigabyte_wmi_hwmon_chip_info = {
	.ops = &gigabyte_wmi_hwmon_ops,
	.info = gigabyte_wmi_hwmon_info,
};

static u8 gigabyte_wmi_detect_sensor_usability(struct wmi_device *wdev)
{
	int i;
	long temp;
	u8 r = 0;

	for (i = 0; i < NUM_TEMPERATURE_SENSORS; i++) {
		if (!gigabyte_wmi_temperature(wdev, i, &temp))
			r |= BIT(i);
	}
	return r;
}

#define DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME(name) \
	{ .matches = { \
		DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."), \
		DMI_EXACT_MATCH(DMI_BOARD_NAME, name), \
	}}

static const struct dmi_system_id gigabyte_wmi_known_working_platforms[] = {
	DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B450M S2H V2"),
	DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550 AORUS ELITE AX V2"),
	DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550 AORUS ELITE"),
	DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550 AORUS ELITE V2"),
	DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550 GAMING X V2"),
	DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550I AORUS PRO AX"),
	DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550M AORUS PRO-P"),
	DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550M DS3H"),
	DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("Z390 I AORUS PRO WIFI-CF"),
	DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("X570 AORUS ELITE"),
	DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("X570 GAMING X"),
	DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("X570 I AORUS PRO WIFI"),
	DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("X570 UD"),
	{ }
};

static int gigabyte_wmi_probe(struct wmi_device *wdev, const void *context)
{
	struct device *hwmon_dev;

	if (!dmi_check_system(gigabyte_wmi_known_working_platforms)) {
		if (!force_load)
			return -ENODEV;
		dev_warn(&wdev->dev, "Forcing load on unknown platform");
	}

	usable_sensors_mask = gigabyte_wmi_detect_sensor_usability(wdev);
	if (!usable_sensors_mask) {
		dev_info(&wdev->dev, "No temperature sensors usable");
		return -ENODEV;
	}

	hwmon_dev = devm_hwmon_device_register_with_info(&wdev->dev, "gigabyte_wmi", wdev,
							 &gigabyte_wmi_hwmon_chip_info, NULL);

	return PTR_ERR_OR_ZERO(hwmon_dev);
}

static const struct wmi_device_id gigabyte_wmi_id_table[] = {
	{ GIGABYTE_WMI_GUID, NULL },
	{ }
};

static struct wmi_driver gigabyte_wmi_driver = {
	.driver = {
		.name = "gigabyte-wmi",
	},
	.id_table = gigabyte_wmi_id_table,
	.probe = gigabyte_wmi_probe,
};
module_wmi_driver(gigabyte_wmi_driver);

MODULE_DEVICE_TABLE(wmi, gigabyte_wmi_id_table);
MODULE_AUTHOR("Thomas Weißschuh <thomas@weissschuh.net>");
MODULE_DESCRIPTION("Gigabyte WMI temperature driver");
MODULE_LICENSE("GPL");
