// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Reverse-engineered NZXT RGB & Fan Controller/Smart Device v2 driver.
 *
 * Copyright (c) 2021 Aleksandr Mezin
 */

#include <linux/hid.h>
#include <linux/hwmon.h>
#include <linux/math.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/spinlock.h>
#include <linux/wait.h>

#include <asm/byteorder.h>
#include <asm/unaligned.h>

/*
 * The device has only 3 fan channels/connectors. But all HID reports have
 * space reserved for up to 8 channels.
 */
#define FAN_CHANNELS 3
#define FAN_CHANNELS_MAX 8

#define UPDATE_INTERVAL_DEFAULT_MS 1000

/* These strings match labels on the device exactly */
static const char *const fan_label[] = {
	"FAN 1",
	"FAN 2",
	"FAN 3",
};

static const char *const curr_label[] = {
	"FAN 1 Current",
	"FAN 2 Current",
	"FAN 3 Current",
};

static const char *const in_label[] = {
	"FAN 1 Voltage",
	"FAN 2 Voltage",
	"FAN 3 Voltage",
};

enum {
	INPUT_REPORT_ID_FAN_CONFIG = 0x61,
	INPUT_REPORT_ID_FAN_STATUS = 0x67,
};

enum {
	FAN_STATUS_REPORT_SPEED = 0x02,
	FAN_STATUS_REPORT_VOLTAGE = 0x04,
};

enum {
	FAN_TYPE_NONE = 0,
	FAN_TYPE_DC = 1,
	FAN_TYPE_PWM = 2,
};

struct unknown_static_data {
	/*
	 * Some configuration data? Stays the same after fan speed changes,
	 * changes in fan configuration, reboots and driver reloads.
	 *
	 * The same data in multiple report types.
	 *
	 * Byte 12 seems to be the number of fan channels, but I am not sure.
	 */
	u8 unknown1[14];
} __packed;

/*
 * The device sends this input report in response to "detect fans" command:
 * a 2-byte output report { 0x60, 0x03 }.
 */
struct fan_config_report {
	/* report_id should be INPUT_REPORT_ID_FAN_CONFIG = 0x61 */
	u8 report_id;
	/* Always 0x03 */
	u8 magic;
	struct unknown_static_data unknown_data;
	/* Fan type as detected by the device. See FAN_TYPE_* enum. */
	u8 fan_type[FAN_CHANNELS_MAX];
} __packed;

/*
 * The device sends these reports at a fixed interval (update interval) -
 * one report with type = FAN_STATUS_REPORT_SPEED, and one report with type =
 * FAN_STATUS_REPORT_VOLTAGE per update interval.
 */
struct fan_status_report {
	/* report_id should be INPUT_REPORT_ID_STATUS = 0x67 */
	u8 report_id;
	/* FAN_STATUS_REPORT_SPEED = 0x02 or FAN_STATUS_REPORT_VOLTAGE = 0x04 */
	u8 type;
	struct unknown_static_data unknown_data;
	/* Fan type as detected by the device. See FAN_TYPE_* enum. */
	u8 fan_type[FAN_CHANNELS_MAX];

	union {
		/* When type == FAN_STATUS_REPORT_SPEED */
		struct {
			/*
			 * Fan speed, in RPM. Zero for channels without fans
			 * connected.
			 */
			__le16 fan_rpm[FAN_CHANNELS_MAX];
			/*
			 * Fan duty cycle, in percent. Non-zero even for
			 * channels without fans connected.
			 */
			u8 duty_percent[FAN_CHANNELS_MAX];
			/*
			 * Exactly the same values as duty_percent[], non-zero
			 * for disconnected fans too.
			 */
			u8 duty_percent_dup[FAN_CHANNELS_MAX];
			/* "Case Noise" in db */
			u8 noise_db;
		} __packed fan_speed;
		/* When type == FAN_STATUS_REPORT_VOLTAGE */
		struct {
			/*
			 * Voltage, in millivolts. Non-zero even when fan is
			 * not connected.
			 */
			__le16 fan_in[FAN_CHANNELS_MAX];
			/*
			 * Current, in milliamperes. Near-zero when
			 * disconnected.
			 */
			__le16 fan_current[FAN_CHANNELS_MAX];
		} __packed fan_voltage;
	} __packed;
} __packed;

