1 #pragma once 2 3 #include <experimental/filesystem> 4 #include <string> 5 #include <vector> 6 7 namespace witherspoon 8 { 9 namespace pmbus 10 { 11 12 namespace fs = std::experimental::filesystem; 13 14 // The file name Linux uses to capture the STATUS_WORD from pmbus. 15 constexpr auto STATUS_WORD = "status0"; 16 17 // The file name Linux uses to capture the VIN_UV_FAULT bit from the STATUS_WORD 18 constexpr auto VIN_UV_FAULT = "in1_alarm"; 19 20 // Uses Page substitution 21 constexpr auto STATUS_VOUT = "statusP_vout"; 22 23 namespace status_word 24 { 25 constexpr auto VOUT_FAULT = 0x8000; 26 } 27 28 /** 29 * If the access should be done in the base 30 * device directory, the hwmon directory, the 31 * pmbus debug directory, or the device debug 32 * directory. 33 */ 34 enum class Type 35 { 36 Base, 37 Hwmon, 38 Debug, 39 DeviceDebug 40 }; 41 42 /** 43 * @class PMBus 44 * 45 * This class is an interface to communicating with PMBus devices 46 * by reading and writing sysfs files. 47 * 48 * Based on the Type parameter, the accesses can either be done 49 * in the base device directory (the one passed into the constructor), 50 * or in the hwmon directory for the device. 51 */ 52 class PMBus 53 { 54 public: 55 56 PMBus() = delete; 57 ~PMBus() = default; 58 PMBus(const PMBus&) = default; 59 PMBus& operator=(const PMBus&) = default; 60 PMBus(PMBus&&) = default; 61 PMBus& operator=(PMBus&&) = default; 62 63 /** 64 * Constructor 65 * 66 * @param[in] path - path to the sysfs directory 67 */ 68 PMBus(const std::string& path) : 69 basePath(path) 70 { 71 findHwmonDir(); 72 } 73 74 /** 75 * Constructor 76 * 77 * This version is required when DeviceDebug 78 * access will be used. 79 * 80 * @param[in] path - path to the sysfs directory 81 * @param[in] driverName - the device driver name 82 * @param[in] instance - chip instance number 83 */ 84 PMBus(const std::string& path, 85 const std::string& driverName, 86 size_t instance) : 87 basePath(path), 88 driverName(driverName), 89 instance(instance) 90 { 91 findHwmonDir(); 92 } 93 94 /** 95 * Reads a file in sysfs that represents a single bit, 96 * therefore doing a PMBus read. 97 * 98 * @param[in] name - path concatenated to 99 * basePath to read 100 * @param[in] type - Path type 101 * 102 * @return bool - false if result was 0, else true 103 */ 104 bool readBit(const std::string& name, Type type); 105 106 /** 107 * Reads a file in sysfs that represents a single bit, 108 * where the page number passed in is substituted 109 * into the name in place of the 'P' character in it. 110 * 111 * @param[in] name - path concatenated to 112 * basePath to read 113 * @param[in] page - page number 114 * @param[in] type - Path type 115 * 116 * @return bool - false if result was 0, else true 117 */ 118 bool readBitInPage(const std::string& name, 119 size_t page, 120 Type type); 121 /** 122 * Read byte(s) from file in sysfs. 123 * 124 * @param[in] name - path concatenated to basePath to read 125 * @param[in] type - Path type 126 * 127 * @return uint64_t - Up to 8 bytes of data read from file. 128 */ 129 uint64_t read(const std::string& name, Type type); 130 131 /** 132 * Writes an integer value to the file, therefore doing 133 * a PMBus write. 134 * 135 * @param[in] name - path concatenated to 136 * basePath to write 137 * @param[in] value - the value to write 138 * @param[in] type - Path type 139 */ 140 void write(const std::string& name, int value, Type type); 141 142 /** 143 * Returns the sysfs base path of this device 144 */ 145 inline const auto& path() const 146 { 147 return basePath; 148 } 149 150 /** 151 * Replaces the 'P' in the string passed in with 152 * the page number passed in. 153 * 154 * For example: 155 * insertPageNum("inP_enable", 42) 156 * returns "in42_enable" 157 * 158 * @param[in] templateName - the name string, with a 'P' in it 159 * @param[in] page - the page number to insert where the P was 160 * 161 * @return string - the new string with the page number in it 162 */ 163 static std::string insertPageNum(const std::string& templateName, 164 size_t page); 165 166 /** 167 * Finds the path relative to basePath to the hwmon directory 168 * for the device and stores it in hwmonRelPath. 169 */ 170 void findHwmonDir(); 171 172 /** 173 * Returns the path to use for the passed in type. 174 * 175 * @param[in] type - Path type 176 * 177 * @return fs::path - the full path 178 */ 179 fs::path getPath(Type type); 180 181 private: 182 183 /** 184 * The sysfs device path 185 */ 186 fs::path basePath; 187 188 /** 189 * The directory name under the basePath hwmon directory 190 */ 191 fs::path hwmonDir; 192 193 /** 194 * The device driver name. Used for finding the device 195 * debug directory. Not required if that directory 196 * isn't used. 197 */ 198 std::string driverName; 199 200 /** 201 * The device instance number. 202 * 203 * Used in conjuction with the driver name for finding 204 * the debug directory. Not required if that directory 205 * isn't used. 206 */ 207 size_t instance = 0; 208 209 /** 210 * The pmbus debug path with status files 211 */ 212 const fs::path debugPath = "/sys/kernel/debug/"; 213 214 }; 215 216 } 217 } 218