blob: 214040dc692a6468868cbd1a12afdc395037e634 [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 Wyman253dc9b2017-08-12 13:45:52 -050014// The file name Linux uses to capture the VIN_UV_FAULT bit from the STATUS_WORD
15constexpr 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
19constexpr auto INPUT_FAULT_WARN = "power1_alarm";
20
Brandon Wyman10295542017-08-09 18:20:44 -050021// The file name Linux uses to capture the STATUS_WORD from pmbus.
Matt Spinlere7e432b2017-08-21 15:01:40 -050022constexpr auto STATUS_WORD = "status0";
Brandon Wyman10295542017-08-09 18:20:44 -050023
Brandon Wyman253dc9b2017-08-12 13:45:52 -050024// The file name Linux uses to capture the STATUS_INPUT from pmbus.
25constexpr auto STATUS_INPUT = "status0_input";
Matt Spinlere7e432b2017-08-21 15:01:40 -050026
27// Uses Page substitution
28constexpr auto STATUS_VOUT = "statusP_vout";
29
30namespace status_word
31{
32constexpr auto VOUT_FAULT = 0x8000;
33}
34
Matt Spinler015e3ad2017-08-01 11:20:47 -050035/**
Matt Spinler57868bc2017-08-03 10:07:41 -050036 * If the access should be done in the base
Matt Spinler8f0d9532017-08-21 11:22:37 -050037 * device directory, the hwmon directory, the
38 * pmbus debug directory, or the device debug
39 * directory.
Matt Spinler57868bc2017-08-03 10:07:41 -050040 */
41enum class Type
42{
43 Base,
Brandon Wymanff5f3392017-08-11 17:43:22 -050044 Hwmon,
Matt Spinler8f0d9532017-08-21 11:22:37 -050045 Debug,
46 DeviceDebug
Matt Spinler57868bc2017-08-03 10:07:41 -050047};
48
49/**
Matt Spinler015e3ad2017-08-01 11:20:47 -050050 * @class PMBus
51 *
52 * This class is an interface to communicating with PMBus devices
53 * by reading and writing sysfs files.
Matt Spinler57868bc2017-08-03 10:07:41 -050054 *
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.
Matt Spinler015e3ad2017-08-01 11:20:47 -050058 */
59class 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 {
Brandon Wymanff5f3392017-08-11 17:43:22 -050078 findHwmonDir();
Matt Spinler015e3ad2017-08-01 11:20:47 -050079 }
80
81 /**
Matt Spinler8f0d9532017-08-21 11:22:37 -050082 * 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 /**
Matt Spinler015e3ad2017-08-01 11:20:47 -0500102 * 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
Matt Spinler8f0d9532017-08-21 11:22:37 -0500107 * @param[in] type - Path type
Matt Spinler015e3ad2017-08-01 11:20:47 -0500108 *
109 * @return bool - false if result was 0, else true
110 */
Matt Spinler57868bc2017-08-03 10:07:41 -0500111 bool readBit(const std::string& name, Type type);
Matt Spinler015e3ad2017-08-01 11:20:47 -0500112
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
Matt Spinler8f0d9532017-08-21 11:22:37 -0500121 * @param[in] type - Path type
Matt Spinler015e3ad2017-08-01 11:20:47 -0500122 *
123 * @return bool - false if result was 0, else true
124 */
125 bool readBitInPage(const std::string& name,
Matt Spinler57868bc2017-08-03 10:07:41 -0500126 size_t page,
127 Type type);
Brandon Wymanf855e822017-08-08 18:04:47 -0500128 /**
129 * Read byte(s) from file in sysfs.
130 *
131 * @param[in] name - path concatenated to basePath to read
Matt Spinler8f0d9532017-08-21 11:22:37 -0500132 * @param[in] type - Path type
Brandon Wymanf855e822017-08-08 18:04:47 -0500133 *
134 * @return uint64_t - Up to 8 bytes of data read from file.
135 */
136 uint64_t read(const std::string& name, Type type);
Matt Spinler015e3ad2017-08-01 11:20:47 -0500137
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
Matt Spinler8f0d9532017-08-21 11:22:37 -0500145 * @param[in] type - Path type
Matt Spinler015e3ad2017-08-01 11:20:47 -0500146 */
Matt Spinler57868bc2017-08-03 10:07:41 -0500147 void write(const std::string& name, int value, Type type);
Matt Spinler015e3ad2017-08-01 11:20:47 -0500148
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
Matt Spinler57868bc2017-08-03 10:07:41 -0500173 /**
174 * Finds the path relative to basePath to the hwmon directory
175 * for the device and stores it in hwmonRelPath.
176 */
Brandon Wymanff5f3392017-08-11 17:43:22 -0500177 void findHwmonDir();
178
179 /**
180 * Returns the path to use for the passed in type.
181 *
Matt Spinler8f0d9532017-08-21 11:22:37 -0500182 * @param[in] type - Path type
Brandon Wymanff5f3392017-08-11 17:43:22 -0500183 *
Matt Spinler8f0d9532017-08-21 11:22:37 -0500184 * @return fs::path - the full path
Brandon Wymanff5f3392017-08-11 17:43:22 -0500185 */
186 fs::path getPath(Type type);
Matt Spinler57868bc2017-08-03 10:07:41 -0500187
Matt Spinler015e3ad2017-08-01 11:20:47 -0500188 private:
189
190 /**
191 * The sysfs device path
192 */
Brandon Wymanff5f3392017-08-11 17:43:22 -0500193 fs::path basePath;
Matt Spinler015e3ad2017-08-01 11:20:47 -0500194
Matt Spinler57868bc2017-08-03 10:07:41 -0500195 /**
Brandon Wymanff5f3392017-08-11 17:43:22 -0500196 * The directory name under the basePath hwmon directory
Matt Spinler57868bc2017-08-03 10:07:41 -0500197 */
Brandon Wymanff5f3392017-08-11 17:43:22 -0500198 fs::path hwmonDir;
199
200 /**
Matt Spinler8f0d9532017-08-21 11:22:37 -0500201 * 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 /**
Brandon Wymanff5f3392017-08-11 17:43:22 -0500217 * The pmbus debug path with status files
218 */
Matt Spinler8f0d9532017-08-21 11:22:37 -0500219 const fs::path debugPath = "/sys/kernel/debug/";
Matt Spinler57868bc2017-08-03 10:07:41 -0500220
Matt Spinler015e3ad2017-08-01 11:20:47 -0500221};
222
223}
224}