1
1
// SPDX-License-Identifier: GPL-2.0+
2
2
/*
3
- * hwmon driver for Aquacomputer devices (D5 Next, Farbwerk, Farbwerk 360, Octo)
3
+ * hwmon driver for Aquacomputer devices (D5 Next, Farbwerk, Farbwerk 360, Octo,
4
+ * Quadro)
4
5
*
5
6
* Aquacomputer devices send HID reports (with ID 0x01) every second to report
6
7
* sensor values.
21
22
22
23
#define USB_VENDOR_ID_AQUACOMPUTER 0x0c70
23
24
#define USB_PRODUCT_ID_FARBWERK 0xf00a
25
+ #define USB_PRODUCT_ID_QUADRO 0xf00d
24
26
#define USB_PRODUCT_ID_D5NEXT 0xf00e
25
27
#define USB_PRODUCT_ID_FARBWERK360 0xf010
26
28
#define USB_PRODUCT_ID_OCTO 0xf011
27
29
28
- enum kinds { d5next , farbwerk , farbwerk360 , octo };
30
+ enum kinds { d5next , farbwerk , farbwerk360 , octo , quadro };
29
31
30
32
static const char * const aqc_device_names [] = {
31
33
[d5next ] = "d5next" ,
32
34
[farbwerk ] = "farbwerk" ,
33
35
[farbwerk360 ] = "farbwerk360" ,
34
- [octo ] = "octo"
36
+ [octo ] = "octo" ,
37
+ [quadro ] = "quadro"
35
38
};
36
39
37
40
#define DRIVER_NAME "aquacomputer_d5next"
@@ -97,6 +100,18 @@ static u8 octo_sensor_fan_offsets[] = { 0x7D, 0x8A, 0x97, 0xA4, 0xB1, 0xBE, 0xCB
97
100
/* Fan speed registers in Octo control report (from 0-100%) */
98
101
static u16 octo_ctrl_fan_offsets [] = { 0x5B , 0xB0 , 0x105 , 0x15A , 0x1AF , 0x204 , 0x259 , 0x2AE };
99
102
103
+ /* Register offsets for the Quadro fan controller */
104
+ #define QUADRO_POWER_CYCLES 0x18
105
+ #define QUADRO_NUM_FANS 4
106
+ #define QUADRO_NUM_SENSORS 4
107
+ #define QUADRO_SENSOR_START 0x34
108
+ #define QUADRO_CTRL_REPORT_SIZE 0x3c1
109
+ #define QUADRO_FLOW_SENSOR_OFFSET 0x6e
110
+ static u8 quadro_sensor_fan_offsets [] = { 0x70 , 0x7D , 0x8A , 0x97 };
111
+
112
+ /* Fan speed registers in Quadro control report (from 0-100%) */
113
+ static u16 quadro_ctrl_fan_offsets [] = { 0x36 , 0x8b , 0xe0 , 0x135 };
114
+
100
115
/* Labels for D5 Next */
101
116
static const char * const label_d5next_temp [] = {
102
117
"Coolant temp"
@@ -124,15 +139,15 @@ static const char *const label_d5next_current[] = {
124
139
"Fan current"
125
140
};
126
141
127
- /* Labels for Farbwerk, Farbwerk 360 and Octo temperature sensors */
142
+ /* Labels for Farbwerk, Farbwerk 360 and Octo and Quadro temperature sensors */
128
143
static const char * const label_temp_sensors [] = {
129
144
"Sensor 1" ,
130
145
"Sensor 2" ,
131
146
"Sensor 3" ,
132
147
"Sensor 4"
133
148
};
134
149
135
- /* Labels for Octo */
150
+ /* Labels for Octo and Quadro (except speed) */
136
151
static const char * const label_fan_speed [] = {
137
152
"Fan 1 speed" ,
138
153
"Fan 2 speed" ,
@@ -177,6 +192,15 @@ static const char *const label_fan_current[] = {
177
192
"Fan 8 current"
178
193
};
179
194
195
+ /* Labels for Quadro fan speeds */
196
+ static const char * const label_quadro_speeds [] = {
197
+ "Fan 1 speed" ,
198
+ "Fan 2 speed" ,
199
+ "Fan 3 speed" ,
200
+ "Fan 4 speed" ,
201
+ "Flow speed [dL/h]"
202
+ };
203
+
180
204
struct aqc_data {
181
205
struct hid_device * hdev ;
182
206
struct device * hwmon_dev ;
@@ -197,6 +221,7 @@ struct aqc_data {
197
221
int num_temp_sensors ;
198
222
int temp_sensor_start_offset ;
199
223
u16 power_cycle_count_offset ;
224
+ u8 flow_sensor_offset ;
200
225
201
226
/* General info, same across all devices */
202
227
u32 serial_number [2 ];
@@ -334,6 +359,18 @@ static umode_t aqc_is_visible(const void *data, enum hwmon_sensor_types type, u3
334
359
}
335
360
break ;
336
361
case hwmon_fan :
362
+ switch (priv -> kind ) {
363
+ case quadro :
364
+ /* Special case to support flow sensor */
365
+ if (channel < priv -> num_fans + 1 )
366
+ return 0444 ;
367
+ break ;
368
+ default :
369
+ if (channel < priv -> num_fans )
370
+ return 0444 ;
371
+ break ;
372
+ }
373
+ break ;
337
374
case hwmon_power :
338
375
case hwmon_curr :
339
376
if (channel < priv -> num_fans )
@@ -578,6 +615,9 @@ static int aqc_raw_event(struct hid_device *hdev, struct hid_report *report, u8
578
615
priv -> voltage_input [2 ] = get_unaligned_be16 (data + D5NEXT_5V_VOLTAGE ) * 10 ;
579
616
priv -> voltage_input [3 ] = get_unaligned_be16 (data + D5NEXT_12V_VOLTAGE ) * 10 ;
580
617
break ;
618
+ case quadro :
619
+ priv -> speed_input [4 ] = get_unaligned_be16 (data + priv -> flow_sensor_offset );
620
+ break ;
581
621
default :
582
622
break ;
583
623
}
@@ -719,6 +759,24 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
719
759
priv -> voltage_label = label_fan_voltage ;
720
760
priv -> current_label = label_fan_current ;
721
761
break ;
762
+ case USB_PRODUCT_ID_QUADRO :
763
+ priv -> kind = quadro ;
764
+
765
+ priv -> num_fans = QUADRO_NUM_FANS ;
766
+ priv -> fan_sensor_offsets = quadro_sensor_fan_offsets ;
767
+ priv -> fan_ctrl_offsets = quadro_ctrl_fan_offsets ;
768
+ priv -> num_temp_sensors = QUADRO_NUM_SENSORS ;
769
+ priv -> temp_sensor_start_offset = QUADRO_SENSOR_START ;
770
+ priv -> power_cycle_count_offset = QUADRO_POWER_CYCLES ;
771
+ priv -> buffer_size = QUADRO_CTRL_REPORT_SIZE ;
772
+ priv -> flow_sensor_offset = QUADRO_FLOW_SENSOR_OFFSET ;
773
+
774
+ priv -> temp_label = label_temp_sensors ;
775
+ priv -> speed_label = label_quadro_speeds ;
776
+ priv -> power_label = label_fan_power ;
777
+ priv -> voltage_label = label_fan_voltage ;
778
+ priv -> current_label = label_fan_current ;
779
+ break ;
722
780
default :
723
781
break ;
724
782
}
@@ -774,6 +832,7 @@ static const struct hid_device_id aqc_table[] = {
774
832
{ HID_USB_DEVICE (USB_VENDOR_ID_AQUACOMPUTER , USB_PRODUCT_ID_FARBWERK ) },
775
833
{ HID_USB_DEVICE (USB_VENDOR_ID_AQUACOMPUTER , USB_PRODUCT_ID_FARBWERK360 ) },
776
834
{ HID_USB_DEVICE (USB_VENDOR_ID_AQUACOMPUTER , USB_PRODUCT_ID_OCTO ) },
835
+ { HID_USB_DEVICE (USB_VENDOR_ID_AQUACOMPUTER , USB_PRODUCT_ID_QUADRO ) },
777
836
{ }
778
837
};
779
838
0 commit comments