blob: 9254fe7a143b0893ce204a695c96566dcc700da4 [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 Wyman442035f2017-08-08 15:58:45 -050017// The file name Linux uses to capture the VIN_UV_FAULT bit from the STATUS_WORD
18constexpr auto VIN_UV_FAULT = "in1_alarm";
Matt Spinlere7e432b2017-08-21 15:01:40 -050019
20// Uses Page substitution
21constexpr auto STATUS_VOUT = "statusP_vout";
22
23namespace status_word
24{
25constexpr auto VOUT_FAULT = 0x8000;
26}
27
Matt Spinler015e3ad2017-08-01 11:20:47 -050028/**
Matt Spinler57868bc2017-08-03 10:07:41 -050029 * If the access should be done in the base
Matt Spinler8f0d9532017-08-21 11:22:37 -050030 * device directory, the hwmon directory, the
31 * pmbus debug directory, or the device debug
32 * directory.
Matt Spinler57868bc2017-08-03 10:07:41 -050033 */
34enum class Type
35{
36 Base,
Brandon Wymanff5f3392017-08-11 17:43:22 -050037 Hwmon,
Matt Spinler8f0d9532017-08-21 11:22:37 -050038 Debug,
39 DeviceDebug
Matt Spinler57868bc2017-08-03 10:07:41 -050040};
41
42/**
Matt Spinler015e3ad2017-08-01 11:20:47 -050043 * @class PMBus
44 *
45 * This class is an interface to communicating with PMBus devices
46 * by reading and writing sysfs files.
Matt Spinler57868bc2017-08-03 10:07:41 -050047 *
48 * Based on the Type parameter, the accesses can either be done
49 * in the base device directory (the one passed into the constructor),
50 * or in the hwmon directory for the device.
Matt Spinler015e3ad2017-08-01 11:20:47 -050051 */
52class PMBus
53{
54 public:
55
56 PMBus() = delete;
57 ~PMBus() = default;
58 PMBus(const PMBus&) = default;
59 PMBus& operator=(const PMBus&) = default;
60 PMBus(PMBus&&) = default;
61 PMBus& operator=(PMBus&&) = default;
62
63 /**
64 * Constructor
65 *
66 * @param[in] path - path to the sysfs directory
67 */
68 PMBus(const std::string& path) :
69 basePath(path)
70 {
Brandon Wymanff5f3392017-08-11 17:43:22 -050071 findHwmonDir();
Matt Spinler015e3ad2017-08-01 11:20:47 -050072 }
73
74 /**
Matt Spinler8f0d9532017-08-21 11:22:37 -050075 * Constructor
76 *
77 * This version is required when DeviceDebug
78 * access will be used.
79 *
80 * @param[in] path - path to the sysfs directory
81 * @param[in] driverName - the device driver name
82 * @param[in] instance - chip instance number
83 */
84 PMBus(const std::string& path,
85 const std::string& driverName,
86 size_t instance) :
87 basePath(path),
88 driverName(driverName),
89 instance(instance)
90 {
91 findHwmonDir();
92 }
93
94 /**
Matt Spinler015e3ad2017-08-01 11:20:47 -050095 * Reads a file in sysfs that represents a single bit,
96 * therefore doing a PMBus read.
97 *
98 * @param[in] name - path concatenated to
99 * basePath to read
Matt Spinler8f0d9532017-08-21 11:22:37 -0500100 * @param[in] type - Path type
Matt Spinler015e3ad2017-08-01 11:20:47 -0500101 *
102 * @return bool - false if result was 0, else true
103 */
Matt Spinler57868bc2017-08-03 10:07:41 -0500104 bool readBit(const std::string& name, Type type);
Matt Spinler015e3ad2017-08-01 11:20:47 -0500105
106 /**
107 * Reads a file in sysfs that represents a single bit,
108 * where the page number passed in is substituted
109 * into the name in place of the 'P' character in it.
110 *
111 * @param[in] name - path concatenated to
112 * basePath to read
113 * @param[in] page - page number
Matt Spinler8f0d9532017-08-21 11:22:37 -0500114 * @param[in] type - Path type
Matt Spinler015e3ad2017-08-01 11:20:47 -0500115 *
116 * @return bool - false if result was 0, else true
117 */
118 bool readBitInPage(const std::string& name,
Matt Spinler57868bc2017-08-03 10:07:41 -0500119 size_t page,
120 Type type);
Brandon Wymanf855e822017-08-08 18:04:47 -0500121 /**
122 * Read byte(s) from file in sysfs.
123 *
124 * @param[in] name - path concatenated to basePath to read
Matt Spinler8f0d9532017-08-21 11:22:37 -0500125 * @param[in] type - Path type
Brandon Wymanf855e822017-08-08 18:04:47 -0500126 *
127 * @return uint64_t - Up to 8 bytes of data read from file.
128 */
129 uint64_t read(const std::string& name, Type type);
Matt Spinler015e3ad2017-08-01 11:20:47 -0500130
131 /**
132 * Writes an integer value to the file, therefore doing
133 * a PMBus write.
134 *
135 * @param[in] name - path concatenated to
136 * basePath to write
137 * @param[in] value - the value to write
Matt Spinler8f0d9532017-08-21 11:22:37 -0500138 * @param[in] type - Path type
Matt Spinler015e3ad2017-08-01 11:20:47 -0500139 */
Matt Spinler57868bc2017-08-03 10:07:41 -0500140 void write(const std::string& name, int value, Type type);
Matt Spinler015e3ad2017-08-01 11:20:47 -0500141
142 /**
143 * Returns the sysfs base path of this device
144 */
145 inline const auto& path() const
146 {
147 return basePath;
148 }
149
150 /**
151 * Replaces the 'P' in the string passed in with
152 * the page number passed in.
153 *
154 * For example:
155 * insertPageNum("inP_enable", 42)
156 * returns "in42_enable"
157 *
158 * @param[in] templateName - the name string, with a 'P' in it
159 * @param[in] page - the page number to insert where the P was
160 *
161 * @return string - the new string with the page number in it
162 */
163 static std::string insertPageNum(const std::string& templateName,
164 size_t page);
165
Matt Spinler57868bc2017-08-03 10:07:41 -0500166 /**
167 * Finds the path relative to basePath to the hwmon directory
168 * for the device and stores it in hwmonRelPath.
169 */
Brandon Wymanff5f3392017-08-11 17:43:22 -0500170 void findHwmonDir();
171
172 /**
173 * Returns the path to use for the passed in type.
174 *
Matt Spinler8f0d9532017-08-21 11:22:37 -0500175 * @param[in] type - Path type
Brandon Wymanff5f3392017-08-11 17:43:22 -0500176 *
Matt Spinler8f0d9532017-08-21 11:22:37 -0500177 * @return fs::path - the full path
Brandon Wymanff5f3392017-08-11 17:43:22 -0500178 */
179 fs::path getPath(Type type);
Matt Spinler57868bc2017-08-03 10:07:41 -0500180
Matt Spinler015e3ad2017-08-01 11:20:47 -0500181 private:
182
183 /**
184 * The sysfs device path
185 */
Brandon Wymanff5f3392017-08-11 17:43:22 -0500186 fs::path basePath;
Matt Spinler015e3ad2017-08-01 11:20:47 -0500187
Matt Spinler57868bc2017-08-03 10:07:41 -0500188 /**
Brandon Wymanff5f3392017-08-11 17:43:22 -0500189 * The directory name under the basePath hwmon directory
Matt Spinler57868bc2017-08-03 10:07:41 -0500190 */
Brandon Wymanff5f3392017-08-11 17:43:22 -0500191 fs::path hwmonDir;
192
193 /**
Matt Spinler8f0d9532017-08-21 11:22:37 -0500194 * The device driver name. Used for finding the device
195 * debug directory. Not required if that directory
196 * isn't used.
197 */
198 std::string driverName;
199
200 /**
201 * The device instance number.
202 *
203 * Used in conjuction with the driver name for finding
204 * the debug directory. Not required if that directory
205 * isn't used.
206 */
207 size_t instance = 0;
208
209 /**
Brandon Wymanff5f3392017-08-11 17:43:22 -0500210 * The pmbus debug path with status files
211 */
Matt Spinler8f0d9532017-08-21 11:22:37 -0500212 const fs::path debugPath = "/sys/kernel/debug/";
Matt Spinler57868bc2017-08-03 10:07:41 -0500213
Matt Spinler015e3ad2017-08-01 11:20:47 -0500214};
215
216}
217}