#define OUTPUT_REPORT_SIZE 64

enum {
	OUTPUT_REPORT_ID_INIT_COMMAND = 0x60,
	OUTPUT_REPORT_ID_SET_FAN_SPEED = 0x62,
};

enum {
	INIT_COMMAND_SET_UPDATE_INTERVAL = 0x02,
	INIT_COMMAND_DETECT_FANS = 0x03,
};

/*
 * This output report sets pwm duty cycle/target fan speed for one or more
 * channels.
 */
struct set_fan_speed_report {
	/* report_id should be OUTPUT_REPORT_ID_SET_FAN_SPEED = 0x62 */
	u8 report_id;
	/* Should be 0x01 */
	u8 magic;
	/* To change fan speed on i-th channel, set i-th bit here */
	u8 channel_bit_mask;
	/*
	 * Fan duty cycle/target speed in percent. For voltage-controlled fans,
	 * the minimal voltage (duty_percent = 1) is about 9V.
	 * Setting duty_percent to 0 (if the channel is selected in
	 * channel_bit_mask) turns off the fan completely (regardless of the
	 * control mode).
	 */
	u8 duty_percent[FAN_CHANNELS_MAX];
} __packed;

struct drvdata {
	struct hid_device *hid;
	struct device *hwmon;

	u8 fan_duty_percent[FAN_CHANNELS];
	u16 fan_rpm[FAN_CHANNELS];
	bool pwm_status_received;

	u16 fan_in[FAN_CHANNELS];
	u16 fan_curr[FAN_CHANNELS];
	bool voltage_status_received;

	u8 fan_type[FAN_CHANNELS];
	bool fan_config_received;

	/*
	 * wq is used to wait for *_received flags to become true.
	 * All accesses to *_received flags and fan_* arrays are performed with
	 * wq.lock held.
	 */
	wait_queue_head_t wq;
	/*
	 * mutex is used to:
	 * 1) Prevent concurrent conflicting changes to update interval and pwm
	 * values (after sending an output hid report, the corresponding field
	 * in drvdata must be updated, and only then new output reports can be
	 * sent).
	 * 2) Synchronize access to output_buffer (well, the buffer is here,
	 * because synchronization is necessary anyway - so why not get rid of
	 * a kmalloc?).
	 */
	struct mutex mutex;
	long update_interval;
	u8 output_buffer[OUTPUT_REPORT_SIZE];
};

static long scale_pwm_value(long val, long orig_max, long new_max)
{
	if (val <= 0)
		return 0;

	/*
	 * Positive values should not become zero: 0 completely turns off the
	 * fan.
	 */
	return max(1L, DIV_ROUND_CLOSEST(min(val, orig_max) * new_max, orig_max));
}

static void handle_fan_config_report(struct drvdata *drvdata, void *data, int size)
{
	struct fan_config_report *report = data;
	int i;

	if (size < sizeof(struct fan_config_report))
		return;

	if (report->magic != 0x03)
		return;

	spin_lock(&drvdata->wq.lock);

	for (i = 0; i < FAN_CHANNELS; i++)
		drvdata->fan_type[i] = report->fan_type[i];

	drvdata->fan_config_received = true;
	wake_up_all_locked(&drvdata->wq);
	spin_unlock(&drvdata->wq.lock);
}

