/* Once the lock bit is set, the virtual registers become read-only * until the next power cycle.
*/ if (data->control & SCH5627_CTRL_LOCK) return 0444;
switch (type) { case hwmon_temp: switch (attr) { case hwmon_temp_max: case hwmon_temp_crit: return 0644; default: break;
} break; case hwmon_fan: switch (attr) { case hwmon_fan_min: return 0644; default: break;
} break; case hwmon_pwm: switch (attr) { case hwmon_pwm_auto_channels_temp: return 0644; default: break;
} break; default: break;
}
return 0444;
}
staticint sch5627_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, long *val)
{ struct sch5627_data *data = dev_get_drvdata(dev); int ret, value;
switch (type) { case hwmon_temp: switch (attr) { case hwmon_temp_input:
ret = sch5627_update_temp(data); if (ret < 0) return ret;
*val = reg_to_temp(data->temp[channel]); return 0; case hwmon_temp_max:
ret = regmap_read(data->regmap, SCH5627_REG_TEMP_ABS[channel], &value); if (ret < 0) return ret;
*val = reg_to_temp_limit((u8)value); return 0; case hwmon_temp_crit:
ret = regmap_read(data->regmap, SCH5627_REG_TEMP_HIGH[channel], &value); if (ret < 0) return ret;
*val = reg_to_temp_limit((u8)value); return 0; case hwmon_temp_fault:
ret = sch5627_update_temp(data); if (ret < 0) return ret;
*val = (data->temp[channel] == 0); return 0; default: break;
} break; case hwmon_fan: switch (attr) { case hwmon_fan_input:
ret = sch5627_update_fan(data); if (ret < 0) return ret;
ret = reg_to_rpm(data->fan[channel]); if (ret < 0) return ret;
*val = ret; return 0; case hwmon_fan_min:
ret = sch56xx_regmap_read16(data->regmap, SCH5627_REG_FAN_MIN[channel],
&value); if (ret < 0) return ret;
ret = reg_to_rpm((u16)value); if (ret < 0) return ret;
*val = ret; return 0; case hwmon_fan_fault:
ret = sch5627_update_fan(data); if (ret < 0) return ret;
*val = (data->fan[channel] == 0xffff); return 0; default: break;
} break; case hwmon_pwm: switch (attr) { case hwmon_pwm_auto_channels_temp:
ret = regmap_read(data->regmap, SCH5627_REG_PWM_MAP[channel], &value); if (ret < 0) return ret;
*val = value; return 0; default: break;
} break; case hwmon_in:
ret = sch5627_update_in(data); if (ret < 0) return ret; switch (attr) { case hwmon_in_input:
*val = DIV_ROUND_CLOSEST(data->in[channel] * SCH5627_REG_IN_FACTOR[channel],
10000); return 0; default: break;
} break; default: break;
}
build_code = sch56xx_read_virtual_reg(data->addr,
SCH5627_REG_BUILD_CODE); if (build_code < 0) return build_code;
build_id = sch56xx_read_virtual_reg16(data->addr,
SCH5627_REG_BUILD_ID); if (build_id < 0) return build_id;
hwmon_rev = sch56xx_read_virtual_reg(data->addr,
SCH5627_REG_HWMON_REV); if (hwmon_rev < 0) return hwmon_rev;
val = sch56xx_read_virtual_reg(data->addr, SCH5627_REG_CTRL); if (val < 0) return val;
data->control = val; if (!(data->control & SCH5627_CTRL_START)) {
pr_err("hardware monitoring not enabled\n"); return -ENODEV;
}
data->regmap = devm_regmap_init_sch56xx(&pdev->dev, &data->update_lock, data->addr,
&sch5627_regmap_config); if (IS_ERR(data->regmap)) return PTR_ERR(data->regmap);
/* Trigger a Vbat voltage measurement, so that we get a valid reading
the first time we read Vbat */
sch56xx_write_virtual_reg(data->addr, SCH5627_REG_CTRL, data->control | SCH5627_CTRL_VBAT);
data->last_battery = jiffies;
pr_info("found %s chip at %#hx\n", DEVNAME, data->addr);
pr_info("firmware build: code 0x%02X, id 0x%04X, hwmon: rev 0x%02X\n",
build_code, build_id, hwmon_rev);
regcache_cache_only(data->regmap, false); /* We must not access the virtual registers when the lock bit is set */ if (data->control & SCH5627_CTRL_LOCK) return regcache_drop_region(data->regmap, 0, U16_MAX);
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.