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 VIN_UV_FAULT bit from the STATUS_WORD
15 constexpr auto VIN_UV_FAULT = "in1_alarm";
16 
17 // The file name Linux uses to capture the input fault or warning bit from the
18 // STATUS_WORD
19 constexpr auto INPUT_FAULT_WARN = "power1_alarm";
20 
21 // The file name Linux uses to capture the STATUS_WORD from pmbus.
22 constexpr auto STATUS_WORD = "status0";
23 
24 // The file name Linux uses to capture the STATUS_INPUT from pmbus.
25 constexpr auto STATUS_INPUT = "status0_input";
26 
27 // Uses Page substitution
28 constexpr auto STATUS_VOUT = "statusP_vout";
29 
30 namespace status_word
31 {
32 constexpr auto VOUT_FAULT = 0x8000;
33 }
34 
35 /**
36  * If the access should be done in the base
37  * device directory, the hwmon directory, the
38  * pmbus debug directory, or the device debug
39  * directory.
40  */
41 enum class Type
42 {
43     Base,
44     Hwmon,
45     Debug,
46     DeviceDebug
47 };
48 
49 /**
50  * @class PMBus
51  *
52  * This class is an interface to communicating with PMBus devices
53  * by reading and writing sysfs files.
54  *
55  * Based on the Type parameter, the accesses can either be done
56  * in the base device directory (the one passed into the constructor),
57  * or in the hwmon directory for the device.
58  */
59 class PMBus
60 {
61     public:
62 
63         PMBus() = delete;
64         ~PMBus() = default;
65         PMBus(const PMBus&) = default;
66         PMBus& operator=(const PMBus&) = default;
67         PMBus(PMBus&&) = default;
68         PMBus& operator=(PMBus&&) = default;
69 
70         /**
71          * Constructor
72          *
73          * @param[in] path - path to the sysfs directory
74          */
75         PMBus(const std::string& path) :
76             basePath(path)
77         {
78             findHwmonDir();
79         }
80 
81         /**
82          * Constructor
83          *
84          * This version is required when DeviceDebug
85          * access will be used.
86          *
87          * @param[in] path - path to the sysfs directory
88          * @param[in] driverName - the device driver name
89          * @param[in] instance - chip instance number
90          */
91         PMBus(const std::string& path,
92               const std::string& driverName,
93               size_t instance) :
94             basePath(path),
95             driverName(driverName),
96             instance(instance)
97         {
98             findHwmonDir();
99         }
100 
101         /**
102          * Reads a file in sysfs that represents a single bit,
103          * therefore doing a PMBus read.
104          *
105          * @param[in] name - path concatenated to
106          *                   basePath to read
107          * @param[in] type - Path type
108          *
109          * @return bool - false if result was 0, else true
110          */
111         bool readBit(const std::string& name, Type type);
112 
113         /**
114          * Reads a file in sysfs that represents a single bit,
115          * where the page number passed in is substituted
116          * into the name in place of the 'P' character in it.
117          *
118          * @param[in] name - path concatenated to
119          *                   basePath to read
120          * @param[in] page - page number
121          * @param[in] type - Path type
122          *
123          * @return bool - false if result was 0, else true
124          */
125         bool readBitInPage(const std::string& name,
126                            size_t page,
127                            Type type);
128         /**
129          * Read byte(s) from file in sysfs.
130          *
131          * @param[in] name   - path concatenated to basePath to read
132          * @param[in] type   - Path type
133          *
134          * @return uint64_t - Up to 8 bytes of data read from file.
135          */
136         uint64_t read(const std::string& name, Type type);
137 
138         /**
139          * Writes an integer value to the file, therefore doing
140          * a PMBus write.
141          *
142          * @param[in] name - path concatenated to
143          *                   basePath to write
144          * @param[in] value - the value to write
145          * @param[in] type - Path type
146          */
147         void write(const std::string& name, int value, Type type);
148 
149         /**
150          * Returns the sysfs base path of this device
151          */
152         inline const auto& path() const
153         {
154             return basePath;
155         }
156 
157         /**
158          * Replaces the 'P' in the string passed in with
159          * the page number passed in.
160          *
161          * For example:
162          *   insertPageNum("inP_enable", 42)
163          *   returns "in42_enable"
164          *
165          * @param[in] templateName - the name string, with a 'P' in it
166          * @param[in] page - the page number to insert where the P was
167          *
168          * @return string - the new string with the page number in it
169          */
170         static std::string insertPageNum(const std::string& templateName,
171                                          size_t page);
172 
173         /**
174          * Finds the path relative to basePath to the hwmon directory
175          * for the device and stores it in hwmonRelPath.
176          */
177          void findHwmonDir();
178 
179         /**
180          * Returns the path to use for the passed in type.
181          *
182          * @param[in] type - Path type
183          *
184          * @return fs::path - the full path
185          */
186          fs::path getPath(Type type);
187 
188     private:
189 
190         /**
191          * The sysfs device path
192          */
193         fs::path basePath;
194 
195         /**
196          * The directory name under the basePath hwmon directory
197          */
198         fs::path hwmonDir;
199 
200         /**
201          * The device driver name.  Used for finding the device
202          * debug directory.  Not required if that directory
203          * isn't used.
204          */
205         std::string driverName;
206 
207         /**
208          * The device instance number.
209          *
210          * Used in conjuction with the driver name for finding
211          * the debug directory.  Not required if that directory
212          * isn't used.
213          */
214         size_t instance = 0;
215 
216         /**
217          * The pmbus debug path with status files
218          */
219         const fs::path debugPath = "/sys/kernel/debug/";
220 
221 };
222 
223 }
224 }
225