blob: 23121b997a44fdb90ece245e1e3c0ae90383f51e [file] [log] [blame]
Matt Spinler015e3ad2017-08-01 11:20:47 -05001#pragma once
2
3#include <experimental/filesystem>
4#include <string>
5#include <vector>
6
7namespace witherspoon
8{
9namespace pmbus
10{
11
Brandon Wymanff5f3392017-08-11 17:43:22 -050012namespace fs = std::experimental::filesystem;
13
Brandon Wyman10295542017-08-09 18:20:44 -050014// The file name Linux uses to capture the STATUS_WORD from pmbus.
Matt Spinlere7e432b2017-08-21 15:01:40 -050015constexpr auto STATUS_WORD = "status0";
Brandon Wyman10295542017-08-09 18:20:44 -050016
Brandon Wyman253dc9b2017-08-12 13:45:52 -050017// The file name Linux uses to capture the STATUS_INPUT from pmbus.
18constexpr auto STATUS_INPUT = "status0_input";
Matt Spinlere7e432b2017-08-21 15:01:40 -050019
Brandon Wyman764c7972017-08-22 17:05:36 -050020// Voltage out status.
21// Overvoltage fault or warning, Undervoltage fault or warning, maximum or
22// minimum warning, ....
Matt Spinlere7e432b2017-08-21 15:01:40 -050023// Uses Page substitution
24constexpr auto STATUS_VOUT = "statusP_vout";
25
Brandon Wyman764c7972017-08-22 17:05:36 -050026// Current output status bits.
27constexpr auto STATUS_IOUT = "status0_iout";
28
29// Manufacturing specific status bits
30constexpr auto STATUS_MFR = "status0_mfr";
31
Matt Spinlere7e432b2017-08-21 15:01:40 -050032namespace status_word
33{
34constexpr auto VOUT_FAULT = 0x8000;
Brandon Wyman764c7972017-08-22 17:05:36 -050035
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.
40constexpr auto INPUT_FAULT_WARN = 0x2000;
41
42// The bit mask representing the POWER_GOOD Negated bit of the STATUS_WORD.
43constexpr auto POWER_GOOD_NEGATED = 0x0800;
44
45// The bit mask representing the UNITI_IS_OFF bit of the STATUS_WORD.
46constexpr auto UNIT_IS_OFF = 0x0040;
47
Brandon Wymanab05c072017-08-30 18:26:41 -050048// Bit 5 of the STATUS_BYTE, or lower byte of STATUS_WORD is used to indicate
49// an output overvoltage fault.
50constexpr auto VOUT_OV_FAULT = 0x0020;
51
Brandon Wymanb165c252017-08-25 18:59:54 -050052// The bit mask representing that an output overcurrent fault has occurred.
53constexpr auto IOUT_OC_FAULT = 0x0010;
54
Brandon Wyman764c7972017-08-22 17:05:36 -050055// 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.
59constexpr auto VIN_UV_FAULT = 0x0008;
60
Matt Spinlere7e432b2017-08-21 15:01:40 -050061}
62
Matt Spinler015e3ad2017-08-01 11:20:47 -050063/**
Matt Spinler57868bc2017-08-03 10:07:41 -050064 * If the access should be done in the base
Matt Spinler8f0d9532017-08-21 11:22:37 -050065 * device directory, the hwmon directory, the
66 * pmbus debug directory, or the device debug
67 * directory.
Matt Spinler57868bc2017-08-03 10:07:41 -050068 */
69enum class Type
70{
71 Base,
Brandon Wymanff5f3392017-08-11 17:43:22 -050072 Hwmon,
Matt Spinler8f0d9532017-08-21 11:22:37 -050073 Debug,
74 DeviceDebug
Matt Spinler57868bc2017-08-03 10:07:41 -050075};
76
77/**
Matt Spinler015e3ad2017-08-01 11:20:47 -050078 * @class PMBus
79 *
80 * This class is an interface to communicating with PMBus devices
81 * by reading and writing sysfs files.
Matt Spinler57868bc2017-08-03 10:07:41 -050082 *
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.
Matt Spinler015e3ad2017-08-01 11:20:47 -050086 */
87class 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 {
Brandon Wymanff5f3392017-08-11 17:43:22 -0500106 findHwmonDir();
Matt Spinler015e3ad2017-08-01 11:20:47 -0500107 }
108
109 /**
Matt Spinler8f0d9532017-08-21 11:22:37 -0500110 * 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 /**
Matt Spinler015e3ad2017-08-01 11:20:47 -0500130 * 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
Matt Spinler8f0d9532017-08-21 11:22:37 -0500135 * @param[in] type - Path type
Matt Spinler015e3ad2017-08-01 11:20:47 -0500136 *
137 * @return bool - false if result was 0, else true
138 */
Matt Spinler57868bc2017-08-03 10:07:41 -0500139 bool readBit(const std::string& name, Type type);
Matt Spinler015e3ad2017-08-01 11:20:47 -0500140
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
Matt Spinler8f0d9532017-08-21 11:22:37 -0500149 * @param[in] type - Path type
Matt Spinler015e3ad2017-08-01 11:20:47 -0500150 *
151 * @return bool - false if result was 0, else true
152 */
153 bool readBitInPage(const std::string& name,
Matt Spinler57868bc2017-08-03 10:07:41 -0500154 size_t page,
155 Type type);
Brandon Wymanf855e822017-08-08 18:04:47 -0500156 /**
157 * Read byte(s) from file in sysfs.
158 *
159 * @param[in] name - path concatenated to basePath to read
Matt Spinler8f0d9532017-08-21 11:22:37 -0500160 * @param[in] type - Path type
Brandon Wymanf855e822017-08-08 18:04:47 -0500161 *
162 * @return uint64_t - Up to 8 bytes of data read from file.
163 */
164 uint64_t read(const std::string& name, Type type);
Matt Spinler015e3ad2017-08-01 11:20:47 -0500165
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
Matt Spinler8f0d9532017-08-21 11:22:37 -0500173 * @param[in] type - Path type
Matt Spinler015e3ad2017-08-01 11:20:47 -0500174 */
Matt Spinler57868bc2017-08-03 10:07:41 -0500175 void write(const std::string& name, int value, Type type);
Matt Spinler015e3ad2017-08-01 11:20:47 -0500176
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
Matt Spinler57868bc2017-08-03 10:07:41 -0500201 /**
202 * Finds the path relative to basePath to the hwmon directory
203 * for the device and stores it in hwmonRelPath.
204 */
Brandon Wyman764c7972017-08-22 17:05:36 -0500205 void findHwmonDir();
Brandon Wymanff5f3392017-08-11 17:43:22 -0500206
207 /**
208 * Returns the path to use for the passed in type.
209 *
Matt Spinler8f0d9532017-08-21 11:22:37 -0500210 * @param[in] type - Path type
Brandon Wymanff5f3392017-08-11 17:43:22 -0500211 *
Matt Spinler8f0d9532017-08-21 11:22:37 -0500212 * @return fs::path - the full path
Brandon Wymanff5f3392017-08-11 17:43:22 -0500213 */
Brandon Wyman764c7972017-08-22 17:05:36 -0500214 fs::path getPath(Type type);
Matt Spinler57868bc2017-08-03 10:07:41 -0500215
Matt Spinler015e3ad2017-08-01 11:20:47 -0500216 private:
217
218 /**
219 * The sysfs device path
220 */
Brandon Wymanff5f3392017-08-11 17:43:22 -0500221 fs::path basePath;
Matt Spinler015e3ad2017-08-01 11:20:47 -0500222
Matt Spinler57868bc2017-08-03 10:07:41 -0500223 /**
Brandon Wymanff5f3392017-08-11 17:43:22 -0500224 * The directory name under the basePath hwmon directory
Matt Spinler57868bc2017-08-03 10:07:41 -0500225 */
Brandon Wymanff5f3392017-08-11 17:43:22 -0500226 fs::path hwmonDir;
227
228 /**
Matt Spinler8f0d9532017-08-21 11:22:37 -0500229 * 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 /**
Brandon Wymanff5f3392017-08-11 17:43:22 -0500245 * The pmbus debug path with status files
246 */
Matt Spinler8f0d9532017-08-21 11:22:37 -0500247 const fs::path debugPath = "/sys/kernel/debug/";
Matt Spinler57868bc2017-08-03 10:07:41 -0500248
Matt Spinler015e3ad2017-08-01 11:20:47 -0500249};
250
251}
252}