Remove overlays for i2c based devices

Use sysfs instead

Change-Id: I8a6d57aabbebff8d488f8a61fc34ed5315c56807
Signed-off-by: James Feist <james.feist@linux.intel.com>
diff --git a/include/devices.hpp b/include/devices.hpp
new file mode 100644
index 0000000..8eb87d1
--- /dev/null
+++ b/include/devices.hpp
@@ -0,0 +1,55 @@
+/*
+// Copyright (c) 2018 Intel 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.
+*/
+
+#pragma once
+#include <boost/container/flat_map.hpp>
+
+namespace devices
+{
+
+struct CmpStr
+{
+    bool operator()(const char *a, const char *b) const
+    {
+        return std::strcmp(a, b) < 0;
+    }
+};
+
+struct ExportTemplate
+{
+    ExportTemplate(const char *parameters, const char *device) :
+        parameters(parameters), device(device){};
+    const char *parameters;
+    const char *device;
+};
+
+const boost::container::flat_map<const char *, ExportTemplate, CmpStr>
+    exportTemplates{
+        {{"PCA9543Mux",
+          ExportTemplate("pca9543 $Address",
+                         "/sys/bus/i2c/devices/i2c-$Bus/new_device")},
+         {"PCA9545Mux",
+          ExportTemplate("pca9545 $Address",
+                         "/sys/bus/i2c/devices/i2c-$Bus/new_device")},
+         {"TMP75", ExportTemplate("tmp75 $Address",
+                                  "/sys/bus/i2c/devices/i2c-$Bus/new_device")
+
+         },
+         {"TMP421", ExportTemplate("tmp421 $Address",
+                                   "/sys/bus/i2c/devices/i2c-$Bus/new_device")
+
+         }}};
+} // namespace devices
\ No newline at end of file
diff --git a/overlay_templates/PCA9543Mux.template b/overlay_templates/PCA9543Mux.template
deleted file mode 100644
index bb4b9ea..0000000
--- a/overlay_templates/PCA9543Mux.template
+++ /dev/null
@@ -1,29 +0,0 @@
-/dts-v1/;
-/plugin/;
-/ {
-    compatible = "$Platform";
-    fragment@0{
-        target = <&i2c$Bus>;
-        __overlay__{
-            status = "okay";
-            $Name: smbus_mux@$Address {
-                compatible = "nxp,pca9543";
-                reg = <0x$Address>;
-                #address-cells = <1>;
-                #size-cells = <0>;
-                oemname1 = "$Name";
-                $Name_0: $Name@0 {
-                    #address-cells = <1>;
-                    #size-cells = <0>;
-                    reg = <0>;
-                };
-                $Name_1: $Name@1 {
-                    #address-cells = <1>;
-                    #size-cells = <0>;
-                    reg = <1>;
-                };
-            };
-        };
-
-    };
-};
diff --git a/overlay_templates/PCA9545Mux.template b/overlay_templates/PCA9545Mux.template
deleted file mode 100644
index 7108b80..0000000
--- a/overlay_templates/PCA9545Mux.template
+++ /dev/null
@@ -1,39 +0,0 @@
-/dts-v1/;
-/plugin/;
-/ {
-    compatible = "$Platform";
-    fragment@0{
-        target = <&i2c$Bus>;
-        __overlay__{
-            status = "okay";
-            $Name: smbus_mux@$Address {
-                compatible = "nxp,pca9545";
-                reg = <0x$Address>;
-                #address-cells = <1>;
-                #size-cells = <0>;
-                oemname1 = "$Name";
-                $Name_0: $Name@0 {
-                    #address-cells = <1>;
-                    #size-cells = <0>;
-                    reg = <0>;
-                };
-                $Name_1: $Name@1 {
-                    #address-cells = <1>;
-                    #size-cells = <0>;
-                    reg = <1>;
-                };
-                $Name_2: $Name@2{
-                    #address-cells = <1>;
-                    #size-cells = <0>;
-                    reg = <2>;
-                };
-                $Name_3: $Name@3{
-                    #address-cells = <1>;
-                    #size-cells = <0>;
-                    reg = <3>;
-                };
-            };
-        };
-
-    };
-};
diff --git a/overlay_templates/TMP421.template b/overlay_templates/TMP421.template
deleted file mode 100644
index b819651..0000000
--- a/overlay_templates/TMP421.template
+++ /dev/null
@@ -1,21 +0,0 @@
-/dts-v1/;
-/plugin/;
-/ {
-    compatible = "$Platform";
-    fragment@0{
-        target = <&i2c$Bus>;
-        __overlay__{
-            #address-cells = <1>;
-            #size-cells = <0>;
-            status = "okay";
-            $Name$Name1: tmp421@$Address {
-                compatible = "ti,tmp421";
-                reg = <0x$Address>;
-                oemname1 = "$Name";
-                oemname2 = "$Name1";
-                scale = "-3";
-            };
-        };
-
-    };
-};
\ No newline at end of file
diff --git a/overlay_templates/TMP75.template b/overlay_templates/TMP75.template
deleted file mode 100644
index 164c9ec..0000000
--- a/overlay_templates/TMP75.template
+++ /dev/null
@@ -1,20 +0,0 @@
-/dts-v1/;
-/plugin/;
-/ {
-    compatible = "$Platform";
-    fragment@0{
-        target = <&i2c$Bus>;
-        __overlay__{
-            #address-cells = <1>;
-            #size-cells = <0>;
-            status = "okay";
-            $Name: tmp75@$Address {
-                compatible = "ti,tmp75";
-                reg = <0x$Address>;
-                oemname1 = "$Name";
-                scale = "-3";
-            };
-        };
-
-    };
-};
\ No newline at end of file
diff --git a/src/Overlay.cpp b/src/Overlay.cpp
index d5ddb69..f937dbe 100644
--- a/src/Overlay.cpp
+++ b/src/Overlay.cpp
@@ -18,10 +18,12 @@
 #include <iostream>
 #include <regex>
 #include <boost/process/child.hpp>
