Merge tag 'trace-tools-v6.5' of git://git.kernel.org/pub/scm/linux/kernel/git/trace...
[linux-2.6-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,
b3d3be6c 4 * Quadro, High Flow Next, Aquaero, Aquastream Ultimate, Leakshield)
0e35f63f 5 *
2fd3eec1 6 * Aquacomputer devices send HID reports (with ID 0x01) every second to report
e0f6c370
AS
7 * sensor values, except for devices that communicate through the
8 * legacy way (currently, Poweradjust 3).
0e35f63f
AS
9 *
10 * Copyright 2021 Aleksa Savic <savicaleksa83@gmail.com>
229b159c 11 * Copyright 2022 Jack Doan <me@jackdoan.com>
0e35f63f
AS
12 */
13
752b9279 14#include <linux/crc16.h>
0e35f63f
AS
15#include <linux/debugfs.h>
16#include <linux/hid.h>
17#include <linux/hwmon.h>
18#include <linux/jiffies.h>
19#include <linux/module.h>
752b9279 20#include <linux/mutex.h>
0e35f63f 21#include <linux/seq_file.h>
2fd3eec1 22#include <asm/unaligned.h>
0e35f63f 23
2fd3eec1 24#define USB_VENDOR_ID_AQUACOMPUTER 0x0c70
2c552111 25#define USB_PRODUCT_ID_AQUAERO 0xf001
229b159c 26#define USB_PRODUCT_ID_FARBWERK 0xf00a
cdbe34da 27#define USB_PRODUCT_ID_QUADRO 0xf00d
2fd3eec1
AS
28#define USB_PRODUCT_ID_D5NEXT 0xf00e
29#define USB_PRODUCT_ID_FARBWERK360 0xf010
752b9279 30#define USB_PRODUCT_ID_OCTO 0xf011
aed80bb9 31#define USB_PRODUCT_ID_HIGHFLOWNEXT 0xf012
b3d3be6c 32#define USB_PRODUCT_ID_LEAKSHIELD 0xf014
19692f17 33#define USB_PRODUCT_ID_AQUASTREAMXT 0xf0b6
7505dab7 34#define USB_PRODUCT_ID_AQUASTREAMULT 0xf00b
e0f6c370 35#define USB_PRODUCT_ID_POWERADJUST3 0xf0bd
0e35f63f 36
7505dab7
AS
37enum kinds {
38 d5next, farbwerk, farbwerk360, octo, quadro,
19692f17 39 highflownext, aquaero, poweradjust3, aquastreamult,
b3d3be6c 40 aquastreamxt, leakshield
7505dab7 41};
0e35f63f 42
2fd3eec1
AS
43static const char *const aqc_device_names[] = {
44 [d5next] = "d5next",
229b159c 45 [farbwerk] = "farbwerk",
752b9279 46 [farbwerk360] = "farbwerk360",
cdbe34da 47 [octo] = "octo",
aed80bb9 48 [quadro] = "quadro",
2c552111 49 [highflownext] = "highflownext",
b3d3be6c 50 [leakshield] = "leakshield",
19692f17 51 [aquastreamxt] = "aquastreamxt",
e0f6c370 52 [aquaero] = "aquaero",
7505dab7 53 [aquastreamult] = "aquastreamultimate",
e0f6c370 54 [poweradjust3] = "poweradjust3"
2fd3eec1 55};
0e35f63f 56
2fd3eec1
AS
57#define DRIVER_NAME "aquacomputer_d5next"
58
59#define STATUS_REPORT_ID 0x01
60#define STATUS_UPDATE_INTERVAL (2 * HZ) /* In seconds */
ad2f0811 61#define SERIAL_PART_OFFSET 2
2fd3eec1 62
752b9279 63#define CTRL_REPORT_ID 0x03
6c83ccb1 64#define AQUAERO_CTRL_REPORT_ID 0x0b
752b9279
AS
65
66/* The HID report that the official software always sends
67 * after writing values, currently same for all devices
68 */
69#define SECONDARY_CTRL_REPORT_ID 0x02
70#define SECONDARY_CTRL_REPORT_SIZE 0x0B
71
72static u8 secondary_ctrl_report[] = {
73 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x34, 0xC6
74};
75
6c83ccb1
LA
76/* Secondary HID report values for Aquaero */
77#define AQUAERO_SECONDARY_CTRL_REPORT_ID 0x06
78#define AQUAERO_SECONDARY_CTRL_REPORT_SIZE 0x07
79
80static u8 aquaero_secondary_ctrl_report[] = {
81 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00
82};
83
e0f6c370 84/* Report IDs for legacy devices */
19692f17
AS
85#define AQUASTREAMXT_STATUS_REPORT_ID 0x04
86
e0f6c370
AS
87#define POWERADJUST3_STATUS_REPORT_ID 0x03
88
d0450fc1
LA
89/* Data types for reading and writing control reports */
90#define AQC_8 0
91#define AQC_BE16 1
92
2c552111 93/* Info, sensor sizes and offsets for most Aquacomputer devices */
ad2f0811
LA
94#define AQC_SERIAL_START 0x3
95#define AQC_FIRMWARE_VERSION 0xD
96
8bcb02bd 97#define AQC_SENSOR_SIZE 0x02
fdbfd330 98#define AQC_SENSOR_NA 0x7FFF
654c9735
AS
99#define AQC_FAN_PERCENT_OFFSET 0x00
100#define AQC_FAN_VOLTAGE_OFFSET 0x02
101#define AQC_FAN_CURRENT_OFFSET 0x04
102#define AQC_FAN_POWER_OFFSET 0x06
103#define AQC_FAN_SPEED_OFFSET 0x08
0e35f63f 104
2c552111
LA
105/* Specs of the Aquaero fan controllers */
106#define AQUAERO_SERIAL_START 0x07
107#define AQUAERO_FIRMWARE_VERSION 0x0B
108#define AQUAERO_NUM_FANS 4
109#define AQUAERO_NUM_SENSORS 8
110#define AQUAERO_NUM_VIRTUAL_SENSORS 8
3d2e9f58 111#define AQUAERO_NUM_CALC_VIRTUAL_SENSORS 4
2c552111 112#define AQUAERO_NUM_FLOW_SENSORS 2
6c83ccb1 113#define AQUAERO_CTRL_REPORT_SIZE 0xa93
bd1e92f9
LA
114#define AQUAERO_CTRL_PRESET_ID 0x5c
115#define AQUAERO_CTRL_PRESET_SIZE 0x02
116#define AQUAERO_CTRL_PRESET_START 0x55c
2c552111
LA
117
118/* Sensor report offsets for Aquaero fan controllers */
119#define AQUAERO_SENSOR_START 0x65
120#define AQUAERO_VIRTUAL_SENSOR_START 0x85
3d2e9f58 121#define AQUAERO_CALC_VIRTUAL_SENSOR_START 0x95
2c552111
LA
122#define AQUAERO_FLOW_SENSORS_START 0xF9
123#define AQUAERO_FAN_VOLTAGE_OFFSET 0x04
124#define AQUAERO_FAN_CURRENT_OFFSET 0x06
125#define AQUAERO_FAN_POWER_OFFSET 0x08
126#define AQUAERO_FAN_SPEED_OFFSET 0x00
127static u16 aquaero_sensor_fan_offsets[] = { 0x167, 0x173, 0x17f, 0x18B };
128
866e630a
LA
129/* Control report offsets for the Aquaero fan controllers */
130#define AQUAERO_TEMP_CTRL_OFFSET 0xdb
bd1e92f9
LA
131#define AQUAERO_FAN_CTRL_MIN_PWR_OFFSET 0x04
132#define AQUAERO_FAN_CTRL_MAX_PWR_OFFSET 0x06
133#define AQUAERO_FAN_CTRL_SRC_OFFSET 0x10
134static u16 aquaero_ctrl_fan_offsets[] = { 0x20c, 0x220, 0x234, 0x248 };
866e630a 135
d5d896b8 136/* Specs of the D5 Next pump */
654c9735
AS
137#define D5NEXT_NUM_FANS 2
138#define D5NEXT_NUM_SENSORS 1
e2769f5e 139#define D5NEXT_NUM_VIRTUAL_SENSORS 8
d5d896b8
AS
140#define D5NEXT_CTRL_REPORT_SIZE 0x329
141
142/* Sensor report offsets for the D5 Next pump */
143#define D5NEXT_POWER_CYCLES 0x18
144#define D5NEXT_COOLANT_TEMP 0x57
654c9735
AS
145#define D5NEXT_PUMP_OFFSET 0x6c
146#define D5NEXT_FAN_OFFSET 0x5f
147#define D5NEXT_5V_VOLTAGE 0x39
f4caa262 148#define D5NEXT_12V_VOLTAGE 0x37
d5d896b8 149#define D5NEXT_VIRTUAL_SENSORS_START 0x3f
1ed5036b 150static u16 d5next_sensor_fan_offsets[] = { D5NEXT_PUMP_OFFSET, D5NEXT_FAN_OFFSET };
0e35f63f 151
d5d896b8
AS
152/* Control report offsets for the D5 Next pump */
153#define D5NEXT_TEMP_CTRL_OFFSET 0x2D /* Temperature sensor offsets location */
154static u16 d5next_ctrl_fan_offsets[] = { 0x97, 0x42 }; /* Pump and fan speed (from 0-100%) */
09e89309 155
7505dab7
AS
156/* Specs of the Aquastream Ultimate pump */
157/* Pump does not follow the standard structure, so only consider the fan */
158#define AQUASTREAMULT_NUM_FANS 1
159#define AQUASTREAMULT_NUM_SENSORS 2
160
161/* Sensor report offsets for the Aquastream Ultimate pump */
162#define AQUASTREAMULT_SENSOR_START 0x2D
163#define AQUASTREAMULT_PUMP_OFFSET 0x51
164#define AQUASTREAMULT_PUMP_VOLTAGE 0x3D
165#define AQUASTREAMULT_PUMP_CURRENT 0x53
166#define AQUASTREAMULT_PUMP_POWER 0x55
167#define AQUASTREAMULT_FAN_OFFSET 0x41
168#define AQUASTREAMULT_PRESSURE_OFFSET 0x57
169#define AQUASTREAMULT_FLOW_SENSOR_OFFSET 0x37
170#define AQUASTREAMULT_FAN_VOLTAGE_OFFSET 0x02
171#define AQUASTREAMULT_FAN_CURRENT_OFFSET 0x00
172#define AQUASTREAMULT_FAN_POWER_OFFSET 0x04
173#define AQUASTREAMULT_FAN_SPEED_OFFSET 0x06
174static u16 aquastreamult_sensor_fan_offsets[] = { AQUASTREAMULT_FAN_OFFSET };
175
d5d896b8 176/* Spec and sensor report offset for the Farbwerk RGB controller */
229b159c
JD
177#define FARBWERK_NUM_SENSORS 4
178#define FARBWERK_SENSOR_START 0x2f
229b159c 179
d5d896b8 180/* Specs of the Farbwerk 360 RGB controller */
e2769f5e 181#define FARBWERK360_NUM_SENSORS 4
e2769f5e 182#define FARBWERK360_NUM_VIRTUAL_SENSORS 16
662d20b3 183#define FARBWERK360_CTRL_REPORT_SIZE 0x682
d5d896b8
AS
184
185/* Sensor report offsets for the Farbwerk 360 */
186#define FARBWERK360_SENSOR_START 0x32
187#define FARBWERK360_VIRTUAL_SENSORS_START 0x3a
188
189/* Control report offsets for the Farbwerk 360 */
662d20b3 190#define FARBWERK360_TEMP_CTRL_OFFSET 0x8
0e35f63f 191
d5d896b8 192/* Specs of the Octo fan controller */
752b9279 193#define OCTO_NUM_FANS 8
752b9279 194#define OCTO_NUM_SENSORS 4
e2769f5e 195#define OCTO_NUM_VIRTUAL_SENSORS 16
654c9735 196#define OCTO_CTRL_REPORT_SIZE 0x65F
d5d896b8
AS
197
198/* Sensor report offsets for the Octo */
199#define OCTO_POWER_CYCLES 0x18
200#define OCTO_SENSOR_START 0x3D
201#define OCTO_VIRTUAL_SENSORS_START 0x45
1ed5036b 202static u16 octo_sensor_fan_offsets[] = { 0x7D, 0x8A, 0x97, 0xA4, 0xB1, 0xBE, 0xCB, 0xD8 };
752b9279 203
d5d896b8
AS
204/* Control report offsets for the Octo */
205#define OCTO_TEMP_CTRL_OFFSET 0xA
206/* Fan speed offsets (0-100%) */
752b9279
AS
207static u16 octo_ctrl_fan_offsets[] = { 0x5B, 0xB0, 0x105, 0x15A, 0x1AF, 0x204, 0x259, 0x2AE };
208
d5d896b8 209/* Specs of Quadro fan controller */
cdbe34da
AS
210#define QUADRO_NUM_FANS 4
211#define QUADRO_NUM_SENSORS 4
e2769f5e 212#define QUADRO_NUM_VIRTUAL_SENSORS 16
a2ba7ee2 213#define QUADRO_NUM_FLOW_SENSORS 1
cdbe34da 214#define QUADRO_CTRL_REPORT_SIZE 0x3c1
d5d896b8
AS
215
216/* Sensor report offsets for the Quadro */
217#define QUADRO_POWER_CYCLES 0x18
218#define QUADRO_SENSOR_START 0x34
219#define QUADRO_VIRTUAL_SENSORS_START 0x3c
cdbe34da 220#define QUADRO_FLOW_SENSOR_OFFSET 0x6e
1ed5036b 221static u16 quadro_sensor_fan_offsets[] = { 0x70, 0x7D, 0x8A, 0x97 };
cdbe34da 222
d5d896b8
AS
223/* Control report offsets for the Quadro */
224#define QUADRO_TEMP_CTRL_OFFSET 0xA
6ff838f2 225#define QUADRO_FLOW_PULSES_CTRL_OFFSET 0x6
d5d896b8 226static u16 quadro_ctrl_fan_offsets[] = { 0x37, 0x8c, 0xe1, 0x136 }; /* Fan speed offsets (0-100%) */
cdbe34da 227
d5d896b8 228/* Specs of High Flow Next flow sensor */
aed80bb9 229#define HIGHFLOWNEXT_NUM_SENSORS 2
a2ba7ee2 230#define HIGHFLOWNEXT_NUM_FLOW_SENSORS 1
d5d896b8
AS
231
232/* Sensor report offsets for the High Flow Next */
aed80bb9
AS
233#define HIGHFLOWNEXT_SENSOR_START 85
234#define HIGHFLOWNEXT_FLOW 81
235#define HIGHFLOWNEXT_WATER_QUALITY 89
236#define HIGHFLOWNEXT_POWER 91
237#define HIGHFLOWNEXT_CONDUCTIVITY 95
238#define HIGHFLOWNEXT_5V_VOLTAGE 97
239#define HIGHFLOWNEXT_5V_VOLTAGE_USB 99
240
b3d3be6c
AS
241/* Specs of the Leakshield */
242#define LEAKSHIELD_NUM_SENSORS 2
243
244/* Sensor report offsets for Leakshield */
245#define LEAKSHIELD_PRESSURE_ADJUSTED 285
246#define LEAKSHIELD_TEMPERATURE_1 265
247#define LEAKSHIELD_TEMPERATURE_2 287
248#define LEAKSHIELD_PRESSURE_MIN 291
249#define LEAKSHIELD_PRESSURE_TARGET 293
250#define LEAKSHIELD_PRESSURE_MAX 295
251#define LEAKSHIELD_PUMP_RPM_IN 101
252#define LEAKSHIELD_FLOW_IN 111
253#define LEAKSHIELD_RESERVOIR_VOLUME 313
254#define LEAKSHIELD_RESERVOIR_FILLED 311
255
19692f17
AS
256/* Specs of the Aquastream XT pump */
257#define AQUASTREAMXT_SERIAL_START 0x3a
258#define AQUASTREAMXT_FIRMWARE_VERSION 0x32
259#define AQUASTREAMXT_NUM_FANS 2
260#define AQUASTREAMXT_NUM_SENSORS 3
261#define AQUASTREAMXT_FAN_STOPPED 0x4
262#define AQUASTREAMXT_PUMP_CONVERSION_CONST 45000000
263#define AQUASTREAMXT_FAN_CONVERSION_CONST 5646000
264#define AQUASTREAMXT_SENSOR_REPORT_SIZE 0x42
265
266/* Sensor report offsets and info for Aquastream XT */
267#define AQUASTREAMXT_SENSOR_START 0xd
268#define AQUASTREAMXT_FAN_VOLTAGE_OFFSET 0x7
269#define AQUASTREAMXT_FAN_STATUS_OFFSET 0x1d
270#define AQUASTREAMXT_PUMP_VOLTAGE_OFFSET 0x9
271#define AQUASTREAMXT_PUMP_CURR_OFFSET 0xb
272static u16 aquastreamxt_sensor_fan_offsets[] = { 0x13, 0x1b };
273
e0f6c370
AS
274/* Specs of the Poweradjust 3 */
275#define POWERADJUST3_NUM_SENSORS 1
276#define POWERADJUST3_SENSOR_REPORT_SIZE 0x32
277
278/* Sensor report offsets for the Poweradjust 3 */
279#define POWERADJUST3_SENSOR_START 0x03
280
2fd3eec1 281/* Labels for D5 Next */
752b9279
AS
282static const char *const label_d5next_temp[] = {
283 "Coolant temp"
284};
0e35f63f 285
2fd3eec1
AS
286static const char *const label_d5next_speeds[] = {
287 "Pump speed",
288 "Fan speed"
289};
0e35f63f 290
2fd3eec1
AS
291static const char *const label_d5next_power[] = {
292 "Pump power",
293 "Fan power"
0e35f63f
AS
294};
295
2fd3eec1
AS
296static const char *const label_d5next_voltages[] = {
297 "Pump voltage",
298 "Fan voltage",
f4caa262
AS
299 "+5V voltage",
300 "+12V voltage"
0e35f63f
AS
301};
302
2fd3eec1
AS
303static const char *const label_d5next_current[] = {
304 "Pump current",
305 "Fan current"
0e35f63f
AS
306};
307
2c552111 308/* Labels for Aquaero, Farbwerk, Farbwerk 360 and Octo and Quadro temperature sensors */
2fd3eec1
AS
309static const char *const label_temp_sensors[] = {
310 "Sensor 1",
311 "Sensor 2",
312 "Sensor 3",
2c552111
LA
313 "Sensor 4",
314 "Sensor 5",
315 "Sensor 6",
316 "Sensor 7",
317 "Sensor 8"
0e35f63f
AS
318};
319
e2769f5e
AS
320static const char *const label_virtual_temp_sensors[] = {
321 "Virtual sensor 1",
322 "Virtual sensor 2",
323 "Virtual sensor 3",
324 "Virtual sensor 4",
325 "Virtual sensor 5",
326 "Virtual sensor 6",
327 "Virtual sensor 7",
328 "Virtual sensor 8",
329 "Virtual sensor 9",
330 "Virtual sensor 10",
331 "Virtual sensor 11",
332 "Virtual sensor 12",
333 "Virtual sensor 13",
334 "Virtual sensor 14",
335 "Virtual sensor 15",
336 "Virtual sensor 16",
337};
338
3d2e9f58
AS
339static const char *const label_aquaero_calc_temp_sensors[] = {
340 "Calc. virtual sensor 1",
341 "Calc. virtual sensor 2",
342 "Calc. virtual sensor 3",
343 "Calc. virtual sensor 4"
344};
345
cdbe34da 346/* Labels for Octo and Quadro (except speed) */
752b9279
AS
347static const char *const label_fan_speed[] = {
348 "Fan 1 speed",
349 "Fan 2 speed",
350 "Fan 3 speed",
351 "Fan 4 speed",
352 "Fan 5 speed",
353 "Fan 6 speed",
354 "Fan 7 speed",
355 "Fan 8 speed"
356};
357
358static const char *const label_fan_power[] = {
359 "Fan 1 power",
360 "Fan 2 power",
361 "Fan 3 power",
362 "Fan 4 power",
363 "Fan 5 power",
364 "Fan 6 power",
365 "Fan 7 power",
366 "Fan 8 power"
367};
368
369static const char *const label_fan_voltage[] = {
370 "Fan 1 voltage",
371 "Fan 2 voltage",
372 "Fan 3 voltage",
373 "Fan 4 voltage",
374 "Fan 5 voltage",
375 "Fan 6 voltage",
376 "Fan 7 voltage",
377 "Fan 8 voltage"
378};
379
380static const char *const label_fan_current[] = {
381 "Fan 1 current",
382 "Fan 2 current",
383 "Fan 3 current",
384 "Fan 4 current",
385 "Fan 5 current",
386 "Fan 6 current",
387 "Fan 7 current",
388 "Fan 8 current"
389};
390
cdbe34da
AS
391/* Labels for Quadro fan speeds */
392static const char *const label_quadro_speeds[] = {
393 "Fan 1 speed",
394 "Fan 2 speed",
395 "Fan 3 speed",
396 "Fan 4 speed",
397 "Flow speed [dL/h]"
398};
399
2c552111
LA
400/* Labels for Aquaero fan speeds */
401static const char *const label_aquaero_speeds[] = {
402 "Fan 1 speed",
403 "Fan 2 speed",
404 "Fan 3 speed",
405 "Fan 4 speed",
406 "Flow sensor 1 [dL/h]",
407 "Flow sensor 2 [dL/h]"
408};
409
aed80bb9
AS
410/* Labels for High Flow Next */
411static const char *const label_highflownext_temp_sensors[] = {
412 "Coolant temp",
413 "External sensor"
414};
415
416static const char *const label_highflownext_fan_speed[] = {
417 "Flow [dL/h]",
418 "Water quality [%]",
419 "Conductivity [nS/cm]",
420};
421
422static const char *const label_highflownext_power[] = {
423 "Dissipated power",
424};
425
426static const char *const label_highflownext_voltage[] = {
427 "+5V voltage",
428 "+5V USB voltage"
429};
430
b3d3be6c
AS
431/* Labels for Leakshield */
432static const char *const label_leakshield_temp_sensors[] = {
433 "Temperature 1",
434 "Temperature 2"
435};
436
437static const char *const label_leakshield_fan_speed[] = {
438 "Pressure [ubar]",
439 "User-Provided Pump Speed",
440 "User-Provided Flow [dL/h]",
441 "Reservoir Volume [ml]",
442 "Reservoir Filled [ml]",
443};
444
19692f17
AS
445/* Labels for Aquastream XT */
446static const char *const label_aquastreamxt_temp_sensors[] = {
447 "Fan IC temp",
448 "External sensor",
449 "Coolant temp"
450};
451
7505dab7
AS
452/* Labels for Aquastream Ultimate */
453static const char *const label_aquastreamult_temp[] = {
454 "Coolant temp",
455 "External temp"
456};
457
458static const char *const label_aquastreamult_speeds[] = {
459 "Fan speed",
460 "Pump speed",
461 "Pressure [mbar]",
462 "Flow speed [dL/h]"
463};
464
465static const char *const label_aquastreamult_power[] = {
466 "Fan power",
467 "Pump power"
468};
469
470static const char *const label_aquastreamult_voltages[] = {
471 "Fan voltage",
472 "Pump voltage"
473};
474
475static const char *const label_aquastreamult_current[] = {
476 "Fan current",
477 "Pump current"
478};
479
e0f6c370
AS
480/* Labels for Poweradjust 3 */
481static const char *const label_poweradjust3_temp_sensors[] = {
482 "External sensor"
483};
484
249c7521
LA
485struct aqc_fan_structure_offsets {
486 u8 voltage;
487 u8 curr;
488 u8 power;
489 u8 speed;
490};
491
2c552111
LA
492/* Fan structure offsets for Aquaero */
493static struct aqc_fan_structure_offsets aqc_aquaero_fan_structure = {
494 .voltage = AQUAERO_FAN_VOLTAGE_OFFSET,
495 .curr = AQUAERO_FAN_CURRENT_OFFSET,
496 .power = AQUAERO_FAN_POWER_OFFSET,
497 .speed = AQUAERO_FAN_SPEED_OFFSET
498};
499
7505dab7
AS
500/* Fan structure offsets for Aquastream Ultimate */
501static struct aqc_fan_structure_offsets aqc_aquastreamult_fan_structure = {
502 .voltage = AQUASTREAMULT_FAN_VOLTAGE_OFFSET,
503 .curr = AQUASTREAMULT_FAN_CURRENT_OFFSET,
504 .power = AQUASTREAMULT_FAN_POWER_OFFSET,
505 .speed = AQUASTREAMULT_FAN_SPEED_OFFSET
506};
507
508/* Fan structure offsets for all devices except those above */
249c7521
LA
509static struct aqc_fan_structure_offsets aqc_general_fan_structure = {
510 .voltage = AQC_FAN_VOLTAGE_OFFSET,
511 .curr = AQC_FAN_CURRENT_OFFSET,
512 .power = AQC_FAN_POWER_OFFSET,
513 .speed = AQC_FAN_SPEED_OFFSET
514};
515
2fd3eec1 516struct aqc_data {
0e35f63f
AS
517 struct hid_device *hdev;
518 struct device *hwmon_dev;
519 struct dentry *debugfs;
752b9279 520 struct mutex mutex; /* Used for locking access when reading and writing PWM values */
2fd3eec1
AS
521 enum kinds kind;
522 const char *name;
523
e0f6c370 524 int status_report_id; /* Used for legacy devices, report is stored in buffer */
b29090ba
LA
525 int ctrl_report_id;
526 int secondary_ctrl_report_id;
527 int secondary_ctrl_report_size;
528 u8 *secondary_ctrl_report;
e0f6c370 529
752b9279
AS
530 int buffer_size;
531 u8 *buffer;
532 int checksum_start;
533 int checksum_length;
534 int checksum_offset;
535
654c9735 536 int num_fans;
1ed5036b 537 u16 *fan_sensor_offsets;
654c9735
AS
538 u16 *fan_ctrl_offsets;
539 int num_temp_sensors;
540 int temp_sensor_start_offset;
e2769f5e
AS
541 int num_virtual_temp_sensors;
542 int virtual_temp_sensor_start_offset;
3d2e9f58
AS
543 int num_calc_virt_temp_sensors;
544 int calc_virt_temp_sensor_start_offset;
662d20b3 545 u16 temp_ctrl_offset;
654c9735 546 u16 power_cycle_count_offset;
a2ba7ee2
LA
547 int num_flow_sensors;
548 u8 flow_sensors_start_offset;
6ff838f2 549 u8 flow_pulses_ctrl_offset;
249c7521 550 struct aqc_fan_structure_offsets *fan_structure;
654c9735 551
2fd3eec1 552 /* General info, same across all devices */
ad2f0811 553 u8 serial_number_start_offset;
2fd3eec1 554 u32 serial_number[2];
ad2f0811 555 u8 firmware_version_offset;
2fd3eec1
AS
556 u16 firmware_version;
557
654c9735 558 /* How many times the device was powered on, if available */
2fd3eec1
AS
559 u32 power_cycles;
560
561 /* Sensor values */
3d2e9f58 562 s32 temp_input[20]; /* Max 4 physical and 16 virtual or 8 physical and 12 virtual */
b3d3be6c
AS
563 s32 speed_input[8];
564 u32 speed_input_min[1];
565 u32 speed_input_target[1];
566 u32 speed_input_max[1];
752b9279
AS
567 u32 power_input[8];
568 u16 voltage_input[8];
569 u16 current_input[8];
570
571 /* Label values */
572 const char *const *temp_label;
e2769f5e 573 const char *const *virtual_temp_label;
3d2e9f58 574 const char *const *calc_virt_temp_label; /* For Aquaero */
752b9279
AS
575 const char *const *speed_label;
576 const char *const *power_label;
577 const char *const *voltage_label;
578 const char *const *current_label;
2fd3eec1 579
0e35f63f
AS
580 unsigned long updated;
581};
582
752b9279
AS
583/* Converts from centi-percent */
584static int aqc_percent_to_pwm(u16 val)
585{
586 return DIV_ROUND_CLOSEST(val * 255, 100 * 100);
587}
588
589/* Converts to centi-percent */
590static int aqc_pwm_to_percent(long val)
591{
592 if (val < 0 || val > 255)
593 return -EINVAL;
594
595 return DIV_ROUND_CLOSEST(val * 100 * 100, 255);
596}
597
19692f17
AS
598/* Converts raw value for Aquastream XT pump speed to RPM */
599static int aqc_aquastreamxt_convert_pump_rpm(u16 val)
600{
601 if (val > 0)
602 return DIV_ROUND_CLOSEST(AQUASTREAMXT_PUMP_CONVERSION_CONST, val);
603 return 0;
604}
605
606/* Converts raw value for Aquastream XT fan speed to RPM */
607static int aqc_aquastreamxt_convert_fan_rpm(u16 val)
608{
609 if (val > 0)
610 return DIV_ROUND_CLOSEST(AQUASTREAMXT_FAN_CONVERSION_CONST, val);
611 return 0;
612}
613
752b9279
AS
614/* Expects the mutex to be locked */
615static int aqc_get_ctrl_data(struct aqc_data *priv)
616{
617 int ret;
618
619 memset(priv->buffer, 0x00, priv->buffer_size);
b29090ba 620 ret = hid_hw_raw_request(priv->hdev, priv->ctrl_report_id, priv->buffer, priv->buffer_size,
752b9279
AS
621 HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
622 if (ret < 0)
623 ret = -ENODATA;
624
625 return ret;
626}
627
628/* Expects the mutex to be locked */
629static int aqc_send_ctrl_data(struct aqc_data *priv)
630{
631 int ret;
632 u16 checksum;
633
6c83ccb1
LA
634 /* Checksum is not needed for Aquaero */
635 if (priv->kind != aquaero) {
636 /* Init and xorout value for CRC-16/USB is 0xffff */
637 checksum = crc16(0xffff, priv->buffer + priv->checksum_start,
638 priv->checksum_length);
639 checksum ^= 0xffff;
752b9279 640
6c83ccb1
LA
641 /* Place the new checksum at the end of the report */
642 put_unaligned_be16(checksum, priv->buffer + priv->checksum_offset);
643 }
752b9279
AS
644
645 /* Send the patched up report back to the device */
b29090ba 646 ret = hid_hw_raw_request(priv->hdev, priv->ctrl_report_id, priv->buffer, priv->buffer_size,
752b9279
AS
647 HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
648 if (ret < 0)
649 return ret;
650
651 /* The official software sends this report after every change, so do it here as well */
b29090ba
LA
652 ret = hid_hw_raw_request(priv->hdev, priv->secondary_ctrl_report_id,
653 priv->secondary_ctrl_report, priv->secondary_ctrl_report_size,
654 HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
752b9279
AS
655 return ret;
656}
657
662d20b3 658/* Refreshes the control buffer and stores value at offset in val */
d0450fc1 659static int aqc_get_ctrl_val(struct aqc_data *priv, int offset, long *val, int type)
752b9279
AS
660{
661 int ret;
662
663 mutex_lock(&priv->mutex);
664
665 ret = aqc_get_ctrl_data(priv);
666 if (ret < 0)
667 goto unlock_and_return;
668
d0450fc1
LA
669 switch (type) {
670 case AQC_BE16:
671 *val = (s16)get_unaligned_be16(priv->buffer + offset);
672 break;
673 case AQC_8:
674 *val = priv->buffer[offset];
675 break;
676 default:
677 ret = -EINVAL;
678 }
752b9279
AS
679
680unlock_and_return:
681 mutex_unlock(&priv->mutex);
682 return ret;
683}
684
4d09d155 685static int aqc_set_ctrl_vals(struct aqc_data *priv, int *offsets, long *vals, int *types, int len)
752b9279 686{
4d09d155 687 int ret, i;
752b9279
AS
688
689 mutex_lock(&priv->mutex);
690
691 ret = aqc_get_ctrl_data(priv);
692 if (ret < 0)
693 goto unlock_and_return;
694
4d09d155
LA
695 for (i = 0; i < len; i++) {
696 switch (types[i]) {
697 case AQC_BE16:
698 put_unaligned_be16((s16)vals[i], priv->buffer + offsets[i]);
699 break;
700 case AQC_8:
701 priv->buffer[offsets[i]] = (u8)vals[i];
702 break;
703 default:
704 ret = -EINVAL;
705 }
d0450fc1
LA
706 }
707
708 if (ret < 0)
709 goto unlock_and_return;
752b9279
AS
710
711 ret = aqc_send_ctrl_data(priv);
712
713unlock_and_return:
714 mutex_unlock(&priv->mutex);
715 return ret;
716}
717
4d09d155
LA
718static int aqc_set_ctrl_val(struct aqc_data *priv, int offset, long val, int type)
719{
720 return aqc_set_ctrl_vals(priv, &offset, &val, &type, 1);
721}
722
752b9279 723static umode_t aqc_is_visible(const void *data, enum hwmon_sensor_types type, u32 attr, int channel)
0e35f63f 724{
2fd3eec1
AS
725 const struct aqc_data *priv = data;
726
727 switch (type) {
728 case hwmon_temp:
662d20b3
AS
729 if (channel < priv->num_temp_sensors) {
730 switch (attr) {
731 case hwmon_temp_label:
732 case hwmon_temp_input:
733 return 0444;
734 case hwmon_temp_offset:
735 if (priv->temp_ctrl_offset != 0)
736 return 0644;
737 break;
738 default:
739 break;
740 }
741 }
742
3d2e9f58
AS
743 if (channel <
744 priv->num_temp_sensors + priv->num_virtual_temp_sensors +
745 priv->num_calc_virt_temp_sensors)
662d20b3
AS
746 switch (attr) {
747 case hwmon_temp_label:
748 case hwmon_temp_input:
749 return 0444;
750 default:
751 break;
752 }
2fd3eec1 753 break;
752b9279 754 case hwmon_pwm:
654c9735 755 if (priv->fan_ctrl_offsets && channel < priv->num_fans) {
752b9279
AS
756 switch (attr) {
757 case hwmon_pwm_input:
758 return 0644;
759 default:
760 break;
761 }
752b9279
AS
762 }
763 break;
2fd3eec1 764 case hwmon_fan:
6ff838f2
AS
765 switch (attr) {
766 case hwmon_fan_input:
767 case hwmon_fan_label:
768 switch (priv->kind) {
7505dab7
AS
769 case aquastreamult:
770 /*
771 * Special case to support pump RPM, fan RPM,
772 * pressure and flow sensor
773 */
774 if (channel < 4)
775 return 0444;
776 break;
6ff838f2
AS
777 case highflownext:
778 /* Special case to support flow sensor, water quality
779 * and conductivity
780 */
781 if (channel < 3)
782 return 0444;
783 break;
b3d3be6c
AS
784 case leakshield:
785 /* Special case for Leakshield sensors */
786 if (channel < 5)
787 return 0444;
788 break;
2c552111 789 case aquaero:
6ff838f2 790 case quadro:
a2ba7ee2
LA
791 /* Special case to support flow sensors */
792 if (channel < priv->num_fans + priv->num_flow_sensors)
6ff838f2
AS
793 return 0444;
794 break;
795 default:
796 if (channel < priv->num_fans)
797 return 0444;
798 break;
799 }
aed80bb9 800 break;
6ff838f2
AS
801 case hwmon_fan_pulses:
802 /* Special case for Quadro flow sensor */
803 if (priv->kind == quadro && channel == priv->num_fans)
804 return 0644;
cdbe34da 805 break;
b3d3be6c
AS
806 case hwmon_fan_min:
807 case hwmon_fan_max:
808 case hwmon_fan_target:
809 /* Special case for Leakshield pressure sensor */
810 if (priv->kind == leakshield && channel == 0)
811 return 0444;
812 break;
cdbe34da 813 default:
cdbe34da
AS
814 break;
815 }
816 break;
2fd3eec1 817 case hwmon_power:
aed80bb9 818 switch (priv->kind) {
7505dab7
AS
819 case aquastreamult:
820 /* Special case to support pump and fan power */
821 if (channel < 2)
822 return 0444;
823 break;
aed80bb9
AS
824 case highflownext:
825 /* Special case to support one power sensor */
826 if (channel == 0)
827 return 0444;
828 break;
19692f17
AS
829 case aquastreamxt:
830 break;
aed80bb9
AS
831 default:
832 if (channel < priv->num_fans)
833 return 0444;
834 break;
835 }
836 break;
2fd3eec1 837 case hwmon_curr:
7505dab7
AS
838 switch (priv->kind) {
839 case aquastreamult:
840 /* Special case to support pump and fan current */
841 if (channel < 2)
842 return 0444;
843 break;
19692f17
AS
844 case aquastreamxt:
845 /* Special case to support pump current */
846 if (channel == 0)
847 return 0444;
848 break;
7505dab7
AS
849 default:
850 if (channel < priv->num_fans)
851 return 0444;
852 break;
853 }
752b9279
AS
854 break;
855 case hwmon_in:
856 switch (priv->kind) {
857 case d5next:
f4caa262
AS
858 /* Special case to support +5V and +12V voltage sensors */
859 if (channel < priv->num_fans + 2)
752b9279
AS
860 return 0444;
861 break;
7505dab7 862 case aquastreamult:
aed80bb9
AS
863 case highflownext:
864 /* Special case to support two voltage sensors */
865 if (channel < 2)
866 return 0444;
867 break;
2fd3eec1 868 default:
654c9735
AS
869 if (channel < priv->num_fans)
870 return 0444;
2fd3eec1
AS
871 break;
872 }
873 break;
874 default:
875 break;
876 }
877
878 return 0;
0e35f63f
AS
879}
880
e0f6c370
AS
881/* Read device sensors by manually requesting the sensor report (legacy way) */
882static int aqc_legacy_read(struct aqc_data *priv)
883{
884 int ret, i, sensor_value;
885
886 mutex_lock(&priv->mutex);
887
888 memset(priv->buffer, 0x00, priv->buffer_size);
889 ret = hid_hw_raw_request(priv->hdev, priv->status_report_id, priv->buffer,
890 priv->buffer_size, HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
891 if (ret < 0)
892 goto unlock_and_return;
893
894 /* Temperature sensor readings */
895 for (i = 0; i < priv->num_temp_sensors; i++) {
896 sensor_value = get_unaligned_le16(priv->buffer + priv->temp_sensor_start_offset +
897 i * AQC_SENSOR_SIZE);
898 priv->temp_input[i] = sensor_value * 10;
899 }
900
19692f17
AS
901 /* Special-case sensor readings */
902 switch (priv->kind) {
903 case aquastreamxt:
904 /* Info provided with every report */
905 priv->serial_number[0] = get_unaligned_le16(priv->buffer +
906 priv->serial_number_start_offset);
907 priv->firmware_version =
908 get_unaligned_le16(priv->buffer + priv->firmware_version_offset);
909
910 /* Read pump speed in RPM */
911 sensor_value = get_unaligned_le16(priv->buffer + priv->fan_sensor_offsets[0]);
912 priv->speed_input[0] = aqc_aquastreamxt_convert_pump_rpm(sensor_value);
913
914 /* Read fan speed in RPM, if available */
915 sensor_value = get_unaligned_le16(priv->buffer + AQUASTREAMXT_FAN_STATUS_OFFSET);
916 if (sensor_value == AQUASTREAMXT_FAN_STOPPED) {
917 priv->speed_input[1] = 0;
918 } else {
919 sensor_value =
920 get_unaligned_le16(priv->buffer + priv->fan_sensor_offsets[1]);
921 priv->speed_input[1] = aqc_aquastreamxt_convert_fan_rpm(sensor_value);
922 }
923
924 /* Calculation derived from linear regression */
925 sensor_value = get_unaligned_le16(priv->buffer + AQUASTREAMXT_PUMP_CURR_OFFSET);
926 priv->current_input[0] = DIV_ROUND_CLOSEST(sensor_value * 176, 100) - 52;
927
928 sensor_value = get_unaligned_le16(priv->buffer + AQUASTREAMXT_PUMP_VOLTAGE_OFFSET);
929 priv->voltage_input[0] = DIV_ROUND_CLOSEST(sensor_value * 1000, 61);
930
931 sensor_value = get_unaligned_le16(priv->buffer + AQUASTREAMXT_FAN_VOLTAGE_OFFSET);
932 priv->voltage_input[1] = DIV_ROUND_CLOSEST(sensor_value * 1000, 63);
933 break;
934 default:
935 break;
936 }
937
e0f6c370
AS
938 priv->updated = jiffies;
939
940unlock_and_return:
941 mutex_unlock(&priv->mutex);
942 return ret;
943}
944
2fd3eec1
AS
945static int aqc_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
946 int channel, long *val)
0e35f63f 947{
752b9279 948 int ret;
2fd3eec1 949 struct aqc_data *priv = dev_get_drvdata(dev);
0e35f63f 950
e0f6c370
AS
951 if (time_after(jiffies, priv->updated + STATUS_UPDATE_INTERVAL)) {
952 if (priv->status_report_id != 0) {
953 /* Legacy devices require manual reads */
954 ret = aqc_legacy_read(priv);
955 if (ret < 0)
956 return -ENODATA;
957 } else {
958 return -ENODATA;
959 }
960 }
0e35f63f
AS
961
962 switch (type) {
963 case hwmon_temp:
662d20b3
AS
964 switch (attr) {
965 case hwmon_temp_input:
966 if (priv->temp_input[channel] == -ENODATA)
967 return -ENODATA;
968
969 *val = priv->temp_input[channel];
970 break;
971 case hwmon_temp_offset:
972 ret =
973 aqc_get_ctrl_val(priv, priv->temp_ctrl_offset +
d0450fc1 974 channel * AQC_SENSOR_SIZE, val, AQC_BE16);
662d20b3
AS
975 if (ret < 0)
976 return ret;
2fd3eec1 977
662d20b3
AS
978 *val *= 10;
979 break;
980 default:
981 break;
982 }
0e35f63f
AS
983 break;
984 case hwmon_fan:
6ff838f2
AS
985 switch (attr) {
986 case hwmon_fan_input:
b3d3be6c
AS
987 if (priv->speed_input[channel] == -ENODATA)
988 return -ENODATA;
989
6ff838f2
AS
990 *val = priv->speed_input[channel];
991 break;
b3d3be6c
AS
992 case hwmon_fan_min:
993 *val = priv->speed_input_min[channel];
994 break;
995 case hwmon_fan_max:
996 *val = priv->speed_input_max[channel];
997 break;
998 case hwmon_fan_target:
999 *val = priv->speed_input_target[channel];
1000 break;
6ff838f2 1001 case hwmon_fan_pulses:
d0450fc1
LA
1002 ret = aqc_get_ctrl_val(priv, priv->flow_pulses_ctrl_offset,
1003 val, AQC_BE16);
6ff838f2
AS
1004 if (ret < 0)
1005 return ret;
1006 break;
1007 default:
1008 break;
1009 }
0e35f63f
AS
1010 break;
1011 case hwmon_power:
1012 *val = priv->power_input[channel];
1013 break;
752b9279 1014 case hwmon_pwm:
bd1e92f9
LA
1015 switch (priv->kind) {
1016 case aquaero:
1017 ret = aqc_get_ctrl_val(priv,
1018 AQUAERO_CTRL_PRESET_START + channel * AQUAERO_CTRL_PRESET_SIZE,
1019 val, AQC_BE16);
1020 if (ret < 0)
1021 return ret;
1022 *val = aqc_percent_to_pwm(*val);
1023 break;
1024 default:
d0450fc1
LA
1025 ret = aqc_get_ctrl_val(priv, priv->fan_ctrl_offsets[channel],
1026 val, AQC_BE16);
752b9279
AS
1027 if (ret < 0)
1028 return ret;
1029
1030 *val = aqc_percent_to_pwm(ret);
bd1e92f9 1031 break;
752b9279
AS
1032 }
1033 break;
0e35f63f
AS
1034 case hwmon_in:
1035 *val = priv->voltage_input[channel];
1036 break;
1037 case hwmon_curr:
1038 *val = priv->current_input[channel];
1039 break;
1040 default:
1041 return -EOPNOTSUPP;
1042 }
1043
1044 return 0;
1045}
1046
2fd3eec1
AS
1047static int aqc_read_string(struct device *dev, enum hwmon_sensor_types type, u32 attr,
1048 int channel, const char **str)
0e35f63f 1049{
2fd3eec1
AS
1050 struct aqc_data *priv = dev_get_drvdata(dev);
1051
3d2e9f58
AS
1052 /* Number of sensors that are not calculated */
1053 int num_non_calc_sensors = priv->num_temp_sensors + priv->num_virtual_temp_sensors;
1054
0e35f63f
AS
1055 switch (type) {
1056 case hwmon_temp:
3d2e9f58 1057 if (channel < priv->num_temp_sensors) {
e2769f5e 1058 *str = priv->temp_label[channel];
3d2e9f58
AS
1059 } else {
1060 if (priv->kind == aquaero && channel >= num_non_calc_sensors)
1061 *str =
1062 priv->calc_virt_temp_label[channel - num_non_calc_sensors];
1063 else
1064 *str = priv->virtual_temp_label[channel - priv->num_temp_sensors];
1065 }
0e35f63f
AS
1066 break;
1067 case hwmon_fan:
752b9279 1068 *str = priv->speed_label[channel];
0e35f63f
AS
1069 break;
1070 case hwmon_power:
752b9279 1071 *str = priv->power_label[channel];
0e35f63f
AS
1072 break;
1073 case hwmon_in:
752b9279 1074 *str = priv->voltage_label[channel];
0e35f63f
AS
1075 break;
1076 case hwmon_curr:
752b9279
AS
1077 *str = priv->current_label[channel];
1078 break;
1079 default:
1080 return -EOPNOTSUPP;
1081 }
1082
1083 return 0;
1084}
1085
1086static int aqc_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel,
1087 long val)
1088{
1089 int ret, pwm_value;
bd1e92f9
LA
1090 /* Arrays for setting multiple values at once in the control report */
1091 int ctrl_values_offsets[4];
1092 long ctrl_values[4];
1093 int ctrl_values_types[4];
752b9279
AS
1094 struct aqc_data *priv = dev_get_drvdata(dev);
1095
1096 switch (type) {
662d20b3
AS
1097 case hwmon_temp:
1098 switch (attr) {
1099 case hwmon_temp_offset:
1100 /* Limit temp offset to +/- 15K as in the official software */
1101 val = clamp_val(val, -15000, 15000) / 10;
1102 ret =
1103 aqc_set_ctrl_val(priv, priv->temp_ctrl_offset +
d0450fc1 1104 channel * AQC_SENSOR_SIZE, val, AQC_BE16);
662d20b3
AS
1105 if (ret < 0)
1106 return ret;
1107 break;
1108 default:
1109 return -EOPNOTSUPP;
1110 }
1111 break;
6ff838f2
AS
1112 case hwmon_fan:
1113 switch (attr) {
1114 case hwmon_fan_pulses:
1115 val = clamp_val(val, 10, 1000);
d0450fc1
LA
1116 ret = aqc_set_ctrl_val(priv, priv->flow_pulses_ctrl_offset,
1117 val, AQC_BE16);
6ff838f2
AS
1118 if (ret < 0)
1119 return ret;
1120 break;
1121 default:
1122 break;
1123 }
1124 break;
752b9279
AS
1125 case hwmon_pwm:
1126 switch (attr) {
1127 case hwmon_pwm_input:
bd1e92f9
LA
1128 pwm_value = aqc_pwm_to_percent(val);
1129 if (pwm_value < 0)
1130 return pwm_value;
752b9279 1131
bd1e92f9
LA
1132 switch (priv->kind) {
1133 case aquaero:
1134 /* Write pwm value to preset corresponding to the channel */
1135 ctrl_values_offsets[0] = AQUAERO_CTRL_PRESET_START +
1136 channel * AQUAERO_CTRL_PRESET_SIZE;
1137 ctrl_values[0] = pwm_value;
1138 ctrl_values_types[0] = AQC_BE16;
1139
1140 /* Write preset number in fan control source */
1141 ctrl_values_offsets[1] = priv->fan_ctrl_offsets[channel] +
1142 AQUAERO_FAN_CTRL_SRC_OFFSET;
1143 ctrl_values[1] = AQUAERO_CTRL_PRESET_ID + channel;
1144 ctrl_values_types[1] = AQC_BE16;
1145
1146 /* Set minimum power to 0 to allow the fan to turn off */
1147 ctrl_values_offsets[2] = priv->fan_ctrl_offsets[channel] +
1148 AQUAERO_FAN_CTRL_MIN_PWR_OFFSET;
1149 ctrl_values[2] = 0;
1150 ctrl_values_types[2] = AQC_BE16;
1151
1152 /* Set maximum power to 255 to allow the fan to reach max speed */
1153 ctrl_values_offsets[3] = priv->fan_ctrl_offsets[channel] +
1154 AQUAERO_FAN_CTRL_MAX_PWR_OFFSET;
1155 ctrl_values[3] = aqc_pwm_to_percent(255);
1156 ctrl_values_types[3] = AQC_BE16;
1157
1158 ret = aqc_set_ctrl_vals(priv, ctrl_values_offsets, ctrl_values,
1159 ctrl_values_types, 4);
1160 if (ret < 0)
1161 return ret;
1162 break;
1163 default:
654c9735 1164 ret = aqc_set_ctrl_val(priv, priv->fan_ctrl_offsets[channel],
d0450fc1 1165 pwm_value, AQC_BE16);
752b9279
AS
1166 if (ret < 0)
1167 return ret;
bd1e92f9 1168 break;
752b9279 1169 }
2fd3eec1
AS
1170 break;
1171 default:
1172 break;
1173 }
0e35f63f
AS
1174 break;
1175 default:
1176 return -EOPNOTSUPP;
1177 }
1178
1179 return 0;
1180}
1181
2fd3eec1
AS
1182static const struct hwmon_ops aqc_hwmon_ops = {
1183 .is_visible = aqc_is_visible,
1184 .read = aqc_read,
1185 .read_string = aqc_read_string,
752b9279 1186 .write = aqc_write
0e35f63f
AS
1187};
1188
832dc510 1189static const struct hwmon_channel_info * const aqc_info[] = {
2fd3eec1 1190 HWMON_CHANNEL_INFO(temp,
662d20b3
AS
1191 HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_OFFSET,
1192 HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_OFFSET,
1193 HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_OFFSET,
1194 HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_OFFSET,
866e630a
LA
1195 HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_OFFSET,
1196 HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_OFFSET,
1197 HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_OFFSET,
1198 HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_OFFSET,
e2769f5e
AS
1199 HWMON_T_INPUT | HWMON_T_LABEL,
1200 HWMON_T_INPUT | HWMON_T_LABEL,
1201 HWMON_T_INPUT | HWMON_T_LABEL,
1202 HWMON_T_INPUT | HWMON_T_LABEL,
1203 HWMON_T_INPUT | HWMON_T_LABEL,
1204 HWMON_T_INPUT | HWMON_T_LABEL,
1205 HWMON_T_INPUT | HWMON_T_LABEL,
1206 HWMON_T_INPUT | HWMON_T_LABEL,
2fd3eec1
AS
1207 HWMON_T_INPUT | HWMON_T_LABEL,
1208 HWMON_T_INPUT | HWMON_T_LABEL,
1209 HWMON_T_INPUT | HWMON_T_LABEL,
1210 HWMON_T_INPUT | HWMON_T_LABEL),
1211 HWMON_CHANNEL_INFO(fan,
b3d3be6c
AS
1212 HWMON_F_INPUT | HWMON_F_LABEL | HWMON_F_MIN | HWMON_F_MAX |
1213 HWMON_F_TARGET,
752b9279
AS
1214 HWMON_F_INPUT | HWMON_F_LABEL,
1215 HWMON_F_INPUT | HWMON_F_LABEL,
1216 HWMON_F_INPUT | HWMON_F_LABEL,
6ff838f2 1217 HWMON_F_INPUT | HWMON_F_LABEL | HWMON_F_PULSES,
752b9279 1218 HWMON_F_INPUT | HWMON_F_LABEL,
2fd3eec1
AS
1219 HWMON_F_INPUT | HWMON_F_LABEL,
1220 HWMON_F_INPUT | HWMON_F_LABEL),
1221 HWMON_CHANNEL_INFO(power,
752b9279
AS
1222 HWMON_P_INPUT | HWMON_P_LABEL,
1223 HWMON_P_INPUT | HWMON_P_LABEL,
1224 HWMON_P_INPUT | HWMON_P_LABEL,
1225 HWMON_P_INPUT | HWMON_P_LABEL,
1226 HWMON_P_INPUT | HWMON_P_LABEL,
1227 HWMON_P_INPUT | HWMON_P_LABEL,
2fd3eec1
AS
1228 HWMON_P_INPUT | HWMON_P_LABEL,
1229 HWMON_P_INPUT | HWMON_P_LABEL),
752b9279
AS
1230 HWMON_CHANNEL_INFO(pwm,
1231 HWMON_PWM_INPUT,
1232 HWMON_PWM_INPUT,
1233 HWMON_PWM_INPUT,
1234 HWMON_PWM_INPUT,
1235 HWMON_PWM_INPUT,
1236 HWMON_PWM_INPUT,
1237 HWMON_PWM_INPUT,
1238 HWMON_PWM_INPUT),
2fd3eec1 1239 HWMON_CHANNEL_INFO(in,
752b9279
AS
1240 HWMON_I_INPUT | HWMON_I_LABEL,
1241 HWMON_I_INPUT | HWMON_I_LABEL,
1242 HWMON_I_INPUT | HWMON_I_LABEL,
1243 HWMON_I_INPUT | HWMON_I_LABEL,
1244 HWMON_I_INPUT | HWMON_I_LABEL,
2fd3eec1
AS
1245 HWMON_I_INPUT | HWMON_I_LABEL,
1246 HWMON_I_INPUT | HWMON_I_LABEL,
0e35f63f 1247 HWMON_I_INPUT | HWMON_I_LABEL),
2fd3eec1 1248 HWMON_CHANNEL_INFO(curr,
752b9279
AS
1249 HWMON_C_INPUT | HWMON_C_LABEL,
1250 HWMON_C_INPUT | HWMON_C_LABEL,
1251 HWMON_C_INPUT | HWMON_C_LABEL,
1252 HWMON_C_INPUT | HWMON_C_LABEL,
1253 HWMON_C_INPUT | HWMON_C_LABEL,
1254 HWMON_C_INPUT | HWMON_C_LABEL,
2fd3eec1
AS
1255 HWMON_C_INPUT | HWMON_C_LABEL,
1256 HWMON_C_INPUT | HWMON_C_LABEL),
0e35f63f
AS
1257 NULL
1258};
1259
2fd3eec1
AS
1260static const struct hwmon_chip_info aqc_chip_info = {
1261 .ops = &aqc_hwmon_ops,
1262 .info = aqc_info,
0e35f63f
AS
1263};
1264
229b159c 1265static int aqc_raw_event(struct hid_device *hdev, struct hid_report *report, u8 *data, int size)
0e35f63f 1266{
e2769f5e 1267 int i, j, sensor_value;
2fd3eec1 1268 struct aqc_data *priv;
0e35f63f 1269
2fd3eec1 1270 if (report->id != STATUS_REPORT_ID)
0e35f63f
AS
1271 return 0;
1272
1273 priv = hid_get_drvdata(hdev);
1274
1275 /* Info provided with every report */
ad2f0811
LA
1276 priv->serial_number[0] = get_unaligned_be16(data + priv->serial_number_start_offset);
1277 priv->serial_number[1] = get_unaligned_be16(data + priv->serial_number_start_offset +
1278 SERIAL_PART_OFFSET);
1279 priv->firmware_version = get_unaligned_be16(data + priv->firmware_version_offset);
0e35f63f 1280
e2769f5e 1281 /* Physical temperature sensor readings */
654c9735
AS
1282 for (i = 0; i < priv->num_temp_sensors; i++) {
1283 sensor_value = get_unaligned_be16(data +
1284 priv->temp_sensor_start_offset +
8bcb02bd 1285 i * AQC_SENSOR_SIZE);
fdbfd330 1286 if (sensor_value == AQC_SENSOR_NA)
654c9735
AS
1287 priv->temp_input[i] = -ENODATA;
1288 else
1289 priv->temp_input[i] = sensor_value * 10;
1290 }
0e35f63f 1291
e2769f5e
AS
1292 /* Virtual temperature sensor readings */
1293 for (j = 0; j < priv->num_virtual_temp_sensors; j++) {
1294 sensor_value = get_unaligned_be16(data +
1295 priv->virtual_temp_sensor_start_offset +
8bcb02bd 1296 j * AQC_SENSOR_SIZE);
fdbfd330 1297 if (sensor_value == AQC_SENSOR_NA)
e2769f5e
AS
1298 priv->temp_input[i] = -ENODATA;
1299 else
1300 priv->temp_input[i] = sensor_value * 10;
1301 i++;
1302 }
1303
654c9735
AS
1304 /* Fan speed and related readings */
1305 for (i = 0; i < priv->num_fans; i++) {
1306 priv->speed_input[i] =
249c7521
LA
1307 get_unaligned_be16(data + priv->fan_sensor_offsets[i] +
1308 priv->fan_structure->speed);
654c9735
AS
1309 priv->power_input[i] =
1310 get_unaligned_be16(data + priv->fan_sensor_offsets[i] +
249c7521 1311 priv->fan_structure->power) * 10000;
654c9735
AS
1312 priv->voltage_input[i] =
1313 get_unaligned_be16(data + priv->fan_sensor_offsets[i] +
249c7521 1314 priv->fan_structure->voltage) * 10;
654c9735 1315 priv->current_input[i] =
249c7521
LA
1316 get_unaligned_be16(data + priv->fan_sensor_offsets[i] +
1317 priv->fan_structure->curr);
654c9735 1318 }
0e35f63f 1319
a2ba7ee2
LA
1320 /* Flow sensor readings */
1321 for (j = 0; j < priv->num_flow_sensors; j++) {
1322 priv->speed_input[i] = get_unaligned_be16(data + priv->flow_sensors_start_offset +
1323 j * AQC_SENSOR_SIZE);
1324 i++;
1325 }
1326
654c9735
AS
1327 if (priv->power_cycle_count_offset != 0)
1328 priv->power_cycles = get_unaligned_be32(data + priv->power_cycle_count_offset);
0e35f63f 1329
654c9735
AS
1330 /* Special-case sensor readings */
1331 switch (priv->kind) {
3d2e9f58
AS
1332 case aquaero:
1333 /* Read calculated virtual temp sensors */
1334 i = priv->num_temp_sensors + priv->num_virtual_temp_sensors;
1335 for (j = 0; j < priv->num_calc_virt_temp_sensors; j++) {
1336 sensor_value = get_unaligned_be16(data +
1337 priv->calc_virt_temp_sensor_start_offset +
1338 j * AQC_SENSOR_SIZE);
fdbfd330 1339 if (sensor_value == AQC_SENSOR_NA)
3d2e9f58
AS
1340 priv->temp_input[i] = -ENODATA;
1341 else
1342 priv->temp_input[i] = sensor_value * 10;
1343 i++;
1344 }
1345 break;
7505dab7
AS
1346 case aquastreamult:
1347 priv->speed_input[1] = get_unaligned_be16(data + AQUASTREAMULT_PUMP_OFFSET);
1348 priv->speed_input[2] = get_unaligned_be16(data + AQUASTREAMULT_PRESSURE_OFFSET);
1349 priv->speed_input[3] = get_unaligned_be16(data + AQUASTREAMULT_FLOW_SENSOR_OFFSET);
1350
1351 priv->power_input[1] = get_unaligned_be16(data + AQUASTREAMULT_PUMP_POWER) * 10000;
1352
1353 priv->voltage_input[1] = get_unaligned_be16(data + AQUASTREAMULT_PUMP_VOLTAGE) * 10;
1354
1355 priv->current_input[1] = get_unaligned_be16(data + AQUASTREAMULT_PUMP_CURRENT);
1356 break;
654c9735 1357 case d5next:
2fd3eec1 1358 priv->voltage_input[2] = get_unaligned_be16(data + D5NEXT_5V_VOLTAGE) * 10;
f4caa262 1359 priv->voltage_input[3] = get_unaligned_be16(data + D5NEXT_12V_VOLTAGE) * 10;
752b9279 1360 break;
aed80bb9
AS
1361 case highflownext:
1362 /* If external temp sensor is not connected, its power reading is also N/A */
1363 if (priv->temp_input[1] == -ENODATA)
1364 priv->power_input[0] = -ENODATA;
1365 else
1366 priv->power_input[0] =
1367 get_unaligned_be16(data + HIGHFLOWNEXT_POWER) * 1000000;
1368
1369 priv->voltage_input[0] = get_unaligned_be16(data + HIGHFLOWNEXT_5V_VOLTAGE) * 10;
1370 priv->voltage_input[1] =
1371 get_unaligned_be16(data + HIGHFLOWNEXT_5V_VOLTAGE_USB) * 10;
1372
aed80bb9
AS
1373 priv->speed_input[1] = get_unaligned_be16(data + HIGHFLOWNEXT_WATER_QUALITY);
1374 priv->speed_input[2] = get_unaligned_be16(data + HIGHFLOWNEXT_CONDUCTIVITY);
1375 break;
b3d3be6c
AS
1376 case leakshield:
1377 priv->speed_input[0] =
1378 ((s16)get_unaligned_be16(data + LEAKSHIELD_PRESSURE_ADJUSTED)) * 100;
1379 priv->speed_input_min[0] = get_unaligned_be16(data + LEAKSHIELD_PRESSURE_MIN) * 100;
1380 priv->speed_input_target[0] =
1381 get_unaligned_be16(data + LEAKSHIELD_PRESSURE_TARGET) * 100;
1382 priv->speed_input_max[0] = get_unaligned_be16(data + LEAKSHIELD_PRESSURE_MAX) * 100;
1383
1384 priv->speed_input[1] = get_unaligned_be16(data + LEAKSHIELD_PUMP_RPM_IN);
1385 if (priv->speed_input[1] == AQC_SENSOR_NA)
1386 priv->speed_input[1] = -ENODATA;
1387
1388 priv->speed_input[2] = get_unaligned_be16(data + LEAKSHIELD_FLOW_IN);
1389 if (priv->speed_input[2] == AQC_SENSOR_NA)
1390 priv->speed_input[2] = -ENODATA;
1391
1392 priv->speed_input[3] = get_unaligned_be16(data + LEAKSHIELD_RESERVOIR_VOLUME);
1393 priv->speed_input[4] = get_unaligned_be16(data + LEAKSHIELD_RESERVOIR_FILLED);
1394
1395 /* Second temp sensor is not positioned after the first one, read it here */
1396 priv->temp_input[1] = get_unaligned_be16(data + LEAKSHIELD_TEMPERATURE_2) * 10;
1397 break;
2fd3eec1
AS
1398 default:
1399 break;
1400 }
0e35f63f
AS
1401
1402 priv->updated = jiffies;
1403
1404 return 0;
1405}
1406
1407#ifdef CONFIG_DEBUG_FS
1408
1409static int serial_number_show(struct seq_file *seqf, void *unused)
1410{
2fd3eec1 1411 struct aqc_data *priv = seqf->private;
0e35f63f
AS
1412
1413 seq_printf(seqf, "%05u-%05u\n", priv->serial_number[0], priv->serial_number[1]);
1414
1415 return 0;
1416}
1417DEFINE_SHOW_ATTRIBUTE(serial_number);
1418
1419static int firmware_version_show(struct seq_file *seqf, void *unused)
1420{
2fd3eec1 1421 struct aqc_data *priv = seqf->private;
0e35f63f
AS
1422
1423 seq_printf(seqf, "%u\n", priv->firmware_version);
1424
1425 return 0;
1426}
1427DEFINE_SHOW_ATTRIBUTE(firmware_version);
1428
1429static int power_cycles_show(struct seq_file *seqf, void *unused)
1430{
2fd3eec1 1431 struct aqc_data *priv = seqf->private;
0e35f63f
AS
1432
1433 seq_printf(seqf, "%u\n", priv->power_cycles);
1434
1435 return 0;
1436}
1437DEFINE_SHOW_ATTRIBUTE(power_cycles);
1438
2fd3eec1 1439static void aqc_debugfs_init(struct aqc_data *priv)
0e35f63f 1440{
2fd3eec1 1441 char name[64];
0e35f63f 1442
2fd3eec1
AS
1443 scnprintf(name, sizeof(name), "%s_%s-%s", "aquacomputer", priv->name,
1444 dev_name(&priv->hdev->dev));
0e35f63f
AS
1445
1446 priv->debugfs = debugfs_create_dir(name, NULL);
2fd3eec1 1447
e0f6c370
AS
1448 if (priv->serial_number_start_offset != 0)
1449 debugfs_create_file("serial_number", 0444, priv->debugfs, priv,
1450 &serial_number_fops);
1451 if (priv->firmware_version_offset != 0)
1452 debugfs_create_file("firmware_version", 0444, priv->debugfs, priv,
1453 &firmware_version_fops);
654c9735 1454 if (priv->power_cycle_count_offset != 0)
2fd3eec1 1455 debugfs_create_file("power_cycles", 0444, priv->debugfs, priv, &power_cycles_fops);
0e35f63f
AS
1456}
1457
1458#else
1459
2fd3eec1 1460static void aqc_debugfs_init(struct aqc_data *priv)
0e35f63f
AS
1461{
1462}
1463
1464#endif
1465
2fd3eec1 1466static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
0e35f63f 1467{
2fd3eec1 1468 struct aqc_data *priv;
0e35f63f
AS
1469 int ret;
1470
1471 priv = devm_kzalloc(&hdev->dev, sizeof(*priv), GFP_KERNEL);
1472 if (!priv)
1473 return -ENOMEM;
1474
1475 priv->hdev = hdev;
1476 hid_set_drvdata(hdev, priv);
1477
2fd3eec1 1478 priv->updated = jiffies - STATUS_UPDATE_INTERVAL;
0e35f63f
AS
1479
1480 ret = hid_parse(hdev);
1481 if (ret)
1482 return ret;
1483
1484 ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW);
1485 if (ret)
1486 return ret;
1487
1488 ret = hid_hw_open(hdev);
1489 if (ret)
1490 goto fail_and_stop;
1491
2fd3eec1 1492 switch (hdev->product) {
2c552111
LA
1493 case USB_PRODUCT_ID_AQUAERO:
1494 /*
1495 * Aquaero presents itself as three HID devices under the same product ID:
1496 * "aquaero keyboard/mouse", "aquaero System Control" and "aquaero Device",
1497 * which is the one we want to communicate with. Unlike most other Aquacomputer
1498 * devices, Aquaero does not return meaningful data when explicitly requested
1499 * using GET_FEATURE_REPORT.
1500 *
1501 * The difference between "aquaero Device" and the other two is in the collections
1502 * they present. The two other devices have the type of the second element in
1503 * their respective collections set to 1, while the real device has it set to 0.
1504 */
1505 if (hdev->collection[1].type != 0) {
1506 ret = -ENODEV;
1507 goto fail_and_close;
1508 }
1509
1510 priv->kind = aquaero;
1511
1512 priv->num_fans = AQUAERO_NUM_FANS;
1513 priv->fan_sensor_offsets = aquaero_sensor_fan_offsets;
bd1e92f9 1514 priv->fan_ctrl_offsets = aquaero_ctrl_fan_offsets;
2c552111
LA
1515
1516 priv->num_temp_sensors = AQUAERO_NUM_SENSORS;
1517 priv->temp_sensor_start_offset = AQUAERO_SENSOR_START;
1518 priv->num_virtual_temp_sensors = AQUAERO_NUM_VIRTUAL_SENSORS;
1519 priv->virtual_temp_sensor_start_offset = AQUAERO_VIRTUAL_SENSOR_START;
3d2e9f58
AS
1520 priv->num_calc_virt_temp_sensors = AQUAERO_NUM_CALC_VIRTUAL_SENSORS;
1521 priv->calc_virt_temp_sensor_start_offset = AQUAERO_CALC_VIRTUAL_SENSOR_START;
2c552111
LA
1522 priv->num_flow_sensors = AQUAERO_NUM_FLOW_SENSORS;
1523 priv->flow_sensors_start_offset = AQUAERO_FLOW_SENSORS_START;
1524
6c83ccb1 1525 priv->buffer_size = AQUAERO_CTRL_REPORT_SIZE;
866e630a 1526 priv->temp_ctrl_offset = AQUAERO_TEMP_CTRL_OFFSET;
6c83ccb1 1527
2c552111
LA
1528 priv->temp_label = label_temp_sensors;
1529 priv->virtual_temp_label = label_virtual_temp_sensors;
3d2e9f58 1530 priv->calc_virt_temp_label = label_aquaero_calc_temp_sensors;
2c552111
LA
1531 priv->speed_label = label_aquaero_speeds;
1532 priv->power_label = label_fan_power;
1533 priv->voltage_label = label_fan_voltage;
1534 priv->current_label = label_fan_current;
1535 break;
2fd3eec1
AS
1536 case USB_PRODUCT_ID_D5NEXT:
1537 priv->kind = d5next;
752b9279 1538
654c9735
AS
1539 priv->num_fans = D5NEXT_NUM_FANS;
1540 priv->fan_sensor_offsets = d5next_sensor_fan_offsets;
09e89309 1541 priv->fan_ctrl_offsets = d5next_ctrl_fan_offsets;
d5d896b8 1542
654c9735
AS
1543 priv->num_temp_sensors = D5NEXT_NUM_SENSORS;
1544 priv->temp_sensor_start_offset = D5NEXT_COOLANT_TEMP;
e2769f5e
AS
1545 priv->num_virtual_temp_sensors = D5NEXT_NUM_VIRTUAL_SENSORS;
1546 priv->virtual_temp_sensor_start_offset = D5NEXT_VIRTUAL_SENSORS_START;
662d20b3 1547 priv->temp_ctrl_offset = D5NEXT_TEMP_CTRL_OFFSET;
654c9735 1548
d5d896b8
AS
1549 priv->buffer_size = D5NEXT_CTRL_REPORT_SIZE;
1550
1551 priv->power_cycle_count_offset = D5NEXT_POWER_CYCLES;
1552
752b9279 1553 priv->temp_label = label_d5next_temp;
e2769f5e 1554 priv->virtual_temp_label = label_virtual_temp_sensors;
752b9279
AS
1555 priv->speed_label = label_d5next_speeds;
1556 priv->power_label = label_d5next_power;
1557 priv->voltage_label = label_d5next_voltages;
1558 priv->current_label = label_d5next_current;
2fd3eec1 1559 break;
229b159c
JD
1560 case USB_PRODUCT_ID_FARBWERK:
1561 priv->kind = farbwerk;
1562
654c9735 1563 priv->num_fans = 0;
d5d896b8 1564
654c9735
AS
1565 priv->num_temp_sensors = FARBWERK_NUM_SENSORS;
1566 priv->temp_sensor_start_offset = FARBWERK_SENSOR_START;
d5d896b8 1567
229b159c
JD
1568 priv->temp_label = label_temp_sensors;
1569 break;
2fd3eec1
AS
1570 case USB_PRODUCT_ID_FARBWERK360:
1571 priv->kind = farbwerk360;
752b9279 1572
654c9735 1573 priv->num_fans = 0;
d5d896b8 1574
654c9735
AS
1575 priv->num_temp_sensors = FARBWERK360_NUM_SENSORS;
1576 priv->temp_sensor_start_offset = FARBWERK360_SENSOR_START;
e2769f5e
AS
1577 priv->num_virtual_temp_sensors = FARBWERK360_NUM_VIRTUAL_SENSORS;
1578 priv->virtual_temp_sensor_start_offset = FARBWERK360_VIRTUAL_SENSORS_START;
662d20b3 1579 priv->temp_ctrl_offset = FARBWERK360_TEMP_CTRL_OFFSET;
d5d896b8
AS
1580
1581 priv->buffer_size = FARBWERK360_CTRL_REPORT_SIZE;
1582
752b9279 1583 priv->temp_label = label_temp_sensors;
e2769f5e 1584 priv->virtual_temp_label = label_virtual_temp_sensors;
752b9279
AS
1585 break;
1586 case USB_PRODUCT_ID_OCTO:
1587 priv->kind = octo;
654c9735
AS
1588
1589 priv->num_fans = OCTO_NUM_FANS;
1590 priv->fan_sensor_offsets = octo_sensor_fan_offsets;
1591 priv->fan_ctrl_offsets = octo_ctrl_fan_offsets;
d5d896b8 1592
654c9735
AS
1593 priv->num_temp_sensors = OCTO_NUM_SENSORS;
1594 priv->temp_sensor_start_offset = OCTO_SENSOR_START;
e2769f5e
AS
1595 priv->num_virtual_temp_sensors = OCTO_NUM_VIRTUAL_SENSORS;
1596 priv->virtual_temp_sensor_start_offset = OCTO_VIRTUAL_SENSORS_START;
662d20b3 1597 priv->temp_ctrl_offset = OCTO_TEMP_CTRL_OFFSET;
752b9279 1598
d5d896b8
AS
1599 priv->buffer_size = OCTO_CTRL_REPORT_SIZE;
1600
1601 priv->power_cycle_count_offset = OCTO_POWER_CYCLES;
1602
752b9279 1603 priv->temp_label = label_temp_sensors;
e2769f5e 1604 priv->virtual_temp_label = label_virtual_temp_sensors;
752b9279
AS
1605 priv->speed_label = label_fan_speed;
1606 priv->power_label = label_fan_power;
1607 priv->voltage_label = label_fan_voltage;
1608 priv->current_label = label_fan_current;
2fd3eec1 1609 break;
cdbe34da
AS
1610 case USB_PRODUCT_ID_QUADRO:
1611 priv->kind = quadro;
1612
1613 priv->num_fans = QUADRO_NUM_FANS;
1614 priv->fan_sensor_offsets = quadro_sensor_fan_offsets;
1615 priv->fan_ctrl_offsets = quadro_ctrl_fan_offsets;
d5d896b8 1616
cdbe34da
AS
1617 priv->num_temp_sensors = QUADRO_NUM_SENSORS;
1618 priv->temp_sensor_start_offset = QUADRO_SENSOR_START;
e2769f5e
AS
1619 priv->num_virtual_temp_sensors = QUADRO_NUM_VIRTUAL_SENSORS;
1620 priv->virtual_temp_sensor_start_offset = QUADRO_VIRTUAL_SENSORS_START;
a2ba7ee2
LA
1621 priv->num_flow_sensors = QUADRO_NUM_FLOW_SENSORS;
1622 priv->flow_sensors_start_offset = QUADRO_FLOW_SENSOR_OFFSET;
1623
d5d896b8
AS
1624 priv->temp_ctrl_offset = QUADRO_TEMP_CTRL_OFFSET;
1625
cdbe34da 1626 priv->buffer_size = QUADRO_CTRL_REPORT_SIZE;
d5d896b8 1627
6ff838f2 1628 priv->flow_pulses_ctrl_offset = QUADRO_FLOW_PULSES_CTRL_OFFSET;
d5d896b8 1629 priv->power_cycle_count_offset = QUADRO_POWER_CYCLES;
cdbe34da
AS
1630
1631 priv->temp_label = label_temp_sensors;
e2769f5e 1632 priv->virtual_temp_label = label_virtual_temp_sensors;
cdbe34da
AS
1633 priv->speed_label = label_quadro_speeds;
1634 priv->power_label = label_fan_power;
1635 priv->voltage_label = label_fan_voltage;
1636 priv->current_label = label_fan_current;
1637 break;
aed80bb9
AS
1638 case USB_PRODUCT_ID_HIGHFLOWNEXT:
1639 priv->kind = highflownext;
1640
1641 priv->num_fans = 0;
d5d896b8 1642
aed80bb9
AS
1643 priv->num_temp_sensors = HIGHFLOWNEXT_NUM_SENSORS;
1644 priv->temp_sensor_start_offset = HIGHFLOWNEXT_SENSOR_START;
a2ba7ee2
LA
1645 priv->num_flow_sensors = HIGHFLOWNEXT_NUM_FLOW_SENSORS;
1646 priv->flow_sensors_start_offset = HIGHFLOWNEXT_FLOW;
d5d896b8 1647
aed80bb9
AS
1648 priv->power_cycle_count_offset = QUADRO_POWER_CYCLES;
1649
1650 priv->temp_label = label_highflownext_temp_sensors;
1651 priv->speed_label = label_highflownext_fan_speed;
1652 priv->power_label = label_highflownext_power;
1653 priv->voltage_label = label_highflownext_voltage;
1654 break;
b3d3be6c
AS
1655 case USB_PRODUCT_ID_LEAKSHIELD:
1656 /*
1657 * Choose the right Leakshield device, because
1658 * the other one acts as a keyboard
1659 */
1660 if (hdev->type != 2) {
1661 ret = -ENODEV;
1662 goto fail_and_close;
1663 }
1664
1665 priv->kind = leakshield;
1666
1667 priv->num_fans = 0;
1668 priv->num_temp_sensors = LEAKSHIELD_NUM_SENSORS;
1669 priv->temp_sensor_start_offset = LEAKSHIELD_TEMPERATURE_1;
1670
1671 priv->temp_label = label_leakshield_temp_sensors;
1672 priv->speed_label = label_leakshield_fan_speed;
1673 break;
19692f17
AS
1674 case USB_PRODUCT_ID_AQUASTREAMXT:
1675 priv->kind = aquastreamxt;
1676
1677 priv->num_fans = AQUASTREAMXT_NUM_FANS;
1678 priv->fan_sensor_offsets = aquastreamxt_sensor_fan_offsets;
1679
1680 priv->num_temp_sensors = AQUASTREAMXT_NUM_SENSORS;
1681 priv->temp_sensor_start_offset = AQUASTREAMXT_SENSOR_START;
1682 priv->buffer_size = AQUASTREAMXT_SENSOR_REPORT_SIZE;
1683
1684 priv->temp_label = label_aquastreamxt_temp_sensors;
1685 priv->speed_label = label_d5next_speeds;
1686 priv->voltage_label = label_d5next_voltages;
1687 priv->current_label = label_d5next_current;
1688 break;
7505dab7
AS
1689 case USB_PRODUCT_ID_AQUASTREAMULT:
1690 priv->kind = aquastreamult;
1691
1692 priv->num_fans = AQUASTREAMULT_NUM_FANS;
1693 priv->fan_sensor_offsets = aquastreamult_sensor_fan_offsets;
1694
1695 priv->num_temp_sensors = AQUASTREAMULT_NUM_SENSORS;
1696 priv->temp_sensor_start_offset = AQUASTREAMULT_SENSOR_START;
1697
1698 priv->temp_label = label_aquastreamult_temp;
1699 priv->speed_label = label_aquastreamult_speeds;
1700 priv->power_label = label_aquastreamult_power;
1701 priv->voltage_label = label_aquastreamult_voltages;
1702 priv->current_label = label_aquastreamult_current;
1703 break;
e0f6c370
AS
1704 case USB_PRODUCT_ID_POWERADJUST3:
1705 priv->kind = poweradjust3;
1706
1707 priv->num_fans = 0;
1708
1709 priv->num_temp_sensors = POWERADJUST3_NUM_SENSORS;
1710 priv->temp_sensor_start_offset = POWERADJUST3_SENSOR_START;
1711 priv->buffer_size = POWERADJUST3_SENSOR_REPORT_SIZE;
1712
1713 priv->temp_label = label_poweradjust3_temp_sensors;
1714 break;
2fd3eec1
AS
1715 default:
1716 break;
1717 }
1718
2c552111
LA
1719 switch (priv->kind) {
1720 case aquaero:
1721 priv->serial_number_start_offset = AQUAERO_SERIAL_START;
1722 priv->firmware_version_offset = AQUAERO_FIRMWARE_VERSION;
1723
1724 priv->fan_structure = &aqc_aquaero_fan_structure;
6c83ccb1
LA
1725
1726 priv->ctrl_report_id = AQUAERO_CTRL_REPORT_ID;
1727 priv->secondary_ctrl_report_id = AQUAERO_SECONDARY_CTRL_REPORT_ID;
1728 priv->secondary_ctrl_report_size = AQUAERO_SECONDARY_CTRL_REPORT_SIZE;
1729 priv->secondary_ctrl_report = aquaero_secondary_ctrl_report;
2c552111 1730 break;
e0f6c370
AS
1731 case poweradjust3:
1732 priv->status_report_id = POWERADJUST3_STATUS_REPORT_ID;
1733 break;
19692f17
AS
1734 case aquastreamxt:
1735 priv->serial_number_start_offset = AQUASTREAMXT_SERIAL_START;
1736 priv->firmware_version_offset = AQUASTREAMXT_FIRMWARE_VERSION;
1737
1738 priv->status_report_id = AQUASTREAMXT_STATUS_REPORT_ID;
1739 break;
2c552111
LA
1740 default:
1741 priv->serial_number_start_offset = AQC_SERIAL_START;
1742 priv->firmware_version_offset = AQC_FIRMWARE_VERSION;
ad2f0811 1743
b29090ba
LA
1744 priv->ctrl_report_id = CTRL_REPORT_ID;
1745 priv->secondary_ctrl_report_id = SECONDARY_CTRL_REPORT_ID;
1746 priv->secondary_ctrl_report_size = SECONDARY_CTRL_REPORT_SIZE;
1747 priv->secondary_ctrl_report = secondary_ctrl_report;
1748
7505dab7
AS
1749 if (priv->kind == aquastreamult)
1750 priv->fan_structure = &aqc_aquastreamult_fan_structure;
1751 else
1752 priv->fan_structure = &aqc_general_fan_structure;
2c552111
LA
1753 break;
1754 }
249c7521 1755
654c9735
AS
1756 if (priv->buffer_size != 0) {
1757 priv->checksum_start = 0x01;
1758 priv->checksum_length = priv->buffer_size - 3;
1759 priv->checksum_offset = priv->buffer_size - 2;
1760 }
1761
2fd3eec1
AS
1762 priv->name = aqc_device_names[priv->kind];
1763
752b9279 1764 priv->buffer = devm_kzalloc(&hdev->dev, priv->buffer_size, GFP_KERNEL);
8877ecb0
CJ
1765 if (!priv->buffer) {
1766 ret = -ENOMEM;
1767 goto fail_and_close;
1768 }
752b9279
AS
1769
1770 mutex_init(&priv->mutex);
1771
2fd3eec1
AS
1772 priv->hwmon_dev = hwmon_device_register_with_info(&hdev->dev, priv->name, priv,
1773 &aqc_chip_info, NULL);
0e35f63f
AS
1774
1775 if (IS_ERR(priv->hwmon_dev)) {
1776 ret = PTR_ERR(priv->hwmon_dev);
1777 goto fail_and_close;
1778 }
1779
2fd3eec1 1780 aqc_debugfs_init(priv);
0e35f63f
AS
1781
1782 return 0;
1783
1784fail_and_close:
1785 hid_hw_close(hdev);
1786fail_and_stop:
1787 hid_hw_stop(hdev);
1788 return ret;
1789}
1790
2fd3eec1 1791static void aqc_remove(struct hid_device *hdev)
0e35f63f 1792{
2fd3eec1 1793 struct aqc_data *priv = hid_get_drvdata(hdev);
0e35f63f
AS
1794
1795 debugfs_remove_recursive(priv->debugfs);
1796 hwmon_device_unregister(priv->hwmon_dev);
1797
1798 hid_hw_close(hdev);
1799 hid_hw_stop(hdev);
1800}
1801
2fd3eec1 1802static const struct hid_device_id aqc_table[] = {
2c552111 1803 { HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_AQUAERO) },
2fd3eec1 1804 { HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_D5NEXT) },
229b159c 1805 { HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_FARBWERK) },
2fd3eec1 1806 { HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_FARBWERK360) },
752b9279 1807 { HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_OCTO) },
cdbe34da 1808 { HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_QUADRO) },
aed80bb9 1809 { HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_HIGHFLOWNEXT) },
b3d3be6c 1810 { HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_LEAKSHIELD) },
19692f17 1811 { HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_AQUASTREAMXT) },
7505dab7 1812 { HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_AQUASTREAMULT) },
e0f6c370 1813 { HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_POWERADJUST3) },
2fd3eec1 1814 { }
0e35f63f
AS
1815};
1816
2fd3eec1 1817MODULE_DEVICE_TABLE(hid, aqc_table);
0e35f63f 1818
2fd3eec1 1819static struct hid_driver aqc_driver = {
0e35f63f 1820 .name = DRIVER_NAME,
2fd3eec1
AS
1821 .id_table = aqc_table,
1822 .probe = aqc_probe,
1823 .remove = aqc_remove,
1824 .raw_event = aqc_raw_event,
0e35f63f
AS
1825};
1826
2fd3eec1 1827static int __init aqc_init(void)
0e35f63f 1828{
2fd3eec1 1829 return hid_register_driver(&aqc_driver);
0e35f63f
AS
1830}
1831
2fd3eec1 1832static void __exit aqc_exit(void)
0e35f63f 1833{
2fd3eec1 1834 hid_unregister_driver(&aqc_driver);
0e35f63f
AS
1835}
1836
1837/* Request to initialize after the HID bus to ensure it's not being loaded before */
2fd3eec1
AS
1838late_initcall(aqc_init);
1839module_exit(aqc_exit);
0e35f63f
AS
1840
1841MODULE_LICENSE("GPL");
1842MODULE_AUTHOR("Aleksa Savic <savicaleksa83@gmail.com>");
229b159c 1843MODULE_AUTHOR("Jack Doan <me@jackdoan.com>");
2fd3eec1 1844MODULE_DESCRIPTION("Hwmon driver for Aquacomputer devices");