// SPDX-License-Identifier: GPL-2.0+
/*
 * nzxt-kraken2.c - hwmon driver for NZXT Kraken X42/X52/X62/X72 coolers
 *
 * The device asynchronously sends HID reports (with id 0x04) twice a second to
 * communicate current fan speed, pump speed and coolant temperature.  The
 * device does not respond to Get_Report requests for this status report.
 *
 * Copyright 2019-2021  Jonas Malaco <jonas@protocubo.io>
 */

#include <asm/unaligned.h>
#include <linux/hid.h>
#include <linux/hwmon.h>
#include <linux/jiffies.h>
#include <linux/module.h>

#define STATUS_REPORT_ID	0x04
#define STATUS_VALIDITY		2 /* seconds; equivalent to 4 missed updates */

static const char *const kraken2_temp_label[] = {
	"Coolant",
};

static const char *const kraken2_fan_label[] = {
	"Fan",
	"Pump",
};

struct kraken2_priv_data {
	struct hid_device *hid_dev;
	struct device *hwmon_dev;
	s32 temp_input[1];
	u16 fan_input[2];
	unsigned long updated; /* jiffies */
};

static umode_t kraken2_is_visible(const void *data,
				  enum hwmon_sensor_types type,
				  u32 attr, int channel)
{
	return 0444;
}

static int kraken2_read(struct device *dev, enum hwmon_sensor_types type,
			u32 attr, int channel, long *val)
{
	struct kraken2_priv_data *priv = dev_get_drvdata(dev);

	if (time_after(jiffies, priv->updated + STATUS_VALIDITY * HZ))
		return -ENODATA;

	switch (type) {
	case hwmon_temp:
		*val = priv->temp_input[channel];
		break;
	case hwmon_fan:
		*val = priv->fan_input[channel];
		break;
	default:
		return -EOPNOTSUPP; /* unreachable */
	}

	return 0;
}

static int kraken2_read_string(struct device *dev, enum hwmon_sensor_types type,
			       u32 attr, int channel, const char **str)
{
	switch (type) {
	case hwmon_temp:
		*str = kraken2_temp_label[channel];
		break;
	case hwmon_fan:
		*str = kraken2_fan_label[channel];
		break;
	default:
		return -EOPNOTSUPP; /* unreachable */
	}
	return 0;
}

static const struct hwmon_ops kraken2_hwmon_ops = {
	.is_visible = kraken2_is_visible,
	.read = kraken2_read,
	.read_string = kraken2_read_string,
};

static const struct hwmon_channel_info * const kraken2_info[] = {
	HWMON_CHANNEL_INFO(temp,
			   HWMON_T_INPUT | HWMON_T_LABEL),
	HWMON_CHANNEL_INFO(fan,
			   HWMON_F_INPUT | HWMON_F_LABEL,
			   HWMON_F_INPUT | HWMON_F_LABEL),
	NULL
};

static const struct hwmon_chip_info kraken2_chip_info = {
	.ops = &kraken2_hwmon_ops,
	.info = kraken2_info,
};

static int kraken2_raw_event(struct hid_device *hdev,
			     struct hid_report *report, u8 *data, int size)
{
	struct kraken2_priv_data *priv;

	if (size < 7 || report->id != STATUS_REPORT_ID)
		return 0;

	priv = hid_get_drvdata(hdev);

	/*
	 * The fractional byte of the coolant temperature has been observed to
	 * be in the interval [1,9], but some of these steps are also
	 * consistently skipped for certain integer parts.
	 *
	 * For the lack of a better idea, assume that the resolution is 0.1°C,
	 * and that the missing steps are artifacts of how the firmware
	 * processes the raw sensor data.
	 */
	priv->temp_input[0] = data[1] * 1000 + data[2] * 100;

	priv->fan_input[0] = get_unaligned_be16(data + 3);
	priv->fan_input[1] = get_unaligned_be16(data + 5);

	priv->updated = jiffies;

	return 0;
}

static int kraken2_probe(struct hid_device *hdev,
			 const struct hid_device_id *id)
{
	struct kraken2_priv_data *priv;
	int ret;

	priv = devm_kzalloc(&hdev->dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	priv->hid_dev = hdev;
	hid_set_drvdata(hdev, priv);

	/*
	 * Initialize ->updated to STATUS_VALIDITY seconds in the past, making
	 * the initial empty data invalid for kraken2_read without the need for
	 * a special case there.
	 */
	priv->updated = jiffies - STATUS_VALIDITY * HZ;

	ret = hid_parse(hdev);
	if (ret) {
		hid_err(hdev, "hid parse failed with %d\n", ret);
		return ret;
	}

	/*
	 * Enable hidraw so existing user-space tools can continue to work.
	 */
	ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW);
	if (ret) {
		hid_err(hdev, "hid hw start failed with %d\n", ret);
		return ret;
	}

	ret = hid_hw_open(hdev);
	if (ret) {
		hid_err(hdev, "hid hw open failed with %d\n", ret);
		goto fail_and_stop;
	}

	priv->hwmon_dev = hwmon_device_register_with_info(&hdev->dev, "kraken2",
							  priv, &kraken2_chip_info,
							  NULL);
	if (IS_ERR(priv->hwmon_dev)) {
		ret = PTR_ERR(priv->hwmon_dev);
		hid_err(hdev, "hwmon registration failed with %d\n", ret);
		goto fail_and_close;
	}

	return 0;

fail_and_close:
	hid_hw_close(hdev);
fail_and_stop:
	hid_hw_stop(hdev);
	return ret;
}

static void kraken2_remove(struct hid_device *hdev)
{
	struct kraken2_priv_data *priv = hid_get_drvdata(hdev);

	hwmon_device_unregister(priv->hwmon_dev);

	hid_hw_close(hdev);
	hid_hw_stop(hdev);
}

static const struct hid_device_id kraken2_table[] = {
	{ HID_USB_DEVICE(0x1e71, 0x170e) }, /* NZXT Kraken X42/X52/X62/X72 */
	{ }
};

MODULE_DEVICE_TABLE(hid, kraken2_table);

static struct hid_driver kraken2_driver = {
	.name = "nzxt-kraken2",
	.id_table = kraken2_table,
	.probe = kraken2_probe,
	.remove = kraken2_remove,
	.raw_event = kraken2_raw_event,
};

static int __init kraken2_init(void)
{
	return hid_register_driver(&kraken2_driver);
}

static void __exit kraken2_exit(void)
{
	hid_unregister_driver(&kraken2_driver);
}

/*
 * When compiled into the kernel, initialize after the hid bus.
 */
late_initcall(kraken2_init);
module_exit(kraken2_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jonas Malaco <jonas@protocubo.io>");
MODULE_DESCRIPTION("Hwmon driver for NZXT Kraken X42/X52/X62/X72 coolers");
