1015e3adeSMatt Spinler #pragma once 2015e3adeSMatt Spinler 39c7897ceSBrandon Wyman #include <filesystem> 4015e3adeSMatt Spinler #include <string> 5015e3adeSMatt Spinler #include <vector> 6015e3adeSMatt Spinler 7ab093328SLei YU namespace phosphor 8015e3adeSMatt Spinler { 9015e3adeSMatt Spinler namespace pmbus 10015e3adeSMatt Spinler { 11015e3adeSMatt Spinler 129c7897ceSBrandon Wyman namespace fs = std::filesystem; 13ff5f339cSBrandon Wyman 1410295547SBrandon Wyman // The file name Linux uses to capture the STATUS_WORD from pmbus. 15e7e432b4SMatt Spinler constexpr auto STATUS_WORD = "status0"; 1610295547SBrandon Wyman 17253dc9b9SBrandon Wyman // The file name Linux uses to capture the STATUS_INPUT from pmbus. 18253dc9b9SBrandon Wyman constexpr auto STATUS_INPUT = "status0_input"; 19e7e432b4SMatt Spinler 20764c797eSBrandon Wyman // Voltage out status. 21764c797eSBrandon Wyman // Overvoltage fault or warning, Undervoltage fault or warning, maximum or 22764c797eSBrandon Wyman // minimum warning, .... 23e7e432b4SMatt Spinler // Uses Page substitution 24e7e432b4SMatt Spinler constexpr auto STATUS_VOUT = "statusP_vout"; 25e7e432b4SMatt Spinler 26de16d053SMatt Spinler namespace status_vout 27de16d053SMatt Spinler { 28de16d053SMatt Spinler // Mask of bits that are only warnings 29de16d053SMatt Spinler constexpr auto WARNING_MASK = 0x6A; 30f0f02b9aSMatt Spinler } // namespace status_vout 31de16d053SMatt Spinler 32764c797eSBrandon Wyman // Current output status bits. 33764c797eSBrandon Wyman constexpr auto STATUS_IOUT = "status0_iout"; 34764c797eSBrandon Wyman 35764c797eSBrandon Wyman // Manufacturing specific status bits 36764c797eSBrandon Wyman constexpr auto STATUS_MFR = "status0_mfr"; 37764c797eSBrandon Wyman 3812661f1eSBrandon Wyman // Reports on the status of any fans installed in position 1 and 2. 3912661f1eSBrandon Wyman constexpr auto STATUS_FANS_1_2 = "status0_fans12"; 4012661f1eSBrandon Wyman 4112661f1eSBrandon Wyman // Reports on temperature faults or warnings. Overtemperature fault, 4212661f1eSBrandon Wyman // overtemperature warning, undertemperature warning, undertemperature fault. 4312661f1eSBrandon Wyman constexpr auto STATUS_TEMPERATURE = "status0_temp"; 4412661f1eSBrandon Wyman 45e7e432b4SMatt Spinler namespace status_word 46e7e432b4SMatt Spinler { 47e7e432b4SMatt Spinler constexpr auto VOUT_FAULT = 0x8000; 48764c797eSBrandon Wyman 49764c797eSBrandon Wyman // The IBM CFF power supply driver does map this bit to power1_alarm in the 50764c797eSBrandon Wyman // hwmon space, but since the other bits that need to be checked do not have 51764c797eSBrandon Wyman // a similar mapping, the code will just read STATUS_WORD and use bit masking 52764c797eSBrandon Wyman // to see if the INPUT FAULT OR WARNING bit is on. 53764c797eSBrandon Wyman constexpr auto INPUT_FAULT_WARN = 0x2000; 54764c797eSBrandon Wyman 55764c797eSBrandon Wyman // The bit mask representing the POWER_GOOD Negated bit of the STATUS_WORD. 56764c797eSBrandon Wyman constexpr auto POWER_GOOD_NEGATED = 0x0800; 57764c797eSBrandon Wyman 5812661f1eSBrandon Wyman // The bit mask representing the FAN FAULT or WARNING bit of the STATUS_WORD. 5912661f1eSBrandon Wyman // Bit 2 of the high byte of STATUS_WORD. 6012661f1eSBrandon Wyman constexpr auto FAN_FAULT = 0x0400; 6112661f1eSBrandon Wyman 62764c797eSBrandon Wyman // The bit mask representing the UNITI_IS_OFF bit of the STATUS_WORD. 63764c797eSBrandon Wyman constexpr auto UNIT_IS_OFF = 0x0040; 64764c797eSBrandon Wyman 65ab05c079SBrandon Wyman // Bit 5 of the STATUS_BYTE, or lower byte of STATUS_WORD is used to indicate 66ab05c079SBrandon Wyman // an output overvoltage fault. 67ab05c079SBrandon Wyman constexpr auto VOUT_OV_FAULT = 0x0020; 68ab05c079SBrandon Wyman 69b165c251SBrandon Wyman // The bit mask representing that an output overcurrent fault has occurred. 70b165c251SBrandon Wyman constexpr auto IOUT_OC_FAULT = 0x0010; 71b165c251SBrandon Wyman 72764c797eSBrandon Wyman // The IBM CFF power supply driver does map this bit to in1_alarm, however, 73764c797eSBrandon Wyman // since a number of the other bits are not mapped that way for STATUS_WORD, 74764c797eSBrandon Wyman // this code will just read the entire STATUS_WORD and use bit masking to find 75764c797eSBrandon Wyman // out if that fault is on. 76764c797eSBrandon Wyman constexpr auto VIN_UV_FAULT = 0x0008; 77764c797eSBrandon Wyman 78875b363cSBrandon Wyman // The bit mask representing the TEMPERATURE FAULT or WARNING bit of the 79875b363cSBrandon Wyman // STATUS_WORD. Bit 2 of the low byte (STATUS_BYTE). 80875b363cSBrandon Wyman constexpr auto TEMPERATURE_FAULT_WARN = 0x0004; 81875b363cSBrandon Wyman 82f0f02b9aSMatt Spinler } // namespace status_word 83875b363cSBrandon Wyman 84*e8c9cd64SLei YU namespace status_vout 85*e8c9cd64SLei YU { 86*e8c9cd64SLei YU // The IBM CFF power supply driver maps MFR's OV_FAULT and VAUX_FAULT to this 87*e8c9cd64SLei YU // bit. 88*e8c9cd64SLei YU constexpr auto OV_FAULT = 0x80; 89*e8c9cd64SLei YU 90*e8c9cd64SLei YU // The IBM CFF power supply driver maps MFR's UV_FAULT to this bit. 91*e8c9cd64SLei YU constexpr auto UV_FAULT = 0x10; 92*e8c9cd64SLei YU } // namespace status_vout 93*e8c9cd64SLei YU 94875b363cSBrandon Wyman namespace status_temperature 95875b363cSBrandon Wyman { 96875b363cSBrandon Wyman // Overtemperature Fault 97875b363cSBrandon Wyman constexpr auto OT_FAULT = 0x80; 98f0f02b9aSMatt Spinler } // namespace status_temperature 99e7e432b4SMatt Spinler 100015e3adeSMatt Spinler /** 1014dc4678eSMatt Spinler * Where the access should be done 10257868bc5SMatt Spinler */ 10357868bc5SMatt Spinler enum class Type 10457868bc5SMatt Spinler { 1054dc4678eSMatt Spinler Base, // base device directory 1064dc4678eSMatt Spinler Hwmon, // hwmon directory 1074dc4678eSMatt Spinler Debug, // pmbus debug directory 1084dc4678eSMatt Spinler DeviceDebug, // device debug directory 1094dc4678eSMatt Spinler HwmonDeviceDebug // hwmon device debug directory 11057868bc5SMatt Spinler }; 11157868bc5SMatt Spinler 11257868bc5SMatt Spinler /** 113015e3adeSMatt Spinler * @class PMBus 114015e3adeSMatt Spinler * 115015e3adeSMatt Spinler * This class is an interface to communicating with PMBus devices 116015e3adeSMatt Spinler * by reading and writing sysfs files. 11757868bc5SMatt Spinler * 11857868bc5SMatt Spinler * Based on the Type parameter, the accesses can either be done 11957868bc5SMatt Spinler * in the base device directory (the one passed into the constructor), 12057868bc5SMatt Spinler * or in the hwmon directory for the device. 121015e3adeSMatt Spinler */ 122015e3adeSMatt Spinler class PMBus 123015e3adeSMatt Spinler { 124015e3adeSMatt Spinler public: 125015e3adeSMatt Spinler PMBus() = delete; 126015e3adeSMatt Spinler ~PMBus() = default; 127015e3adeSMatt Spinler PMBus(const PMBus&) = default; 128015e3adeSMatt Spinler PMBus& operator=(const PMBus&) = default; 129015e3adeSMatt Spinler PMBus(PMBus&&) = default; 130015e3adeSMatt Spinler PMBus& operator=(PMBus&&) = default; 131015e3adeSMatt Spinler 132015e3adeSMatt Spinler /** 133015e3adeSMatt Spinler * Constructor 134015e3adeSMatt Spinler * 135015e3adeSMatt Spinler * @param[in] path - path to the sysfs directory 136015e3adeSMatt Spinler */ 137f0f02b9aSMatt Spinler PMBus(const std::string& path) : basePath(path) 138015e3adeSMatt Spinler { 139ff5f339cSBrandon Wyman findHwmonDir(); 140015e3adeSMatt Spinler } 141015e3adeSMatt Spinler 142015e3adeSMatt Spinler /** 1438f0d953fSMatt Spinler * Constructor 1448f0d953fSMatt Spinler * 1458f0d953fSMatt Spinler * This version is required when DeviceDebug 1468f0d953fSMatt Spinler * access will be used. 1478f0d953fSMatt Spinler * 1488f0d953fSMatt Spinler * @param[in] path - path to the sysfs directory 1498f0d953fSMatt Spinler * @param[in] driverName - the device driver name 1508f0d953fSMatt Spinler * @param[in] instance - chip instance number 1518f0d953fSMatt Spinler */ 152f0f02b9aSMatt Spinler PMBus(const std::string& path, const std::string& driverName, 1538f0d953fSMatt Spinler size_t instance) : 1548f0d953fSMatt Spinler basePath(path), 155f0f02b9aSMatt Spinler driverName(driverName), instance(instance) 1568f0d953fSMatt Spinler { 1578f0d953fSMatt Spinler findHwmonDir(); 1588f0d953fSMatt Spinler } 1598f0d953fSMatt Spinler 1608f0d953fSMatt Spinler /** 161015e3adeSMatt Spinler * Reads a file in sysfs that represents a single bit, 162015e3adeSMatt Spinler * therefore doing a PMBus read. 163015e3adeSMatt Spinler * 164015e3adeSMatt Spinler * @param[in] name - path concatenated to 165015e3adeSMatt Spinler * basePath to read 1668f0d953fSMatt Spinler * @param[in] type - Path type 167015e3adeSMatt Spinler * 168015e3adeSMatt Spinler * @return bool - false if result was 0, else true 169015e3adeSMatt Spinler */ 17057868bc5SMatt Spinler bool readBit(const std::string& name, Type type); 171015e3adeSMatt Spinler 172015e3adeSMatt Spinler /** 173015e3adeSMatt Spinler * Reads a file in sysfs that represents a single bit, 174015e3adeSMatt Spinler * where the page number passed in is substituted 175015e3adeSMatt Spinler * into the name in place of the 'P' character in it. 176015e3adeSMatt Spinler * 177015e3adeSMatt Spinler * @param[in] name - path concatenated to 178015e3adeSMatt Spinler * basePath to read 179015e3adeSMatt Spinler * @param[in] page - page number 1808f0d953fSMatt Spinler * @param[in] type - Path type 181015e3adeSMatt Spinler * 182015e3adeSMatt Spinler * @return bool - false if result was 0, else true 183015e3adeSMatt Spinler */ 184f0f02b9aSMatt Spinler bool readBitInPage(const std::string& name, size_t page, Type type); 185f855e82aSBrandon Wyman /** 1863b7b38baSBrandon Wyman * Checks if the file for the given name and type exists. 1873b7b38baSBrandon Wyman * 1883b7b38baSBrandon Wyman * @param[in] name - path concatenated to basePath to read 1893b7b38baSBrandon Wyman * @param[in] type - Path type 1903b7b38baSBrandon Wyman * 1913b7b38baSBrandon Wyman * @return bool - True if file exists, false if it does not. 1923b7b38baSBrandon Wyman */ 1933b7b38baSBrandon Wyman bool exists(const std::string& name, Type type); 1943b7b38baSBrandon Wyman 1953b7b38baSBrandon Wyman /** 196f855e82aSBrandon Wyman * Read byte(s) from file in sysfs. 197f855e82aSBrandon Wyman * 198f855e82aSBrandon Wyman * @param[in] name - path concatenated to basePath to read 1998f0d953fSMatt Spinler * @param[in] type - Path type 200f855e82aSBrandon Wyman * 201f855e82aSBrandon Wyman * @return uint64_t - Up to 8 bytes of data read from file. 202f855e82aSBrandon Wyman */ 203f855e82aSBrandon Wyman uint64_t read(const std::string& name, Type type); 204015e3adeSMatt Spinler 205015e3adeSMatt Spinler /** 206fbae7b6cSMatt Spinler * Read a string from file in sysfs. 207fbae7b6cSMatt Spinler * 208fbae7b6cSMatt Spinler * @param[in] name - path concatenated to basePath to read 209fbae7b6cSMatt Spinler * @param[in] type - Path type 210fbae7b6cSMatt Spinler * 211fbae7b6cSMatt Spinler * @return string - The data read from the file. 212fbae7b6cSMatt Spinler */ 213fbae7b6cSMatt Spinler std::string readString(const std::string& name, Type type); 214fbae7b6cSMatt Spinler 215fbae7b6cSMatt Spinler /** 216fa23e330SMatt Spinler * Read data from a binary file in sysfs. 217fa23e330SMatt Spinler * 218fa23e330SMatt Spinler * @param[in] name - path concatenated to basePath to read 219fa23e330SMatt Spinler * @param[in] type - Path type 220fa23e330SMatt Spinler * @param[in] length - length of data to read, in bytes 221fa23e330SMatt Spinler * 222fa23e330SMatt Spinler * @return vector<uint8_t> - The data read from the file. 223fa23e330SMatt Spinler */ 224f0f02b9aSMatt Spinler std::vector<uint8_t> readBinary(const std::string& name, Type type, 225fa23e330SMatt Spinler size_t length); 226fa23e330SMatt Spinler 227fa23e330SMatt Spinler /** 228015e3adeSMatt Spinler * Writes an integer value to the file, therefore doing 229015e3adeSMatt Spinler * a PMBus write. 230015e3adeSMatt Spinler * 231015e3adeSMatt Spinler * @param[in] name - path concatenated to 232015e3adeSMatt Spinler * basePath to write 233015e3adeSMatt Spinler * @param[in] value - the value to write 2348f0d953fSMatt Spinler * @param[in] type - Path type 235015e3adeSMatt Spinler */ 23657868bc5SMatt Spinler void write(const std::string& name, int value, Type type); 237015e3adeSMatt Spinler 238015e3adeSMatt Spinler /** 239015e3adeSMatt Spinler * Returns the sysfs base path of this device 240015e3adeSMatt Spinler */ 241015e3adeSMatt Spinler inline const auto& path() const 242015e3adeSMatt Spinler { 243015e3adeSMatt Spinler return basePath; 244015e3adeSMatt Spinler } 245015e3adeSMatt Spinler 246015e3adeSMatt Spinler /** 247015e3adeSMatt Spinler * Replaces the 'P' in the string passed in with 248015e3adeSMatt Spinler * the page number passed in. 249015e3adeSMatt Spinler * 250015e3adeSMatt Spinler * For example: 251015e3adeSMatt Spinler * insertPageNum("inP_enable", 42) 252015e3adeSMatt Spinler * returns "in42_enable" 253015e3adeSMatt Spinler * 254015e3adeSMatt Spinler * @param[in] templateName - the name string, with a 'P' in it 255015e3adeSMatt Spinler * @param[in] page - the page number to insert where the P was 256015e3adeSMatt Spinler * 257015e3adeSMatt Spinler * @return string - the new string with the page number in it 258015e3adeSMatt Spinler */ 259015e3adeSMatt Spinler static std::string insertPageNum(const std::string& templateName, 260015e3adeSMatt Spinler size_t page); 261015e3adeSMatt Spinler 26257868bc5SMatt Spinler /** 26357868bc5SMatt Spinler * Finds the path relative to basePath to the hwmon directory 26457868bc5SMatt Spinler * for the device and stores it in hwmonRelPath. 26557868bc5SMatt Spinler */ 266ff5f339cSBrandon Wyman void findHwmonDir(); 267ff5f339cSBrandon Wyman 268ff5f339cSBrandon Wyman /** 269ff5f339cSBrandon Wyman * Returns the path to use for the passed in type. 270ff5f339cSBrandon Wyman * 2718f0d953fSMatt Spinler * @param[in] type - Path type 272ff5f339cSBrandon Wyman * 2738f0d953fSMatt Spinler * @return fs::path - the full path 274ff5f339cSBrandon Wyman */ 275ff5f339cSBrandon Wyman fs::path getPath(Type type); 27657868bc5SMatt Spinler 277015e3adeSMatt Spinler private: 278015e3adeSMatt Spinler /** 279ba05348fSMatt Spinler * Returns the device name 280ba05348fSMatt Spinler * 281ba05348fSMatt Spinler * This is found in the 'name' file in basePath. 282ba05348fSMatt Spinler * 283ba05348fSMatt Spinler * @return string - the device name 284ba05348fSMatt Spinler */ 285ba05348fSMatt Spinler std::string getDeviceName(); 286ba05348fSMatt Spinler 287ba05348fSMatt Spinler /** 288015e3adeSMatt Spinler * The sysfs device path 289015e3adeSMatt Spinler */ 290ff5f339cSBrandon Wyman fs::path basePath; 291015e3adeSMatt Spinler 29257868bc5SMatt Spinler /** 293ff5f339cSBrandon Wyman * The directory name under the basePath hwmon directory 29457868bc5SMatt Spinler */ 295ff5f339cSBrandon Wyman fs::path hwmonDir; 296ff5f339cSBrandon Wyman 297ff5f339cSBrandon Wyman /** 2988f0d953fSMatt Spinler * The device driver name. Used for finding the device 2998f0d953fSMatt Spinler * debug directory. Not required if that directory 3008f0d953fSMatt Spinler * isn't used. 3018f0d953fSMatt Spinler */ 3028f0d953fSMatt Spinler std::string driverName; 3038f0d953fSMatt Spinler 3048f0d953fSMatt Spinler /** 3058f0d953fSMatt Spinler * The device instance number. 3068f0d953fSMatt Spinler * 307cab48342SGunnar Mills * Used in conjunction with the driver name for finding 3088f0d953fSMatt Spinler * the debug directory. Not required if that directory 3098f0d953fSMatt Spinler * isn't used. 3108f0d953fSMatt Spinler */ 3118f0d953fSMatt Spinler size_t instance = 0; 3128f0d953fSMatt Spinler 3138f0d953fSMatt Spinler /** 314ff5f339cSBrandon Wyman * The pmbus debug path with status files 315ff5f339cSBrandon Wyman */ 3168f0d953fSMatt Spinler const fs::path debugPath = "/sys/kernel/debug/"; 317015e3adeSMatt Spinler }; 318015e3adeSMatt Spinler 319f0f02b9aSMatt Spinler } // namespace pmbus 320ab093328SLei YU } // namespace phosphor 321