blob: b39cb89564fbe7eb1af8e142c633f504030db925 [file] [log] [blame]
Brandon Wymana0f33ce2019-10-17 18:32:29 -05001#pragma once
2
Brandon Wyman8d195772020-01-27 15:03:51 -06003#include "pmbus.hpp"
Brandon Wymanaed1f752019-11-25 18:10:52 -06004#include "types.hpp"
Brandon Wyman3f1242f2020-01-28 13:11:25 -06005#include "utility.hpp"
Brandon Wymanaed1f752019-11-25 18:10:52 -06006
7#include <sdbusplus/bus/match.hpp>
8
Brandon Wyman1d7a7df2020-03-26 10:14:05 -05009#include <stdexcept>
10
Brandon Wymana0f33ce2019-10-17 18:32:29 -050011namespace phosphor::power::psu
12{
Brandon Wyman3f1242f2020-01-28 13:11:25 -060013
Brandon Wyman1d7a7df2020-03-26 10:14:05 -050014#ifdef IBM_VPD
15// PMBus device driver "file name" to read for CCIN value.
16constexpr auto CCIN = "ccin";
17constexpr auto PART_NUMBER = "part_number";
18constexpr auto FRU_NUMBER = "fru";
19constexpr auto SERIAL_HEADER = "header";
20constexpr auto SERIAL_NUMBER = "serial_number";
21constexpr auto FW_VERSION = "fw_version";
22
23// The D-Bus property name to update with the CCIN value.
24constexpr auto MODEL_PROP = "Model";
25constexpr auto PN_PROP = "PartNumber";
26constexpr auto SN_PROP = "SerialNumber";
27constexpr auto VERSION_PROP = "Version";
28
29// ipzVPD Keyword sizes
30static constexpr auto FL_KW_SIZE = 20;
31#endif
32
Brandon Wymanf65c4062020-08-19 13:15:53 -050033constexpr auto LOG_LIMIT = 3;
34
Brandon Wymana0f33ce2019-10-17 18:32:29 -050035/**
36 * @class PowerSupply
37 * Represents a PMBus power supply device.
38 */
39class PowerSupply
40{
41 public:
Brandon Wymanaed1f752019-11-25 18:10:52 -060042 PowerSupply() = delete;
Brandon Wymana0f33ce2019-10-17 18:32:29 -050043 PowerSupply(const PowerSupply&) = delete;
44 PowerSupply(PowerSupply&&) = delete;
45 PowerSupply& operator=(const PowerSupply&) = delete;
46 PowerSupply& operator=(PowerSupply&&) = delete;
47 ~PowerSupply() = default;
48
49 /**
Brandon Wymanc63941c2020-01-27 16:49:33 -060050 * @param[in] invpath - String for inventory path to use
51 * @param[in] i2cbus - The bus number this power supply is on
52 * @param[in] i2caddr - The 16-bit I2C address of the power supply
Brandon Wymanaed1f752019-11-25 18:10:52 -060053 */
Brandon Wymanc63941c2020-01-27 16:49:33 -060054 PowerSupply(sdbusplus::bus::bus& bus, const std::string& invpath,
Brandon Wyman510acaa2020-11-05 18:32:04 -060055 std::uint8_t i2cbus, const std::uint16_t i2caddr);
Brandon Wymanaed1f752019-11-25 18:10:52 -060056
Brandon Wyman3f1242f2020-01-28 13:11:25 -060057 phosphor::pmbus::PMBusBase& getPMBus()
58 {
59 return *pmbusIntf;
60 }
61
Brandon Wymanaed1f752019-11-25 18:10:52 -060062 /**
Brandon Wymana0f33ce2019-10-17 18:32:29 -050063 * Power supply specific function to analyze for faults/errors.
64 *
65 * Various PMBus status bits will be checked for fault conditions.
66 * If a certain fault bits are on, the appropriate error will be
67 * committed.
68 */
Brandon Wyman3f1242f2020-01-28 13:11:25 -060069 void analyze();
Brandon Wymana0f33ce2019-10-17 18:32:29 -050070
71 /**
Brandon Wyman59a35792020-06-04 12:37:40 -050072 * Write PMBus ON_OFF_CONFIG
73 *
74 * This function will be called to cause the PMBus device driver to send the
75 * ON_OFF_CONFIG command. Takes one byte of data.
76 *
77 * @param[in] data - The ON_OFF_CONFIG data byte mask.
78 */
79 void onOffConfig(uint8_t data);
80
81 /**
Brandon Wymana0f33ce2019-10-17 18:32:29 -050082 * Write PMBus CLEAR_FAULTS
83 *
84 * This function will be called in various situations in order to clear
85 * any fault status bits that may have been set, in order to start over
86 * with a clean state. Presence changes and power state changes will
87 * want to clear any faults logged.
88 */
Brandon Wyman3c208462020-05-13 16:25:58 -050089 void clearFaults();
Brandon Wymana0f33ce2019-10-17 18:32:29 -050090
91 /**
92 * @brief Adds properties to the inventory.
93 *
94 * Reads the values from the device and writes them to the
95 * associated power supply D-Bus inventory object.
96 *
97 * This needs to be done on startup, and each time the presence
98 * state changes.
99 *
100 * Properties added:
101 * - Serial Number
102 * - Part Number
103 * - CCIN (Customer Card Identification Number) - added as the Model
104 * - Firmware version
105 */
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500106 void updateInventory();
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500107
Brandon Wymanaed1f752019-11-25 18:10:52 -0600108 /**
109 * @brief Accessor function to indicate present status
110 */
111 bool isPresent() const
112 {
113 return present;
114 }
115
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600116 /**
Brandon Wymanfed0ba22020-09-26 20:02:51 -0500117 * @brief Returns the last read value from STATUS_WORD.
118 */
119 uint64_t getStatusWord() const
120 {
121 return statusWord;
122 }
123
124 /**
Jay Meyer10d94052020-11-30 14:41:21 -0600125 * @brief Returns the last read value from STATUS_MFR.
126 */
127 uint64_t getMFRFault() const
128 {
129 return statusMFR;
130 }
131
132 /**
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600133 * @brief Returns true if a fault was found.
134 */
135 bool isFaulted() const
136 {
Brandon Wyman4176d6b2020-10-07 17:41:06 -0500137 return (faultFound || hasCommFault());
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600138 }
139
140 /**
Brandon Wymanb76ab242020-09-16 18:06:06 -0500141 * @brief Return whether a fault has been logged for this power supply
142 */
143 bool isFaultLogged() const
144 {
145 return faultLogged;
146 }
147
148 /**
149 * @brief Called when a fault for this power supply has been logged.
150 */
151 void setFaultLogged()
152 {
153 faultLogged = true;
154 }
155
156 /**
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600157 * @brief Returns true if INPUT fault occurred.
158 */
159 bool hasInputFault() const
160 {
161 return inputFault;
162 }
163
164 /**
165 * @brief Returns true if MFRSPECIFIC occurred.
166 */
167 bool hasMFRFault() const
168 {
169 return mfrFault;
170 }
171
172 /**
173 * @brief Returns true if VIN_UV_FAULT occurred.
174 */
175 bool hasVINUVFault() const
176 {
177 return vinUVFault;
178 }
179
Brandon Wymanc9efe412020-10-09 15:42:50 -0500180 /**
181 * @brief Returns the device path
182 *
183 * This can be used for error call outs.
184 * Example: /sys/bus/i2c/devices/3-0068
185 */
Brandon Wyman4176d6b2020-10-07 17:41:06 -0500186 const std::string getDevicePath() const
187 {
188 return pmbusIntf->path();
189 }
190
Brandon Wymanc9efe412020-10-09 15:42:50 -0500191 /**
192 * @brief Returns this power supplies inventory path.
193 *
194 * This can be used for error call outs.
195 * Example:
196 * /xyz/openbmc_project/inventory/system/chassis/motherboard/powersupply1
197 */
Brandon Wyman7e495272020-09-26 19:57:46 -0500198 const std::string& getInventoryPath() const
199 {
200 return inventoryPath;
201 }
202
Brandon Wymanc9efe412020-10-09 15:42:50 -0500203 /**
204 * @brief Returns the firmware revision version read from the power supply
205 */
206 const std::string& getFWVersion() const
207 {
208 return fwVersion;
209 }
210
Adriana Kobylak572a9052021-03-30 15:58:07 +0000211 /**
212 * @brief Returns the model name of the power supply
213 */
214 const std::string& getModelName() const
215 {
216 return modelName;
217 }
218
Brandon Wymanf65c4062020-08-19 13:15:53 -0500219 /** @brief Returns true if the number of failed reads exceeds limit
220 * TODO: or CML bit on.
221 */
222 bool hasCommFault() const
223 {
224 return readFail >= LOG_LIMIT;
225 }
226
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500227 private:
Brandon Wymanaed1f752019-11-25 18:10:52 -0600228 /** @brief systemd bus member */
229 sdbusplus::bus::bus& bus;
230
Brandon Wyman9564e942020-11-10 14:01:42 -0600231 /** @brief Will be updated to the latest/lastvalue read from STATUS_WORD.*/
Brandon Wymanfed0ba22020-09-26 20:02:51 -0500232 uint64_t statusWord = 0;
233
Jay Meyer10d94052020-11-30 14:41:21 -0600234 /** @brief Will be updated to the latest/lastvalue read from STATUS_MFR.*/
235 uint64_t statusMFR = 0;
236
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500237 /** @brief True if a fault has already been found and not cleared */
238 bool faultFound = false;
Brandon Wymanaed1f752019-11-25 18:10:52 -0600239
Brandon Wymanb76ab242020-09-16 18:06:06 -0500240 /** @brief True if an error for a fault has already been logged. */
241 bool faultLogged = false;
242
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600243 /** @brief True if bit 5 of STATUS_WORD high byte is on. */
244 bool inputFault = false;
245
246 /** @brief True if bit 4 of STATUS_WORD high byte is on. */
247 bool mfrFault = false;
248
249 /** @brief True if bit 3 of STATUS_WORD low byte is on. */
250 bool vinUVFault = false;
251
Brandon Wymanf65c4062020-08-19 13:15:53 -0500252 /** @brief Count of the number of read failures. */
253 size_t readFail = 0;
254
Brandon Wymanaed1f752019-11-25 18:10:52 -0600255 /**
256 * @brief D-Bus path to use for this power supply's inventory status.
257 **/
258 std::string inventoryPath;
259
260 /** @brief True if the power supply is present. */
261 bool present = false;
262
Adriana Kobylak572a9052021-03-30 15:58:07 +0000263 /** @brief Power supply model name. */
264 std::string modelName;
265
Brandon Wymanaed1f752019-11-25 18:10:52 -0600266 /** @brief D-Bus match variable used to subscribe to Present property
267 * changes.
268 **/
269 std::unique_ptr<sdbusplus::bus::match_t> presentMatch;
270
271 /** @brief D-Bus match variable used to subscribe for Present property
272 * interface added.
273 */
274 std::unique_ptr<sdbusplus::bus::match_t> presentAddedMatch;
275
276 /**
Brandon Wyman8d195772020-01-27 15:03:51 -0600277 * @brief Pointer to the PMBus interface
278 *
279 * Used to read or write to/from PMBus power supply devices.
280 */
Brandon Wyman9564e942020-11-10 14:01:42 -0600281 std::unique_ptr<phosphor::pmbus::PMBusBase> pmbusIntf = nullptr;
Brandon Wyman8d195772020-01-27 15:03:51 -0600282
Brandon Wymanc9efe412020-10-09 15:42:50 -0500283 /** @brief Stored copy of the firmware version/revision string */
284 std::string fwVersion;
285
Brandon Wyman8d195772020-01-27 15:03:51 -0600286 /**
Brandon Wymanaed1f752019-11-25 18:10:52 -0600287 * @brief Updates the presence status by querying D-Bus
288 *
289 * The D-Bus inventory properties for this power supply will be read to
290 * determine if the power supply is present or not and update this
291 * object's present member variable to reflect current status.
292 **/
293 void updatePresence();
294
295 /**
296 * @brief Callback for inventory property changes
297 *
298 * Process change of Present property for power supply.
299 *
300 * @param[in] msg - Data associated with Present change signal
301 **/
302 void inventoryChanged(sdbusplus::message::message& msg);
Brandon Wyman9a507db2021-02-25 16:15:22 -0600303
304 /**
305 * @brief Callback for inventory property added.
306 *
307 * Process add of the interface with the Present property for power supply.
308 *
309 * @param[in] msg - Data associated with Present add signal
310 **/
311 void inventoryAdded(sdbusplus::message::message& msg);
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500312};
313
314} // namespace phosphor::power::psu