staticint mp2891_read_byte_data(struct i2c_client *client, int page, int reg)
{ int ret;
switch (reg) { case PMBUS_VOUT_MODE: /* *TheMP2891doesnotfollowstandardPMBusprotocolcompletely,the *PMBUS_VOUT_MODE(0x20)inMP2891isreservedand0x00isalways *returnedwhentheregisterisread.Butthecalculationofvoutin *thisdriverisbasedondirectformat.Asaresult,theformatof *voutisenforcedtodirect.
*/
ret = PB_VOUT_MODE_DIRECT; break; default:
ret = -ENODATA; break;
}
return ret;
}
staticint mp2891_read_word_data(struct i2c_client *client, int page, int phase, int reg)
{ conststruct pmbus_driver_info *info = pmbus_get_driver_info(client); struct mp2891_data *data = to_mp2891_data(info); int ret;
switch (reg) { case PMBUS_READ_VIN:
ret = pmbus_read_word_data(client, page, phase, reg); if (ret < 0) return ret;
ret = ret & GENMASK(9, 0); break; case PMBUS_READ_IIN: /* *TheMP2891doesnothavestandardPMBUS_READ_IINregister(0x89), *theiintelemetrycanbeobtainedthroughthevenderredefined *registerREAD_IIN_EST(0x95).TheMP2891PMBUS_READ_IINregister *islinear11format,Butthepoutscaleissetto1A/Lsb(using *r/m/bscale).Asaresult,theiinreadfromMP2891shouldbe *calculatedtoA,thenreturntheresulttopmbuscore.
*/
ret = pmbus_read_word_data(client, page, phase, READ_IIN_EST); if (ret < 0) return ret;
ret = mp2891_reg2data_linear11(ret); break; case PMBUS_READ_PIN: /* *TheMP2891hasstandardPMBUS_READ_PINregister(0x97),butthis *isnotusedtoreadtheinputpowerperrail.Theinputpower *perrailisreadthroughthevenderredefinedregister *READ_PIN_EST(0x94).TheMP2891PMBUS_READ_PINregisterislinear11 *format,Butthepoutscaleissetto1W/Lsb(usingr/m/bscale). *Asaresult,thepinreadfromMP2891shouldbecalculatedtoW, *thenreturntheresulttopmbuscore.
*/
ret = pmbus_read_word_data(client, page, phase, READ_PIN_EST); if (ret < 0) return ret;
ret = mp2891_reg2data_linear11(ret); break; case PMBUS_READ_POUT: /* *TheMP2891PMBUS_READ_POUTregisterislinear11format,andthe *exponentisnotaconstantvalue.Butthepoutscaleissetto *1W/Lsb(usingr/m/bscale).Asaresult,thepoutreadfromMP2891 *shouldbecalculatedtoW,thenreturntheresulttopmbuscore.
*/
ret = pmbus_read_word_data(client, page, phase, reg); if (ret < 0) return ret;
ret = mp2891_reg2data_linear11(ret); break; case PMBUS_READ_VOUT: case PMBUS_VOUT_UV_WARN_LIMIT:
ret = pmbus_read_word_data(client, page, phase, reg); if (ret < 0) return ret;
ret = DIV_ROUND_CLOSEST(ret * data->vout_scale[page], MP2891_VOUT_SCALE_DIV); break; case PMBUS_READ_IOUT:
ret = pmbus_read_word_data(client, page, phase, reg); if (ret < 0) return ret;
ret = DIV_ROUND_CLOSEST((ret & GENMASK(10, 0)) * data->iout_scale[page],
MP2891_IOUT_SCALE_DIV); break; case PMBUS_OT_FAULT_LIMIT: case PMBUS_OT_WARN_LIMIT: /* *ThescaleofMP2891PMBUS_OT_FAULT_LIMITandPMBUS_OT_WARN_LIMIT *is1°C/LSBandtheyhave40°Coffset.
*/
ret = pmbus_read_word_data(client, page, phase, reg); if (ret < 0) return ret;
ret = (ret & GENMASK(7, 0)) - MP2891_TEMP_LIMIT_OFFSET; break; case PMBUS_VIN_OV_FAULT_LIMIT: /* *TheMP2891PMBUS_VIN_OV_FAULT_LIMITscaleis125mV/Lsb. *butthevinscaleissetto31.25mV/Lsb(usingr/m/bscale). *Asaresult,thelimitvalueshouldbemultipliedby4.
*/
ret = pmbus_read_word_data(client, page, phase, reg); if (ret < 0) return ret;
ret = (ret & GENMASK(7, 0)) * 4; break; case PMBUS_VOUT_UV_FAULT_LIMIT:
ret = pmbus_read_word_data(client, page, phase, reg); if (ret < 0) return ret;
if (FIELD_GET(GENMASK(11, 8), ret))
ret = FIELD_GET(GENMASK(7, 0), ret) * MP2891_UV_LIMIT_SCALE -
(FIELD_GET(GENMASK(11, 8), ret) + 1) * MP2891_OVUV_DELTA_SCALE; else
ret = FIELD_GET(GENMASK(7, 0), ret) * MP2891_UV_LIMIT_SCALE;
ret = ret < 0 ? 0 : ret; break; case PMBUS_VOUT_OV_FAULT_LIMIT:
ret = pmbus_read_word_data(client, page, phase, reg); if (ret < 0) return ret;
if (FIELD_GET(GENMASK(11, 8), ret))
ret = FIELD_GET(GENMASK(7, 0), ret) * MP2891_OV_LIMIT_SCALE +
(FIELD_GET(GENMASK(11, 8), ret) + 1) * MP2891_OVUV_DELTA_SCALE; else
ret = FIELD_GET(GENMASK(7, 0), ret) * MP2891_OV_LIMIT_SCALE; break; case PMBUS_IOUT_OC_WARN_LIMIT: case PMBUS_IOUT_OC_FAULT_LIMIT:
ret = pmbus_read_word_data(client, page, phase, reg); if (ret < 0) return ret;
ret = DIV_ROUND_CLOSEST((ret & GENMASK(7, 0)) * data->iout_scale[page] *
MP2891_IOUT_LIMIT_UINT, MP2891_IOUT_SCALE_DIV); break; case PMBUS_IIN_OC_WARN_LIMIT: /* *ThescaleofPMBUS_IIN_OC_WARN_LIMITis0.5A/Lsb,buttheiinscale *issetto1A/Lsb(usingr/m/bscale),sotheworddatashouldbe *dividedby2.
*/
ret = pmbus_read_word_data(client, 0, phase, reg); if (ret < 0) return ret;
ret = DIV_ROUND_CLOSEST((ret & GENMASK(9, 0)), 2); break; case PMBUS_PIN_OP_WARN_LIMIT: /* *ThescaleofPMBUS_PIN_OP_WARN_LIMITis2W/Lsb,butthepinscale *issetto1W/Lsb(usingr/m/bscale),sotheworddatashouldbe *multipliedby2.
*/
ret = pmbus_read_word_data(client, 0, phase, reg); if (ret < 0) return ret;
ret = (ret & GENMASK(9, 0)) * MP2891_PIN_LIMIT_UINT; break; case PMBUS_READ_TEMPERATURE_1: case PMBUS_VIN_UV_FAULT_LIMIT: case PMBUS_VIN_UV_WARN_LIMIT:
ret = -ENODATA; break; default:
ret = -EINVAL; break;
}
return ret;
}
staticint mp2891_write_word_data(struct i2c_client *client, int page, int reg,
u16 word)
{ conststruct pmbus_driver_info *info = pmbus_get_driver_info(client); struct mp2891_data *data = to_mp2891_data(info); int ret;
switch (reg) { case PMBUS_VOUT_UV_WARN_LIMIT:
ret = pmbus_write_word_data(client, page, reg,
DIV_ROUND_CLOSEST(word * MP2891_VOUT_SCALE_DIV,
data->vout_scale[page])); break; case PMBUS_VOUT_UV_FAULT_LIMIT: /* *ThePMBUS_VOUT_UV_FAULT_LIMIT[7:0]isthelimitvalue,andbit8-bit15 *shouldnotbechanged.
*/
ret = pmbus_read_word_data(client, page, 0xff, reg); if (ret < 0) return ret;
if (FIELD_GET(GENMASK(11, 8), ret))
ret = pmbus_write_word_data(client, page, reg,
(ret & ~GENMASK(7, 0)) |
FIELD_PREP(GENMASK(7, 0),
DIV_ROUND_CLOSEST(word +
(FIELD_GET(GENMASK(11, 8), ret) + 1) *
MP2891_OVUV_DELTA_SCALE,
MP2891_UV_LIMIT_SCALE))); else
ret = pmbus_write_word_data(client, page, reg,
(ret & ~GENMASK(7, 0)) |
FIELD_PREP(GENMASK(7, 0),
DIV_ROUND_CLOSEST(word,
MP2891_UV_LIMIT_SCALE))); break; case PMBUS_VOUT_OV_FAULT_LIMIT: /* *ThePMBUS_VOUT_OV_FAULT_LIMIT[7:0]isthelimitvalue,andbit8-bit15 *shouldnotbechanged.
*/
ret = pmbus_read_word_data(client, page, 0xff, reg); if (ret < 0) return ret;
MODULE_AUTHOR("Noah Wang <noahwang.wang@outlook.com>");
MODULE_DESCRIPTION("PMBus driver for MPS MP2891");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS("PMBUS");
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.19 Sekunden
(vorverarbeitet am 2026-09-29)
¤
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.