blob: 6291debeed1ce65e8cbaa9b5ad419802054d715f [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"
B. J. Wyman681b2a32021-04-20 22:31:22 +00005#include "util.hpp"
Brandon Wyman3f1242f2020-01-28 13:11:25 -06006#include "utility.hpp"
Brandon Wymanaed1f752019-11-25 18:10:52 -06007
B. J. Wyman681b2a32021-04-20 22:31:22 +00008#include <gpiod.hpp>
Brandon Wymanaed1f752019-11-25 18:10:52 -06009#include <sdbusplus/bus/match.hpp>
10
B. J. Wyman681b2a32021-04-20 22:31:22 +000011#include <filesystem>
Brandon Wyman1d7a7df2020-03-26 10:14:05 -050012#include <stdexcept>
13
Brandon Wymana0f33ce2019-10-17 18:32:29 -050014namespace phosphor::power::psu
15{
Brandon Wyman3f1242f2020-01-28 13:11:25 -060016
Chanh Nguyenc12c53b2021-04-06 17:24:47 +070017#if IBM_VPD
Brandon Wyman1d7a7df2020-03-26 10:14:05 -050018// PMBus device driver "file name" to read for CCIN value.
19constexpr auto CCIN = "ccin";
20constexpr auto PART_NUMBER = "part_number";
21constexpr auto FRU_NUMBER = "fru";
22constexpr auto SERIAL_HEADER = "header";
23constexpr auto SERIAL_NUMBER = "serial_number";
24constexpr auto FW_VERSION = "fw_version";
25
26// The D-Bus property name to update with the CCIN value.
27constexpr auto MODEL_PROP = "Model";
28constexpr auto PN_PROP = "PartNumber";
29constexpr auto SN_PROP = "SerialNumber";
30constexpr auto VERSION_PROP = "Version";
31
32// ipzVPD Keyword sizes
33static constexpr auto FL_KW_SIZE = 20;
34#endif
35
Brandon Wymanf65c4062020-08-19 13:15:53 -050036constexpr auto LOG_LIMIT = 3;
37
Brandon Wymana0f33ce2019-10-17 18:32:29 -050038/**
39 * @class PowerSupply
40 * Represents a PMBus power supply device.
41 */
42class PowerSupply
43{
44 public:
Brandon Wymanaed1f752019-11-25 18:10:52 -060045 PowerSupply() = delete;
Brandon Wymana0f33ce2019-10-17 18:32:29 -050046 PowerSupply(const PowerSupply&) = delete;
47 PowerSupply(PowerSupply&&) = delete;
48 PowerSupply& operator=(const PowerSupply&) = delete;
49 PowerSupply& operator=(PowerSupply&&) = delete;
50 ~PowerSupply() = default;
51
52 /**
Brandon Wymanc63941c2020-01-27 16:49:33 -060053 * @param[in] invpath - String for inventory path to use
54 * @param[in] i2cbus - The bus number this power supply is on
55 * @param[in] i2caddr - The 16-bit I2C address of the power supply
B. J. Wyman681b2a32021-04-20 22:31:22 +000056 * @param[in] gpioLineName - The gpio-line-name to read for presence. See
57 * https://github.com/openbmc/docs/blob/master/designs/device-tree-gpio-naming.md
Brandon Wymanaed1f752019-11-25 18:10:52 -060058 */
Brandon Wymanc63941c2020-01-27 16:49:33 -060059 PowerSupply(sdbusplus::bus::bus& bus, const std::string& invpath,
B. J. Wyman681b2a32021-04-20 22:31:22 +000060 std::uint8_t i2cbus, const std::uint16_t i2caddr,
61 const std::string& gpioLineName);
Brandon Wymanaed1f752019-11-25 18:10:52 -060062
Brandon Wyman3f1242f2020-01-28 13:11:25 -060063 phosphor::pmbus::PMBusBase& getPMBus()
64 {
65 return *pmbusIntf;
66 }
67
B. J. Wyman681b2a32021-04-20 22:31:22 +000068 GPIOInterface* getPresenceGPIO()
69 {
70 return presenceGPIO.get();
71 }
72
Brandon Wymanaed1f752019-11-25 18:10:52 -060073 /**
Brandon Wymana0f33ce2019-10-17 18:32:29 -050074 * Power supply specific function to analyze for faults/errors.
75 *
76 * Various PMBus status bits will be checked for fault conditions.
77 * If a certain fault bits are on, the appropriate error will be
78 * committed.
79 */
Brandon Wyman3f1242f2020-01-28 13:11:25 -060080 void analyze();
Brandon Wymana0f33ce2019-10-17 18:32:29 -050081
82 /**
Brandon Wyman59a35792020-06-04 12:37:40 -050083 * Write PMBus ON_OFF_CONFIG
84 *
85 * This function will be called to cause the PMBus device driver to send the
86 * ON_OFF_CONFIG command. Takes one byte of data.
87 *
88 * @param[in] data - The ON_OFF_CONFIG data byte mask.
89 */
90 void onOffConfig(uint8_t data);
91
92 /**
Brandon Wymana0f33ce2019-10-17 18:32:29 -050093 * Write PMBus CLEAR_FAULTS
94 *
95 * This function will be called in various situations in order to clear
96 * any fault status bits that may have been set, in order to start over
97 * with a clean state. Presence changes and power state changes will
98 * want to clear any faults logged.
99 */
Brandon Wyman3c208462020-05-13 16:25:58 -0500100 void clearFaults();
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500101
102 /**
103 * @brief Adds properties to the inventory.
104 *
105 * Reads the values from the device and writes them to the
106 * associated power supply D-Bus inventory object.
107 *
108 * This needs to be done on startup, and each time the presence
109 * state changes.
110 *
111 * Properties added:
112 * - Serial Number
113 * - Part Number
114 * - CCIN (Customer Card Identification Number) - added as the Model
115 * - Firmware version
116 */
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500117 void updateInventory();
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500118
Brandon Wymanaed1f752019-11-25 18:10:52 -0600119 /**
120 * @brief Accessor function to indicate present status
121 */
122 bool isPresent() const
123 {
124 return present;
125 }
126
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600127 /**
Brandon Wymanfed0ba22020-09-26 20:02:51 -0500128 * @brief Returns the last read value from STATUS_WORD.
129 */
130 uint64_t getStatusWord() const
131 {
132 return statusWord;
133 }
134
135 /**
Jay Meyer10d94052020-11-30 14:41:21 -0600136 * @brief Returns the last read value from STATUS_MFR.
137 */
138 uint64_t getMFRFault() const
139 {
140 return statusMFR;
141 }
142
143 /**
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600144 * @brief Returns true if a fault was found.
145 */
146 bool isFaulted() const
147 {
Brandon Wyman4176d6b2020-10-07 17:41:06 -0500148 return (faultFound || hasCommFault());
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600149 }
150
151 /**
Brandon Wymanb76ab242020-09-16 18:06:06 -0500152 * @brief Return whether a fault has been logged for this power supply
153 */
154 bool isFaultLogged() const
155 {
156 return faultLogged;
157 }
158
159 /**
160 * @brief Called when a fault for this power supply has been logged.
161 */
162 void setFaultLogged()
163 {
164 faultLogged = true;
165 }
166
167 /**
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600168 * @brief Returns true if INPUT fault occurred.
169 */
170 bool hasInputFault() const
171 {
172 return inputFault;
173 }
174
175 /**
176 * @brief Returns true if MFRSPECIFIC occurred.
177 */
178 bool hasMFRFault() const
179 {
180 return mfrFault;
181 }
182
183 /**
184 * @brief Returns true if VIN_UV_FAULT occurred.
185 */
186 bool hasVINUVFault() const
187 {
188 return vinUVFault;
189 }
190
Brandon Wymanc9efe412020-10-09 15:42:50 -0500191 /**
192 * @brief Returns the device path
193 *
194 * This can be used for error call outs.
195 * Example: /sys/bus/i2c/devices/3-0068
196 */
Brandon Wyman4176d6b2020-10-07 17:41:06 -0500197 const std::string getDevicePath() const
198 {
199 return pmbusIntf->path();
200 }
201
Brandon Wymanc9efe412020-10-09 15:42:50 -0500202 /**
203 * @brief Returns this power supplies inventory path.
204 *
205 * This can be used for error call outs.
206 * Example:
207 * /xyz/openbmc_project/inventory/system/chassis/motherboard/powersupply1
208 */
Brandon Wyman7e495272020-09-26 19:57:46 -0500209 const std::string& getInventoryPath() const
210 {
211 return inventoryPath;
212 }
213
Brandon Wymanc9efe412020-10-09 15:42:50 -0500214 /**
215 * @brief Returns the firmware revision version read from the power supply
216 */
217 const std::string& getFWVersion() const
218 {
219 return fwVersion;
220 }
221
Adriana Kobylak572a9052021-03-30 15:58:07 +0000222 /**
223 * @brief Returns the model name of the power supply
224 */
225 const std::string& getModelName() const
226 {
227 return modelName;
228 }
229
Brandon Wymanf65c4062020-08-19 13:15:53 -0500230 /** @brief Returns true if the number of failed reads exceeds limit
231 * TODO: or CML bit on.
232 */
233 bool hasCommFault() const
234 {
235 return readFail >= LOG_LIMIT;
236 }
237
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500238 private:
Brandon Wymanaed1f752019-11-25 18:10:52 -0600239 /** @brief systemd bus member */
240 sdbusplus::bus::bus& bus;
241
Brandon Wyman9564e942020-11-10 14:01:42 -0600242 /** @brief Will be updated to the latest/lastvalue read from STATUS_WORD.*/
Brandon Wymanfed0ba22020-09-26 20:02:51 -0500243 uint64_t statusWord = 0;
244
Jay Meyer10d94052020-11-30 14:41:21 -0600245 /** @brief Will be updated to the latest/lastvalue read from STATUS_MFR.*/
246 uint64_t statusMFR = 0;
247
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500248 /** @brief True if a fault has already been found and not cleared */
249 bool faultFound = false;
Brandon Wymanaed1f752019-11-25 18:10:52 -0600250
Brandon Wymanb76ab242020-09-16 18:06:06 -0500251 /** @brief True if an error for a fault has already been logged. */
252 bool faultLogged = false;
253
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600254 /** @brief True if bit 5 of STATUS_WORD high byte is on. */
255 bool inputFault = false;
256
257 /** @brief True if bit 4 of STATUS_WORD high byte is on. */
258 bool mfrFault = false;
259
260 /** @brief True if bit 3 of STATUS_WORD low byte is on. */
261 bool vinUVFault = false;
262
Brandon Wymanf65c4062020-08-19 13:15:53 -0500263 /** @brief Count of the number of read failures. */
264 size_t readFail = 0;
265
Brandon Wymanaed1f752019-11-25 18:10:52 -0600266 /**
267 * @brief D-Bus path to use for this power supply's inventory status.
268 **/
269 std::string inventoryPath;
270
B. J. Wyman681b2a32021-04-20 22:31:22 +0000271 /**
272 * @brief The libgpiod object for monitoring PSU presence
273 */
274 std::unique_ptr<GPIOInterface> presenceGPIO = nullptr;
275
Brandon Wymanaed1f752019-11-25 18:10:52 -0600276 /** @brief True if the power supply is present. */
277 bool present = false;
278
Adriana Kobylak572a9052021-03-30 15:58:07 +0000279 /** @brief Power supply model name. */
280 std::string modelName;
281
Brandon Wymanaed1f752019-11-25 18:10:52 -0600282 /** @brief D-Bus match variable used to subscribe to Present property
283 * changes.
284 **/
285 std::unique_ptr<sdbusplus::bus::match_t> presentMatch;
286
287 /** @brief D-Bus match variable used to subscribe for Present property
288 * interface added.
289 */
290 std::unique_ptr<sdbusplus::bus::match_t> presentAddedMatch;
291
292 /**
Brandon Wyman8d195772020-01-27 15:03:51 -0600293 * @brief Pointer to the PMBus interface
294 *
295 * Used to read or write to/from PMBus power supply devices.
296 */
Brandon Wyman9564e942020-11-10 14:01:42 -0600297 std::unique_ptr<phosphor::pmbus::PMBusBase> pmbusIntf = nullptr;
Brandon Wyman8d195772020-01-27 15:03:51 -0600298
Brandon Wymanc9efe412020-10-09 15:42:50 -0500299 /** @brief Stored copy of the firmware version/revision string */
300 std::string fwVersion;
301
Brandon Wyman8d195772020-01-27 15:03:51 -0600302 /**
B. J. Wyman681b2a32021-04-20 22:31:22 +0000303 * @brief The file system path used for binding the device driver.
304 */
305 const std::filesystem::path bindPath;
306
307 /* @brief The string to pass in for binding the device driver. */
308 std::string bindDevice;
309
310 /**
311 * @brief Binds or unbinds the power supply device driver
312 *
313 * Called when a presence change is detected to either bind the device
314 * driver for the power supply when it is installed, or unbind the device
315 * driver when the power supply is removed.
316 *
317 * Writes <device> to <path>/bind (or unbind)
318 *
319 * @param present - when true, will bind the device driver
320 * when false, will unbind the device driver
321 */
322 void bindOrUnbindDriver(bool present);
323
324 /**
Brandon Wymanaed1f752019-11-25 18:10:52 -0600325 * @brief Updates the presence status by querying D-Bus
326 *
327 * The D-Bus inventory properties for this power supply will be read to
328 * determine if the power supply is present or not and update this
329 * object's present member variable to reflect current status.
330 **/
331 void updatePresence();
332
333 /**
B. J. Wyman681b2a32021-04-20 22:31:22 +0000334 * @brief Updates the power supply presence by reading the GPIO line.
335 */
336 void updatePresenceGPIO();
337
338 /**
Brandon Wymanaed1f752019-11-25 18:10:52 -0600339 * @brief Callback for inventory property changes
340 *
341 * Process change of Present property for power supply.
342 *
B. J. Wyman681b2a32021-04-20 22:31:22 +0000343 * This is used if we are watching the D-Bus properties instead of reading
344 * the GPIO presence line ourselves.
345 *
Brandon Wymanaed1f752019-11-25 18:10:52 -0600346 * @param[in] msg - Data associated with Present change signal
347 **/
348 void inventoryChanged(sdbusplus::message::message& msg);
Brandon Wyman9a507db2021-02-25 16:15:22 -0600349
350 /**
351 * @brief Callback for inventory property added.
352 *
353 * Process add of the interface with the Present property for power supply.
354 *
B. J. Wyman681b2a32021-04-20 22:31:22 +0000355 * This is used if we are watching the D-Bus properties instead of reading
356 * the GPIO presence line ourselves.
357 *
Brandon Wyman9a507db2021-02-25 16:15:22 -0600358 * @param[in] msg - Data associated with Present add signal
359 **/
360 void inventoryAdded(sdbusplus::message::message& msg);
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500361};
362
363} // namespace phosphor::power::psu