diff --git a/i2c-vr/mps/mp2x6xx.cpp b/i2c-vr/mps/mp2x6xx.cpp
new file mode 100644
index 0000000..a558f04
--- /dev/null
+++ b/i2c-vr/mps/mp2x6xx.cpp
@@ -0,0 +1,437 @@
+#include "mp2x6xx.hpp"
+
+#include "common/include/utils.hpp"
+
+#include <phosphor-logging/lg2.hpp>
+
+PHOSPHOR_LOG2_USING;
+
+namespace phosphor::software::VR
+{
+
+static constexpr size_t vendorIdLength = 3;
+static constexpr size_t deviceIdLength = 4;
+static constexpr size_t configIdLength = 2;
+static constexpr size_t statusByteLength = 1;
+static constexpr size_t crcLength = 2;
+
+static constexpr std::string_view productIdRegName = "TRIM_MFR_PRODUCT_ID2";
+static constexpr std::string_view crcUserRegName = "CRC_USER";
+
+static constexpr uint8_t pageMask = 0x0F;
+static constexpr uint8_t configMask = 0xF0;
+
+static constexpr uint8_t disableWriteProtect = 0x00;
+static constexpr uint16_t disablePage2WriteProtect = 0x128C;
+static constexpr uint16_t disablePage3WriteProtect = 0x0082;
+
+enum class MP2X6XXCmd : uint8_t
+{
+    // Page 0 commands
+    readCRCReg = 0xED,
+    // Page 1 commands
+    mfrMTPMemoryCtrl = 0xCC,
+    // Page 2 commands
+    selectConfigCtrl = 0x1A,
+    // Page 3 commands
+    mfrMTPMemoryCtrlPage3 = 0x81,
+};
+
+sdbusplus::async::task<bool> MP2X6XX::parseDeviceConfiguration()
+{
+    if (!configuration)
+    {
+        error("Device configuration not initialized");
+        co_return false;
+    }
+
+    configuration->vendorId = 0x4D5053;
+
+    for (const auto& tokens : parser->lineTokens)
+    {
+        if (!parser->isValidDataTokens(tokens))
+        {
+            continue;
+        }
+
+        auto regName = parser->getVal<std::string>(tokens, ATE::regName);
+        if (regName == productIdRegName)
+        {
+            configuration->productId =
+                parser->getVal<uint32_t>(tokens, ATE::regDataHex);
+            configuration->configId =
+                parser->getVal<uint32_t>(tokens, ATE::configId);
+        }
+        else if (regName == crcUserRegName)
+        {
+            configuration->crcUser =
+                parser->getVal<uint32_t>(tokens, ATE::regDataHex);
+            break;
+        }
+    }
+
+    co_return true;
+}
+
+sdbusplus::async::task<bool> MP2X6XX::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->productId == 0 || configuration->configId == 0)
+    {
+        error("Image verification failed - missing product or config ID");
+        co_return false;
+    }
+
+    co_return true;
+}
+
+sdbusplus::async::task<bool> MP2X6XX::checkId(PMBusCmd pmBusCmd,
+                                              uint32_t expected)
+{
+    const uint8_t cmd = static_cast<uint8_t>(pmBusCmd);
+    size_t idLen = 0;
+    bool blockRead = false;
+
+    switch (pmBusCmd)
+    {
+        case PMBusCmd::mfrId:
+            idLen = vendorIdLength;
+            blockRead = true;
+            break;
+        case PMBusCmd::icDeviceId:
+            idLen = deviceIdLength;
+            blockRead = true;
+            break;
+        case PMBusCmd::mfrSerial:
+            idLen = configIdLength;
+            break;
+        default:
+            error("Invalid command for ID check: {CMD}", "CMD", lg2::hex, cmd);
+            co_return false;
+    }
+
+    std::vector<uint8_t> rbuf;
+    std::vector<uint8_t> tbuf;
+
+    tbuf = buildByteVector(PMBusCmd::page, MPSPage::page0);
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to set page 0 for ID check");
+        co_return false;
+    }
+
+    tbuf = {cmd};
+    rbuf.resize(idLen + (blockRead ? statusByteLength : 0));
+
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("I2C failure during ID check, cmd {CMD}", "CMD", lg2::hex, cmd);
+        co_return false;
+    }
+
+    auto idBytes = std::span(rbuf).subspan(blockRead ? statusByteLength : 0);
+    uint32_t id = bytesToInt<uint32_t>(idBytes);
+
+    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> MP2X6XX::unlockWriteProtect()
+{
+    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 unlocking write protect");
+        co_return false;
+    }
+
+    tbuf = buildByteVector(PMBusCmd::writeProtect, disableWriteProtect);
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to disable write protect");
+        co_return false;
+    }
+
+    // unlock page 2 write protect
+    tbuf = buildByteVector(PMBusCmd::page, MPSPage::page1);
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to set page 1 for unlocking write protect for page 2");
+        co_return false;
+    }
+
+    tbuf =
+        buildByteVector(MP2X6XXCmd::mfrMTPMemoryCtrl, disablePage2WriteProtect);
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to unlock page 2 write protect");
+        co_return false;
+    }
+
+    // unlock page 3 write protect
+    tbuf = buildByteVector(PMBusCmd::page, MPSPage::page3);
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to set page 3 for unlocking write protect for page 3");
+        co_return false;
+    }
+
+    tbuf = buildByteVector(MP2X6XXCmd::mfrMTPMemoryCtrlPage3,
+                           disablePage3WriteProtect);
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to unlock page 3 write protect");
+        co_return false;
+    }
+
+    debug("Unlocked write protect");
+
+    co_return true;
+}
+
+sdbusplus::async::task<bool> MP2X6XX::selectConfig(uint8_t config)
+{
+    // MPS config select command:
+    // Writes to Page 2 @ 0x1A: value = 0x0F00 | ((config + 7) << 4)
+    // For config 1–6 → result: 0x0F80 to 0x0FD0
+
+    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 for configuration switch");
+        co_return false;
+    }
+
+    constexpr uint8_t baseOffset = 7;
+    uint8_t encodedNibble = static_cast<uint8_t>((config + baseOffset) << 4);
+    uint16_t command = 0x0F00 | encodedNibble;
+
+    tbuf = buildByteVector(MP2X6XXCmd::selectConfigCtrl, command);
+
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to write config select command {CMD} for config {CONFIG}",
+              "CMD", lg2::hex, command, "CONFIG", config);
+        co_return false;
+    }
+
+    debug("Switched to config {CONFIG}", "CONFIG", config);
+    co_return true;
+}
+
+sdbusplus::async::task<bool> MP2X6XX::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 storeUserCode())
+    {
+        error("Failed to store user code after programming config data");
+        co_return false;
+    }
+
+    co_return true;
+}
+
+sdbusplus::async::task<bool> MP2X6XX::configAllRegisters()
+{
+    for (const auto& [config, gdata] : getGroupedConfigData(configMask, 4))
+    {
+        debug("Configuring registers for config {CONFIG}", "CONFIG", config);
+
+        // Select the appropriate config before programming its registers
+        if (config > 0 && !co_await selectConfig(config))
+        {
+            co_return false;
+        }
+
+        if (!co_await programConfigData(gdata))
+        {
+            error("Failed to program configuration {CONFIG}", "CONFIG", config);
+            co_return false;
+        }
+
+        debug("Configured {SIZE} registers for config {CONFIG}", "SIZE",
+              gdata.size(), "CONFIG", config);
+    }
+
+    co_return true;
+}
+
+sdbusplus::async::task<bool> MP2X6XX::storeUserCode()
+{
+    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 user code");
+        co_return false;
+    }
+
+    tbuf = buildByteVector(PMBusCmd::storeUserCode);
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to store user code");
+        co_return false;
+    }
+
+    // Wait store user code
+    co_await sdbusplus::async::sleep_for(ctx, std::chrono::milliseconds(500));
+
+    debug("Stored user code");
+
+    co_return true;
+}
+
+sdbusplus::async::task<bool> MP2X6XX::getCRC(uint32_t* checksum)
+{
+    if (checksum == nullptr)
+    {
+        error("getCRC() called with null checksum pointer");
+        co_return false;
+    }
+
+    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 CRC read");
+        co_return false;
+    }
+
+    tbuf = buildByteVector(MP2X6XXCmd::readCRCReg);
+    rbuf.resize(crcLength);
+    if (!i2cInterface.sendReceive(tbuf, rbuf))
+    {
+        error("Failed to read CRC from device");
+        co_return false;
+    }
+
+    if (rbuf.size() < crcLength)
+    {
+        error("CRC read returned insufficient data");
+        co_return false;
+    }
+
+    *checksum = bytesToInt<uint32_t>(rbuf);
+
+    debug("Read CRC: {CRC}", "CRC", lg2::hex, *checksum);
+
+    co_return true;
+}
+
+sdbusplus::async::task<bool> MP2X6XX::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->crcUser);
+
+    co_return configuration->crcUser == crc;
+}
+
+bool MP2X6XX::forcedUpdateAllowed()
+{
+    return true;
+}
+
+sdbusplus::async::task<bool> MP2X6XX::updateFirmware(bool force)
+{
+    (void)force;
+
+    if (!co_await checkId(PMBusCmd::mfrId, configuration->vendorId))
+    {
+        co_return false;
+    }
+
+    if (!co_await checkId(PMBusCmd::icDeviceId, configuration->productId))
+    {
+        co_return false;
+    }
+
+    if (!co_await checkId(PMBusCmd::mfrSerial, configuration->configId))
+    {
+        co_return false;
+    }
+
+    if (!co_await unlockWriteProtect())
+    {
+        co_return false;
+    }
+
+    if (!co_await configAllRegisters())
+    {
+        co_return false;
+    }
+
+    if (!(co_await checkMTPCRC()))
+    {
+        co_return false;
+    }
+
+    co_return true;
+}
+
+} // namespace phosphor::software::VR
diff --git a/i2c-vr/mps/mp2x6xx.hpp b/i2c-vr/mps/mp2x6xx.hpp
new file mode 100644
index 0000000..8c504a4
--- /dev/null
+++ b/i2c-vr/mps/mp2x6xx.hpp
@@ -0,0 +1,34 @@
+#pragma once
+
+#include "common/include/pmbus.hpp"
+#include "mps.hpp"
+
+namespace phosphor::software::VR
+{
+
+class MP2X6XX : public MPSVoltageRegulator
+{
+  public:
+    MP2X6XX(sdbusplus::async::context& ctx, uint16_t bus, uint16_t address) :
+        MPSVoltageRegulator(ctx, bus, address)
+    {}
+
+    sdbusplus::async::task<bool> verifyImage(const uint8_t* image,
+                                             size_t imageSize) final;
+    sdbusplus::async::task<bool> updateFirmware(bool force) final;
+    sdbusplus::async::task<bool> getCRC(uint32_t* checksum) final;
+    sdbusplus::async::task<bool> parseDeviceConfiguration() final;
+    bool forcedUpdateAllowed() final;
+
+  private:
+    sdbusplus::async::task<bool> checkId(PMBusCmd pmBusCmd, uint32_t expected);
+    sdbusplus::async::task<bool> unlockWriteProtect();
+    sdbusplus::async::task<bool> storeUserCode();
+    sdbusplus::async::task<bool> checkMTPCRC();
+    sdbusplus::async::task<bool> selectConfig(uint8_t config);
+    sdbusplus::async::task<bool> configAllRegisters();
+    sdbusplus::async::task<bool> programConfigData(
+        const std::vector<MPSData>& gdata);
+};
+
+} // namespace phosphor::software::VR
diff --git a/i2c-vr/mps/mps.cpp b/i2c-vr/mps/mps.cpp
new file mode 100644
index 0000000..ee0abf9
--- /dev/null
+++ b/i2c-vr/mps/mps.cpp
@@ -0,0 +1,93 @@
+#include "mps.hpp"
+
+namespace phosphor::software::VR
+{
+
+bool MPSImageParser::isValidDataTokens(
+    const std::vector<std::string_view>& tokens)
+{
+    return tokens.size() > static_cast<size_t>(ATE::regName) &&
+           !tokens[0].starts_with('*');
+}
+
+MPSData MPSImageParser::extractData(const std::vector<std::string_view>& tokens)
+{
+    MPSData data;
+    data.page = getVal<uint8_t>(tokens, ATE::pageNum);
+    data.addr = getVal<uint8_t>(tokens, ATE::regAddrHex);
+
+    std::string regData = getVal<std::string>(tokens, ATE::regDataHex);
+    size_t byteCount = std::min(regData.length() / 2, size_t(4));
+    for (size_t i = 0; i < byteCount; ++i)
+    {
+        data.data[byteCount - 1 - i] = static_cast<uint8_t>(
+            std::stoul(regData.substr(i * 2, 2), nullptr, 16));
+    }
+
+    data.length = static_cast<uint8_t>(byteCount);
+    return data;
+}
+
+std::vector<MPSData> MPSImageParser::getRegistersData()
+{
+    std::vector<MPSData> registersData;
+    for (const auto& tokens : lineTokens)
+    {
+        if (tokens[0].starts_with("END"))
+        {
+            break;
+        }
+
+        if (isValidDataTokens(tokens))
+        {
+            registersData.push_back(extractData(tokens));
+        }
+    }
+    return registersData;
+}
+
+sdbusplus::async::task<bool> MPSVoltageRegulator::parseImage(
+    const uint8_t* image, size_t imageSize)
+{
+    parser = std::make_unique<MPSImageParser>(image, imageSize);
+
+    configuration = std::make_unique<MPSConfig>();
+    configuration->registersData = parser->getRegistersData();
+
+    if (!co_await parseDeviceConfiguration())
+    {
+        co_return false;
+    }
+
+    lg2::debug(
+        "Parsed configuration: Data Size={SIZE}, Vendor ID={VID}, "
+        "Product ID={PID}, Config ID={CID}, CRC User={CRCUSR}, "
+        "CRC Multi={CRCMULTI}",
+        "SIZE", configuration->registersData.size(), "VID", lg2::hex,
+        configuration->vendorId, "PID", lg2::hex, configuration->productId,
+        "CID", lg2::hex, configuration->configId, "CRCUSR", lg2::hex,
+        configuration->crcUser, "CRCMULTI", lg2::hex, configuration->crcMulti);
+
+    co_return true;
+}
+
+std::map<uint8_t, std::vector<MPSData>>
+    MPSVoltageRegulator::getGroupedConfigData(uint8_t configMask, uint8_t shift)
+{
+    std::map<uint8_t, std::vector<MPSData>> groupedData;
+
+    if (!configuration)
+    {
+        return groupedData;
+    }
+
+    for (const auto& data : configuration->registersData)
+    {
+        uint8_t config = (data.page & configMask) >> shift;
+        groupedData[config].push_back(data);
+    }
+
+    return groupedData;
+}
+
+} // namespace phosphor::software::VR
diff --git a/i2c-vr/mps/mps.hpp b/i2c-vr/mps/mps.hpp
new file mode 100644
index 0000000..da6f854
--- /dev/null
+++ b/i2c-vr/mps/mps.hpp
@@ -0,0 +1,290 @@
+#pragma once
+
+#include "common/include/i2c/i2c.hpp"
+#include "i2c-vr/vr.hpp"
+
+#include <phosphor-logging/lg2.hpp>
+
+#include <cstdint>
+#include <iterator>
+#include <memory>
+#include <string_view>
+#include <vector>
+
+namespace phosphor::software::VR
+{
+
+/**
+ * @brief
+ * Columns of an Automated Test Equipment (ATE) format configuration file.
+ * Each enumerator corresponds to a tab-separated column index.
+ */
+enum class ATE : uint8_t
+{
+    configId = 0,
+    pageNum,
+    regAddrHex,
+    regAddrDec,
+    regName,
+    regDataHex,
+    regDataDec,
+    writeType,
+    colCount,
+};
+
+enum class MPSPage : uint8_t
+{
+    page0 = 0,
+    page1,
+    page2,
+    page3,
+    page4,
+};
+
+struct MPSData
+{
+    uint8_t page = 0;
+    uint8_t addr = 0;
+    uint8_t length = 0;
+    std::array<uint8_t, 4> data{};
+};
+
+struct MPSConfig
+{
+    uint32_t vendorId = 0;
+    uint32_t productId = 0;
+    uint32_t configId = 0;
+    uint32_t crcUser = 0;
+    uint32_t crcMulti = 0;
+    std::vector<MPSData> registersData;
+};
+
+/**
+ * @brief
+ * Utility class to iterate over lines and tokenize them by tab characters.
+ */
+class TokenizedLines
+{
+  public:
+    TokenizedLines(const uint8_t* d, size_t s) :
+        data(reinterpret_cast<const char*>(d), s)
+    {}
+    /**
+     * @brief Iterator over tokenized lines.
+     */
+    struct Iterator
+    {
+        using iterator_category = std::forward_iterator_tag;
+        using value_type = std::vector<std::string_view>;
+        using difference_type = std::ptrdiff_t;
+        using pointer = const value_type*;
+        using reference = const value_type&;
+
+        Iterator() = default; // End iterator
+        Iterator(std::string_view sv) : remaining(sv)
+        {
+            next();
+        }
+
+        reference operator*() const
+        {
+            return currentTokens;
+        }
+
+        pointer operator->() const
+        {
+            return &currentTokens;
+        }
+
+        Iterator& operator++()
+        {
+            next();
+            return *this;
+        }
+
+        Iterator operator++(int)
+        {
+            auto result = *this;
+            ++(*this);
+            return result;
+        }
+
+        friend bool operator==(const Iterator& a, const Iterator& b)
+        {
+            return a.remaining.empty() && b.remaining.empty();
+        }
+
+        friend bool operator!=(const Iterator& a, const Iterator& b)
+        {
+            return !(a == b);
+        }
+
+      private:
+        std::string_view remaining;
+        std::vector<std::string_view> currentTokens;
+
+        void next()
+        {
+            currentTokens.clear();
+            if (remaining.empty())
+            {
+                return;
+            }
+
+            // Extract current line
+            auto newlinePos = remaining.find('\n');
+            std::string_view line = remaining.substr(0, newlinePos);
+            remaining = (newlinePos == std::string_view::npos)
+                            ? std::string_view{}
+                            : remaining.substr(newlinePos + 1);
+
+            // Tokenize by tab
+            size_t start = 0;
+            while (start < line.size())
+            {
+                start = line.find_first_not_of('\t', start);
+                if (start == std::string_view::npos)
+                {
+                    break;
+                }
+
+                auto end = line.find('\t', start);
+                currentTokens.emplace_back(line.substr(start, end - start));
+                start = (end == std::string_view::npos) ? line.size() : end;
+            }
+        }
+    };
+
+    Iterator begin() const
+    {
+        return Iterator(data);
+    }
+
+    static Iterator end()
+    {
+        return Iterator();
+    }
+
+  private:
+    std::string_view data;
+};
+
+/**
+ * @brief Base parser for MPS configuration images.
+ */
+class MPSImageParser
+{
+  public:
+    MPSImageParser(const uint8_t* image, size_t imageSize) :
+        lineTokens(image, imageSize)
+    {}
+
+    template <typename>
+    inline static constexpr bool always_false = false;
+
+    /**
+     * @brief Extract a typed value from a tokenized line.
+     * @tparam T Return type (string or integral type)
+     * @param tokens Tokenized line
+     * @param index Column index (ATE enum)
+     * @return Parsed value or default if invalid
+     */
+    template <typename T>
+    T getVal(const std::vector<std::string_view>& tokens, ATE index)
+    {
+        size_t idx = static_cast<size_t>(index);
+
+        if (tokens.size() <= idx)
+        {
+            lg2::error("Index out of range for ATE enum: {INDEX}", "INDEX",
+                       static_cast<uint32_t>(idx));
+            return T{};
+        }
+
+        std::string_view token = tokens[idx];
+
+        if constexpr (std::is_same_v<T, std::string>)
+        {
+            return std::string(token);
+        }
+        else if constexpr (std::is_integral_v<T>)
+        {
+            unsigned long val = 0;
+            try
+            {
+                val = std::stoul(std::string(token), nullptr, 16);
+            }
+            catch (...)
+            {
+                lg2::error("Invalid hex value: {INDEX}", "INDEX",
+                           static_cast<uint32_t>(idx));
+                return T{};
+            }
+            return static_cast<T>(val);
+        }
+        else
+        {
+            static_assert(always_false<T>, "Unsupported type in getVal");
+        }
+    }
+
+    /**
+     * @brief Check if a tokenized line contains valid register data.
+     */
+    static bool isValidDataTokens(const std::vector<std::string_view>& tokens);
+
+    /**
+     * @brief Convert tokenized line into MPSData structure.
+     */
+    MPSData extractData(const std::vector<std::string_view>& tokens);
+
+    /**
+     * @brief Collect all register data entries from the parsed image.
+     */
+    std::vector<MPSData> getRegistersData();
+
+    TokenizedLines lineTokens;
+};
+
+/**
+ * @brief Base class for MPS Voltage Regulators.
+ */
+class MPSVoltageRegulator : public VoltageRegulator
+{
+  public:
+    MPSVoltageRegulator(sdbusplus::async::context& ctx, uint16_t bus,
+                        uint16_t address) :
+        VoltageRegulator(ctx), i2cInterface(phosphor::i2c::I2C(bus, address))
+    {}
+
+    /**
+     * @brief Parse device-specific configuration from the loaded image.
+     * @return async task returning true if parsing succeeds
+     */
+    virtual sdbusplus::async::task<bool> parseDeviceConfiguration() = 0;
+
+    /**
+     * @brief Parse an image file into internal MPS configuration.
+     * @param image Pointer to the image data
+     * @param imageSize Size of the image data
+     * @return async task returning true if parsing succeeds
+     */
+    sdbusplus::async::task<bool> parseImage(const uint8_t* image,
+                                            size_t imageSize);
+
+    /**
+     * @brief Group register data by page, optionally masked and shifted.
+     * @param configMask Bitmask to select relevant page bits (default 0xFF)
+     * @param shift Number of bits to shift masked value to obtain group key
+     * @return map of page keys to vector of MPSData
+     */
+    std::map<uint8_t, std::vector<MPSData>> getGroupedConfigData(
+        uint8_t configMask = 0xFF, uint8_t shift = 0);
+
+  protected:
+    phosphor::i2c::I2C i2cInterface;
+    std::unique_ptr<MPSImageParser> parser;
+    std::unique_ptr<MPSConfig> configuration;
+};
+
+} // namespace phosphor::software::VR
