Skip to content

Commit 19692f1

Browse files
aleksamagickagroeck
authored andcommitted
hwmon: (aquacomputer_d5next) Add support for Aquacomputer Aquastream XT
Extend aquacomputer_d5next driver to expose various hardware sensors of the Aquacomputer Aquastream XT watercooling pump, which communicates through a proprietary USB HID protocol. Implemented by Leonard Anderweit [1] [2]. Coolant temp, fan IC and external temp sensor readings are available, along with speed and voltage of both the pump and optionally connected fan. It also exposes pump current. Additionally, serial number and firmware version are exposed through debugfs. [1] aleksamagicka/aquacomputer_d5next-hwmon#46 [2] aleksamagicka/aquacomputer_d5next-hwmon#49 Originally-from: Leonard Anderweit <leonard.anderweit@gmail.com> Signed-off-by: Aleksa Savic <savicaleksa83@gmail.com> Link: https://lore.kernel.org/r/20230416181702.9892-1-savicaleksa83@gmail.com Signed-off-by: Guenter Roeck <linux@roeck-us.net>
1 parent 0be1007 commit 19692f1

2 files changed

Lines changed: 118 additions & 1 deletion

File tree

Documentation/hwmon/aquacomputer_d5next.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Supported devices:
1212
* Aquacomputer Octo fan controller
1313
* Aquacomputer Quadro fan controller
1414
* Aquacomputer High Flow Next sensor
15+
* Aquacomputer Aquastream XT watercooling pump
1516
* Aquacomputer Aquastream Ultimate watercooling pump
1617
* Aquacomputer Poweradjust 3 fan controller
1718

@@ -56,6 +57,10 @@ The High Flow Next exposes +5V voltages, water quality, conductivity and flow re
5657
A temperature sensor can be connected to it, in which case it provides its reading
5758
and an estimation of the dissipated/absorbed power in the liquid cooling loop.
5859

60+
The Aquastream XT pump exposes temperature readings for the coolant, external sensor
61+
and fan IC. It also exposes pump and fan speeds (in RPM), voltages, as well as pump
62+
current.
63+
5964
The Aquastream Ultimate pump exposes coolant temp and an external temp sensor, along
6065
with speed, power, voltage and current of both the pump and optionally connected fan.
6166
It also exposes pressure and flow speed readings.

drivers/hwmon/aquacomputer_d5next.c

Lines changed: 113 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,14 @@
2929
#define USB_PRODUCT_ID_FARBWERK360 0xf010
3030
#define USB_PRODUCT_ID_OCTO 0xf011
3131
#define USB_PRODUCT_ID_HIGHFLOWNEXT 0xf012
32+
#define USB_PRODUCT_ID_AQUASTREAMXT 0xf0b6
3233
#define USB_PRODUCT_ID_AQUASTREAMULT 0xf00b
3334
#define USB_PRODUCT_ID_POWERADJUST3 0xf0bd
3435

3536
enum kinds {
3637
d5next, farbwerk, farbwerk360, octo, quadro,
37-
highflownext, aquaero, poweradjust3, aquastreamult
38+
highflownext, aquaero, poweradjust3, aquastreamult,
39+
aquastreamxt
3840
};
3941

