xref: /openbmc/phosphor-power/pmbus.hpp (revision ab05c0792d07a95bd3bdd177b90b72a768af08ee)
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 
26764c797eSBrandon Wyman // Current output status bits.
27764c797eSBrandon Wyman constexpr auto STATUS_IOUT = "status0_iout";
28764c797eSBrandon Wyman 
29764c797eSBrandon Wyman // Manufacturing specific status bits
30764c797eSBrandon Wyman constexpr auto STATUS_MFR = "status0_mfr";
31764c797eSBrandon Wyman 
32e7e432b4SMatt Spinler namespace status_word
33e7e432b4SMatt Spinler {
34e7e432b4SMatt Spinler constexpr auto VOUT_FAULT = 0x8000;
35764c797eSBrandon Wyman 
36764c797eSBrandon Wyman // The IBM CFF power supply driver does map this bit to power1_alarm in the
37764c797eSBrandon Wyman // hwmon space, but since the other bits that need to be checked do not have
38764c797eSBrandon Wyman // a similar mapping, the code will just read STATUS_WORD and use bit masking
39764c797eSBrandon Wyman // to see if the INPUT FAULT OR WARNING bit is on.
40764c797eSBrandon Wyman constexpr auto INPUT_FAULT_WARN = 0x2000;
41764c797eSBrandon Wyman 
42764c797eSBrandon Wyman // The bit mask representing the POWER_GOOD Negated bit of the STATUS_WORD.
43764c797eSBrandon Wyman constexpr auto POWER_GOOD_NEGATED = 0x0800;
44764c797eSBrandon Wyman 
45764c797eSBrandon Wyman // The bit mask representing the UNITI_IS_OFF bit of the STATUS_WORD.
46764c797eSBrandon Wyman constexpr auto UNIT_IS_OFF = 0x0040;
47764c797eSBrandon Wyman 
48*ab05c079SBrandon Wyman // Bit 5 of the STATUS_BYTE, or lower byte of STATUS_WORD is used to indicate
49*ab05c079SBrandon Wyman // an output overvoltage fault.
50*ab05c079SBrandon Wyman constexpr auto VOUT_OV_FAULT = 0x0020;
51*ab05c079SBrandon Wyman 
52b165c251SBrandon Wyman // The bit mask representing that an output overcurrent fault has occurred.
53b165c251SBrandon Wyman constexpr auto IOUT_OC_FAULT = 0x0010;
54b165c251SBrandon Wyman 
55764c797eSBrandon Wyman // The IBM CFF power supply driver does map this bit to in1_alarm, however,
56764c797eSBrandon Wyman // since a number of the other bits are not mapped that way for STATUS_WORD,
57764c797eSBrandon Wyman // this code will just read the entire STATUS_WORD and use bit masking to find
58764c797eSBrandon Wyman // out if that fault is on.
59764c797eSBrandon Wyman constexpr auto VIN_UV_FAULT = 0x0008;
60764c797eSBrandon Wyman 
61e7e432b4SMatt Spinler }
62e7e432b4SMatt Spinler 
63015e3adeSMatt Spinler /**
6457868bc5SMatt Spinler  * If the access should be done in the base
658f0d953fSMatt Spinler  * device directory, the hwmon directory, the
668f0d953fSMatt Spinler  * pmbus debug directory, or the device debug
678f0d953fSMatt Spinler  * directory.
6857868bc5SMatt Spinler  */
6957868bc5SMatt Spinler enum class Type
7057868bc5SMatt Spinler {
7157868bc5SMatt Spinler     Base,
72ff5f339cSBrandon Wyman     Hwmon,
738f0d953fSMatt Spinler     Debug,
748f0d953fSMatt Spinler     DeviceDebug
7557868bc5SMatt Spinler };
7657868bc5SMatt Spinler 
7757868bc5SMatt Spinler /**
78015e3adeSMatt Spinler  * @class PMBus
79015e3adeSMatt Spinler  *
80015e3adeSMatt Spinler  * This class is an interface to communicating with PMBus devices
81015e3adeSMatt Spinler  * by reading and writing sysfs files.
8257868bc5SMatt Spinler  *
8357868bc5SMatt Spinler  * Based on the Type parameter, the accesses can either be done
8457868bc5SMatt Spinler  * in the base device directory (the one passed into the constructor),
8557868bc5SMatt Spinler  * or in the hwmon directory for the device.
86015e3adeSMatt Spinler  */
87015e3adeSMatt Spinler class PMBus
88015e3adeSMatt Spinler {
89015e3adeSMatt Spinler     public:
90015e3adeSMatt Spinler 
91015e3adeSMatt Spinler         PMBus() = delete;
92015e3adeSMatt Spinler         ~PMBus() = default;
93015e3adeSMatt Spinler         PMBus(const PMBus&) = default;
94015e3adeSMatt Spinler         PMBus& operator=(const PMBus&) = default;
95015e3adeSMatt Spinler         PMBus(PMBus&&) = default;
96015e3adeSMatt Spinler         PMBus& operator=(PMBus&&) = default;
97015e3adeSMatt Spinler 
98015e3adeSMatt Spinler         /**
99015e3adeSMatt Spinler          * Constructor
100015e3adeSMatt Spinler          *
101015e3adeSMatt Spinler          * @param[in] path - path to the sysfs directory
102015e3adeSMatt Spinler          */
103015e3adeSMatt Spinler         PMBus(const std::string& path) :
104015e3adeSMatt Spinler             basePath(path)
105015e3adeSMatt Spinler         {
106ff5f339cSBrandon Wyman             findHwmonDir();
107015e3adeSMatt Spinler         }
108015e3adeSMatt Spinler 
109015e3adeSMatt Spinler         /**
1108f0d953fSMatt Spinler          * Constructor
1118f0d953fSMatt Spinler          *
1128f0d953fSMatt Spinler          * This version is required when DeviceDebug
1138f0d953fSMatt Spinler          * access will be used.
1148f0d953fSMatt Spinler          *
1158f0d953fSMatt Spinler          * @param[in] path - path to the sysfs directory
1168f0d953fSMatt Spinler          * @param[in] driverName - the device driver name
1178f0d953fSMatt Spinler          * @param[in] instance - chip instance number
1188f0d953fSMatt Spinler          */
1198f0d953fSMatt Spinler         PMBus(const std::string& path,
1208f0d953fSMatt Spinler               const std::string& driverName,
1218f0d953fSMatt Spinler               size_t instance) :
1228f0d953fSMatt Spinler             basePath(path),
1238f0d953fSMatt Spinler             driverName(driverName),
1248f0d953fSMatt Spinler             instance(instance)
1258f0d953fSMatt Spinler         {
1268f0d953fSMatt Spinler             findHwmonDir();
1278f0d953fSMatt Spinler         }
1288f0d953fSMatt Spinler 
1298f0d953fSMatt Spinler         /**
130015e3adeSMatt Spinler          * Reads a file in sysfs that represents a single bit,
131015e3adeSMatt Spinler          * therefore doing a PMBus read.
132015e3adeSMatt Spinler          *
133015e3adeSMatt Spinler          * @param[in] name - path concatenated to
134015e3adeSMatt Spinler          *                   basePath to read
1358f0d953fSMatt Spinler          * @param[in] type - Path type
136015e3adeSMatt Spinler          *
137015e3adeSMatt Spinler          * @return bool - false if result was 0, else true
138015e3adeSMatt Spinler          */
13957868bc5SMatt Spinler         bool readBit(const std::string& name, Type type);
140015e3adeSMatt Spinler 
141015e3adeSMatt Spinler         /**
142015e3adeSMatt Spinler          * Reads a file in sysfs that represents a single bit,
143015e3adeSMatt Spinler          * where the page number passed in is substituted
144015e3adeSMatt Spinler          * into the name in place of the 'P' character in it.
145015e3adeSMatt Spinler          *
146015e3adeSMatt Spinler          * @param[in] name - path concatenated to
147015e3adeSMatt Spinler          *                   basePath to read
148015e3adeSMatt Spinler          * @param[in] page - page number
1498f0d953fSMatt Spinler          * @param[in] type - Path type
150015e3adeSMatt Spinler          *
151015e3adeSMatt Spinler          * @return bool - false if result was 0, else true
152015e3adeSMatt Spinler          */
153015e3adeSMatt Spinler         bool readBitInPage(const std::string& name,
15457868bc5SMatt Spinler                            size_t page,
15557868bc5SMatt Spinler                            Type type);
156f855e82aSBrandon Wyman         /**
157f855e82aSBrandon Wyman          * Read byte(s) from file in sysfs.
158f855e82aSBrandon Wyman          *
159f855e82aSBrandon Wyman          * @param[in] name   - path concatenated to basePath to read
1608f0d953fSMatt Spinler          * @param[in] type   - Path type
161f855e82aSBrandon Wyman          *
162f855e82aSBrandon Wyman          * @return uint64_t - Up to 8 bytes of data read from file.
163f855e82aSBrandon Wyman          */
164f855e82aSBrandon Wyman         uint64_t read(const std::string& name, Type type);
165015e3adeSMatt Spinler 
166015e3adeSMatt Spinler         /**
167015e3adeSMatt Spinler          * Writes an integer value to the file, therefore doing
168015e3adeSMatt Spinler          * a PMBus write.
169015e3adeSMatt Spinler          *
170015e3adeSMatt Spinler          * @param[in] name - path concatenated to
171015e3adeSMatt Spinler          *                   basePath to write
172015e3adeSMatt Spinler          * @param[in] value - the value to write
1738f0d953fSMatt Spinler          * @param[in] type - Path type
174015e3adeSMatt Spinler          */
17557868bc5SMatt Spinler         void write(const std::string& name, int value, Type type);
176015e3adeSMatt Spinler 
177015e3adeSMatt Spinler         /**
178015e3adeSMatt Spinler          * Returns the sysfs base path of this device
179015e3adeSMatt Spinler          */
180015e3adeSMatt Spinler         inline const auto& path() const
181015e3adeSMatt Spinler         {
182015e3adeSMatt Spinler             return basePath;
183015e3adeSMatt Spinler         }
184015e3adeSMatt Spinler 
185015e3adeSMatt Spinler         /**
186015e3adeSMatt Spinler          * Replaces the 'P' in the string passed in with
187015e3adeSMatt Spinler          * the page number passed in.
188015e3adeSMatt Spinler          *
189015e3adeSMatt Spinler          * For example:
190015e3adeSMatt Spinler          *   insertPageNum("inP_enable", 42)
191015e3adeSMatt Spinler          *   returns "in42_enable"
192015e3adeSMatt Spinler          *
193015e3adeSMatt Spinler          * @param[in] templateName - the name string, with a 'P' in it
194015e3adeSMatt Spinler          * @param[in] page - the page number to insert where the P was
195015e3adeSMatt Spinler          *
196015e3adeSMatt Spinler          * @return string - the new string with the page number in it
197015e3adeSMatt Spinler          */
198015e3adeSMatt Spinler         static std::string insertPageNum(const std::string& templateName,
199015e3adeSMatt Spinler                                          size_t page);
200015e3adeSMatt Spinler 
20157868bc5SMatt Spinler         /**
20257868bc5SMatt Spinler          * Finds the path relative to basePath to the hwmon directory
20357868bc5SMatt Spinler          * for the device and stores it in hwmonRelPath.
20457868bc5SMatt Spinler          */
205ff5f339cSBrandon Wyman         void findHwmonDir();
206ff5f339cSBrandon Wyman 
207ff5f339cSBrandon Wyman         /**
208ff5f339cSBrandon Wyman          * Returns the path to use for the passed in type.
209ff5f339cSBrandon Wyman          *
2108f0d953fSMatt Spinler          * @param[in] type - Path type
211ff5f339cSBrandon Wyman          *
2128f0d953fSMatt Spinler          * @return fs::path - the full path
213ff5f339cSBrandon Wyman          */
214ff5f339cSBrandon Wyman         fs::path getPath(Type type);
21557868bc5SMatt Spinler 
216015e3adeSMatt Spinler     private:
217015e3adeSMatt Spinler 
218015e3adeSMatt Spinler         /**
219015e3adeSMatt Spinler          * The sysfs device path
220015e3adeSMatt Spinler          */
221ff5f339cSBrandon Wyman         fs::path basePath;
222015e3adeSMatt Spinler 
22357868bc5SMatt Spinler         /**
224ff5f339cSBrandon Wyman          * The directory name under the basePath hwmon directory
22557868bc5SMatt Spinler          */
226ff5f339cSBrandon Wyman         fs::path hwmonDir;
227ff5f339cSBrandon Wyman 
228ff5f339cSBrandon Wyman         /**
2298f0d953fSMatt Spinler          * The device driver name.  Used for finding the device
2308f0d953fSMatt Spinler          * debug directory.  Not required if that directory
2318f0d953fSMatt Spinler          * isn't used.
2328f0d953fSMatt Spinler          */
2338f0d953fSMatt Spinler         std::string driverName;
2348f0d953fSMatt Spinler 
2358f0d953fSMatt Spinler         /**
2368f0d953fSMatt Spinler          * The device instance number.
2378f0d953fSMatt Spinler          *
2388f0d953fSMatt Spinler          * Used in conjuction with the driver name for finding
2398f0d953fSMatt Spinler          * the debug directory.  Not required if that directory
2408f0d953fSMatt Spinler          * isn't used.
2418f0d953fSMatt Spinler          */
2428f0d953fSMatt Spinler         size_t instance = 0;
2438f0d953fSMatt Spinler 
2448f0d953fSMatt Spinler         /**
245ff5f339cSBrandon Wyman          * The pmbus debug path with status files
246ff5f339cSBrandon Wyman          */
2478f0d953fSMatt Spinler         const fs::path debugPath = "/sys/kernel/debug/";
24857868bc5SMatt Spinler 
249015e3adeSMatt Spinler };
250015e3adeSMatt Spinler 
251015e3adeSMatt Spinler }
252015e3adeSMatt Spinler }
253