xref: /openbmc/phosphor-power/pmbus.hpp (revision ab05c079)
1 #pragma once
2 
3 #include <experimental/filesystem>
4 #include <string>
5 #include <vector>
6 
7 namespace witherspoon
8 {
9 namespace pmbus
10 {
11 
12 namespace fs = std::experimental::filesystem;
13 
14 // The file name Linux uses to capture the STATUS_WORD from pmbus.
15 constexpr auto STATUS_WORD = "status0";
16 
17 // The file name Linux uses to capture the STATUS_INPUT from pmbus.
18 constexpr auto STATUS_INPUT = "status0_input";
19 
20 // Voltage out status.
21 // Overvoltage fault or warning, Undervoltage fault or warning, maximum or
22 // minimum warning, ....
23 // Uses Page substitution
24 constexpr auto STATUS_VOUT = "statusP_vout";
25 
26 // Current output status bits.
27 constexpr auto STATUS_IOUT = "status0_iout";
28 
29 // Manufacturing specific status bits
30 constexpr auto STATUS_MFR = "status0_mfr";
31 
32 namespace status_word
33 {
34 constexpr auto VOUT_FAULT = 0x8000;
35 
36 // The IBM CFF power supply driver does map this bit to power1_alarm in the
37 // hwmon space, but since the other bits that need to be checked do not have
38 // a similar mapping, the code will just read STATUS_WORD and use bit masking
39 // to see if the INPUT FAULT OR WARNING bit is on.
40 constexpr auto INPUT_FAULT_WARN = 0x2000;
41 
42 // The bit mask representing the POWER_GOOD Negated bit of the STATUS_WORD.
43 constexpr auto POWER_GOOD_NEGATED = 0x0800;
44 
45 // The bit mask representing the UNITI_IS_OFF bit of the STATUS_WORD.
46 constexpr auto UNIT_IS_OFF = 0x0040;
47 
48 // Bit 5 of the STATUS_BYTE, or lower byte of STATUS_WORD is used to indicate
49 // an output overvoltage fault.
50 constexpr auto VOUT_OV_FAULT = 0x0020;
51 
52 // The bit mask representing that an output overcurrent fault has occurred.
53 constexpr auto IOUT_OC_FAULT = 0x0010;
54 
55 // The IBM CFF power supply driver does map this bit to in1_alarm, however,
56 // since a number of the other bits are not mapped that way for STATUS_WORD,
57 // this code will just read the entire STATUS_WORD and use bit masking to find
58 // out if that fault is on.
59 constexpr auto VIN_UV_FAULT = 0x0008;
60 
61 }
62 
63 /**
64  * If the access should be done in the base
65  * device directory, the hwmon directory, the
66  * pmbus debug directory, or the device debug
67  * directory.
68  */
69 enum class Type
70 {
71     Base,
72     Hwmon,
73     Debug,
74     DeviceDebug
75 };
76 
77 /**
78  * @class PMBus
79  *
80  * This class is an interface to communicating with PMBus devices
81  * by reading and writing sysfs files.
82  *
83  * Based on the Type parameter, the accesses can either be done
84  * in the base device directory (the one passed into the constructor),
85  * or in the hwmon directory for the device.
86  */
87 class PMBus
88 {
89     public:
90 
91         PMBus() = delete;
92         ~PMBus() = default;
93         PMBus(const PMBus&) = default;
94         PMBus& operator=(const PMBus&) = default;
95         PMBus(PMBus&&) = default;
96         PMBus& operator=(PMBus&&) = default;
97 
98         /**
99          * Constructor
100          *
101          * @param[in] path - path to the sysfs directory
102          */
103         PMBus(const std::string& path) :
104             basePath(path)
105         {
106             findHwmonDir();
107         }
108 
109         /**
110          * Constructor
111          *
112          * This version is required when DeviceDebug
113          * access will be used.
114          *
115          * @param[in] path - path to the sysfs directory
116          * @param[in] driverName - the device driver name
117          * @param[in] instance - chip instance number
118          */
119         PMBus(const std::string& path,
120               const std::string& driverName,
121               size_t instance) :
122             basePath(path),
123             driverName(driverName),
124             instance(instance)
125         {
126             findHwmonDir();
127         }
128 
129         /**
130          * Reads a file in sysfs that represents a single bit,
131          * therefore doing a PMBus read.
132          *
133          * @param[in] name - path concatenated to
134          *                   basePath to read
135          * @param[in] type - Path type
136          *
137          * @return bool - false if result was 0, else true
138          */
139         bool readBit(const std::string& name, Type type);
140 
141         /**
142          * Reads a file in sysfs that represents a single bit,
143          * where the page number passed in is substituted
144          * into the name in place of the 'P' character in it.
145          *
146          * @param[in] name - path concatenated to
147          *                   basePath to read
148          * @param[in] page - page number
149          * @param[in] type - Path type
150          *
151          * @return bool - false if result was 0, else true
152          */
153         bool readBitInPage(const std::string& name,
154                            size_t page,
155                            Type type);
156         /**
157          * Read byte(s) from file in sysfs.
158          *
159          * @param[in] name   - path concatenated to basePath to read
160          * @param[in] type   - Path type
161          *
162          * @return uint64_t - Up to 8 bytes of data read from file.
163          */
164         uint64_t read(const std::string& name, Type type);
165 
166         /**
167          * Writes an integer value to the file, therefore doing
168          * a PMBus write.
169          *
170          * @param[in] name - path concatenated to
171          *                   basePath to write
172          * @param[in] value - the value to write
173          * @param[in] type - Path type
174          */
175         void write(const std::string& name, int value, Type type);
176 
177         /**
178          * Returns the sysfs base path of this device
179          */
180         inline const auto& path() const
181         {
182             return basePath;
183         }
184 
185         /**
186          * Replaces the 'P' in the string passed in with
187          * the page number passed in.
188          *
189          * For example:
190          *   insertPageNum("inP_enable", 42)
191          *   returns "in42_enable"
192          *
193          * @param[in] templateName - the name string, with a 'P' in it
194          * @param[in] page - the page number to insert where the P was
195          *
196          * @return string - the new string with the page number in it
197          */
198         static std::string insertPageNum(const std::string& templateName,
199                                          size_t page);
200 
201         /**
202          * Finds the path relative to basePath to the hwmon directory
203          * for the device and stores it in hwmonRelPath.
204          */
205         void findHwmonDir();
206 
207         /**
208          * Returns the path to use for the passed in type.
209          *
210          * @param[in] type - Path type
211          *
212          * @return fs::path - the full path
213          */
214         fs::path getPath(Type type);
215 
216     private:
217 
218         /**
219          * The sysfs device path
220          */
221         fs::path basePath;
222 
223         /**
224          * The directory name under the basePath hwmon directory
225          */
226         fs::path hwmonDir;
227 
228         /**
229          * The device driver name.  Used for finding the device
230          * debug directory.  Not required if that directory
231          * isn't used.
232          */
233         std::string driverName;
234 
235         /**
236          * The device instance number.
237          *
238          * Used in conjuction with the driver name for finding
239          * the debug directory.  Not required if that directory
240          * isn't used.
241          */
242         size_t instance = 0;
243 
244         /**
245          * The pmbus debug path with status files
246          */
247         const fs::path debugPath = "/sys/kernel/debug/";
248 
249 };
250 
251 }
252 }
253