nvl32: Add nvl32 target
Also adds an i2c device class to allow us to send raw i2c
Tested:
ran on the nvl32-obmc model and i2c devices were enumerated correctly.
as well as mctp devices
Change-Id: I073156de2bbe06b06017379de35e076166df3875
Signed-off-by: Marc Olberding <molberding@nvidia.com>
diff --git a/i2c.cpp b/i2c.cpp
index e6d60e1..cc8be13 100644
--- a/i2c.cpp
+++ b/i2c.cpp
@@ -3,9 +3,22 @@
#include "i2c.hpp"
+#include <fcntl.h>
+#include <linux/i2c-dev.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+#include <filesystem>
#include <format>
#include <fstream>
#include <iostream>
+
+extern "C"
+{
+#include <i2c/smbus.h>
+#include <linux/i2c-dev.h>
+}
+
namespace i2c
{
@@ -68,4 +81,44 @@
std::cerr << std::format("{} device created at bus {}", device_type, bus);
}
+
+RawDevice::RawDevice(size_t bus, uint8_t address)
+{
+ std::string bus_path = std::format("/dev/i2c-{}", bus);
+ std::filesystem::path dev_path = bus_path;
+ fd = open(dev_path.c_str(), O_RDWR);
+ if (fd < 0)
+ {
+ std::cerr << std::format("failed to open {}\n", dev_path.native());
+ throw std::runtime_error(
+ std::format("Failed to open {}", dev_path.native()));
+ }
+
+ if (ioctl(fd, I2C_SLAVE, address) < 0)
+ {
+ // dtor won't be called since we never finished constructing it, clean
+ // up our fd
+ close(fd);
+ throw std::runtime_error(
+ std::format("Failed to specify address {}", address));
+ }
+}
+
+RawDevice::~RawDevice()
+{
+ close(fd);
+}
+
+int RawDevice::read_byte(uint8_t reg, uint8_t& val)
+{
+ int result = i2c_smbus_read_byte_data(fd, reg);
+ if (result < 0)
+ {
+ return -result;
+ }
+
+ val = result;
+ return 0;
+}
+
} // namespace i2c