4042
static const char *const aqc_device_names[] = {
@@ -44,6 +46,7 @@ static const char *const aqc_device_names[] = {
4446
[octo] = "octo",
4547
[quadro] = "quadro",
4648
[highflownext] = "highflownext",
49+
[aquastreamxt] = "aquastreamxt",
4750
[aquaero] = "aquaero",
4851
[aquastreamult] = "aquastreamultimate",
4952
[poweradjust3] = "poweradjust3"
@@ -77,6 +80,8 @@ static u8 aquaero_secondary_ctrl_report[] = {
7780
};
7881

7982
/* Report IDs for legacy devices */
83+
#define AQUASTREAMXT_STATUS_REPORT_ID 0x04
84+
8085
#define POWERADJUST3_STATUS_REPORT_ID 0x03
8186

8287
/* Data types for reading and writing control reports */
@@ -231,6 +236,24 @@ static u16 quadro_ctrl_fan_offsets[] = { 0x37, 0x8c, 0xe1, 0x136 }; /* Fan speed
231236
#define HIGHFLOWNEXT_5V_VOLTAGE 97
232237
#define HIGHFLOWNEXT_5V_VOLTAGE_USB 99
233238

239+
/* Specs of the Aquastream XT pump */
240+
#define AQUASTREAMXT_SERIAL_START 0x3a
241+
#define AQUASTREAMXT_FIRMWARE_VERSION 0x32
242+
#define AQUASTREAMXT_NUM_FANS 2
243+
#define AQUASTREAMXT_NUM_SENSORS 3
244+
#define AQUASTREAMXT_FAN_STOPPED 0x4
245+
#define AQUASTREAMXT_PUMP_CONVERSION_CONST 45000000
246+
#define AQUASTREAMXT_FAN_CONVERSION_CONST 5646000
247+
#define AQUASTREAMXT_SENSOR_REPORT_SIZE 0x42
248+
249+
/* Sensor report offsets and info for Aquastream XT */
250+
#define AQUASTREAMXT_SENSOR_START 0xd
251+
#define AQUASTREAMXT_FAN_VOLTAGE_OFFSET 0x7
252+
#define AQUASTREAMXT_FAN_STATUS_OFFSET 0x1d
253+
#define AQUASTREAMXT_PUMP_VOLTAGE_OFFSET 0x9
254+
#define AQUASTREAMXT_PUMP_CURR_OFFSET 0xb
255+
static u16 aquastreamxt_sensor_fan_offsets[] = { 0x13, 0x1b };
256+
234257
/* Specs of the Poweradjust 3 */
235258
#define POWERADJUST3_NUM_SENSORS 1
236259
#define POWERADJUST3_SENSOR_REPORT_SIZE 0x32
@@ -388,6 +411,13 @@ static const char *const label_highflownext_voltage[] = {
388411
"+5V USB voltage"
389412
};
390413

414+
/* Labels for Aquastream XT */
415+
static const char *const label_aquastreamxt_temp_sensors[] = {
416+
"Fan IC temp",
417+
"External sensor",
418+
"Coolant temp"
419+
};
420+
391421
/* Labels for Aquastream Ultimate */
392422
static const char *const label_aquastreamult_temp[] = {
393423
"Coolant temp",
@@ -531,6 +561,22 @@ static int aqc_pwm_to_percent(long val)
531561
return DIV_ROUND_CLOSEST(val * 100 * 100, 255);
532562
}
533563

564+
/* Converts raw value for Aquastream XT pump speed to RPM */
565+
static int aqc_aquastreamxt_convert_pump_rpm(u16 val)
566+
{
567+
if (val > 0)
568+
return DIV_ROUND_CLOSEST(AQUASTREAMXT_PUMP_CONVERSION_CONST, val);
569+
return 0;
570+
}
571+
572+
/* Converts raw value for Aquastream XT fan speed to RPM */
573+
static int aqc_aquastreamxt_convert_fan_rpm(u16 val)
574+
{
575+
if (val > 0)
576+
return DIV_ROUND_CLOSEST(AQUASTREAMXT_FAN_CONVERSION_CONST, val);
577+
return 0;
578+
}
579+
534580
/* Expects the mutex to be locked */
535581
static int aqc_get_ctrl_data(struct aqc_data *priv)
536582
{
@@ -734,6 +780,8 @@ static umode_t aqc_is_visible(const void *data, enum hwmon_sensor_types type, u3
734780
if (channel == 0)
735781
return 0444;
736782
break;
783+
case aquastreamxt:
784+
break;
737785
default:
738786
if (channel < priv->num_fans)
739787
return 0444;
@@ -747,6 +795,11 @@ static umode_t aqc_is_visible(const void *data, enum hwmon_sensor_types type, u3
747795
if (channel < 2)
748796
return 0444;
749797
break;
798+
case aquastreamxt:
799+
/* Special case to support pump current */
800+
if (channel == 0)
801+
return 0444;
802+
break;
750803
default:
751804
if (channel < priv->num_fans)
752805
return 0444;
@@ -799,6 +852,43 @@ static int aqc_legacy_read(struct aqc_data *priv)
799852
priv->temp_input[i] = sensor_value * 10;
800853
}
801854

855+
/* Special-case sensor readings */
856+
switch (priv->kind) {
857+
case aquastreamxt:
858+
/* Info provided with every report */
859+
priv->serial_number[0] = get_unaligned_le16(priv->buffer +
860+
priv->serial_number_start_offset);
861+
priv->firmware_version =
862+
get_unaligned_le16(priv->buffer + priv->firmware_version_offset);
863+
864+
/* Read pump speed in RPM */
865+
sensor_value = get_unaligned_le16(priv->buffer + priv->fan_sensor_offsets[0]);
866+
priv->speed_input[0] = aqc_aquastreamxt_convert_pump_rpm(sensor_value);
867+
868+
/* Read fan speed in RPM, if available */
869+
sensor_value = get_unaligned_le16(priv->buffer + AQUASTREAMXT_FAN_STATUS_OFFSET);
870+
if (sensor_value == AQUASTREAMXT_FAN_STOPPED) {
871+
priv->speed_input[1] = 0;
872+
} else {
873+
sensor_value =
874+
get_unaligned_le16(priv->buffer + priv->fan_sensor_offsets[1]);
875+
priv->speed_input[1] = aqc_aquastreamxt_convert_fan_rpm(sensor_value);
876+
}
877+
878+
/* Calculation derived from linear regression */
879+
sensor_value = get_unaligned_le16(priv->buffer + AQUASTREAMXT_PUMP_CURR_OFFSET);
880+
priv->current_input[0] = DIV_ROUND_CLOSEST(sensor_value * 176, 100) - 52;
881+
882+
sensor_value = get_unaligned_le16(priv->buffer + AQUASTREAMXT_PUMP_VOLTAGE_OFFSET);
883+
priv->voltage_input[0] = DIV_ROUND_CLOSEST(sensor_value * 1000, 61);
884+
885+
sensor_value = get_unaligned_le16(priv->buffer + AQUASTREAMXT_FAN_VOLTAGE_OFFSET);
886+
priv->voltage_input[1] = DIV_ROUND_CLOSEST(sensor_value * 1000, 63);
887+
break;
888+
default:
889+
break;
890+
}
891+
802892
priv->updated = jiffies;
803893

804894
unlock_and_return:
@@ -1481,6 +1571,21 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
14811571
priv->power_label = label_highflownext_power;
14821572
priv->voltage_label = label_highflownext_voltage;
14831573
break;
1574+
case USB_PRODUCT_ID_AQUASTREAMXT:
1575+
priv->kind = aquastreamxt;
1576+
1577+
priv->num_fans = AQUASTREAMXT_NUM_FANS;
1578+
priv->fan_sensor_offsets = aquastreamxt_sensor_fan_offsets;
1579+
1580+
priv->num_temp_sensors = AQUASTREAMXT_NUM_SENSORS;
1581+
priv->temp_sensor_start_offset = AQUASTREAMXT_SENSOR_START;
1582+
priv->buffer_size = AQUASTREAMXT_SENSOR_REPORT_SIZE;
1583+
1584+
priv->temp_label = label_aquastreamxt_temp_sensors;
1585+
priv->speed_label = label_d5next_speeds;
1586+
priv->voltage_label = label_d5next_voltages;
1587+
priv->current_label = label_d5next_current;
1588+
break;
14841589
case USB_PRODUCT_ID_AQUASTREAMULT:
14851590
priv->kind = aquastreamult;
14861591

@@ -1526,6 +1631,12 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
15261631
case poweradjust3:
15271632
priv->status_report_id = POWERADJUST3_STATUS_REPORT_ID;
15281633
break;
1634+
case aquastreamxt:
1635+
priv->serial_number_start_offset = AQUASTREAMXT_SERIAL_START;
1636+
priv->firmware_version_offset = AQUASTREAMXT_FIRMWARE_VERSION;
1637+
1638+
priv->status_report_id = AQUASTREAMXT_STATUS_REPORT_ID;
1639+
break;
15291640
default:
15301641
priv->serial_number_start_offset = AQC_SERIAL_START;
15311642
priv->firmware_version_offset = AQC_FIRMWARE_VERSION;
@@ -1596,6 +1707,7 @@ static const struct hid_device_id aqc_table[] = {
15961707
{ HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_OCTO) },
15971708
{ HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_QUADRO) },
15981709
{ HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_HIGHFLOWNEXT) },
1710+
{ HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_AQUASTREAMXT) },
15991711
{ HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_AQUASTREAMULT) },
16001712
{ HID_USB_DEVICE(USB_VENDOR_ID_AQUACOMPUTER, USB_PRODUCT_ID_POWERADJUST3) },
16011713
{ }

0 commit comments

Comments
 (0)