adcsensor: improve bridge gpio handling

This commit improves bridge gpio handling using name based gpio line
access and polarity setting support.

Tested: P3VBAT sensor reading worked correctly.

Change-Id: Iff174c52dba90cc068f4b5e527d4ab1c381817d0
Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
diff --git a/src/ADCSensor.cpp b/src/ADCSensor.cpp
index 2141ac4..ab1481b 100644
--- a/src/ADCSensor.cpp
+++ b/src/ADCSensor.cpp
@@ -37,24 +37,6 @@
 static constexpr double roundFactor = 10000; // 3 decimal places
 static constexpr double maxReading = 20;
 static constexpr double minReading = 0;
-static constexpr const char* sysGpioPath = "/sys/class/gpio/gpio";
-static constexpr const char* postfixValue = "/value";
-
-void setGpio(int gpioN, int value)
-{
-    std::string device = sysGpioPath + std::to_string(gpioN) + postfixValue;
-    std::fstream gpioFile;
-
-    gpioFile.open(device, std::ios::out);
-
-    if (!gpioFile.good())
-    {
-        std::cerr << "Error opening device " << device << "\n";
-        return;
-    }
-    gpioFile << std::to_string(value);
-    gpioFile.close();
-}
 
 ADCSensor::ADCSensor(const std::string& path,
                      sdbusplus::asio::object_server& objectServer,
@@ -63,7 +45,7 @@
                      std::vector<thresholds::Threshold>&& _thresholds,
                      const double scaleFactor, PowerState readState,
                      const std::string& sensorConfiguration,
-                     std::optional<int> bridgeGpio) :
+                     std::optional<BridgeGpio> bridgeGpio) :
     Sensor(boost::replace_all_copy(sensorName, " ", "_"),
            std::move(_thresholds), sensorConfiguration,
            "xyz.openbmc_project.Configuration.ADC", maxReading, minReading),
@@ -111,7 +93,7 @@
 {
     if (bridgeGpio.has_value())
     {
-        setGpio(*bridgeGpio, 1);
+        (*bridgeGpio).set(1);
         // In case a channel has a bridge circuit,we have to turn the bridge on
         // prior to reading a value at least for one scan cycle to get a valid
         // value. Guarantee that the HW signal can be stable, the HW signal
@@ -191,7 +173,7 @@
     inputDev.close();
     if (bridgeGpio.has_value())
     {
-        setGpio(*bridgeGpio, 0);
+        (*bridgeGpio).set(0);
     }
     int fd = open(path.c_str(), O_RDONLY);
     if (fd <= 0)
diff --git a/src/ADCSensorMain.cpp b/src/ADCSensorMain.cpp
index 188aad9..8a88244 100644
--- a/src/ADCSensorMain.cpp
+++ b/src/ADCSensorMain.cpp
@@ -230,21 +230,41 @@
             }
         }
 
-        auto findBridgeGpio = baseConfiguration->second.find("BridgeGpio");
-        std::optional<int> gpioNum;
-
-        if (findBridgeGpio != baseConfiguration->second.end())
+        std::optional<BridgeGpio> bridgeGpio;
+        for (const SensorBaseConfiguration& suppConfig : *sensorData)
         {
-            int gpioPin =
-                std::visit(VariantToIntVisitor(), findBridgeGpio->second);
-            gpioNum = static_cast<std::optional<int>>(gpioPin);
+            if (suppConfig.first.find("BridgeGpio") != std::string::npos)
+            {
+                auto findName = suppConfig.second.find("Name");
+                if (findName != suppConfig.second.end())
+                {
+                    std::string gpioName =
+                        std::visit(VariantToStringVisitor(), findName->second);
+
+                    int polarity = gpiod::line::ACTIVE_HIGH;
+                    auto findPolarity = suppConfig.second.find("Polarity");
+                    if (findPolarity != suppConfig.second.end())
+                    {
+                        if (std::string("Low") ==
+                            std::visit(VariantToStringVisitor(),
+                                       findPolarity->second))
+                        {
+                            polarity = gpiod::line::ACTIVE_LOW;
+                        }
+                    }
+                    bridgeGpio = BridgeGpio(gpioName, polarity);
+                }
+
+                break;
+            }
         }
+
         auto& sensor = sensors[sensorName];
         sensor = nullptr;
         sensor = std::make_unique<ADCSensor>(
             path.string(), objectServer, dbusConnection, io, sensorName,
             std::move(sensorThresholds), scaleFactor, readState, *interfacePath,
-            gpioNum);
+            bridgeGpio);
     }
 }