diff --git a/i2c-vr/mps/mp297x.cpp b/i2c-vr/mps/mp297x.cpp
new file mode 100644
index 0000000..e9ae9cd
--- /dev/null
+++ b/i2c-vr/mps/mp297x.cpp
@@ -0,0 +1,530 @@
+#include "mp297x.hpp"
+
+#include "common/include/utils.hpp"
+
+#include <phosphor-logging/lg2.hpp>
+
+#include <fstream>
+
+PHOSPHOR_LOG2_USING;
+
+namespace phosphor::software::VR
+{
+
+static constexpr size_t statusByteLength = 1;
+
+static constexpr std::string_view crcUserRegName = "CRC_USER";
+static constexpr std::string_view crcMultiRegName = "CRC_MULTI";
+
+enum class MP297XCmd : uint8_t
+{
+    // Page 0 commands
+    storeDataIntoMTP = 0xF1,
+
+    // Page 1 commands
+    writeProtectMode = 0x35,
+    enableMTPPageWR = 0x4F,
+
+    // Page 2 commands
+    enableMultiConfigCRC = 0xF3,
+
+    // Page 0x29 commands
+    readUserCodeCRC = 0xFF,
+
+    // Page 0x2A commands
+    readMultiConfigCRC = 0xBF,
+};
+
+sdbusplus::async::task<bool> MP297X::parseDeviceConfiguration()
+{
+    if (!configuration)
+    {
+        error("Device configuration not initialized");
+        co_return false;
+    }
+
+    configuration->vendorId = 0x0025;
+    configuration->productId = 0x0071;
+
+    for (const auto& tokens : parser->lineTokens)
+    {
+        if (!parser->isValidDataTokens(tokens))
+        {
+            continue;
+        }
+
+        auto regName = parser->getVal<std::string>(tokens, ATE::regName);
+
+        if (regName == crcUserRegName)
+        {
+            configuration->configId =
+                parser->getVal<uint32_t>(tokens, ATE::configId);
+            configuration->crcUser =
+                parser->getVal<uint32_t>(tokens, ATE::regDataHex);
+        }
+        else if (regName == crcMultiRegName)
+        {
+            configuration->crcMulti =
+                parser->getVal<uint32_t>(tokens, ATE::regDataHex);
+            break;
+        }
+    }
+
+    co_return true;
+}
+
+sdbusplus::async::task<bool> MP297X::verifyImage(const uint8_t* image,
+                                                 size_t imageSize)
+{
+    if (!co_await parseImage(image, imageSize))
+    {
+        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->configId == 0)
+    {
+        error("Image verification failed - missing config ID");
+        co_return false;
+    }
+
+    co_return true;
+}
+
+sdbusplus::async::task<bool> MP297X::checkId(PMBusCmd idCmd, uint32_t expected)
+{
+    constexpr size_t idLength = 2;
+
+    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 ID check");
+        co_return false;
+    }
+
+    tbuf = buildByteVector(idCmd);
+    rbuf.resize(statusByteLength + idLength);
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to read ID, cmd={CMD}", "CMD", lg2::hex,
+              static_cast<uint8_t>(idCmd));
+        co_return false;
+    }
+
+    auto idBytes = std::span(rbuf).subspan(statusByteLength);
+    auto id = bytesToInt<uint32_t>(idBytes);
+
+    if (id != expected)
+    {
+        error("ID check failed for cmd {CMD}: got {ID}, expected {EXP}", "CMD",
+              lg2::hex, static_cast<uint8_t>(idCmd), "ID", lg2::hex, id, "EXP",
+              lg2::hex, expected);
+        co_return false;
+    }
+
+    co_return true;
+}
+
+sdbusplus::async::task<bool> MP297X::isPasswordUnlock()
+{
+    constexpr uint8_t passwordMatchMask = 0x08;
+
+    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 password unlock check");
+        co_return false;
+    }
+
+    tbuf = buildByteVector(PMBusCmd::statusCML);
+    rbuf.resize(statusByteLength);
+
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to check password unlock status");
+        co_return false;
+    }
+
+    auto unlocked = (rbuf[0] & passwordMatchMask) != 0;
+
+    debug("Password unlock status: {STATUS}", "STATUS",
+          unlocked ? "Unlocked" : "Locked");
+
+    co_return unlocked;
+}
+
+sdbusplus::async::task<bool> MP297X::unlockWriteProtect()
+{
+    constexpr uint8_t writeProtectModeMask = 0x04;
+    constexpr uint8_t unlockMemoryProtect = 0x00;
+    constexpr uint8_t unlockMTPProtect = 0x63;
+
+    std::vector<uint8_t> tbuf;
+    std::vector<uint8_t> rbuf(statusByteLength);
+
+    // Get write protection mode
+    tbuf = buildByteVector(PMBusCmd::page, MPSPage::page1);
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to set page 1 to check write protection mode");
+        co_return false;
+    }
+
+    tbuf = buildByteVector(MP297XCmd::writeProtectMode);
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to get write protect mode");
+        co_return false;
+    }
+
+    auto isMTPMode = (rbuf[0] & writeProtectModeMask) == 0;
+    auto unlockData = isMTPMode ? unlockMTPProtect : unlockMemoryProtect;
+
+    // Unlock write protection
+    tbuf = buildByteVector(PMBusCmd::page, MPSPage::page0);
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to set page 0 to unlock write protection");
+        co_return false;
+    }
+
+    tbuf = buildByteVector(PMBusCmd::writeProtect, unlockData);
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to unlock write protection");
+        co_return false;
+    }
+
+    debug("Unlocked {MODE} write protection", "MODE",
+          isMTPMode ? "MTP" : "memory");
+    co_return true;
+}
+
+sdbusplus::async::task<bool> MP297X::programPageRegisters(
+    MPSPage page, const std::map<uint8_t, std::vector<MPSData>>& groupedData)
+{
+    auto pageNum = static_cast<uint8_t>(page);
+
+    if (groupedData.find(pageNum) == groupedData.end())
+    {
+        debug("No data found for page {PAGE}", "PAGE", pageNum);
+        co_return true;
+    }
+
+    const auto& data = groupedData.at(pageNum);
+
+    // Page 2 is the multi-config page. Enter page2A to write config value
+    // to MTP space directly during multi-config page programming.
+    if (page == MPSPage::page2)
+    {
+        page = MPSPage::page2A;
+        pageNum = static_cast<uint8_t>(page);
+    }
+
+    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 {PAGE} to program registers", "PAGE",
+              pageNum);
+        co_return false;
+    }
+
+    auto i2cWriteWithRetry =
+        [&](const std::vector<uint8_t>& tbuf) -> sdbusplus::async::task<bool> {
+        std::vector<uint8_t> rbuf;
+        constexpr size_t maxRetries = 3;
+        constexpr auto retryDelay = std::chrono::milliseconds(10);
+
+        for (size_t i = 1; i <= maxRetries; ++i)
+        {
+            if (i2cInterface.sendReceive(tbuf, rbuf))
+            {
+                co_return true;
+            }
+            error("I2C write failed, retry {RETRY}", "RETRY", i);
+            co_await sdbusplus::async::sleep_for(ctx, retryDelay);
+        }
+        co_return false;
+    };
+
+    for (const auto& regData : data)
+    {
+        tbuf = {regData.addr};
+        tbuf.insert(tbuf.end(), regData.data.begin(),
+                    regData.data.begin() + regData.length);
+
+        if (!(co_await i2cWriteWithRetry(tbuf)))
+        {
+            error(
+                "Failed to write data {DATA} to register {REG} on page {PAGE}",
+                "DATA", lg2::hex, bytesToInt<uint32_t>(regData.data), "REG",
+                lg2::hex, regData.addr, "PAGE", pageNum);
+            co_return false;
+        }
+
+        if (page == MPSPage::page2A)
+        {
+            // Page 2A requires a delay after each register write
+            co_await sdbusplus::async::sleep_for(ctx,
+                                                 std::chrono::milliseconds(2));
+        }
+    }
+
+    debug("Programmed {N} registers on page {PAGE}", "N", data.size(), "PAGE",
+          pageNum);
+
+    co_return true;
+}
+
+sdbusplus::async::task<bool> MP297X::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 for storing data into MTP");
+        co_return false;
+    }
+
+    tbuf = buildByteVector(MP297XCmd::storeDataIntoMTP);
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to store data into MTP");
+        co_return false;
+    }
+
+    // Wait store data into MTP
+    co_await sdbusplus::async::sleep_for(ctx, std::chrono::milliseconds(500));
+
+    debug("Stored data into MTP");
+
+    co_return true;
+}
+
+sdbusplus::async::task<bool> MP297X::enableMTPPageWriteRead()
+{
+    constexpr uint8_t mtpByteRWEnable = 0x20;
+
+    std::vector<uint8_t> tbuf;
+    std::vector<uint8_t> rbuf;
+
+    tbuf = buildByteVector(PMBusCmd::page, MPSPage::page1);
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to set page 1 to enable MTP page write/read");
+        co_return false;
+    }
+
+    tbuf = buildByteVector(MP297XCmd::enableMTPPageWR);
+    rbuf.resize(statusByteLength);
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to read MTP page write/read status");
+        co_return false;
+    }
+
+    uint8_t enableMTPPageWRData = rbuf[0] | mtpByteRWEnable;
+    tbuf = buildByteVector(MP297XCmd::enableMTPPageWR, enableMTPPageWRData);
+    rbuf.resize(0);
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to enable MTP page write/read");
+        co_return false;
+    }
+
+    debug("Enabled MTP page write/read");
+    co_return true;
+}
+
+sdbusplus::async::task<bool> MP297X::enableMultiConfigCRC()
+{
+    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 enable multi-config CRC");
+        co_return false;
+    }
+
+    tbuf = buildByteVector(MP297XCmd::enableMultiConfigCRC);
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to enable multi-config CRC");
+        co_return false;
+    }
+
+    debug("Enabled multi-config CRC");
+    co_return true;
+}
+
+sdbusplus::async::task<bool> MP297X::getCRC(uint32_t* checksum)
+{
+    if (checksum == nullptr)
+    {
+        error("getCRC() called with null checksum pointer");
+        co_return false;
+    }
+
+    constexpr size_t crcLength = 2;
+
+    std::vector<uint8_t> tbuf;
+    std::vector<uint8_t> rbuf;
+
+    uint16_t userCodeCRC = 0;
+    uint16_t multiConfigCRC = 0;
+
+    // Read User Code CRC
+    tbuf = buildByteVector(PMBusCmd::page, MPSPage::page29);
+    rbuf.resize(0);
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to set page 29 for User Code CRC read");
+        co_return false;
+    }
+
+    tbuf = buildByteVector(MP297XCmd::readUserCodeCRC);
+    rbuf.resize(crcLength);
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to read User Code CRC from device");
+        co_return false;
+    }
+
+    userCodeCRC = bytesToInt<uint16_t>(rbuf);
+
+    // Read Multi Config CRC
+    tbuf = buildByteVector(PMBusCmd::page, MPSPage::page2A);
+    rbuf.resize(0);
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to set page 2A for Multi Config CRC read");
+        co_return false;
+    }
+
+    tbuf = buildByteVector(MP297XCmd::readMultiConfigCRC);
+    rbuf.resize(crcLength);
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to read Multi Config CRC from device");
+        co_return false;
+    }
+
+    multiConfigCRC = bytesToInt<uint16_t>(rbuf);
+
+    // Combine: [byte3 byte2] = userCodeCRC, [byte1 byte0] = multiConfigCRC
+    *checksum = (static_cast<uint32_t>(userCodeCRC) << 16) |
+                static_cast<uint32_t>(multiConfigCRC);
+
+    debug("Read CRC: {CRC}", "CRC", lg2::hex, *checksum);
+
+    co_return true;
+}
+
+sdbusplus::async::task<bool> MP297X::checkMTPCRC()
+{
+    uint32_t crc = 0;
+    auto expectedCRC = (configuration->crcUser << 16) | configuration->crcMulti;
+
+    // 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, expectedCRC);
+
+    co_return crc == expectedCRC;
+}
+
+bool MP297X::forcedUpdateAllowed()
+{
+    return true;
+}
+
+sdbusplus::async::task<bool> MP297X::updateFirmware(bool force)
+{
+    (void)force;
+
+    auto groupedConfigData = getGroupedConfigData();
+
+    if (!co_await checkId(PMBusCmd::mfrId, configuration->vendorId))
+    {
+        co_return false;
+    }
+
+    if (!co_await checkId(PMBusCmd::mfrModel, configuration->productId))
+    {
+        co_return false;
+    }
+
+    if (!co_await isPasswordUnlock())
+    {
+        co_return false;
+    }
+
+    if (!co_await unlockWriteProtect())
+    {
+        co_return false;
+    }
+
+    if (!co_await programPageRegisters(MPSPage::page0, groupedConfigData))
+    {
+        co_return false;
+    }
+
+    if (!co_await programPageRegisters(MPSPage::page1, groupedConfigData))
+    {
+        co_return false;
+    }
+
+    if (!co_await storeDataIntoMTP())
+    {
+        co_return false;
+    }
+
+    if (!co_await enableMTPPageWriteRead())
+    {
+        co_return false;
+    }
+
+    if (!co_await enableMultiConfigCRC())
+    {
+        co_return false;
+    }
+
+    if (!co_await programPageRegisters(MPSPage::page2, groupedConfigData))
+    {
+        co_return false;
+    }
+
+    if (!(co_await checkMTPCRC()))
+    {
+        co_return false;
+    }
+
+    co_return true;
+}
+
+} // namespace phosphor::software::VR
