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