+#include <boost/algorithm/string/predicate.hpp>
 #include <experimental/filesystem>
 #include <boost/container/flat_map.hpp>
 #include <boost/container/flat_set.hpp>
 #include <nlohmann/json.hpp>
+#include <devices.hpp>
 #include <Overlay.hpp>
 #include <Utils.hpp>
 
@@ -139,6 +141,85 @@
     }
 }
 
+void exportDevice(const devices::ExportTemplate &exportTemplate,
+                  const nlohmann::json &configuration)
+{
+
+    std::string parameters = exportTemplate.parameters;
+    std::string device = exportTemplate.device;
+    std::string name = "unknown";
+    const uint64_t *bus = nullptr;
+    const uint64_t *address = nullptr;
+
+    for (auto keyPair = configuration.begin(); keyPair != configuration.end();
+         keyPair++)
+    {
+        std::string subsituteString;
+
+        if (keyPair.key() == "Name" &&
+            keyPair.value().type() == nlohmann::json::value_t::string)
+        {
+            subsituteString = std::regex_replace(
+                keyPair.value().get<std::string>(), ILLEGAL_NAME_REGEX, "_");
+            name = subsituteString;
+        }
+        else
+        {
+            subsituteString = jsonToString(keyPair.value());
+        }
+
+        if (keyPair.key() == "Bus")
+        {
+            bus = keyPair.value().get_ptr<const uint64_t *>();
+        }
+        else if (keyPair.key() == "Address")
+        {
+            address = keyPair.value().get_ptr<const uint64_t *>();
+        }
+        boost::replace_all(parameters, TEMPLATE_CHAR + keyPair.key(),
+                           subsituteString);
+        boost::replace_all(device, TEMPLATE_CHAR + keyPair.key(),
+                           subsituteString);
+    }
+
+    // if we found bus and address we can attempt to prevent errors
+    if (bus != nullptr && address != nullptr)
+    {
+        std::ostringstream hex;
+        hex << std::hex << *address;
+        const std::string &addressHex = hex.str();
+        std::string busStr = std::to_string(*bus);
+
+        std::experimental::filesystem::path devicePath(device);
+        const std::string &dir = devicePath.parent_path().string();
+        for (const auto &path :
+             std::experimental::filesystem::directory_iterator(dir))
+        {
+            if (!std::experimental::filesystem::is_directory(path))
+            {
+                continue;
+            }
+
+            const std::string &directoryName = path.path().filename();
+            if (boost::starts_with(directoryName, busStr) &&
+                boost::ends_with(directoryName, addressHex))
+            {
+                return; // already exported
+            }
+        }
+    }
+
+    std::ofstream deviceFile(device);
+    if (!deviceFile.good())
+    {
+        std::cerr << "Error writing " << device << "\n";
+        return;
+    }
+    deviceFile << parameters;
+    deviceFile.close();
+}
+
+// this is now deprecated
 void createOverlay(const std::string &templatePath,
                    const nlohmann::json &configuration)
 {
@@ -214,18 +295,6 @@
     out << templateStr;
     out.close();
 
-    // this is for muxes, we need to store the diff of i2c devices before
-    // and after scanning to load new symbols into device tree so that if we
-    // later add devices to the "virtual" i2c device, we can match the phandle
-    // to the correct mux
-    std::vector<std::experimental::filesystem::path> i2cDevsBefore;
-    auto findMux = MUX_TYPES.find(type);
-    if (findMux != MUX_TYPES.end())
-    {
-        findFiles(std::experimental::filesystem::path(I2C_DEVS_DIR),
-                  R"(i2c-\d+)", i2cDevsBefore);
-    }
-
     // compile dtbo and load overlay
     boost::process::child c1(DTC, "-@", "-q", "-I", "dts", "-O", "dtb", "-o",
                              dtboFilename, dtsFilename);
@@ -247,10 +316,6 @@
     {
         forceProbe(findForceProbe->second);
     }
-    if (findMux != MUX_TYPES.end())
-    {
-        fixupSymbols(i2cDevsBefore);
-    }
 }
 
 bool loadOverlays(const nlohmann::json &systemConfiguration)
@@ -292,7 +357,7 @@
             }
             std::string type = findType.value().get<std::string>();
             std::string typeFile = type + std::string(".template");
-            for (auto path : paths)
+            for (const auto &path : paths)
             {
                 if (path.filename() != typeFile)
                 {
@@ -301,6 +366,12 @@
                 createOverlay(path.string(), configuration);
                 break;
             }
+
+            auto device = devices::exportTemplates.find(type.c_str());
+            if (device != devices::exportTemplates.end())
+            {
+                exportDevice(device->second, configuration);
+            }
         }
     }