Lei YU | 0ab90ca | 2017-07-13 17:02:23 +0800 | [diff] [blame] | 1 | #include <algorithm> |
Lei YU | b5259a1 | 2017-09-01 16:22:40 +0800 | [diff] [blame] | 2 | #include <cassert> |
Lei YU | 0ab90ca | 2017-07-13 17:02:23 +0800 | [diff] [blame] | 3 | #include <fstream> |
| 4 | |
| 5 | #include "config.h" |
| 6 | #include "i2c_occ.hpp" |
| 7 | |
| 8 | #ifdef I2C_OCC |
| 9 | |
| 10 | namespace i2c_occ |
| 11 | { |
| 12 | |
| 13 | namespace fs = std::experimental::filesystem; |
| 14 | |
Lei YU | 41470e5 | 2017-11-30 16:03:50 +0800 | [diff] [blame] | 15 | // The occ_master sysfs file |
| 16 | constexpr auto OCC_MASTER_FILE = "occ_master"; |
Lei YU | 0ab90ca | 2017-07-13 17:02:23 +0800 | [diff] [blame] | 17 | // The device name's length, e.g. "p8-occ-hwmon" |
| 18 | constexpr auto DEVICE_NAME_LENGTH = 12; |
Lei YU | b5259a1 | 2017-09-01 16:22:40 +0800 | [diff] [blame] | 19 | // The occ name's length, e.g. "occ" |
| 20 | constexpr auto OCC_NAME_LENGTH = 3; |
Lei YU | 0ab90ca | 2017-07-13 17:02:23 +0800 | [diff] [blame] | 21 | |
| 22 | // static assert to make sure the i2c occ device name is expected |
| 23 | static_assert(sizeof(I2C_OCC_DEVICE_NAME) -1 == DEVICE_NAME_LENGTH); |
Lei YU | b5259a1 | 2017-09-01 16:22:40 +0800 | [diff] [blame] | 24 | static_assert(sizeof(OCC_NAME) -1 == OCC_NAME_LENGTH); |
Lei YU | 0ab90ca | 2017-07-13 17:02:23 +0800 | [diff] [blame] | 25 | |
Lei YU | 41470e5 | 2017-11-30 16:03:50 +0800 | [diff] [blame] | 26 | static bool isMasterOcc(const fs::directory_entry& p) |
| 27 | { |
| 28 | auto f = p / OCC_MASTER_FILE; |
| 29 | auto str = getFileContent(f); |
| 30 | return (!str.empty()) && (str[0] == '1'); |
| 31 | } |
| 32 | |
Lei YU | 0ab90ca | 2017-07-13 17:02:23 +0800 | [diff] [blame] | 33 | std::string getFileContent(const fs::path& f) |
| 34 | { |
| 35 | std::string ret(DEVICE_NAME_LENGTH, 0); |
| 36 | std::ifstream ifs(f.c_str(), std::ios::binary); |
| 37 | if (ifs.is_open()) |
| 38 | { |
| 39 | ifs.read(&ret[0], DEVICE_NAME_LENGTH); |
| 40 | ret.resize(ifs.gcount()); |
| 41 | } |
| 42 | return ret; |
| 43 | } |
| 44 | |
| 45 | std::vector<std::string> getOccHwmonDevices(const char* path) |
| 46 | { |
| 47 | std::vector<std::string> result{}; |
| 48 | |
| 49 | if (fs::is_directory(path)) |
| 50 | { |
| 51 | for (auto & p : fs::directory_iterator(path)) |
| 52 | { |
| 53 | // Check if a device's name is "p8-occ-hwmon" |
| 54 | auto f = p / "name"; |
| 55 | auto str = getFileContent(f); |
| 56 | if (str == I2C_OCC_DEVICE_NAME) |
| 57 | { |
Lei YU | 41470e5 | 2017-11-30 16:03:50 +0800 | [diff] [blame] | 58 | if (isMasterOcc(p)) |
| 59 | { |
| 60 | // Insert master occ at the beginning |
| 61 | result.emplace(result.begin(), p.path().filename()); |
| 62 | } |
| 63 | else |
| 64 | { |
| 65 | result.emplace_back(p.path().filename()); |
| 66 | } |
Lei YU | 0ab90ca | 2017-07-13 17:02:23 +0800 | [diff] [blame] | 67 | } |
| 68 | } |
Lei YU | 41470e5 | 2017-11-30 16:03:50 +0800 | [diff] [blame] | 69 | } |
| 70 | if (!result.empty()) |
| 71 | { |
| 72 | // Sort the occ devices except for master |
| 73 | std::sort(result.begin() + 1, result.end()); |
Lei YU | 0ab90ca | 2017-07-13 17:02:23 +0800 | [diff] [blame] | 74 | } |
| 75 | return result; |
| 76 | } |
| 77 | |
| 78 | void i2cToDbus(std::string& path) |
| 79 | { |
| 80 | std::replace(path.begin(), path.end(), '-', '_'); |
| 81 | } |
| 82 | |
| 83 | void dbusToI2c(std::string& path) |
| 84 | { |
| 85 | std::replace(path.begin(), path.end(), '_', '-'); |
| 86 | } |
| 87 | |
| 88 | std::string getI2cDeviceName(const std::string& dbusPath) |
| 89 | { |
| 90 | auto name = fs::path(dbusPath).filename().string(); |
Lei YU | b5259a1 | 2017-09-01 16:22:40 +0800 | [diff] [blame] | 91 | |
| 92 | // Need to make sure the name starts with "occ" |
| 93 | assert(name.compare(0, OCC_NAME_LENGTH, OCC_NAME) == 0); |
| 94 | |
| 95 | // Change name like occ_3_0050 to 3_0050 |
| 96 | name.erase(0, OCC_NAME_LENGTH + 1); |
| 97 | |
Lei YU | 0ab90ca | 2017-07-13 17:02:23 +0800 | [diff] [blame] | 98 | dbusToI2c(name); |
| 99 | return name; |
| 100 | } |
| 101 | |
| 102 | } // namespace i2c_occ |
| 103 | |
| 104 | #endif |
| 105 | |