hwmon: (it87) Add DMI table for future extensions
[linux-block.git] / drivers / hwmon / aquacomputer_d5next.c
CommitLineData
0e35f63f
AS
1// SPDX-License-Identifier: GPL-2.0+
2/*
cdbe34da 3 * hwmon driver for Aquacomputer devices (D5 Next, Farbwerk, Farbwerk 360, Octo,
aed80bb9 4 * Quadro, High Flow Next)
0e35f63f 5 *
2fd3eec1
AS
6 * Aquacomputer devices send HID reports (with ID 0x01) every second to report
7 * sensor values.
0e35f63f
AS
8 *
9 * Copyright 2021 Aleksa Savic <savicaleksa83@gmail.com>
229b159c 10 * Copyright 2022 Jack Doan <me@jackdoan.com>
0e35f63f
AS
11 */
12
752b9279 13#include <linux/crc16.h>
0e35f63f
AS
14#include <linux/debugfs.h>
15#include <linux/hid.h>
16#include <linux/hwmon.h>
17#include <linux/jiffies.h>
18#include <linux/module.h>
752b9279 19#include <linux/mutex.h>
0e35f63f 20#include <linux/seq_file.h>
2fd3eec1 21#include <asm/unaligned.h>
0e35f63f 22
2fd3eec1 23#define USB_VENDOR_ID_AQUACOMPUTER 0x0c70
229b159c 24#define USB_PRODUCT_ID_FARBWERK 0xf00a
cdbe34da 25#define USB_PRODUCT_ID_QUADRO 0xf00d
2fd3eec1
AS
26#define USB_PRODUCT_ID_D5NEXT 0xf00e
27#define USB_PRODUCT_ID_FARBWERK360 0xf010
752b9279 28#define USB_PRODUCT_ID_OCTO 0xf011
aed80bb9 29#define USB_PRODUCT_ID_HIGHFLOWNEXT 0xf012
0e35f63f 30
aed80bb9 31enum kinds { d5next, farbwerk, farbwerk360, octo, quadro, highflownext };
0e35f63f 32
2fd3eec1
AS
33static const char *const aqc_device_names[] = {
34 [d5next] = "d5next",
229b159c 35 [farbwerk] = "farbwerk",
752b9279 36 [farbwerk360] = "farbwerk360",
cdbe34da 37 [octo] = "octo",
aed80bb9
AS
38 [quadro] = "quadro",
39 [highflownext] = "highflownext"
2fd3eec1 40};
0e35f63f 41
2fd3eec1
AS
42#define DRIVER_NAME "aquacomputer_d5next"
43
44#define STATUS_REPORT_ID 0x01
45#define STATUS_UPDATE_INTERVAL (2 * HZ) /* In seconds */
46#define SERIAL_FIRST_PART 3
47#define SERIAL_SECOND_PART 5
48#define FIRMWARE_VERSION 13
49
752b9279
AS
50#define CTRL_REPORT_ID 0x03
51
52/* The HID report that the official software always sends
53 * after writing values, currently same for all devices
54 */
55#define SECONDARY_CTRL_REPORT_ID 0x02
56#define SECONDARY_CTRL_REPORT_SIZE 0x0B
57
58static u8 secondary_ctrl_report[] = {
59 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x34, 0xC6
60};
61
654c9735
AS
62/* Register offsets for all Aquacomputer devices */
63#define AQC_TEMP_SENSOR_SIZE 0x02
64#define AQC_TEMP_SENSOR_DISCONNECTED 0x7FFF
65#define AQC_FAN_PERCENT_OFFSET 0x00
66#define AQC_FAN_VOLTAGE_OFFSET 0x02
67#define AQC_FAN_CURRENT_OFFSET 0x04
68#define AQC_FAN_POWER_OFFSET 0x06
69#define AQC_FAN_SPEED_OFFSET 0x08
0e35f63f 70
654c9735
AS
71/* Register offsets for the D5 Next pump */
72#define D5NEXT_POWER_CYCLES 0x18
73#define D5NEXT_COOLANT_TEMP 0x57
74#define D5NEXT_NUM_FANS 2
75#define D5NEXT_NUM_SENSORS 1
e2769f5e
AS
76#define D5NEXT_NUM_VIRTUAL_SENSORS 8
77#define D5NEXT_VIRTUAL_SENSORS_START 0x3f
654c9735
AS
78#define D5NEXT_PUMP_OFFSET 0x6c
79#define D5NEXT_FAN_OFFSET 0x5f
80#define D5NEXT_5V_VOLTAGE 0x39
f4caa262 81#define D5NEXT_12V_VOLTAGE 0x37
09e89309 82#define D5NEXT_CTRL_REPORT_SIZE 0x329
662d20b3 83#define D5NEXT_TEMP_CTRL_OFFSET 0x2D
654c9735 84static u8 d5next_sensor_fan_offsets[] = { D5NEXT_PUMP_OFFSET, D5NEXT_FAN_OFFSET };
0e35f63f 85
09e89309
AS
86/* Pump and fan speed registers in D5 Next control report (from 0-100%) */
87static u16 d5next_ctrl_fan_offsets[] = { 0x97, 0x42 };
88
229b159c
JD
89/* Register offsets for the Farbwerk RGB controller */
90#define FARBWERK_NUM_SENSORS 4
91#define FARBWERK_SENSOR_START 0x2f
229b159c 92
2fd3eec1 93/* Register offsets for the Farbwerk 360 RGB controller */
e2769f5e
AS
94#define FARBWERK360_NUM_SENSORS 4
95#define FARBWERK360_SENSOR_START 0x32
96#define FARBWERK360_NUM_VIRTUAL_SENSORS 16
97#define FARBWERK360_VIRTUAL_SENSORS_START 0x3a
662d20b3
AS
98#define FARBWERK360_CTRL_REPORT_SIZE 0x682
99#define FARBWERK360_TEMP_CTRL_OFFSET 0x8
0e35f63f 100
752b9279
AS
101/* Register offsets for the Octo fan controller */
102#define OCTO_POWER_CYCLES 0x18
103#define OCTO_NUM_FANS 8
752b9279
AS
104#define OCTO_NUM_SENSORS 4
105#define OCTO_SENSOR_START 0x3D
e2769f5e
AS
106#define OCTO_NUM_VIRTUAL_SENSORS 16
107#define OCTO_VIRTUAL_SENSORS_START 0x45
654c9735 108#define OCTO_CTRL_REPORT_SIZE 0x65F
662d20b3 109#define OCTO_TEMP_CTRL_OFFSET 0xA
654c9735 110static u8 octo_sensor_fan_offsets[] = { 0x7D, 0x8A, 0x97, 0xA4, 0xB1, 0xBE, 0xCB, 0xD8 };
752b9279
AS
111
112/* Fan speed registers in Octo control report (from 0-100%) */
113static u16 octo_ctrl_fan_offsets[] = { 0x5B, 0xB0, 0x105, 0x15A, 0x1AF, 0x204, 0x259, 0x2AE };
114
cdbe34da
AS
115/* Register offsets for the Quadro fan controller */
116#define QUADRO_POWER_CYCLES 0x18
117#define QUADRO_NUM_FANS 4
118#define QUADRO_NUM_SENSORS 4
119#define QUADRO_SENSOR_START 0x34
e2769f5e
AS
120#define QUADRO_NUM_VIRTUAL_SENSORS 16
121#define QUADRO_VIRTUAL_SENSORS_START 0x3c
cdbe34da
AS
122#define QUADRO_CTRL_REPORT_SIZE 0x3c1
123#define QUADRO_FLOW_SENSOR_OFFSET 0x6e
662d20b3 124#define QUADRO_TEMP_CTRL_OFFSET 0xA
cdbe34da
AS
125static u8 quadro_sensor_fan_offsets[] = { 0x70, 0x7D, 0x8A, 0x97 };
126
127/* Fan speed registers in Quadro control report (from 0-100%) */
b7f3e965 128static u16 quadro_ctrl_fan_offsets[] = { 0x37, 0x8c, 0xe1, 0x136 };
cdbe34da 129
aed80bb9
AS
130/* Register offsets for the High Flow Next */
131#define HIGHFLOWNEXT_NUM_SENSORS 2
132#define HIGHFLOWNEXT_SENSOR_START 85
133#define HIGHFLOWNEXT_FLOW 81
134#define HIGHFLOWNEXT_WATER_QUALITY 89
135#define HIGHFLOWNEXT_POWER 91
136#define HIGHFLOWNEXT_CONDUCTIVITY 95
137#define HIGHFLOWNEXT_5V_VOLTAGE 97
138#define HIGHFLOWNEXT_5V_VOLTAGE_USB 99
139
2fd3eec1 140/* Labels for D5 Next */
752b9279
AS
141static const char *const label_d5next_temp[] = {
142 "Coolant temp"
143};
0e35f63f 144
2fd3eec1
AS
145static const char *const label_d5next_speeds[] = {
146 "Pump speed",
147 "Fan speed"
148};
0e35f63f 149
2fd3eec1
AS
150static const char *const label_d5next_power[] = {
151 "Pump power",
152 "Fan power"
0e35f63f
AS
153};
154
2fd3eec1
AS
155static const char *const label_d5next_voltages[] = {
156 "Pump voltage",
157 "Fan voltage",
f4caa262
AS
158 "+5V voltage",
159 "+12V voltage"
0e35f63f
AS
160};
161
2fd3eec1
AS
162static const char *const label_d5next_current[] = {
163 "Pump current",
164 "Fan current"
0e35f63f
AS
165};
166
cdbe34da 167/* Labels for Farbwerk, Farbwerk 360 and Octo and Quadro temperature sensors */
2fd3eec1
AS
168static const char *const label_temp_sensors[] = {
169 "Sensor 1",
170 "Sensor 2",
171 "Sensor 3",
172 "Sensor 4"
0e35f63f
AS
173};
174
e2769f5e
AS
175static const char *const label_virtual_temp_sensors[] = {
176 "Virtual sensor 1",
177 "Virtual sensor 2",
178 "Virtual sensor 3",
179 "Virtual sensor 4",
180 "Virtual sensor 5",
181 "Virtual sensor 6",
182 "Virtual sensor 7",
183 "Virtual sensor 8",
184 "Virtual sensor 9",
185 "Virtual sensor 10",
186 "Virtual sensor 11",
187 "Virtual sensor 12",
188 "Virtual sensor 13",
189 "Virtual sensor 14",
190 "Virtual sensor 15",
191 "Virtual sensor 16",
192};
193
cdbe34da 194/* Labels for Octo and Quadro (except speed) */
752b9279
AS
195static const char *const label_fan_speed[] = {
196 "Fan 1 speed",
197 "Fan 2 speed",
198 "Fan 3 speed",
199 "Fan 4 speed",
200 "Fan 5 speed",
201 "Fan 6 speed",
202 "Fan 7 speed",
203 "Fan 8 speed"
204};
205
206static const char *const label_fan_power[] = {
207 "Fan 1 power",
208 "Fan 2 power",
209 "Fan 3 power",
210 "Fan 4 power",
211 "Fan 5 power",
212 "Fan 6 power",
213 "Fan 7 power",
214 "Fan 8 power"
215};
216
217static const char *const label_fan_voltage[] = {
218 "Fan 1 voltage",
219 "Fan 2 voltage",
220 "Fan 3 voltage",
221 "Fan 4 voltage",
222 "Fan 5 voltage",
223 "Fan 6 voltage",
224 "Fan 7 voltage",
225 "Fan 8 voltage"
226};
227
228static const char *const label_fan_current[] = {
229 "Fan 1 current",
230 "Fan 2 current",
231 "Fan 3 current",
232 "Fan 4 current",
233 "Fan 5 current",
234 "Fan 6 current",
235 "Fan 7 current",
236 "Fan 8 current"
237};
238
cdbe34da
AS
239/* Labels for Quadro fan speeds */
240static const char *const label_quadro_speeds[] = {
241 "Fan 1 speed",
242 "Fan 2 speed",
243 "Fan 3 speed",
244 "Fan 4 speed",
245 "Flow speed [dL/h]"
246};
247
aed80bb9
AS
248/* Labels for High Flow Next */
249static const char *const label_highflownext_temp_sensors[] = {
250 "Coolant temp",
251 "External sensor"
252};
253
254static const char *const label_highflownext_fan_speed[] = {
255 "Flow [dL/h]",
256 "Water quality [%]",
257 "Conductivity [nS/cm]",
258};
259
260static const char *const label_highflownext_power[] = {
261 "Dissipated power",
262};
263
264static const char *const label_highflownext_voltage[] = {
265 "+5V voltage",
266 "+5V USB voltage"
267};
268
2fd3eec1 269struct aqc_data {
0e35f63f
AS
270 struct hid_device *hdev;
271 struct device *hwmon_dev;
272 struct dentry *debugfs;
752b9279 273 struct mutex mutex; /* Used for locking access when reading and writing PWM values */
2fd3eec1
AS
274 enum kinds kind;
275 const char *name;
276
752b9279
AS
277 int buffer_size;
278 u8 *buffer;
279 int checksum_start;
280 int checksum_length;
281 int checksum_offset;
282
654c9735
AS
283 int num_fans;
284 u8 *fan_sensor_offsets;
285 u16 *fan_ctrl_offsets;
286 int num_temp_sensors;
287 int temp_sensor_start_offset;
e2769f5e
AS
288 int num_virtual_temp_sensors;
289 int virtual_temp_sensor_start_offset;
662d20b3 290 u16 temp_ctrl_offset;
654c9735 291 u16 power_cycle_count_offset;
cdbe34da 292 u8 flow_sensor_offset;
654c9735 293
2fd3eec1
AS
294 /* General info, same across all devices */
295 u32 serial_number[2];
296 u16 firmware_version;
297
654c9735 298 /* How many times the device was powered on, if available */
2fd3eec1
AS
299 u32 power_cycles;
300
301 /* Sensor values */
e2769f5e 302 s32 temp_input[20]; /* Max 4 physical and 16 virtual */
752b9279
AS
303 u16 speed_input[8];
304 u32 power_input[8];
305 u16 voltage_input[8];
306 u16 current_input[8];
307
308 /* Label values */
309 const char *const *temp_label;
e2769f5e 310 const char *const *virtual_temp_label;
752b9279
AS
311 const char *const *speed_label;
312 const char *const *power_label;
313 const char *const *voltage_label;
314 const char *const *current_label;
2fd3eec1 315
0e35f63f
AS
316 unsigned long updated;
317};
318
752b9279
AS
319/* Converts from centi-percent */
320static int aqc_percent_to_pwm(u16 val)
321{
322 return DIV_ROUND_CLOSEST(val * 255, 100 * 100);
323}
324
325/* Converts to centi-percent */
326static int aqc_pwm_to_percent(long val)
327{
328 if (val < 0 || val > 255)
329 return -EINVAL;
330
331 return DIV_ROUND_CLOSEST(val * 100 * 100, 255);
332}
333
334/* Expects the mutex to be locked */
335static int aqc_get_ctrl_data(struct aqc_data *priv)
336{
337 int ret;
338
339 memset(priv->buffer, 0x00, priv->buffer_size);
340 ret = hid_hw_raw_request(priv->hdev, CTRL_REPORT_ID, priv->buffer, priv->buffer_size,
341 HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
342 if (ret < 0)
343 ret = -ENODATA;
344
345 return ret;
346}
347
348/* Expects the mutex to be locked */
349static int aqc_send_ctrl_data(struct aqc_data *priv)
350{
351 int ret;
352 u16 checksum;
353
354 /* Init and xorout value for CRC-16/USB is 0xffff */
355 checksum = crc16(0xffff, priv->buffer + priv->checksum_start, priv->checksum_length);
356 checksum ^= 0xffff;
357
358 /* Place the new checksum at the end of the report */
359 put_unaligned_be16(checksum, priv->buffer + priv->checksum_offset);
360
361 /* Send the patched up report back to the device */
362 ret = hid_hw_raw_request(priv->hdev, CTRL_REPORT_ID, priv->buffer, priv->buffer_size,
363 HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
364 if (ret < 0)
365 return ret;
366
367 /* The official software sends this report after every change, so do it here as well */
368 ret = hid_hw_raw_request(priv->hdev, SECONDARY_CTRL_REPORT_ID, secondary_ctrl_report,
369 SECONDARY_CTRL_REPORT_SIZE, HID_FEATURE_REPORT,
370 HID_REQ_SET_REPORT);
371 return ret;
372}
373
662d20b3
AS
374/* Refreshes the control buffer and stores value at offset in val */
375static int aqc_get_ctrl_val(struct aqc_data *priv, int offset, long *val)
752b9279
AS
376{
377 int ret;
378
379 mutex_lock(&priv->mutex);
380
381 ret = aqc_get_ctrl_data(priv);
382 if (ret < 0)
383 goto unlock_and_return;
384
662d20b3 385 *val = (s16)get_unaligned_be16(priv->buffer + offset);
752b9279
AS
386
387unlock_and_return:
388 mutex_unlock(&priv->mutex);
389 return ret;
390}
391
392static int aqc_set_ctrl_val(struct aqc_data *priv, int offset, long val)
393{
394 int ret;
395
396 mutex_lock(&priv->mutex);
397
398 ret = aqc_get_ctrl_data(priv);
399 if (ret < 0)
400 goto unlock_and_return;
401
662d20b3 402 put_unaligned_be16((s16)val, priv->buffer + offset);
752b9279
AS
403
404 ret = aqc_send_ctrl_data(priv);
405
406unlock_and_return:
407 mutex_unlock(&priv->mutex);
408 return ret;
409}
410
411static umode_t aqc_is_visible(const void *data, enum hwmon_sensor_types type, u32 attr, int channel)
0e35f63f 412{
2fd3eec1
AS
413 const struct aqc_data *priv = data;
414
415 switch (type) {
416 case hwmon_temp:
662d20b3
AS
417 if (channel < priv->num_temp_sensors) {
418 switch (attr) {
419 case hwmon_temp_label:
420 case hwmon_temp_input:
421 return 0444;
422 case hwmon_temp_offset:
423 if (priv->temp_ctrl_offset != 0)
424 return 0644;
425 break;
426 default:
427 break;
428 }
429 }
430
e2769f5e 431 if (channel < priv->num_temp_sensors + priv->num_virtual_temp_sensors)
662d20b3
AS
432 switch (attr) {
433 case hwmon_temp_label:
434 case hwmon_temp_input:
435 return 0444;
436 default:
437 break;
438 }
2fd3eec1 439 break;
752b9279 440 case hwmon_pwm:
654c9735 441 if (priv->fan_ctrl_offsets && channel < priv->num_fans) {
752b9279
AS
442 switch (attr) {
443 case hwmon_pwm_input:
444 return 0644;
445 default:
446 break;
447 }
752b9279
AS
448 }
449 break;
2fd3eec1 450 case hwmon_fan:
cdbe34da 451 switch (priv->kind) {
aed80bb9
AS
452 case highflownext:
453 /* Special case to support flow sensor, water quality and conductivity */
454 if (channel < 3)
455 return 0444;
456 break;
cdbe34da
AS
457 case quadro:
458 /* Special case to support flow sensor */
459 if (channel < priv->num_fans + 1)
460 return 0444;
461 break;
462 default:
463 if (channel < priv->num_fans)
464 return 0444;
465 break;
466 }
467 break;
2fd3eec1 468 case hwmon_power:
aed80bb9
AS
469 switch (priv->kind) {
470 case highflownext:
471 /* Special case to support one power sensor */
472 if (channel == 0)
473 return 0444;
474 break;
475 default:
476 if (channel < priv->num_fans)
477 return 0444;
478 break;
479 }
480 break;
2fd3eec1 481 case hwmon_curr:
654c9735 482 if (channel < priv->num_fans)
752b9279 483 return 0444;
752b9279
AS
484 break;
485 case hwmon_in:
486 switch (priv->kind) {
487 case d5next:
f4caa262
AS
488 /* Special case to support +5V and +12V voltage sensors */
489 if (channel < priv->num_fans + 2)
752b9279
AS
490 return 0444;
491 break;
aed80bb9
AS
492 case highflownext:
493 /* Special case to support two voltage sensors */
494 if (channel < 2)
495 return 0444;
496 break;
2fd3eec1 497 default:
654c9735
AS
498 if (channel < priv->num_fans)
499 return 0444;
2fd3eec1
AS
500 break;
501 }
502 break;
503 default:
504 break;
505 }
506
507 return 0;
0e35f63f
AS
508}
509
2fd3eec1
AS
510static int aqc_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
511 int channel, long *val)
0e35f63f 512{
752b9279 513 int ret;
2fd3eec1 514 struct aqc_data *priv = dev_get_drvdata(dev);
0e35f63f 515
2fd3eec1 516 if (time_after(jiffies, priv->updated + STATUS_UPDATE_INTERVAL))
0e35f63f
AS
517 return -ENODATA;
518
519 switch (type) {
520 case hwmon_temp:
662d20b3
AS
521 switch (attr) {
522 case hwmon_temp_input:
523 if (priv->temp_input[channel] == -ENODATA)
524 return -ENODATA;
525
526 *val = priv->temp_input[channel];
527 break;
528 case hwmon_temp_offset:
529 ret =
530 aqc_get_ctrl_val(priv, priv->temp_ctrl_offset +
531 channel * AQC_TEMP_SENSOR_SIZE, val);
532 if (ret < 0)
533 return ret;
2fd3eec1 534
662d20b3
AS
535 *val *= 10;
536 break;
537 default:
538 break;
539 }
0e35f63f
AS
540 break;
541 case hwmon_fan:
542 *val = priv->speed_input[channel];
543 break;
544 case hwmon_power:
545 *val = priv->power_input[channel];
546 break;
752b9279 547 case hwmon_pwm:
654c9735 548 if (priv->fan_ctrl_offsets) {
662d20b3 549 ret = aqc_get_ctrl_val(priv, priv->fan_ctrl_offsets[channel], val);
752b9279
AS
550 if (ret < 0)
551 return ret;
552
553 *val = aqc_percent_to_pwm(ret);
752b9279
AS
554 }
555 break;
0e35f63f
AS
556 case hwmon_in:
557 *val = priv->voltage_input[channel];
558 break;
559 case hwmon_curr:
560 *val = priv->current_input[channel];
561 break;
562 default:
563 return -EOPNOTSUPP;
564 }
565
566 return 0;
567}
568
2fd3eec1
AS
569static int aqc_read_string(struct device *dev, enum hwmon_sensor_types type, u32 attr,
570 int channel, const char **str)
0e35f63f 571{
2fd3eec1
AS
572 struct aqc_data *priv = dev_get_drvdata(dev);
573
0e35f63f
AS
574 switch (type) {
575 case hwmon_temp:
e2769f5e
AS
576 if (channel < priv->num_temp_sensors)
577 *str = priv->temp_label[channel];
578 else
579 *str = priv->virtual_temp_label[channel - priv->num_temp_sensors];
0e35f63f
AS
580 break;
581 case hwmon_fan:
752b9279 582 *str = priv->speed_label[channel];
0e35f63f
AS
583 break;
584 case hwmon_power:
752b9279 585 *str = priv->power_label[channel];
0e35f63f
AS
586 break;
587 case hwmon_in:
752b9279 588 *str = priv->voltage_label[channel];
0e35f63f
AS
589 break;
590 case hwmon_curr:
752b9279
AS
591 *str = priv->current_label[channel];
592 break;
593 default:
594 return -EOPNOTSUPP;
595 }
596
597 return 0;
598}
599
600static int aqc_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel,
601 long val)
602{
603 int ret, pwm_value;
604 struct aqc_data *priv = dev_get_drvdata(dev);
605
606 switch (type) {
662d20b3
AS
607 case hwmon_temp:
608 switch (attr) {
609 case hwmon_temp_offset:
610 /* Limit temp offset to +/- 15K as in the official software */
611 val = clamp_val(val, -15000, 15000) / 10;
612 ret =
613 aqc_set_ctrl_val(priv, priv->temp_ctrl_offset +
614 channel * AQC_TEMP_SENSOR_SIZE, val);
615 if (ret < 0)
616 return ret;
617 break;
618 default:
619 return -EOPNOTSUPP;
620 }
621 break;
752b9279
AS
622 case hwmon_pwm:
623 switch (attr) {
624 case hwmon_pwm_input:
654c9735 625 if (priv->fan_ctrl_offsets) {
752b9279
AS
626 pwm_value = aqc_pwm_to_percent(val);
627 if (pwm_value < 0)
628 return pwm_value;
629
654c9735 630 ret = aqc_set_ctrl_val(priv, priv->fan_ctrl_offsets[channel],
752b9279
AS
631 pwm_value);
632 if (ret < 0)
633 return ret;
752b9279 634 }
2fd3eec1
AS
635 break;
636 default:
637 break;
638 }
0e35f63f
AS
639 break;
640 default:
641 return -EOPNOTSUPP;
642 }
643
644 return 0;
645}
646
2fd3eec1
AS
647static const struct hwmon_ops aqc_hwmon_ops = {
648 .is_visible = aqc_is_visible,
649 .read = aqc_read,
650 .read_string = aqc_read_string,
752b9279 651 .write = aqc_write
0e35f63f
AS
652};
653
2fd3eec1
AS
654static const struct hwmon_channel_info *aqc_info[] = {
655 HWMON_CHANNEL_INFO(temp,
662d20b3
AS
656 HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_OFFSET,
657 HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_OFFSET,
658 HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_OFFSET,
659 HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_OFFSET,
e2769f5e
AS
660 HWMON_T_INPUT | HWMON_T_LABEL,
661 HWMON_T_INPUT | HWMON_T_LABEL,
662 HWMON_T_INPUT | HWMON_T_LABEL,
663 HWMON_T_INPUT | HWMON_T_LABEL,
664 HWMON_T_INPUT | HWMON_T_LABEL,
665 HWMON_T_INPUT | HWMON_T_LABEL,
666 HWMON_T_INPUT | HWMON_T_LABEL,
667 HWMON_T_INPUT | HWMON_T_LABEL,
668 HWMON_T_INPUT | HWMON_T_LABEL,
669 HWMON_T_INPUT | HWMON_T_LABEL,
670 HWMON_T_INPUT | HWMON_T_LABEL,
671 HWMON_T_INPUT | HWMON_T_LABEL,
2fd3eec1
AS
672 HWMON_T_INPUT | HWMON_T_LABEL,
673 HWMON_T_INPUT | HWMON_T_LABEL,
674 HWMON_T_INPUT | HWMON_T_LABEL,
675 HWMON_T_INPUT | HWMON_T_LABEL),
676 HWMON_CHANNEL_INFO(fan,
752b9279
AS
677 HWMON_F_INPUT | HWMON_F_LABEL,
678 HWMON_F_INPUT | HWMON_F_LABEL,
679 HWMON_F_INPUT | HWMON_F_LABEL,
680 HWMON_F_INPUT | HWMON_F_LABEL,
681 HWMON_F_INPUT | HWMON_F_LABEL,
682 HWMON_F_INPUT | HWMON_F_LABEL,
2fd3eec1
AS
683 HWMON_F_INPUT | HWMON_F_LABEL,
684 HWMON_F_INPUT | HWMON_F_LABEL),
685 HWMON_CHANNEL_INFO(power,
752b9279
AS
686 HWMON_P_INPUT | HWMON_P_LABEL,
687 HWMON_P_INPUT | HWMON_P_LABEL,
688 HWMON_P_INPUT | HWMON_P_LABEL,
689 HWMON_P_INPUT | HWMON_P_LABEL,
690 HWMON_P_INPUT | HWMON_P_LABEL,
691 HWMON_P_INPUT | HWMON_P_LABEL,
2fd3eec1
AS
692 HWMON_P_INPUT | HWMON_P_LABEL,
693 HWMON_P_INPUT | HWMON_P_LABEL),
752b9279
AS
694 HWMON_CHANNEL_INFO(pwm,
695 HWMON_PWM_INPUT,
696 HWMON_PWM_INPUT,
697 HWMON_PWM_INPUT,
698 HWMON_PWM_INPUT,
699 HWMON_PWM_INPUT,
700 HWMON_PWM_INPUT,
701 HWMON_PWM_INPUT,
702 HWMON_PWM_INPUT),
2fd3eec1 703 HWMON_CHANNEL_INFO(in,
752b9279
AS
704 HWMON_I_INPUT | HWMON_I_LABEL,
705 HWMON_I_INPUT | HWMON_I_LABEL,
706 HWMON_I_INPUT | HWMON_I_LABEL,
707 HWMON_I_INPUT | HWMON_I_LABEL,
708 HWMON_I_INPUT | HWMON_I_LABEL,
2fd3eec1
AS
709 HWMON_I_INPUT | HWMON_I_LABEL,
710 HWMON_I_INPUT | HWMON_I_LABEL,
0e35f63f 711 HWMON_I_INPUT | HWMON_I_LABEL),
2fd3eec1 712 HWMON_CHANNEL_INFO(curr,
752b9279
AS
713 HWMON_C_INPUT | HWMON_C_LABEL,
714 HWMON_C_INPUT | HWMON_C_LABEL,
715 HWMON_C_INPUT | HWMON_C_LABEL,
716 HWMON_C_INPUT | HWMON_C_LABEL,
717 HWMON_C_INPUT | HWMON_C_LABEL,
718 HWMON_C_INPUT | HWMON_C_LABEL,
2fd3eec1
AS
719 HWMON_C_INPUT | HWMON_C_LABEL,
720 HWMON_C_INPUT | HWMON_C_LABEL),
0e35f63f
AS
721 NULL
722};
723
2fd3eec1
AS
724static const struct hwmon_chip_info aqc_chip_info = {
725 .ops = &aqc_hwmon_ops,
726 .info = aqc_info,
0e35f63f
AS
727};
728
229b159c 729static int aqc_raw_event(struct hid_device *hdev, struct hid_report *report, u8 *data, int size)
0e35f63f 730{
e2769f5e 731 int i, j, sensor_value;
2fd3eec1 732 struct aqc_data *priv;
0e35f63f 733
2fd3eec1 734 if (report->id != STATUS_REPORT_ID)
0e35f63f
AS
735 return 0;
736
737 priv = hid_get_drvdata(hdev);
738
739 /* Info provided with every report */
2fd3eec1
AS
740 priv->serial_number[0] = get_unaligned_be16(data + SERIAL_FIRST_PART);
741 priv->serial_number[1] = get_unaligned_be16(data + SERIAL_SECOND_PART);
742 priv->firmware_version = get_unaligned_be16(data + FIRMWARE_VERSION);
0e35f63f 743
e2769f5e 744 /* Physical temperature sensor readings */
654c9735
AS
745 for (i = 0; i < priv->num_temp_sensors; i++) {
746 sensor_value = get_unaligned_be16(data +
747 priv->temp_sensor_start_offset +
748 i * AQC_TEMP_SENSOR_SIZE);
749 if (sensor_value == AQC_TEMP_SENSOR_DISCONNECTED)
750 priv->temp_input[i] = -ENODATA;
751 else
752 priv->temp_input[i] = sensor_value * 10;
753 }
0e35f63f 754
e2769f5e
AS
755 /* Virtual temperature sensor readings */
756 for (j = 0; j < priv->num_virtual_temp_sensors; j++) {
757 sensor_value = get_unaligned_be16(data +
758 priv->virtual_temp_sensor_start_offset +
759 j * AQC_TEMP_SENSOR_SIZE);
760 if (sensor_value == AQC_TEMP_SENSOR_DISCONNECTED)
761 priv->temp_input[i] = -ENODATA;
762 else
763 priv->temp_input[i] = sensor_value * 10;
764 i++;
765 }
766
654c9735
AS
767 /* Fan speed and related readings */
768 for (i = 0; i < priv->num_fans; i++) {
769 priv->speed_input[i] =
770 get_unaligned_be16(data + priv->fan_sensor_offsets[i] + AQC_FAN_SPEED_OFFSET);
771 priv->power_input[i] =
772 get_unaligned_be16(data + priv->fan_sensor_offsets[i] +
773 AQC_FAN_POWER_OFFSET) * 10000;
774 priv->voltage_input[i] =
775 get_unaligned_be16(data + priv->fan_sensor_offsets[i] +
776 AQC_FAN_VOLTAGE_OFFSET) * 10;
777 priv->current_input[i] =
778 get_unaligned_be16(data + priv->fan_sensor_offsets[i] + AQC_FAN_CURRENT_OFFSET);
779 }
0e35f63f 780
654c9735
AS
781 if (priv->power_cycle_count_offset != 0)
782 priv->power_cycles = get_unaligned_be32(data + priv->power_cycle_count_offset);
0e35f63f 783
654c9735
AS
784 /* Special-case sensor readings */
785 switch (priv->kind) {
786 case d5next:
2fd3eec1 787 priv->voltage_input[2] = get_unaligned_be16(data + D5NEXT_5V_VOLTAGE) * 10;
f4caa262 788 priv->voltage_input[3] = get_unaligned_be16(data + D5NEXT_12V_VOLTAGE) * 10;
752b9279 789 break;
cdbe34da
AS
790 case quadro:
791 priv->speed_input[4] = get_unaligned_be16(data + priv->flow_sensor_offset);
792 break;
aed80bb9
AS
793 case highflownext:
794 /* If external temp sensor is not connected, its power reading is also N/A */
795 if (priv->temp_input[1] == -ENODATA)
796 priv->power_input[0] = -ENODATA;
797 else
798 priv->power_input[0] =
799 get_unaligned_be16(data + HIGHFLOWNEXT_POWER) * 1000000;
800
801 priv->voltage_input[0] = get_unaligned_be16(data + HIGHFLOWNEXT_5V_VOLTAGE) * 10;
802 priv->voltage_input[1] =
803 get_unaligned_be16(data + HIGHFLOWNEXT_5V_VOLTAGE_USB) * 10;
804
805 priv->speed_input[0] = get_unaligned_be16(data + HIGHFLOWNEXT_FLOW);
806 priv->speed_input[1] = get_unaligned_be16(data + HIGHFLOWNEXT_WATER_QUALITY);
807 priv->speed_input[2] = get_unaligned_be16(data + HIGHFLOWNEXT_CONDUCTIVITY);
808 break;
2fd3eec1
AS
809 default:
810 break;
811 }
0e35f63f
AS
812
813 priv->updated = jiffies;
814
815 return 0;
816}
817
818#ifdef CONFIG_DEBUG_FS
819
820static int serial_number_show(struct seq_file *seqf, void *unused)
821{
2fd3eec1 822 struct aqc_data *priv = seqf->private;
0e35f63f
AS
823
824 seq_printf(seqf, "%05u-%05u\n", priv->serial_number[0], priv->serial_number[1]);
825
826 return 0;
827}
828DEFINE_SHOW_ATTRIBUTE(serial_number);
829
830static int firmware_version_show(struct seq_file *seqf, void *unused)
831{
2fd3eec1 832 struct aqc_data *priv = seqf->private;
0e35f63f
AS
833
834 seq_printf(seqf, "%u\n", priv->firmware_version);
835
836 return 0;
837}
838DEFINE_SHOW_ATTRIBUTE(firmware_version);
839
840static int power_cycles_show(struct seq_file *seqf, void *unused)
841{
2fd3eec1 842 struct aqc_data *priv = seqf->private;
0e35f63f
AS
843
844 seq_printf(seqf, "%u\n", priv->power_cycles);
845
846 return 0;
847}
848DEFINE_SHOW_ATTRIBUTE(power_cycles);
849
2fd3eec1 850static void aqc_debugfs_init(struct aqc_data *priv)
0e35f63f 851{
2fd3eec1 852 char name[64];
0e35f63f 853
2fd3eec1
AS
854 scnprintf(name, sizeof(name), "%s_%s-%s", "aquacomputer", priv->name,
855 dev_name(&priv->hdev->dev));
0e35f63f
AS
856
857 priv->debugfs = debugfs_create_dir(name, NULL);
858 debugfs_create_file("serial_number", 0444, priv->debugfs, priv, &serial_number_fops);
859 debugfs_create_file("firmware_version", 0444, priv->debugfs, priv, &firmware_version_fops);
2fd3eec1 860
654c9735 861 if (priv->power_cycle_count_offset != 0)
2fd3eec1 862 debugfs_create_file("power_cycles", 0444, priv->debugfs, priv, &power_cycles_fops);
0e35f63f
AS
863}
864
865#else
866
2fd3eec1 867static void aqc_debugfs_init(struct aqc_data *priv)
0e35f63f
AS
868{
869}
870
871#endif
872
2fd3eec1 873static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
0e35f63f 874{
2fd3eec1 875 struct aqc_data *priv;
0e35f63f
AS
876 int ret;
877
878 priv = devm_kzalloc(&hdev->dev, sizeof(*priv), GFP_KERNEL);
879 if (!priv)
880 return -ENOMEM;
881
882 priv->hdev = hdev;
883 hid_set_drvdata(hdev, priv);
884
2fd3eec1 885 priv->updated = jiffies - STATUS_UPDATE_INTERVAL;
0e35f63f
AS
886
887 ret = hid_parse(hdev);
888 if (ret)
889 return ret;
890
891 ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW);
892 if (ret)
893 return ret;
894
895 ret = hid_hw_open(hdev);
896 if (ret)
897 goto fail_and_stop;
898
2fd3eec1
AS
899 switch (hdev->product) {
900 case USB_PRODUCT_ID_D5NEXT:
901 priv->kind = d5next;
752b9279 902
654c9735
AS
903 priv->num_fans = D5NEXT_NUM_FANS;
904 priv->fan_sensor_offsets = d5next_sensor_fan_offsets;
09e89309 905 priv->fan_ctrl_offsets = d5next_ctrl_fan_offsets;
654c9735
AS
906 priv->num_temp_sensors = D5NEXT_NUM_SENSORS;
907 priv->temp_sensor_start_offset = D5NEXT_COOLANT_TEMP;
e2769f5e
AS
908 priv->num_virtual_temp_sensors = D5NEXT_NUM_VIRTUAL_SENSORS;
909 priv->virtual_temp_sensor_start_offset = D5NEXT_VIRTUAL_SENSORS_START;
654c9735 910 priv->power_cycle_count_offset = D5NEXT_POWER_CYCLES;
09e89309 911 priv->buffer_size = D5NEXT_CTRL_REPORT_SIZE;
662d20b3 912 priv->temp_ctrl_offset = D5NEXT_TEMP_CTRL_OFFSET;
654c9735 913
752b9279 914 priv->temp_label = label_d5next_temp;
e2769f5e 915 priv->virtual_temp_label = label_virtual_temp_sensors;
752b9279
AS
916 priv->speed_label = label_d5next_speeds;
917 priv->power_label = label_d5next_power;
918 priv->voltage_label = label_d5next_voltages;
919 priv->current_label = label_d5next_current;
2fd3eec1 920 break;
229b159c
JD
921 case USB_PRODUCT_ID_FARBWERK:
922 priv->kind = farbwerk;
923
654c9735
AS
924 priv->num_fans = 0;
925 priv->num_temp_sensors = FARBWERK_NUM_SENSORS;
926 priv->temp_sensor_start_offset = FARBWERK_SENSOR_START;
229b159c
JD
927 priv->temp_label = label_temp_sensors;
928 break;
2fd3eec1
AS
929 case USB_PRODUCT_ID_FARBWERK360:
930 priv->kind = farbwerk360;
752b9279 931
654c9735
AS
932 priv->num_fans = 0;
933 priv->num_temp_sensors = FARBWERK360_NUM_SENSORS;
934 priv->temp_sensor_start_offset = FARBWERK360_SENSOR_START;
e2769f5e
AS
935 priv->num_virtual_temp_sensors = FARBWERK360_NUM_VIRTUAL_SENSORS;
936 priv->virtual_temp_sensor_start_offset = FARBWERK360_VIRTUAL_SENSORS_START;
662d20b3
AS
937 priv->buffer_size = FARBWERK360_CTRL_REPORT_SIZE;
938 priv->temp_ctrl_offset = FARBWERK360_TEMP_CTRL_OFFSET;
752b9279 939 priv->temp_label = label_temp_sensors;
e2769f5e 940 priv->virtual_temp_label = label_virtual_temp_sensors;
752b9279
AS
941 break;
942 case USB_PRODUCT_ID_OCTO:
943 priv->kind = octo;
654c9735
AS
944
945 priv->num_fans = OCTO_NUM_FANS;
946 priv->fan_sensor_offsets = octo_sensor_fan_offsets;
947 priv->fan_ctrl_offsets = octo_ctrl_fan_offsets;
948 priv->num_temp_sensors = OCTO_NUM_SENSORS;
949 priv->temp_sensor_start_offset = OCTO_SENSOR_START;
e2769f5e
AS
950 priv->num_virtual_temp_sensors = OCTO_NUM_VIRTUAL_SENSORS;
951 priv->virtual_temp_sensor_start_offset = OCTO_VIRTUAL_SENSORS_START;
654c9735 952 priv->power_cycle_count_offset = OCTO_POWER_CYCLES;
752b9279 953 priv->buffer_size = OCTO_CTRL_REPORT_SIZE;
662d20b3 954 priv->temp_ctrl_offset = OCTO_TEMP_CTRL_OFFSET;
752b9279
AS
955
956 priv->temp_label = label_temp_sensors;
e2769f5e 957 priv->virtual_temp_label = label_virtual_temp_sensors;
752b9279
AS
958 priv->speed_label = label_fan_speed;
959 priv->power_label = label_fan_power;
960 priv->voltage_label = label_fan_voltage;
961 priv->current_label = label_fan_current;
2fd3eec1 962 break;
cdbe34da
AS
963 case USB_PRODUCT_ID_QUADRO:
964 priv->kind = quadro;
965
966 priv->num_fans = QUADRO_NUM_FANS;
967 priv->fan_sensor_offsets = quadro_sensor_fan_offsets;
968 priv->fan_ctrl_offsets = quadro_ctrl_fan_offsets;
969 priv->num_temp_sensors = QUADRO_NUM_SENSORS;
970 priv->temp_sensor_start_offset = QUADRO_SENSOR_START;
e2769f5e
AS
971 priv->num_virtual_temp_sensors = QUADRO_NUM_VIRTUAL_SENSORS;
972 priv->virtual_temp_sensor_start_offset = QUADRO_VIRTUAL_SENSORS_START;
cdbe34da
AS
973 priv->power_cycle_count_offset = QUADRO_POWER_CYCLES;
974 priv->buffer_size = QUADRO_CTRL_REPORT_SIZE;
975 priv->flow_sensor_offset = QUADRO_FLOW_SENSOR_OFFSET;
662d20b3 976 priv->temp_ctrl_offset = QUADRO_TEMP_CTRL_OFFSET;
cdbe34da
AS
977
978 priv->temp_label = label_temp_sensors;
e2769f5e 979 priv->virtual_temp_label = label_virtual_temp_sensors;
cdbe34da
AS
980 priv->speed_label = label_quadro_speeds;
981 priv->power_label = label_fan_power;
982 priv->voltage_label = label_fan_voltage;
983 priv->current_label = label_fan_current;
984 break;
aed80bb9
AS
985 case USB_PRODUCT_ID_HIGHFLOWNEXT:
986 priv->kind = highflownext;
987
988 priv->num_fans = 0;
989 priv->num_temp_sensors = HIGHFLOWNEXT_NUM_SENSORS;
990 priv->temp_sensor_start_offset = HIGHFLOWNEXT_SENSOR_START;
991 priv->power_cycle_count_offset = QUADRO_POWER_CYCLES;
992
993 priv->temp_label = label_highflownext_temp_sensors;
994 priv->speed_label = label_highflownext_fan_speed;
995 priv->power_label = label_highflownext_power;
996 priv->voltage_label = label_highflownext_voltage;
997 break;
2fd3eec1
AS
998 default:
999 break;
1000 }
1001
654c9735
AS
1002 if (priv->buffer_size != 0) {
1003 priv->checksum_start = 0x01;
1004 priv->checksum_length = priv->buffer_size - 3;
1005 priv->checksum_offset = priv->buffer_size - 2;
1006 }
1007
2fd3eec1
AS
1008 priv->name = aqc_device_names[priv->kind];
1009
752b9279 1010 priv->buffer = devm_kzalloc(&hdev->dev, priv->buffer_size, GFP_KERNEL);
8877ecb0
CJ
1011 if (!priv->buffer) {
1012 ret = -ENOMEM;
1013 goto fail_and_close;
1014 }
752b9279
AS
1015
1016 mutex_init(&priv->mutex);
1017
2fd3eec1
AS
1018 priv->hwmon_dev = hwmon_device_register_with_info(&hdev->dev, priv->name, priv,
1019 &aqc_chip_info, NULL);
0e35f63f
AS
1020
1021 if (IS_ERR(priv->hwmon_dev)) {
1022 ret = PTR_ERR(priv->hwmon_dev);
1023 goto fail_and_close;
1024 }
1025
2fd3eec1 1026 aqc_debugfs_init(priv);
0e35f63f
AS
1027
1028 return 0;
1029
1030fail_and_close:
1031 hid_hw_close(hdev);
1032fail_and_stop:
1033 hid_hw_stop(hdev);
1034 return ret;
1035}
1036
2fd3eec1 1037static void aqc_remove(struct hid_device *hdev)
0e35f63f 1038{
2fd3eec1 1039 struct aqc_data *priv = hid_get_drvdata(hdev);
0e35f63f
AS
1040
1041 debugfs_remove_recursive(priv->debugfs);
1042 hwmon_device_unregister(priv->hwmon_dev);
1043
1044 hid_hw_close(hdev);
1045 hid_hw_stop(hdev);
1046}
1047
2fd3eec1
AS
1048static const struct hid_device_id aqc_table[] = {
1049 { HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_D5NEXT) },
229b159c 1050 { HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_FARBWERK) },
2fd3eec1 1051 { HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_FARBWERK360) },
752b9279 1052 { HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_OCTO) },
cdbe34da 1053 { HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_QUADRO) },
aed80bb9 1054 { HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_HIGHFLOWNEXT) },
2fd3eec1 1055 { }
0e35f63f
AS
1056};
1057
2fd3eec1 1058MODULE_DEVICE_TABLE(hid, aqc_table);
0e35f63f 1059
2fd3eec1 1060static struct hid_driver aqc_driver = {
0e35f63f 1061 .name = DRIVER_NAME,
2fd3eec1
AS
1062 .id_table = aqc_table,
1063 .probe = aqc_probe,
1064 .remove = aqc_remove,
1065 .raw_event = aqc_raw_event,
0e35f63f
AS
1066};
1067
2fd3eec1 1068static int __init aqc_init(void)
0e35f63f 1069{
2fd3eec1 1070 return hid_register_driver(&aqc_driver);
0e35f63f
AS
1071}
1072
2fd3eec1 1073static void __exit aqc_exit(void)
0e35f63f 1074{
2fd3eec1 1075 hid_unregister_driver(&aqc_driver);
0e35f63f
AS
1076}
1077
1078/* Request to initialize after the HID bus to ensure it's not being loaded before */
2fd3eec1
AS
1079late_initcall(aqc_init);
1080module_exit(aqc_exit);
0e35f63f
AS
1081
1082MODULE_LICENSE("GPL");
1083MODULE_AUTHOR("Aleksa Savic <savicaleksa83@gmail.com>");
229b159c 1084MODULE_AUTHOR("Jack Doan <me@jackdoan.com>");
2fd3eec1 1085MODULE_DESCRIPTION("Hwmon driver for Aquacomputer devices");