xref: /openbmc/phosphor-power/pmbus.hpp (revision de16d053f3275d44279cb662b08da451dc2c66f9)
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 
26*de16d053SMatt Spinler namespace status_vout
27*de16d053SMatt Spinler {
28*de16d053SMatt Spinler // Mask of bits that are only warnings
29*de16d053SMatt Spinler constexpr auto WARNING_MASK = 0x6A;
30*de16d053SMatt Spinler }
31*de16d053SMatt 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 
82875b363cSBrandon Wyman }
83875b363cSBrandon Wyman 
84875b363cSBrandon Wyman namespace status_temperature
85875b363cSBrandon Wyman {
86875b363cSBrandon Wyman // Overtemperature Fault
87875b363cSBrandon Wyman constexpr auto OT_FAULT = 0x80;
88e7e432b4SMatt Spinler }
89e7e432b4SMatt Spinler 
90015e3adeSMatt Spinler /**
9157868bc5SMatt Spinler  * If the access should be done in the base
928f0d953fSMatt Spinler  * device directory, the hwmon directory, the
938f0d953fSMatt Spinler  * pmbus debug directory, or the device debug
948f0d953fSMatt Spinler  * directory.
9557868bc5SMatt Spinler  */
9657868bc5SMatt Spinler enum class Type
9757868bc5SMatt Spinler {
9857868bc5SMatt Spinler     Base,
99ff5f339cSBrandon Wyman     Hwmon,
1008f0d953fSMatt Spinler     Debug,
1018f0d953fSMatt Spinler     DeviceDebug
10257868bc5SMatt Spinler };
10357868bc5SMatt Spinler 
10457868bc5SMatt Spinler /**
105015e3adeSMatt Spinler  * @class PMBus
106015e3adeSMatt Spinler  *
107015e3adeSMatt Spinler  * This class is an interface to communicating with PMBus devices
108015e3adeSMatt Spinler  * by reading and writing sysfs files.
10957868bc5SMatt Spinler  *
11057868bc5SMatt Spinler  * Based on the Type parameter, the accesses can either be done
11157868bc5SMatt Spinler  * in the base device directory (the one passed into the constructor),
11257868bc5SMatt Spinler  * or in the hwmon directory for the device.
113015e3adeSMatt Spinler  */
114015e3adeSMatt Spinler class PMBus
115015e3adeSMatt Spinler {
116015e3adeSMatt Spinler     public:
117015e3adeSMatt Spinler 
118015e3adeSMatt Spinler         PMBus() = delete;
119015e3adeSMatt Spinler         ~PMBus() = default;
120015e3adeSMatt Spinler         PMBus(const PMBus&) = default;
121015e3adeSMatt Spinler         PMBus& operator=(const PMBus&) = default;
122015e3adeSMatt Spinler         PMBus(PMBus&&) = default;
123015e3adeSMatt Spinler         PMBus& operator=(PMBus&&) = default;
124015e3adeSMatt Spinler 
125015e3adeSMatt Spinler         /**
126015e3adeSMatt Spinler          * Constructor
127015e3adeSMatt Spinler          *
128015e3adeSMatt Spinler          * @param[in] path - path to the sysfs directory
129015e3adeSMatt Spinler          */
130015e3adeSMatt Spinler         PMBus(const std::string& path) :
131015e3adeSMatt Spinler             basePath(path)
132015e3adeSMatt Spinler         {
133ff5f339cSBrandon Wyman             findHwmonDir();
134015e3adeSMatt Spinler         }
135015e3adeSMatt Spinler 
136015e3adeSMatt Spinler         /**
1378f0d953fSMatt Spinler          * Constructor
1388f0d953fSMatt Spinler          *
1398f0d953fSMatt Spinler          * This version is required when DeviceDebug
1408f0d953fSMatt Spinler          * access will be used.
1418f0d953fSMatt Spinler          *
1428f0d953fSMatt Spinler          * @param[in] path - path to the sysfs directory
1438f0d953fSMatt Spinler          * @param[in] driverName - the device driver name
1448f0d953fSMatt Spinler          * @param[in] instance - chip instance number
1458f0d953fSMatt Spinler          */
1468f0d953fSMatt Spinler         PMBus(const std::string& path,
1478f0d953fSMatt Spinler               const std::string& driverName,
1488f0d953fSMatt Spinler               size_t instance) :
1498f0d953fSMatt Spinler             basePath(path),
1508f0d953fSMatt Spinler             driverName(driverName),
1518f0d953fSMatt Spinler             instance(instance)
1528f0d953fSMatt Spinler         {
1538f0d953fSMatt Spinler             findHwmonDir();
1548f0d953fSMatt Spinler         }
1558f0d953fSMatt Spinler 
1568f0d953fSMatt Spinler         /**
157015e3adeSMatt Spinler          * Reads a file in sysfs that represents a single bit,
158015e3adeSMatt Spinler          * therefore doing a PMBus read.
159015e3adeSMatt Spinler          *
160015e3adeSMatt Spinler          * @param[in] name - path concatenated to
161015e3adeSMatt Spinler          *                   basePath to read
1628f0d953fSMatt Spinler          * @param[in] type - Path type
163015e3adeSMatt Spinler          *
164015e3adeSMatt Spinler          * @return bool - false if result was 0, else true
165015e3adeSMatt Spinler          */
16657868bc5SMatt Spinler         bool readBit(const std::string& name, Type type);
167015e3adeSMatt Spinler 
168015e3adeSMatt Spinler         /**
169015e3adeSMatt Spinler          * Reads a file in sysfs that represents a single bit,
170015e3adeSMatt Spinler          * where the page number passed in is substituted
171015e3adeSMatt Spinler          * into the name in place of the 'P' character in it.
172015e3adeSMatt Spinler          *
173015e3adeSMatt Spinler          * @param[in] name - path concatenated to
174015e3adeSMatt Spinler          *                   basePath to read
175015e3adeSMatt Spinler          * @param[in] page - page number
1768f0d953fSMatt Spinler          * @param[in] type - Path type
177015e3adeSMatt Spinler          *
178015e3adeSMatt Spinler          * @return bool - false if result was 0, else true
179015e3adeSMatt Spinler          */
180015e3adeSMatt Spinler         bool readBitInPage(const std::string& name,
18157868bc5SMatt Spinler                            size_t page,
18257868bc5SMatt Spinler                            Type type);
183f855e82aSBrandon Wyman         /**
1843b7b38baSBrandon Wyman          * Checks if the file for the given name and type exists.
1853b7b38baSBrandon Wyman          *
1863b7b38baSBrandon Wyman          * @param[in] name   - path concatenated to basePath to read
1873b7b38baSBrandon Wyman          * @param[in] type   - Path type
1883b7b38baSBrandon Wyman          *
1893b7b38baSBrandon Wyman          * @return bool - True if file exists, false if it does not.
1903b7b38baSBrandon Wyman          */
1913b7b38baSBrandon Wyman         bool exists(const std::string& name, Type type);
1923b7b38baSBrandon Wyman 
1933b7b38baSBrandon Wyman         /**
194f855e82aSBrandon Wyman          * Read byte(s) from file in sysfs.
195f855e82aSBrandon Wyman          *
196f855e82aSBrandon Wyman          * @param[in] name   - path concatenated to basePath to read
1978f0d953fSMatt Spinler          * @param[in] type   - Path type
198f855e82aSBrandon Wyman          *
199f855e82aSBrandon Wyman          * @return uint64_t - Up to 8 bytes of data read from file.
200f855e82aSBrandon Wyman          */
201f855e82aSBrandon Wyman         uint64_t read(const std::string& name, Type type);
202015e3adeSMatt Spinler 
203015e3adeSMatt Spinler         /**
204015e3adeSMatt Spinler          * Writes an integer value to the file, therefore doing
205015e3adeSMatt Spinler          * a PMBus write.
206015e3adeSMatt Spinler          *
207015e3adeSMatt Spinler          * @param[in] name - path concatenated to
208015e3adeSMatt Spinler          *                   basePath to write
209015e3adeSMatt Spinler          * @param[in] value - the value to write
2108f0d953fSMatt Spinler          * @param[in] type - Path type
211015e3adeSMatt Spinler          */
21257868bc5SMatt Spinler         void write(const std::string& name, int value, Type type);
213015e3adeSMatt Spinler 
214015e3adeSMatt Spinler         /**
215015e3adeSMatt Spinler          * Returns the sysfs base path of this device
216015e3adeSMatt Spinler          */
217015e3adeSMatt Spinler         inline const auto& path() const
218015e3adeSMatt Spinler         {
219015e3adeSMatt Spinler             return basePath;
220015e3adeSMatt Spinler         }
221015e3adeSMatt Spinler 
222015e3adeSMatt Spinler         /**
223015e3adeSMatt Spinler          * Replaces the 'P' in the string passed in with
224015e3adeSMatt Spinler          * the page number passed in.
225015e3adeSMatt Spinler          *
226015e3adeSMatt Spinler          * For example:
227015e3adeSMatt Spinler          *   insertPageNum("inP_enable", 42)
228015e3adeSMatt Spinler          *   returns "in42_enable"
229015e3adeSMatt Spinler          *
230015e3adeSMatt Spinler          * @param[in] templateName - the name string, with a 'P' in it
231015e3adeSMatt Spinler          * @param[in] page - the page number to insert where the P was
232015e3adeSMatt Spinler          *
233015e3adeSMatt Spinler          * @return string - the new string with the page number in it
234015e3adeSMatt Spinler          */
235015e3adeSMatt Spinler         static std::string insertPageNum(const std::string& templateName,
236015e3adeSMatt Spinler                                          size_t page);
237015e3adeSMatt Spinler 
23857868bc5SMatt Spinler         /**
23957868bc5SMatt Spinler          * Finds the path relative to basePath to the hwmon directory
24057868bc5SMatt Spinler          * for the device and stores it in hwmonRelPath.
24157868bc5SMatt Spinler          */
242ff5f339cSBrandon Wyman         void findHwmonDir();
243ff5f339cSBrandon Wyman 
244ff5f339cSBrandon Wyman         /**
245ff5f339cSBrandon Wyman          * Returns the path to use for the passed in type.
246ff5f339cSBrandon Wyman          *
2478f0d953fSMatt Spinler          * @param[in] type - Path type
248ff5f339cSBrandon Wyman          *
2498f0d953fSMatt Spinler          * @return fs::path - the full path
250ff5f339cSBrandon Wyman          */
251ff5f339cSBrandon Wyman         fs::path getPath(Type type);
25257868bc5SMatt Spinler 
253015e3adeSMatt Spinler     private:
254015e3adeSMatt Spinler 
255015e3adeSMatt Spinler         /**
256015e3adeSMatt Spinler          * The sysfs device path
257015e3adeSMatt Spinler          */
258ff5f339cSBrandon Wyman         fs::path basePath;
259015e3adeSMatt Spinler 
26057868bc5SMatt Spinler         /**
261ff5f339cSBrandon Wyman          * The directory name under the basePath hwmon directory
26257868bc5SMatt Spinler          */
263ff5f339cSBrandon Wyman         fs::path hwmonDir;
264ff5f339cSBrandon Wyman 
265ff5f339cSBrandon Wyman         /**
2668f0d953fSMatt Spinler          * The device driver name.  Used for finding the device
2678f0d953fSMatt Spinler          * debug directory.  Not required if that directory
2688f0d953fSMatt Spinler          * isn't used.
2698f0d953fSMatt Spinler          */
2708f0d953fSMatt Spinler         std::string driverName;
2718f0d953fSMatt Spinler 
2728f0d953fSMatt Spinler         /**
2738f0d953fSMatt Spinler          * The device instance number.
2748f0d953fSMatt Spinler          *
2758f0d953fSMatt Spinler          * Used in conjuction with the driver name for finding
2768f0d953fSMatt Spinler          * the debug directory.  Not required if that directory
2778f0d953fSMatt Spinler          * isn't used.
2788f0d953fSMatt Spinler          */
2798f0d953fSMatt Spinler         size_t instance = 0;
2808f0d953fSMatt Spinler 
2818f0d953fSMatt Spinler         /**
282ff5f339cSBrandon Wyman          * The pmbus debug path with status files
283ff5f339cSBrandon Wyman          */
2848f0d953fSMatt Spinler         const fs::path debugPath = "/sys/kernel/debug/";
28557868bc5SMatt Spinler 
286015e3adeSMatt Spinler };
287015e3adeSMatt Spinler 
288015e3adeSMatt Spinler }
289015e3adeSMatt Spinler }
290