diff --git a/i2c-vr/mps/mp994x.cpp b/i2c-vr/mps/mp994x.cpp
new file mode 100644
index 0000000..6342001
--- /dev/null
+++ b/i2c-vr/mps/mp994x.cpp
@@ -0,0 +1,544 @@
+#include "mp994x.hpp"
+
+#include "common/include/utils.hpp"
+
+#include <phosphor-logging/lg2.hpp>
+
+PHOSPHOR_LOG2_USING;
+
+namespace phosphor::software::VR
+{
+
+static constexpr std::string_view vendorIdRegName = "VENDOR_ID_VR";
+static constexpr std::string_view mfrDeviceIDCFGRegName = "MFR_DEVICE_ID_CFG";
+static constexpr std::string_view crcUserMultiRegName = "CRC_USER_MULTI";
+
+static constexpr uint8_t pageMask = 0x0F;
+
+enum class MP994XCmd : uint8_t
+{
+    // Page 0 commands
+    storeUserAll = 0x15,
+    userData08 = 0xB8,
+
+    // Page 2 commands
+    mfrMulconfigSel = 0xAB,
+    configId = 0xAF,
+    mfrNVMPmbusCtrl = 0xCA,
+    mfrDebug = 0xD4,
+    deviceId = 0xDB,
+
+    // Page 5 commands
+    vendorId = 0xBA,
+
+    // Page 7 commands
+    storeFaultTrigger = 0x51,
+};
+
+sdbusplus::async::task<bool> MP994X::parseDeviceConfiguration()
+{
+    if (!configuration)
+    {
+        error("Device configuration not initialized");
+        co_return false;
+    }
+
+    for (const auto& tokens : parser->lineTokens)
+    {
+        if (!parser->isValidDataTokens(tokens))
+        {
+            continue;
+        }
+
+        auto regName = parser->getVal<std::string>(tokens, ATE::regName);
+
+        if (regName == vendorIdRegName)
+        {
+            configuration->vendorId =
+                parser->getVal<uint32_t>(tokens, ATE::regDataHex);
+            configuration->configId =
+                parser->getVal<uint32_t>(tokens, ATE::configId);
+        }
+        else if (regName == mfrDeviceIDCFGRegName)
+        {
+            configuration->productId =
+                parser->getVal<uint32_t>(tokens, ATE::regDataHex);
+        }
+        else if (regName == crcUserMultiRegName)
+        {
+            configuration->crcMulti =
+                parser->getVal<uint32_t>(tokens, ATE::regDataHex);
+            break;
+        }
+    }
+
+    co_return true;
+}
+
+sdbusplus::async::task<bool> MP994X::verifyImage(const uint8_t* image,
+                                                 size_t imageSize)
+{
+    if (!co_await parseImage(image, imageSize, MPSImageType::type1))
+    {
+        error("Image verification failed: image parsing failed");
+        co_return false;
+    }
+
+    if (configuration->registersData.empty())
+    {
+        error("Image verification failed: no data found");
+        co_return false;
+    }
+
+    if (configuration->vendorId == 0 || configuration->productId == 0 ||
+        configuration->configId == 0)
+    {
+        error("Image verification failed: missing required field "
+              "vendor ID, product ID, or config ID");
+        co_return false;
+    }
+
+    co_return true;
+}
+
+sdbusplus::async::task<bool> MP994X::checkId(MP994XCmd idCmd, uint32_t expected)
+{
+    static constexpr size_t vendorIdLength = 2;
+    static constexpr size_t productIdLength = 1;
+    static constexpr size_t configIdLength = 2;
+
+    MPSPage page;
+    size_t idLen = 0;
+    const uint8_t cmd = static_cast<uint8_t>(idCmd);
+
+    switch (idCmd)
+    {
+        case MP994XCmd::vendorId:
+            page = MPSPage::page5;
+            idLen = vendorIdLength;
+            break;
+        case MP994XCmd::deviceId:
+            page = MPSPage::page2;
+            idLen = productIdLength;
+            break;
+        case MP994XCmd::configId:
+            page = MPSPage::page2;
+            idLen = configIdLength;
+            break;
+        default:
+            error("Invalid command for ID check: {CMD}", "CMD", lg2::hex, cmd);
+            co_return false;
+    }
+
+    std::vector<uint8_t> tbuf;
+    std::vector<uint8_t> rbuf;
+
+    tbuf = buildByteVector(PMBusCmd::page, page);
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to set page for ID check");
+        co_return false;
+    }
+
+    tbuf = buildByteVector(idCmd);
+    rbuf.resize(idLen);
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to read ID, cmd={CMD}", "CMD", lg2::hex, cmd);
+        co_return false;
+    }
+
+    auto id = bytesToInt<uint32_t>(rbuf);
+
+    if (id != expected)
+    {
+        error("ID check failed for cmd {CMD}: got {ID}, expected {EXP}", "CMD",
+              lg2::hex, cmd, "ID", lg2::hex, id, "EXP", lg2::hex, expected);
+        co_return false;
+    }
+
+    co_return true;
+}
+
+sdbusplus::async::task<bool> MP994X::unlockWriteProtect()
+{
+    static constexpr uint8_t unlockWriteProtectData = 0x00;
+
+    std::vector<uint8_t> tbuf;
+    std::vector<uint8_t> rbuf;
+
+    tbuf = buildByteVector(PMBusCmd::page, MPSPage::page0);
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to set page 0 to unlock write protection mode");
+        co_return false;
+    }
+
+    tbuf = buildByteVector(PMBusCmd::writeProtect, unlockWriteProtectData);
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to unlock write protect mode");
+        co_return false;
+    }
+
+    debug("Write protection unlocked");
+    co_return true;
+}
+
+sdbusplus::async::task<bool> MP994X::disableStoreFaultTriggering()
+{
+    static constexpr size_t mfrDebugDataLength = 2;
+    static constexpr uint16_t enableEnteringPage7Mask = 0x8000;
+    static constexpr uint16_t disableStoreFaultTriggeringData = 0x1000;
+
+    std::vector<uint8_t> tbuf;
+    std::vector<uint8_t> rbuf;
+
+    // enable entering page 7
+    tbuf = buildByteVector(PMBusCmd::page, MPSPage::page2);
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to set page 2 to enable entering page 7");
+        co_return false;
+    }
+
+    tbuf = buildByteVector(MP994XCmd::mfrDebug);
+    rbuf.resize(mfrDebugDataLength);
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to read MFR Debug register to enable entering 7");
+        co_return false;
+    }
+
+    uint16_t data = (rbuf[1] << 8) | rbuf[0] | enableEnteringPage7Mask;
+    tbuf = buildByteVector(MP994XCmd::mfrDebug, data);
+    rbuf.clear();
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to enable entering page 7");
+        co_return false;
+    }
+
+    // disable store fault triggering
+    tbuf = buildByteVector(PMBusCmd::page, MPSPage::page7);
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to set page 7 to disable store fault triggering");
+        co_return false;
+    }
+
+    tbuf = buildByteVector(MP994XCmd::storeFaultTrigger,
+                           disableStoreFaultTriggeringData);
+    rbuf.clear();
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to disable store fault triggering");
+        co_return false;
+    }
+
+    debug("Disabled store fault triggerring");
+
+    co_return true;
+}
+
+sdbusplus::async::task<bool> MP994X::setMultiConfigAddress(uint8_t config)
+{
+    // MPS994X: Select multi-configuration address
+    // Write to Page 2 @ 0xAB:
+    //   - Bit[3] = MFR_MULCONFIG_SEL (1 = enable)
+    //   - Bit[2:0] = MFR_MULCONFIG_ADDR (0 ~ 7 → selects one of 8 configs)
+    // Resulting values for config set 1 ~ 8: 0x08 ~ 0x0F
+
+    auto addr = config - 1;
+
+    static constexpr uint8_t maxMultiConfigAddr = 7;
+    static constexpr uint8_t enableMultiConfigAddrSel = 0x08;
+
+    if (addr > maxMultiConfigAddr)
+    {
+        error("Invalid multi config address: {ADDR}", "ADDR", addr);
+    }
+
+    std::vector<uint8_t> tbuf;
+    std::vector<uint8_t> rbuf;
+
+    tbuf = buildByteVector(PMBusCmd::page, MPSPage::page2);
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to set page 2 to set multi config address");
+        co_return false;
+    }
+
+    uint8_t selectAddrData = enableMultiConfigAddrSel + addr;
+    tbuf = buildByteVector(MP994XCmd::mfrMulconfigSel, selectAddrData);
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to write {DATA} to multi config select register {REG}",
+              "DATA", lg2::hex, selectAddrData, "REG", lg2::hex,
+              static_cast<uint8_t>(MP994XCmd::mfrMulconfigSel));
+        co_return false;
+    }
+
+    debug("Selected multi config set address {ADDR}", "ADDR", addr);
+    co_return true;
+}
+
+sdbusplus::async::task<bool> MP994X::programConfigData(
+    const std::vector<MPSData>& gdata)
+{
+    std::vector<uint8_t> tbuf;
+    std::vector<uint8_t> rbuf;
+
+    for (const auto& data : gdata)
+    {
+        uint8_t page = data.page & pageMask;
+
+        tbuf = buildByteVector(PMBusCmd::page, page);
+        if (!i2cInterface.sendReceive(tbuf, rbuf))
+        {
+            error("Failed to set page {PAGE} for register {REG}", "PAGE", page,
+                  "REG", lg2::hex, data.addr);
+            co_return false;
+        }
+
+        tbuf = {data.addr};
+        tbuf.insert(tbuf.end(), data.data.begin(),
+                    data.data.begin() + data.length);
+
+        if (!i2cInterface.sendReceive(tbuf, rbuf))
+        {
+            error(
+                "Failed to write data {DATA} to register {REG} on page {PAGE}",
+                "DATA", lg2::hex, bytesToInt<uint32_t>(data.data), "REG",
+                lg2::hex, data.addr, "PAGE", page);
+            co_return false;
+        }
+    }
+
+    if (!co_await storeDataIntoMTP())
+    {
+        error("Failed to store code into MTP after programming config data");
+        co_return false;
+    }
+
+    co_return true;
+}
+
+sdbusplus::async::task<bool> MP994X::programAllRegisters()
+{
+    // config 0 = User Registers
+    // config 1 ~ 8 = Multi-configuration Registers
+    for (const auto& [config, gdata] : getGroupedConfigData(~pageMask, 4))
+    {
+        debug("Configuring registers for config set {SET}", "SET", config);
+
+        if (config > 0)
+        {
+            if (!co_await setMultiConfigAddress(config))
+            {
+                co_return false;
+            }
+        }
+
+        if (!co_await programConfigData(gdata))
+        {
+            error("Failed to program config set {SET}", "SET", config);
+            co_return false;
+        }
+
+        debug("Configured {SIZE} registers for config set {SET}", "SIZE",
+              gdata.size(), "SET", config);
+    }
+
+    debug("All registers were programmed successfully");
+
+    co_return true;
+}
+
+sdbusplus::async::task<bool> MP994X::storeDataIntoMTP()
+{
+    std::vector<uint8_t> tbuf;
+    std::vector<uint8_t> rbuf;
+
+    tbuf = buildByteVector(PMBusCmd::page, MPSPage::page0);
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to set page 0 to store data into MTP");
+        co_return false;
+    }
+
+    tbuf = buildByteVector(MP994XCmd::storeUserAll);
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to store data into MTP");
+        co_return false;
+    }
+
+    // Wait store data
+    co_await sdbusplus::async::sleep_for(ctx, std::chrono::milliseconds(1000));
+
+    debug("Stored data into MTP");
+    co_return true;
+}
+
+sdbusplus::async::task<bool> MP994X::getCRC(uint32_t* checksum)
+{
+    static constexpr size_t crcUserMultiDataLength = 4;
+    static constexpr size_t statusByteLength = 1;
+
+    std::vector<uint8_t> tbuf;
+    std::vector<uint8_t> rbuf;
+
+    tbuf = buildByteVector(PMBusCmd::page, MPSPage::page0);
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to set page 0 for get user data");
+        co_return false;
+    }
+
+    tbuf = buildByteVector(MP994XCmd::userData08);
+    rbuf.resize(crcUserMultiDataLength + statusByteLength);
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to get user data on page 0");
+        co_return false;
+    }
+
+    auto crcBytes = std::span(rbuf).subspan(statusByteLength);
+    *checksum = bytesToInt<uint32_t>(crcBytes);
+
+    debug("Read CRC: {CRC}", "CRC", lg2::hex, *checksum);
+    co_return true;
+}
+
+sdbusplus::async::task<bool> MP994X::restoreDataFromNVM()
+{
+    static constexpr size_t nvmPmbusCtrlDataLength = 2;
+    static constexpr uint16_t enableRestoreDataFromMTPMask = 0x0008;
+
+    std::vector<uint8_t> tbuf;
+    std::vector<uint8_t> rbuf;
+
+    // enable restore data from MTP
+    tbuf = buildByteVector(PMBusCmd::page, MPSPage::page2);
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to set page 2 to enable restore data from MTP");
+        co_return false;
+    }
+
+    tbuf = buildByteVector(MP994XCmd::mfrNVMPmbusCtrl);
+    rbuf.resize(nvmPmbusCtrlDataLength);
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to read NVM PMBUS Ctrl register");
+        co_return false;
+    }
+
+    uint16_t data = ((rbuf[1] << 8) | rbuf[0]) | enableRestoreDataFromMTPMask;
+    tbuf = buildByteVector(MP994XCmd::mfrNVMPmbusCtrl, data);
+    rbuf.clear();
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to enable restore data from MTP");
+        co_return false;
+    }
+
+    // restore data from NVM
+    tbuf = buildByteVector(PMBusCmd::page, MPSPage::page0);
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to set page 0 for restore MTP and verify");
+    }
+
+    tbuf = buildByteVector(PMBusCmd::restoreUserAll);
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to restore data from NVM");
+        co_return false;
+    }
+
+    // wait restore data
+    co_await sdbusplus::async::sleep_for(ctx, std::chrono::milliseconds(500));
+
+    debug("Restored data from NVM success");
+
+    co_return true;
+}
+
+sdbusplus::async::task<bool> MP994X::checkMTPCRC()
+{
+    uint32_t crc = 0;
+    // NOLINTBEGIN(clang-analyzer-core.uninitialized.Branch)
+    if (!co_await getCRC(&crc))
+    // NOLINTEND(clang-analyzer-core.uninitialized.Branch)
+    {
+        error("Failed to get CRC for MTP check");
+        co_return false;
+    }
+
+    debug("MTP CRC: {CRC}, Expected: {EXP}", "CRC", lg2::hex, crc, "EXP",
+          lg2::hex, configuration->crcMulti);
+
+    co_return configuration->crcMulti == crc;
+}
+
+bool MP994X::forcedUpdateAllowed()
+{
+    return true;
+}
+
+sdbusplus::async::task<bool> MP994X::updateFirmware(bool force)
+{
+    (void)force;
+
+    if (!configuration)
+    {
+        error("Configuration not loaded");
+        co_return false;
+    }
+
+    if (!co_await checkId(MP994XCmd::vendorId, configuration->vendorId))
+    {
+        co_return false;
+    }
+
+    if (!co_await checkId(MP994XCmd::deviceId, configuration->productId))
+    {
+        co_return false;
+    }
+
+    if (!co_await checkId(MP994XCmd::configId, configuration->configId))
+    {
+        co_return false;
+    }
+
+    if (!co_await unlockWriteProtect())
+    {
+        co_return false;
+    }
+
+    if (!co_await disableStoreFaultTriggering())
+    {
+        co_return false;
+    }
+
+    if (!co_await programAllRegisters())
+    {
+        co_return false;
+    }
+
+    if (!co_await restoreDataFromNVM())
+    {
+        co_return false;
+    }
+
+    if (!co_await checkMTPCRC())
+    {
+        co_return false;
+    }
+
+    co_return true;
+}
+
+} // namespace phosphor::software::VR
