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