/* poll the fan rpm */
ret = qnap_mcu_exec(hwm->mcu, cmd, sizeof(cmd), reply, sizeof(reply)); if (ret) return ret;
/* First bytes must mirror the sent command */ if (memcmp(cmd, reply, sizeof(cmd))) return -EIO;
/* * There is an unknown bit set in bit7. * Bits [6:0] report the actual temperature as returned by the * original qnap firmware-tools, so just drop bit7 for now.
*/ return (reply[3] & 0x7f) * 1000;
}
staticint qnap_mcu_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
u32 attr, int channel, long val)
{ struct qnap_mcu_hwmon *hwm = dev_get_drvdata(dev);
switch (attr) { case hwmon_pwm_input: if (val < 0 || val > 255) return -EINVAL;
if (val != 0)
val = clamp_val(val, hwm->pwm_min, hwm->pwm_max);
staticint qnap_mcu_hwmon_get_cooling_data(struct device *dev, struct qnap_mcu_hwmon *hwm)
{ struct fwnode_handle *fwnode; int num, i, ret;
fwnode = device_get_named_child_node(dev->parent, "fan-0"); if (!fwnode) return 0;
/* if we found the fan-node, we're keeping it until device-unbind */
hwm->fan_node = fwnode;
ret = devm_add_action_or_reset(dev, devm_fan_node_release, hwm); if (ret) return ret;
num = fwnode_property_count_u32(fwnode, "cooling-levels"); if (num <= 0) return dev_err_probe(dev, num ? : -EINVAL, "Failed to count elements in 'cooling-levels'\n");
hwm->fan_cooling_levels = devm_kcalloc(dev, num, sizeof(u32),
GFP_KERNEL); if (!hwm->fan_cooling_levels) return -ENOMEM;
ret = fwnode_property_read_u32_array(fwnode, "cooling-levels",
hwm->fan_cooling_levels, num); if (ret) return dev_err_probe(dev, ret, "Failed to read 'cooling-levels'\n");
for (i = 0; i < num; i++) { if (hwm->fan_cooling_levels[i] > hwm->pwm_max) return dev_err_probe(dev, -EINVAL, "fan state[%d]:%d > %d\n", i,
hwm->fan_cooling_levels[i], hwm->pwm_max);
}
ret = qnap_mcu_hwmon_get_cooling_data(dev, hwm); if (ret) return ret;
hwm->fan_state = hwm->fan_max_state;
hwmon = devm_hwmon_device_register_with_info(dev, "qnapmcu",
hwm, &hwm->info, NULL); if (IS_ERR(hwmon)) return dev_err_probe(dev, PTR_ERR(hwmon), "Failed to register hwmon device\n");
/* * Only register cooling device when we found cooling-levels. * qnap_mcu_hwmon_get_cooling_data() will fail when reading malformed * levels and only succeed with either no or correct cooling levels.
*/ if (IS_ENABLED(CONFIG_THERMAL) && hwm->fan_cooling_levels) {
cdev = devm_thermal_of_cooling_device_register(dev,
to_of_node(hwm->fan_node), "qnap-mcu-hwmon",
hwm, &qnap_mcu_hwmon_cooling_ops); if (IS_ERR(cdev)) return dev_err_probe(dev, PTR_ERR(cdev), "Failed to register qnap-mcu-hwmon as cooling device\n");
hwm->cdev = cdev;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.