Skip to content

Commit 8ec8d6c

Browse files
aleksamagickagroeck
authored andcommitted
hwmon: (nzxt-kraken3) Add support for NZXT Kraken 2023 (standard and Elite) models
Add support for NZXT Kraken 2023 (standard) and NZXT Kraken 2023 Elite all-in-one CPU coolers. These models communicate identically to the NZXT Kraken Z-series (Z53 code paths) in all cases except when writing the fan curve, where setting additional bits in the report is needed. Reviewed-by: Jonas Malaco <jonas@protocubo.io> Signed-off-by: Aleksa Savic <savicaleksa83@gmail.com> Link: https://lore.kernel.org/r/20240428104812.14037-3-savicaleksa83@gmail.com Signed-off-by: Guenter Roeck <linux@roeck-us.net>
1 parent cbeb479 commit 8ec8d6c

2 files changed

Lines changed: 41 additions & 16 deletions

File tree

Documentation/hwmon/nzxt-kraken3.rst

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,20 @@ Supported devices:
1111
* NZXT Kraken Z53
1212
* NZXT Kraken Z63
1313
* NZXT Kraken Z73
14+
* NZXT Kraken 2023
15+
* NZXT Kraken 2023 Elite
1416

1517
Author: Jonas Malaco, Aleksa Savic
1618

1719
Description
1820
-----------
1921

20-
This driver enables hardware monitoring support for NZXT Kraken X53/X63/X73 and
21-
Z53/Z63/Z73 all-in-one CPU liquid coolers. All models expose liquid temperature
22-
and pump speed (in RPM), as well as PWM control (either as a fixed value
23-
or through a temp-PWM curve). The Z-series models additionally expose the speed
24-
and duty of an optionally connected fan, with the same PWM control capabilities.
22+
This driver enables hardware monitoring support for NZXT Kraken X53/X63/X73,
23+
Z53/Z63/Z73 and Kraken 2023 (standard and Elite) all-in-one CPU liquid coolers.
24+
All models expose liquid temperature and pump speed (in RPM), as well as PWM
25+
control (either as a fixed value or through a temp-PWM curve). The Z-series and
26+
Kraken 2023 models additionally expose the speed and duty of an optionally connected
27+
fan, with the same PWM control capabilities.
2528

2629
Pump and fan duty control mode can be set through pwm[1-2]_enable, where 1 is
2730
for the manual control mode and 2 is for the liquid temp to PWM curve mode.
@@ -39,9 +42,9 @@ The devices can report if they are faulty. The driver supports that situation
3942
and will issue a warning. This can also happen when the USB cable is connected,
4043
but SATA power is not.
4144

42-
The addressable RGB LEDs and LCD screen (only on Z-series models) are not
43-
supported in this driver, but can be controlled through existing userspace tools,
44-
such as `liquidctl`_.
45+
The addressable RGB LEDs and LCD screen (only on Z-series and Kraken 2023 models)
46+
are not supported in this driver, but can be controlled through existing userspace
47+
tools, such as `liquidctl`_.
4548

4649
.. _liquidctl: https://github.com/liquidctl/liquidctl
4750

drivers/hwmon/nzxt-kraken3.c

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
// SPDX-License-Identifier: GPL-2.0+
22
/*
3-
* hwmon driver for NZXT Kraken X53/X63/X73 and Z53/Z63/Z73 all in one coolers.
4-
* X53 and Z53 in code refer to all models in their respective series (shortened
5-
* for brevity).
3+
* hwmon driver for NZXT Kraken X53/X63/X73, Z53/Z63/Z73 and 2023/2023 Elite all in one coolers.
4+
* X53 and Z53 in code refer to all models in their respective series (shortened for brevity).
5+
* 2023 models use the Z53 code paths.
66
*
77
* Copyright 2021 Jonas Malaco <jonas@protocubo.io>
88
* Copyright 2022 Aleksa Savic <savicaleksa83@gmail.com>
@@ -23,8 +23,10 @@
2323
#define USB_PRODUCT_ID_X53 0x2007
2424
#define USB_PRODUCT_ID_X53_SECOND 0x2014
2525
#define USB_PRODUCT_ID_Z53 0x3008
26+
#define USB_PRODUCT_ID_KRAKEN2023 0x300E
27+
#define USB_PRODUCT_ID_KRAKEN2023_ELITE 0x300C
2628

27-
enum kinds { X53, Z53 } __packed;
29+
enum kinds { X53, Z53, KRAKEN2023 } __packed;
2830
enum pwm_enable { off, manual, curve } __packed;
2931

3032
#define DRIVER_NAME "nzxt_kraken3"
@@ -136,6 +138,7 @@ static umode_t kraken3_is_visible(const void *data, enum hwmon_sensor_types type
136138
return 0444;
137139
break;
138140
case Z53:
141+
case KRAKEN2023:
139142
/* Pump and fan */
140143
if (channel < 2)
141144
return 0444;
@@ -155,6 +158,7 @@ static umode_t kraken3_is_visible(const void *data, enum hwmon_sensor_types type
155158
return 0644;
156159
break;
157160
case Z53:
161+
case KRAKEN2023:
158162
/* Pump and fan */
159163
if (channel < 2)
160164
return 0644;
@@ -242,6 +246,7 @@ static int kraken3_read_x53(struct kraken3_data *priv)
242246
return 0;
243247
}
244248

