Refactor common functions into files

Refactor common functions into files that can be reused by other
platforms. This is just a start, but make it so we can put different
platform init routines in other files and still access the functions
for gpio i2c and filesystem helpers.

Tested:
flash onto a gb200, log output was clean.

```
USB_HUB_RESET_L-O Request to set to 0
USB_HUB_RESET_L-O Set to 0
HMC present in platformSleeping for 100 milliseconds
SGPIO_BMC_EN-O Request to set to 1
SGPIO_BMC_EN-O Set to 1
HMC_BMC_DETECT-O Request to set to 0
HMC_BMC_DETECT-O Set to 0
BMC_EROT_FPGA_SPI_MUX_SEL-O Request to set to 1
BMC_EROT_FPGA_SPI_MUX_SEL-O Set to 1
BMC_12V_CTRL-O Request to set to 1
BMC_12V_CTRL-O Set to 1
PWR_BRAKE_L-O Request to set to 1
PWR_BRAKE_L-O Set to 1
SHDN_REQ_L-O Request to set to 1
SHDN_REQ_L-O Set to 1
SHDN_FORCE_L-O Request to set to 1
SHDN_FORCE_L-O Set to 1
SYS_RST_IN_L-O Request to set to 0
SYS_RST_IN_L-O Set to 0
FPGA_READY_BMC-I GpioEvent is already 1
SEC_FPGA_READY_BMC-I GpioEvent is already 1
EROT_FPGA_RST_L-O Request to set to 1
EROT_FPGA_RST_L-O Set to 1
SEC_EROT_FPGA_RST_L-O Request to set to 1
SEC_EROT_FPGA_RST_L-O Set to 1
Sleeping for 100 milliseconds
FPGA_RST_L-O Request to set to 1
FPGA_RST_L-O Set to 1
FPGA_READY_BMC-I  Waiting to go to assert
FPGA_READY_BMC-I Timeout
FPGA_READY_BMC-I failed to assert
SEC_FPGA_READY_BMC-I  Waiting to go to assert
SEC_FPGA_READY_BMC-I Timeout
SEC_FPGA_READY_BMC-I failed to assert
1e78a100 unbound
1e78a100 bound
1e78a180 unbound
1e78a180 bound
RUN_POWER_EN-O Request to set to 1
RUN_POWER_EN-O Set to 1
SYS_RST_IN_L-O Request to set to 1
SYS_RST_IN_L-O Settingto 1
GLOBAL_WP_BMC-O Request to set to 0
GLOBAL_WP_BMC-O Set to 0
BMC_READY-O Request to set to 1
BMC_READY-O Set to 1
USB_HUB_RESET_L-O Request to set to 1
USB_HUB_RESET_L-O Settingto 1
Platform init complete
```

Change-Id: I7f2134470536d48e1face39075c5fa1d40dc0de7
Signed-off-by: Marc Olberding <molberding@nvidia.com>
diff --git a/i2c.cpp b/i2c.cpp
new file mode 100644
index 0000000..e6d60e1
--- /dev/null
+++ b/i2c.cpp
@@ -0,0 +1,71 @@
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileCopyrightText: 2025 NVIDIA
+
+#include "i2c.hpp"
+
+#include <format>
+#include <fstream>
+#include <iostream>
+namespace i2c
+{
+
+void rebind_controller(std::string_view number)
+{
+    std::string bindpath =
+        std::format("/sys/bus/platform/drivers/aspeed-i2c-bus/unbind", number);
+    std::ofstream bindofs(bindpath);
+    if (!bindofs)
+    {
+        std::cerr << std::format("{} unable to open\n", bindpath);
+        return;
+    }
+    try
+    {
+        bindofs << std::format("{}.i2c\n", number);
+    }
+    catch (const std::system_error& e)
+    {
+        std::cerr << std::format("{} unable to write\n", bindpath);
+        return;
+    }
+    bindofs.close();
+    std::cerr << std::format("{} unbound\n", number);
+
+    std::string unbindpath =
+        std::format("/sys/bus/platform/drivers/aspeed-i2c-bus/bind", number);
+    std::ofstream unbindofs(unbindpath);
+    if (!unbindofs)
+    {
+        std::cerr << std::format("{} unable to open\n", unbindpath);
+        return;
+    }
+    try
+    {
+        unbindofs << std::format("{}.i2c\n", number);
+    }
+    catch (const std::system_error& e)
+    {
+        std::cerr << std::format("{} unable to write\n", unbindpath);
+        return;
+    }
+    std::cerr << std::format("{} bound\n", number);
+}
+
+void new_device(unsigned int bus, unsigned int address,
+                std::string_view device_type)
+{
+    std::string path =
+        std::format("/sys/bus/i2c/devices/i2c-{}/new_device", bus);
+    std::cerr << std::format("attempting to open {}", path);
+    std::ofstream new_device(path);
+    if (!new_device)
+    {
+        std::cerr << "Error: Unable to create I2C device\n";
+        return;
+    }
+    new_device << std::format("{} 0x{:02x}", device_type, address);
+    new_device.close();
+
+    std::cerr << std::format("{} device created at bus {}", device_type, bus);
+}
+} // namespace i2c