Make it possible to choose the target interface

The current code will always try to add a FanSpeed
interface if an <X>_target sysfs file is present, and
a FanPwm interface if a pwm<X> file is present.

For devices that have both types of files, it will
create both interfaces, and since each have a Target
property, it can cause REST calls which get these
properties to return the wrong one, as they can't
select the interface to use.

To fix this, allow a TARGET_MODE environment variable
to be specified to select which target to try to create,
either RPM or PWM.  If TARGET_MODE isn't there, default
to the current behavior of creating an interface for
whichever sysfs file type is exposed, so the code doesn't
limit what is created.

Tested: Set TARGET_MODE to RPM and then PWM in the config
        file, and ensure only the 1 interface is created.
        Remove that entry from the config file, and ensure
        it still works as it does today.

Change-Id: I2983e514c86c8d4fb785648520a913339daf6c8f
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
diff --git a/mainloop.cpp b/mainloop.cpp
index 1cd5db6..9af3053 100644
--- a/mainloop.cpp
+++ b/mainloop.cpp
@@ -293,6 +293,32 @@
 
 void MainLoop::run()
 {
+    //If this device supports target speeds,
+    //check which type to use.
+    targetType fanTargetType = targetType::DEFAULT;
+    auto targetMode = getenv("TARGET_MODE");
+    if (targetMode)
+    {
+        std::string type{targetMode};
+        std::transform(type.begin(), type.end(), type.begin(), toupper);
+
+        if (type == RPM_TARGET)
+        {
+            fanTargetType = targetType::RPM;
+        }
+        else if (type == PWM_TARGET)
+        {
+            fanTargetType = targetType::PWM;
+        }
+        else
+        {
+            log<level::ERR>(
+                    "Invalid TARGET_MODE env var found",
+                    entry("TARGET_MODE=%s", targetMode),
+                    entry("DEVPATH=%s", _devPath.c_str()));
+        }
+    }
+
     // Check sysfs for available sensors.
     auto sensors = std::make_unique<SensorSet>(_hwmonRoot + '/' + _instance);
 
@@ -358,15 +384,23 @@
         addThreshold<WarningObject>(i.first.first, id, sensorValue, info);
         addThreshold<CriticalObject>(i.first.first, id, sensorValue, info);
 
-        auto target = addTarget<hwmon::FanSpeed>(
-                i.first, ioAccess, _devPath, info);
-
-        if (target)
+        if ((fanTargetType == targetType::RPM) ||
+            (fanTargetType == targetType::DEFAULT))
         {
-            target->enable();
+            auto target = addTarget<hwmon::FanSpeed>(
+                    i.first, ioAccess, _devPath, info);
+
+            if (target)
+            {
+                target->enable();
+            }
         }
 
-        addTarget<hwmon::FanPwm>(i.first, ioAccess, _devPath, info);
+        if ((fanTargetType == targetType::PWM) ||
+            (fanTargetType == targetType::DEFAULT))
+        {
+            addTarget<hwmon::FanPwm>(i.first, ioAccess, _devPath, info);
+        }
 
         // All the interfaces have been created.  Go ahead
         // and emit InterfacesAdded.
diff --git a/targets.hpp b/targets.hpp
index de86170..ecef77b 100644
--- a/targets.hpp
+++ b/targets.hpp
@@ -7,6 +7,16 @@
 #include "fan_speed.hpp"
 #include "fan_pwm.hpp"
 
+enum class targetType
+{
+    DEFAULT,
+    RPM,
+    PWM
+};
+
+static constexpr auto RPM_TARGET = "RPM";
+static constexpr auto PWM_TARGET = "PWM";
+
 /** @class Targets
  *  @brief Target type traits.
  *