summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/hwmon/aquacomputer_d5next.rst32
-rw-r--r--drivers/hwmon/aquacomputer_d5next.c88
2 files changed, 100 insertions, 20 deletions
diff --git a/Documentation/hwmon/aquacomputer_d5next.rst b/Documentation/hwmon/aquacomputer_d5next.rst
index 33649a1e3a05..b63a78d47624 100644
--- a/Documentation/hwmon/aquacomputer_d5next.rst
+++ b/Documentation/hwmon/aquacomputer_d5next.rst
@@ -20,10 +20,11 @@ This driver exposes hardware sensors of listed Aquacomputer devices, which
communicate through proprietary USB HID protocols.
For the D5 Next pump, available sensors are pump and fan speed, power, voltage
-and current, as well as coolant temperature. Also available through debugfs are
-the serial number, firmware version and power-on count. Attaching a fan to it is
-optional and allows it to be controlled using temperature curves directly from the
-pump. If it's not connected, the fan-related sensors will report zeroes.
+and current, as well as coolant temperature and eight virtual temp sensors. Also
+available through debugfs are the serial number, firmware version and power-on
+count. Attaching a fan to it is optional and allows it to be controlled using
+temperature curves directly from the pump. If it's not connected, the fan-related
+sensors will report zeroes.
The pump can be configured either through software or via its physical
interface. Configuring the pump through this driver is not implemented, as it
@@ -31,14 +32,19 @@ seems to require sending it a complete configuration. That includes addressable
RGB LEDs, for which there is no standard sysfs interface. Thus, that task is
better suited for userspace tools.
-The Octo exposes four temperature sensors and eight PWM controllable fans, along
-with their speed (in RPM), power, voltage and current.
+The Octo exposes four physical and sixteen virtual temperature sensors, as well as
+eight PWM controllable fans, along with their speed (in RPM), power, voltage and
+current.
-The Quadro exposes four temperature sensors, a flow sensor and four PWM controllable
-fans, along with their speed (in RPM), power, voltage and current.
+The Quadro exposes four physical and sixteen virtual temperature sensors, a flow
+sensor and four PWM controllable fans, along with their speed (in RPM), power,
+voltage and current.
-The Farbwerk and Farbwerk 360 expose four temperature sensors. Depending on the device,
-not all sysfs and debugfs entries will be available.
+The Farbwerk and Farbwerk 360 expose four temperature sensors. Additionally,
+sixteen virtual temperature sensors of the Farbwerk 360 are exposed.
+
+Depending on the device, not all sysfs and debugfs entries will be available.
+Writing to virtual temperature sensors is not currently supported.
Usage notes
-----------
@@ -49,14 +55,14 @@ the kernel and supports hotswapping.
Sysfs entries
-------------
-================ ==============================================
-temp[1-4]_input Temperature sensors (in millidegrees Celsius)
+================ ==============================================================
+temp[1-20]_input Physical/virtual temperature sensors (in millidegrees Celsius)
fan[1-8]_input Pump/fan speed (in RPM) / Flow speed (in dL/h)
power[1-8]_input Pump/fan power (in micro Watts)
in[0-7]_input Pump/fan voltage (in milli Volts)
curr[1-8]_input Pump/fan current (in milli Amperes)
pwm[1-8] Fan PWM (0 - 255)
-================ ==============================================
+================ ==============================================================
Debugfs entries
---------------
diff --git a/drivers/hwmon/aquacomputer_d5next.c b/drivers/hwmon/aquacomputer_d5next.c
index 36752cf2cac9..77cc8f50b8af 100644
--- a/drivers/hwmon/aquacomputer_d5next.c
+++ b/drivers/hwmon/aquacomputer_d5next.c
@@ -71,6 +71,8 @@ static u8 secondary_ctrl_report[] = {
#define D5NEXT_COOLANT_TEMP 0x57
#define D5NEXT_NUM_FANS 2
#define D5NEXT_NUM_SENSORS 1
+#define D5NEXT_NUM_VIRTUAL_SENSORS 8
+#define D5NEXT_VIRTUAL_SENSORS_START 0x3f
#define D5NEXT_PUMP_OFFSET 0x6c
#define D5NEXT_FAN_OFFSET 0x5f
#define D5NEXT_5V_VOLTAGE 0x39
@@ -86,14 +88,18 @@ static u16 d5next_ctrl_fan_offsets[] = { 0x97, 0x42 };
#define FARBWERK_SENSOR_START 0x2f
/* Register offsets for the Farbwerk 360 RGB controller */
-#define FARBWERK360_NUM_SENSORS 4
-#define FARBWERK360_SENSOR_START 0x32
+#define FARBWERK360_NUM_SENSORS 4
+#define FARBWERK360_SENSOR_START 0x32
+#define FARBWERK360_NUM_VIRTUAL_SENSORS 16
+#define FARBWERK360_VIRTUAL_SENSORS_START 0x3a
/* Register offsets for the Octo fan controller */
#define OCTO_POWER_CYCLES 0x18
#define OCTO_NUM_FANS 8
#define OCTO_NUM_SENSORS 4
#define OCTO_SENSOR_START 0x3D
+#define OCTO_NUM_VIRTUAL_SENSORS 16
+#define OCTO_VIRTUAL_SENSORS_START 0x45
#define OCTO_CTRL_REPORT_SIZE 0x65F
static u8 octo_sensor_fan_offsets[] = { 0x7D, 0x8A, 0x97, 0xA4, 0xB1, 0xBE, 0xCB, 0xD8 };
@@ -105,6 +111,8 @@ static u16 octo_ctrl_fan_offsets[] = { 0x5B, 0xB0, 0x105, 0x15A, 0x1AF, 0x204, 0
#define QUADRO_NUM_FANS 4
#define QUADRO_NUM_SENSORS 4
#define QUADRO_SENSOR_START 0x34
+#define QUADRO_NUM_VIRTUAL_SENSORS 16
+#define QUADRO_VIRTUAL_SENSORS_START 0x3c
#define QUADRO_CTRL_REPORT_SIZE 0x3c1
#define QUADRO_FLOW_SENSOR_OFFSET 0x6e
static u8 quadro_sensor_fan_offsets[] = { 0x70, 0x7D, 0x8A, 0x97 };
@@ -147,6 +155,25 @@ static const char *const label_temp_sensors[] = {
"Sensor 4"
};
+static const char *const label_virtual_temp_sensors[] = {
+ "Virtual sensor 1",
+ "Virtual sensor 2",
+ "Virtual sensor 3",
+ "Virtual sensor 4",
+ "Virtual sensor 5",
+ "Virtual sensor 6",
+ "Virtual sensor 7",
+ "Virtual sensor 8",
+ "Virtual sensor 9",
+ "Virtual sensor 10",
+ "Virtual sensor 11",
+ "Virtual sensor 12",
+ "Virtual sensor 13",
+ "Virtual sensor 14",
+ "Virtual sensor 15",
+ "Virtual sensor 16",
+};
+
/* Labels for Octo and Quadro (except speed) */
static const char *const label_fan_speed[] = {
"Fan 1 speed",
@@ -220,6 +247,8 @@ struct aqc_data {
u16 *fan_ctrl_offsets;
int num_temp_sensors;
int temp_sensor_start_offset;
+ int num_virtual_temp_sensors;
+ int virtual_temp_sensor_start_offset;
u16 power_cycle_count_offset;
u8 flow_sensor_offset;
@@ -231,7 +260,7 @@ struct aqc_data {
u32 power_cycles;
/* Sensor values */
- s32 temp_input[4];
+ s32 temp_input[20]; /* Max 4 physical and 16 virtual */
u16 speed_input[8];
u32 power_input[8];
u16 voltage_input[8];
@@ -239,6 +268,7 @@ struct aqc_data {
/* Label values */
const char *const *temp_label;
+ const char *const *virtual_temp_label;
const char *const *speed_label;
const char *const *power_label;
const char *const *voltage_label;
@@ -345,7 +375,7 @@ static umode_t aqc_is_visible(const void *data, enum hwmon_sensor_types type, u3
switch (type) {
case hwmon_temp:
- if (channel < priv->num_temp_sensors)
+ if (channel < priv->num_temp_sensors + priv->num_virtual_temp_sensors)
return 0444;
break;
case hwmon_pwm:
@@ -447,7 +477,10 @@ static int aqc_read_string(struct device *dev, enum hwmon_sensor_types type, u32
switch (type) {
case hwmon_temp:
- *str = priv->temp_label[channel];
+ if (channel < priv->num_temp_sensors)
+ *str = priv->temp_label[channel];
+ else
+ *str = priv->virtual_temp_label[channel - priv->num_temp_sensors];
break;
case hwmon_fan:
*str = priv->speed_label[channel];
@@ -512,6 +545,22 @@ static const struct hwmon_channel_info *aqc_info[] = {
HWMON_T_INPUT | HWMON_T_LABEL,
HWMON_T_INPUT | HWMON_T_LABEL,
HWMON_T_INPUT | HWMON_T_LABEL,
+ HWMON_T_INPUT | HWMON_T_LABEL,
+ HWMON_T_INPUT | HWMON_T_LABEL,
+ HWMON_T_INPUT | HWMON_T_LABEL,
+ HWMON_T_INPUT | HWMON_T_LABEL,
+ HWMON_T_INPUT | HWMON_T_LABEL,
+ HWMON_T_INPUT | HWMON_T_LABEL,
+ HWMON_T_INPUT | HWMON_T_LABEL,
+ HWMON_T_INPUT | HWMON_T_LABEL,
+ HWMON_T_INPUT | HWMON_T_LABEL,
+ HWMON_T_INPUT | HWMON_T_LABEL,
+ HWMON_T_INPUT | HWMON_T_LABEL,
+ HWMON_T_INPUT | HWMON_T_LABEL,
+ HWMON_T_INPUT | HWMON_T_LABEL,
+ HWMON_T_INPUT | HWMON_T_LABEL,
+ HWMON_T_INPUT | HWMON_T_LABEL,
+ HWMON_T_INPUT | HWMON_T_LABEL,
HWMON_T_INPUT | HWMON_T_LABEL),
HWMON_CHANNEL_INFO(fan,
HWMON_F_INPUT | HWMON_F_LABEL,
@@ -568,7 +617,7 @@ static const struct hwmon_chip_info aqc_chip_info = {
static int aqc_raw_event(struct hid_device *hdev, struct hid_report *report, u8 *data, int size)
{
- int i, sensor_value;
+ int i, j, sensor_value;
struct aqc_data *priv;
if (report->id != STATUS_REPORT_ID)
@@ -581,7 +630,7 @@ static int aqc_raw_event(struct hid_device *hdev, struct hid_report *report, u8
priv->serial_number[1] = get_unaligned_be16(data + SERIAL_SECOND_PART);
priv->firmware_version = get_unaligned_be16(data + FIRMWARE_VERSION);
- /* Temperature sensor readings */
+ /* Physical temperature sensor readings */
for (i = 0; i < priv->num_temp_sensors; i++) {
sensor_value = get_unaligned_be16(data +
priv->temp_sensor_start_offset +
@@ -592,6 +641,18 @@ static int aqc_raw_event(struct hid_device *hdev, struct hid_report *report, u8
priv->temp_input[i] = sensor_value * 10;
}
+ /* Virtual temperature sensor readings */
+ for (j = 0; j < priv->num_virtual_temp_sensors; j++) {
+ sensor_value = get_unaligned_be16(data +
+ priv->virtual_temp_sensor_start_offset +
+ j * AQC_TEMP_SENSOR_SIZE);
+ if (sensor_value == AQC_TEMP_SENSOR_DISCONNECTED)
+ priv->temp_input[i] = -ENODATA;
+ else
+ priv->temp_input[i] = sensor_value * 10;
+ i++;
+ }
+
/* Fan speed and related readings */
for (i = 0; i < priv->num_fans; i++) {
priv->speed_input[i] =
@@ -717,10 +778,13 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
priv->fan_ctrl_offsets = d5next_ctrl_fan_offsets;
priv->num_temp_sensors = D5NEXT_NUM_SENSORS;
priv->temp_sensor_start_offset = D5NEXT_COOLANT_TEMP;
+ priv->num_virtual_temp_sensors = D5NEXT_NUM_VIRTUAL_SENSORS;
+ priv->virtual_temp_sensor_start_offset = D5NEXT_VIRTUAL_SENSORS_START;
priv->power_cycle_count_offset = D5NEXT_POWER_CYCLES;
priv->buffer_size = D5NEXT_CTRL_REPORT_SIZE;
priv->temp_label = label_d5next_temp;
+ priv->virtual_temp_label = label_virtual_temp_sensors;
priv->speed_label = label_d5next_speeds;
priv->power_label = label_d5next_power;
priv->voltage_label = label_d5next_voltages;
@@ -740,7 +804,11 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
priv->num_fans = 0;
priv->num_temp_sensors = FARBWERK360_NUM_SENSORS;
priv->temp_sensor_start_offset = FARBWERK360_SENSOR_START;
+ priv->num_virtual_temp_sensors = FARBWERK360_NUM_VIRTUAL_SENSORS;
+ priv->virtual_temp_sensor_start_offset = FARBWERK360_VIRTUAL_SENSORS_START;
+
priv->temp_label = label_temp_sensors;
+ priv->virtual_temp_label = label_virtual_temp_sensors;
break;
case USB_PRODUCT_ID_OCTO:
priv->kind = octo;
@@ -750,10 +818,13 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
priv->fan_ctrl_offsets = octo_ctrl_fan_offsets;
priv->num_temp_sensors = OCTO_NUM_SENSORS;
priv->temp_sensor_start_offset = OCTO_SENSOR_START;
+ priv->num_virtual_temp_sensors = OCTO_NUM_VIRTUAL_SENSORS;
+ priv->virtual_temp_sensor_start_offset = OCTO_VIRTUAL_SENSORS_START;
priv->power_cycle_count_offset = OCTO_POWER_CYCLES;
priv->buffer_size = OCTO_CTRL_REPORT_SIZE;
priv->temp_label = label_temp_sensors;
+ priv->virtual_temp_label = label_virtual_temp_sensors;
priv->speed_label = label_fan_speed;
priv->power_label = label_fan_power;
priv->voltage_label = label_fan_voltage;
@@ -767,11 +838,14 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
priv->fan_ctrl_offsets = quadro_ctrl_fan_offsets;
priv->num_temp_sensors = QUADRO_NUM_SENSORS;
priv->temp_sensor_start_offset = QUADRO_SENSOR_START;
+ priv->num_virtual_temp_sensors = QUADRO_NUM_VIRTUAL_SENSORS;
+ priv->virtual_temp_sensor_start_offset = QUADRO_VIRTUAL_SENSORS_START;
priv->power_cycle_count_offset = QUADRO_POWER_CYCLES;
priv->buffer_size = QUADRO_CTRL_REPORT_SIZE;
priv->flow_sensor_offset = QUADRO_FLOW_SENSOR_OFFSET;
priv->temp_label = label_temp_sensors;
+ priv->virtual_temp_label = label_virtual_temp_sensors;
priv->speed_label = label_quadro_speeds;
priv->power_label = label_fan_power;
priv->voltage_label = label_fan_voltage;