diff --git a/common/i2c/i2c.cpp b/common/i2c/i2c.cpp
index 99de04b..6f8414d 100644
--- a/common/i2c/i2c.cpp
+++ b/common/i2c/i2c.cpp
@@ -37,41 +37,45 @@
     uint8_t readSize) const
 // NOLINTEND(readability-static-accessed-through-instance)
 {
+    bool result = true;
+
     if (fd <= 0)
     {
-        co_return false;
+        result = false;
     }
-
-    struct i2c_msg msg[2];
-    struct i2c_rdwr_ioctl_data readWriteData;
-    int msgIndex = 0;
-
-    if (writeSize)
+    else
     {
-        msg[msgIndex].addr = deviceNode;
-        msg[msgIndex].flags = 0;
-        msg[msgIndex].len = writeSize;
-        msg[msgIndex].buf = writeData;
-        msgIndex++;
-    }
+        struct i2c_msg msg[2];
+        struct i2c_rdwr_ioctl_data readWriteData;
+        int msgIndex = 0;
 
-    if (readSize)
-    {
-        msg[msgIndex].addr = deviceNode;
-        msg[msgIndex].flags = I2C_M_RD;
-        msg[msgIndex].len = readSize;
-        msg[msgIndex].buf = readData;
-        msgIndex++;
-    }
+        if (writeSize)
+        {
+            msg[msgIndex].addr = deviceNode;
+            msg[msgIndex].flags = 0;
+            msg[msgIndex].len = writeSize;
+            msg[msgIndex].buf = writeData;
+            msgIndex++;
+        }
 
-    readWriteData.msgs = msg;
-    readWriteData.nmsgs = msgIndex;
+        if (readSize)
+        {
+            msg[msgIndex].addr = deviceNode;
+            msg[msgIndex].flags = I2C_M_RD;
+            msg[msgIndex].len = readSize;
+            msg[msgIndex].buf = readData;
+            msgIndex++;
+        }
 
-    if (ioctl(fd, I2C_RDWR, &readWriteData) < 0)
-    {
-        co_return false;
+        readWriteData.msgs = msg;
+        readWriteData.nmsgs = msgIndex;
+
+        if (ioctl(fd, I2C_RDWR, &readWriteData) < 0)
+        {
+            result = false;
+        }
     }
-    co_return true;
+    co_return result;
 }
 
 int I2C::close() const
