diff --git a/phosphor-power-sequencer/src/README.md b/phosphor-power-sequencer/src/README.md
index 70213a1..91a1580 100644
--- a/phosphor-power-sequencer/src/README.md
+++ b/phosphor-power-sequencer/src/README.md
@@ -17,9 +17,10 @@
 interface.
 
 Determines the type and I2C information of the power sequencer device with the
-Entity Manager `xyz.openbmc_project.Configuration.UCD90320` interface. If a
-specific device interface is not provided or not desired, a generic base class
-implementation (see the `PowerSequencerMonitor` class below) will be used.
+Entity Manager `xyz.openbmc_project.Configuration.UCD90320` or
+`xyz.openbmc_project.Configuration.UCD90160` interface. If a specific device
+interface is not provided or not desired, a generic base class implementation
+(see the `PowerSequencerMonitor` class below) will be used.
 
 ### PowerInterface
 
@@ -39,9 +40,18 @@
 any device specific analysis and does not need Entity Manager or JSON file
 configuration.
 
+### UCD90xMonitor
+
+Defines a base class for monitoring the UCD90\* family of power sequencer
+devices and implements the common behavior. Uses the Entity Manager
+`IBMCompatibleSystem` interface to locate its JSON based configuration. The
+loaded configuration allows pgood failure analysis to determine the specific
+voltage rail or pgood pin which has failed.
+
 ### UCD90320Monitor
 
-Implements a specific UCD90320 power sequencer device monitoring class. Uses the
-Entity Manager `IBMCompatibleSystem` interface to locate its JSON based
-configuration. The loaded configuration allows pgood failure analysis to
-determine the specific voltage rail or pgood pin which has failed.
+Implements a specific UCD90320 power sequencer device monitoring class.
+
+### UCD90160Monitor
+
+Implements a specific UCD90160 power sequencer device monitoring class.
diff --git a/phosphor-power-sequencer/src/meson.build b/phosphor-power-sequencer/src/meson.build
index 3d1c8d0..de691c9 100644
--- a/phosphor-power-sequencer/src/meson.build
+++ b/phosphor-power-sequencer/src/meson.build
@@ -9,6 +9,8 @@
     'power_control.cpp',
     'power_interface.cpp',
     'power_sequencer_monitor.cpp',
