Support Nuvoton pmw/tach fans

Support pwm/tach fans on the Nuvoton NPCM7xx BMC. They work similarly to
the already implemented Aspeed fans and can be detected by looking for
the device f0103000.pwm-fan-controller.

Tested: pwm and tach published to dbus when configured in
entity-manager json:

{
    "Name": "System fan connector 0",
    "Pwm": 0,
    "Status": "disabled",
    "Tachs": [0],
    "Type": "FanConnector"
},
{
    "Index": 0,
    "BindConnector": "System fan connector 0",
    "Name": "fan0",
    "Type": "NuvotonFan"
},

$ busctl --no-page tree xyz.openbmc_project.FanSensor
`-/xyz
  `-/xyz/openbmc_project
    |-/xyz/openbmc_project/control
    | `-/xyz/openbmc_project/control/fanpwm
    |   |-/xyz/openbmc_project/control/fanpwm/Pwm_1
    |   |-/xyz/openbmc_project/control/fanpwm/Pwm_2
    |   |-/xyz/openbmc_project/control/fanpwm/Pwm_3
    |   |-/xyz/openbmc_project/control/fanpwm/Pwm_4
    |   `-/xyz/openbmc_project/control/fanpwm/Pwm_5
    `-/xyz/openbmc_project/sensors
      |-/xyz/openbmc_project/sensors/fan_pwm
      | |-/xyz/openbmc_project/sensors/fan_pwm/Pwm_1
      | |-/xyz/openbmc_project/sensors/fan_pwm/Pwm_2
      | |-/xyz/openbmc_project/sensors/fan_pwm/Pwm_3
      | |-/xyz/openbmc_project/sensors/fan_pwm/Pwm_4
      | `-/xyz/openbmc_project/sensors/fan_pwm/Pwm_5
      `-/xyz/openbmc_project/sensors/fan_tach
        |-/xyz/openbmc_project/sensors/fan_tach/fan0
        |-/xyz/openbmc_project/sensors/fan_tach/fan1
        |-/xyz/openbmc_project/sensors/fan_tach/fan2
        |-/xyz/openbmc_project/sensors/fan_tach/fan3
        `-/xyz/openbmc_project/sensors/fan_tach/fan4

Signed-off-by: Peter Lundgren <peterlundgren@google.com>
Change-Id: Icf6cba1b8d4d33ccdd9b2dc9ba91209e4a5b2478
diff --git a/src/FanMain.cpp b/src/FanMain.cpp
index b0237c2..d8eb6e7 100644
--- a/src/FanMain.cpp
+++ b/src/FanMain.cpp
@@ -32,9 +32,10 @@
 
 namespace fs = std::filesystem;
 
-static constexpr std::array<const char*, 2> sensorTypes = {
+static constexpr std::array<const char*, 3> sensorTypes = {
     "xyz.openbmc_project.Configuration.AspeedFan",
-    "xyz.openbmc_project.Configuration.I2CFan"};
+    "xyz.openbmc_project.Configuration.I2CFan",
+    "xyz.openbmc_project.Configuration.NuvotonFan"};
 constexpr const char* redundancyConfiguration =
     "xyz.openbmc_project.Configuration.FanRedundancy";
 static std::regex inputRegex(R"(fan(\d+)_input)");
@@ -42,7 +43,8 @@
 enum class FanTypes
 {
     aspeed,
-    i2c
+    i2c,
+    nuvoton
 };
 
 // todo: power supply fan redundancy
@@ -56,6 +58,10 @@
     {
         return FanTypes::aspeed;
     }
+    else if (boost::ends_with(canonical, "f0103000.pwm-fan-controller"))
+    {
+        return FanTypes::nuvoton;
+    }
     // todo: will we need to support other types?
     return FanTypes::i2c;
 }
@@ -158,10 +164,10 @@
             {
                 continue;
             }
-            if (fanType == FanTypes::aspeed)
+            if (fanType == FanTypes::aspeed || fanType == FanTypes::nuvoton)
             {
-                // there will be only 1 aspeed sensor object in sysfs, we found
-                // the fan
+                // there will be only 1 aspeed or nuvoton sensor object in
+                // sysfs, we found the fan
                 sensorData = &(sensor.second);
                 break;
             }