xref: /openbmc/phosphor-power/pmbus.hpp (revision f0f02b9ae21ece3d691c1bbea348b468787ed2ff)
1015e3adeSMatt Spinler #pragma once
2015e3adeSMatt Spinler 
3015e3adeSMatt Spinler #include <experimental/filesystem>
4015e3adeSMatt Spinler #include <string>
5015e3adeSMatt Spinler #include <vector>
6015e3adeSMatt Spinler 
7015e3adeSMatt Spinler namespace witherspoon
8015e3adeSMatt Spinler {
9015e3adeSMatt Spinler namespace pmbus
10015e3adeSMatt Spinler {
11015e3adeSMatt Spinler 
12ff5f339cSBrandon Wyman namespace fs = std::experimental::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;
30*f0f02b9aSMatt 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 
82*f0f02b9aSMatt Spinler } // namespace status_word
83875b363cSBrandon Wyman 
84875b363cSBrandon Wyman namespace status_temperature
85875b363cSBrandon Wyman {
86875b363cSBrandon Wyman // Overtemperature Fault
87875b363cSBrandon Wyman constexpr auto OT_FAULT = 0x80;
88*f0f02b9aSMatt 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      */
127*f0f02b9aSMatt 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      */
142*f0f02b9aSMatt Spinler     PMBus(const std::string& path, const std::string& driverName,
1438f0d953fSMatt Spinler           size_t instance) :
1448f0d953fSMatt Spinler         basePath(path),
145*f0f02b9aSMatt 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      */
174*f0f02b9aSMatt 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      */
214*f0f02b9aSMatt 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 
309*f0f02b9aSMatt Spinler } // namespace pmbus
310*f0f02b9aSMatt Spinler } // namespace witherspoon
311