+    'ucd90x_monitor.cpp',
+    'ucd90160_monitor.cpp',
     'ucd90320_monitor.cpp',
     dependencies: [
         libgpiodcxx,
diff --git a/phosphor-power-sequencer/src/power_sequencer_monitor.cpp b/phosphor-power-sequencer/src/power_sequencer_monitor.cpp
index 603dae1..3c8f999 100644
--- a/phosphor-power-sequencer/src/power_sequencer_monitor.cpp
+++ b/phosphor-power-sequencer/src/power_sequencer_monitor.cpp
@@ -22,7 +22,6 @@
 #include <phosphor-logging/log.hpp>
 
 #include <exception>
-#include <map>
 
 namespace phosphor::power::sequencer
 {
@@ -93,13 +92,12 @@
     else if (timeout)
     {
         // Default to timeout error
-        logError("xyz.openbmc_project.Power.Error.PowerOnTimeout",
-                 additionalData);
+        logError(powerOnTimeoutError, additionalData);
     }
     else
     {
         // Default to generic pgood error
-        logError("xyz.openbmc_project.Power.Error.Shutdown", additionalData);
+        logError(shutdownError, additionalData);
     }
     if (!timeout)
     {
diff --git a/phosphor-power-sequencer/src/power_sequencer_monitor.hpp b/phosphor-power-sequencer/src/power_sequencer_monitor.hpp
index ed095bb..740b0cd 100644
--- a/phosphor-power-sequencer/src/power_sequencer_monitor.hpp
+++ b/phosphor-power-sequencer/src/power_sequencer_monitor.hpp
@@ -8,6 +8,10 @@
 namespace phosphor::power::sequencer
 {
 
+constexpr auto powerOnTimeoutError =
+    "xyz.openbmc_project.Power.Error.PowerOnTimeout";
+constexpr auto shutdownError = "xyz.openbmc_project.Power.Error.Shutdown";
+
 /**
  * @class PowerSequencerMonitor
  * Define a base class for monitoring a power sequencer device.
@@ -52,7 +56,7 @@
      */
     sdbusplus::bus_t& bus;
 
-    /*
+    /**
      * Create a BMC Dump
      */
     void createBmcDump();
diff --git a/phosphor-power-sequencer/src/ucd90160_monitor.cpp b/phosphor-power-sequencer/src/ucd90160_monitor.cpp
new file mode 100644
index 0000000..f933230
--- /dev/null
+++ b/phosphor-power-sequencer/src/ucd90160_monitor.cpp
@@ -0,0 +1,27 @@
+/**
+ * Copyright © 2022 IBM Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ucd90160_monitor.hpp"
+
+namespace phosphor::power::sequencer
+{
+
+UCD90160Monitor::UCD90160Monitor(sdbusplus::bus_t& bus, std::uint8_t i2cBus,
+                                 std::uint16_t i2cAddress) :
+    UCD90xMonitor(bus, i2cBus, i2cAddress, "UCD90160", 16)
+{}
+
+} // namespace phosphor::power::sequencer
diff --git a/phosphor-power-sequencer/src/ucd90160_monitor.hpp b/phosphor-power-sequencer/src/ucd90160_monitor.hpp
new file mode 100644
index 0000000..31d4567
--- /dev/null
+++ b/phosphor-power-sequencer/src/ucd90160_monitor.hpp
@@ -0,0 +1,37 @@
+#pragma once
+
+#include "ucd90x_monitor.hpp"
+
+#include <sdbusplus/bus.hpp>
+
+#include <cstdint>
+
+namespace phosphor::power::sequencer
+{
+
+/**
+ * @class UCD90160Monitor
+ * This class implements fault analysis for the UCD90160
+ * power sequencer device.
+ */
+class UCD90160Monitor : public UCD90xMonitor
+{
+  public:
+    UCD90160Monitor() = delete;
+    UCD90160Monitor(const UCD90160Monitor&) = delete;
+    UCD90160Monitor& operator=(const UCD90160Monitor&) = delete;
+    UCD90160Monitor(UCD90160Monitor&&) = delete;
+    UCD90160Monitor& operator=(UCD90160Monitor&&) = delete;
+    virtual ~UCD90160Monitor() = default;
+
+    /**
+     * Create a device object for UCD90160 monitoring.
+     * @param bus D-Bus bus object
+     * @param i2cBus The bus number of the power sequencer device
+     * @param i2cAddress The I2C address of the power sequencer device
+     */
+    UCD90160Monitor(sdbusplus::bus_t& bus, std::uint8_t i2cBus,
+                    std::uint16_t i2cAddress);
+};
+
+} // namespace phosphor::power::sequencer
diff --git a/phosphor-power-sequencer/src/ucd90320_monitor.cpp b/phosphor-power-sequencer/src/ucd90320_monitor.cpp
index c6adcc0..818977b 100644
--- a/phosphor-power-sequencer/src/ucd90320_monitor.cpp
+++ b/phosphor-power-sequencer/src/ucd90320_monitor.cpp
@@ -16,378 +16,28 @@
 
 #include "ucd90320_monitor.hpp"
 
-#include "types.hpp"
-#include "utility.hpp"
-
 #include <fmt/format.h>
 #include <fmt/ranges.h>
 
-#include <nlohmann/json.hpp>
 #include <phosphor-logging/log.hpp>
-#include <sdbusplus/bus.hpp>
-#include <xyz/openbmc_project/Common/Device/error.hpp>
 
-#include <chrono>
-#include <fstream>
-#include <map>
 #include <span>
-#include <string>
 
 namespace phosphor::power::sequencer
 {
 
-using json = nlohmann::json;
-using namespace pmbus;
 using namespace phosphor::logging;
-using namespace phosphor::power;
-
-const std::string compatibleInterface =
-    "xyz.openbmc_project.Configuration.IBMCompatibleSystem";
-const std::string compatibleNamesProperty = "Names";
-
-namespace device_error = sdbusplus::xyz::openbmc_project::Common::Device::Error;
 
 UCD90320Monitor::UCD90320Monitor(sdbusplus::bus_t& bus, std::uint8_t i2cBus,
                                  std::uint16_t i2cAddress) :
-    PowerSequencerMonitor(bus),
-    match{bus,
-          sdbusplus::bus::match::rules::interfacesAdded() +
-              sdbusplus::bus::match::rules::sender(
-                  "xyz.openbmc_project.EntityManager"),
-          std::bind(&UCD90320Monitor::interfacesAddedHandler, this,
-                    std::placeholders::_1)},
-    pmbusInterface{
-        fmt::format("/sys/bus/i2c/devices/{}-{:04x}", i2cBus, i2cAddress)
-            .c_str(),
-        "ucd9000", 0}
+    UCD90xMonitor(bus, i2cBus, i2cAddress, "UCD90320", 32)
+{}
 
+void UCD90320Monitor::formatGpioValues(
+    const std::vector<int>& values, unsigned int numberLines,
+    std::map<std::string, std::string>& additionalData) const
 {
-    // Use the compatible system types information, if already available, to
-    // load the configuration file
-    findCompatibleSystemTypes();
-}
-
-void UCD90320Monitor::findCompatibleSystemTypes()
-{
-    try
-    {
-        auto subTree = util::getSubTree(bus, "/xyz/openbmc_project/inventory",
-                                        compatibleInterface, 0);
-
-        auto objectIt = subTree.cbegin();
-        if (objectIt != subTree.cend())
-        {
-            const auto& objPath = objectIt->first;
-
-            // Get the first service name
-            auto serviceIt = objectIt->second.cbegin();
-            if (serviceIt != objectIt->second.cend())
-            {
-                std::string service = serviceIt->first;
-                if (!service.empty())
-                {
-                    std::vector<std::string> compatibleSystemTypes;
-
-                    // Get compatible system types property value
-                    util::getProperty(compatibleInterface,
-                                      compatibleNamesProperty, objPath, service,
-                                      bus, compatibleSystemTypes);
-
-                    log<level::DEBUG>(
-                        fmt::format("Found compatible systems: {}",
-                                    compatibleSystemTypes)
-                            .c_str());
-                    // Use compatible systems information to find config file
-                    findConfigFile(compatibleSystemTypes);
-                }
-            }
-        }
-    }
-    catch (const std::exception&)
-    {
-        // Compatible system types information is not available.
-    }
-}
-
-void UCD90320Monitor::findConfigFile(
-    const std::vector<std::string>& compatibleSystemTypes)
-{
-    // Expected config file path name:
-    // /usr/share/phosphor-power-sequencer/UCD90320Monitor_<systemType>.json
-
-    // Add possible file names based on compatible system types (if any)
-    for (const std::string& systemType : compatibleSystemTypes)
-    {
-        // Check if file exists
-        std::filesystem::path pathName{
-            "/usr/share/phosphor-power-sequencer/UCD90320Monitor_" +
-            systemType + ".json"};
-        if (std::filesystem::exists(pathName))
-        {
-            log<level::INFO>(
-                fmt::format("Config file path: {}", pathName.string()).c_str());
-            parseConfigFile(pathName);
-            break;
-        }
-    }
-}
-
-void UCD90320Monitor::interfacesAddedHandler(sdbusplus::message_t& msg)
-{
-    // Only continue if message is valid and rails / pins have not already been
-    // found
-    if (!msg || !rails.empty())
-    {
-        return;
-    }
-
-    try
-    {
-        // Read the dbus message
-        sdbusplus::message::object_path objPath;
-        std::map<std::string,
-                 std::map<std::string, std::variant<std::vector<std::string>>>>
-            interfaces;
-        msg.read(objPath, interfaces);
-
-        // Find the compatible interface, if present
-        auto itIntf = interfaces.find(compatibleInterface);
-        if (itIntf != interfaces.cend())
-        {
-            // Find the Names property of the compatible interface, if present
-            auto itProp = itIntf->second.find(compatibleNamesProperty);
-            if (itProp != itIntf->second.cend())
-            {
-                // Get value of Names property
-                const auto& propValue = std::get<0>(itProp->second);
-                if (!propValue.empty())
-                {
-                    log<level::INFO>(
-                        fmt::format(
-                            "InterfacesAdded for compatible systems: {}",
-                            propValue)
-                            .c_str());
-
-                    // Use compatible systems information to find config file
-                    findConfigFile(propValue);
-                }
-            }
-        }
-    }
-    catch (const std::exception&)
-    {
-        // Error trying to read interfacesAdded message.
-    }
-}
-
-bool UCD90320Monitor::isPresent(const std::string& inventoryPath)
-{
-    // Empty path indicates no presence check is needed
-    if (inventoryPath.empty())
-    {
-        return true;
-    }
-
-    // Get presence from D-Bus interface/property
-    try
-    {
-        bool present{true};
-        util::getProperty(INVENTORY_IFACE, PRESENT_PROP, inventoryPath,
-                          INVENTORY_MGR_IFACE, bus, present);
-        log<level::INFO>(
-            fmt::format("Presence, path: {}, value: {}", inventoryPath, present)
-                .c_str());
-        return present;
-    }
-    catch (const std::exception& e)
-    {
-        log<level::INFO>(
-            fmt::format("Error getting presence property, path: {}, error: {}",
-                        inventoryPath, e.what())
-                .c_str());
-        return false;
-    }
-}
-
-void UCD90320Monitor::parseConfigFile(const std::filesystem::path& pathName)
-{
-    try
-    {
-        std::ifstream file{pathName};
-        json rootElement = json::parse(file);
-
-        // Parse rail information from config file
-        auto railsIterator = rootElement.find("rails");
-        if (railsIterator != rootElement.end())
-        {
-            for (const auto& railElement : *railsIterator)
-            {
-                auto nameIterator = railElement.find("name");
-
-                if (nameIterator != railElement.end())
-                {
-                    Rail rail;
-                    rail.name = (*nameIterator).get<std::string>();
-
-                    // Presence element is optional
-                    auto presenceIterator = railElement.find("presence");
-                    if (presenceIterator != railElement.end())
-                    {
-                        rail.presence = (*presenceIterator).get<std::string>();
-                    }
-
-                    log<level::DEBUG>(
-                        fmt::format("Adding rail, name: {}, presence: {}",
-                                    rail.name, rail.presence)
-                            .c_str());
-                    rails.emplace_back(std::move(rail));
-                }
-                else
-                {
-                    log<level::ERR>(
-                        fmt::format(
-                            "No name found within rail in configuration file: {}",
-                            pathName.string())
-                            .c_str());
-                }
-            }
-        }
-        else
-        {
-            log<level::ERR>(
-                fmt::format("No rails found in configuration file: {}",
-                            pathName.string())
-                    .c_str());
-        }
-        log<level::DEBUG>(
-            fmt::format("Found number of rails: {}", rails.size()).c_str());
-
-        // Parse pin information from config file
-        auto pinsIterator = rootElement.find("pins");
-        if (pinsIterator != rootElement.end())
-        {
-            for (const auto& pinElement : *pinsIterator)
-            {
-                auto nameIterator = pinElement.find("name");
-                auto lineIterator = pinElement.find("line");
-
-                if (nameIterator != pinElement.end() &&
-                    lineIterator != pinElement.end())
-                {
-                    Pin pin;
-                    pin.name = (*nameIterator).get<std::string>();
-                    pin.line = (*lineIterator).get<unsigned int>();
-
-                    // Presence element is optional
-                    auto presenceIterator = pinElement.find("presence");
-                    if (presenceIterator != pinElement.end())
-                    {
-                        pin.presence = (*presenceIterator).get<std::string>();
-                    }
-
-                    log<level::DEBUG>(
-                        fmt::format(
-                            "Adding pin, name: {}, line: {}, presence: {}",
-                            pin.name, pin.line, pin.presence)
-                            .c_str());
-                    pins.emplace_back(std::move(pin));
-                }
-                else
-                {
-                    log<level::ERR>(
-                        fmt::format(
-                            "No name or line found within pin in configuration file: {}",
-                            pathName.string())
-                            .c_str());
-                }
-            }
-        }
-        else
-        {
-            log<level::ERR>(
-                fmt::format("No pins found in configuration file: {}",
-                            pathName.string())
-                    .c_str());
-        }
-        log<level::DEBUG>(
-            fmt::format("Found number of pins: {}", pins.size()).c_str());
-    }
-    catch (const std::exception& e)
-    {
-        log<level::ERR>(
-            fmt::format("Error parsing configuration file, error: {}", e.what())
-                .c_str());
-    }
-}
-
-void UCD90320Monitor::onFailure(bool timeout,
-                                const std::string& powerSupplyError)
-{
-    std::string message;
-    std::map<std::string, std::string> additionalData{};
-
-    try
-    {
-        onFailureCheckRails(message, additionalData, powerSupplyError);
-        onFailureCheckPins(message, additionalData);
-    }
-    catch (const std::exception& e)
-    {
-        log<level::ERR>(
-            fmt::format("Error when collecting metadata, error: {}", e.what())
-                .c_str());
-        additionalData.emplace("ERROR", e.what());
-    }
-
-    if (message.empty())
-    {
-        // Could not isolate, but we know something failed, so issue a timeout
-        // or generic power good error
-        message = timeout ? "xyz.openbmc_project.Power.Error.PowerOnTimeout"
-                          : "xyz.openbmc_project.Power.Error.Shutdown";
-    }
-    logError(message, additionalData);
-    if (!timeout)
-    {
-        createBmcDump();
-    }
-}
-
-void UCD90320Monitor::onFailureCheckPins(
-    std::string& message, std::map<std::string, std::string>& additionalData)
-{
-    // Setup a list of all the GPIOs on the chip
-    gpiod::chip chip{"ucd90320", gpiod::chip::OPEN_BY_LABEL};
-    log<level::INFO>(fmt::format("GPIO chip name: {}", chip.name()).c_str());
-    log<level::INFO>(fmt::format("GPIO chip label: {}", chip.label()).c_str());
-    unsigned int numberLines = chip.num_lines();
-    log<level::INFO>(
-        fmt::format("GPIO chip number of lines: {}", numberLines).c_str());
-
-    // Workaround libgpiod bulk line maximum by getting values from individual
-    // lines
-    std::vector<int> values;
-    try
-    {
-        for (unsigned int offset = 0; offset < numberLines; ++offset)
-        {
-            gpiod::line line = chip.get_line(offset);
-            line.request({"phosphor-power-control",
-                          gpiod::line_request::DIRECTION_INPUT, 0});
-            values.push_back(line.get_value());
-            line.release();
-        }
-    }
-    catch (const std::exception& e)
-    {
-        log<level::ERR>(
-            fmt::format("Error reading device GPIOs, error: {}", e.what())
-                .c_str());
-        additionalData.emplace("GPIO_ERROR", e.what());
-    }
-
-    // Add GPIO values to additional data, device has 84 GPIO pins so that value
-    // is expected
+    // Device has 84 GPIO pins so that value is expected
     if (numberLines == 84 && values.size() >= 84)
     {
         log<level::INFO>(fmt::format("MAR01-24 GPIO values: {}",
@@ -426,114 +76,6 @@
         log<level::INFO>(fmt::format("GPIO values: {}", values).c_str());
         additionalData.emplace("GPIO_VALUES", fmt::format("{}", values));
     }
-
-    // Only check GPIOs if no rail fail was found
-    if (message.empty())
-    {
-        for (size_t pin = 0; pin < pins.size(); ++pin)
-        {
-            unsigned int line = pins[pin].line;
-            if (line < values.size())
-            {
-                int value = values[line];
-
-                if ((value == 0) && isPresent(pins[pin].presence))
-                {
-                    additionalData.emplace("INPUT_NUM",
-                                           fmt::format("{}", line));
-                    additionalData.emplace("INPUT_NAME", pins[pin].name);
-                    message =
-                        "xyz.openbmc_project.Power.Error.PowerSequencerPGOODFault";
-                    return;
-                }
-            }
-        }
-    }
-}
-
-void UCD90320Monitor::onFailureCheckRails(
-    std::string& message, std::map<std::string, std::string>& additionalData,
-    const std::string& powerSupplyError)
-{
-    auto statusWord = readStatusWord();
-    additionalData.emplace("STATUS_WORD", fmt::format("{:#06x}", statusWord));
-    try
-    {
-        additionalData.emplace("MFR_STATUS",
-                               fmt::format("{:#014x}", readMFRStatus()));
-    }
-    catch (const std::exception& e)
-    {
-        log<level::ERR>(
-            fmt::format("Error when collecting MFR_STATUS, error: {}", e.what())
-                .c_str());
-        additionalData.emplace("ERROR", e.what());
-    }
-
-    // The status_word register has a summary bit to tell us if each page even
-    // needs to be checked
-    if (statusWord & status_word::VOUT_FAULT)
-    {
-        constexpr size_t numberPages = 32;
-        for (size_t page = 0; page < numberPages; page++)
-        {
-            auto statusVout = pmbusInterface.insertPageNum(STATUS_VOUT, page);
-            if (pmbusInterface.exists(statusVout, Type::Debug))
-            {
-                uint8_t vout = pmbusInterface.read(statusVout, Type::Debug);
-
-                if (vout)
-                {
-                    // If any bits are on log them, though some are just
-                    // warnings so they won't cause errors
-                    log<level::INFO>(
-                        fmt::format("{}, value: {:#04x}", statusVout, vout)
-                            .c_str());
-
-                    // Log errors if any non-warning bits on
-                    if (vout & ~status_vout::WARNING_MASK)
-                    {
-                        additionalData.emplace(
-                            fmt::format("STATUS{}_VOUT", page),
-                            fmt::format("{:#04x}", vout));
-
-                        // Base the callouts on the first present vout failure
-                        // found
-                        if (message.empty() && (page < rails.size()) &&
-                            isPresent(rails[page].presence))
-                        {
-                            additionalData.emplace("RAIL_NAME",
-                                                   rails[page].name);
-
-                            // Use power supply error if set and 12v rail has
-                            // failed, else use voltage error
-                            message =
-                                ((page == 0) && !powerSupplyError.empty())
-                                    ? powerSupplyError
-                                    : "xyz.openbmc_project.Power.Error.PowerSequencerVoltageFault";
-                        }
-                    }
-                }
-            }
-        }
-    }
-    // If no vout failure found, but power supply error is set, use power supply
-    // error
-    if (message.empty())
-    {
-        message = powerSupplyError;
-    }
-}
-
-uint16_t UCD90320Monitor::readStatusWord()
-{
-    return pmbusInterface.read(STATUS_WORD, Type::Debug);
-}
-
-uint64_t UCD90320Monitor::readMFRStatus()
-{
-    const std::string mfrStatus = "mfr_status";
-    return pmbusInterface.read(mfrStatus, Type::HwmonDeviceDebug);
 }
 
 } // namespace phosphor::power::sequencer
diff --git a/phosphor-power-sequencer/src/ucd90320_monitor.hpp b/phosphor-power-sequencer/src/ucd90320_monitor.hpp
index 9bcbf77..a40456d 100644
--- a/phosphor-power-sequencer/src/ucd90320_monitor.hpp
+++ b/phosphor-power-sequencer/src/ucd90320_monitor.hpp
@@ -1,37 +1,23 @@
 #pragma once
 
-#include "pmbus.hpp"
-#include "power_sequencer_monitor.hpp"
+#include "ucd90x_monitor.hpp"
 
-#include <gpiod.hpp>
 #include <sdbusplus/bus.hpp>
-#include <sdbusplus/bus/match.hpp>
 
-#include <filesystem>
+#include <cstdint>
+#include <map>
+#include <string>
 #include <vector>
 
 namespace phosphor::power::sequencer
 {
 
-struct Pin
-{
-    std::string name;
-    unsigned int line;
-    std::string presence;
-};
-
-struct Rail
-{
-    std::string name;
-    std::string presence;
-};
-
 /**
  * @class UCD90320Monitor
  * This class implements fault analysis for the UCD90320
  * power sequencer device.
  */
-class UCD90320Monitor : public PowerSequencerMonitor
+class UCD90320Monitor : public UCD90xMonitor
 {
   public:
     UCD90320Monitor() = delete;
@@ -50,103 +36,11 @@
     UCD90320Monitor(sdbusplus::bus_t& bus, std::uint8_t i2cBus,
                     std::uint16_t i2cAddress);
 
-    /**
-     * Callback function to handle interfacesAdded D-Bus signals
-     * @param msg Expanded sdbusplus message data
-     */
-    void interfacesAddedHandler(sdbusplus::message_t& msg);
-
-    /** @copydoc PowerSequencerMonitor::onFailure() */
-    void onFailure(bool timeout, const std::string& powerSupplyError) override;
-
-  private:
-    /**
-     * The match to Entity Manager interfaces added.
-     */
-    sdbusplus::bus::match_t match;
-
-    /**
-     * List of pins
-     */
-    std::vector<Pin> pins;
-
-    /**
-     * The read/write interface to this hardware
-     */
-    pmbus::PMBus pmbusInterface;
-
-    /**
-     * List of rails
-     */
-    std::vector<Rail> rails;
-
-    /**
-     * Finds the list of compatible system types using D-Bus methods.
-     * This list is used to find the correct JSON configuration file for the
-     * current system.
-     */
-    void findCompatibleSystemTypes();
-
-    /**
-     * Finds the JSON configuration file.
-     * Looks for a configuration file based on the list of compatible system
-     * types.
-     * Throws an exception if an operating system error occurs while checking
-     * for the existance of a file.
-     * @param compatibleSystemTypes List of compatible system types
-     */
-    void findConfigFile(const std::vector<std::string>& compatibleSystemTypes);
-
-    /**
-     * Returns whether the hardware with the specified inventory path is
-     * present.
-     * If an error occurs while obtaining the presence value, presence is
-     * assumed to be false. An empty string path indicates no presence check is
-     * needed.
-     * @param inventoryPath D-Bus inventory path of the hardware
-     * @return true if hardware is present, false otherwise
-     */
-    bool isPresent(const std::string& inventoryPath);
-
-    /**
-     * Analyzes the device pins for errors when the device is known to be in an
-     * error state.
-     * @param message Message property of the error log entry
-     * @param additionalData AdditionalData property of the error log entry
-     */
-    void onFailureCheckPins(std::string& message,
-                            std::map<std::string, std::string>& additionalData);
-
-    /**
-     * Analyzes the device rails for errors when the device is known to be in an
-     * error state.
-     * @param message Message property of the error log entry
-     * @param additionalData AdditionalData property of the error log entry
-     * @param powerSupplyError The power supply error to log. A default
-     * std:string, i.e. empty string (""), is passed when there is no power
-     * supply error to log.
-     */
-    void onFailureCheckRails(std::string& message,
-                             std::map<std::string, std::string>& additionalData,
-                             const std::string& powerSupplyError);
-
-    /**
-     * Parse the JSON configuration file.
-     * @param pathName the path name
-     */
-    void parseConfigFile(const std::filesystem::path& pathName);
-
-    /**
-     * Reads the mfr_status register
-     * @return the register contents
-     */
-    uint64_t readMFRStatus();
-
-    /**
-     * Reads the status_word register
-     * @return the register contents
-     */
-    uint16_t readStatusWord();
+  protected:
+    /** @copydoc UCD90xMonitor::formatGpioValues() */
+    void formatGpioValues(
+        const std::vector<int>& values, unsigned int numberLines,
+        std::map<std::string, std::string>& additionalData) const override;
 };
 
 } // namespace phosphor::power::sequencer
diff --git a/phosphor-power-sequencer/src/ucd90x_monitor.cpp b/phosphor-power-sequencer/src/ucd90x_monitor.cpp
new file mode 100644
index 0000000..2dc4675
--- /dev/null
+++ b/phosphor-power-sequencer/src/ucd90x_monitor.cpp
@@ -0,0 +1,564 @@
+/**
+ * Copyright © 2022 IBM Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ucd90x_monitor.hpp"
+
+#include "types.hpp"
+#include "utility.hpp"
+
+#include <fmt/format.h>
+#include <fmt/ranges.h>
+
+#include <gpiod.hpp>
+#include <nlohmann/json.hpp>
+#include <phosphor-logging/log.hpp>
+
+#include <algorithm>
+#include <chrono>
+#include <exception>
+#include <fstream>
+
+namespace phosphor::power::sequencer
+{
+
+using json = nlohmann::json;
+using namespace pmbus;
+using namespace phosphor::logging;
+
+const std::string compatibleInterface =
+    "xyz.openbmc_project.Configuration.IBMCompatibleSystem";
+const std::string compatibleNamesProperty = "Names";
+
+UCD90xMonitor::UCD90xMonitor(sdbusplus::bus_t& bus, std::uint8_t i2cBus,
+                             std::uint16_t i2cAddress,
+                             const std::string& deviceName,
+                             size_t numberPages) :
+    PowerSequencerMonitor(bus),
+    deviceName{deviceName},
+    match{bus,
+          sdbusplus::bus::match::rules::interfacesAdded() +
+              sdbusplus::bus::match::rules::sender(
+                  "xyz.openbmc_project.EntityManager"),
+          std::bind(&UCD90xMonitor::interfacesAddedHandler, this,
+                    std::placeholders::_1)},
+    numberPages{numberPages},
+    pmbusInterface{
+        fmt::format("/sys/bus/i2c/devices/{}-{:04x}", i2cBus, i2cAddress)
+            .c_str(),
+        "ucd9000", 0}
+{
+    log<level::DEBUG>(
+        fmt::format("Device path: {}", pmbusInterface.path().string()).c_str());
+    log<level::DEBUG>(fmt::format("Hwmon path: {}",
+                                  pmbusInterface.getPath(Type::Hwmon).string())
+                          .c_str());
+    log<level::DEBUG>(fmt::format("Debug path: {}",
+                                  pmbusInterface.getPath(Type::Debug).string())
+                          .c_str());
+    log<level::DEBUG>(
+        fmt::format("Device debug path: {}",
+                    pmbusInterface.getPath(Type::DeviceDebug).string())
+            .c_str());
+    log<level::DEBUG>(
+        fmt::format("Hwmon device debug path: {}",
+                    pmbusInterface.getPath(Type::HwmonDeviceDebug).string())
+            .c_str());
+
+    // Use the compatible system types information, if already available, to
+    // load the configuration file
+    findCompatibleSystemTypes();
+}
+
+void UCD90xMonitor::findCompatibleSystemTypes()
+{
+    try
+    {
+        auto subTree = util::getSubTree(bus, "/xyz/openbmc_project/inventory",
+                                        compatibleInterface, 0);
+
+        auto objectIt = subTree.cbegin();
+        if (objectIt != subTree.cend())
+        {
+            const auto& objPath = objectIt->first;
+
+            // Get the first service name
+            auto serviceIt = objectIt->second.cbegin();
+            if (serviceIt != objectIt->second.cend())
+            {
+                std::string service = serviceIt->first;
+                if (!service.empty())
+                {
+                    std::vector<std::string> compatibleSystemTypes;
+
+                    // Get compatible system types property value
+                    util::getProperty(compatibleInterface,
+                                      compatibleNamesProperty, objPath, service,
+                                      bus, compatibleSystemTypes);
+
+                    log<level::DEBUG>(
+                        fmt::format("Found compatible systems: {}",
+                                    compatibleSystemTypes)
+                            .c_str());
+                    // Use compatible systems information to find config file
+                    findConfigFile(compatibleSystemTypes);
+                }
+            }
+        }
+    }
+    catch (const std::exception&)
+    {
+        // Compatible system types information is not available.
+    }
+}
+
+void UCD90xMonitor::findConfigFile(
+    const std::vector<std::string>& compatibleSystemTypes)
+{
+    // Expected config file path name:
+    // /usr/share/phosphor-power-sequencer/<deviceName>Monitor_<systemType>.json
+
+    // Add possible file names based on compatible system types (if any)
+    for (const std::string& systemType : compatibleSystemTypes)
+    {
+        // Check if file exists
+        std::filesystem::path pathName{"/usr/share/phosphor-power-sequencer/" +
+                                       deviceName + "Monitor_" + systemType +
+                                       ".json"};
+        log<level::DEBUG>(
+            fmt::format("Attempting config file path: {}", pathName.string())
+                .c_str());
+        if (std::filesystem::exists(pathName))
+        {
+            log<level::INFO>(
+                fmt::format("Config file path: {}", pathName.string()).c_str());
+            parseConfigFile(pathName);
+            break;
+        }
+    }
+}
+
+void UCD90xMonitor::interfacesAddedHandler(sdbusplus::message_t& msg)
+{
+    // Only continue if message is valid and rails / pins have not already been
+    // found
+    if (!msg || !rails.empty())
+    {
+        return;
+    }
+
+    try
+    {
+        // Read the dbus message
+        sdbusplus::message::object_path objPath;
+        std::map<std::string,
+                 std::map<std::string, std::variant<std::vector<std::string>>>>
+            interfaces;
+        msg.read(objPath, interfaces);
+
+        // Find the compatible interface, if present
+        auto itIntf = interfaces.find(compatibleInterface);
+        if (itIntf != interfaces.cend())
+        {
+            // Find the Names property of the compatible interface, if present
+            auto itProp = itIntf->second.find(compatibleNamesProperty);
+            if (itProp != itIntf->second.cend())
+            {
+                // Get value of Names property
+                const auto& propValue = std::get<0>(itProp->second);
+                if (!propValue.empty())
+                {
+                    log<level::INFO>(
+                        fmt::format(
+                            "InterfacesAdded for compatible systems: {}",
+                            propValue)
+                            .c_str());
+
+                    // Use compatible systems information to find config file
+                    findConfigFile(propValue);
+                }
+            }
+        }
+    }
+    catch (const std::exception&)
+    {
+        // Error trying to read interfacesAdded message.
+    }
+}
+
+bool UCD90xMonitor::isPresent(const std::string& inventoryPath)
+{
+    // Empty path indicates no presence check is needed
+    if (inventoryPath.empty())
+    {
+        return true;
+    }
+
+    // Get presence from D-Bus interface/property
+    try
+    {
+        bool present{true};
+        util::getProperty(INVENTORY_IFACE, PRESENT_PROP, inventoryPath,
+                          INVENTORY_MGR_IFACE, bus, present);
+        log<level::INFO>(
+            fmt::format("Presence, path: {}, value: {}", inventoryPath, present)
+                .c_str());
+        return present;
+    }
+    catch (const std::exception& e)
+    {
+        log<level::INFO>(
+            fmt::format("Error getting presence property, path: {}, error: {}",
+                        inventoryPath, e.what())
+                .c_str());
+        return false;
+    }
+}
+
+void UCD90xMonitor::formatGpioValues(
+    const std::vector<int>& values, unsigned int /*numberLines*/,
+    std::map<std::string, std::string>& additionalData) const
+{
+    log<level::INFO>(fmt::format("GPIO values: {}", values).c_str());
+    additionalData.emplace("GPIO_VALUES", fmt::format("{}", values));
+}
+
+void UCD90xMonitor::onFailure(bool timeout, const std::string& powerSupplyError)
+{
+    std::string message;
+    std::map<std::string, std::string> additionalData{};
+
+    try
+    {
+        onFailureCheckRails(message, additionalData, powerSupplyError);
+        log<level::DEBUG>(
+            fmt::format("After onFailureCheckRails, message: {}", message)
+                .c_str());
+        onFailureCheckPins(message, additionalData);
+        log<level::DEBUG>(
+            fmt::format("After onFailureCheckPins, message: {}", message)
+                .c_str());
+    }
+    catch (const std::exception& e)
+    {
+        log<level::ERR>(
+            fmt::format("Error when collecting metadata, error: {}", e.what())
+                .c_str());
+        additionalData.emplace("ERROR", e.what());
+    }
+
+    if (message.empty())
+    {
+        // Could not isolate, but we know something failed, so issue a timeout
+        // or generic power good error
+        message = timeout ? powerOnTimeoutError : shutdownError;
+    }
+    logError(message, additionalData);
+    if (!timeout)
+    {
+        createBmcDump();
+    }
+}
+
+void UCD90xMonitor::onFailureCheckPins(
+    std::string& message, std::map<std::string, std::string>& additionalData)
+{
+    // Create a lower case version of device name to use as label in libgpiod
+    std::string label{deviceName};
+    std::transform(label.begin(), label.end(), label.begin(), ::tolower);
+
+    // Setup a list of all the GPIOs on the chip
+    gpiod::chip chip{label, gpiod::chip::OPEN_BY_LABEL};
+    log<level::INFO>(fmt::format("GPIO chip name: {}", chip.name()).c_str());
+    log<level::INFO>(fmt::format("GPIO chip label: {}", chip.label()).c_str());
+    unsigned int numberLines = chip.num_lines();
+    log<level::INFO>(
+        fmt::format("GPIO chip number of lines: {}", numberLines).c_str());
+
+    // Workaround libgpiod bulk line maximum by getting values from individual
+    // lines
+    std::vector<int> values;
+    try
+    {
+        for (unsigned int offset = 0; offset < numberLines; ++offset)
+        {
+            gpiod::line line = chip.get_line(offset);
+            line.request({"phosphor-power-control",
+                          gpiod::line_request::DIRECTION_INPUT, 0});
+            values.push_back(line.get_value());
+            line.release();
+        }
+    }
+    catch (const std::exception& e)
+    {
+        log<level::ERR>(
+            fmt::format("Error reading device GPIOs, error: {}", e.what())
+                .c_str());
+        additionalData.emplace("GPIO_ERROR", e.what());
+    }
+
+    formatGpioValues(values, numberLines, additionalData);
+
+    // Only check GPIOs if no rail fail was found
+    if (message.empty())
+    {
+        for (size_t pin = 0; pin < pins.size(); ++pin)
+        {
+            unsigned int line = pins[pin].line;
+            if (line < values.size())
+            {
+                int value = values[line];
+
+                if ((value == 0) && isPresent(pins[pin].presence))
+                {
+                    additionalData.emplace("INPUT_NUM",
+                                           fmt::format("{}", line));
+                    additionalData.emplace("INPUT_NAME", pins[pin].name);
+                    message =
+                        "xyz.openbmc_project.Power.Error.PowerSequencerPGOODFault";
+                    return;
+                }
+            }
+        }
+    }
+}
+
+void UCD90xMonitor::onFailureCheckRails(
+    std::string& message, std::map<std::string, std::string>& additionalData,
+    const std::string& powerSupplyError)
+{
+    auto statusWord = readStatusWord();
+    additionalData.emplace("STATUS_WORD", fmt::format("{:#06x}", statusWord));
+    try
+    {
+        additionalData.emplace("MFR_STATUS",
+                               fmt::format("{:#014x}", readMFRStatus()));
+    }
+    catch (const std::exception& e)
+    {
+        log<level::ERR>(
+            fmt::format("Error when collecting MFR_STATUS, error: {}", e.what())
+                .c_str());
+        additionalData.emplace("ERROR", e.what());
+    }
+
+    // The status_word register has a summary bit to tell us if each page even
+    // needs to be checked
+    if (statusWord & status_word::VOUT_FAULT)
+    {
+        for (size_t page = 0; page < numberPages; page++)
+        {
+            auto statusVout = pmbusInterface.insertPageNum(STATUS_VOUT, page);
+            if (pmbusInterface.exists(statusVout, Type::Debug))
+            {
+                uint8_t vout = pmbusInterface.read(statusVout, Type::Debug);
+
+                if (vout)
+                {
+                    // If any bits are on log them, though some are just
+                    // warnings so they won't cause errors
+                    log<level::INFO>(
+                        fmt::format("{}, value: {:#04x}", statusVout, vout)
+                            .c_str());
+
+                    // Log errors if any non-warning bits on
+                    if (vout & ~status_vout::WARNING_MASK)
+                    {
+                        additionalData.emplace(
+                            fmt::format("STATUS{}_VOUT", page),
+                            fmt::format("{:#04x}", vout));
+
+                        // Base the callouts on the first present vout failure
+                        // found
+                        if (message.empty() && (page < rails.size()) &&
+                            isPresent(rails[page].presence))
+                        {
+                            additionalData.emplace("RAIL_NAME",
+                                                   rails[page].name);
+
+                            // Use power supply error if set and 12v rail has
+                            // failed, else use voltage error
+                            message =
+                                ((page == 0) && !powerSupplyError.empty())
+                                    ? powerSupplyError
+                                    : "xyz.openbmc_project.Power.Error.PowerSequencerVoltageFault";
+                        }
+                    }
+                }
+            }
+        }
+    }
+    // If no vout failure found, but power supply error is set, use power supply
+    // error
+    if (message.empty())
+    {
+        message = powerSupplyError;
+    }
+}
+
+void UCD90xMonitor::parseConfigFile(const std::filesystem::path& pathName)
+{
+    try
+    {
+        log<level::DEBUG>(
+            std::string("Loading configuration file " + pathName.string())
+                .c_str());
+
+        std::ifstream file{pathName};
+        json rootElement = json::parse(file);
+        log<level::DEBUG>(fmt::format("Parsed, root element is_object: {}",
+                                      rootElement.is_object())
+                              .c_str());
+
+        // Parse rail information from config file
+        auto railsIterator = rootElement.find("rails");
+        if (railsIterator != rootElement.end())
+        {
+            for (const auto& railElement : *railsIterator)
+            {
+                log<level::DEBUG>(fmt::format("Rail element is_object: {}",
+                                              railElement.is_object())
+                                      .c_str());
+
+                auto nameIterator = railElement.find("name");
+                if (nameIterator != railElement.end())
+                {
+                    log<level::DEBUG>(fmt::format("Name element is_string: {}",
+                                                  (*nameIterator).is_string())
+                                          .c_str());
+                    Rail rail;
+                    rail.name = (*nameIterator).get<std::string>();
+
+                    // Presence element is optional
+                    auto presenceIterator = railElement.find("presence");
+                    if (presenceIterator != railElement.end())
+                    {
+                        log<level::DEBUG>(
+                            fmt::format("Presence element is_string: {}",
+                                        (*presenceIterator).is_string())
+                                .c_str());
+
+                        rail.presence = (*presenceIterator).get<std::string>();
+                    }
+
+                    log<level::DEBUG>(
+                        fmt::format("Adding rail, name: {}, presence: {}",
+                                    rail.name, rail.presence)
+                            .c_str());
+                    rails.emplace_back(std::move(rail));
+                }
+                else
+                {
+                    log<level::ERR>(
+                        fmt::format(
+                            "No name found within rail in configuration file: {}",
+                            pathName.string())
+                            .c_str());
+                }
+            }
+        }
+        else
+        {
+            log<level::ERR>(
+                fmt::format("No rails found in configuration file: {}",
+                            pathName.string())
+                    .c_str());
+        }
+        log<level::DEBUG>(
+            fmt::format("Found number of rails: {}", rails.size()).c_str());
+
+        // Parse pin information from config file
+        auto pinsIterator = rootElement.find("pins");
+        if (pinsIterator != rootElement.end())
+        {
+            for (const auto& pinElement : *pinsIterator)
+            {
+                log<level::DEBUG>(fmt::format("Pin element is_object: {}",
+                                              pinElement.is_object())
+                                      .c_str());
+                auto nameIterator = pinElement.find("name");
+                auto lineIterator = pinElement.find("line");
+                if (nameIterator != pinElement.end() &&
+                    lineIterator != pinElement.end())
+                {
+                    log<level::DEBUG>(fmt::format("Name element is_string: {}",
+                                                  (*nameIterator).is_string())
+                                          .c_str());
+                    log<level::DEBUG>(
+                        fmt::format("Line element is_number_integer: {}",
+                                    (*lineIterator).is_number_integer())
+                            .c_str());
+                    Pin pin;
+                    pin.name = (*nameIterator).get<std::string>();
+                    pin.line = (*lineIterator).get<unsigned int>();
+
+                    // Presence element is optional
+                    auto presenceIterator = pinElement.find("presence");
+                    if (presenceIterator != pinElement.end())
+                    {
+                        log<level::DEBUG>(
+                            fmt::format("Presence element is_string: {}",
+                                        (*presenceIterator).is_string())
+                                .c_str());
+                        pin.presence = (*presenceIterator).get<std::string>();
+                    }
+
+                    log<level::DEBUG>(
+                        fmt::format(
+                            "Adding pin, name: {}, line: {}, presence: {}",
+                            pin.name, pin.line, pin.presence)
+                            .c_str());
+                    pins.emplace_back(std::move(pin));
+                }
+                else
+                {
+                    log<level::ERR>(
+                        fmt::format(
+                            "No name or line found within pin in configuration file: {}",
+                            pathName.string())
+                            .c_str());
+                }
+            }
+        }
+        else
+        {
+            log<level::ERR>(
+                fmt::format("No pins found in configuration file: {}",
+                            pathName.string())
+                    .c_str());
+        }
+        log<level::DEBUG>(
+            fmt::format("Found number of pins: {}", pins.size()).c_str());
+    }
+    catch (const std::exception& e)
+    {
+        log<level::ERR>(
+            fmt::format("Error parsing configuration file, error: {}", e.what())
+                .c_str());
+    }
+}
+
+uint16_t UCD90xMonitor::readStatusWord()
+{
+    return pmbusInterface.read(STATUS_WORD, Type::Debug);
+}
+
+uint64_t UCD90xMonitor::readMFRStatus()
+{
+    const std::string mfrStatus = "mfr_status";
+    return pmbusInterface.read(mfrStatus, Type::HwmonDeviceDebug);
+}
+
+} // namespace phosphor::power::sequencer
diff --git a/phosphor-power-sequencer/src/ucd90x_monitor.hpp b/phosphor-power-sequencer/src/ucd90x_monitor.hpp
new file mode 100644
index 0000000..f52046c
--- /dev/null
+++ b/phosphor-power-sequencer/src/ucd90x_monitor.hpp
@@ -0,0 +1,178 @@
+#pragma once
+
+#include "pmbus.hpp"
+#include "power_sequencer_monitor.hpp"
+
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/bus/match.hpp>
+
+#include <cstdint>
+#include <filesystem>
+#include <map>
+#include <string>
+#include <vector>
+
+namespace phosphor::power::sequencer
+{
+
+struct Pin
+{
+    std::string name;
+    unsigned int line;
+    std::string presence;
+};
+
+struct Rail
+{
+    std::string name;
+    std::string presence;
+};
+
+/**
+ * @class UCD90xMonitor
+ * Define a base class for monitoring the UCD90* family of power sequencer
+ * devices.
+ */
+class UCD90xMonitor : public PowerSequencerMonitor
+{
+  public:
+    UCD90xMonitor() = delete;
+    UCD90xMonitor(const UCD90xMonitor&) = delete;
+    UCD90xMonitor& operator=(const UCD90xMonitor&) = delete;
+    UCD90xMonitor(UCD90xMonitor&&) = delete;
+    UCD90xMonitor& operator=(UCD90xMonitor&&) = delete;
+    virtual ~UCD90xMonitor() = default;
+
+    /**
+     * Create a base object for UCD90* monitoring.
+     * @param bus D-Bus bus object
+     * @param i2cBus The bus number of the power sequencer device
+     * @param i2cAddress The I2C address of the power sequencer device
+     * @param deviceName The name of the device
+     * @param numberPages The number of pages the PMBus device supports
+     */
+    UCD90xMonitor(sdbusplus::bus_t& bus, std::uint8_t i2cBus,
+                  std::uint16_t i2cAddress, const std::string& deviceName,
+                  size_t numberPages);
+
+    /**
+     * Callback function to handle interfacesAdded D-Bus signals
+     * @param msg Expanded sdbusplus message data
+     */
+    void interfacesAddedHandler(sdbusplus::message_t& msg);
+
+    /** @copydoc PowerSequencerMonitor::onFailure() */
+    void onFailure(bool timeout, const std::string& powerSupplyError) override;
+
+  protected:
+    /**
+     * Formats the GPIO values read from the device.
+     * @param values List of GPIO values
+     * @param numberLines Number of GPIO lines
+     * @param additionalData AdditionalData property of the error log entry
+     */
+    virtual void formatGpioValues(
+        const std::vector<int>& values, unsigned int numberLines,
+        std::map<std::string, std::string>& additionalData) const;
+
+  private:
+    /**
+     * Device name
+     */
+    std::string deviceName;
+
+    /**
+     * The match to Entity Manager interfaces added.
+     */
+    sdbusplus::bus::match_t match;
+
+    /**
+     * The number of pages the PMBus device supports
+     */
+    size_t numberPages;
+
+    /**
+     * List of pins
+     */
+    std::vector<Pin> pins;
+
+    /**
+     * The read/write interface to this hardware
+     */
+    pmbus::PMBus pmbusInterface;
+
+    /**
+     * List of rails
+     */
+    std::vector<Rail> rails;
+
+    /**
+     * Finds the list of compatible system types using D-Bus methods.
+     * This list is used to find the correct JSON configuration file for the
+     * current system.
+     */
+    void findCompatibleSystemTypes();
+
+    /**
+     * Finds the JSON configuration file.
+     * Looks for a configuration file based on the list of compatible system
+     * types.
+     * Throws an exception if an operating system error occurs while checking
+     * for the existance of a file.
+     * @param compatibleSystemTypes List of compatible system types
+     */
+    void findConfigFile(const std::vector<std::string>& compatibleSystemTypes);
+
+    /**
+     * Returns whether the hardware with the specified inventory path is
+     * present.
+     * If an error occurs while obtaining the presence value, presence is
+     * assumed to be false. An empty string path indicates no presence check is
+     * needed.
+     * @param inventoryPath D-Bus inventory path of the hardware
+     * @return true if hardware is present, false otherwise
+     */
+    bool isPresent(const std::string& inventoryPath);
+
+    /**
+     * Analyzes the device pins for errors when the device is known to be in an
+     * error state.
+     * @param message Message property of the error log entry
+     * @param additionalData AdditionalData property of the error log entry
+     */
+    void onFailureCheckPins(std::string& message,
+                            std::map<std::string, std::string>& additionalData);
+
+    /**
+     * Analyzes the device rails for errors when the device is known to be in an
+     * error state.
+     * @param message Message property of the error log entry
+     * @param additionalData AdditionalData property of the error log entry
+     * @param powerSupplyError The power supply error to log. A default
+     * std:string, i.e. empty string (""), is passed when there is no power
+     * supply error to log.
+     */
+    void onFailureCheckRails(std::string& message,
+                             std::map<std::string, std::string>& additionalData,
+                             const std::string& powerSupplyError);
+
+    /**
+     * Parse the JSON configuration file.
+     * @param pathName the path name
+     */
+    void parseConfigFile(const std::filesystem::path& pathName);
+
+    /**
+     * Reads the mfr_status register
+     * @return the register contents
+     */
+    uint64_t readMFRStatus();
+
+    /**
+     * Reads the status_word register
+     * @return the register contents
+     */
+    uint16_t readStatusWord();
+};
+
+} // namespace phosphor::power::sequencer
