-
-
Save dominikpaulus/278886a1955397972bf2ecdd80d69b42 to your computer and use it in GitHub Desktop.
Kernel patch to support (rudimentary) fan control in the FTS Teutates kernel driver
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/drivers/hwmon/ftsteutates.c b/drivers/hwmon/ftsteutates.c | |
index a3a0766..49a7cd5 100644 | |
--- a/drivers/hwmon/ftsteutates.c | |
+++ b/drivers/hwmon/ftsteutates.c | |
@@ -79,6 +79,7 @@ struct fts_data { | |
u8 fan_present; | |
u8 fan_input[FTS_NO_FAN_SENSORS]; /* in rps */ | |
u8 fan_source[FTS_NO_FAN_SENSORS]; | |
+ u8 pwm_input[FTS_NO_FAN_SENSORS]; | |
u8 fan_alarm; | |
}; | |
@@ -86,6 +87,8 @@ struct fts_data { | |
#define FTS_REG_FAN_SOURCE(idx) ((idx) + 0x30) | |
#define FTS_REG_FAN_CONTROL(idx) (((idx) << 16) + 0x4881) | |
+#define FTS_REG_FAN_PWM(idx) (((idx) << 8) + 0x4886) | |
+ | |
#define FTS_REG_TEMP_INPUT(idx) ((idx) + 0x40) | |
#define FTS_REG_TEMP_CONTROL(idx) (((idx) << 16) + 0x0681) | |
@@ -184,9 +187,15 @@ static int fts_update_device(struct fts_data *data) | |
if (err < 0) | |
goto exit; | |
data->fan_source[i] = err; | |
+ | |
+ err = fts_read_byte(data->client, FTS_REG_FAN_PWM(i)); | |
+ if (err < 0) | |
+ goto exit; | |
+ data->pwm_input[i] = err; | |
} else { | |
data->fan_input[i] = 0; | |
data->fan_source[i] = FTS_FAN_SOURCE_INVALID; | |
+ data->pwm_input[i] = 0; | |
} | |
} | |
@@ -365,6 +374,14 @@ static umode_t fts_is_visible(const void *devdata, enum hwmon_sensor_types type, | |
} | |
break; | |
case hwmon_pwm: | |
+ switch (attr) { | |
+ case hwmon_pwm_enable: | |
+ case hwmon_pwm_input: | |
+ return 0644; | |
+ default: | |
+ break; | |
+ } | |
+ break; | |
case hwmon_in: | |
return 0444; | |
default: | |
@@ -423,6 +440,12 @@ static int fts_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, | |
break; | |
case hwmon_pwm: | |
switch (attr) { | |
+ case hwmon_pwm_input: | |
+ *val = data->pwm_input[channel]; | |
+ return 0; | |
+ case hwmon_pwm_enable: | |
+ *val = 1; | |
+ return 0; | |
case hwmon_pwm_auto_channels_temp: | |
if (data->fan_source[channel] == FTS_FAN_SOURCE_INVALID) | |
*val = 0; | |
@@ -484,6 +507,29 @@ static int fts_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, | |
break; | |
} | |
break; | |
+ case hwmon_pwm: | |
+ switch (attr) { | |
+ case hwmon_pwm_input: | |
+ if (val < 0 || val > 255) | |
+ return -EINVAL; | |
+ | |
+ mutex_lock(&data->update_lock); | |
+ ret = fts_write_byte(data->client, FTS_REG_FAN_PWM(channel), val); | |
+ if (ret >= 0) | |
+ data->valid = false; | |
+ | |
+ mutex_unlock(&data->update_lock); | |
+ | |
+ if (ret < 0) | |
+ return ret; | |
+ | |
+ return 0; | |
+ case hwmon_pwm_enable: | |
+ return 0; | |
+ default: | |
+ break; | |
+ } | |
+ break; | |
case hwmon_fan: | |
switch (attr) { | |
case hwmon_fan_alarm: | |
@@ -551,14 +597,14 @@ static const struct hwmon_channel_info * const fts_info[] = { | |
HWMON_F_INPUT | HWMON_F_ALARM | HWMON_F_FAULT | |
), | |
HWMON_CHANNEL_INFO(pwm, | |
- HWMON_PWM_AUTO_CHANNELS_TEMP, | |
- HWMON_PWM_AUTO_CHANNELS_TEMP, | |
- HWMON_PWM_AUTO_CHANNELS_TEMP, | |
- HWMON_PWM_AUTO_CHANNELS_TEMP, | |
- HWMON_PWM_AUTO_CHANNELS_TEMP, | |
- HWMON_PWM_AUTO_CHANNELS_TEMP, | |
- HWMON_PWM_AUTO_CHANNELS_TEMP, | |
- HWMON_PWM_AUTO_CHANNELS_TEMP | |
+ HWMON_PWM_INPUT | HWMON_PWM_ENABLE, | |
+ HWMON_PWM_INPUT | HWMON_PWM_ENABLE, | |
+ HWMON_PWM_INPUT | HWMON_PWM_ENABLE, | |
+ HWMON_PWM_INPUT | HWMON_PWM_ENABLE, | |
+ HWMON_PWM_INPUT | HWMON_PWM_ENABLE, | |
+ HWMON_PWM_INPUT | HWMON_PWM_ENABLE, | |
+ HWMON_PWM_INPUT | HWMON_PWM_ENABLE, | |
+ HWMON_PWM_INPUT | HWMON_PWM_ENABLE | |
), | |
HWMON_CHANNEL_INFO(in, | |
HWMON_I_INPUT, |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment