1015e3adeSMatt Spinler #pragma once 2015e3adeSMatt Spinler 39c7897ceSBrandon Wyman #include <filesystem> 4015e3adeSMatt Spinler #include <string> 5015e3adeSMatt Spinler #include <vector> 6015e3adeSMatt Spinler 7*ab093328SLei 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 84875b363cSBrandon Wyman namespace status_temperature 85875b363cSBrandon Wyman { 86875b363cSBrandon Wyman // Overtemperature Fault 87875b363cSBrandon Wyman constexpr auto OT_FAULT = 0x80; 88f0f02b9aSMatt Spinler } // namespace status_temperature 89e7e432b4SMatt Spinler 90015e3adeSMatt Spinler /** 914dc4678eSMatt Spinler * Where the access should be done 9257868bc5SMatt Spinler */ 9357868bc5SMatt Spinler enum class Type 9457868bc5SMatt Spinler { 954dc4678eSMatt Spinler Base, // base device directory 964dc4678eSMatt Spinler Hwmon, // hwmon directory 974dc4678eSMatt Spinler Debug, // pmbus debug directory 984dc4678eSMatt Spinler DeviceDebug, // device debug directory 994dc4678eSMatt Spinler HwmonDeviceDebug // hwmon device debug directory 10057868bc5SMatt Spinler }; 10157868bc5SMatt Spinler 10257868bc5SMatt Spinler /** 103015e3adeSMatt Spinler * @class PMBus 104015e3adeSMatt Spinler * 105015e3adeSMatt Spinler * This class is an interface to communicating with PMBus devices 106015e3adeSMatt Spinler * by reading and writing sysfs files. 10757868bc5SMatt Spinler * 10857868bc5SMatt Spinler * Based on the Type parameter, the accesses can either be done 10957868bc5SMatt Spinler * in the base device directory (the one passed into the constructor), 11057868bc5SMatt Spinler * or in the hwmon directory for the device. 111015e3adeSMatt Spinler */ 112015e3adeSMatt Spinler class PMBus 113015e3adeSMatt Spinler { 114015e3adeSMatt Spinler public: 115015e3adeSMatt Spinler PMBus() = delete; 116015e3adeSMatt Spinler ~PMBus() = default; 117015e3adeSMatt Spinler PMBus(const PMBus&) = default; 118015e3adeSMatt Spinler PMBus& operator=(const PMBus&) = default; 119015e3adeSMatt Spinler PMBus(PMBus&&) = default; 120015e3adeSMatt Spinler PMBus& operator=(PMBus&&) = default; 121015e3adeSMatt Spinler 122015e3adeSMatt Spinler /** 123015e3adeSMatt Spinler * Constructor 124015e3adeSMatt Spinler * 125015e3adeSMatt Spinler * @param[in] path - path to the sysfs directory 126015e3adeSMatt Spinler */ 127f0f02b9aSMatt Spinler PMBus(const std::string& path) : basePath(path) 128015e3adeSMatt Spinler { 129ff5f339cSBrandon Wyman findHwmonDir(); 130015e3adeSMatt Spinler } 131015e3adeSMatt Spinler 132015e3adeSMatt Spinler /** 1338f0d953fSMatt Spinler * Constructor 1348f0d953fSMatt Spinler * 1358f0d953fSMatt Spinler * This version is required when DeviceDebug 1368f0d953fSMatt Spinler * access will be used. 1378f0d953fSMatt Spinler * 1388f0d953fSMatt Spinler * @param[in] path - path to the sysfs directory 1398f0d953fSMatt Spinler * @param[in] driverName - the device driver name 1408f0d953fSMatt Spinler * @param[in] instance - chip instance number 1418f0d953fSMatt Spinler */ 142f0f02b9aSMatt Spinler PMBus(const std::string& path, const std::string& driverName, 1438f0d953fSMatt Spinler size_t instance) : 1448f0d953fSMatt Spinler basePath(path), 145f0f02b9aSMatt Spinler driverName(driverName), instance(instance) 1468f0d953fSMatt Spinler { 1478f0d953fSMatt Spinler findHwmonDir(); 1488f0d953fSMatt Spinler } 1498f0d953fSMatt Spinler 1508f0d953fSMatt Spinler /** 151015e3adeSMatt Spinler * Reads a file in sysfs that represents a single bit, 152015e3adeSMatt Spinler * therefore doing a PMBus read. 153015e3adeSMatt Spinler * 154015e3adeSMatt Spinler * @param[in] name - path concatenated to 155015e3adeSMatt Spinler * basePath to read 1568f0d953fSMatt Spinler * @param[in] type - Path type 157015e3adeSMatt Spinler * 158015e3adeSMatt Spinler * @return bool - false if result was 0, else true 159015e3adeSMatt Spinler */ 16057868bc5SMatt Spinler bool readBit(const std::string& name, Type type); 161015e3adeSMatt Spinler 162015e3adeSMatt Spinler /** 163015e3adeSMatt Spinler * Reads a file in sysfs that represents a single bit, 164015e3adeSMatt Spinler * where the page number passed in is substituted 165015e3adeSMatt Spinler * into the name in place of the 'P' character in it. 166015e3adeSMatt Spinler * 167015e3adeSMatt Spinler * @param[in] name - path concatenated to 168015e3adeSMatt Spinler * basePath to read 169015e3adeSMatt Spinler * @param[in] page - page number 1708f0d953fSMatt Spinler * @param[in] type - Path type 171015e3adeSMatt Spinler * 172015e3adeSMatt Spinler * @return bool - false if result was 0, else true 173015e3adeSMatt Spinler */ 174f0f02b9aSMatt Spinler bool readBitInPage(const std::string& name, size_t page, Type type); 175f855e82aSBrandon Wyman /** 1763b7b38baSBrandon Wyman * Checks if the file for the given name and type exists. 1773b7b38baSBrandon Wyman * 1783b7b38baSBrandon Wyman * @param[in] name - path concatenated to basePath to read 1793b7b38baSBrandon Wyman * @param[in] type - Path type 1803b7b38baSBrandon Wyman * 1813b7b38baSBrandon Wyman * @return bool - True if file exists, false if it does not. 1823b7b38baSBrandon Wyman */ 1833b7b38baSBrandon Wyman bool exists(const std::string& name, Type type); 1843b7b38baSBrandon Wyman 1853b7b38baSBrandon Wyman /** 186f855e82aSBrandon Wyman * Read byte(s) from file in sysfs. 187f855e82aSBrandon Wyman * 188f855e82aSBrandon Wyman * @param[in] name - path concatenated to basePath to read 1898f0d953fSMatt Spinler * @param[in] type - Path type 190f855e82aSBrandon Wyman * 191f855e82aSBrandon Wyman * @return uint64_t - Up to 8 bytes of data read from file. 192f855e82aSBrandon Wyman */ 193f855e82aSBrandon Wyman uint64_t read(const std::string& name, Type type); 194015e3adeSMatt Spinler 195015e3adeSMatt Spinler /** 196fbae7b6cSMatt Spinler * Read a string from file in sysfs. 197fbae7b6cSMatt Spinler * 198fbae7b6cSMatt Spinler * @param[in] name - path concatenated to basePath to read 199fbae7b6cSMatt Spinler * @param[in] type - Path type 200fbae7b6cSMatt Spinler * 201fbae7b6cSMatt Spinler * @return string - The data read from the file. 202fbae7b6cSMatt Spinler */ 203fbae7b6cSMatt Spinler std::string readString(const std::string& name, Type type); 204fbae7b6cSMatt Spinler 205fbae7b6cSMatt Spinler /** 206fa23e330SMatt Spinler * Read data from a binary file in sysfs. 207fa23e330SMatt Spinler * 208fa23e330SMatt Spinler * @param[in] name - path concatenated to basePath to read 209fa23e330SMatt Spinler * @param[in] type - Path type 210fa23e330SMatt Spinler * @param[in] length - length of data to read, in bytes 211fa23e330SMatt Spinler * 212fa23e330SMatt Spinler * @return vector<uint8_t> - The data read from the file. 213fa23e330SMatt Spinler */ 214f0f02b9aSMatt Spinler std::vector<uint8_t> readBinary(const std::string& name, Type type, 215fa23e330SMatt Spinler size_t length); 216fa23e330SMatt Spinler 217fa23e330SMatt Spinler /** 218015e3adeSMatt Spinler * Writes an integer value to the file, therefore doing 219015e3adeSMatt Spinler * a PMBus write. 220015e3adeSMatt Spinler * 221015e3adeSMatt Spinler * @param[in] name - path concatenated to 222015e3adeSMatt Spinler * basePath to write 223015e3adeSMatt Spinler * @param[in] value - the value to write 2248f0d953fSMatt Spinler * @param[in] type - Path type 225015e3adeSMatt Spinler */ 22657868bc5SMatt Spinler void write(const std::string& name, int value, Type type); 227015e3adeSMatt Spinler 228015e3adeSMatt Spinler /** 229015e3adeSMatt Spinler * Returns the sysfs base path of this device 230015e3adeSMatt Spinler */ 231015e3adeSMatt Spinler inline const auto& path() const 232015e3adeSMatt Spinler { 233015e3adeSMatt Spinler return basePath; 234015e3adeSMatt Spinler } 235015e3adeSMatt Spinler 236015e3adeSMatt Spinler /** 237015e3adeSMatt Spinler * Replaces the 'P' in the string passed in with 238015e3adeSMatt Spinler * the page number passed in. 239015e3adeSMatt Spinler * 240015e3adeSMatt Spinler * For example: 241015e3adeSMatt Spinler * insertPageNum("inP_enable", 42) 242015e3adeSMatt Spinler * returns "in42_enable" 243015e3adeSMatt Spinler * 244015e3adeSMatt Spinler * @param[in] templateName - the name string, with a 'P' in it 245015e3adeSMatt Spinler * @param[in] page - the page number to insert where the P was 246015e3adeSMatt Spinler * 247015e3adeSMatt Spinler * @return string - the new string with the page number in it 248015e3adeSMatt Spinler */ 249015e3adeSMatt Spinler static std::string insertPageNum(const std::string& templateName, 250015e3adeSMatt Spinler size_t page); 251015e3adeSMatt Spinler 25257868bc5SMatt Spinler /** 25357868bc5SMatt Spinler * Finds the path relative to basePath to the hwmon directory 25457868bc5SMatt Spinler * for the device and stores it in hwmonRelPath. 25557868bc5SMatt Spinler */ 256ff5f339cSBrandon Wyman void findHwmonDir(); 257ff5f339cSBrandon Wyman 258ff5f339cSBrandon Wyman /** 259ff5f339cSBrandon Wyman * Returns the path to use for the passed in type. 260ff5f339cSBrandon Wyman * 2618f0d953fSMatt Spinler * @param[in] type - Path type 262ff5f339cSBrandon Wyman * 2638f0d953fSMatt Spinler * @return fs::path - the full path 264ff5f339cSBrandon Wyman */ 265ff5f339cSBrandon Wyman fs::path getPath(Type type); 26657868bc5SMatt Spinler 267015e3adeSMatt Spinler private: 268015e3adeSMatt Spinler /** 269ba05348fSMatt Spinler * Returns the device name 270ba05348fSMatt Spinler * 271ba05348fSMatt Spinler * This is found in the 'name' file in basePath. 272ba05348fSMatt Spinler * 273ba05348fSMatt Spinler * @return string - the device name 274ba05348fSMatt Spinler */ 275ba05348fSMatt Spinler std::string getDeviceName(); 276ba05348fSMatt Spinler 277ba05348fSMatt Spinler /** 278015e3adeSMatt Spinler * The sysfs device path 279015e3adeSMatt Spinler */ 280ff5f339cSBrandon Wyman fs::path basePath; 281015e3adeSMatt Spinler 28257868bc5SMatt Spinler /** 283ff5f339cSBrandon Wyman * The directory name under the basePath hwmon directory 28457868bc5SMatt Spinler */ 285ff5f339cSBrandon Wyman fs::path hwmonDir; 286ff5f339cSBrandon Wyman 287ff5f339cSBrandon Wyman /** 2888f0d953fSMatt Spinler * The device driver name. Used for finding the device 2898f0d953fSMatt Spinler * debug directory. Not required if that directory 2908f0d953fSMatt Spinler * isn't used. 2918f0d953fSMatt Spinler */ 2928f0d953fSMatt Spinler std::string driverName; 2938f0d953fSMatt Spinler 2948f0d953fSMatt Spinler /** 2958f0d953fSMatt Spinler * The device instance number. 2968f0d953fSMatt Spinler * 297cab48342SGunnar Mills * Used in conjunction with the driver name for finding 2988f0d953fSMatt Spinler * the debug directory. Not required if that directory 2998f0d953fSMatt Spinler * isn't used. 3008f0d953fSMatt Spinler */ 3018f0d953fSMatt Spinler size_t instance = 0; 3028f0d953fSMatt Spinler 3038f0d953fSMatt Spinler /** 304ff5f339cSBrandon Wyman * The pmbus debug path with status files 305ff5f339cSBrandon Wyman */ 3068f0d953fSMatt Spinler const fs::path debugPath = "/sys/kernel/debug/"; 307015e3adeSMatt Spinler }; 308015e3adeSMatt Spinler 309f0f02b9aSMatt Spinler } // namespace pmbus 310*ab093328SLei YU } // namespace phosphor 311