Support host selector using cpld definitions

Description:
- Support host selector using cpld definitions

Design:
- Because the current structure only supports config defined by GPIO
  (Yosemite V2), but there are also have the system (Yosemite V3.5)
  gets the host-selector's selection from CPLD.

- So this commit is to extend the current configuration to use CPLD
  definitions. Also, support adding event io from the register file
  which was exported from the CLD driver.

- For example with config json below:
{
   "cpld_definitions": [
        {
            "name": "HOST_SELECTOR",
            "i2c_address": 15,
            "i2c_bus": 12,
            "register_name": "uart-selection-debug-card",
            "max_position": 4
        }
   ]
}

Dependency:
- CLD driver is required (link: https://lore.kernel.org/lkml/20230117094425.19004-1-Delphine_CC_Chiu@Wiwynn.com/)

Test Case:
- When ocp debug card uart button is pressed the position property on
  dbus is correct.

Signed-off-by: Delphine CC Chiu <Delphine_CC_Chiu@wiwynn.com>
Change-Id: I6746afa6d905bd3c681e2921c643b3cd4cb9944c
diff --git a/src/hostSelector_switch.cpp b/src/hostSelector_switch.cpp
index ce168d0..81bd247 100644
--- a/src/hostSelector_switch.cpp
+++ b/src/hostSelector_switch.cpp
@@ -37,38 +37,60 @@
     }
     return INVALID_INDEX;
 }
-void HostSelector::setInitialHostSelectorValue()
+
+char HostSelector::getValueFromFd(int fd)
 {
     char buf;
-    for (size_t index = 0; index < gpioLineCount; index++)
+    auto result = ::lseek(fd, 0, SEEK_SET);
+
+    if (result < 0)
     {
-        auto result = ::lseek(config.gpios[index].fd, 0, SEEK_SET);
+        throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
+            IOError();
+    }
 
-        if (result < 0)
-        {
-            lg2::error("{TYPE}: Gpio fd lseek error: {ERROR}", "TYPE",
-                       getFormFactorType(), "ERROR", errno);
-            throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
-                IOError();
-        }
+    result = ::read(fd, &buf, sizeof(buf));
+    if (result < 0)
+    {
+        throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
+            IOError();
+    }
+    return buf;
+}
 
-        result = ::read(config.gpios[index].fd, &buf, sizeof(buf));
-        if (result < 0)
+void HostSelector::setInitialHostSelectorValue()
+{
+    size_t hsPosMapped = 0;
+
+    try
+    {
+        if (config.type == ConfigType::gpio)
         {
-            lg2::error("{TYPE}: Gpio fd read error: {ERROR}", "TYPE",
-                       getFormFactorType(), "ERROR", errno);
-            throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
-                IOError();
+            for (size_t index = 0; index < gpioLineCount; index++)
+            {
+                GpioState gpioState =
+                    (getValueFromFd(config.gpios[index].fd) == '0')
+                        ? (GpioState::deassert)
+                        : (GpioState::assert);
+                setHostSelectorValue(config.gpios[index].fd, gpioState);
+            }
+            hsPosMapped = getMappedHSConfig(hostSelectorPosition);
         }
-        GpioState gpioState = (buf == '0') ? (GpioState::deassert)
-                                           : (GpioState::assert);
-        setHostSelectorValue(config.gpios[index].fd, gpioState);
-        size_t hsPosMapped = getMappedHSConfig(hostSelectorPosition);
-        if (hsPosMapped != INVALID_INDEX)
+        else if (config.type == ConfigType::cpld)
         {
-            position(hsPosMapped, true);
+            hsPosMapped = getValueFromFd(config.cpld.cpldMappedFd) - '0';
         }
     }
+    catch (const std::exception& e)
+    {
+        lg2::error("{TYPE}: exception while reading fd : {ERROR}", "TYPE",
+                   getFormFactorType(), "ERROR", e.what());
+    }
+
+    if (hsPosMapped != INVALID_INDEX)
+    {
+        position(hsPosMapped, true);
+    }
 }
 
 void HostSelector::setHostSelectorValue(int fd, GpioState state)
@@ -98,34 +120,32 @@
 void HostSelector::handleEvent(sd_event_source* /* es */, int fd,
                                uint32_t /* revents */)
 {
-    int n = -1;
     char buf = '0';
-
-    n = ::lseek(fd, 0, SEEK_SET);
-
-    if (n < 0)
+    try
     {
-        lg2::error("{TYPE}: Gpio fd lseek error: {ERROR}", "TYPE",
-                   getFormFactorType(), "ERROR", errno);
+        buf = getValueFromFd(fd);
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("{TYPE}: exception while reading fd : {ERROR}", "TYPE",
+                   getFormFactorType(), "ERROR", e.what());
         return;
     }
 
-    n = ::read(fd, &buf, sizeof(buf));
-    if (n < 0)
+    size_t hsPosMapped = 0;
+    if (config.type == ConfigType::gpio)
     {
-        lg2::error("{TYPE}: Gpio fd read error: {ERROR}", "TYPE",
-                   getFormFactorType(), "ERROR", errno);
-        throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
-            IOError();
+        // read the gpio state for the io event received
+        GpioState gpioState = (buf == '0') ? (GpioState::deassert)
+                                           : (GpioState::assert);
+
+        setHostSelectorValue(fd, gpioState);
+        hsPosMapped = getMappedHSConfig(hostSelectorPosition);
     }
-
-    // read the gpio state for the io event received
-    GpioState gpioState = (buf == '0') ? (GpioState::deassert)
-                                       : (GpioState::assert);
-
-    setHostSelectorValue(fd, gpioState);
-
-    size_t hsPosMapped = getMappedHSConfig(hostSelectorPosition);
+    else if (config.type == ConfigType::cpld)
+    {
+        hsPosMapped = buf - '0';
+    }
 
     if (hsPosMapped != INVALID_INDEX)
     {