Message ID | 20250313-extend_ec_hwmon_fan-v1-1-5c566776f2c4@chromium.org (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | Export the target RPM fan control by ChromeOS EC under hwmon | expand |
On 2025-03-13 12:47:42+0800, Sung-Chi Li wrote: > Implement the functionality of setting the target fan RPM to ChromeOS > embedded controller under hwmon framework. > > Signed-off-by: Sung-Chi Li <lschyi@chromium.org> > --- > drivers/hwmon/cros_ec_hwmon.c | 34 ++++++++++++++++++++++++++++++++++ > 1 file changed, 34 insertions(+) > > diff --git a/drivers/hwmon/cros_ec_hwmon.c b/drivers/hwmon/cros_ec_hwmon.c > index 9991c3fa020ac859cbbff29dfb669e53248df885..b2fec0768301f116f49c57b8dbfb042b98a573e1 100644 > --- a/drivers/hwmon/cros_ec_hwmon.c > +++ b/drivers/hwmon/cros_ec_hwmon.c > @@ -52,6 +52,26 @@ static int cros_ec_hwmon_read_temp(struct cros_ec_device *cros_ec, u8 index, u8 > return 0; > } > > +static int cros_ec_hwmon_set_fan_rpm(struct cros_ec_device *cros_ec, u8 index, u16 val) > +{ > + struct ec_params_pwm_set_fan_target_rpm_v1 p_v1 = { The v1 protocol was "only" introduces in 2014. Could it be possible that devices without that command are still in use? If so the presence of the command should be probed. What is the name p_v1 supposed to mean? Call it "req", like other parts of the driver. > + .rpm = val, > + .fan_idx = index, > + }; > + > + return cros_ec_cmd(cros_ec, 1, EC_CMD_PWM_SET_FAN_TARGET_RPM, &p_v1, sizeof(p_v1), NULL, 0); cros_ec_cmd() signals success with an exitcode >= 0, while the hwmon APIs only expect 0. In this specific case the success value will also always be zero, as no response is sent by the EC, but for clarity I prefer to have an explicit check. > +} > + > +static int cros_ec_hwmon_write_fan(struct cros_ec_device *cros_ec, u32 attr, int channel, long rpm) > +{ > + switch (attr) { > + case hwmon_fan_target: > + return cros_ec_hwmon_set_fan_rpm(cros_ec, channel, rpm); > + default: > + return -EOPNOTSUPP; > + } > +} > + > static bool cros_ec_hwmon_is_error_fan(u16 speed) > { > return speed == EC_FAN_SPEED_NOT_PRESENT || speed == EC_FAN_SPEED_STALLED; > @@ -140,6 +160,19 @@ static umode_t cros_ec_hwmon_is_visible(const void *data, enum hwmon_sensor_type > return 0; > } > > +static int cros_ec_hwmon_write(struct device *dev, enum hwmon_sensor_types type, > + u32 attr, int channel, long val) > +{ > + struct cros_ec_hwmon_priv *priv = dev_get_drvdata(dev); > + > + switch (type) { > + case hwmon_fan: > + return cros_ec_hwmon_write_fan(priv->cros_ec, attr, channel, val); > + default: > + return -EOPNOTSUPP; > + } > +} > + > static const struct hwmon_channel_info * const cros_ec_hwmon_info[] = { > HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ), > HWMON_CHANNEL_INFO(fan, > @@ -179,6 +212,7 @@ static const struct hwmon_ops cros_ec_hwmon_ops = { > .read = cros_ec_hwmon_read, > .read_string = cros_ec_hwmon_read_string, > .is_visible = cros_ec_hwmon_is_visible, > + .write = cros_ec_hwmon_write, Move the .write directly after .read_string. > }; > > static const struct hwmon_chip_info cros_ec_hwmon_chip_info = { > > -- > 2.49.0.rc0.332.g42c0ae87b1-goog >
diff --git a/drivers/hwmon/cros_ec_hwmon.c b/drivers/hwmon/cros_ec_hwmon.c index 9991c3fa020ac859cbbff29dfb669e53248df885..b2fec0768301f116f49c57b8dbfb042b98a573e1 100644 --- a/drivers/hwmon/cros_ec_hwmon.c +++ b/drivers/hwmon/cros_ec_hwmon.c @@ -52,6 +52,26 @@ static int cros_ec_hwmon_read_temp(struct cros_ec_device *cros_ec, u8 index, u8 return 0; } +static int cros_ec_hwmon_set_fan_rpm(struct cros_ec_device *cros_ec, u8 index, u16 val) +{ + struct ec_params_pwm_set_fan_target_rpm_v1 p_v1 = { + .rpm = val, + .fan_idx = index, + }; + + return cros_ec_cmd(cros_ec, 1, EC_CMD_PWM_SET_FAN_TARGET_RPM, &p_v1, sizeof(p_v1), NULL, 0); +} + +static int cros_ec_hwmon_write_fan(struct cros_ec_device *cros_ec, u32 attr, int channel, long rpm) +{ + switch (attr) { + case hwmon_fan_target: + return cros_ec_hwmon_set_fan_rpm(cros_ec, channel, rpm); + default: + return -EOPNOTSUPP; + } +} + static bool cros_ec_hwmon_is_error_fan(u16 speed) { return speed == EC_FAN_SPEED_NOT_PRESENT || speed == EC_FAN_SPEED_STALLED; @@ -140,6 +160,19 @@ static umode_t cros_ec_hwmon_is_visible(const void *data, enum hwmon_sensor_type return 0; } +static int cros_ec_hwmon_write(struct device *dev, enum hwmon_sensor_types type, + u32 attr, int channel, long val) +{ + struct cros_ec_hwmon_priv *priv = dev_get_drvdata(dev); + + switch (type) { + case hwmon_fan: + return cros_ec_hwmon_write_fan(priv->cros_ec, attr, channel, val); + default: + return -EOPNOTSUPP; + } +} + static const struct hwmon_channel_info * const cros_ec_hwmon_info[] = { HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ), HWMON_CHANNEL_INFO(fan, @@ -179,6 +212,7 @@ static const struct hwmon_ops cros_ec_hwmon_ops = { .read = cros_ec_hwmon_read, .read_string = cros_ec_hwmon_read_string, .is_visible = cros_ec_hwmon_is_visible, + .write = cros_ec_hwmon_write, }; static const struct hwmon_chip_info cros_ec_hwmon_chip_info = {
Implement the functionality of setting the target fan RPM to ChromeOS embedded controller under hwmon framework. Signed-off-by: Sung-Chi Li <lschyi@chromium.org> --- drivers/hwmon/cros_ec_hwmon.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+)