static void handle_fan_status_report(struct drvdata *drvdata, void *data, int size)
{
	struct fan_status_report *report = data;
	int i;

	if (size < sizeof(struct fan_status_report))
		return;

	spin_lock(&drvdata->wq.lock);

	/*
	 * The device sends INPUT_REPORT_ID_FAN_CONFIG = 0x61 report in response
	 * to "detect fans" command. Only accept other data after getting 0x61,
	 * to make sure that fan detection is complete. In particular, fan
	 * detection resets pwm values.
	 */
	if (!drvdata->fan_config_received) {
		spin_unlock(&drvdata->wq.lock);
		return;
	}

	for (i = 0; i < FAN_CHANNELS; i++) {
		if (drvdata->fan_type[i] == report->fan_type[i])
			continue;

		/*
		 * This should not happen (if my expectations about the device
		 * are correct).
		 *
		 * Even if the userspace sends fan detect command through
		 * hidraw, fan config report should arrive first.
		 */
		hid_warn_once(drvdata->hid,
			      "Fan %d type changed unexpectedly from %d to %d",
			      i, drvdata->fan_type[i], report->fan_type[i]);
		drvdata->fan_type[i] = report->fan_type[i];
	}

	switch (report->type) {
	case FAN_STATUS_REPORT_SPEED:
		for (i = 0; i < FAN_CHANNELS; i++) {
			drvdata->fan_rpm[i] =
				get_unaligned_le16(&report->fan_speed.fan_rpm[i]);
			drvdata->fan_duty_percent[i] =
				report->fan_speed.duty_percent[i];
		}

		drvdata->pwm_status_received = true;
		wake_up_all_locked(&drvdata->wq);
		break;

	case FAN_STATUS_REPORT_VOLTAGE:
		for (i = 0; i < FAN_CHANNELS; i++) {
			drvdata->fan_in[i] =
				get_unaligned_le16(&report->fan_voltage.fan_in[i]);
			drvdata->fan_curr[i] =
				get_unaligned_le16(&report->fan_voltage.fan_current[i]);
		}

		drvdata->voltage_status_received = true;
		wake_up_all_locked(&drvdata->wq);
		break;
	}

	spin_unlock(&drvdata->wq.lock);
}

static umode_t nzxt_smart2_hwmon_is_visible(const void *data,
					    enum hwmon_sensor_types type,
					    u32 attr, int channel)
{
	switch (type) {
	case hwmon_pwm:
		switch (attr) {
		case hwmon_pwm_input:
		case hwmon_pwm_enable:
			return 0644;

		default:
			return 0444;
		}

	case hwmon_chip:
		switch (attr) {
		case hwmon_chip_update_interval:
			return 0644;

		default:
			return 0444;
		}

	default:
		return 0444;
	}
}

static int nzxt_smart2_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
				  u32 attr, int channel, long *val)
{
	struct drvdata *drvdata = dev_get_drvdata(dev);
	int res = -EINVAL;

	if (type == hwmon_chip) {
		switch (attr) {
		case hwmon_chip_update_interval:
			*val = drvdata->update_interval;
			return 0;

		default:
			return -EINVAL;
		}
	}

	spin_lock_irq(&drvdata->wq.lock);

	switch (type) {
	case hwmon_pwm:
		/*
		 * fancontrol:
		 * 1) remembers pwm* values when it starts
		 * 2) needs pwm*_enable to be 1 on controlled fans
		 * So make sure we have correct data before allowing pwm* reads.
		 * Returning errors for pwm of fan speed read can even cause
		 * fancontrol to shut down. So the wait is unavoidable.
		 */
		switch (attr) {
		case hwmon_pwm_enable:
			res = wait_event_interruptible_locked_irq(drvdata->wq,
								  drvdata->fan_config_received);
			if (res)
				goto unlock;

			*val = drvdata->fan_type[channel] != FAN_TYPE_NONE;
			break;

		case hwmon_pwm_mode:
			res = wait_event_interruptible_locked_irq(drvdata->wq,
								  drvdata->fan_config_received);
			if (res)
				goto unlock;

			*val = drvdata->fan_type[channel] == FAN_TYPE_PWM;
			break;

		case hwmon_pwm_input:
			res = wait_event_interruptible_locked_irq(drvdata->wq,
								  drvdata->pwm_status_received);
			if (res)
				goto unlock;

			*val = scale_pwm_value(drvdata->fan_duty_percent[channel],
					       100, 255);
			break;
		}
		break;

	case hwmon_fan:
		/*
		 * It's not strictly necessary to wait for *_received in the
		 * remaining cases (fancontrol doesn't care about them). But I'm
		 * doing it to have consistent behavior.
		 */
		if (attr == hwmon_fan_input) {
			res = wait_event_interruptible_locked_irq(drvdata->wq,
								  drvdata->pwm_status_received);
			if (res)
				goto unlock;

			*val = drvdata->fan_rpm[channel];
		}
		break;

	case hwmon_in:
		if (attr == hwmon_in_input) {
			res = wait_event_interruptible_locked_irq(drvdata->wq,
								  drvdata->voltage_status_received);
			if (res)
				goto unlock;

			*val = drvdata->fan_in[channel];
		}
		break;

	case hwmon_curr:
		if (attr == hwmon_curr_input) {
			res = wait_event_interruptible_locked_irq(drvdata->wq,
								  drvdata->voltage_status_received);
			if (res)
				goto unlock;

			*val = drvdata->fan_curr[channel];
		}
		break;

	default:
		break;
	}

unlock:
	spin_unlock_irq(&drvdata->wq.lock);
	return res;
}

static int send_output_report(struct drvdata *drvdata, const void *data,
			      size_t data_size)
{
	int ret;

	if (data_size > sizeof(drvdata->output_buffer))
		return -EINVAL;

	memcpy(drvdata->output_buffer, data, data_size);

	if (data_size < sizeof(drvdata->output_buffer))
		memset(drvdata->output_buffer + data_size, 0,
		       sizeof(drvdata->output_buffer) - data_size);

	ret = hid_hw_output_report(drvdata->hid, drvdata->output_buffer,
				   sizeof(drvdata->output_buffer));
	return ret < 0 ? ret : 0;
}

static int set_pwm(struct drvdata *drvdata, int channel, long val)
{
	int ret;
	u8 duty_percent = scale_pwm_value(val, 255, 100);

	struct set_fan_speed_report report = {
		.report_id = OUTPUT_REPORT_ID_SET_FAN_SPEED,
		.magic = 1,
		.channel_bit_mask = 1 << channel
	};

	ret = mutex_lock_interruptible(&drvdata->mutex);
	if (ret)
		return ret;

	report.duty_percent[channel] = duty_percent;
	ret = send_output_report(drvdata, &report, sizeof(report));
	if (ret)
		goto unlock;

	/*
	 * pwmconfig and fancontrol scripts expect pwm writes to take effect
	 * immediately (i. e. read from pwm* sysfs should return the value
	 * written into it). The device seems to always accept pwm values - even
	 * when there is no fan connected - so update pwm status without waiting
	 * for a report, to make pwmconfig and fancontrol happy. Worst case -
	 * if the device didn't accept new pwm value for some reason (never seen
	 * this in practice) - it will be reported incorrectly only until next
	 * update. This avoids "fan stuck" messages from pwmconfig, and
	 * fancontrol setting fan speed to 100% during shutdown.
	 */
	spin_lock_bh(&drvdata->wq.lock);
	drvdata->fan_duty_percent[channel] = duty_percent;
	spin_unlock_bh(&drvdata->wq.lock);

unlock:
	mutex_unlock(&drvdata->mutex);
	return ret;
}

/*
 * Workaround for fancontrol/pwmconfig trying to write to pwm*_enable even if it
 * already is 1 and read-only. Otherwise, fancontrol won't restore pwm on
 * shutdown properly.
 */
static int set_pwm_enable(struct drvdata *drvdata, int channel, long val)
{
	long expected_val;
	int res;

	spin_lock_irq(&drvdata->wq.lock);

	res = wait_event_interruptible_locked_irq(drvdata->wq,
						  drvdata->fan_config_received);
	if (res) {
		spin_unlock_irq(&drvdata->wq.lock);
		return res;
	}

	expected_val = drvdata->fan_type[channel] != FAN_TYPE_NONE;

	spin_unlock_irq(&drvdata->wq.lock);

	return (val == expected_val) ? 0 : -EOPNOTSUPP;
}

/*
 * Control byte	| Actual update interval in seconds
 * 0xff		| 65.5
 * 0xf7		| 63.46
 * 0x7f		| 32.74
 * 0x3f		| 16.36
 * 0x1f		| 8.17
 * 0x0f		| 4.07
 * 0x07		| 2.02
 * 0x03		| 1.00
 * 0x02		| 0.744
 * 0x01		| 0.488
 * 0x00		| 0.25
 */
static u8 update_interval_to_control_byte(long interval)
{
	if (interval <= 250)
		return 0;

	return clamp_val(1 + DIV_ROUND_CLOSEST(interval - 488, 256), 0, 255);
}

static long control_byte_to_update_interval(u8 control_byte)
{
	if (control_byte == 0)
		return 250;

	return 488 + (control_byte - 1) * 256;
}

static int set_update_interval(struct drvdata *drvdata, long val)
{
	u8 control = update_interval_to_control_byte(val);
	u8 report[] = {
		OUTPUT_REPORT_ID_INIT_COMMAND,
		INIT_COMMAND_SET_UPDATE_INTERVAL,
		0x01,
		0xe8,
		control,
		0x01,
		0xe8,
		control,
	};
	int ret;

	ret = send_output_report(drvdata, report, sizeof(report));
	if (ret)
		return ret;

	drvdata->update_interval = control_byte_to_update_interval(control);
	return 0;
}

static int init_device(struct drvdata *drvdata, long update_interval)
{
	int ret;
	static const u8 detect_fans_report[] = {
		OUTPUT_REPORT_ID_INIT_COMMAND,
		INIT_COMMAND_DETECT_FANS,
	};

	ret = send_output_report(drvdata, detect_fans_report,
				 sizeof(detect_fans_report));
	if (ret)
		return ret;

	return set_update_interval(drvdata, update_interval);
}

static int nzxt_smart2_hwmon_write(struct device *dev,
				   enum hwmon_sensor_types type, u32 attr,
				   int channel, long val)
{
	struct drvdata *drvdata = dev_get_drvdata(dev);
	int ret;

	switch (type) {
	case hwmon_pwm:
		switch (attr) {
		case hwmon_pwm_enable:
			return set_pwm_enable(drvdata, channel, val);

		case hwmon_pwm_input:
			return set_pwm(drvdata, channel, val);

		default:
			return -EINVAL;
		}

	case hwmon_chip:
		switch (attr) {
		case hwmon_chip_update_interval:
			ret = mutex_lock_interruptible(&drvdata->mutex);
			if (ret)
				return ret;

			ret = set_update_interval(drvdata, val);

			mutex_unlock(&drvdata->mutex);
			return ret;

		default:
			return -EINVAL;
		}

	default:
		return -EINVAL;
	}
}

static int nzxt_smart2_hwmon_read_string(struct device *dev,
					 enum hwmon_sensor_types type, u32 attr,
					 int channel, const char **str)
{
	switch (type) {
	case hwmon_fan:
		*str = fan_label[channel];
		return 0;
	case hwmon_curr:
		*str = curr_label[channel];
		return 0;
	case hwmon_in:
		*str = in_label[channel];
		return 0;
	default:
		return -EINVAL;
	}
}

static const struct hwmon_ops nzxt_smart2_hwmon_ops = {
	.is_visible = nzxt_smart2_hwmon_is_visible,
	.read = nzxt_smart2_hwmon_read,
	.read_string = nzxt_smart2_hwmon_read_string,
	.write = nzxt_smart2_hwmon_write,
};

static const struct hwmon_channel_info *nzxt_smart2_channel_info[] = {
	HWMON_CHANNEL_INFO(fan, HWMON_F_INPUT | HWMON_F_LABEL,
			   HWMON_F_INPUT | HWMON_F_LABEL,
			   HWMON_F_INPUT | HWMON_F_LABEL),
	HWMON_CHANNEL_INFO(pwm, HWMON_PWM_INPUT | HWMON_PWM_MODE | HWMON_PWM_ENABLE,
			   HWMON_PWM_INPUT | HWMON_PWM_MODE | HWMON_PWM_ENABLE,
			   HWMON_PWM_INPUT | HWMON_PWM_MODE | HWMON_PWM_ENABLE),
	HWMON_CHANNEL_INFO(in, HWMON_I_INPUT | HWMON_I_LABEL,
			   HWMON_I_INPUT | HWMON_I_LABEL,
			   HWMON_I_INPUT | HWMON_I_LABEL),
	HWMON_CHANNEL_INFO(curr, HWMON_C_INPUT | HWMON_C_LABEL,
			   HWMON_C_INPUT | HWMON_C_LABEL,
			   HWMON_C_INPUT | HWMON_C_LABEL),
	HWMON_CHANNEL_INFO(chip, HWMON_C_UPDATE_INTERVAL),
	NULL
};

static const struct hwmon_chip_info nzxt_smart2_chip_info = {
	.ops = &nzxt_smart2_hwmon_ops,
	.info = nzxt_smart2_channel_info,
};

static int nzxt_smart2_hid_raw_event(struct hid_device *hdev,
				     struct hid_report *report, u8 *data, int size)
{
	struct drvdata *drvdata = hid_get_drvdata(hdev);
	u8 report_id = *data;

	switch (report_id) {
	case INPUT_REPORT_ID_FAN_CONFIG:
		handle_fan_config_report(drvdata, data, size);
		break;

	case INPUT_REPORT_ID_FAN_STATUS:
		handle_fan_status_report(drvdata, data, size);
		break;
	}

