11// SPDX-License-Identifier: GPL-2.0+
22/*
33 * hwmon driver for Aquacomputer devices (D5 Next, Farbwerk, Farbwerk 360, Octo,
4- * Quadro, High Flow Next, Aquaero, Aquastream Ultimate, Leakshield)
4+ * Quadro, High Flow Next, Aquaero, Aquastream Ultimate, Leakshield,
5+ * High Flow USB/MPS Flow family)
56 *
67 * Aquacomputer devices send HID reports (with ID 0x01) every second to report
78 * sensor values, except for devices that communicate through the
8- * legacy way (currently, Poweradjust 3).
9+ * legacy way (currently, Poweradjust 3 and High Flow USB/MPS Flow family ).
910 *
1011 * Copyright 2021 Aleksa Savic <[email protected] > 1112 * Copyright 2022 Jack Doan <[email protected] > 3536#define USB_PRODUCT_ID_AQUASTREAMXT 0xf0b6
3637#define USB_PRODUCT_ID_AQUASTREAMULT 0xf00b
3738#define USB_PRODUCT_ID_POWERADJUST3 0xf0bd
39+ #define USB_PRODUCT_ID_HIGHFLOW 0xf003
3840
3941enum kinds {
4042 d5next , farbwerk , farbwerk360 , octo , quadro ,
4143 highflownext , aquaero , poweradjust3 , aquastreamult ,
42- aquastreamxt , leakshield
44+ aquastreamxt , leakshield , highflow
4345};
4446
4547static const char * const aqc_device_names [] = {
@@ -53,7 +55,8 @@ static const char *const aqc_device_names[] = {
5355 [aquastreamxt ] = "aquastreamxt" ,
5456 [aquaero ] = "aquaero" ,
5557 [aquastreamult ] = "aquastreamultimate" ,
56- [poweradjust3 ] = "poweradjust3"
58+ [poweradjust3 ] = "poweradjust3" ,
59+ [highflow ] = "highflow" /* Covers MPS Flow devices */
5760};
5861
5962#define DRIVER_NAME "aquacomputer_d5next"
@@ -90,6 +93,8 @@ static u8 aquaero_secondary_ctrl_report[] = {
9093
9194#define POWERADJUST3_STATUS_REPORT_ID 0x03
9295
96+ #define HIGHFLOW_STATUS_REPORT_ID 0x02
97+
9398/* Data types for reading and writing control reports */
9499#define AQC_8 0
95100#define AQC_BE16 1
@@ -282,6 +287,17 @@ static u16 aquastreamxt_sensor_fan_offsets[] = { 0x13, 0x1b };
282287/* Sensor report offsets for the Poweradjust 3 */
283288#define POWERADJUST3_SENSOR_START 0x03
284289
290+ /* Specs of the High Flow USB */
291+ #define HIGHFLOW_NUM_SENSORS 2
292+ #define HIGHFLOW_NUM_FLOW_SENSORS 1
293+ #define HIGHFLOW_SENSOR_REPORT_SIZE 0x76
294+
295+ /* Sensor report offsets for the High Flow USB */
296+ #define HIGHFLOW_FIRMWARE_VERSION 0x3
297+ #define HIGHFLOW_SERIAL_START 0x9
298+ #define HIGHFLOW_FLOW_SENSOR_OFFSET 0x23
299+ #define HIGHFLOW_SENSOR_START 0x2b
300+
285301/* Labels for D5 Next */
286302static const char * const label_d5next_temp [] = {
287303 "Coolant temp"
@@ -486,6 +502,16 @@ static const char *const label_poweradjust3_temp_sensors[] = {
486502 "External sensor"
487503};
488504
505+ /* Labels for Highflow */
506+ static const char * const label_highflow_temp [] = {
507+ "External temp" ,
508+ "Internal temp"
509+ };
510+
511+ static const char * const label_highflow_speeds [] = {
512+ "Flow speed [dL/h]"
513+ };
514+
489515struct aqc_fan_structure_offsets {
490516 u8 voltage ;
491517 u8 curr ;
@@ -819,6 +845,7 @@ static umode_t aqc_is_visible(const void *data, enum hwmon_sensor_types type, u3
819845 break ;
820846 case aquaero :
821847 case quadro :
848+ case highflow :
822849 /* Special case to support flow sensors */
823850 if (channel < priv -> num_fans + priv -> num_flow_sensors )
824851 return 0444 ;
@@ -962,6 +989,17 @@ static int aqc_legacy_read(struct aqc_data *priv)
962989 sensor_value = get_unaligned_le16 (priv -> buffer + AQUASTREAMXT_FAN_VOLTAGE_OFFSET );
963990 priv -> voltage_input [1 ] = DIV_ROUND_CLOSEST (sensor_value * 1000 , 63 );
964991 break ;
992+ case highflow :
993+ /* Info provided with every report */
994+ priv -> serial_number [0 ] = get_unaligned_le16 (priv -> buffer +
995+ priv -> serial_number_start_offset );
996+ priv -> firmware_version =
997+ get_unaligned_le16 (priv -> buffer + priv -> firmware_version_offset );
998+
999+ /* Read flow speed */
1000+ priv -> speed_input [0 ] = get_unaligned_le16 (priv -> buffer +
1001+ priv -> flow_sensors_start_offset );
1002+ break ;
9651003 default :
9661004 break ;
9671005 }
@@ -1747,6 +1785,20 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
17471785
17481786 priv -> temp_label = label_poweradjust3_temp_sensors ;
17491787 break ;
1788+ case USB_PRODUCT_ID_HIGHFLOW :
1789+ priv -> kind = highflow ;
1790+
1791+ priv -> num_fans = 0 ;
1792+
1793+ priv -> num_temp_sensors = HIGHFLOW_NUM_SENSORS ;
1794+ priv -> temp_sensor_start_offset = HIGHFLOW_SENSOR_START ;
1795+ priv -> num_flow_sensors = HIGHFLOW_NUM_FLOW_SENSORS ;
1796+ priv -> flow_sensors_start_offset = HIGHFLOW_FLOW_SENSOR_OFFSET ;
1797+ priv -> buffer_size = HIGHFLOW_SENSOR_REPORT_SIZE ;
1798+
1799+ priv -> temp_label = label_highflow_temp ;
1800+ priv -> speed_label = label_highflow_speeds ;
1801+ break ;
17501802 default :
17511803 break ;
17521804 }
@@ -1772,6 +1824,12 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
17721824
17731825 priv -> status_report_id = AQUASTREAMXT_STATUS_REPORT_ID ;
17741826 break ;
1827+ case highflow :
1828+ priv -> serial_number_start_offset = HIGHFLOW_SERIAL_START ;
1829+ priv -> firmware_version_offset = HIGHFLOW_FIRMWARE_VERSION ;
1830+
1831+ priv -> status_report_id = HIGHFLOW_STATUS_REPORT_ID ;
1832+ break ;
17751833 default :
17761834 priv -> serial_number_start_offset = AQC_SERIAL_START ;
17771835 priv -> firmware_version_offset = AQC_FIRMWARE_VERSION ;
@@ -1846,6 +1904,7 @@ static const struct hid_device_id aqc_table[] = {
18461904 { HID_USB_DEVICE (USB_VENDOR_ID_AQUACOMPUTER , USB_PRODUCT_ID_AQUASTREAMXT ) },
18471905 { HID_USB_DEVICE (USB_VENDOR_ID_AQUACOMPUTER , USB_PRODUCT_ID_AQUASTREAMULT ) },
18481906 { HID_USB_DEVICE (USB_VENDOR_ID_AQUACOMPUTER , USB_PRODUCT_ID_POWERADJUST3 ) },
1907+ { HID_USB_DEVICE (USB_VENDOR_ID_AQUACOMPUTER , USB_PRODUCT_ID_HIGHFLOW ) },
18491908 { }
18501909};
18511910
0 commit comments