17e446a40SChristopher Meis #include "i2cvr_software_manager.hpp" 27e446a40SChristopher Meis 37e446a40SChristopher Meis #include "common/include/dbus_helper.hpp" 47e446a40SChristopher Meis #include "common/include/software_manager.hpp" 57e446a40SChristopher Meis #include "i2cvr_device.hpp" 67e446a40SChristopher Meis #include "vr.hpp" 77e446a40SChristopher Meis 87e446a40SChristopher Meis #include <phosphor-logging/lg2.hpp> 97e446a40SChristopher Meis #include <sdbusplus/async.hpp> 107e446a40SChristopher Meis #include <sdbusplus/bus.hpp> 117e446a40SChristopher Meis #include <xyz/openbmc_project/ObjectMapper/client.hpp> 127e446a40SChristopher Meis 137e446a40SChristopher Meis #include <cstdint> 147e446a40SChristopher Meis 157e446a40SChristopher Meis PHOSPHOR_LOG2_USING; 167e446a40SChristopher Meis 177e446a40SChristopher Meis namespace VR = phosphor::software::VR; 187e446a40SChristopher Meis namespace I2CDevice = phosphor::software::i2c_vr::device; 197e446a40SChristopher Meis namespace SoftwareInf = phosphor::software; 207e446a40SChristopher Meis namespace ManagerInf = phosphor::software::manager; 217e446a40SChristopher Meis 227e446a40SChristopher Meis const std::string configDBusName = "I2CVR"; 23*dcf4b607SKevin Tung const std::vector<std::string> emConfigTypes = { 24*dcf4b607SKevin Tung "XDPE1X2XXFirmware", "ISL69269Firmware", "MP2X6XXFirmware"}; 257e446a40SChristopher Meis 267e446a40SChristopher Meis I2CVRSoftwareManager::I2CVRSoftwareManager(sdbusplus::async::context& ctx) : 277e446a40SChristopher Meis ManagerInf::SoftwareManager(ctx, configDBusName) 287e446a40SChristopher Meis {} 297e446a40SChristopher Meis 307e446a40SChristopher Meis void I2CVRSoftwareManager::start() 317e446a40SChristopher Meis { 327e446a40SChristopher Meis std::vector<std::string> configIntfs; 337e446a40SChristopher Meis configIntfs.reserve(emConfigTypes.size()); 347e446a40SChristopher Meis for (auto& name : emConfigTypes) 357e446a40SChristopher Meis { 367e446a40SChristopher Meis configIntfs.push_back("xyz.openbmc_project.Configuration." + name); 377e446a40SChristopher Meis } 387e446a40SChristopher Meis 397e446a40SChristopher Meis ctx.spawn(initDevices(configIntfs)); 407e446a40SChristopher Meis ctx.run(); 417e446a40SChristopher Meis } 427e446a40SChristopher Meis 437e446a40SChristopher Meis sdbusplus::async::task<bool> I2CVRSoftwareManager::initDevice( 447e446a40SChristopher Meis const std::string& service, const std::string& path, SoftwareConfig& config) 457e446a40SChristopher Meis { 467e446a40SChristopher Meis std::string configIface = 477e446a40SChristopher Meis "xyz.openbmc_project.Configuration." + config.configType; 487e446a40SChristopher Meis 497e446a40SChristopher Meis std::optional<uint64_t> busNum = co_await dbusGetRequiredProperty<uint64_t>( 507e446a40SChristopher Meis ctx, service, path, configIface, "Bus"); 517e446a40SChristopher Meis std::optional<uint64_t> address = 527e446a40SChristopher Meis co_await dbusGetRequiredProperty<uint64_t>(ctx, service, path, 537e446a40SChristopher Meis configIface, "Address"); 547e446a40SChristopher Meis std::optional<std::string> vrChipType = 557e446a40SChristopher Meis co_await dbusGetRequiredProperty<std::string>(ctx, service, path, 567e446a40SChristopher Meis configIface, "Type"); 577e446a40SChristopher Meis 587e446a40SChristopher Meis if (!busNum.has_value() || !address.has_value() || !vrChipType.has_value()) 597e446a40SChristopher Meis { 607e446a40SChristopher Meis error("missing config property"); 617e446a40SChristopher Meis co_return false; 627e446a40SChristopher Meis } 637e446a40SChristopher Meis 647e446a40SChristopher Meis VR::VRType vrType; 657e446a40SChristopher Meis if (!VR::stringToEnum(vrChipType.value(), vrType)) 667e446a40SChristopher Meis { 677e446a40SChristopher Meis error("unknown voltage regulator type: {TYPE}", "TYPE", 687e446a40SChristopher Meis vrChipType.value()); 697e446a40SChristopher Meis co_return false; 707e446a40SChristopher Meis } 717e446a40SChristopher Meis 727e446a40SChristopher Meis lg2::debug( 737e446a40SChristopher Meis "[config] Voltage regulator device type: {TYPE} on Bus: {BUS} at Address: {ADDR}", 747e446a40SChristopher Meis "TYPE", vrChipType.value(), "BUS", busNum.value(), "ADDR", 757e446a40SChristopher Meis address.value()); 767e446a40SChristopher Meis 777e446a40SChristopher Meis auto i2cDevice = std::make_unique<I2CDevice::I2CVRDevice>( 787e446a40SChristopher Meis ctx, vrType, static_cast<uint16_t>(busNum.value()), 797e446a40SChristopher Meis static_cast<uint16_t>(address.value()), config, this); 807e446a40SChristopher Meis 817e446a40SChristopher Meis std::unique_ptr<SoftwareInf::Software> software = 827e446a40SChristopher Meis std::make_unique<SoftwareInf::Software>(ctx, *i2cDevice); 837e446a40SChristopher Meis 847e446a40SChristopher Meis uint32_t sum; 857e446a40SChristopher Meis if (!(co_await i2cDevice->getVersion(&sum))) 867e446a40SChristopher Meis { 877e446a40SChristopher Meis error("unable to obtain Version/CRC from voltage regulator"); 887e446a40SChristopher Meis co_return false; 897e446a40SChristopher Meis } 907e446a40SChristopher Meis 912e168dbaSDaniel Hsu software->setVersion(std::format("{:X}", sum), 922e168dbaSDaniel Hsu SoftwareInf::SoftwareVersion::VersionPurpose::Other); 937e446a40SChristopher Meis 94ee551174SKevin Tung software->enableUpdate({RequestedApplyTimes::OnReset}); 957e446a40SChristopher Meis 967e446a40SChristopher Meis i2cDevice->softwareCurrent = std::move(software); 977e446a40SChristopher Meis 987e446a40SChristopher Meis devices.insert({config.objectPath, std::move(i2cDevice)}); 997e446a40SChristopher Meis 1007e446a40SChristopher Meis co_return true; 1017e446a40SChristopher Meis } 1027e446a40SChristopher Meis 1037e446a40SChristopher Meis int main() 1047e446a40SChristopher Meis { 1057e446a40SChristopher Meis sdbusplus::async::context ctx; 1067e446a40SChristopher Meis 1077e446a40SChristopher Meis I2CVRSoftwareManager i2cVRSoftwareManager(ctx); 1087e446a40SChristopher Meis 1097e446a40SChristopher Meis i2cVRSoftwareManager.start(); 1107e446a40SChristopher Meis return 0; 1117e446a40SChristopher Meis } 112