249+
/* Covers Z53 and KRAKEN2023 device kinds */
245250
static int kraken3_read_z53(struct kraken3_data *priv)
246251
{
247252
int ret = mutex_lock_interruptible(&priv->z53_status_request_lock);
@@ -355,6 +360,13 @@ static int kraken3_write_curve(struct kraken3_data *priv, u8 *curve_array, int c
355360
/* Set the correct ID for writing pump/fan duty (0x01 or 0x02, respectively) */
356361
fixed_duty_cmd[SET_DUTY_ID_OFFSET] = channel + 1;
357362

363+
if (priv->kind == KRAKEN2023) {
364+
/* These require 1s in the next one or two slots after SET_DUTY_ID_OFFSET */
365+
fixed_duty_cmd[SET_DUTY_ID_OFFSET + 1] = 1;
366+
if (channel == 1) /* Fan */
367+
fixed_duty_cmd[SET_DUTY_ID_OFFSET + 2] = 1;
368+
}
369+
358370
/* Copy curve to command */
359371
memcpy(fixed_duty_cmd + SET_CURVE_DUTY_CMD_HEADER_LENGTH, curve_array, CUSTOM_CURVE_POINTS);
360372

@@ -502,8 +514,8 @@ static umode_t kraken3_curve_props_are_visible(struct kobject *kobj, struct attr
502514
struct device *dev = kobj_to_dev(kobj);
503515
struct kraken3_data *priv = dev_get_drvdata(dev);
504516

505-
/* Only Z53 has the fan curve */
506-
if (index >= CUSTOM_CURVE_POINTS && priv->kind != Z53)
517+
/* X53 does not have a fan */
518+
if (index >= CUSTOM_CURVE_POINTS && priv->kind == X53)
507519
return 0;
508520

509521
return attr->mode;
@@ -769,8 +781,8 @@ static int kraken3_raw_event(struct hid_device *hdev, struct hid_report *report,
769781
if (priv->kind == X53 && !completion_done(&priv->status_report_processed)) {
770782
/* Mark first X-series device report as received */
771783
complete_all(&priv->status_report_processed);
772-
} else if (priv->kind == Z53) {
773-
/* Additional readings for Z53 */
784+
} else if (priv->kind == Z53 || priv->kind == KRAKEN2023) {
785+
/* Additional readings for Z53 and KRAKEN2023 */
774786
priv->fan_input[1] = get_unaligned_le16(data + Z53_FAN_SPEED_OFFSET);
775787
priv->channel_info[1].reported_duty =
776788
kraken3_percent_to_pwm(data[Z53_FAN_DUTY_OFFSET]);
@@ -907,6 +919,14 @@ static int kraken3_probe(struct hid_device *hdev, const struct hid_device_id *id
907919
priv->kind = Z53;
908920
device_name = "z53";
909921
break;
922+
case USB_PRODUCT_ID_KRAKEN2023:
923+
priv->kind = KRAKEN2023;
924+
device_name = "kraken2023";
925+
break;
926+
case USB_PRODUCT_ID_KRAKEN2023_ELITE:
927+
priv->kind = KRAKEN2023;
928+
device_name = "kraken2023elite";
929+
break;
910930
default:
911931
break;
912932
}
@@ -969,6 +989,8 @@ static const struct hid_device_id kraken3_table[] = {
969989
{ HID_USB_DEVICE(USB_VENDOR_ID_NZXT, USB_PRODUCT_ID_X53) },
970990
{ HID_USB_DEVICE(USB_VENDOR_ID_NZXT, USB_PRODUCT_ID_X53_SECOND) },
971991
{ HID_USB_DEVICE(USB_VENDOR_ID_NZXT, USB_PRODUCT_ID_Z53) },
992+
{ HID_USB_DEVICE(USB_VENDOR_ID_NZXT, USB_PRODUCT_ID_KRAKEN2023) },
993+
{ HID_USB_DEVICE(USB_VENDOR_ID_NZXT, USB_PRODUCT_ID_KRAKEN2023_ELITE) },
972994
{ }
973995
};
974996

0 commit comments

Comments
 (0)