1 #include "i2cvr_software_manager.hpp" 2 3 #include "common/include/dbus_helper.hpp" 4 #include "common/include/software_manager.hpp" 5 #include "i2cvr_device.hpp" 6 #include "vr.hpp" 7 8 #include <phosphor-logging/lg2.hpp> 9 #include <sdbusplus/async.hpp> 10 #include <sdbusplus/bus.hpp> 11 #include <xyz/openbmc_project/ObjectMapper/client.hpp> 12 13 #include <cstdint> 14 15 PHOSPHOR_LOG2_USING; 16 17 namespace VR = phosphor::software::VR; 18 namespace I2CDevice = phosphor::software::i2c_vr::device; 19 namespace SoftwareInf = phosphor::software; 20 namespace ManagerInf = phosphor::software::manager; 21 22 const std::string configDBusName = "I2CVR"; 23 const std::vector<std::string> emConfigTypes = { 24 "XDPE1X2XXFirmware", "ISL69269Firmware", "MP2X6XXFirmware", 25 "MP297XFirmware", "RAA22XGen2Firmware"}; 26 27 I2CVRSoftwareManager::I2CVRSoftwareManager(sdbusplus::async::context& ctx) : 28 ManagerInf::SoftwareManager(ctx, configDBusName) 29 {} 30 31 void I2CVRSoftwareManager::start() 32 { 33 std::vector<std::string> configIntfs; 34 configIntfs.reserve(emConfigTypes.size()); 35 for (auto& name : emConfigTypes) 36 { 37 configIntfs.push_back("xyz.openbmc_project.Configuration." + name); 38 } 39 40 ctx.spawn(initDevices(configIntfs)); 41 ctx.run(); 42 } 43 44 sdbusplus::async::task<bool> I2CVRSoftwareManager::initDevice( 45 const std::string& service, const std::string& path, SoftwareConfig& config) 46 { 47 std::string configIface = 48 "xyz.openbmc_project.Configuration." + config.configType; 49 50 std::optional<uint64_t> busNum = co_await dbusGetRequiredProperty<uint64_t>( 51 ctx, service, path, configIface, "Bus"); 52 std::optional<uint64_t> address = 53 co_await dbusGetRequiredProperty<uint64_t>(ctx, service, path, 54 configIface, "Address"); 55 std::optional<std::string> vrChipType = 56 co_await dbusGetRequiredProperty<std::string>(ctx, service, path, 57 configIface, "Type"); 58 59 if (!busNum.has_value() || !address.has_value() || !vrChipType.has_value()) 60 { 61 error("missing config property"); 62 co_return false; 63 } 64 65 VR::VRType vrType; 66 if (!VR::stringToEnum(vrChipType.value(), vrType)) 67 { 68 error("unknown voltage regulator type: {TYPE}", "TYPE", 69 vrChipType.value()); 70 co_return false; 71 } 72 73 lg2::debug( 74 "[config] Voltage regulator device type: {TYPE} on Bus: {BUS} at Address: {ADDR}", 75 "TYPE", vrChipType.value(), "BUS", busNum.value(), "ADDR", 76 address.value()); 77 78 auto i2cDevice = std::make_unique<I2CDevice::I2CVRDevice>( 79 ctx, vrType, static_cast<uint16_t>(busNum.value()), 80 static_cast<uint16_t>(address.value()), config, this); 81 82 std::unique_ptr<SoftwareInf::Software> software = 83 std::make_unique<SoftwareInf::Software>(ctx, *i2cDevice); 84 85 uint32_t sum; 86 if (!(co_await i2cDevice->getVersion(&sum))) 87 { 88 error("unable to obtain Version/CRC from voltage regulator"); 89 co_return false; 90 } 91 92 software->setVersion(std::format("{:X}", sum), 93 SoftwareInf::SoftwareVersion::VersionPurpose::Other); 94 95 software->enableUpdate({RequestedApplyTimes::OnReset}); 96 97 i2cDevice->softwareCurrent = std::move(software); 98 99 devices.insert({config.objectPath, std::move(i2cDevice)}); 100 101 co_return true; 102 } 103 104 int main() 105 { 106 sdbusplus::async::context ctx; 107 108 I2CVRSoftwareManager i2cVRSoftwareManager(ctx); 109 110 i2cVRSoftwareManager.start(); 111 return 0; 112 } 113