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