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