1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 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. 6 * 7 * Copyright 2021 Jonas Malaco <jonas@protocubo.io> 8 * Copyright 2022 Aleksa Savic <savicaleksa83@gmail.com> 9 */ 10 11 #include <linux/debugfs.h> 12 #include <linux/hid.h> 13 #include <linux/hwmon.h> 14 #include <linux/hwmon-sysfs.h> 15 #include <linux/jiffies.h> 16 #include <linux/module.h> 17 #include <linux/mutex.h> 18 #include <linux/spinlock.h> 19 #include <linux/wait.h> 20 #include <linux/unaligned.h> 21 22 #define USB_VENDOR_ID_NZXT 0x1e71 23 #define USB_PRODUCT_ID_X53 0x2007 24 #define USB_PRODUCT_ID_X53_SECOND 0x2014 25 #define USB_PRODUCT_ID_Z53 0x3008 26 #define USB_PRODUCT_ID_KRAKEN2023 0x300E 27 #define USB_PRODUCT_ID_KRAKEN2023_ELITE 0x300C 28 29 enum kinds { X53, Z53, KRAKEN2023 } __packed; 30 enum pwm_enable { off, manual, curve } __packed; 31 32 #define DRIVER_NAME "nzxt_kraken3" 33 #define STATUS_REPORT_ID 0x75 34 #define FIRMWARE_REPORT_ID 0x11 35 #define STATUS_VALIDITY 2000 /* In ms, equivalent to period of four status reports */ 36 #define CUSTOM_CURVE_POINTS 40 /* For temps from 20C to 59C (critical temp) */ 37 #define PUMP_DUTY_MIN 20 /* In percent */ 38 39 /* Sensor report offsets for Kraken X53 and Z53 */ 40 #define TEMP_SENSOR_START_OFFSET 15 41 #define TEMP_SENSOR_END_OFFSET 16 42 #define PUMP_SPEED_OFFSET 17 43 #define PUMP_DUTY_OFFSET 19 44 45 /* Firmware version report offset for Kraken X53 and Z53 */ 46 #define FIRMWARE_VERSION_OFFSET 17 47 48 /* Sensor report offsets for Kraken Z53 */ 49 #define Z53_FAN_SPEED_OFFSET 23 50 #define Z53_FAN_DUTY_OFFSET 25 51 52 /* Report offsets for control commands for Kraken X53 and Z53 */ 53 #define SET_DUTY_ID_OFFSET 1 54 55 /* Control commands and their lengths for Kraken X53 and Z53 */ 56 57 /* Last byte sets the report interval at 0.5s */ 58 static const u8 set_interval_cmd[] = { 0x70, 0x02, 0x01, 0xB8, 1 }; 59 static const u8 finish_init_cmd[] = { 0x70, 0x01 }; 60 static const u8 __maybe_unused get_fw_version_cmd[] = { 0x10, 0x01 }; 61 static const u8 set_pump_duty_cmd_header[] = { 0x72, 0x00, 0x00, 0x00 }; 62 static const u8 z53_get_status_cmd[] = { 0x74, 0x01 }; 63 64 #define SET_INTERVAL_CMD_LENGTH 5 65 #define FINISH_INIT_CMD_LENGTH 2 66 #define GET_FW_VERSION_CMD_LENGTH 2 67 #define MAX_REPORT_LENGTH 64 68 #define MIN_REPORT_LENGTH 20 69 #define SET_CURVE_DUTY_CMD_HEADER_LENGTH 4 70 /* 4 byte header and 40 duty offsets */ 71 #define SET_CURVE_DUTY_CMD_LENGTH (4 + 40) 72 #define Z53_GET_STATUS_CMD_LENGTH 2 73 74 static const char *const kraken3_temp_label[] = { 75 "Coolant temp", 76 }; 77 78 static const char *const kraken3_fan_label[] = { 79 "Pump speed", 80 "Fan speed" 81 }; 82 83 struct kraken3_channel_info { 84 enum pwm_enable mode; 85 86 /* Both values are PWM */ 87 u16 reported_duty; 88 u16 fixed_duty; /* Manually set fixed duty */ 89 90 u8 pwm_points[CUSTOM_CURVE_POINTS]; 91 }; 92 93 struct kraken3_data { 94 struct hid_device *hdev; 95 struct device *hwmon_dev; 96 struct dentry *debugfs; 97 struct mutex buffer_lock; /* For locking access to buffer */ 98 struct mutex z53_status_request_lock; 99 struct completion fw_version_processed; 100 /* 101 * For X53 devices, tracks whether an initial (one) sensor report was received to 102 * make fancontrol not bail outright. For Z53 devices, whether a status report 103 * was processed after requesting one. 104 */ 105 struct completion status_report_processed; 106 /* For locking the above completion */ 107 spinlock_t status_completion_lock; 108 109 u8 *buffer; 110 struct kraken3_channel_info channel_info[2]; /* Pump and fan */ 111 bool is_device_faulty; 112 113 /* Sensor values */ 114 s32 temp_input[1]; 115 u16 fan_input[2]; 116 117 enum kinds kind; 118 u8 firmware_version[3]; 119 120 unsigned long updated; /* jiffies */ 121 }; 122 123 static umode_t kraken3_is_visible(const void *data, enum hwmon_sensor_types type, u32 attr, 124 int channel) 125 { 126 const struct kraken3_data *priv = data; 127 128 switch (type) { 129 case hwmon_temp: 130 if (channel < 1) 131 return 0444; 132 break; 133 case hwmon_fan: 134 switch (priv->kind) { 135 case X53: 136 /* Just the pump */ 137 if (channel < 1) 138 return 0444; 139 break; 140 case Z53: 141 case KRAKEN2023: 142 /* Pump and fan */ 143 if (channel < 2) 144 return 0444; 145 break; 146 default: 147 break; 148 } 149 break; 150 case hwmon_pwm: 151 switch (attr) { 152 case hwmon_pwm_enable: 153 case hwmon_pwm_input: 154 switch (priv->kind) { 155 case X53: 156 /* Just the pump */ 157 if (channel < 1) 158 return 0644; 159 break; 160 case Z53: 161 case KRAKEN2023: 162 /* Pump and fan */ 163 if (channel < 2) 164 return 0644; 165 break; 166 default: 167 break; 168 } 169 break; 170 default: 171 break; 172 } 173 break; 174 default: 175 break; 176 } 177 178 return 0; 179 } 180 181 /* 182 * Writes the command to the device with the rest of the report (up to 64 bytes) filled 183 * with zeroes. 184 */ 185 static int kraken3_write_expanded(struct kraken3_data *priv, const u8 *cmd, int cmd_length) 186 { 187 int ret; 188 189 mutex_lock(&priv->buffer_lock); 190 191 memcpy_and_pad(priv->buffer, MAX_REPORT_LENGTH, cmd, cmd_length, 0x00); 192 ret = hid_hw_output_report(priv->hdev, priv->buffer, MAX_REPORT_LENGTH); 193 194 mutex_unlock(&priv->buffer_lock); 195 return ret; 196 } 197 198 static int kraken3_percent_to_pwm(long val) 199 { 200 return DIV_ROUND_CLOSEST(val * 255, 100); 201 } 202 203 static int kraken3_pwm_to_percent(long val, int channel) 204 { 205 int percent_value; 206 207 if (val < 0 || val > 255) 208 return -EINVAL; 209 210 percent_value = DIV_ROUND_CLOSEST(val * 100, 255); 211 212 /* Bring up pump duty to min value if needed */ 213 if (channel == 0 && percent_value < PUMP_DUTY_MIN) 214 percent_value = PUMP_DUTY_MIN; 215 216 return percent_value; 217 } 218 219 static int kraken3_read_x53(struct kraken3_data *priv) 220 { 221 int ret; 222 223 if (completion_done(&priv->status_report_processed)) 224 /* 225 * We're here because data is stale. This means that sensor reports haven't 226 * been received for some time in kraken3_raw_event(). On X-series sensor data 227 * can't be manually requested, so return an error. 228 */ 229 return -ENODATA; 230 231 /* 232 * Data needs to be read, but a sensor report wasn't yet received. It's usually 233 * fancontrol that requests data this early and it exits if it reads an error code. 234 * So, wait for the first report to be parsed (but up to STATUS_VALIDITY). 235 * This does not concern the Z series devices, because they send a sensor report 236 * only when requested. 237 */ 238 ret = wait_for_completion_interruptible_timeout(&priv->status_report_processed, 239 msecs_to_jiffies(STATUS_VALIDITY)); 240 if (ret == 0) 241 return -ETIMEDOUT; 242 else if (ret < 0) 243 return ret; 244 245 /* The first sensor report was parsed on time and reading can continue */ 246 return 0; 247 } 248 249 /* Covers Z53 and KRAKEN2023 device kinds */ 250 static int kraken3_read_z53(struct kraken3_data *priv) 251 { 252 int ret = mutex_lock_interruptible(&priv->z53_status_request_lock); 253 254 if (ret < 0) 255 return ret; 256 257 if (!time_after(jiffies, priv->updated + msecs_to_jiffies(STATUS_VALIDITY))) { 258 /* Data is up to date */ 259 goto unlock_and_return; 260 } 261 262 /* 263 * Disable interrupts for a moment to safely reinit the completion, 264 * as hidraw calls could have allowed one or more readers to complete. 265 */ 266 spin_lock_bh(&priv->status_completion_lock); 267 reinit_completion(&priv->status_report_processed); 268 spin_unlock_bh(&priv->status_completion_lock); 269 270 /* Send command for getting status */ 271 ret = kraken3_write_expanded(priv, z53_get_status_cmd, Z53_GET_STATUS_CMD_LENGTH); 272 if (ret < 0) 273 goto unlock_and_return; 274 275 /* Wait for completion from kraken3_raw_event() */ 276 ret = wait_for_completion_interruptible_timeout(&priv->status_report_processed, 277 msecs_to_jiffies(STATUS_VALIDITY)); 278 if (ret == 0) 279 ret = -ETIMEDOUT; 280 281 unlock_and_return: 282 mutex_unlock(&priv->z53_status_request_lock); 283 if (ret < 0) 284 return ret; 285 286 return 0; 287 } 288 289 static int kraken3_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, 290 long *val) 291 { 292 struct kraken3_data *priv = dev_get_drvdata(dev); 293 int ret; 294 295 if (time_after(jiffies, priv->updated + msecs_to_jiffies(STATUS_VALIDITY))) { 296 if (priv->kind == X53) 297 ret = kraken3_read_x53(priv); 298 else 299 ret = kraken3_read_z53(priv); 300 301 if (ret < 0) 302 return ret; 303 304 if (priv->is_device_faulty) 305 return -ENODATA; 306 } 307 308 switch (type) { 309 case hwmon_temp: 310 *val = priv->temp_input[channel]; 311 break; 312 case hwmon_fan: 313 *val = priv->fan_input[channel]; 314 break; 315 case hwmon_pwm: 316 switch (attr) { 317 case hwmon_pwm_enable: 318 *val = priv->channel_info[channel].mode; 319 break; 320 case hwmon_pwm_input: 321 *val = priv->channel_info[channel].reported_duty; 322 break; 323 default: 324 return -EOPNOTSUPP; 325 } 326 break; 327 default: 328 return -EOPNOTSUPP; 329 } 330 331 return 0; 332 } 333 334 static int kraken3_read_string(struct device *dev, enum hwmon_sensor_types type, u32 attr, 335 int channel, const char **str) 336 { 337 switch (type) { 338 case hwmon_temp: 339 *str = kraken3_temp_label[channel]; 340 break; 341 case hwmon_fan: 342 *str = kraken3_fan_label[channel]; 343 break; 344 default: 345 return -EOPNOTSUPP; 346 } 347 348 return 0; 349 } 350 351 /* Writes custom curve to device */ 352 static int kraken3_write_curve(struct kraken3_data *priv, u8 *curve_array, int channel) 353 { 354 u8 fixed_duty_cmd[SET_CURVE_DUTY_CMD_LENGTH]; 355 int ret; 356 357 /* Copy command header */ 358 memcpy(fixed_duty_cmd, set_pump_duty_cmd_header, SET_CURVE_DUTY_CMD_HEADER_LENGTH); 359 360 /* Set the correct ID for writing pump/fan duty (0x01 or 0x02, respectively) */ 361 fixed_duty_cmd[SET_DUTY_ID_OFFSET] = channel + 1; 362 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 370 /* Copy curve to command */ 371 memcpy(fixed_duty_cmd + SET_CURVE_DUTY_CMD_HEADER_LENGTH, curve_array, CUSTOM_CURVE_POINTS); 372 373 ret = kraken3_write_expanded(priv, fixed_duty_cmd, SET_CURVE_DUTY_CMD_LENGTH); 374 return ret; 375 } 376 377 static int kraken3_write_fixed_duty(struct kraken3_data *priv, long val, int channel) 378 { 379 u8 fixed_curve_points[CUSTOM_CURVE_POINTS]; 380 int ret, percent_val, i; 381 382 percent_val = kraken3_pwm_to_percent(val, channel); 383 if (percent_val < 0) 384 return percent_val; 385 386 /* 387 * The devices can only control the duty through a curve. 388 * Since we're setting a fixed duty here, fill the whole curve 389 * (ranging from 20C to 59C) with the same duty, except for 390 * the last point, the critical temperature, where it's maxed 391 * out for safety. 392 */ 393 394 /* Fill the custom curve with the fixed value we're setting */ 395 for (i = 0; i < CUSTOM_CURVE_POINTS - 1; i++) 396 fixed_curve_points[i] = percent_val; 397 398 /* Force duty to 100% at critical temp */ 399 fixed_curve_points[CUSTOM_CURVE_POINTS - 1] = 100; 400 401 /* Write the fixed duty curve to the device */ 402 ret = kraken3_write_curve(priv, fixed_curve_points, channel); 403 return ret; 404 } 405 406 static int kraken3_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, 407 long val) 408 { 409 struct kraken3_data *priv = dev_get_drvdata(dev); 410 int ret; 411 412 switch (type) { 413 case hwmon_pwm: 414 switch (attr) { 415 case hwmon_pwm_input: 416 /* Remember the last set fixed duty for channel */ 417 priv->channel_info[channel].fixed_duty = val; 418 419 if (priv->channel_info[channel].mode == manual) { 420 ret = kraken3_write_fixed_duty(priv, val, channel); 421 if (ret < 0) 422 return ret; 423 424 /* 425 * Lock onto this value and report it until next interrupt status 426 * report is received, so userspace tools can continue to work. 427 */ 428 priv->channel_info[channel].reported_duty = val; 429 } 430 break; 431 case hwmon_pwm_enable: 432 if (val < 0 || val > 2) 433 return -EINVAL; 434 435 switch (val) { 436 case 0: 437 /* Set channel to 100%, direct duty value */ 438 ret = kraken3_write_fixed_duty(priv, 255, channel); 439 if (ret < 0) 440 return ret; 441 442 /* We don't control anything anymore */ 443 priv->channel_info[channel].mode = off; 444 break; 445 case 1: 446 /* Apply the last known direct duty value */ 447 ret = 448 kraken3_write_fixed_duty(priv, 449 priv->channel_info[channel].fixed_duty, 450 channel); 451 if (ret < 0) 452 return ret; 453 454 priv->channel_info[channel].mode = manual; 455 break; 456 case 2: 457 /* Apply the curve and note as enabled */ 458 ret = 459 kraken3_write_curve(priv, 460 priv->channel_info[channel].pwm_points, 461 channel); 462 if (ret < 0) 463 return ret; 464 465 priv->channel_info[channel].mode = curve; 466 break; 467 default: 468 break; 469 } 470 break; 471 default: 472 return -EOPNOTSUPP; 473 } 474 break; 475 default: 476 return -EOPNOTSUPP; 477 } 478 479 return 0; 480 } 481 482 static ssize_t kraken3_fan_curve_pwm_store(struct device *dev, struct device_attribute *attr, 483 const char *buf, size_t count) 484 { 485 struct sensor_device_attribute_2 *dev_attr = to_sensor_dev_attr_2(attr); 486 struct kraken3_data *priv = dev_get_drvdata(dev); 487 long val; 488 int ret; 489 490 if (kstrtol(buf, 10, &val) < 0) 491 return -EINVAL; 492 493 val = kraken3_pwm_to_percent(val, dev_attr->nr); 494 if (val < 0) 495 return val; 496 497 priv->channel_info[dev_attr->nr].pwm_points[dev_attr->index] = val; 498 499 if (priv->channel_info[dev_attr->nr].mode == curve) { 500 /* Apply the curve */ 501 ret = 502 kraken3_write_curve(priv, 503 priv->channel_info[dev_attr->nr].pwm_points, dev_attr->nr); 504 if (ret < 0) 505 return ret; 506 } 507 508 return count; 509 } 510 511 static umode_t kraken3_curve_props_are_visible(struct kobject *kobj, struct attribute *attr, 512 int index) 513 { 514 struct device *dev = kobj_to_dev(kobj); 515 struct kraken3_data *priv = dev_get_drvdata(dev); 516 517 /* X53 does not have a fan */ 518 if (index >= CUSTOM_CURVE_POINTS && priv->kind == X53) 519 return 0; 520 521 return attr->mode; 522 } 523 524 /* Custom pump curve from 20C to 59C (critical temp) */ 525 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point1_pwm, kraken3_fan_curve_pwm, 0, 0); 526 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point2_pwm, kraken3_fan_curve_pwm, 0, 1); 527 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point3_pwm, kraken3_fan_curve_pwm, 0, 2); 528 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point4_pwm, kraken3_fan_curve_pwm, 0, 3); 529 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point5_pwm, kraken3_fan_curve_pwm, 0, 4); 530 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point6_pwm, kraken3_fan_curve_pwm, 0, 5); 531 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point7_pwm, kraken3_fan_curve_pwm, 0, 6); 532 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point8_pwm, kraken3_fan_curve_pwm, 0, 7); 533 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point9_pwm, kraken3_fan_curve_pwm, 0, 8); 534 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point10_pwm, kraken3_fan_curve_pwm, 0, 9); 535 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point11_pwm, kraken3_fan_curve_pwm, 0, 10); 536 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point12_pwm, kraken3_fan_curve_pwm, 0, 11); 537 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point13_pwm, kraken3_fan_curve_pwm, 0, 12); 538 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point14_pwm, kraken3_fan_curve_pwm, 0, 13); 539 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point15_pwm, kraken3_fan_curve_pwm, 0, 14); 540 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point16_pwm, kraken3_fan_curve_pwm, 0, 15); 541 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point17_pwm, kraken3_fan_curve_pwm, 0, 16); 542 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point18_pwm, kraken3_fan_curve_pwm, 0, 17); 543 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point19_pwm, kraken3_fan_curve_pwm, 0, 18); 544 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point20_pwm, kraken3_fan_curve_pwm, 0, 19); 545 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point21_pwm, kraken3_fan_curve_pwm, 0, 20); 546 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point22_pwm, kraken3_fan_curve_pwm, 0, 21); 547 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point23_pwm, kraken3_fan_curve_pwm, 0, 22); 548 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point24_pwm, kraken3_fan_curve_pwm, 0, 23); 549 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point25_pwm, kraken3_fan_curve_pwm, 0, 24); 550 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point26_pwm, kraken3_fan_curve_pwm, 0, 25); 551 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point27_pwm, kraken3_fan_curve_pwm, 0, 26); 552 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point28_pwm, kraken3_fan_curve_pwm, 0, 27); 553 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point29_pwm, kraken3_fan_curve_pwm, 0, 28); 554 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point30_pwm, kraken3_fan_curve_pwm, 0, 29); 555 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point31_pwm, kraken3_fan_curve_pwm, 0, 30); 556 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point32_pwm, kraken3_fan_curve_pwm, 0, 31); 557 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point33_pwm, kraken3_fan_curve_pwm, 0, 32); 558 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point34_pwm, kraken3_fan_curve_pwm, 0, 33); 559 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point35_pwm, kraken3_fan_curve_pwm, 0, 34); 560 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point36_pwm, kraken3_fan_curve_pwm, 0, 35); 561 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point37_pwm, kraken3_fan_curve_pwm, 0, 36); 562 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point38_pwm, kraken3_fan_curve_pwm, 0, 37); 563 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point39_pwm, kraken3_fan_curve_pwm, 0, 38); 564 static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point40_pwm, kraken3_fan_curve_pwm, 0, 39); 565 566 /* Custom fan curve from 20C to 59C (critical temp) */ 567 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point1_pwm, kraken3_fan_curve_pwm, 1, 0); 568 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point2_pwm, kraken3_fan_curve_pwm, 1, 1); 569 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point3_pwm, kraken3_fan_curve_pwm, 1, 2); 570 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point4_pwm, kraken3_fan_curve_pwm, 1, 3); 571 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point5_pwm, kraken3_fan_curve_pwm, 1, 4); 572 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point6_pwm, kraken3_fan_curve_pwm, 1, 5); 573 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point7_pwm, kraken3_fan_curve_pwm, 1, 6); 574 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point8_pwm, kraken3_fan_curve_pwm, 1, 7); 575 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point9_pwm, kraken3_fan_curve_pwm, 1, 8); 576 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point10_pwm, kraken3_fan_curve_pwm, 1, 9); 577 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point11_pwm, kraken3_fan_curve_pwm, 1, 10); 578 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point12_pwm, kraken3_fan_curve_pwm, 1, 11); 579 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point13_pwm, kraken3_fan_curve_pwm, 1, 12); 580 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point14_pwm, kraken3_fan_curve_pwm, 1, 13); 581 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point15_pwm, kraken3_fan_curve_pwm, 1, 14); 582 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point16_pwm, kraken3_fan_curve_pwm, 1, 15); 583 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point17_pwm, kraken3_fan_curve_pwm, 1, 16); 584 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point18_pwm, kraken3_fan_curve_pwm, 1, 17); 585 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point19_pwm, kraken3_fan_curve_pwm, 1, 18); 586 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point20_pwm, kraken3_fan_curve_pwm, 1, 19); 587 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point21_pwm, kraken3_fan_curve_pwm, 1, 20); 588 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point22_pwm, kraken3_fan_curve_pwm, 1, 21); 589 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point23_pwm, kraken3_fan_curve_pwm, 1, 22); 590 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point24_pwm, kraken3_fan_curve_pwm, 1, 23); 591 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point25_pwm, kraken3_fan_curve_pwm, 1, 24); 592 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point26_pwm, kraken3_fan_curve_pwm, 1, 25); 593 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point27_pwm, kraken3_fan_curve_pwm, 1, 26); 594 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point28_pwm, kraken3_fan_curve_pwm, 1, 27); 595 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point29_pwm, kraken3_fan_curve_pwm, 1, 28); 596 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point30_pwm, kraken3_fan_curve_pwm, 1, 29); 597 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point31_pwm, kraken3_fan_curve_pwm, 1, 30); 598 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point32_pwm, kraken3_fan_curve_pwm, 1, 31); 599 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point33_pwm, kraken3_fan_curve_pwm, 1, 32); 600 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point34_pwm, kraken3_fan_curve_pwm, 1, 33); 601 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point35_pwm, kraken3_fan_curve_pwm, 1, 34); 602 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point36_pwm, kraken3_fan_curve_pwm, 1, 35); 603 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point37_pwm, kraken3_fan_curve_pwm, 1, 36); 604 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point38_pwm, kraken3_fan_curve_pwm, 1, 37); 605 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point39_pwm, kraken3_fan_curve_pwm, 1, 38); 606 static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point40_pwm, kraken3_fan_curve_pwm, 1, 39); 607 608 static struct attribute *kraken3_curve_attrs[] = { 609 /* Pump control curve */ 610 &sensor_dev_attr_temp1_auto_point1_pwm.dev_attr.attr, 611 &sensor_dev_attr_temp1_auto_point2_pwm.dev_attr.attr, 612 &sensor_dev_attr_temp1_auto_point3_pwm.dev_attr.attr, 613 &sensor_dev_attr_temp1_auto_point4_pwm.dev_attr.attr, 614 &sensor_dev_attr_temp1_auto_point5_pwm.dev_attr.attr, 615 &sensor_dev_attr_temp1_auto_point6_pwm.dev_attr.attr, 616 &sensor_dev_attr_temp1_auto_point7_pwm.dev_attr.attr, 617 &sensor_dev_attr_temp1_auto_point8_pwm.dev_attr.attr, 618 &sensor_dev_attr_temp1_auto_point9_pwm.dev_attr.attr, 619 &sensor_dev_attr_temp1_auto_point10_pwm.dev_attr.attr, 620 &sensor_dev_attr_temp1_auto_point11_pwm.dev_attr.attr, 621 &sensor_dev_attr_temp1_auto_point12_pwm.dev_attr.attr, 622 &sensor_dev_attr_temp1_auto_point13_pwm.dev_attr.attr, 623 &sensor_dev_attr_temp1_auto_point14_pwm.dev_attr.attr, 624 &sensor_dev_attr_temp1_auto_point15_pwm.dev_attr.attr, 625 &sensor_dev_attr_temp1_auto_point16_pwm.dev_attr.attr, 626 &sensor_dev_attr_temp1_auto_point17_pwm.dev_attr.attr, 627 &sensor_dev_attr_temp1_auto_point18_pwm.dev_attr.attr, 628 &sensor_dev_attr_temp1_auto_point19_pwm.dev_attr.attr, 629 &sensor_dev_attr_temp1_auto_point20_pwm.dev_attr.attr, 630 &sensor_dev_attr_temp1_auto_point21_pwm.dev_attr.attr, 631 &sensor_dev_attr_temp1_auto_point22_pwm.dev_attr.attr, 632 &sensor_dev_attr_temp1_auto_point23_pwm.dev_attr.attr, 633 &sensor_dev_attr_temp1_auto_point24_pwm.dev_attr.attr, 634 &sensor_dev_attr_temp1_auto_point25_pwm.dev_attr.attr, 635 &sensor_dev_attr_temp1_auto_point26_pwm.dev_attr.attr, 636 &sensor_dev_attr_temp1_auto_point27_pwm.dev_attr.attr, 637 &sensor_dev_attr_temp1_auto_point28_pwm.dev_attr.attr, 638 &sensor_dev_attr_temp1_auto_point29_pwm.dev_attr.attr, 639 &sensor_dev_attr_temp1_auto_point30_pwm.dev_attr.attr, 640 &sensor_dev_attr_temp1_auto_point31_pwm.dev_attr.attr, 641 &sensor_dev_attr_temp1_auto_point32_pwm.dev_attr.attr, 642 &sensor_dev_attr_temp1_auto_point33_pwm.dev_attr.attr, 643 &sensor_dev_attr_temp1_auto_point34_pwm.dev_attr.attr, 644 &sensor_dev_attr_temp1_auto_point35_pwm.dev_attr.attr, 645 &sensor_dev_attr_temp1_auto_point36_pwm.dev_attr.attr, 646 &sensor_dev_attr_temp1_auto_point37_pwm.dev_attr.attr, 647 &sensor_dev_attr_temp1_auto_point38_pwm.dev_attr.attr, 648 &sensor_dev_attr_temp1_auto_point39_pwm.dev_attr.attr, 649 &sensor_dev_attr_temp1_auto_point40_pwm.dev_attr.attr, 650 /* Fan control curve (Z53 only) */ 651 &sensor_dev_attr_temp2_auto_point1_pwm.dev_attr.attr, 652 &sensor_dev_attr_temp2_auto_point2_pwm.dev_attr.attr, 653 &sensor_dev_attr_temp2_auto_point3_pwm.dev_attr.attr, 654 &sensor_dev_attr_temp2_auto_point4_pwm.dev_attr.attr, 655 &sensor_dev_attr_temp2_auto_point5_pwm.dev_attr.attr, 656 &sensor_dev_attr_temp2_auto_point6_pwm.dev_attr.attr, 657 &sensor_dev_attr_temp2_auto_point7_pwm.dev_attr.attr, 658 &sensor_dev_attr_temp2_auto_point8_pwm.dev_attr.attr, 659 &sensor_dev_attr_temp2_auto_point9_pwm.dev_attr.attr, 660 &sensor_dev_attr_temp2_auto_point10_pwm.dev_attr.attr, 661 &sensor_dev_attr_temp2_auto_point11_pwm.dev_attr.attr, 662 &sensor_dev_attr_temp2_auto_point12_pwm.dev_attr.attr, 663 &sensor_dev_attr_temp2_auto_point13_pwm.dev_attr.attr, 664 &sensor_dev_attr_temp2_auto_point14_pwm.dev_attr.attr, 665 &sensor_dev_attr_temp2_auto_point15_pwm.dev_attr.attr, 666 &sensor_dev_attr_temp2_auto_point16_pwm.dev_attr.attr, 667 &sensor_dev_attr_temp2_auto_point17_pwm.dev_attr.attr, 668 &sensor_dev_attr_temp2_auto_point18_pwm.dev_attr.attr, 669 &sensor_dev_attr_temp2_auto_point19_pwm.dev_attr.attr, 670 &sensor_dev_attr_temp2_auto_point20_pwm.dev_attr.attr, 671 &sensor_dev_attr_temp2_auto_point21_pwm.dev_attr.attr, 672 &sensor_dev_attr_temp2_auto_point22_pwm.dev_attr.attr, 673 &sensor_dev_attr_temp2_auto_point23_pwm.dev_attr.attr, 674 &sensor_dev_attr_temp2_auto_point24_pwm.dev_attr.attr, 675 &sensor_dev_attr_temp2_auto_point25_pwm.dev_attr.attr, 676 &sensor_dev_attr_temp2_auto_point26_pwm.dev_attr.attr, 677 &sensor_dev_attr_temp2_auto_point27_pwm.dev_attr.attr, 678 &sensor_dev_attr_temp2_auto_point28_pwm.dev_attr.attr, 679 &sensor_dev_attr_temp2_auto_point29_pwm.dev_attr.attr, 680 &sensor_dev_attr_temp2_auto_point30_pwm.dev_attr.attr, 681 &sensor_dev_attr_temp2_auto_point31_pwm.dev_attr.attr, 682 &sensor_dev_attr_temp2_auto_point32_pwm.dev_attr.attr, 683 &sensor_dev_attr_temp2_auto_point33_pwm.dev_attr.attr, 684 &sensor_dev_attr_temp2_auto_point34_pwm.dev_attr.attr, 685 &sensor_dev_attr_temp2_auto_point35_pwm.dev_attr.attr, 686 &sensor_dev_attr_temp2_auto_point36_pwm.dev_attr.attr, 687 &sensor_dev_attr_temp2_auto_point37_pwm.dev_attr.attr, 688 &sensor_dev_attr_temp2_auto_point38_pwm.dev_attr.attr, 689 &sensor_dev_attr_temp2_auto_point39_pwm.dev_attr.attr, 690 &sensor_dev_attr_temp2_auto_point40_pwm.dev_attr.attr, 691 NULL 692 }; 693 694 static const struct attribute_group kraken3_curves_group = { 695 .attrs = kraken3_curve_attrs, 696 .is_visible = kraken3_curve_props_are_visible 697 }; 698 699 static const struct attribute_group *kraken3_groups[] = { 700 &kraken3_curves_group, 701 NULL 702 }; 703 704 static const struct hwmon_ops kraken3_hwmon_ops = { 705 .is_visible = kraken3_is_visible, 706 .read = kraken3_read, 707 .read_string = kraken3_read_string, 708 .write = kraken3_write 709 }; 710 711 static const struct hwmon_channel_info *kraken3_info[] = { 712 HWMON_CHANNEL_INFO(temp, 713 HWMON_T_INPUT | HWMON_T_LABEL), 714 HWMON_CHANNEL_INFO(fan, 715 HWMON_F_INPUT | HWMON_F_LABEL, 716 HWMON_F_INPUT | HWMON_F_LABEL, 717 HWMON_F_INPUT | HWMON_F_LABEL, 718 HWMON_F_INPUT | HWMON_F_LABEL), 719 HWMON_CHANNEL_INFO(pwm, 720 HWMON_PWM_INPUT | HWMON_PWM_ENABLE, 721 HWMON_PWM_INPUT | HWMON_PWM_ENABLE), 722 NULL 723 }; 724 725 static const struct hwmon_chip_info kraken3_chip_info = { 726 .ops = &kraken3_hwmon_ops, 727 .info = kraken3_info, 728 }; 729 730 static int kraken3_raw_event(struct hid_device *hdev, struct hid_report *report, u8 *data, int size) 731 { 732 struct kraken3_data *priv = hid_get_drvdata(hdev); 733 int i; 734 735 if (size < MIN_REPORT_LENGTH) 736 return 0; 737 738 if (report->id == FIRMWARE_REPORT_ID) { 739 /* Read firmware version */ 740 for (i = 0; i < 3; i++) 741 priv->firmware_version[i] = data[FIRMWARE_VERSION_OFFSET + i]; 742 743 if (!completion_done(&priv->fw_version_processed)) 744 complete_all(&priv->fw_version_processed); 745 746 return 0; 747 } 748 749 if (report->id != STATUS_REPORT_ID) 750 return 0; 751 752 if (data[TEMP_SENSOR_START_OFFSET] == 0xff && data[TEMP_SENSOR_END_OFFSET] == 0xff) { 753 hid_err_once(hdev, 754 "firmware or device is possibly damaged (is SATA power connected?), not parsing reports\n"); 755 756 /* 757 * Mark first X-series device report as received, 758 * as well as all for Z-series, if faulty. 759 */ 760 spin_lock(&priv->status_completion_lock); 761 if (priv->kind != X53 || !completion_done(&priv->status_report_processed)) { 762 priv->is_device_faulty = true; 763 complete_all(&priv->status_report_processed); 764 } 765 spin_unlock(&priv->status_completion_lock); 766 767 return 0; 768 } 769 770 /* Received normal data */ 771 priv->is_device_faulty = false; 772 773 /* Temperature and fan sensor readings */ 774 priv->temp_input[0] = 775 data[TEMP_SENSOR_START_OFFSET] * 1000 + data[TEMP_SENSOR_END_OFFSET] * 100; 776 777 priv->fan_input[0] = get_unaligned_le16(data + PUMP_SPEED_OFFSET); 778 priv->channel_info[0].reported_duty = kraken3_percent_to_pwm(data[PUMP_DUTY_OFFSET]); 779 780 spin_lock(&priv->status_completion_lock); 781 if (priv->kind == X53 && !completion_done(&priv->status_report_processed)) { 782 /* Mark first X-series device report as received */ 783 complete_all(&priv->status_report_processed); 784 } else if (priv->kind == Z53 || priv->kind == KRAKEN2023) { 785 /* Additional readings for Z53 and KRAKEN2023 */ 786 priv->fan_input[1] = get_unaligned_le16(data + Z53_FAN_SPEED_OFFSET); 787 priv->channel_info[1].reported_duty = 788 kraken3_percent_to_pwm(data[Z53_FAN_DUTY_OFFSET]); 789 790 if (!completion_done(&priv->status_report_processed)) 791 complete_all(&priv->status_report_processed); 792 } 793 spin_unlock(&priv->status_completion_lock); 794 795 priv->updated = jiffies; 796 797 return 0; 798 } 799 800 static int kraken3_init_device(struct hid_device *hdev) 801 { 802 struct kraken3_data *priv = hid_get_drvdata(hdev); 803 int ret; 804 805 /* Set the polling interval */ 806 ret = kraken3_write_expanded(priv, set_interval_cmd, SET_INTERVAL_CMD_LENGTH); 807 if (ret < 0) 808 return ret; 809 810 /* Finalize the init process */ 811 ret = kraken3_write_expanded(priv, finish_init_cmd, FINISH_INIT_CMD_LENGTH); 812 if (ret < 0) 813 return ret; 814 815 return 0; 816 } 817 818 static int kraken3_get_fw_ver(struct hid_device *hdev) 819 { 820 struct kraken3_data *priv = hid_get_drvdata(hdev); 821 int ret; 822 823 ret = kraken3_write_expanded(priv, get_fw_version_cmd, GET_FW_VERSION_CMD_LENGTH); 824 if (ret < 0) 825 return ret; 826 827 ret = wait_for_completion_interruptible_timeout(&priv->fw_version_processed, 828 msecs_to_jiffies(STATUS_VALIDITY)); 829 if (ret == 0) 830 return -ETIMEDOUT; 831 else if (ret < 0) 832 return ret; 833 834 return 0; 835 } 836 837 static int __maybe_unused kraken3_reset_resume(struct hid_device *hdev) 838 { 839 int ret; 840 841 ret = kraken3_init_device(hdev); 842 if (ret) 843 hid_err(hdev, "req init (reset_resume) failed with %d\n", ret); 844 845 return ret; 846 } 847 848 static int firmware_version_show(struct seq_file *seqf, void *unused) 849 { 850 struct kraken3_data *priv = seqf->private; 851 852 seq_printf(seqf, "%u.%u.%u\n", priv->firmware_version[0], priv->firmware_version[1], 853 priv->firmware_version[2]); 854 855 return 0; 856 } 857 DEFINE_SHOW_ATTRIBUTE(firmware_version); 858 859 static void kraken3_debugfs_init(struct kraken3_data *priv, const char *device_name) 860 { 861 char name[64]; 862 863 if (!priv->firmware_version[0]) 864 return; /* Nothing to display in debugfs */ 865 866 scnprintf(name, sizeof(name), "%s_%s-%s", DRIVER_NAME, device_name, 867 dev_name(&priv->hdev->dev)); 868 869 priv->debugfs = debugfs_create_dir(name, NULL); 870 debugfs_create_file("firmware_version", 0444, priv->debugfs, priv, &firmware_version_fops); 871 } 872 873 static int kraken3_probe(struct hid_device *hdev, const struct hid_device_id *id) 874 { 875 struct kraken3_data *priv; 876 const char *device_name; 877 int ret; 878 879 priv = devm_kzalloc(&hdev->dev, sizeof(*priv), GFP_KERNEL); 880 if (!priv) 881 return -ENOMEM; 882 883 priv->hdev = hdev; 884 hid_set_drvdata(hdev, priv); 885 886 /* 887 * Initialize ->updated to STATUS_VALIDITY seconds in the past, making 888 * the initial empty data invalid for kraken3_read without the need for 889 * a special case there. 890 */ 891 priv->updated = jiffies - msecs_to_jiffies(STATUS_VALIDITY); 892 893 ret = hid_parse(hdev); 894 if (ret) { 895 hid_err(hdev, "hid parse failed with %d\n", ret); 896 return ret; 897 } 898 899 /* Enable hidraw so existing user-space tools can continue to work */ 900 ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW); 901 if (ret) { 902 hid_err(hdev, "hid hw start failed with %d\n", ret); 903 return ret; 904 } 905 906 ret = hid_hw_open(hdev); 907 if (ret) { 908 hid_err(hdev, "hid hw open failed with %d\n", ret); 909 goto fail_and_stop; 910 } 911 912 switch (hdev->product) { 913 case USB_PRODUCT_ID_X53: 914 case USB_PRODUCT_ID_X53_SECOND: 915 priv->kind = X53; 916 device_name = "x53"; 917 break; 918 case USB_PRODUCT_ID_Z53: 919 priv->kind = Z53; 920 device_name = "z53"; 921 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; 930 default: 931 ret = -ENODEV; 932 goto fail_and_close; 933 } 934 935 priv->buffer = devm_kzalloc(&hdev->dev, MAX_REPORT_LENGTH, GFP_KERNEL); 936 if (!priv->buffer) { 937 ret = -ENOMEM; 938 goto fail_and_close; 939 } 940 941 mutex_init(&priv->buffer_lock); 942 mutex_init(&priv->z53_status_request_lock); 943 init_completion(&priv->fw_version_processed); 944 init_completion(&priv->status_report_processed); 945 spin_lock_init(&priv->status_completion_lock); 946 947 hid_device_io_start(hdev); 948 ret = kraken3_init_device(hdev); 949 if (ret < 0) { 950 hid_err(hdev, "device init failed with %d\n", ret); 951 goto fail_and_close; 952 } 953 954 ret = kraken3_get_fw_ver(hdev); 955 if (ret < 0) 956 hid_warn(hdev, "fw version request failed with %d\n", ret); 957 958 priv->hwmon_dev = hwmon_device_register_with_info(&hdev->dev, device_name, priv, 959 &kraken3_chip_info, kraken3_groups); 960 if (IS_ERR(priv->hwmon_dev)) { 961 ret = PTR_ERR(priv->hwmon_dev); 962 hid_err(hdev, "hwmon registration failed with %d\n", ret); 963 goto fail_and_close; 964 } 965 966 kraken3_debugfs_init(priv, device_name); 967 968 return 0; 969 970 fail_and_close: 971 hid_hw_close(hdev); 972 fail_and_stop: 973 hid_hw_stop(hdev); 974 return ret; 975 } 976 977 static void kraken3_remove(struct hid_device *hdev) 978 { 979 struct kraken3_data *priv = hid_get_drvdata(hdev); 980 981 debugfs_remove_recursive(priv->debugfs); 982 hwmon_device_unregister(priv->hwmon_dev); 983 984 hid_hw_close(hdev); 985 hid_hw_stop(hdev); 986 } 987 988 static const struct hid_device_id kraken3_table[] = { 989 /* NZXT Kraken X53/X63/X73 have two possible product IDs */ 990 { HID_USB_DEVICE(USB_VENDOR_ID_NZXT, USB_PRODUCT_ID_X53) }, 991 { HID_USB_DEVICE(USB_VENDOR_ID_NZXT, USB_PRODUCT_ID_X53_SECOND) }, 992 { HID_USB_DEVICE(USB_VENDOR_ID_NZXT, USB_PRODUCT_ID_Z53) }, 993 { HID_USB_DEVICE(USB_VENDOR_ID_NZXT, USB_PRODUCT_ID_KRAKEN2023) }, 994 { HID_USB_DEVICE(USB_VENDOR_ID_NZXT, USB_PRODUCT_ID_KRAKEN2023_ELITE) }, 995 { } 996 }; 997 998 MODULE_DEVICE_TABLE(hid, kraken3_table); 999 1000 static struct hid_driver kraken3_driver = { 1001 .name = DRIVER_NAME, 1002 .id_table = kraken3_table, 1003 .probe = kraken3_probe, 1004 .remove = kraken3_remove, 1005 .raw_event = kraken3_raw_event, 1006 #ifdef CONFIG_PM 1007 .reset_resume = kraken3_reset_resume, 1008 #endif 1009 }; 1010 1011 static int __init kraken3_init(void) 1012 { 1013 return hid_register_driver(&kraken3_driver); 1014 } 1015 1016 static void __exit kraken3_exit(void) 1017 { 1018 hid_unregister_driver(&kraken3_driver); 1019 } 1020 1021 /* When compiled into the kernel, initialize after the HID bus */ 1022 late_initcall(kraken3_init); 1023 module_exit(kraken3_exit); 1024 1025 MODULE_LICENSE("GPL"); 1026 MODULE_AUTHOR("Jonas Malaco <jonas@protocubo.io>"); 1027 MODULE_AUTHOR("Aleksa Savic <savicaleksa83@gmail.com>"); 1028 MODULE_DESCRIPTION("Hwmon driver for NZXT Kraken X53/X63/X73, Z53/Z63/Z73 coolers"); 1029