blob: d3734fea93333475bdd55e62716d0418f6b88bb5 [file] [log] [blame]
#include "tlbmc/hal/sysfs/i2c.h"
#include <cstdint>
#include <fstream>
#include <string>
#include <string_view>
#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/substitute.h"
#include "i2c_common_config.pb.h"
namespace milotic_tlbmc {
boost::filesystem::path I2cSysfs::Geti2cBusPath(uint64_t bus) const {
boost::filesystem::path path(config_.i2c_sysfs_path);
path /= "i2c-";
return absl::Substitute(path.string() + "$0", bus);
}
absl::Status I2cSysfs::NewDevice(const I2cCommonConfig& config,
std::string_view driver_name) const {
if (IsDevicePresent(config)) {
return absl::AlreadyExistsError(
absl::Substitute("Device $0 already exists", config));
}
boost::filesystem::path path = Geti2cBusPath(config.bus()) / "new_device";
std::ofstream file(path.string());
if (!file.good()) {
return absl::InternalError(
absl::Substitute("Failed to open $0", path.string()));
}
file << driver_name << " " << config.address() << "\n";
file.flush();
if (!file.good()) {
return absl::InternalError(
absl::Substitute("Failed to write to $0", path.string()));
}
return absl::OkStatus();
}
absl::Status I2cSysfs::DeleteDevice(const I2cCommonConfig& config) const {
// No `IsDevicePresent` check on this like in `NewDevice`, since it
// might be used to clean up after a device instantiation that was only
// partially successful
boost::filesystem::path path = Geti2cBusPath(config.bus()) / "delete_device";
std::ofstream file(path.string());
if (!file.good()) {
return absl::InternalError(
absl::Substitute("Failed to open $0", path.string()));
}
file << config.address() << "\n";
file.flush();
if (!file.good()) {
return absl::InternalError(
absl::Substitute("Failed to write to $0", path.string()));
}
return absl::OkStatus();
}
bool I2cSysfs::IsDevicePresent(const I2cCommonConfig& config) const {
boost::filesystem::path path = Geti2cBusPath(config.bus());
path /= GetDeviceDirectoryName(config);
return boost::filesystem::exists(path);
}
std::string I2cSysfs::GetDeviceDirectoryName(const I2cCommonConfig& config) {
return absl::Substitute(
"$0-$1", config.bus(),
absl::StrCat(absl::Hex(config.address(), absl::kZeroPad4)));
}
} // namespace milotic_tlbmc