channels, the value matches the value of the primary channel.
fan[1-12]_input RO fan tachometer speed in RPM
fan[1-12]_fault RO fan experienced fault
+fan[1-12]_min RW minimum fan speed in RPM. Equivalent to target fan speed
+ in PWM mode and if PWM support is disabled for a channel.
+ Equivalent to half the target fan speed in RPM mode.
+ The value is RO for companion channels (7-12). For those
+ channels, the value matches the value of the primary channel.
+ Note: In RPM mode, if the pwm duty cycle is 100%, the
+ minimum fan speed is equivalent to the target fan speed,
+ and the chip will report a fault condition if the fan
+ speed is below the target fan speed.
fan[1-6]_target RW desired fan speed in RPM
pwm[1-6]_enable RW regulator mode, 0=disabled (duty cycle=0%), 1=manual mode, 2=rpm mode
pwm[1-6] RW read: current pwm duty cycle,
if (rv < 0)
goto abort;
data->pwm[i] = rv;
-
- rv = i2c_smbus_read_word_swapped(client,
- MAX31790_REG_TARGET_COUNT(i));
- if (rv < 0)
- goto abort;
- data->target_count[i] = rv;
}
+ rv = i2c_smbus_read_word_swapped(client, MAX31790_REG_TARGET_COUNT(i));
+ if (rv < 0)
+ goto abort;
+ data->target_count[i] = rv;
}
data->last_updated = jiffies;
rpm = RPM_FROM_REG(data->tach[channel], sr);
*val = rpm;
return 0;
+ case hwmon_fan_min:
+ channel %= NR_CHANNEL;
+ sr = get_tach_period(data->fan_dynamics[channel]);
+ if (!(data->fan_config[channel] & MAX31790_FAN_CFG_RPM_MODE) ||
+ (data->fan_config[channel] & MAX31790_FAN_CFG_TACH_INPUT)) {
+ /* pwm mode: target == min */
+ rpm = RPM_FROM_REG(data->target_count[channel], sr);
+ } else {
+ /* rpm mode: min tach count is twice target count */
+ u16 tach = min(data->target_count[channel] * 2, FAN_COUNT_REG_MAX);
+
+ rpm = RPM_FROM_REG(tach, sr);
+ }
+ *val = rpm;
+ return 0;
case hwmon_fan_target:
sr = get_tach_period(data->fan_dynamics[channel]);
rpm = RPM_FROM_REG(data->target_count[channel], sr);
data->fan_config[channel] = config;
}
break;
+ case hwmon_fan_min:
+ /*
+ * The minimum fan speed is the same as the target fan speed in
+ * PWM mode and if a PWM channel is disabled, or it is half the
+ * target fan speed in RPM mode.
+ */
+ if (!(data->fan_config[channel] & MAX31790_FAN_CFG_TACH_INPUT) &&
+ (data->fan_config[channel] & MAX31790_FAN_CFG_RPM_MODE)) {
+ /* partial clamp to avoid overflow */
+ if (val > FAN_RPM_MAX / 2)
+ val = FAN_RPM_MAX / 2;
+ val *= 2;
+ }
+ fallthrough;
case hwmon_fan_target:
val = clamp_val(val, FAN_RPM_MIN, FAN_RPM_MAX);
bits = bits_for_tach_period(val);
u8 fan_config = data->fan_config[channel % NR_CHANNEL];
switch (attr) {
+ case hwmon_fan_min:
case hwmon_fan_enable:
if (channel < NR_CHANNEL)
return 0644;
static const struct hwmon_channel_info *max31790_info[] = {
HWMON_CHANNEL_INFO(fan,
- HWMON_F_ENABLE | HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_FAULT,
- HWMON_F_ENABLE | HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_FAULT,
- HWMON_F_ENABLE | HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_FAULT,
- HWMON_F_ENABLE | HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_FAULT,
- HWMON_F_ENABLE | HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_FAULT,
- HWMON_F_ENABLE | HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_FAULT,
- HWMON_F_ENABLE | HWMON_F_INPUT | HWMON_F_FAULT,
- HWMON_F_ENABLE | HWMON_F_INPUT | HWMON_F_FAULT,
- HWMON_F_ENABLE | HWMON_F_INPUT | HWMON_F_FAULT,
- HWMON_F_ENABLE | HWMON_F_INPUT | HWMON_F_FAULT,
- HWMON_F_ENABLE | HWMON_F_INPUT | HWMON_F_FAULT,
- HWMON_F_ENABLE | HWMON_F_INPUT | HWMON_F_FAULT),
+ HWMON_F_ENABLE | HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_TARGET |
+ HWMON_F_FAULT,
+ HWMON_F_ENABLE | HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_TARGET |
+ HWMON_F_FAULT,
+ HWMON_F_ENABLE | HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_TARGET |
+ HWMON_F_FAULT,
+ HWMON_F_ENABLE | HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_TARGET |
+ HWMON_F_FAULT,
+ HWMON_F_ENABLE | HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_TARGET |
+ HWMON_F_FAULT,
+ HWMON_F_ENABLE | HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_TARGET |
+ HWMON_F_FAULT,
+ HWMON_F_ENABLE | HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_FAULT,
+ HWMON_F_ENABLE | HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_FAULT,
+ HWMON_F_ENABLE | HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_FAULT,
+ HWMON_F_ENABLE | HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_FAULT,
+ HWMON_F_ENABLE | HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_FAULT,
+ HWMON_F_ENABLE | HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_FAULT),
HWMON_CHANNEL_INFO(pwm,
HWMON_PWM_INPUT | HWMON_PWM_ENABLE,
HWMON_PWM_INPUT | HWMON_PWM_ENABLE,