0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/hid.h>
0009 #include <linux/hwmon.h>
0010 #include <linux/math.h>
0011 #include <linux/module.h>
0012 #include <linux/mutex.h>
0013 #include <linux/spinlock.h>
0014 #include <linux/wait.h>
0015
0016 #include <asm/byteorder.h>
0017 #include <asm/unaligned.h>
0018
0019
0020
0021
0022
0023 #define FAN_CHANNELS 3
0024 #define FAN_CHANNELS_MAX 8
0025
0026 #define UPDATE_INTERVAL_DEFAULT_MS 1000
0027
0028
0029 static const char *const fan_label[] = {
0030 "FAN 1",
0031 "FAN 2",
0032 "FAN 3",
0033 };
0034
0035 static const char *const curr_label[] = {
0036 "FAN 1 Current",
0037 "FAN 2 Current",
0038 "FAN 3 Current",
0039 };
0040
0041 static const char *const in_label[] = {
0042 "FAN 1 Voltage",
0043 "FAN 2 Voltage",
0044 "FAN 3 Voltage",
0045 };
0046
0047 enum {
0048 INPUT_REPORT_ID_FAN_CONFIG = 0x61,
0049 INPUT_REPORT_ID_FAN_STATUS = 0x67,
0050 };
0051
0052 enum {
0053 FAN_STATUS_REPORT_SPEED = 0x02,
0054 FAN_STATUS_REPORT_VOLTAGE = 0x04,
0055 };
0056
0057 enum {
0058 FAN_TYPE_NONE = 0,
0059 FAN_TYPE_DC = 1,
0060 FAN_TYPE_PWM = 2,
0061 };
0062
0063 struct unknown_static_data {
0064
0065
0066
0067
0068
0069
0070
0071
0072 u8 unknown1[14];
0073 } __packed;
0074
0075
0076
0077
0078
0079 struct fan_config_report {
0080
0081 u8 report_id;
0082
0083 u8 magic;
0084 struct unknown_static_data unknown_data;
0085
0086 u8 fan_type[FAN_CHANNELS_MAX];
0087 } __packed;
0088
0089
0090
0091
0092
0093
0094 struct fan_status_report {
0095
0096 u8 report_id;
0097
0098 u8 type;
0099 struct unknown_static_data unknown_data;
0100
0101 u8 fan_type[FAN_CHANNELS_MAX];
0102
0103 union {
0104
0105 struct {
0106
0107
0108
0109
0110 __le16 fan_rpm[FAN_CHANNELS_MAX];
0111
0112
0113
0114
0115 u8 duty_percent[FAN_CHANNELS_MAX];
0116
0117
0118
0119
0120 u8 duty_percent_dup[FAN_CHANNELS_MAX];
0121
0122 u8 noise_db;
0123 } __packed fan_speed;
0124
0125 struct {
0126
0127
0128
0129
0130 __le16 fan_in[FAN_CHANNELS_MAX];
0131
0132
0133
0134
0135 __le16 fan_current[FAN_CHANNELS_MAX];
0136 } __packed fan_voltage;
0137 } __packed;
0138 } __packed;
0139
0140 #define OUTPUT_REPORT_SIZE 64
0141
0142 enum {
0143 OUTPUT_REPORT_ID_INIT_COMMAND = 0x60,
0144 OUTPUT_REPORT_ID_SET_FAN_SPEED = 0x62,
0145 };
0146
0147 enum {
0148 INIT_COMMAND_SET_UPDATE_INTERVAL = 0x02,
0149 INIT_COMMAND_DETECT_FANS = 0x03,
0150 };
0151
0152
0153
0154
0155
0156 struct set_fan_speed_report {
0157
0158 u8 report_id;
0159
0160 u8 magic;
0161
0162 u8 channel_bit_mask;
0163
0164
0165
0166
0167
0168
0169
0170 u8 duty_percent[FAN_CHANNELS_MAX];
0171 } __packed;
0172
0173 struct drvdata {
0174 struct hid_device *hid;
0175 struct device *hwmon;
0176
0177 u8 fan_duty_percent[FAN_CHANNELS];
0178 u16 fan_rpm[FAN_CHANNELS];
0179 bool pwm_status_received;
0180
0181 u16 fan_in[FAN_CHANNELS];
0182 u16 fan_curr[FAN_CHANNELS];
0183 bool voltage_status_received;
0184
0185 u8 fan_type[FAN_CHANNELS];
0186 bool fan_config_received;
0187
0188
0189
0190
0191
0192
0193 wait_queue_head_t wq;
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204 struct mutex mutex;
0205 long update_interval;
0206 u8 output_buffer[OUTPUT_REPORT_SIZE];
0207 };
0208
0209 static long scale_pwm_value(long val, long orig_max, long new_max)
0210 {
0211 if (val <= 0)
0212 return 0;
0213
0214
0215
0216
0217
0218 return max(1L, DIV_ROUND_CLOSEST(min(val, orig_max) * new_max, orig_max));
0219 }
0220
0221 static void handle_fan_config_report(struct drvdata *drvdata, void *data, int size)
0222 {
0223 struct fan_config_report *report = data;
0224 int i;
0225
0226 if (size < sizeof(struct fan_config_report))
0227 return;
0228
0229 if (report->magic != 0x03)
0230 return;
0231
0232 spin_lock(&drvdata->wq.lock);
0233
0234 for (i = 0; i < FAN_CHANNELS; i++)
0235 drvdata->fan_type[i] = report->fan_type[i];
0236
0237 drvdata->fan_config_received = true;
0238 wake_up_all_locked(&drvdata->wq);
0239 spin_unlock(&drvdata->wq.lock);
0240 }
0241
0242 static void handle_fan_status_report(struct drvdata *drvdata, void *data, int size)
0243 {
0244 struct fan_status_report *report = data;
0245 int i;
0246
0247 if (size < sizeof(struct fan_status_report))
0248 return;
0249
0250 spin_lock(&drvdata->wq.lock);
0251
0252
0253
0254
0255
0256
0257
0258 if (!drvdata->fan_config_received) {
0259 spin_unlock(&drvdata->wq.lock);
0260 return;
0261 }
0262
0263 for (i = 0; i < FAN_CHANNELS; i++) {
0264 if (drvdata->fan_type[i] == report->fan_type[i])
0265 continue;
0266
0267
0268
0269
0270
0271
0272
0273
0274 hid_warn_once(drvdata->hid,
0275 "Fan %d type changed unexpectedly from %d to %d",
0276 i, drvdata->fan_type[i], report->fan_type[i]);
0277 drvdata->fan_type[i] = report->fan_type[i];
0278 }
0279
0280 switch (report->type) {
0281 case FAN_STATUS_REPORT_SPEED:
0282 for (i = 0; i < FAN_CHANNELS; i++) {
0283 drvdata->fan_rpm[i] =
0284 get_unaligned_le16(&report->fan_speed.fan_rpm[i]);
0285 drvdata->fan_duty_percent[i] =
0286 report->fan_speed.duty_percent[i];
0287 }
0288
0289 drvdata->pwm_status_received = true;
0290 wake_up_all_locked(&drvdata->wq);
0291 break;
0292
0293 case FAN_STATUS_REPORT_VOLTAGE:
0294 for (i = 0; i < FAN_CHANNELS; i++) {
0295 drvdata->fan_in[i] =
0296 get_unaligned_le16(&report->fan_voltage.fan_in[i]);
0297 drvdata->fan_curr[i] =
0298 get_unaligned_le16(&report->fan_voltage.fan_current[i]);
0299 }
0300
0301 drvdata->voltage_status_received = true;
0302 wake_up_all_locked(&drvdata->wq);
0303 break;
0304 }
0305
0306 spin_unlock(&drvdata->wq.lock);
0307 }
0308
0309 static umode_t nzxt_smart2_hwmon_is_visible(const void *data,
0310 enum hwmon_sensor_types type,
0311 u32 attr, int channel)
0312 {
0313 switch (type) {
0314 case hwmon_pwm:
0315 switch (attr) {
0316 case hwmon_pwm_input:
0317 case hwmon_pwm_enable:
0318 return 0644;
0319
0320 default:
0321 return 0444;
0322 }
0323
0324 case hwmon_chip:
0325 switch (attr) {
0326 case hwmon_chip_update_interval:
0327 return 0644;
0328
0329 default:
0330 return 0444;
0331 }
0332
0333 default:
0334 return 0444;
0335 }
0336 }
0337
0338 static int nzxt_smart2_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
0339 u32 attr, int channel, long *val)
0340 {
0341 struct drvdata *drvdata = dev_get_drvdata(dev);
0342 int res = -EINVAL;
0343
0344 if (type == hwmon_chip) {
0345 switch (attr) {
0346 case hwmon_chip_update_interval:
0347 *val = drvdata->update_interval;
0348 return 0;
0349
0350 default:
0351 return -EINVAL;
0352 }
0353 }
0354
0355 spin_lock_irq(&drvdata->wq.lock);
0356
0357 switch (type) {
0358 case hwmon_pwm:
0359
0360
0361
0362
0363
0364
0365
0366
0367 switch (attr) {
0368 case hwmon_pwm_enable:
0369 res = wait_event_interruptible_locked_irq(drvdata->wq,
0370 drvdata->fan_config_received);
0371 if (res)
0372 goto unlock;
0373
0374 *val = drvdata->fan_type[channel] != FAN_TYPE_NONE;
0375 break;
0376
0377 case hwmon_pwm_mode:
0378 res = wait_event_interruptible_locked_irq(drvdata->wq,
0379 drvdata->fan_config_received);
0380 if (res)
0381 goto unlock;
0382
0383 *val = drvdata->fan_type[channel] == FAN_TYPE_PWM;
0384 break;
0385
0386 case hwmon_pwm_input:
0387 res = wait_event_interruptible_locked_irq(drvdata->wq,
0388 drvdata->pwm_status_received);
0389 if (res)
0390 goto unlock;
0391
0392 *val = scale_pwm_value(drvdata->fan_duty_percent[channel],
0393 100, 255);
0394 break;
0395 }
0396 break;
0397
0398 case hwmon_fan:
0399
0400
0401
0402
0403
0404 if (attr == hwmon_fan_input) {
0405 res = wait_event_interruptible_locked_irq(drvdata->wq,
0406 drvdata->pwm_status_received);
0407 if (res)
0408 goto unlock;
0409
0410 *val = drvdata->fan_rpm[channel];
0411 }
0412 break;
0413
0414 case hwmon_in:
0415 if (attr == hwmon_in_input) {
0416 res = wait_event_interruptible_locked_irq(drvdata->wq,
0417 drvdata->voltage_status_received);
0418 if (res)
0419 goto unlock;
0420
0421 *val = drvdata->fan_in[channel];
0422 }
0423 break;
0424
0425 case hwmon_curr:
0426 if (attr == hwmon_curr_input) {
0427 res = wait_event_interruptible_locked_irq(drvdata->wq,
0428 drvdata->voltage_status_received);
0429 if (res)
0430 goto unlock;
0431
0432 *val = drvdata->fan_curr[channel];
0433 }
0434 break;
0435
0436 default:
0437 break;
0438 }
0439
0440 unlock:
0441 spin_unlock_irq(&drvdata->wq.lock);
0442 return res;
0443 }
0444
0445 static int send_output_report(struct drvdata *drvdata, const void *data,
0446 size_t data_size)
0447 {
0448 int ret;
0449
0450 if (data_size > sizeof(drvdata->output_buffer))
0451 return -EINVAL;
0452
0453 memcpy(drvdata->output_buffer, data, data_size);
0454
0455 if (data_size < sizeof(drvdata->output_buffer))
0456 memset(drvdata->output_buffer + data_size, 0,
0457 sizeof(drvdata->output_buffer) - data_size);
0458
0459 ret = hid_hw_output_report(drvdata->hid, drvdata->output_buffer,
0460 sizeof(drvdata->output_buffer));
0461 return ret < 0 ? ret : 0;
0462 }
0463
0464 static int set_pwm(struct drvdata *drvdata, int channel, long val)
0465 {
0466 int ret;
0467 u8 duty_percent = scale_pwm_value(val, 255, 100);
0468
0469 struct set_fan_speed_report report = {
0470 .report_id = OUTPUT_REPORT_ID_SET_FAN_SPEED,
0471 .magic = 1,
0472 .channel_bit_mask = 1 << channel
0473 };
0474
0475 ret = mutex_lock_interruptible(&drvdata->mutex);
0476 if (ret)
0477 return ret;
0478
0479 report.duty_percent[channel] = duty_percent;
0480 ret = send_output_report(drvdata, &report, sizeof(report));
0481 if (ret)
0482 goto unlock;
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494
0495 spin_lock_bh(&drvdata->wq.lock);
0496 drvdata->fan_duty_percent[channel] = duty_percent;
0497 spin_unlock_bh(&drvdata->wq.lock);
0498
0499 unlock:
0500 mutex_unlock(&drvdata->mutex);
0501 return ret;
0502 }
0503
0504
0505
0506
0507
0508
0509 static int set_pwm_enable(struct drvdata *drvdata, int channel, long val)
0510 {
0511 long expected_val;
0512 int res;
0513
0514 spin_lock_irq(&drvdata->wq.lock);
0515
0516 res = wait_event_interruptible_locked_irq(drvdata->wq,
0517 drvdata->fan_config_received);
0518 if (res) {
0519 spin_unlock_irq(&drvdata->wq.lock);
0520 return res;
0521 }
0522
0523 expected_val = drvdata->fan_type[channel] != FAN_TYPE_NONE;
0524
0525 spin_unlock_irq(&drvdata->wq.lock);
0526
0527 return (val == expected_val) ? 0 : -EOPNOTSUPP;
0528 }
0529
0530
0531
0532
0533
0534
0535
0536
0537
0538
0539
0540
0541
0542
0543
0544 static u8 update_interval_to_control_byte(long interval)
0545 {
0546 if (interval <= 250)
0547 return 0;
0548
0549 return clamp_val(1 + DIV_ROUND_CLOSEST(interval - 488, 256), 0, 255);
0550 }
0551
0552 static long control_byte_to_update_interval(u8 control_byte)
0553 {
0554 if (control_byte == 0)
0555 return 250;
0556
0557 return 488 + (control_byte - 1) * 256;
0558 }
0559
0560 static int set_update_interval(struct drvdata *drvdata, long val)
0561 {
0562 u8 control = update_interval_to_control_byte(val);
0563 u8 report[] = {
0564 OUTPUT_REPORT_ID_INIT_COMMAND,
0565 INIT_COMMAND_SET_UPDATE_INTERVAL,
0566 0x01,
0567 0xe8,
0568 control,
0569 0x01,
0570 0xe8,
0571 control,
0572 };
0573 int ret;
0574
0575 ret = send_output_report(drvdata, report, sizeof(report));
0576 if (ret)
0577 return ret;
0578
0579 drvdata->update_interval = control_byte_to_update_interval(control);
0580 return 0;
0581 }
0582
0583 static int init_device(struct drvdata *drvdata, long update_interval)
0584 {
0585 int ret;
0586 static const u8 detect_fans_report[] = {
0587 OUTPUT_REPORT_ID_INIT_COMMAND,
0588 INIT_COMMAND_DETECT_FANS,
0589 };
0590
0591 ret = send_output_report(drvdata, detect_fans_report,
0592 sizeof(detect_fans_report));
0593 if (ret)
0594 return ret;
0595
0596 return set_update_interval(drvdata, update_interval);
0597 }
0598
0599 static int nzxt_smart2_hwmon_write(struct device *dev,
0600 enum hwmon_sensor_types type, u32 attr,
0601 int channel, long val)
0602 {
0603 struct drvdata *drvdata = dev_get_drvdata(dev);
0604 int ret;
0605
0606 switch (type) {
0607 case hwmon_pwm:
0608 switch (attr) {
0609 case hwmon_pwm_enable:
0610 return set_pwm_enable(drvdata, channel, val);
0611
0612 case hwmon_pwm_input:
0613 return set_pwm(drvdata, channel, val);
0614
0615 default:
0616 return -EINVAL;
0617 }
0618
0619 case hwmon_chip:
0620 switch (attr) {
0621 case hwmon_chip_update_interval:
0622 ret = mutex_lock_interruptible(&drvdata->mutex);
0623 if (ret)
0624 return ret;
0625
0626 ret = set_update_interval(drvdata, val);
0627
0628 mutex_unlock(&drvdata->mutex);
0629 return ret;
0630
0631 default:
0632 return -EINVAL;
0633 }
0634
0635 default:
0636 return -EINVAL;
0637 }
0638 }
0639
0640 static int nzxt_smart2_hwmon_read_string(struct device *dev,
0641 enum hwmon_sensor_types type, u32 attr,
0642 int channel, const char **str)
0643 {
0644 switch (type) {
0645 case hwmon_fan:
0646 *str = fan_label[channel];
0647 return 0;
0648 case hwmon_curr:
0649 *str = curr_label[channel];
0650 return 0;
0651 case hwmon_in:
0652 *str = in_label[channel];
0653 return 0;
0654 default:
0655 return -EINVAL;
0656 }
0657 }
0658
0659 static const struct hwmon_ops nzxt_smart2_hwmon_ops = {
0660 .is_visible = nzxt_smart2_hwmon_is_visible,
0661 .read = nzxt_smart2_hwmon_read,
0662 .read_string = nzxt_smart2_hwmon_read_string,
0663 .write = nzxt_smart2_hwmon_write,
0664 };
0665
0666 static const struct hwmon_channel_info *nzxt_smart2_channel_info[] = {
0667 HWMON_CHANNEL_INFO(fan, HWMON_F_INPUT | HWMON_F_LABEL,
0668 HWMON_F_INPUT | HWMON_F_LABEL,
0669 HWMON_F_INPUT | HWMON_F_LABEL),
0670 HWMON_CHANNEL_INFO(pwm, HWMON_PWM_INPUT | HWMON_PWM_MODE | HWMON_PWM_ENABLE,
0671 HWMON_PWM_INPUT | HWMON_PWM_MODE | HWMON_PWM_ENABLE,
0672 HWMON_PWM_INPUT | HWMON_PWM_MODE | HWMON_PWM_ENABLE),
0673 HWMON_CHANNEL_INFO(in, HWMON_I_INPUT | HWMON_I_LABEL,
0674 HWMON_I_INPUT | HWMON_I_LABEL,
0675 HWMON_I_INPUT | HWMON_I_LABEL),
0676 HWMON_CHANNEL_INFO(curr, HWMON_C_INPUT | HWMON_C_LABEL,
0677 HWMON_C_INPUT | HWMON_C_LABEL,
0678 HWMON_C_INPUT | HWMON_C_LABEL),
0679 HWMON_CHANNEL_INFO(chip, HWMON_C_UPDATE_INTERVAL),
0680 NULL
0681 };
0682
0683 static const struct hwmon_chip_info nzxt_smart2_chip_info = {
0684 .ops = &nzxt_smart2_hwmon_ops,
0685 .info = nzxt_smart2_channel_info,
0686 };
0687
0688 static int nzxt_smart2_hid_raw_event(struct hid_device *hdev,
0689 struct hid_report *report, u8 *data, int size)
0690 {
0691 struct drvdata *drvdata = hid_get_drvdata(hdev);
0692 u8 report_id = *data;
0693
0694 switch (report_id) {
0695 case INPUT_REPORT_ID_FAN_CONFIG:
0696 handle_fan_config_report(drvdata, data, size);
0697 break;
0698
0699 case INPUT_REPORT_ID_FAN_STATUS:
0700 handle_fan_status_report(drvdata, data, size);
0701 break;
0702 }
0703
0704 return 0;
0705 }
0706
0707 static int __maybe_unused nzxt_smart2_hid_reset_resume(struct hid_device *hdev)
0708 {
0709 struct drvdata *drvdata = hid_get_drvdata(hdev);
0710
0711
0712
0713
0714
0715 spin_lock_bh(&drvdata->wq.lock);
0716 drvdata->fan_config_received = false;
0717 drvdata->pwm_status_received = false;
0718 drvdata->voltage_status_received = false;
0719 spin_unlock_bh(&drvdata->wq.lock);
0720
0721 return init_device(drvdata, drvdata->update_interval);
0722 }
0723
0724 static int nzxt_smart2_hid_probe(struct hid_device *hdev,
0725 const struct hid_device_id *id)
0726 {
0727 struct drvdata *drvdata;
0728 int ret;
0729
0730 drvdata = devm_kzalloc(&hdev->dev, sizeof(struct drvdata), GFP_KERNEL);
0731 if (!drvdata)
0732 return -ENOMEM;
0733
0734 drvdata->hid = hdev;
0735 hid_set_drvdata(hdev, drvdata);
0736
0737 init_waitqueue_head(&drvdata->wq);
0738
0739 mutex_init(&drvdata->mutex);
0740 devm_add_action(&hdev->dev, (void (*)(void *))mutex_destroy,
0741 &drvdata->mutex);
0742
0743 ret = hid_parse(hdev);
0744 if (ret)
0745 return ret;
0746
0747 ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW);
0748 if (ret)
0749 return ret;
0750
0751 ret = hid_hw_open(hdev);
0752 if (ret)
0753 goto out_hw_stop;
0754
0755 hid_device_io_start(hdev);
0756
0757 init_device(drvdata, UPDATE_INTERVAL_DEFAULT_MS);
0758
0759 drvdata->hwmon =
0760 hwmon_device_register_with_info(&hdev->dev, "nzxtsmart2", drvdata,
0761 &nzxt_smart2_chip_info, NULL);
0762 if (IS_ERR(drvdata->hwmon)) {
0763 ret = PTR_ERR(drvdata->hwmon);
0764 goto out_hw_close;
0765 }
0766
0767 return 0;
0768
0769 out_hw_close:
0770 hid_hw_close(hdev);
0771
0772 out_hw_stop:
0773 hid_hw_stop(hdev);
0774 return ret;
0775 }
0776
0777 static void nzxt_smart2_hid_remove(struct hid_device *hdev)
0778 {
0779 struct drvdata *drvdata = hid_get_drvdata(hdev);
0780
0781 hwmon_device_unregister(drvdata->hwmon);
0782
0783 hid_hw_close(hdev);
0784 hid_hw_stop(hdev);
0785 }
0786
0787 static const struct hid_device_id nzxt_smart2_hid_id_table[] = {
0788 { HID_USB_DEVICE(0x1e71, 0x2006) },
0789 { HID_USB_DEVICE(0x1e71, 0x200d) },
0790 { HID_USB_DEVICE(0x1e71, 0x2009) },
0791 { HID_USB_DEVICE(0x1e71, 0x200e) },
0792 { HID_USB_DEVICE(0x1e71, 0x2010) },
0793 {},
0794 };
0795
0796 static struct hid_driver nzxt_smart2_hid_driver = {
0797 .name = "nzxt-smart2",
0798 .id_table = nzxt_smart2_hid_id_table,
0799 .probe = nzxt_smart2_hid_probe,
0800 .remove = nzxt_smart2_hid_remove,
0801 .raw_event = nzxt_smart2_hid_raw_event,
0802 #ifdef CONFIG_PM
0803 .reset_resume = nzxt_smart2_hid_reset_resume,
0804 #endif
0805 };
0806
0807 static int __init nzxt_smart2_init(void)
0808 {
0809 return hid_register_driver(&nzxt_smart2_hid_driver);
0810 }
0811
0812 static void __exit nzxt_smart2_exit(void)
0813 {
0814 hid_unregister_driver(&nzxt_smart2_hid_driver);
0815 }
0816
0817 MODULE_DEVICE_TABLE(hid, nzxt_smart2_hid_id_table);
0818 MODULE_AUTHOR("Aleksandr Mezin <mezin.alexander@gmail.com>");
0819 MODULE_DESCRIPTION("Driver for NZXT RGB & Fan Controller/Smart Device V2");
0820 MODULE_LICENSE("GPL");
0821
0822
0823
0824
0825
0826
0827
0828 late_initcall(nzxt_smart2_init);
0829 module_exit(nzxt_smart2_exit);