diff options
author | Lei YU <mine260309@gmail.com> | 2017-07-13 17:02:23 +0800 |
---|---|---|
committer | Lei YU <mine260309@gmail.com> | 2017-08-28 10:31:42 +0800 |
commit | 0ab90ca75b825db8e2427ea62ea3ee212c9accbb (patch) | |
tree | 6d7934495cf7233f54f5bd882469056c4f700142 /i2c_occ.cpp | |
parent | 3ace7576176afed9196fb308c766de6b1252d3ea (diff) | |
download | openpower-occ-control-0ab90ca75b825db8e2427ea62ea3ee212c9accbb.tar.gz openpower-occ-control-0ab90ca75b825db8e2427ea62ea3ee212c9accbb.zip |
Add I2C OCC support for P8 systems
P8 system uses I2C OCC and it uses different driver for occ-hwmon.
Add `--enable-i2c-occ` configure option to enable the support.
It searches i2c device names in sysfs to get all occ-hwmon devices and
use the i2c device name to bind/unbind the driver.
The occ control object path for I2C OCC hwmon becomes something like
/org/open_power/control/3_0050, where 3_0050 is the i2c address.
Change-Id: I8b9d8d4429c563528dc88fb2679b265c53d7a2d5
Signed-off-by: Lei YU <mine260309@gmail.com>
Diffstat (limited to 'i2c_occ.cpp')
-rw-r--r-- | i2c_occ.cpp | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/i2c_occ.cpp b/i2c_occ.cpp new file mode 100644 index 0000000..ffbb844 --- /dev/null +++ b/i2c_occ.cpp @@ -0,0 +1,73 @@ +#include <algorithm> +#include <fstream> + +#include "config.h" +#include "i2c_occ.hpp" + +#ifdef I2C_OCC + +namespace i2c_occ +{ + +namespace fs = std::experimental::filesystem; + +// The device name's length, e.g. "p8-occ-hwmon" +constexpr auto DEVICE_NAME_LENGTH = 12; + +// static assert to make sure the i2c occ device name is expected +static_assert(sizeof(I2C_OCC_DEVICE_NAME) -1 == DEVICE_NAME_LENGTH); + +std::string getFileContent(const fs::path& f) +{ + std::string ret(DEVICE_NAME_LENGTH, 0); + std::ifstream ifs(f.c_str(), std::ios::binary); + if (ifs.is_open()) + { + ifs.read(&ret[0], DEVICE_NAME_LENGTH); + ret.resize(ifs.gcount()); + } + return ret; +} + +std::vector<std::string> getOccHwmonDevices(const char* path) +{ + std::vector<std::string> result{}; + + if (fs::is_directory(path)) + { + for (auto & p : fs::directory_iterator(path)) + { + // Check if a device's name is "p8-occ-hwmon" + auto f = p / "name"; + auto str = getFileContent(f); + if (str == I2C_OCC_DEVICE_NAME) + { + result.emplace_back(p.path().filename()); + } + } + std::sort(result.begin(), result.end()); + } + return result; +} + +void i2cToDbus(std::string& path) +{ + std::replace(path.begin(), path.end(), '-', '_'); +} + +void dbusToI2c(std::string& path) +{ + std::replace(path.begin(), path.end(), '_', '-'); +} + +std::string getI2cDeviceName(const std::string& dbusPath) +{ + auto name = fs::path(dbusPath).filename().string(); + dbusToI2c(name); + return name; +} + +} // namespace i2c_occ + +#endif + |