brintos

brintos / linux-shallow public Read only

0
0
Text · 20.0 KiB · c2d1173 Raw
840 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Reverse-engineered NZXT RGB & Fan Controller/Smart Device v2 driver.4 *5 * Copyright (c) 2021 Aleksandr Mezin6 */7 8#include <linux/hid.h>9#include <linux/hwmon.h>10#include <linux/math.h>11#include <linux/module.h>12#include <linux/mutex.h>13#include <linux/spinlock.h>14#include <linux/wait.h>15 16#include <asm/byteorder.h>17#include <linux/unaligned.h>18 19/*20 * The device has only 3 fan channels/connectors. But all HID reports have21 * space reserved for up to 8 channels.22 */23#define FAN_CHANNELS 324#define FAN_CHANNELS_MAX 825 26#define UPDATE_INTERVAL_DEFAULT_MS 100027 28/* These strings match labels on the device exactly */29static const char *const fan_label[] = {30	"FAN 1",31	"FAN 2",32	"FAN 3",33};34 35static const char *const curr_label[] = {36	"FAN 1 Current",37	"FAN 2 Current",38	"FAN 3 Current",39};40 41static const char *const in_label[] = {42	"FAN 1 Voltage",43	"FAN 2 Voltage",44	"FAN 3 Voltage",45};46 47enum {48	INPUT_REPORT_ID_FAN_CONFIG = 0x61,49	INPUT_REPORT_ID_FAN_STATUS = 0x67,50};51 52enum {53	FAN_STATUS_REPORT_SPEED = 0x02,54	FAN_STATUS_REPORT_VOLTAGE = 0x04,55};56 57enum {58	FAN_TYPE_NONE = 0,59	FAN_TYPE_DC = 1,60	FAN_TYPE_PWM = 2,61};62 63struct unknown_static_data {64	/*65	 * Some configuration data? Stays the same after fan speed changes,66	 * changes in fan configuration, reboots and driver reloads.67	 *68	 * The same data in multiple report types.69	 *70	 * Byte 12 seems to be the number of fan channels, but I am not sure.71	 */72	u8 unknown1[14];73} __packed;74 75/*76 * The device sends this input report in response to "detect fans" command:77 * a 2-byte output report { 0x60, 0x03 }.78 */79struct fan_config_report {80	/* report_id should be INPUT_REPORT_ID_FAN_CONFIG = 0x61 */81	u8 report_id;82	/* Always 0x03 */83	u8 magic;84	struct unknown_static_data unknown_data;85	/* Fan type as detected by the device. See FAN_TYPE_* enum. */86	u8 fan_type[FAN_CHANNELS_MAX];87} __packed;88 89/*90 * The device sends these reports at a fixed interval (update interval) -91 * one report with type = FAN_STATUS_REPORT_SPEED, and one report with type =92 * FAN_STATUS_REPORT_VOLTAGE per update interval.93 */94struct fan_status_report {95	/* report_id should be INPUT_REPORT_ID_STATUS = 0x67 */96	u8 report_id;97	/* FAN_STATUS_REPORT_SPEED = 0x02 or FAN_STATUS_REPORT_VOLTAGE = 0x04 */98	u8 type;99	struct unknown_static_data unknown_data;100	/* Fan type as detected by the device. See FAN_TYPE_* enum. */101	u8 fan_type[FAN_CHANNELS_MAX];102 103	union {104		/* When type == FAN_STATUS_REPORT_SPEED */105		struct {106			/*107			 * Fan speed, in RPM. Zero for channels without fans108			 * connected.109			 */110			__le16 fan_rpm[FAN_CHANNELS_MAX];111			/*112			 * Fan duty cycle, in percent. Non-zero even for113			 * channels without fans connected.114			 */115			u8 duty_percent[FAN_CHANNELS_MAX];116			/*117			 * Exactly the same values as duty_percent[], non-zero118			 * for disconnected fans too.119			 */120			u8 duty_percent_dup[FAN_CHANNELS_MAX];121			/* "Case Noise" in db */122			u8 noise_db;123		} __packed fan_speed;124		/* When type == FAN_STATUS_REPORT_VOLTAGE */125		struct {126			/*127			 * Voltage, in millivolts. Non-zero even when fan is128			 * not connected.129			 */130			__le16 fan_in[FAN_CHANNELS_MAX];131			/*132			 * Current, in milliamperes. Near-zero when133			 * disconnected.134			 */135			__le16 fan_current[FAN_CHANNELS_MAX];136		} __packed fan_voltage;137	} __packed;138} __packed;139 140#define OUTPUT_REPORT_SIZE 64141 142enum {143	OUTPUT_REPORT_ID_INIT_COMMAND = 0x60,144	OUTPUT_REPORT_ID_SET_FAN_SPEED = 0x62,145};146 147enum {148	INIT_COMMAND_SET_UPDATE_INTERVAL = 0x02,149	INIT_COMMAND_DETECT_FANS = 0x03,150};151 152/*153 * This output report sets pwm duty cycle/target fan speed for one or more154 * channels.155 */156struct set_fan_speed_report {157	/* report_id should be OUTPUT_REPORT_ID_SET_FAN_SPEED = 0x62 */158	u8 report_id;159	/* Should be 0x01 */160	u8 magic;161	/* To change fan speed on i-th channel, set i-th bit here */162	u8 channel_bit_mask;163	/*164	 * Fan duty cycle/target speed in percent. For voltage-controlled fans,165	 * the minimal voltage (duty_percent = 1) is about 9V.166	 * Setting duty_percent to 0 (if the channel is selected in167	 * channel_bit_mask) turns off the fan completely (regardless of the168	 * control mode).169	 */170	u8 duty_percent[FAN_CHANNELS_MAX];171} __packed;172 173struct drvdata {174	struct hid_device *hid;175	struct device *hwmon;176 177	u8 fan_duty_percent[FAN_CHANNELS];178	u16 fan_rpm[FAN_CHANNELS];179	bool pwm_status_received;180 181	u16 fan_in[FAN_CHANNELS];182	u16 fan_curr[FAN_CHANNELS];183	bool voltage_status_received;184 185	u8 fan_type[FAN_CHANNELS];186	bool fan_config_received;187 188	/*189	 * wq is used to wait for *_received flags to become true.190	 * All accesses to *_received flags and fan_* arrays are performed with191	 * wq.lock held.192	 */193	wait_queue_head_t wq;194	/*195	 * mutex is used to:196	 * 1) Prevent concurrent conflicting changes to update interval and pwm197	 * values (after sending an output hid report, the corresponding field198	 * in drvdata must be updated, and only then new output reports can be199	 * sent).200	 * 2) Synchronize access to output_buffer (well, the buffer is here,201	 * because synchronization is necessary anyway - so why not get rid of202	 * a kmalloc?).203	 */204	struct mutex mutex;205	long update_interval;206	u8 output_buffer[OUTPUT_REPORT_SIZE];207};208 209static long scale_pwm_value(long val, long orig_max, long new_max)210{211	if (val <= 0)212		return 0;213 214	/*215	 * Positive values should not become zero: 0 completely turns off the216	 * fan.217	 */218	return max(1L, DIV_ROUND_CLOSEST(min(val, orig_max) * new_max, orig_max));219}220 221static void handle_fan_config_report(struct drvdata *drvdata, void *data, int size)222{223	struct fan_config_report *report = data;224	int i;225 226	if (size < sizeof(struct fan_config_report))227		return;228 229	if (report->magic != 0x03)230		return;231 232	spin_lock(&drvdata->wq.lock);233 234	for (i = 0; i < FAN_CHANNELS; i++)235		drvdata->fan_type[i] = report->fan_type[i];236 237	drvdata->fan_config_received = true;238	wake_up_all_locked(&drvdata->wq);239	spin_unlock(&drvdata->wq.lock);240}241 242static void handle_fan_status_report(struct drvdata *drvdata, void *data, int size)243{244	struct fan_status_report *report = data;245	int i;246 247	if (size < sizeof(struct fan_status_report))248		return;249 250	spin_lock(&drvdata->wq.lock);251 252	/*253	 * The device sends INPUT_REPORT_ID_FAN_CONFIG = 0x61 report in response254	 * to "detect fans" command. Only accept other data after getting 0x61,255	 * to make sure that fan detection is complete. In particular, fan256	 * detection resets pwm values.257	 */258	if (!drvdata->fan_config_received) {259		spin_unlock(&drvdata->wq.lock);260		return;261	}262 263	for (i = 0; i < FAN_CHANNELS; i++) {264		if (drvdata->fan_type[i] == report->fan_type[i])265			continue;266 267		/*268		 * This should not happen (if my expectations about the device269		 * are correct).270		 *271		 * Even if the userspace sends fan detect command through272		 * hidraw, fan config report should arrive first.273		 */274		hid_warn_once(drvdata->hid,275			      "Fan %d type changed unexpectedly from %d to %d",276			      i, drvdata->fan_type[i], report->fan_type[i]);277		drvdata->fan_type[i] = report->fan_type[i];278	}279 280	switch (report->type) {281	case FAN_STATUS_REPORT_SPEED:282		for (i = 0; i < FAN_CHANNELS; i++) {283			drvdata->fan_rpm[i] =284				get_unaligned_le16(&report->fan_speed.fan_rpm[i]);285			drvdata->fan_duty_percent[i] =286				report->fan_speed.duty_percent[i];287		}288 289		drvdata->pwm_status_received = true;290		wake_up_all_locked(&drvdata->wq);291		break;292 293	case FAN_STATUS_REPORT_VOLTAGE:294		for (i = 0; i < FAN_CHANNELS; i++) {295			drvdata->fan_in[i] =296				get_unaligned_le16(&report->fan_voltage.fan_in[i]);297			drvdata->fan_curr[i] =298				get_unaligned_le16(&report->fan_voltage.fan_current[i]);299		}300 301		drvdata->voltage_status_received = true;302		wake_up_all_locked(&drvdata->wq);303		break;304	}305 306	spin_unlock(&drvdata->wq.lock);307}308 309static umode_t nzxt_smart2_hwmon_is_visible(const void *data,310					    enum hwmon_sensor_types type,311					    u32 attr, int channel)312{313	switch (type) {314	case hwmon_pwm:315		switch (attr) {316		case hwmon_pwm_input:317		case hwmon_pwm_enable:318			return 0644;319 320		default:321			return 0444;322		}323 324	case hwmon_chip:325		switch (attr) {326		case hwmon_chip_update_interval:327			return 0644;328 329		default:330			return 0444;331		}332 333	default:334		return 0444;335	}336}337 338static int nzxt_smart2_hwmon_read(struct device *dev, enum hwmon_sensor_types type,339				  u32 attr, int channel, long *val)340{341	struct drvdata *drvdata = dev_get_drvdata(dev);342	int res = -EINVAL;343 344	if (type == hwmon_chip) {345		switch (attr) {346		case hwmon_chip_update_interval:347			*val = drvdata->update_interval;348			return 0;349 350		default:351			return -EINVAL;352		}353	}354 355	spin_lock_irq(&drvdata->wq.lock);356 357	switch (type) {358	case hwmon_pwm:359		/*360		 * fancontrol:361		 * 1) remembers pwm* values when it starts362		 * 2) needs pwm*_enable to be 1 on controlled fans363		 * So make sure we have correct data before allowing pwm* reads.364		 * Returning errors for pwm of fan speed read can even cause365		 * fancontrol to shut down. So the wait is unavoidable.366		 */367		switch (attr) {368		case hwmon_pwm_enable:369			res = wait_event_interruptible_locked_irq(drvdata->wq,370								  drvdata->fan_config_received);371			if (res)372				goto unlock;373 374			*val = drvdata->fan_type[channel] != FAN_TYPE_NONE;375			break;376 377		case hwmon_pwm_mode:378			res = wait_event_interruptible_locked_irq(drvdata->wq,379								  drvdata->fan_config_received);380			if (res)381				goto unlock;382 383			*val = drvdata->fan_type[channel] == FAN_TYPE_PWM;384			break;385 386		case hwmon_pwm_input:387			res = wait_event_interruptible_locked_irq(drvdata->wq,388								  drvdata->pwm_status_received);389			if (res)390				goto unlock;391 392			*val = scale_pwm_value(drvdata->fan_duty_percent[channel],393					       100, 255);394			break;395		}396		break;397 398	case hwmon_fan:399		/*400		 * It's not strictly necessary to wait for *_received in the401		 * remaining cases (fancontrol doesn't care about them). But I'm402		 * doing it to have consistent behavior.403		 */404		if (attr == hwmon_fan_input) {405			res = wait_event_interruptible_locked_irq(drvdata->wq,406								  drvdata->pwm_status_received);407			if (res)408				goto unlock;409 410			*val = drvdata->fan_rpm[channel];411		}412		break;413 414	case hwmon_in:415		if (attr == hwmon_in_input) {416			res = wait_event_interruptible_locked_irq(drvdata->wq,417								  drvdata->voltage_status_received);418			if (res)419				goto unlock;420 421			*val = drvdata->fan_in[channel];422		}423		break;424 425	case hwmon_curr:426		if (attr == hwmon_curr_input) {427			res = wait_event_interruptible_locked_irq(drvdata->wq,428								  drvdata->voltage_status_received);429			if (res)430				goto unlock;431 432			*val = drvdata->fan_curr[channel];433		}434		break;435 436	default:437		break;438	}439 440unlock:441	spin_unlock_irq(&drvdata->wq.lock);442	return res;443}444 445static int send_output_report(struct drvdata *drvdata, const void *data,446			      size_t data_size)447{448	int ret;449 450	if (data_size > sizeof(drvdata->output_buffer))451		return -EINVAL;452 453	memcpy(drvdata->output_buffer, data, data_size);454 455	if (data_size < sizeof(drvdata->output_buffer))456		memset(drvdata->output_buffer + data_size, 0,457		       sizeof(drvdata->output_buffer) - data_size);458 459	ret = hid_hw_output_report(drvdata->hid, drvdata->output_buffer,460				   sizeof(drvdata->output_buffer));461	return ret < 0 ? ret : 0;462}463 464static int set_pwm(struct drvdata *drvdata, int channel, long val)465{466	int ret;467	u8 duty_percent = scale_pwm_value(val, 255, 100);468 469	struct set_fan_speed_report report = {470		.report_id = OUTPUT_REPORT_ID_SET_FAN_SPEED,471		.magic = 1,472		.channel_bit_mask = 1 << channel473	};474 475	ret = mutex_lock_interruptible(&drvdata->mutex);476	if (ret)477		return ret;478 479	report.duty_percent[channel] = duty_percent;480	ret = send_output_report(drvdata, &report, sizeof(report));481	if (ret)482		goto unlock;483 484	/*485	 * pwmconfig and fancontrol scripts expect pwm writes to take effect486	 * immediately (i. e. read from pwm* sysfs should return the value487	 * written into it). The device seems to always accept pwm values - even488	 * when there is no fan connected - so update pwm status without waiting489	 * for a report, to make pwmconfig and fancontrol happy. Worst case -490	 * if the device didn't accept new pwm value for some reason (never seen491	 * this in practice) - it will be reported incorrectly only until next492	 * update. This avoids "fan stuck" messages from pwmconfig, and493	 * fancontrol setting fan speed to 100% during shutdown.494	 */495	spin_lock_bh(&drvdata->wq.lock);496	drvdata->fan_duty_percent[channel] = duty_percent;497	spin_unlock_bh(&drvdata->wq.lock);498 499unlock:500	mutex_unlock(&drvdata->mutex);501	return ret;502}503 504/*505 * Workaround for fancontrol/pwmconfig trying to write to pwm*_enable even if it506 * already is 1 and read-only. Otherwise, fancontrol won't restore pwm on507 * shutdown properly.508 */509static int set_pwm_enable(struct drvdata *drvdata, int channel, long val)510{511	long expected_val;512	int res;513 514	spin_lock_irq(&drvdata->wq.lock);515 516	res = wait_event_interruptible_locked_irq(drvdata->wq,517						  drvdata->fan_config_received);518	if (res) {519		spin_unlock_irq(&drvdata->wq.lock);520		return res;521	}522 523	expected_val = drvdata->fan_type[channel] != FAN_TYPE_NONE;524 525	spin_unlock_irq(&drvdata->wq.lock);526 527	return (val == expected_val) ? 0 : -EOPNOTSUPP;528}529 530/*531 * Control byte	| Actual update interval in seconds532 * 0xff		| 65.5533 * 0xf7		| 63.46534 * 0x7f		| 32.74535 * 0x3f		| 16.36536 * 0x1f		| 8.17537 * 0x0f		| 4.07538 * 0x07		| 2.02539 * 0x03		| 1.00540 * 0x02		| 0.744541 * 0x01		| 0.488542 * 0x00		| 0.25543 */544static u8 update_interval_to_control_byte(long interval)545{546	if (interval <= 250)547		return 0;548 549	return clamp_val(1 + DIV_ROUND_CLOSEST(interval - 488, 256), 0, 255);550}551 552static long control_byte_to_update_interval(u8 control_byte)553{554	if (control_byte == 0)555		return 250;556 557	return 488 + (control_byte - 1) * 256;558}559 560static int set_update_interval(struct drvdata *drvdata, long val)561{562	u8 control = update_interval_to_control_byte(val);563	u8 report[] = {564		OUTPUT_REPORT_ID_INIT_COMMAND,565		INIT_COMMAND_SET_UPDATE_INTERVAL,566		0x01,567		0xe8,568		control,569		0x01,570		0xe8,571		control,572	};573	int ret;574 575	ret = send_output_report(drvdata, report, sizeof(report));576	if (ret)577		return ret;578 579	drvdata->update_interval = control_byte_to_update_interval(control);580	return 0;581}582 583static int init_device(struct drvdata *drvdata, long update_interval)584{585	int ret;586	static const u8 detect_fans_report[] = {587		OUTPUT_REPORT_ID_INIT_COMMAND,588		INIT_COMMAND_DETECT_FANS,589	};590 591	ret = send_output_report(drvdata, detect_fans_report,592				 sizeof(detect_fans_report));593	if (ret)594		return ret;595 596	return set_update_interval(drvdata, update_interval);597}598 599static int nzxt_smart2_hwmon_write(struct device *dev,600				   enum hwmon_sensor_types type, u32 attr,601				   int channel, long val)602{603	struct drvdata *drvdata = dev_get_drvdata(dev);604	int ret;605 606	switch (type) {607	case hwmon_pwm:608		switch (attr) {609		case hwmon_pwm_enable:610			return set_pwm_enable(drvdata, channel, val);611 612		case hwmon_pwm_input:613			return set_pwm(drvdata, channel, val);614 615		default:616			return -EINVAL;617		}618 619	case hwmon_chip:620		switch (attr) {621		case hwmon_chip_update_interval:622			ret = mutex_lock_interruptible(&drvdata->mutex);623			if (ret)624				return ret;625 626			ret = set_update_interval(drvdata, val);627 628			mutex_unlock(&drvdata->mutex);629			return ret;630 631		default:632			return -EINVAL;633		}634 635	default:636		return -EINVAL;637	}638}639 640static int nzxt_smart2_hwmon_read_string(struct device *dev,641					 enum hwmon_sensor_types type, u32 attr,642					 int channel, const char **str)643{644	switch (type) {645	case hwmon_fan:646		*str = fan_label[channel];647		return 0;648	case hwmon_curr:649		*str = curr_label[channel];650		return 0;651	case hwmon_in:652		*str = in_label[channel];653		return 0;654	default:655		return -EINVAL;656	}657}658 659static const struct hwmon_ops nzxt_smart2_hwmon_ops = {660	.is_visible = nzxt_smart2_hwmon_is_visible,661	.read = nzxt_smart2_hwmon_read,662	.read_string = nzxt_smart2_hwmon_read_string,663	.write = nzxt_smart2_hwmon_write,664};665 666static const struct hwmon_channel_info * const nzxt_smart2_channel_info[] = {667	HWMON_CHANNEL_INFO(fan, HWMON_F_INPUT | HWMON_F_LABEL,668			   HWMON_F_INPUT | HWMON_F_LABEL,669			   HWMON_F_INPUT | HWMON_F_LABEL),670	HWMON_CHANNEL_INFO(pwm, HWMON_PWM_INPUT | HWMON_PWM_MODE | HWMON_PWM_ENABLE,671			   HWMON_PWM_INPUT | HWMON_PWM_MODE | HWMON_PWM_ENABLE,672			   HWMON_PWM_INPUT | HWMON_PWM_MODE | HWMON_PWM_ENABLE),673	HWMON_CHANNEL_INFO(in, HWMON_I_INPUT | HWMON_I_LABEL,674			   HWMON_I_INPUT | HWMON_I_LABEL,675			   HWMON_I_INPUT | HWMON_I_LABEL),676	HWMON_CHANNEL_INFO(curr, HWMON_C_INPUT | HWMON_C_LABEL,677			   HWMON_C_INPUT | HWMON_C_LABEL,678			   HWMON_C_INPUT | HWMON_C_LABEL),679	HWMON_CHANNEL_INFO(chip, HWMON_C_UPDATE_INTERVAL),680	NULL681};682 683static const struct hwmon_chip_info nzxt_smart2_chip_info = {684	.ops = &nzxt_smart2_hwmon_ops,685	.info = nzxt_smart2_channel_info,686};687 688static int nzxt_smart2_hid_raw_event(struct hid_device *hdev,689				     struct hid_report *report, u8 *data, int size)690{691	struct drvdata *drvdata = hid_get_drvdata(hdev);692	u8 report_id = *data;693 694	switch (report_id) {695	case INPUT_REPORT_ID_FAN_CONFIG:696		handle_fan_config_report(drvdata, data, size);697		break;698 699	case INPUT_REPORT_ID_FAN_STATUS:700		handle_fan_status_report(drvdata, data, size);701		break;702	}703 704	return 0;705}706 707static int __maybe_unused nzxt_smart2_hid_reset_resume(struct hid_device *hdev)708{709	struct drvdata *drvdata = hid_get_drvdata(hdev);710 711	/*712	 * Userspace is still frozen (so no concurrent sysfs attribute access713	 * is possible), but raw_event can already be called concurrently.714	 */715	spin_lock_bh(&drvdata->wq.lock);716	drvdata->fan_config_received = false;717	drvdata->pwm_status_received = false;718	drvdata->voltage_status_received = false;719	spin_unlock_bh(&drvdata->wq.lock);720 721	return init_device(drvdata, drvdata->update_interval);722}723 724static void mutex_fini(void *lock)725{726	mutex_destroy(lock);727}728 729static int nzxt_smart2_hid_probe(struct hid_device *hdev,730				 const struct hid_device_id *id)731{732	struct drvdata *drvdata;733	int ret;734 735	drvdata = devm_kzalloc(&hdev->dev, sizeof(struct drvdata), GFP_KERNEL);736	if (!drvdata)737		return -ENOMEM;738 739	drvdata->hid = hdev;740	hid_set_drvdata(hdev, drvdata);741 742	init_waitqueue_head(&drvdata->wq);743 744	mutex_init(&drvdata->mutex);745	ret = devm_add_action_or_reset(&hdev->dev, mutex_fini, &drvdata->mutex);746	if (ret)747		return ret;748 749	ret = hid_parse(hdev);750	if (ret)751		return ret;752 753	ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW);754	if (ret)755		return ret;756 757	ret = hid_hw_open(hdev);758	if (ret)759		goto out_hw_stop;760 761	hid_device_io_start(hdev);762 763	init_device(drvdata, UPDATE_INTERVAL_DEFAULT_MS);764 765	drvdata->hwmon =766		hwmon_device_register_with_info(&hdev->dev, "nzxtsmart2", drvdata,767						&nzxt_smart2_chip_info, NULL);768	if (IS_ERR(drvdata->hwmon)) {769		ret = PTR_ERR(drvdata->hwmon);770		goto out_hw_close;771	}772 773	return 0;774 775out_hw_close:776	hid_hw_close(hdev);777 778out_hw_stop:779	hid_hw_stop(hdev);780	return ret;781}782 783static void nzxt_smart2_hid_remove(struct hid_device *hdev)784{785	struct drvdata *drvdata = hid_get_drvdata(hdev);786 787	hwmon_device_unregister(drvdata->hwmon);788 789	hid_hw_close(hdev);790	hid_hw_stop(hdev);791}792 793static const struct hid_device_id nzxt_smart2_hid_id_table[] = {794	{ HID_USB_DEVICE(0x1e71, 0x2006) }, /* NZXT Smart Device V2 */795	{ HID_USB_DEVICE(0x1e71, 0x200d) }, /* NZXT Smart Device V2 */796	{ HID_USB_DEVICE(0x1e71, 0x200f) }, /* NZXT Smart Device V2 */797	{ HID_USB_DEVICE(0x1e71, 0x2009) }, /* NZXT RGB & Fan Controller */798	{ HID_USB_DEVICE(0x1e71, 0x200e) }, /* NZXT RGB & Fan Controller */799	{ HID_USB_DEVICE(0x1e71, 0x2010) }, /* NZXT RGB & Fan Controller */800	{ HID_USB_DEVICE(0x1e71, 0x2011) }, /* NZXT RGB & Fan Controller (6 RGB) */801	{ HID_USB_DEVICE(0x1e71, 0x2019) }, /* NZXT RGB & Fan Controller (6 RGB) */802	{ HID_USB_DEVICE(0x1e71, 0x2020) }, /* NZXT RGB & Fan Controller (6 RGB) */803	{},804};805 806static struct hid_driver nzxt_smart2_hid_driver = {807	.name = "nzxt-smart2",808	.id_table = nzxt_smart2_hid_id_table,809	.probe = nzxt_smart2_hid_probe,810	.remove = nzxt_smart2_hid_remove,811	.raw_event = nzxt_smart2_hid_raw_event,812#ifdef CONFIG_PM813	.reset_resume = nzxt_smart2_hid_reset_resume,814#endif815};816 817static int __init nzxt_smart2_init(void)818{819	return hid_register_driver(&nzxt_smart2_hid_driver);820}821 822static void __exit nzxt_smart2_exit(void)823{824	hid_unregister_driver(&nzxt_smart2_hid_driver);825}826 827MODULE_DEVICE_TABLE(hid, nzxt_smart2_hid_id_table);828MODULE_AUTHOR("Aleksandr Mezin <mezin.alexander@gmail.com>");829MODULE_DESCRIPTION("Driver for NZXT RGB & Fan Controller/Smart Device V2");830MODULE_LICENSE("GPL");831 832/*833 * With module_init()/module_hid_driver() and the driver built into the kernel:834 *835 * Driver 'nzxt_smart2' was unable to register with bus_type 'hid' because the836 * bus was not initialized.837 */838late_initcall(nzxt_smart2_init);839module_exit(nzxt_smart2_exit);840