Lines Matching +full:pwm +full:- +full:fan

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Reverse-engineered NZXT RGB & Fan Controller/Smart Device v2 driver.
20 * The device has only 3 fan channels/connectors. But all HID reports have
30 "FAN 1",
31 "FAN 2",
32 "FAN 3",
36 "FAN 1 Current",
37 "FAN 2 Current",
38 "FAN 3 Current",
42 "FAN 1 Voltage",
43 "FAN 2 Voltage",
44 "FAN 3 Voltage",
65 * Some configuration data? Stays the same after fan speed changes,
66 * changes in fan configuration, reboots and driver reloads.
70 * Byte 12 seems to be the number of fan channels, but I am not sure.
77 * a 2-byte output report { 0x60, 0x03 }.
85 /* Fan type as detected by the device. See FAN_TYPE_* enum. */
90 * The device sends these reports at a fixed interval (update interval) -
100 /* Fan type as detected by the device. See FAN_TYPE_* enum. */
107 * Fan speed, in RPM. Zero for channels without fans
112 * Fan duty cycle, in percent. Non-zero even for
117 * Exactly the same values as duty_percent[], non-zero
127 * Voltage, in millivolts. Non-zero even when fan is
132 * Current, in milliamperes. Near-zero when
153 * This output report sets pwm duty cycle/target fan speed for one or more
161 /* To change fan speed on i-th channel, set i-th bit here */
164 * Fan duty cycle/target speed in percent. For voltage-controlled fans,
167 * channel_bit_mask) turns off the fan completely (regardless of the
196 * 1) Prevent concurrent conflicting changes to update interval and pwm
201 * because synchronization is necessary anyway - so why not get rid of
216 * fan. in scale_pwm_value()
229 if (report->magic != 0x03) in handle_fan_config_report()
232 spin_lock(&drvdata->wq.lock); in handle_fan_config_report()
235 drvdata->fan_type[i] = report->fan_type[i]; in handle_fan_config_report()
237 drvdata->fan_config_received = true; in handle_fan_config_report()
238 wake_up_all_locked(&drvdata->wq); in handle_fan_config_report()
239 spin_unlock(&drvdata->wq.lock); in handle_fan_config_report()
250 spin_lock(&drvdata->wq.lock); in handle_fan_status_report()
255 * to make sure that fan detection is complete. In particular, fan in handle_fan_status_report()
256 * detection resets pwm values. in handle_fan_status_report()
258 if (!drvdata->fan_config_received) { in handle_fan_status_report()
259 spin_unlock(&drvdata->wq.lock); in handle_fan_status_report()
264 if (drvdata->fan_type[i] == report->fan_type[i]) in handle_fan_status_report()
271 * Even if the userspace sends fan detect command through in handle_fan_status_report()
272 * hidraw, fan config report should arrive first. in handle_fan_status_report()
274 hid_warn_once(drvdata->hid, in handle_fan_status_report()
275 "Fan %d type changed unexpectedly from %d to %d", in handle_fan_status_report()
276 i, drvdata->fan_type[i], report->fan_type[i]); in handle_fan_status_report()
277 drvdata->fan_type[i] = report->fan_type[i]; in handle_fan_status_report()
280 switch (report->type) { in handle_fan_status_report()
283 drvdata->fan_rpm[i] = in handle_fan_status_report()
284 get_unaligned_le16(&report->fan_speed.fan_rpm[i]); in handle_fan_status_report()
285 drvdata->fan_duty_percent[i] = in handle_fan_status_report()
286 report->fan_speed.duty_percent[i]; in handle_fan_status_report()
289 drvdata->pwm_status_received = true; in handle_fan_status_report()
290 wake_up_all_locked(&drvdata->wq); in handle_fan_status_report()
295 drvdata->fan_in[i] = in handle_fan_status_report()
296 get_unaligned_le16(&report->fan_voltage.fan_in[i]); in handle_fan_status_report()
297 drvdata->fan_curr[i] = in handle_fan_status_report()
298 get_unaligned_le16(&report->fan_voltage.fan_current[i]); in handle_fan_status_report()
301 drvdata->voltage_status_received = true; in handle_fan_status_report()
302 wake_up_all_locked(&drvdata->wq); in handle_fan_status_report()
306 spin_unlock(&drvdata->wq.lock); in handle_fan_status_report()
342 int res = -EINVAL; in nzxt_smart2_hwmon_read()
347 *val = drvdata->update_interval; in nzxt_smart2_hwmon_read()
351 return -EINVAL; in nzxt_smart2_hwmon_read()
355 spin_lock_irq(&drvdata->wq.lock); in nzxt_smart2_hwmon_read()
361 * 1) remembers pwm* values when it starts in nzxt_smart2_hwmon_read()
362 * 2) needs pwm*_enable to be 1 on controlled fans in nzxt_smart2_hwmon_read()
363 * So make sure we have correct data before allowing pwm* reads. in nzxt_smart2_hwmon_read()
364 * Returning errors for pwm of fan speed read can even cause in nzxt_smart2_hwmon_read()
369 res = wait_event_interruptible_locked_irq(drvdata->wq, in nzxt_smart2_hwmon_read()
370 drvdata->fan_config_received); in nzxt_smart2_hwmon_read()
374 *val = drvdata->fan_type[channel] != FAN_TYPE_NONE; in nzxt_smart2_hwmon_read()
378 res = wait_event_interruptible_locked_irq(drvdata->wq, in nzxt_smart2_hwmon_read()
379 drvdata->fan_config_received); in nzxt_smart2_hwmon_read()
383 *val = drvdata->fan_type[channel] == FAN_TYPE_PWM; in nzxt_smart2_hwmon_read()
387 res = wait_event_interruptible_locked_irq(drvdata->wq, in nzxt_smart2_hwmon_read()
388 drvdata->pwm_status_received); in nzxt_smart2_hwmon_read()
392 *val = scale_pwm_value(drvdata->fan_duty_percent[channel], in nzxt_smart2_hwmon_read()
405 res = wait_event_interruptible_locked_irq(drvdata->wq, in nzxt_smart2_hwmon_read()
406 drvdata->pwm_status_received); in nzxt_smart2_hwmon_read()
410 *val = drvdata->fan_rpm[channel]; in nzxt_smart2_hwmon_read()
416 res = wait_event_interruptible_locked_irq(drvdata->wq, in nzxt_smart2_hwmon_read()
417 drvdata->voltage_status_received); in nzxt_smart2_hwmon_read()
421 *val = drvdata->fan_in[channel]; in nzxt_smart2_hwmon_read()
427 res = wait_event_interruptible_locked_irq(drvdata->wq, in nzxt_smart2_hwmon_read()
428 drvdata->voltage_status_received); in nzxt_smart2_hwmon_read()
432 *val = drvdata->fan_curr[channel]; in nzxt_smart2_hwmon_read()
441 spin_unlock_irq(&drvdata->wq.lock); in nzxt_smart2_hwmon_read()
450 if (data_size > sizeof(drvdata->output_buffer)) in send_output_report()
451 return -EINVAL; in send_output_report()
453 memcpy(drvdata->output_buffer, data, data_size); in send_output_report()
455 if (data_size < sizeof(drvdata->output_buffer)) in send_output_report()
456 memset(drvdata->output_buffer + data_size, 0, in send_output_report()
457 sizeof(drvdata->output_buffer) - data_size); in send_output_report()
459 ret = hid_hw_output_report(drvdata->hid, drvdata->output_buffer, in send_output_report()
460 sizeof(drvdata->output_buffer)); in send_output_report()
475 ret = mutex_lock_interruptible(&drvdata->mutex); in set_pwm()
485 * pwmconfig and fancontrol scripts expect pwm writes to take effect in set_pwm()
486 * immediately (i. e. read from pwm* sysfs should return the value in set_pwm()
487 * written into it). The device seems to always accept pwm values - even in set_pwm()
488 * when there is no fan connected - so update pwm status without waiting in set_pwm()
489 * for a report, to make pwmconfig and fancontrol happy. Worst case - in set_pwm()
490 * if the device didn't accept new pwm value for some reason (never seen in set_pwm()
491 * this in practice) - it will be reported incorrectly only until next in set_pwm()
492 * update. This avoids "fan stuck" messages from pwmconfig, and in set_pwm()
493 * fancontrol setting fan speed to 100% during shutdown. in set_pwm()
495 spin_lock_bh(&drvdata->wq.lock); in set_pwm()
496 drvdata->fan_duty_percent[channel] = duty_percent; in set_pwm()
497 spin_unlock_bh(&drvdata->wq.lock); in set_pwm()
500 mutex_unlock(&drvdata->mutex); in set_pwm()
505 * Workaround for fancontrol/pwmconfig trying to write to pwm*_enable even if it
506 * already is 1 and read-only. Otherwise, fancontrol won't restore pwm on
514 spin_lock_irq(&drvdata->wq.lock); in set_pwm_enable()
516 res = wait_event_interruptible_locked_irq(drvdata->wq, in set_pwm_enable()
517 drvdata->fan_config_received); in set_pwm_enable()
519 spin_unlock_irq(&drvdata->wq.lock); in set_pwm_enable()
523 expected_val = drvdata->fan_type[channel] != FAN_TYPE_NONE; in set_pwm_enable()
525 spin_unlock_irq(&drvdata->wq.lock); in set_pwm_enable()
527 return (val == expected_val) ? 0 : -EOPNOTSUPP; in set_pwm_enable()
549 return clamp_val(1 + DIV_ROUND_CLOSEST(interval - 488, 256), 0, 255); in update_interval_to_control_byte()
557 return 488 + (control_byte - 1) * 256; in control_byte_to_update_interval()
579 drvdata->update_interval = control_byte_to_update_interval(control); in set_update_interval()
616 return -EINVAL; in nzxt_smart2_hwmon_write()
622 ret = mutex_lock_interruptible(&drvdata->mutex); in nzxt_smart2_hwmon_write()
628 mutex_unlock(&drvdata->mutex); in nzxt_smart2_hwmon_write()
632 return -EINVAL; in nzxt_smart2_hwmon_write()
636 return -EINVAL; in nzxt_smart2_hwmon_write()
655 return -EINVAL; in nzxt_smart2_hwmon_read_string()
667 HWMON_CHANNEL_INFO(fan, HWMON_F_INPUT | HWMON_F_LABEL,
670 HWMON_CHANNEL_INFO(pwm, HWMON_PWM_INPUT | HWMON_PWM_MODE | HWMON_PWM_ENABLE,
715 spin_lock_bh(&drvdata->wq.lock); in nzxt_smart2_hid_reset_resume()
716 drvdata->fan_config_received = false; in nzxt_smart2_hid_reset_resume()
717 drvdata->pwm_status_received = false; in nzxt_smart2_hid_reset_resume()
718 drvdata->voltage_status_received = false; in nzxt_smart2_hid_reset_resume()
719 spin_unlock_bh(&drvdata->wq.lock); in nzxt_smart2_hid_reset_resume()
721 return init_device(drvdata, drvdata->update_interval); in nzxt_smart2_hid_reset_resume()
735 drvdata = devm_kzalloc(&hdev->dev, sizeof(struct drvdata), GFP_KERNEL); in nzxt_smart2_hid_probe()
737 return -ENOMEM; in nzxt_smart2_hid_probe()
739 drvdata->hid = hdev; in nzxt_smart2_hid_probe()
742 init_waitqueue_head(&drvdata->wq); in nzxt_smart2_hid_probe()
744 mutex_init(&drvdata->mutex); in nzxt_smart2_hid_probe()
745 ret = devm_add_action_or_reset(&hdev->dev, mutex_fini, &drvdata->mutex); in nzxt_smart2_hid_probe()
765 drvdata->hwmon = in nzxt_smart2_hid_probe()
766 hwmon_device_register_with_info(&hdev->dev, "nzxtsmart2", drvdata, in nzxt_smart2_hid_probe()
768 if (IS_ERR(drvdata->hwmon)) { in nzxt_smart2_hid_probe()
769 ret = PTR_ERR(drvdata->hwmon); in nzxt_smart2_hid_probe()
787 hwmon_device_unregister(drvdata->hwmon); in nzxt_smart2_hid_remove()
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) */
807 .name = "nzxt-smart2",
829 MODULE_DESCRIPTION("Driver for NZXT RGB & Fan Controller/Smart Device V2");