diff --git a/cpld/README.md b/cpld/README.md
new file mode 100644
index 0000000..db8af3d
--- /dev/null
+++ b/cpld/README.md
@@ -0,0 +1,21 @@
+# CPLD Update Daemon
+
+This daemon implements the update process for CPLD attached via I2C bus.
+
+## Configuration Example
+
+The following shows an example of entity manager configuration record for
+lattice LCMXO3LF-4300C CPLD.
+
+```json
+{
+  "Address": "0x40",
+  "Bus": 5,
+  "FirmwareInfo": {
+    "CompatibleHardware": "com.meta.Hardware.CPLD",
+    "VendorIANA": 40981
+  },
+  "Name": "LCMXO3LF_4300C",
+  "Type": "LatticeXO3Firmware"
+}
+```
diff --git a/cpld/cpld.cpp b/cpld/cpld.cpp
new file mode 100644
index 0000000..2392e48
--- /dev/null
+++ b/cpld/cpld.cpp
@@ -0,0 +1,52 @@
+#include "cpld.hpp"
+
+namespace phosphor::software::cpld
+{
+
+sdbusplus::async::task<bool> CPLDDevice::updateDevice(const uint8_t* image,
+                                                      size_t image_size)
+{
+    if (cpldInterface == nullptr)
+    {
+        lg2::error("CPLD interface is not initialized");
+        co_return false;
+    }
+    else
+    {
+        setUpdateProgress(1);
+        if (!(co_await cpldInterface->updateFirmware(
+                false, image, image_size, [this](int percent) -> bool {
+                    return this->setUpdateProgress(percent);
+                })))
+        {
+            lg2::error("Failed to update CPLD firmware");
+            co_return false;
+        }
+
+        setUpdateProgress(100);
+        lg2::info("Successfully updated CPLD");
+        co_return true;
+    }
+}
+
+sdbusplus::async::task<bool> CPLDDevice::getVersion(std::string& version)
+{
+    if (cpldInterface == nullptr)
+    {
+        lg2::error("CPLD interface is not initialized");
+        co_return false;
+    }
+    else
+    {
+        if (!(co_await cpldInterface->getVersion(version)))
+        {
+            lg2::error("Failed to get CPLD version");
+            co_return false;
+        }
+
+        lg2::info("CPLD version: {VERSION}", "VERSION", version);
+        co_return true;
+    }
+}
+
+} // namespace phosphor::software::cpld
diff --git a/cpld/cpld.hpp b/cpld/cpld.hpp
new file mode 100644
index 0000000..a6bf18b
--- /dev/null
+++ b/cpld/cpld.hpp
@@ -0,0 +1,39 @@
+#pragma once
+
+#include "common/include/device.hpp"
+#include "common/include/software_manager.hpp"
+#include "cpld_interface.hpp"
+
+#include <phosphor-logging/lg2.hpp>
+#include <sdbusplus/async/context.hpp>
+
+PHOSPHOR_LOG2_USING;
+
+namespace ManagerInf = phosphor::software::manager;
+
+namespace phosphor::software::cpld
+{
+
+class CPLDDevice : public Device
+{
+  public:
+    CPLDDevice(sdbusplus::async::context& ctx, const std::string& chiptype,
+               const std::string& chipname, const uint16_t& bus,
+               const uint8_t& address, SoftwareConfig& config,
+               ManagerInf::SoftwareManager* parent) :
+        Device(ctx, config, parent,
+               {RequestedApplyTimes::Immediate, RequestedApplyTimes::OnReset}),
+        cpldInterface(CPLDFactory::instance().create(chiptype, ctx, chipname,
+                                                     bus, address))
+    {}
+
+    using Device::softwareCurrent;
+    sdbusplus::async::task<bool> updateDevice(const uint8_t* image,
+                                              size_t image_size) final;
+    sdbusplus::async::task<bool> getVersion(std::string& version);
+
+  private:
+    std::unique_ptr<CPLDInterface> cpldInterface;
+};
+
+} // namespace phosphor::software::cpld
diff --git a/cpld/cpld_interface.cpp b/cpld/cpld_interface.cpp
new file mode 100644
index 0000000..a67e03e
--- /dev/null
+++ b/cpld/cpld_interface.cpp
@@ -0,0 +1,43 @@
+#include "cpld_interface.hpp"
+
+#include "lattice/interface.hpp"
+
+namespace phosphor::software::cpld
+{
+
+CPLDFactory& CPLDFactory::instance()
+{
+    static CPLDFactory factory;
+    return factory;
+}
+
+void CPLDFactory::registerCPLD(const std::string& vendorName, Creator creator)
+{
+    creators[vendorName] = std::move(creator);
+}
+
+std::unique_ptr<CPLDInterface> CPLDFactory::create(
+    const std::string& vendorName, sdbusplus::async::context& ctx,
+    const std::string& chipName, uint16_t bus, uint8_t address) const
+{
+    auto it = creators.find(vendorName);
+    if (it != creators.end())
+    {
+        return (it->second)(ctx, chipName, bus, address);
+    }
+    return nullptr;
+}
+
+std::vector<std::string> CPLDFactory::getConfigs()
+{
+    std::vector<std::string> configs;
+    configs.reserve(creators.size());
+
+    std::transform(creators.begin(), creators.end(),
+                   std::back_inserter(configs),
+                   [](const auto& pair) { return pair.first; });
+
+    return configs;
+}
+
+} // namespace phosphor::software::cpld
diff --git a/cpld/cpld_interface.hpp b/cpld/cpld_interface.hpp
new file mode 100644
index 0000000..6dec356
--- /dev/null
+++ b/cpld/cpld_interface.hpp
@@ -0,0 +1,62 @@
+#pragma once
+
+#include <sdbusplus/async.hpp>
+
+#include <cstdint>
+#include <functional>
+#include <memory>
+#include <string>
+
+namespace phosphor::software::cpld
+{
+
+class CPLDInterface
+{
+  public:
+    CPLDInterface(sdbusplus::async::context& ctx, const std::string& chipname,
+                  uint16_t bus, uint8_t address) :
+        ctx(ctx), chipname(chipname), bus(bus), address(address)
+    {}
+
+    virtual ~CPLDInterface() = default;
+    CPLDInterface(const CPLDInterface&) = delete;
+    CPLDInterface& operator=(const CPLDInterface&) = delete;
+    CPLDInterface(CPLDInterface&&) = delete;
+    CPLDInterface& operator=(CPLDInterface&&) = delete;
+
+    virtual sdbusplus::async::task<bool> updateFirmware(
+        bool force, const uint8_t* image, size_t imageSize,
+        std::function<bool(int)> progress = nullptr) = 0;
+
+    virtual sdbusplus::async::task<bool> getVersion(std::string& version) = 0;
+
+  protected:
+    sdbusplus::async::context& ctx;
+    std::string chipname;
+    uint16_t bus;
+    uint8_t address;
+};
+
+class CPLDFactory
+{
+  public:
+    using Creator = std::function<std::unique_ptr<CPLDInterface>(
+        sdbusplus::async::context& ctx, const std::string& chipName,
+        uint16_t bus, uint8_t address)>;
+    using ConfigProvider = std::function<std::vector<std::string>()>;
+
+    static CPLDFactory& instance();
+
+    void registerCPLD(const std::string& vendorName, Creator creator);
+
+    std::unique_ptr<CPLDInterface> create(
+        const std::string& vendorName, sdbusplus::async::context& ctx,
+        const std::string& chipName, uint16_t bus, uint8_t address) const;
+
+    std::vector<std::string> getConfigs();
+
+  private:
+    std::unordered_map<std::string, Creator> creators;
+};
+
+} // namespace phosphor::software::cpld
diff --git a/cpld/cpld_software_manager.cpp b/cpld/cpld_software_manager.cpp
new file mode 100644
index 0000000..faf14a5
--- /dev/null
+++ b/cpld/cpld_software_manager.cpp
@@ -0,0 +1,93 @@
+#include "cpld_software_manager.hpp"
+
+#include "common/include/dbus_helper.hpp"
+#include "cpld.hpp"
+
+#include <phosphor-logging/lg2.hpp>
+#include <sdbusplus/async.hpp>
+
+PHOSPHOR_LOG2_USING;
+
+using namespace phosphor::software::cpld;
+
+sdbusplus::async::task<bool> CPLDSoftwareManager::initDevice(
+    const std::string& service, const std::string& path, SoftwareConfig& config)
+{
+    std::string configIface =
+        "xyz.openbmc_project.Configuration." + config.configType;
+
+    std::optional<uint64_t> busNo = co_await dbusGetRequiredProperty<uint64_t>(
+        ctx, service, path, configIface, "Bus");
+    std::optional<uint64_t> address =
+        co_await dbusGetRequiredProperty<uint64_t>(ctx, service, path,
+                                                   configIface, "Address");
+    std::optional<std::string> chipType =
+        co_await dbusGetRequiredProperty<std::string>(ctx, service, path,
+                                                      configIface, "Type");
+    std::optional<std::string> chipName =
+        co_await dbusGetRequiredProperty<std::string>(ctx, service, path,
+                                                      configIface, "Name");
+
+    if (!busNo.has_value() || !address.has_value() || !chipType.has_value() ||
+        !chipName.has_value())
+    {
+        error("missing config property");
+        co_return false;
+    }
+
+    lg2::debug(
+        "CPLD device type: {TYPE} - {NAME} on Bus: {BUS} at Address: {ADDR}",
+        "TYPE", chipType.value(), "NAME", chipName.value(), "BUS",
+        busNo.value(), "ADDR", address.value());
+
+    auto cpld = std::make_unique<CPLDDevice>(
+        ctx, chipType.value(), chipName.value(), busNo.value(), address.value(),
+        config, this);
+
+    std::string version = "unknown";
+    if (!(co_await cpld->getVersion(version)))
+    {
+        lg2::error("Failed to get CPLD version for {NAME}", "NAME",
+                   chipName.value());
+    }
+
+    std::unique_ptr<Software> software = std::make_unique<Software>(ctx, *cpld);
+
+    software->setVersion(version);
+
+    std::set<RequestedApplyTimes> allowedApplyTimes = {
+        RequestedApplyTimes::Immediate, RequestedApplyTimes::OnReset};
+
+    software->enableUpdate(allowedApplyTimes);
+
+    cpld->softwareCurrent = std::move(software);
+
+    devices.insert({config.objectPath, std::move(cpld)});
+
+    co_return true;
+}
+
+void CPLDSoftwareManager::start()
+{
+    std::vector<std::string> configIntfs;
+    auto configs = CPLDFactory::instance().getConfigs();
+    configIntfs.reserve(configs.size());
+    for (const auto& config : configs)
+    {
+        configIntfs.push_back("xyz.openbmc_project.Configuration." + config);
+    }
+
+    ctx.spawn(initDevices(configIntfs));
+    ctx.run();
+}
+
+int main()
+{
+    sdbusplus::async::context ctx;
+
+    CPLDSoftwareManager cpldSoftwareManager(ctx);
+
+    cpldSoftwareManager.start();
+
+    return 0;
+}
diff --git a/cpld/cpld_software_manager.hpp b/cpld/cpld_software_manager.hpp
new file mode 100644
index 0000000..37530cf
--- /dev/null
+++ b/cpld/cpld_software_manager.hpp
@@ -0,0 +1,22 @@
+#pragma once
+
+#include "common/include/software_manager.hpp"
+
+namespace phosphor::software::cpld
+{
+
+class CPLDSoftwareManager : public phosphor::software::manager::SoftwareManager
+{
+  public:
+    CPLDSoftwareManager(sdbusplus::async::context& ctx) :
+        SoftwareManager(ctx, "CPLD")
+    {}
+
+    sdbusplus::async::task<bool> initDevice(const std::string& service,
+                                            const std::string& path,
+                                            SoftwareConfig& config) final;
+
+    void start();
+};
+
+} // namespace phosphor::software::cpld
diff --git a/cpld/lattice/interface.cpp b/cpld/lattice/interface.cpp
new file mode 100644
index 0000000..21663f0
--- /dev/null
+++ b/cpld/lattice/interface.cpp
@@ -0,0 +1,63 @@
+#include "interface.hpp"
+
+#include "lattice.hpp"
+
+#include <phosphor-logging/lg2.hpp>
+
+namespace phosphor::software::cpld
+{
+
+const std::vector<std::string> supportedTypes = {
+    "LatticeXO2Firmware",
+    "LatticeXO3Firmware",
+};
+
+sdbusplus::async::task<bool> LatticeCPLD::updateFirmware(
+    bool /*force*/, const uint8_t* image, size_t imageSize,
+    std::function<bool(int)> progressCallBack)
+{
+    lg2::info("Updating Lattice CPLD firmware");
+
+    std::replace(chipname.begin(), chipname.end(), '_', '-');
+    auto cpldManager = std::make_unique<CpldLatticeManager>(
+        ctx, bus, address, image, imageSize, chipname, "CFG0", false);
+
+    co_return co_await cpldManager->updateFirmware(progressCallBack);
+}
+
+sdbusplus::async::task<bool> LatticeCPLD::getVersion(std::string& version)
+{
+    lg2::info("Getting Lattice CPLD version");
+
+    std::replace(chipname.begin(), chipname.end(), '_', '-');
+    auto cpldManager = std::make_unique<CpldLatticeManager>(
+        ctx, bus, address, nullptr, 0, chipname, "CFG0", false);
+
+    co_return co_await cpldManager->getVersion(version);
+}
+
+} // namespace phosphor::software::cpld
+
+// Factory function to create lattice CPLD device
+namespace
+{
+using namespace phosphor::software::cpld;
+
+// Register all the CPLD type with the CPLD factory
+const bool vendorRegistered = [] {
+    for (const auto& type : supportedTypes)
+    {
+        CPLDFactory::instance().registerCPLD(
+            type,
+            [](sdbusplus::async::context& ctx, const std::string& chipname,
+               uint16_t bus, uint8_t address) {
+                // Create and return a LatticeCPLD instance
+                // Pass the parameters to the constructor
+                return std::make_unique<LatticeCPLD>(ctx, chipname, bus,
+                                                     address);
+            });
+    }
+    return true;
+}();
+
+} // namespace
diff --git a/cpld/lattice/interface.hpp b/cpld/lattice/interface.hpp
new file mode 100644
index 0000000..67d0915
--- /dev/null
+++ b/cpld/lattice/interface.hpp
@@ -0,0 +1,21 @@
+#include "cpld/cpld_interface.hpp"
+
+namespace phosphor::software::cpld
+{
+
+class LatticeCPLD : public CPLDInterface
+{
+  public:
+    LatticeCPLD(sdbusplus::async::context& ctx, const std::string& chipname,
+                uint16_t bus, uint8_t address) :
+        CPLDInterface(ctx, chipname, bus, address)
+    {}
+
+    sdbusplus::async::task<bool> updateFirmware(
+        bool force, const uint8_t* image, size_t imageSize,
+        std::function<bool(int)> progress) final;
+
+    sdbusplus::async::task<bool> getVersion(std::string& version) final;
+};
+
+} // namespace phosphor::software::cpld
diff --git a/cpld/lattice/lattice.cpp b/cpld/lattice/lattice.cpp
new file mode 100644
index 0000000..ce70fa3
--- /dev/null
+++ b/cpld/lattice/lattice.cpp
@@ -0,0 +1,933 @@
+#include "lattice.hpp"
+
+#include <phosphor-logging/lg2.hpp>
+
+#include <algorithm>
+#include <fstream>
+#include <map>
+#include <thread>
+#include <vector>
+
+using sdbusplus::async::details::context_friend;
+
+constexpr uint8_t busyWaitmaxRetry = 30;
+constexpr uint8_t busyFlagBit = 0x80;
+constexpr std::chrono::milliseconds waitBusyTime(200);
+
+static constexpr std::string_view tagQF = "QF";
+static constexpr std::string_view tagUH = "UH";
+static constexpr std::string_view tagCFStart = "L000";
+static constexpr std::string_view tagChecksum = "C";
+static constexpr std::string_view tagUserCode = "NOTE User Electronic";
+static constexpr std::string_view tagEbrInitData = "NOTE EBR_INIT DATA";
+
+constexpr uint8_t isOK = 0;
+constexpr uint8_t isReady = 0;
+constexpr uint8_t busyOrReadyBit = 4;
+constexpr uint8_t failOrOKBit = 5;
+
+constexpr bool enableUpdateEbrInit = false;
+
+enum cpldI2cCmd
+{
+    commandEraseFlash = 0x0E,
+    commandDisableConfigInterface = 0x26,
+    commandReadStatusReg = 0x3C,
+    commandResetConfigFlash = 0x46,
+    commandProgramDone = 0x5E,
+    commandProgramPage = 0x70,
+    commandEnableConfigMode = 0x74,
+    commandReadFwVersion = 0xC0,
+    commandProgramUserCode = 0xC2,
+    commandReadDeviceId = 0xE0,
+    commandReadBusyFlag = 0xF0,
+};
+
+static uint8_t reverse_bit(uint8_t b)
+{
+    b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
+    b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
+    b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
+    return b;
+}
+
+const std::map<std::string, std::vector<uint8_t>> xo2xo3DeviceIdMap = {
+    {"LCMXO3LF-4300C", {0x61, 0x2b, 0xc0, 0x43}},
+    {"LCMXO3LF-4300", {0x61, 0x2b, 0xc0, 0x43}},
+    {"LCMXO3LF-6900", {0x61, 0x2b, 0xd0, 0x43}},
+    {"LCMXO3D-4300", {0x01, 0x2e, 0x20, 0x43}},
+    {"LCMXO3D-9400", {0x21, 0x2e, 0x30, 0x43}},
+};
+
+static int findNumberSize(const std::string& end, const std::string& start,
+                          const std::string& line)
+{
+    auto pos1 = line.find(start);
+    auto pos2 = line.find(end);
+
+    if (pos1 == std::string::npos || pos2 == std::string::npos || pos1 >= pos2)
+    {
+        return false;
+    }
+
+    return static_cast<int>(pos2 - pos1 - 1);
+}
+
+bool CpldLatticeManager::jedFileParser()
+{
+    bool cfStart = false;
+    bool ufmStart = false; // for isLCMXO3D
+    bool ufmPrepare = false;
+    bool versionStart = false;
+    bool checksumStart = false;
+    bool ebrInitDataStart = false;
+    int numberSize = 0;
+
+    if (image == nullptr || imageSize == 0)
+    {
+        lg2::error(
+            "Error: JED file is empty or not found. Please check the file.");
+        return false;
+    }
+
+    // Convert binary data to a string
+    std::string content(reinterpret_cast<const char*>(image), imageSize);
+    // Use stringstream to simulate file reading
+    std::istringstream iss(content);
+    std::string line;
+
+    // Parsing JED file
+    while (getline(iss, line))
+    {
+        if (line.rfind(tagQF, 0) == 0)
+        {
+            numberSize = findNumberSize("*", "F", line);
+            if (numberSize <= 0)
+            {
+                lg2::error("Error in parsing QF tag");
+                return false;
+            }
+            static constexpr auto start = tagQF.length();
+            fwInfo.QF = std::stoul(line.substr(start, numberSize));
+
+            lg2::debug("QF Size = {QF}", "QF", fwInfo.QF);
+        }
+        else if (line.rfind(tagCFStart, 0) == 0)
+        {
+            cfStart = true;
+        }
+        else if (enableUpdateEbrInit && line.rfind(tagEbrInitData, 0) == 0)
+        {
+            ebrInitDataStart = true;
+        }
+        else if (ufmPrepare)
+        {
+            ufmPrepare = false;
+            ufmStart = true;
+            continue;
+        }
+        else if (line.rfind(tagUserCode, 0) == 0)
+        {
+            versionStart = true;
+        }
+        else if (line.rfind(tagChecksum, 0) == 0)
+        {
+            checksumStart = true;
+        }
+
+        if (line.rfind("NOTE DEVICE NAME:", 0) == 0)
+        {
+            lg2::error(line.c_str());
+            if (line.find(chip) != std::string::npos)
+            {
+                lg2::debug("[OK] The image device name match with chip name");
+            }
+            else
+            {
+                lg2::debug("STOP UPDATEING: The image not match with chip.");
+                return false;
+            }
+        }
+
+        if (cfStart)
+        {
+            // L000
+            if ((line.rfind(tagCFStart, 0)) && (line.size() != 1))
+            {
+                if ((line.rfind('0', 0) == 0) || (line.rfind('1', 0) == 0))
+                {
+                    while (!line.empty())
+                    {
+                        auto binaryStr = line.substr(0, 8);
+                        try
+                        {
+                            fwInfo.cfgData.push_back(
+                                std::stoi(binaryStr, 0, 2));
+                            line.erase(0, 8);
+                        }
+                        catch (const std::invalid_argument& error)
+                        {
+                            break;
+                        }
+                        catch (...)
+                        {
+                            lg2::error("Error while parsing CF section");
+                            return false;
+                        }
+                    }
+                }
+                else
+                {
+                    lg2::debug("CF size = {CF}", "CF", fwInfo.cfgData.size());
+                    cfStart = false;
+                    if (!ebrInitDataStart)
+                    {
+                        ufmPrepare = true;
+                    }
+                }
+            }
+        }
+        else if (enableUpdateEbrInit && ebrInitDataStart)
+        {
+            // NOTE EBR_INIT DATA
+            if ((line.rfind(tagEbrInitData, 0)) && (line.size() != 1))
+            {
+                if ((line.rfind('L', 0)) && (line.size() != 1))
+                {
+                    if ((line.rfind('0', 0) == 0) || (line.rfind('1', 0) == 0))
+                    {
+                        while (!line.empty())
+                        {
+                            auto binaryStr = line.substr(0, 8);
+                            try
+                            {
+                                fwInfo.cfgData.push_back(
+                                    std::stoi(binaryStr, 0, 2));
+                                line.erase(0, 8);
+                            }
+                            catch (const std::invalid_argument& error)
+                            {
+                                break;
+                            }
+                            catch (...)
+                            {
+                                lg2::error("Error while parsing CF section");
+                                return false;
+                            }
+                        }
+                    }
+                    else
+                    {
+                        lg2::debug("CF size with EBR_INIT Data = {CF}", "CF",
+                                   fwInfo.cfgData.size());
+                        ebrInitDataStart = false;
+                        ufmPrepare = true;
+                    }
+                }
+            }
+        }
+        else if ((checksumStart) && (line.size() != 1))
+        {
+            checksumStart = false;
+            numberSize = findNumberSize("*", "C", line);
+            if (numberSize <= 0)
+            {
+                lg2::error("Error in parsing checksum");
+                return false;
+            }
+            static constexpr auto start = tagChecksum.length();
+            std::istringstream iss(line.substr(start, numberSize));
+            iss >> std::hex >> fwInfo.checksum;
+
+            lg2::debug("Checksum = {CHECKSUM}", "CHECKSUM", fwInfo.checksum);
+        }
+        else if (versionStart)
+        {
+            if ((line.rfind(tagUserCode, 0)) && (line.size() != 1))
+            {
+                versionStart = false;
+
+                if (line.rfind(tagUH, 0) == 0)
+                {
+                    numberSize = findNumberSize("*", "H", line);
+                    if (numberSize <= 0)
+                    {
+                        lg2::error("Error in parsing version");
+                        return false;
+                    }
+                    static constexpr auto start = tagUH.length();
+                    std::istringstream iss(line.substr(start, numberSize));
+                    iss >> std::hex >> fwInfo.version;
+
+                    lg2::debug("UserCode = {USERCODE}", "USERCODE",
+                               fwInfo.version);
+                }
+            }
+        }
+        else if (ufmStart)
+        {
+            if ((line.rfind('L', 0)) && (line.size() != 1))
+            {
+                if ((line.rfind('0', 0) == 0) || (line.rfind('1', 0) == 0))
+                {
+                    while (!line.empty())
+                    {
+                        auto binaryStr = line.substr(0, 8);
+                        try
+                        {
+                            fwInfo.ufmData.push_back(
+                                std::stoi(binaryStr, 0, 2));
+                            line.erase(0, 8);
+                        }
+                        catch (const std::invalid_argument& error)
+                        {
+                            break;
+                        }
+                        catch (...)
+                        {
+                            lg2::error("Error while parsing UFM section");
+                            return false;
+                        }
+                    }
+                }
+                else
+                {
+                    lg2::debug("UFM size = {UFM}", "UFM",
+                               fwInfo.ufmData.size());
+                    ufmStart = false;
+                }
+            }
+        }
+    }
+
+    return true;
+}
+
+bool CpldLatticeManager::verifyChecksum()
+{
+    // Compute check sum
+    unsigned int jedFileCheckSum = 0;
+    for (unsigned i = 0; i < fwInfo.cfgData.size(); i++)
+    {
+        jedFileCheckSum += reverse_bit(fwInfo.cfgData.at(i));
+    }
+    for (unsigned i = 0; i < fwInfo.ufmData.size(); i++)
+    {
+        jedFileCheckSum += reverse_bit(fwInfo.ufmData.at(i));
+    }
+    lg2::debug("jedFileCheckSum = {JEDFILECHECKSUM}", "JEDFILECHECKSUM",
+               jedFileCheckSum);
+    jedFileCheckSum = jedFileCheckSum & 0xffff;
+
+    if ((fwInfo.checksum != jedFileCheckSum) || (fwInfo.checksum == 0))
+    {
+        lg2::error("CPLD JED File CheckSum Error = {JEDFILECHECKSUM}",
+                   "JEDFILECHECKSUM", jedFileCheckSum);
+        return false;
+    }
+
+    lg2::debug("JED File Checksum compare success");
+    return true;
+}
+
+sdbusplus::async::task<bool> CpldLatticeManager::readDeviceId()
+{
+    auto sched = context_friend::get_scheduler(ctx);
+    std::vector<uint8_t> command = {commandReadDeviceId, 0x0, 0x0, 0x0};
+    constexpr size_t resSize = 4;
+    std::vector<uint8_t> readData(resSize, 0);
+    bool success = co_await stdexec::starts_on(
+        sched, i2cInterface.sendReceive(command.data(), command.size(),
+                                        readData.data(), resSize));
+    if (!success)
+    {
+        lg2::error(
+            "Fail to read device Id. Please check the I2C bus and address.");
+        co_return false;
+    }
+
+    auto chipWantToUpdate = xo2xo3DeviceIdMap.find(chip);
+
+    if (chipWantToUpdate != xo2xo3DeviceIdMap.end() &&
+        chipWantToUpdate->second == readData)
+    {
+        if (chip.rfind("LCMXO3D", 0) == 0)
+        {
+            isLCMXO3D = true;
+            if (!target.empty() && target != "CFG0" && target != "CFG1")
+            {
+                lg2::error("Unknown target. Only CFG0 and CFG1 are supported.");
+                co_return false;
+            }
+        }
+
+        lg2::debug("Device ID match with chip. Chip name: {CHIPNAME}",
+                   "CHIPNAME", chip);
+        co_return true;
+    }
+
+    lg2::error(
+        "The device id not match with chip. Only the following chip names are supported: ");
+    for (const auto& chip : xo2xo3DeviceIdMap)
+    {
+        lg2::error(chip.first.c_str());
+    }
+    co_return false;
+}
+
+sdbusplus::async::task<bool> CpldLatticeManager::enableProgramMode()
+{
+    auto sched = context_friend::get_scheduler(ctx);
+    std::vector<uint8_t> command = {commandEnableConfigMode, 0x08, 0x0, 0x0};
+    bool success = co_await stdexec::starts_on(
+        sched,
+        i2cInterface.sendReceive(command.data(), command.size(), nullptr, 0));
+
+    if (!success)
+    {
+        co_return false;
+    }
+
+    if (!(co_await waitBusyAndVerify()))
+    {
+        lg2::error("Wait busy and verify fail");
+        co_return false;
+    }
+    co_await sdbusplus::async::sleep_for(ctx, waitBusyTime);
+    co_return true;
+}
+
+sdbusplus::async::task<bool> CpldLatticeManager::eraseFlash()
+{
+    auto sched = context_friend::get_scheduler(ctx);
+    std::vector<uint8_t> command;
+
+    if (isLCMXO3D)
+    {
+        /*
+        Erase the different internal
+        memories. The bit in YYY defines
+        which memory is erased in Flash
+        access mode.
+        Bit 1=Enable
+        8 Erase CFG0
+        9 Erase CFG1
+        10 Erase UFM0
+        11 Erase UFM1
+        12 Erase UFM2
+        13 Erase UFM3
+        14 Erase CSEC
+        15 Erase USEC
+        16 Erase PUBKEY
+        17 Erase AESKEY
+        18 Erase FEA
+        19 Reserved
+        commandEraseFlash = 0x0E, 0Y YY 00
+        */
+        if (target.empty() || target == "CFG0")
+        {
+            command = {commandEraseFlash, 0x00, 0x01, 0x00};
+        }
+        else if (target == "CFG1")
+        {
+            command = {commandEraseFlash, 0x00, 0x02, 0x00};
+        }
+        else
+        {
+            lg2::error("Error: unknown target.");
+            co_return false;
+        }
+    }
+    else
+    {
+        command = {commandEraseFlash, 0xC, 0x0, 0x0};
+    }
+
+    bool success = co_await stdexec::starts_on(
+        sched,
+        i2cInterface.sendReceive(command.data(), command.size(), nullptr, 0));
+    if (!success)
+    {
+        co_return false;
+    }
+
+    if (!(co_await waitBusyAndVerify()))
+    {
+        lg2::error("Wait busy and verify fail");
+        co_return false;
+    }
+    co_await sdbusplus::async::sleep_for(ctx, waitBusyTime);
+    co_return true;
+}
+
+sdbusplus::async::task<bool> CpldLatticeManager::resetConfigFlash()
+{
+    auto sched = context_friend::get_scheduler(ctx);
+    std::vector<uint8_t> command;
+    if (isLCMXO3D)
+    {
+        /*
+        Set Page Address pointer to the
+        beginning of the different internal
+        Flash sectors. The bit in YYYY
+        defines which sector is selected.
+        Bit Flash sector selected
+        8 CFG0
+        9 CFG1
+        10 FEA
+        11 PUBKEY
+        12 AESKEY
+        13 CSEC
+        14 UFM0
+        15 UFM1
+        16 UFM2
+        17 UFM3
+        18 USEC
+        19 Reserved
+        20 Reserved
+        21 Reserved
+        22 Reserved
+        commandResetConfigFlash = 0x46, YY YY 00
+        */
+        if (target.empty() || target == "CFG0")
+        {
+            command = {commandResetConfigFlash, 0x00, 0x01, 0x00};
+        }
+        else if (target == "CFG1")
+        {
+            command = {commandResetConfigFlash, 0x00, 0x02, 0x00};
+        }
+        else
+        {
+            lg2::error(
+                "Error: unknown target. Only CFG0 and CFG1 are supported.");
+            co_return false;
+        }
+    }
+    else
+    {
+        command = {commandResetConfigFlash, 0x0, 0x0, 0x0};
+    }
+
+    co_return co_await stdexec::starts_on(
+        sched,
+        i2cInterface.sendReceive(command.data(), command.size(), nullptr, 0));
+}
+
+sdbusplus::async::task<bool> CpldLatticeManager::writeProgramPage()
+{
+    /*
+    Program one NVCM/Flash page. Can be
+    used to program the NVCM0/CFG or
+    NVCM1/UFM.
+    */
+    auto sched = context_friend::get_scheduler(ctx);
+    std::vector<uint8_t> command = {commandProgramPage, 0x0, 0x0, 0x01};
+    size_t iterSize = 16;
+
+    for (size_t i = 0; i < fwInfo.cfgData.size(); i += iterSize)
+    {
+        double progressRate =
+            ((double(i) / double(fwInfo.cfgData.size())) * 100);
+        std::cout << "Update :" << std::fixed << std::dec
+                  << std::setprecision(2) << progressRate << "% \r";
+
+        uint8_t len = ((i + iterSize) < fwInfo.cfgData.size())
+                          ? iterSize
+                          : (fwInfo.cfgData.size() - i);
+        std::vector<uint8_t> data = command;
+
+        data.insert(
+            data.end(), fwInfo.cfgData.begin() + static_cast<std::ptrdiff_t>(i),
+            fwInfo.cfgData.begin() + static_cast<std::ptrdiff_t>(i + len));
+
+        bool success = co_await stdexec::starts_on(
+            sched,
+            i2cInterface.sendReceive(data.data(), data.size(), nullptr, 0));
+        if (!success)
+        {
+            co_return false;
+        }
+
+        /*
+         Reference spec
+         Important! If don't sleep, it will take a long time to update.
+        */
+        co_await sdbusplus::async::sleep_for(ctx,
+                                             std::chrono::microseconds(200));
+
+        if (!(co_await waitBusyAndVerify()))
+        {
+            lg2::error("Wait busy and verify fail");
+            co_return false;
+        }
+
+        data.clear();
+    }
+
+    co_return true;
+}
+
+sdbusplus::async::task<bool> CpldLatticeManager::programUserCode()
+{
+    auto sched = context_friend::get_scheduler(ctx);
+    std::vector<uint8_t> command = {commandProgramUserCode, 0x0, 0x0, 0x0};
+    for (int i = 3; i >= 0; i--)
+    {
+        command.push_back((fwInfo.version >> (i * 8)) & 0xFF);
+    }
+    bool success = co_await stdexec::starts_on(
+        sched,
+        i2cInterface.sendReceive(command.data(), command.size(), nullptr, 0));
+
+    if (!success)
+    {
+        co_return false;
+    }
+
+    if (!(co_await waitBusyAndVerify()))
+    {
+        lg2::error("Wait busy and verify fail");
+        co_return false;
+    }
+
+    co_return true;
+}
+
+sdbusplus::async::task<bool> CpldLatticeManager::programDone()
+{
+    auto sched = context_friend::get_scheduler(ctx);
+    std::vector<uint8_t> command = {commandProgramDone, 0x0, 0x0, 0x0};
+    bool success = co_await stdexec::starts_on(
+        sched,
+        i2cInterface.sendReceive(command.data(), command.size(), nullptr, 0));
+
+    if (!success)
+    {
+        co_return false;
+    }
+    if (!(co_await waitBusyAndVerify()))
+    {
+        lg2::error("Wait busy and verify fail");
+        co_return false;
+    }
+
+    co_return true;
+}
+
+sdbusplus::async::task<bool> CpldLatticeManager::disableConfigInterface()
+{
+    auto sched = context_friend::get_scheduler(ctx);
+    std::vector<uint8_t> command = {commandDisableConfigInterface, 0x0, 0x0};
+
+    bool success = co_await stdexec::starts_on(
+        sched,
+        i2cInterface.sendReceive(command.data(), command.size(), nullptr, 0));
+
+    co_return success;
+}
+
+sdbusplus::async::task<bool> CpldLatticeManager::waitBusyAndVerify()
+{
+    uint8_t retry = 0;
+
+    while (retry <= busyWaitmaxRetry)
+    {
+        uint8_t busyFlag = 0xff;
+
+        if (!(co_await readBusyFlag(busyFlag)))
+        {
+            lg2::error("Fail to read busy flag.");
+            co_return false;
+        }
+
+        if (busyFlag & busyFlagBit)
+        {
+            co_await sdbusplus::async::sleep_for(ctx, waitBusyTime);
+            retry++;
+            if (retry > busyWaitmaxRetry)
+            {
+                lg2::error(
+                    "Status Reg : Busy! Please check the I2C bus and address.");
+                co_return false;
+            }
+        }
+        else
+        {
+            break;
+        }
+    } // while loop busy check
+
+    // Check out status reg
+    uint8_t statusReg = 0xff;
+
+    if (!(co_await readStatusReg(statusReg)))
+    {
+        lg2::error("Fail to read status register.");
+        co_return false;
+    }
+
+    if (((statusReg >> busyOrReadyBit) & 1) == isReady &&
+        ((statusReg >> failOrOKBit) & 1) == isOK)
+    {
+        lg2::debug("Status Reg : OK");
+        co_return true;
+    }
+
+    lg2::error("Status Reg : Fail! Please check the I2C bus and address.");
+    co_return false;
+}
+
+sdbusplus::async::task<bool> CpldLatticeManager::readBusyFlag(uint8_t& busyFlag)
+{
+    auto sched = context_friend::get_scheduler(ctx);
+    std::vector<uint8_t> command = {commandReadBusyFlag, 0x0, 0x0, 0x0};
+    constexpr size_t resSize = 1;
+    std::vector<uint8_t> readData(resSize, 0);
+    bool success = co_await stdexec::starts_on(
+        sched, i2cInterface.sendReceive(command.data(), command.size(),
+                                        readData.data(), resSize));
+
+    if (!success || (readData.size() != resSize))
+    {
+        co_return false;
+    }
+    busyFlag = readData.at(0);
+    co_return true;
+}
+
+sdbusplus::async::task<bool> CpldLatticeManager::readStatusReg(
+    uint8_t& statusReg)
+{
+    auto sched = context_friend::get_scheduler(ctx);
+    std::vector<uint8_t> command = {commandReadStatusReg, 0x0, 0x0, 0x0};
+    constexpr size_t resSize = 4;
+    std::vector<uint8_t> readData(resSize, 0);
+    bool success = co_await stdexec::starts_on(
+        sched, i2cInterface.sendReceive(command.data(), command.size(),
+                                        readData.data(), resSize));
+
+    if (!success || (readData.size() != resSize))
+    {
+        co_return false;
+    }
+    /*
+    Read Status Register
+    [LSC_READ_STATUS]
+    0x3C 00 00 00 N/A YY YY YY YY Bit 1 0
+    12 Busy Ready
+    13 Fail OK
+        */
+    statusReg = readData.at(2);
+    co_return true;
+}
+
+sdbusplus::async::task<bool> CpldLatticeManager::readUserCode(
+    uint32_t& userCode)
+{
+    auto sched = context_friend::get_scheduler(ctx);
+    std::vector<uint8_t> command = {commandReadFwVersion, 0x0, 0x0, 0x0};
+    constexpr size_t resSize = 4;
+    std::vector<uint8_t> readData(resSize, 0);
+    bool success = co_await stdexec::starts_on(
+        sched, i2cInterface.sendReceive(command.data(), command.size(),
+                                        readData.data(), resSize));
+
+    if (!success)
+    {
+        co_return false;
+    }
+
+    for (size_t i = 0; i < resSize; i++)
+    {
+        userCode |= readData.at(i) << ((3 - i) * 8);
+    }
+    co_return true;
+}
+
+sdbusplus::async::task<bool> CpldLatticeManager::XO2XO3FamilyUpdate(
+    std::function<bool(int)> progressCallBack)
+{
+    if (progressCallBack == nullptr)
+    {
+        lg2::error("Error: progressCallBack is null.");
+        co_return false;
+    }
+
+    if (!(co_await readDeviceId()))
+    {
+        co_return false;
+    }
+    progressCallBack(10);
+
+    if (!jedFileParser())
+    {
+        lg2::error("JED file parsing failed");
+        co_return false;
+    }
+    progressCallBack(15);
+
+    if (!verifyChecksum())
+    {
+        lg2::error("Checksum verification failed");
+        co_return false;
+    }
+    progressCallBack(20);
+
+    if (!isLCMXO3D)
+    {
+        lg2::error("is not LCMXO3D");
+    }
+
+    lg2::debug("Starts to update ...");
+    lg2::debug("Enable program mode.");
+    progressCallBack(25);
+
+    co_await waitBusyAndVerify();
+
+    if (!(co_await enableProgramMode()))
+    {
+        lg2::error("Enable program mode failed.");
+        co_return false;
+    }
+    progressCallBack(30);
+
+    lg2::debug("Erase flash.");
+    if (!(co_await eraseFlash()))
+    {
+        lg2::error("Erase flash failed.");
+        co_return false;
+    }
+    progressCallBack(40);
+
+    lg2::debug("Reset config flash.");
+    if (!(co_await resetConfigFlash()))
+    {
+        lg2::error("Reset config flash failed.");
+        co_return false;
+    }
+    progressCallBack(50);
+
+    lg2::debug("Write program page ...");
+    if (!(co_await writeProgramPage()))
+    {
+        lg2::error("Write program page failed.");
+        co_return false;
+    }
+    lg2::debug("Write program page done.");
+    progressCallBack(60);
+
+    lg2::debug("Program user code.");
+    if (!(co_await programUserCode()))
+    {
+        lg2::error("Program user code failed.");
+        co_return false;
+    }
+    progressCallBack(70);
+
+    if (!(co_await programDone()))
+    {
+        lg2::error("Program not done.");
+        co_return false;
+    }
+    progressCallBack(80);
+
+    lg2::debug("Disable config interface.");
+    if (!(co_await disableConfigInterface()))
+    {
+        lg2::error("Disable Config Interface failed.");
+        co_return false;
+    }
+    progressCallBack(90);
+
+    lg2::debug("Update completed!");
+
+    co_return true;
+}
+
+sdbusplus::async::task<bool> CpldLatticeManager::updateFirmware(
+    std::function<bool(int)> progressCallBack)
+{
+    if (xo2xo3DeviceIdMap.find(chip) != xo2xo3DeviceIdMap.end())
+    {
+        co_return co_await XO2XO3FamilyUpdate(progressCallBack);
+    }
+    lg2::error("Unsupported chip type: {CHIP}", "CHIP", chip);
+    co_return false;
+}
+
+std::string uint32ToHexStr(uint32_t value)
+{
+    std::ostringstream oss;
+    oss << std::setfill('0') << std::setw(8) << std::hex << std::uppercase
+        << value;
+    return oss.str();
+}
+
+sdbusplus::async::task<bool> CpldLatticeManager::getVersion(
+    std::string& version)
+{
+    uint32_t userCode = 0;
+
+    if (target.empty())
+    {
+        if (!(co_await readUserCode(userCode)))
+        {
+            lg2::error("Read usercode failed.");
+            co_return false;
+        }
+
+        lg2::debug("CPLD version: {VERSION}", "VERSION", userCode);
+    }
+    else if (target == "CFG0" || target == "CFG1")
+    {
+        isLCMXO3D = true;
+        co_await waitBusyAndVerify();
+
+        if (!(co_await enableProgramMode()))
+        {
+            lg2::error("Enable program mode failed.");
+            co_return false;
+        }
+
+        if (!(co_await resetConfigFlash()))
+        {
+            lg2::error("Reset config flash failed.");
+            co_return false;
+        }
+
+        if (!(co_await readUserCode(userCode)))
+        {
+            lg2::error("Read usercode failed.");
+            co_return false;
+        }
+
+        if (!(co_await programDone()))
+        {
+            lg2::error("Program not done.");
+            co_return false;
+        }
+
+        if (!(co_await disableConfigInterface()))
+        {
+            lg2::error("Disable Config Interface failed.");
+            co_return false;
+        }
+
+        lg2::debug("CPLD {TARGET} version: {VERSION}", "TARGET", target,
+                   "VERSION", userCode);
+    }
+    else
+    {
+        lg2::error("Error: unknown target.");
+        co_return false;
+    }
+
+    if (userCode == 0)
+    {
+        lg2::error("User code is zero, cannot get version.");
+        co_return false;
+    }
+    version = uint32ToHexStr(userCode);
+    co_return true;
+}
diff --git a/cpld/lattice/lattice.hpp b/cpld/lattice/lattice.hpp
new file mode 100644
index 0000000..0bdc2bb
--- /dev/null
+++ b/cpld/lattice/lattice.hpp
@@ -0,0 +1,63 @@
+#pragma once
+#include "common/include/i2c/i2c.hpp"
+
+#include <chrono>
+#include <iostream>
+#include <string_view>
+#include <utility>
+
+struct cpldI2cInfo
+{
+    unsigned long int QF; // Quantity of Fuses
+    unsigned int* UFM;    // User Flash Memory
+    unsigned int version;
+    unsigned int checksum;
+    std::vector<uint8_t> cfgData;
+    std::vector<uint8_t> ufmData;
+};
+
+class CpldLatticeManager
+{
+  public:
+    CpldLatticeManager(sdbusplus::async::context& ctx, const uint16_t bus,
+                       const uint8_t address, const uint8_t* image,
+                       size_t imageSize, const std::string& chip,
+                       const std::string& target, const bool debugMode) :
+        ctx(ctx), image(image), imageSize(imageSize), chip(chip),
+        target(target), debugMode(debugMode),
+        i2cInterface(phosphor::i2c::I2C(bus, address))
+    {}
+    sdbusplus::async::task<bool> updateFirmware(
+        std::function<bool(int)> progressCallBack);
+    sdbusplus::async::task<bool> getVersion(std::string& version);
+
+  private:
+    sdbusplus::async::context& ctx;
+    cpldI2cInfo fwInfo{};
+    const uint8_t* image;
+    size_t imageSize;
+    std::string chip;
+    std::string target;
+    bool isLCMXO3D = false;
+    bool debugMode = false;
+    phosphor::i2c::I2C i2cInterface;
+
+    sdbusplus::async::task<bool> XO2XO3FamilyUpdate(
+        std::function<bool(int)> progressCallBack);
+
+    int indexof(const char* str, const char* ptn);
+    bool jedFileParser();
+    bool verifyChecksum();
+    sdbusplus::async::task<bool> readDeviceId();
+    sdbusplus::async::task<bool> enableProgramMode();
+    sdbusplus::async::task<bool> eraseFlash();
+    sdbusplus::async::task<bool> resetConfigFlash();
+    sdbusplus::async::task<bool> writeProgramPage();
+    sdbusplus::async::task<bool> programUserCode();
+    sdbusplus::async::task<bool> programDone();
+    sdbusplus::async::task<bool> disableConfigInterface();
+    sdbusplus::async::task<bool> readBusyFlag(uint8_t& busyFlag);
+    sdbusplus::async::task<bool> readStatusReg(uint8_t& statusReg);
+    sdbusplus::async::task<bool> waitBusyAndVerify();
+    sdbusplus::async::task<bool> readUserCode(uint32_t& userCode);
+};
diff --git a/cpld/meson.build b/cpld/meson.build
new file mode 100644
index 0000000..2ab8793
--- /dev/null
+++ b/cpld/meson.build
@@ -0,0 +1,31 @@
+cpld_src = files('cpld.cpp', 'cpld_interface.cpp', 'cpld_software_manager.cpp')
+
+cpld_vendor_src = files('lattice/interface.cpp', 'lattice/lattice.cpp')
+
+executable(
+    'phosphor-cpld-software-update',
+    cpld_src,
+    cpld_vendor_src,
+    include_directories: [include_directories('.'), common_include, libi2c_inc],
+    dependencies: [
+        pdi_dep,
+        phosphor_logging_dep,
+        sdbusplus_dep,
+        libpldm_dep,
+        libi2c_dep,
+    ],
+    link_with: [libpldmutil, software_common_lib, libi2c_dev],
+    link_args: '-li2c',
+    install_dir: get_option('libexecdir') / 'phosphor-code-mgmt',
+    install: true,
+)
+
+systemd_system_unit_dir = dependency('systemd').get_variable(
+    'systemdsystemunitdir',
+    pkgconfig_define: ['prefix', get_option('prefix')],
+)
+
+install_data(
+    'xyz.openbmc_project.Software.CPLD.service',
+    install_dir: systemd_system_unit_dir,
+)
diff --git a/cpld/xyz.openbmc_project.Software.CPLD.service b/cpld/xyz.openbmc_project.Software.CPLD.service
new file mode 100644
index 0000000..4ec7273
--- /dev/null
+++ b/cpld/xyz.openbmc_project.Software.CPLD.service
@@ -0,0 +1,14 @@
+[Unit]
+Description=CPLD Code Update Daemon
+After=xyz.openbmc_project.ObjectMapper
+After=xyz.openbmc_project.EntityManager.service
+
+[Service]
+Restart=always
+Type=dbus
+BusName=xyz.openbmc_project.Software.CPLD
+RemainAfterExit=no
+ExecStart=/usr/libexec/phosphor-code-mgmt/phosphor-cpld-software-update
+
+[Install]
+WantedBy=multi-user.target
diff --git a/meson.build b/meson.build
index 6a03c9a..f1a5428 100644
--- a/meson.build
+++ b/meson.build
@@ -72,6 +72,8 @@
     'i2cvr-software-update',
 ).allowed() or get_option(
     'eepromdevice-software-update',
+).allowed() or get_option(
+    'cpld-software-update',
 ).allowed()
 
 if common_build
@@ -90,8 +92,13 @@
     subdir('bios')
 endif
 
-if get_option('i2cvr-software-update').allowed()
+if get_option('i2cvr-software-update').allowed() or get_option(
+    'cpld-software-update',
+).allowed()
     subdir('common/i2c/')
+endif
+
+if get_option('i2cvr-software-update').allowed()
     subdir('i2c-vr')
 endif
 
@@ -99,6 +106,10 @@
     subdir('eeprom-device')
 endif
 
+if get_option('cpld-software-update').allowed()
+    subdir('cpld')
+endif
+
 if build_tests.allowed()
     subdir('test')
 endif
diff --git a/meson.options b/meson.options
index c178e69..6c09029 100644
--- a/meson.options
+++ b/meson.options
@@ -57,6 +57,13 @@
 )
 
 option(
+    'cpld-software-update',
+    type: 'feature',
+    value: 'enabled',
+    description: 'Enable update of CPLD',
+)
+
+option(
     'side-switch-on-boot',
     type: 'feature',
     value: 'enabled',
