aboutsummaryrefslogtreecommitdiff
path: root/drivers/hwmon
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/aquacomputer_d5next.c64
1 files changed, 59 insertions, 5 deletions
diff --git a/drivers/hwmon/aquacomputer_d5next.c b/drivers/hwmon/aquacomputer_d5next.c
index 61c1ffcd8f3b..17fad3142118 100644
--- a/drivers/hwmon/aquacomputer_d5next.c
+++ b/drivers/hwmon/aquacomputer_d5next.c
@@ -104,6 +104,9 @@ static u8 aquaero_secondary_ctrl_report[] = {
#define AQUAERO_NUM_CALC_VIRTUAL_SENSORS 4
#define AQUAERO_NUM_FLOW_SENSORS 2
#define AQUAERO_CTRL_REPORT_SIZE 0xa93
+#define AQUAERO_CTRL_PRESET_ID 0x5c
+#define AQUAERO_CTRL_PRESET_SIZE 0x02
+#define AQUAERO_CTRL_PRESET_START 0x55c
/* Sensor report offsets for Aquaero fan controllers */
#define AQUAERO_SENSOR_START 0x65
@@ -118,6 +121,10 @@ static u16 aquaero_sensor_fan_offsets[] = { 0x167, 0x173, 0x17f, 0x18B };
/* Control report offsets for the Aquaero fan controllers */
#define AQUAERO_TEMP_CTRL_OFFSET 0xdb
+#define AQUAERO_FAN_CTRL_MIN_PWR_OFFSET 0x04
+#define AQUAERO_FAN_CTRL_MAX_PWR_OFFSET 0x06
+#define AQUAERO_FAN_CTRL_SRC_OFFSET 0x10
+static u16 aquaero_ctrl_fan_offsets[] = { 0x20c, 0x220, 0x234, 0x248 };
/* Specs of the D5 Next pump */
#define D5NEXT_NUM_FANS 2
@@ -857,13 +864,23 @@ static int aqc_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
*val = priv->power_input[channel];
break;
case hwmon_pwm:
- if (priv->fan_ctrl_offsets) {
+ switch (priv->kind) {
+ case aquaero:
+ ret = aqc_get_ctrl_val(priv,
+ AQUAERO_CTRL_PRESET_START + channel * AQUAERO_CTRL_PRESET_SIZE,
+ val, AQC_BE16);
+ if (ret < 0)
+ return ret;
+ *val = aqc_percent_to_pwm(*val);
+ break;
+ default:
ret = aqc_get_ctrl_val(priv, priv->fan_ctrl_offsets[channel],
val, AQC_BE16);
if (ret < 0)
return ret;
*val = aqc_percent_to_pwm(ret);
+ break;
}
break;
case hwmon_in:
@@ -922,6 +939,10 @@ static int aqc_write(struct device *dev, enum hwmon_sensor_types type, u32 attr,
long val)
{
int ret, pwm_value;
+ /* Arrays for setting multiple values at once in the control report */
+ int ctrl_values_offsets[4];
+ long ctrl_values[4];
+ int ctrl_values_types[4];
struct aqc_data *priv = dev_get_drvdata(dev);
switch (type) {
@@ -956,15 +977,47 @@ static int aqc_write(struct device *dev, enum hwmon_sensor_types type, u32 attr,
case hwmon_pwm:
switch (attr) {
case hwmon_pwm_input:
- if (priv->fan_ctrl_offsets) {
- pwm_value = aqc_pwm_to_percent(val);
- if (pwm_value < 0)
- return pwm_value;
+ pwm_value = aqc_pwm_to_percent(val);
+ if (pwm_value < 0)
+ return pwm_value;
+ switch (priv->kind) {
+ case aquaero:
+ /* Write pwm value to preset corresponding to the channel */
+ ctrl_values_offsets[0] = AQUAERO_CTRL_PRESET_START +
+ channel * AQUAERO_CTRL_PRESET_SIZE;
+ ctrl_values[0] = pwm_value;
+ ctrl_values_types[0] = AQC_BE16;
+
+ /* Write preset number in fan control source */
+ ctrl_values_offsets[1] = priv->fan_ctrl_offsets[channel] +
+ AQUAERO_FAN_CTRL_SRC_OFFSET;
+ ctrl_values[1] = AQUAERO_CTRL_PRESET_ID + channel;
+ ctrl_values_types[1] = AQC_BE16;
+
+ /* Set minimum power to 0 to allow the fan to turn off */
+ ctrl_values_offsets[2] = priv->fan_ctrl_offsets[channel] +
+ AQUAERO_FAN_CTRL_MIN_PWR_OFFSET;
+ ctrl_values[2] = 0;
+ ctrl_values_types[2] = AQC_BE16;
+
+ /* Set maximum power to 255 to allow the fan to reach max speed */
+ ctrl_values_offsets[3] = priv->fan_ctrl_offsets[channel] +
+ AQUAERO_FAN_CTRL_MAX_PWR_OFFSET;
+ ctrl_values[3] = aqc_pwm_to_percent(255);
+ ctrl_values_types[3] = AQC_BE16;
+
+ ret = aqc_set_ctrl_vals(priv, ctrl_values_offsets, ctrl_values,
+ ctrl_values_types, 4);
+ if (ret < 0)
+ return ret;
+ break;
+ default:
ret = aqc_set_ctrl_val(priv, priv->fan_ctrl_offsets[channel],
pwm_value, AQC_BE16);
if (ret < 0)
return ret;
+ break;
}
break;
default:
@@ -1287,6 +1340,7 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
priv->num_fans = AQUAERO_NUM_FANS;
priv->fan_sensor_offsets = aquaero_sensor_fan_offsets;
+ priv->fan_ctrl_offsets = aquaero_ctrl_fan_offsets;
priv->num_temp_sensors = AQUAERO_NUM_SENSORS;
priv->temp_sensor_start_offset = AQUAERO_SENSOR_START;