xref: /openbmc/phosphor-power/pmbus.hpp (revision 4dc4678e1d5c226cd594b4c9dd434540a889adc2)
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;
30de16d053SMatt Spinler }
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 
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 /**
91*4dc4678eSMatt Spinler  * Where the access should be done
9257868bc5SMatt Spinler  */
9357868bc5SMatt Spinler enum class Type
9457868bc5SMatt Spinler {
95*4dc4678eSMatt Spinler     Base,             // base device directory
96*4dc4678eSMatt Spinler     Hwmon,            // hwmon directory
97*4dc4678eSMatt Spinler     Debug,            // pmbus debug directory
98*4dc4678eSMatt Spinler     DeviceDebug,      // device debug directory
99*4dc4678eSMatt 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 
116015e3adeSMatt Spinler         PMBus() = delete;
117015e3adeSMatt Spinler         ~PMBus() = default;
118015e3adeSMatt Spinler         PMBus(const PMBus&) = default;
119015e3adeSMatt Spinler         PMBus& operator=(const PMBus&) = default;
120015e3adeSMatt Spinler         PMBus(PMBus&&) = default;
121015e3adeSMatt Spinler         PMBus& operator=(PMBus&&) = default;
122015e3adeSMatt Spinler 
123015e3adeSMatt Spinler         /**
124015e3adeSMatt Spinler          * Constructor
125015e3adeSMatt Spinler          *
126015e3adeSMatt Spinler          * @param[in] path - path to the sysfs directory
127015e3adeSMatt Spinler          */
128015e3adeSMatt Spinler         PMBus(const std::string& path) :
129015e3adeSMatt Spinler             basePath(path)
130015e3adeSMatt Spinler         {
131ff5f339cSBrandon Wyman             findHwmonDir();
132015e3adeSMatt Spinler         }
133015e3adeSMatt Spinler 
134015e3adeSMatt Spinler         /**
1358f0d953fSMatt Spinler          * Constructor
1368f0d953fSMatt Spinler          *
1378f0d953fSMatt Spinler          * This version is required when DeviceDebug
1388f0d953fSMatt Spinler          * access will be used.
1398f0d953fSMatt Spinler          *
1408f0d953fSMatt Spinler          * @param[in] path - path to the sysfs directory
1418f0d953fSMatt Spinler          * @param[in] driverName - the device driver name
1428f0d953fSMatt Spinler          * @param[in] instance - chip instance number
1438f0d953fSMatt Spinler          */
1448f0d953fSMatt Spinler         PMBus(const std::string& path,
1458f0d953fSMatt Spinler               const std::string& driverName,
1468f0d953fSMatt Spinler               size_t instance) :
1478f0d953fSMatt Spinler             basePath(path),
1488f0d953fSMatt Spinler             driverName(driverName),
1498f0d953fSMatt Spinler             instance(instance)
1508f0d953fSMatt Spinler         {
1518f0d953fSMatt Spinler             findHwmonDir();
1528f0d953fSMatt Spinler         }
1538f0d953fSMatt Spinler 
1548f0d953fSMatt Spinler         /**
155015e3adeSMatt Spinler          * Reads a file in sysfs that represents a single bit,
156015e3adeSMatt Spinler          * therefore doing a PMBus read.
157015e3adeSMatt Spinler          *
158015e3adeSMatt Spinler          * @param[in] name - path concatenated to
159015e3adeSMatt Spinler          *                   basePath to read
1608f0d953fSMatt Spinler          * @param[in] type - Path type
161015e3adeSMatt Spinler          *
162015e3adeSMatt Spinler          * @return bool - false if result was 0, else true
163015e3adeSMatt Spinler          */
16457868bc5SMatt Spinler         bool readBit(const std::string& name, Type type);
165015e3adeSMatt Spinler 
166015e3adeSMatt Spinler         /**
167015e3adeSMatt Spinler          * Reads a file in sysfs that represents a single bit,
168015e3adeSMatt Spinler          * where the page number passed in is substituted
169015e3adeSMatt Spinler          * into the name in place of the 'P' character in it.
170015e3adeSMatt Spinler          *
171015e3adeSMatt Spinler          * @param[in] name - path concatenated to
172015e3adeSMatt Spinler          *                   basePath to read
173015e3adeSMatt Spinler          * @param[in] page - page number
1748f0d953fSMatt Spinler          * @param[in] type - Path type
175015e3adeSMatt Spinler          *
176015e3adeSMatt Spinler          * @return bool - false if result was 0, else true
177015e3adeSMatt Spinler          */
178015e3adeSMatt Spinler         bool readBitInPage(const std::string& name,
17957868bc5SMatt Spinler                            size_t page,
18057868bc5SMatt Spinler                            Type type);
181f855e82aSBrandon Wyman         /**
1823b7b38baSBrandon Wyman          * Checks if the file for the given name and type exists.
1833b7b38baSBrandon Wyman          *
1843b7b38baSBrandon Wyman          * @param[in] name   - path concatenated to basePath to read
1853b7b38baSBrandon Wyman          * @param[in] type   - Path type
1863b7b38baSBrandon Wyman          *
1873b7b38baSBrandon Wyman          * @return bool - True if file exists, false if it does not.
1883b7b38baSBrandon Wyman          */
1893b7b38baSBrandon Wyman         bool exists(const std::string& name, Type type);
1903b7b38baSBrandon Wyman 
1913b7b38baSBrandon Wyman         /**
192f855e82aSBrandon Wyman          * Read byte(s) from file in sysfs.
193f855e82aSBrandon Wyman          *
194f855e82aSBrandon Wyman          * @param[in] name   - path concatenated to basePath to read
1958f0d953fSMatt Spinler          * @param[in] type   - Path type
196f855e82aSBrandon Wyman          *
197f855e82aSBrandon Wyman          * @return uint64_t - Up to 8 bytes of data read from file.
198f855e82aSBrandon Wyman          */
199f855e82aSBrandon Wyman         uint64_t read(const std::string& name, Type type);
200015e3adeSMatt Spinler 
201015e3adeSMatt Spinler         /**
202015e3adeSMatt Spinler          * Writes an integer value to the file, therefore doing
203015e3adeSMatt Spinler          * a PMBus write.
204015e3adeSMatt Spinler          *
205015e3adeSMatt Spinler          * @param[in] name - path concatenated to
206015e3adeSMatt Spinler          *                   basePath to write
207015e3adeSMatt Spinler          * @param[in] value - the value to write
2088f0d953fSMatt Spinler          * @param[in] type - Path type
209015e3adeSMatt Spinler          */
21057868bc5SMatt Spinler         void write(const std::string& name, int value, Type type);
211015e3adeSMatt Spinler 
212015e3adeSMatt Spinler         /**
213015e3adeSMatt Spinler          * Returns the sysfs base path of this device
214015e3adeSMatt Spinler          */
215015e3adeSMatt Spinler         inline const auto& path() const
216015e3adeSMatt Spinler         {
217015e3adeSMatt Spinler             return basePath;
218015e3adeSMatt Spinler         }
219015e3adeSMatt Spinler 
220015e3adeSMatt Spinler         /**
221015e3adeSMatt Spinler          * Replaces the 'P' in the string passed in with
222015e3adeSMatt Spinler          * the page number passed in.
223015e3adeSMatt Spinler          *
224015e3adeSMatt Spinler          * For example:
225015e3adeSMatt Spinler          *   insertPageNum("inP_enable", 42)
226015e3adeSMatt Spinler          *   returns "in42_enable"
227015e3adeSMatt Spinler          *
228015e3adeSMatt Spinler          * @param[in] templateName - the name string, with a 'P' in it
229015e3adeSMatt Spinler          * @param[in] page - the page number to insert where the P was
230015e3adeSMatt Spinler          *
231015e3adeSMatt Spinler          * @return string - the new string with the page number in it
232015e3adeSMatt Spinler          */
233015e3adeSMatt Spinler         static std::string insertPageNum(const std::string& templateName,
234015e3adeSMatt Spinler                                          size_t page);
235015e3adeSMatt Spinler 
23657868bc5SMatt Spinler         /**
23757868bc5SMatt Spinler          * Finds the path relative to basePath to the hwmon directory
23857868bc5SMatt Spinler          * for the device and stores it in hwmonRelPath.
23957868bc5SMatt Spinler          */
240ff5f339cSBrandon Wyman         void findHwmonDir();
241ff5f339cSBrandon Wyman 
242ff5f339cSBrandon Wyman         /**
243ff5f339cSBrandon Wyman          * Returns the path to use for the passed in type.
244ff5f339cSBrandon Wyman          *
2458f0d953fSMatt Spinler          * @param[in] type - Path type
246ff5f339cSBrandon Wyman          *
2478f0d953fSMatt Spinler          * @return fs::path - the full path
248ff5f339cSBrandon Wyman          */
249ff5f339cSBrandon Wyman         fs::path getPath(Type type);
25057868bc5SMatt Spinler 
251015e3adeSMatt Spinler     private:
252015e3adeSMatt Spinler 
253015e3adeSMatt Spinler         /**
254ba05348fSMatt Spinler          * Returns the device name
255ba05348fSMatt Spinler          *
256ba05348fSMatt Spinler          * This is found in the 'name' file in basePath.
257ba05348fSMatt Spinler          *
258ba05348fSMatt Spinler          * @return string - the device name
259ba05348fSMatt Spinler          */
260ba05348fSMatt Spinler         std::string getDeviceName();
261ba05348fSMatt Spinler 
262ba05348fSMatt Spinler         /**
263015e3adeSMatt Spinler          * The sysfs device path
264015e3adeSMatt Spinler          */
265ff5f339cSBrandon Wyman         fs::path basePath;
266015e3adeSMatt Spinler 
26757868bc5SMatt Spinler         /**
268ff5f339cSBrandon Wyman          * The directory name under the basePath hwmon directory
26957868bc5SMatt Spinler          */
270ff5f339cSBrandon Wyman         fs::path hwmonDir;
271ff5f339cSBrandon Wyman 
272ff5f339cSBrandon Wyman         /**
2738f0d953fSMatt Spinler          * The device driver name.  Used for finding the device
2748f0d953fSMatt Spinler          * debug directory.  Not required if that directory
2758f0d953fSMatt Spinler          * isn't used.
2768f0d953fSMatt Spinler          */
2778f0d953fSMatt Spinler         std::string driverName;
2788f0d953fSMatt Spinler 
2798f0d953fSMatt Spinler         /**
2808f0d953fSMatt Spinler          * The device instance number.
2818f0d953fSMatt Spinler          *
2828f0d953fSMatt Spinler          * Used in conjuction with the driver name for finding
2838f0d953fSMatt Spinler          * the debug directory.  Not required if that directory
2848f0d953fSMatt Spinler          * isn't used.
2858f0d953fSMatt Spinler          */
2868f0d953fSMatt Spinler         size_t instance = 0;
2878f0d953fSMatt Spinler 
2888f0d953fSMatt Spinler         /**
289ff5f339cSBrandon Wyman          * The pmbus debug path with status files
290ff5f339cSBrandon Wyman          */
2918f0d953fSMatt Spinler         const fs::path debugPath = "/sys/kernel/debug/";
29257868bc5SMatt Spinler 
293015e3adeSMatt Spinler };
294015e3adeSMatt Spinler 
295015e3adeSMatt Spinler }
296015e3adeSMatt Spinler }
297