	return 0;
}

static int __maybe_unused nzxt_smart2_hid_reset_resume(struct hid_device *hdev)
{
	struct drvdata *drvdata = hid_get_drvdata(hdev);

	/*
	 * Userspace is still frozen (so no concurrent sysfs attribute access
	 * is possible), but raw_event can already be called concurrently.
	 */
	spin_lock_bh(&drvdata->wq.lock);
	drvdata->fan_config_received = false;
	drvdata->pwm_status_received = false;
	drvdata->voltage_status_received = false;
	spin_unlock_bh(&drvdata->wq.lock);

	return init_device(drvdata, drvdata->update_interval);
}

static int nzxt_smart2_hid_probe(struct hid_device *hdev,
				 const struct hid_device_id *id)
{
	struct drvdata *drvdata;
	int ret;

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

	drvdata->hid = hdev;
	hid_set_drvdata(hdev, drvdata);

	init_waitqueue_head(&drvdata->wq);

	mutex_init(&drvdata->mutex);
	devm_add_action(&hdev->dev, (void (*)(void *))mutex_destroy,
			&drvdata->mutex);

	ret = hid_parse(hdev);
	if (ret)
		return ret;

	ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW);
	if (ret)
		return ret;

	ret = hid_hw_open(hdev);
	if (ret)
		goto out_hw_stop;

	hid_device_io_start(hdev);

	init_device(drvdata, UPDATE_INTERVAL_DEFAULT_MS);

	drvdata->hwmon =
		hwmon_device_register_with_info(&hdev->dev, "nzxtsmart2", drvdata,
						&nzxt_smart2_chip_info, NULL);
	if (IS_ERR(drvdata->hwmon)) {
		ret = PTR_ERR(drvdata->hwmon);
		goto out_hw_close;
	}

	return 0;

out_hw_close:
	hid_hw_close(hdev);

out_hw_stop:
	hid_hw_stop(hdev);
	return ret;
}

static void nzxt_smart2_hid_remove(struct hid_device *hdev)
{
	struct drvdata *drvdata = hid_get_drvdata(hdev);

	hwmon_device_unregister(drvdata->hwmon);

	hid_hw_close(hdev);
	hid_hw_stop(hdev);
}

static const struct hid_device_id nzxt_smart2_hid_id_table[] = {
	{ HID_USB_DEVICE(0x1e71, 0x2006) }, /* NZXT Smart Device V2 */
	{ HID_USB_DEVICE(0x1e71, 0x200d) }, /* NZXT Smart Device V2 */
	{ HID_USB_DEVICE(0x1e71, 0x2009) }, /* NZXT RGB & Fan Controller */
	{ HID_USB_DEVICE(0x1e71, 0x200e) }, /* NZXT RGB & Fan Controller */
	{ HID_USB_DEVICE(0x1e71, 0x2010) }, /* NZXT RGB & Fan Controller */
	{},
};

static struct hid_driver nzxt_smart2_hid_driver = {
	.name = "nzxt-smart2",
	.id_table = nzxt_smart2_hid_id_table,
	.probe = nzxt_smart2_hid_probe,
	.remove = nzxt_smart2_hid_remove,
	.raw_event = nzxt_smart2_hid_raw_event,
#ifdef CONFIG_PM
	.reset_resume = nzxt_smart2_hid_reset_resume,
#endif
};

static int __init nzxt_smart2_init(void)
{
	return hid_register_driver(&nzxt_smart2_hid_driver);
}

static void __exit nzxt_smart2_exit(void)
{
	hid_unregister_driver(&nzxt_smart2_hid_driver);
}

MODULE_DEVICE_TABLE(hid, nzxt_smart2_hid_id_table);
MODULE_AUTHOR("Aleksandr Mezin <mezin.alexander@gmail.com>");
MODULE_DESCRIPTION("Driver for NZXT RGB & Fan Controller/Smart Device V2");
MODULE_LICENSE("GPL");

/*
 * With module_init()/module_hid_driver() and the driver built into the kernel:
 *
 * Driver 'nzxt_smart2' was unable to register with bus_type 'hid' because the
 * bus was not initialized.
 */
late_initcall(nzxt_smart2_init);
module_exit(nzxt_smart2_exit);
