blob: 6f1044c744fcb98d9c160ee2668535f160c0b2c4 [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";
Brandon Wymana169b0f2021-12-07 20:18:06 +000029constexpr auto SPARE_PN_PROP = "SparePartNumber";
Brandon Wyman1d7a7df2020-03-26 10:14:05 -050030constexpr auto SN_PROP = "SerialNumber";
31constexpr auto VERSION_PROP = "Version";
32
33// ipzVPD Keyword sizes
34static constexpr auto FL_KW_SIZE = 20;
35#endif
36
Brandon Wymanf65c4062020-08-19 13:15:53 -050037constexpr auto LOG_LIMIT = 3;
Brandon Wyman06ca4592021-12-06 22:52:23 +000038constexpr auto DEGLITCH_LIMIT = 3;
Brandon Wymanf65c4062020-08-19 13:15:53 -050039
Brandon Wymana0f33ce2019-10-17 18:32:29 -050040/**
41 * @class PowerSupply
42 * Represents a PMBus power supply device.
43 */
44class PowerSupply
45{
46 public:
Brandon Wymanaed1f752019-11-25 18:10:52 -060047 PowerSupply() = delete;
Brandon Wymana0f33ce2019-10-17 18:32:29 -050048 PowerSupply(const PowerSupply&) = delete;
49 PowerSupply(PowerSupply&&) = delete;
50 PowerSupply& operator=(const PowerSupply&) = delete;
51 PowerSupply& operator=(PowerSupply&&) = delete;
52 ~PowerSupply() = default;
53
54 /**
Brandon Wymanc63941c2020-01-27 16:49:33 -060055 * @param[in] invpath - String for inventory path to use
56 * @param[in] i2cbus - The bus number this power supply is on
57 * @param[in] i2caddr - The 16-bit I2C address of the power supply
B. J. Wyman681b2a32021-04-20 22:31:22 +000058 * @param[in] gpioLineName - The gpio-line-name to read for presence. See
59 * https://github.com/openbmc/docs/blob/master/designs/device-tree-gpio-naming.md
Brandon Wymanaed1f752019-11-25 18:10:52 -060060 */
Brandon Wymanc63941c2020-01-27 16:49:33 -060061 PowerSupply(sdbusplus::bus::bus& bus, const std::string& invpath,
B. J. Wyman681b2a32021-04-20 22:31:22 +000062 std::uint8_t i2cbus, const std::uint16_t i2caddr,
63 const std::string& gpioLineName);
Brandon Wymanaed1f752019-11-25 18:10:52 -060064
Brandon Wyman3f1242f2020-01-28 13:11:25 -060065 phosphor::pmbus::PMBusBase& getPMBus()
66 {
67 return *pmbusIntf;
68 }
69
Adriana Kobylak3ca062a2021-10-20 15:27:23 +000070 GPIOInterfaceBase* getPresenceGPIO()
B. J. Wyman681b2a32021-04-20 22:31:22 +000071 {
72 return presenceGPIO.get();
73 }
74
B. J. Wymand8b8cb12021-07-15 22:03:34 +000075 std::string getPresenceGPIOName() const
76 {
77 if (presenceGPIO != nullptr)
78 {
79 return presenceGPIO->getName();
80 }
81 else
82 {
83 return std::string();
84 }
85 }
86
Brandon Wymanaed1f752019-11-25 18:10:52 -060087 /**
Brandon Wymana0f33ce2019-10-17 18:32:29 -050088 * Power supply specific function to analyze for faults/errors.
89 *
90 * Various PMBus status bits will be checked for fault conditions.
91 * If a certain fault bits are on, the appropriate error will be
92 * committed.
93 */
Brandon Wyman3f1242f2020-01-28 13:11:25 -060094 void analyze();
Brandon Wymana0f33ce2019-10-17 18:32:29 -050095
96 /**
Brandon Wyman59a35792020-06-04 12:37:40 -050097 * Write PMBus ON_OFF_CONFIG
98 *
99 * This function will be called to cause the PMBus device driver to send the
100 * ON_OFF_CONFIG command. Takes one byte of data.
101 *
102 * @param[in] data - The ON_OFF_CONFIG data byte mask.
103 */
104 void onOffConfig(uint8_t data);
105
106 /**
Brandon Wymane3f7ad22021-12-21 20:27:45 +0000107 * Clears all the member variables that indicate if a fault bit was seen as
108 * on in the STATUS_WORD or STATUS_MFR_SPECIFIC response.
109 */
110 void clearFaultFlags()
111 {
Brandon Wymanc2906f42021-12-21 20:14:56 +0000112 inputFault = 0;
113 mfrFault = 0;
Brandon Wymane3f7ad22021-12-21 20:27:45 +0000114 statusMFR = 0;
Brandon Wymanc2906f42021-12-21 20:14:56 +0000115 vinUVFault = 0;
116 cmlFault = 0;
117 voutOVFault = 0;
118 ioutOCFault = 0;
119 voutUVFault = 0;
120 fanFault = 0;
121 tempFault = 0;
Brandon Wymane3f7ad22021-12-21 20:27:45 +0000122 pgoodFault = 0;
Brandon Wymanc2906f42021-12-21 20:14:56 +0000123 psKillFault = 0;
124 ps12VcsFault = 0;
125 psCS12VFault = 0;
Brandon Wymane3f7ad22021-12-21 20:27:45 +0000126 }
127
128 /**
Brandon Wyman3225a452022-03-18 18:51:49 +0000129 * @brief Function to specifically clear VIN_UV/OFF fault(s).
130 *
131 * The PMBus HWMON device driver has various alarm "files" to read out of
132 * sysfs. Reading those files will indicate if various alarms are active or
133 * not, and then specifically clear those faults that go with that alarm.
134 *
135 * The VIN_UV fault, indicated in STATUS_INPUT, goes with in1_lcrit_alarm.
136 * When a VIN_UV fault occurs, the "Unit Off For Insufficient Input Voltage"
137 * may also be active. Reading in1_lcrit_alarm should clear both fault bits,
138 * resulting in the corresponding fault bits in STATUS_WORD also clearing.
139 *
140 * See: https://www.kernel.org/doc/html/latest/hwmon/pmbus.html
141 */
142 void clearVinUVFault();
143
144 /**
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500145 * Write PMBus CLEAR_FAULTS
146 *
147 * This function will be called in various situations in order to clear
148 * any fault status bits that may have been set, in order to start over
149 * with a clean state. Presence changes and power state changes will
150 * want to clear any faults logged.
151 */
Brandon Wyman3c208462020-05-13 16:25:58 -0500152 void clearFaults();
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500153
154 /**
155 * @brief Adds properties to the inventory.
156 *
157 * Reads the values from the device and writes them to the
158 * associated power supply D-Bus inventory object.
159 *
160 * This needs to be done on startup, and each time the presence
161 * state changes.
162 *
163 * Properties added:
164 * - Serial Number
165 * - Part Number
166 * - CCIN (Customer Card Identification Number) - added as the Model
167 * - Firmware version
168 */
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500169 void updateInventory();
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500170
Brandon Wymanaed1f752019-11-25 18:10:52 -0600171 /**
172 * @brief Accessor function to indicate present status
173 */
174 bool isPresent() const
175 {
176 return present;
177 }
178
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600179 /**
Brandon Wymanfed0ba22020-09-26 20:02:51 -0500180 * @brief Returns the last read value from STATUS_WORD.
181 */
182 uint64_t getStatusWord() const
183 {
184 return statusWord;
185 }
186
187 /**
Brandon Wymanf07bc792021-10-12 19:00:35 +0000188 * @brief Returns the last read value from STATUS_INPUT.
189 */
190 uint64_t getStatusInput() const
191 {
192 return statusInput;
193 }
194
195 /**
Jay Meyer10d94052020-11-30 14:41:21 -0600196 * @brief Returns the last read value from STATUS_MFR.
197 */
198 uint64_t getMFRFault() const
199 {
200 return statusMFR;
201 }
202
203 /**
Brandon Wyman85c7bf42021-10-19 22:28:48 +0000204 * @brief Returns the last read value from STATUS_CML.
205 */
206 uint64_t getStatusCML() const
207 {
208 return statusCML;
209 }
210
211 /**
Brandon Wyman6710ba22021-10-27 17:39:31 +0000212 * @brief Returns the last read value from STATUS_VOUT.
213 */
214 uint64_t getStatusVout() const
215 {
216 return statusVout;
217 }
218
219 /**
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000220 * @brief Returns the last value read from STATUS_IOUT.
221 */
222 uint64_t getStatusIout() const
223 {
224 return statusIout;
225 }
226
227 /**
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000228 * @brief Returns the last value read from STATUS_FANS_1_2.
229 */
230 uint64_t getStatusFans12() const
231 {
232 return statusFans12;
233 }
234
235 /**
Brandon Wyman96893a42021-11-05 19:56:57 +0000236 * @brief Returns the last value read from STATUS_TEMPERATURE.
237 */
238 uint64_t getStatusTemperature() const
239 {
240 return statusTemperature;
241 }
242
243 /**
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600244 * @brief Returns true if a fault was found.
245 */
246 bool isFaulted() const
247 {
Brandon Wymanc2906f42021-12-21 20:14:56 +0000248 return (hasCommFault() || (vinUVFault >= DEGLITCH_LIMIT) ||
249 (inputFault >= DEGLITCH_LIMIT) ||
250 (voutOVFault >= DEGLITCH_LIMIT) ||
251 (ioutOCFault >= DEGLITCH_LIMIT) ||
252 (voutUVFault >= DEGLITCH_LIMIT) ||
253 (fanFault >= DEGLITCH_LIMIT) || (tempFault >= DEGLITCH_LIMIT) ||
254 (pgoodFault >= DEGLITCH_LIMIT) || (mfrFault >= DEGLITCH_LIMIT));
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600255 }
256
257 /**
Brandon Wymanb76ab242020-09-16 18:06:06 -0500258 * @brief Return whether a fault has been logged for this power supply
259 */
260 bool isFaultLogged() const
261 {
262 return faultLogged;
263 }
264
265 /**
266 * @brief Called when a fault for this power supply has been logged.
267 */
268 void setFaultLogged()
269 {
270 faultLogged = true;
271 }
272
273 /**
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600274 * @brief Returns true if INPUT fault occurred.
275 */
276 bool hasInputFault() const
277 {
Brandon Wymanc2906f42021-12-21 20:14:56 +0000278 return (inputFault >= DEGLITCH_LIMIT);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600279 }
280
281 /**
282 * @brief Returns true if MFRSPECIFIC occurred.
283 */
284 bool hasMFRFault() const
285 {
Brandon Wymanc2906f42021-12-21 20:14:56 +0000286 return (mfrFault >= DEGLITCH_LIMIT);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600287 }
288
289 /**
290 * @brief Returns true if VIN_UV_FAULT occurred.
291 */
292 bool hasVINUVFault() const
293 {
Brandon Wymanc2906f42021-12-21 20:14:56 +0000294 return (vinUVFault >= DEGLITCH_LIMIT);
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600295 }
296
Brandon Wymanc9efe412020-10-09 15:42:50 -0500297 /**
Brandon Wyman6710ba22021-10-27 17:39:31 +0000298 * @brief Returns true if VOUT_OV_FAULT occurred.
299 */
300 bool hasVoutOVFault() const
301 {
Brandon Wymanc2906f42021-12-21 20:14:56 +0000302 return (voutOVFault >= DEGLITCH_LIMIT);
Brandon Wyman6710ba22021-10-27 17:39:31 +0000303 }
304
305 /**
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000306 * @brief Returns true if IOUT_OC fault occurred (bit 4 STATUS_BYTE).
307 */
308 bool hasIoutOCFault() const
309 {
Brandon Wymanc2906f42021-12-21 20:14:56 +0000310 return (ioutOCFault >= DEGLITCH_LIMIT);
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000311 }
312
313 /**
Brandon Wyman2cf46942021-10-28 19:09:16 +0000314 * @brief Returns true if VOUT_UV_FAULT occurred.
315 */
316 bool hasVoutUVFault() const
317 {
Brandon Wymanc2906f42021-12-21 20:14:56 +0000318 return (voutUVFault >= DEGLITCH_LIMIT);
Brandon Wyman2cf46942021-10-28 19:09:16 +0000319 }
320
321 /**
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000322 *@brief Returns true if fan fault occurred.
323 */
324 bool hasFanFault() const
325 {
Brandon Wymanc2906f42021-12-21 20:14:56 +0000326 return (fanFault >= DEGLITCH_LIMIT);
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000327 }
328
329 /**
Brandon Wyman96893a42021-11-05 19:56:57 +0000330 * @brief Returns true if TEMPERATURE fault occurred.
331 */
332 bool hasTempFault() const
333 {
Brandon Wymanc2906f42021-12-21 20:14:56 +0000334 return (tempFault >= DEGLITCH_LIMIT);
Brandon Wyman96893a42021-11-05 19:56:57 +0000335 }
336
337 /**
Brandon Wyman2916ea52021-11-06 03:31:18 +0000338 * @brief Returns true if there is a PGood fault (PGOOD# inactive, or OFF
339 * bit on).
340 */
341 bool hasPgoodFault() const
342 {
Brandon Wyman06ca4592021-12-06 22:52:23 +0000343 return (pgoodFault >= DEGLITCH_LIMIT);
Brandon Wyman2916ea52021-11-06 03:31:18 +0000344 }
345
346 /**
Brandon Wyman39ea02b2021-11-23 23:22:23 +0000347 * @brief Return true if there is a PS_Kill fault.
348 */
349 bool hasPSKillFault() const
350 {
Brandon Wymanc2906f42021-12-21 20:14:56 +0000351 return (psKillFault >= DEGLITCH_LIMIT);
Brandon Wyman39ea02b2021-11-23 23:22:23 +0000352 }
353
354 /**
355 * @brief Returns true if there is a 12Vcs (standy power) fault.
356 */
357 bool hasPS12VcsFault() const
358 {
Brandon Wymanc2906f42021-12-21 20:14:56 +0000359 return (ps12VcsFault >= DEGLITCH_LIMIT);
Brandon Wyman39ea02b2021-11-23 23:22:23 +0000360 }
361
362 /**
363 * @brief Returns true if there is a 12V current-share fault.
364 */
365 bool hasPSCS12VFault() const
366 {
Brandon Wymanc2906f42021-12-21 20:14:56 +0000367 return (psCS12VFault >= DEGLITCH_LIMIT);
Brandon Wyman39ea02b2021-11-23 23:22:23 +0000368 }
369
370 /**
Brandon Wymanc9efe412020-10-09 15:42:50 -0500371 * @brief Returns the device path
372 *
373 * This can be used for error call outs.
374 * Example: /sys/bus/i2c/devices/3-0068
375 */
Brandon Wyman4176d6b2020-10-07 17:41:06 -0500376 const std::string getDevicePath() const
377 {
378 return pmbusIntf->path();
379 }
380
Brandon Wymanc9efe412020-10-09 15:42:50 -0500381 /**
Brandon Wyman321a6152022-03-19 00:11:44 +0000382 * @brief Returns this power supply's inventory path.
Brandon Wymanc9efe412020-10-09 15:42:50 -0500383 *
384 * This can be used for error call outs.
385 * Example:
386 * /xyz/openbmc_project/inventory/system/chassis/motherboard/powersupply1
387 */
Brandon Wyman7e495272020-09-26 19:57:46 -0500388 const std::string& getInventoryPath() const
389 {
390 return inventoryPath;
391 }
392
Brandon Wymanc9efe412020-10-09 15:42:50 -0500393 /**
Brandon Wyman321a6152022-03-19 00:11:44 +0000394 * @brief Returns the short name (last part of inventoryPath).
395 */
396 const std::string& getShortName() const
397 {
398 return shortName;
399 }
400
401 /**
Brandon Wymanc9efe412020-10-09 15:42:50 -0500402 * @brief Returns the firmware revision version read from the power supply
403 */
404 const std::string& getFWVersion() const
405 {
406 return fwVersion;
407 }
408
Adriana Kobylak572a9052021-03-30 15:58:07 +0000409 /**
410 * @brief Returns the model name of the power supply
411 */
412 const std::string& getModelName() const
413 {
414 return modelName;
415 }
416
Brandon Wymanf65c4062020-08-19 13:15:53 -0500417 /** @brief Returns true if the number of failed reads exceeds limit
418 * TODO: or CML bit on.
419 */
420 bool hasCommFault() const
421 {
Brandon Wymanc2906f42021-12-21 20:14:56 +0000422 return ((readFail >= LOG_LIMIT) || (cmlFault >= DEGLITCH_LIMIT));
Brandon Wymanf65c4062020-08-19 13:15:53 -0500423 }
424
Adriana Kobylak4175ffb2021-08-02 14:51:05 +0000425 /**
426 * @brief Reads the pmbus input voltage and returns that actual voltage
427 * reading and the calculated input voltage based on thresholds.
428 * @param[out] actualInputVoltage - The actual voltage reading, in Volts.
429 * @param[out] inputVoltage - A rounded up/down value of the actual input
430 * voltage based on thresholds, in Volts.
431 */
432 void getInputVoltage(double& actualInputVoltage, int& inputVoltage) const;
433
Matt Spinler0975eaf2022-02-14 15:38:30 -0600434 /**
435 * @brief Check if the PS is considered to be available or not
436 *
437 * It is unavailable if any of:
438 * - not present
439 * - input fault active
440 * - Vin UV fault active
441 * - PS KILL fault active
442 * - Iout OC fault active
443 *
444 * Other faults will, through creating error logs with callouts, already
445 * be setting the Functional property to false.
446 *
447 * On changes, the Available property is updated in the inventory.
448 */
449 void checkAvailability();
450
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500451 private:
Brandon Wymanaed1f752019-11-25 18:10:52 -0600452 /** @brief systemd bus member */
453 sdbusplus::bus::bus& bus;
454
Brandon Wyman9564e942020-11-10 14:01:42 -0600455 /** @brief Will be updated to the latest/lastvalue read from STATUS_WORD.*/
Brandon Wymanfed0ba22020-09-26 20:02:51 -0500456 uint64_t statusWord = 0;
457
Brandon Wyman9e292ee2022-03-10 22:56:23 +0000458 /** @brief Will be set to the last read value of STATUS_WORD. */
459 uint64_t statusWordOld = 0;
460
Brandon Wymanf07bc792021-10-12 19:00:35 +0000461 /** @brief Will be updated to the latest/lastvalue read from STATUS_INPUT.*/
462 uint64_t statusInput = 0;
463
Jay Meyer10d94052020-11-30 14:41:21 -0600464 /** @brief Will be updated to the latest/lastvalue read from STATUS_MFR.*/
465 uint64_t statusMFR = 0;
466
Brandon Wyman85c7bf42021-10-19 22:28:48 +0000467 /** @brief Will be updated to the latest/last value read from STATUS_CML.*/
468 uint64_t statusCML = 0;
469
Brandon Wyman6710ba22021-10-27 17:39:31 +0000470 /** @brief Will be updated to the latest/last value read from STATUS_VOUT.*/
471 uint64_t statusVout = 0;
472
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000473 /** @brief Will be updated to the latest/last value read from STATUS_IOUT.*/
474 uint64_t statusIout = 0;
475
Brandon Wyman96893a42021-11-05 19:56:57 +0000476 /** @brief Will be updated to the latest/last value read from
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000477 * STATUS_FANS_1_2. */
478 uint64_t statusFans12 = 0;
479
480 /** @brief Will be updated to the latest/last value read from
Brandon Wyman96893a42021-11-05 19:56:57 +0000481 * STATUS_TEMPERATURE.*/
482 uint64_t statusTemperature = 0;
483
Brandon Wyman82affd92021-11-24 19:12:49 +0000484 /** @brief Will be updated with latest converted value read from READ_VIN */
485 int inputVoltage = phosphor::pmbus::in_input::VIN_VOLTAGE_0;
486
Brandon Wyman4fc191f2022-03-10 23:07:13 +0000487 /** @brief Will be updated with the actual voltage last read from READ_VIN
488 */
489 double actualInputVoltage = 0;
490
Brandon Wymanb76ab242020-09-16 18:06:06 -0500491 /** @brief True if an error for a fault has already been logged. */
492 bool faultLogged = false;
493
Brandon Wymanc2906f42021-12-21 20:14:56 +0000494 /** @brief Incremented if bit 1 of STATUS_WORD low byte is on.
495 *
496 * Considered faulted if reaches DEGLITCH_LIMIT.
497 */
498 size_t cmlFault = 0;
Brandon Wyman85c7bf42021-10-19 22:28:48 +0000499
Brandon Wymanc2906f42021-12-21 20:14:56 +0000500 /** @brief Incremented if bit 5 of STATUS_WORD high byte is on.
501 *
502 * Considered faulted if reaches DEGLITCH_LIMIT.
503 */
504 size_t inputFault = 0;
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600505
Brandon Wymanc2906f42021-12-21 20:14:56 +0000506 /** @brief Incremented if bit 4 of STATUS_WORD high byte is on.
507 *
508 * Considered faulted if reaches DEGLITCH_LIMIT.
509 */
510 size_t mfrFault = 0;
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600511
Brandon Wymanc2906f42021-12-21 20:14:56 +0000512 /** @brief Incremented if bit 3 of STATUS_WORD low byte is on.
513 *
514 * Considered faulted if reaches DEGLITCH_LIMIT.
515 */
516 size_t vinUVFault = 0;
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600517
Brandon Wymanc2906f42021-12-21 20:14:56 +0000518 /** @brief Incremented if bit 5 of STATUS_WORD low byte is on.
519 *
520 * Considered faulted if reaches DEGLITCH_LIMIT.
521 */
522 size_t voutOVFault = 0;
Brandon Wyman6710ba22021-10-27 17:39:31 +0000523
Brandon Wymanc2906f42021-12-21 20:14:56 +0000524 /** @brief Incremented if bit 4 of STATUS_WORD low byte is on.
525 *
526 * Considered faulted if reaches DEGLITCH_LIMIT.
527 */
528 size_t ioutOCFault = 0;
Brandon Wymanb10b3be2021-11-09 22:12:15 +0000529
Brandon Wymanc2906f42021-12-21 20:14:56 +0000530 /** @brief Incremented if bit 7 of STATUS_WORD high byte is on and bit 5
531 * (VOUT_OV) of low byte is off.
532 *
533 * Considered faulted if reaches DEGLITCH_LIMIT.
534 */
535 size_t voutUVFault = 0;
Brandon Wyman2cf46942021-10-28 19:09:16 +0000536
Brandon Wymanc2906f42021-12-21 20:14:56 +0000537 /** @brief Incremented if FANS fault/warn bit on in STATUS_WORD.
538 *
539 * Considered faulted if reaches DEGLITCH_LIMIT.
540 */
541 size_t fanFault = 0;
Brandon Wyman7ee4d7e2021-11-19 20:48:23 +0000542
Brandon Wymanc2906f42021-12-21 20:14:56 +0000543 /** @brief Incremented if bit 2 of STATUS_WORD low byte is on.
544 *
545 * Considered faulted if reaches DEGLITCH_LIMIT. */
546 size_t tempFault = 0;
Brandon Wyman96893a42021-11-05 19:56:57 +0000547
Brandon Wyman2cf46942021-10-28 19:09:16 +0000548 /**
Brandon Wyman06ca4592021-12-06 22:52:23 +0000549 * @brief Incremented if bit 11 or 6 of STATUS_WORD is on. PGOOD# is
550 * inactive, or the unit is off.
551 *
552 * Considered faulted if reaches DEGLITCH_LIMIT.
Brandon Wyman2916ea52021-11-06 03:31:18 +0000553 */
Brandon Wyman925c0262021-12-21 20:15:36 +0000554 size_t pgoodFault = 0;
Brandon Wyman2916ea52021-11-06 03:31:18 +0000555
Brandon Wyman39ea02b2021-11-23 23:22:23 +0000556 /**
557 * @brief Power Supply Kill fault.
Brandon Wymanc2906f42021-12-21 20:14:56 +0000558 *
559 * Incremented based on bits in STATUS_MFR_SPECIFIC. IBM power supplies use
560 * bit 4 to indicate this fault. Considered faulted if it reaches
561 * DEGLITCH_LIMIT.
Brandon Wyman39ea02b2021-11-23 23:22:23 +0000562 */
Brandon Wymanc2906f42021-12-21 20:14:56 +0000563 size_t psKillFault = 0;
Brandon Wyman39ea02b2021-11-23 23:22:23 +0000564
565 /**
566 * @brief Power Supply 12Vcs fault (standby power).
Brandon Wymanc2906f42021-12-21 20:14:56 +0000567 *
568 * Incremented based on bits in STATUS_MFR_SPECIFIC. IBM power supplies use
569 * bit 6 to indicate this fault. Considered faulted if it reaches
570 * DEGLITCH_LIMIT.
Brandon Wyman39ea02b2021-11-23 23:22:23 +0000571 */
Brandon Wymanc2906f42021-12-21 20:14:56 +0000572 size_t ps12VcsFault = 0;
Brandon Wyman39ea02b2021-11-23 23:22:23 +0000573
574 /**
575 * @brief Power Supply Current-Share fault in 12V domain.
Brandon Wymanc2906f42021-12-21 20:14:56 +0000576 *
577 * Incremented based on bits in STATUS_MFR_SPECIFIC. IBM power supplies use
578 * bit 7 to indicate this fault. Considered faulted if it reaches
579 * DEGLITCH_LIMIT.
Brandon Wyman39ea02b2021-11-23 23:22:23 +0000580 */
Brandon Wymanc2906f42021-12-21 20:14:56 +0000581 size_t psCS12VFault = 0;
Brandon Wyman39ea02b2021-11-23 23:22:23 +0000582
Brandon Wymanf65c4062020-08-19 13:15:53 -0500583 /** @brief Count of the number of read failures. */
584 size_t readFail = 0;
585
Brandon Wymanaed1f752019-11-25 18:10:52 -0600586 /**
Brandon Wymanc2203432021-12-21 23:09:48 +0000587 * @brief Examine STATUS_WORD for CML (communication, memory, logic fault).
588 */
589 void analyzeCMLFault();
590
591 /**
Brandon Wymane3b0bb02021-12-21 23:16:48 +0000592 * @brief Examine STATUS_WORD for INPUT bit on.
593 *
594 * "An input voltage, input current, or input power fault or warning has
595 * occurred."
596 */
597 void analyzeInputFault();
598
599 /**
Brandon Wymanc2c87132021-12-21 23:22:18 +0000600 * @brief Examine STATUS_WORD for VOUT being set.
601 *
602 * If VOUT is on, "An output voltage fault or warning has occurred.", and
603 * VOUT_OV_FAULT is on, there is an output over-voltage fault.
604 */
605 void analyzeVoutOVFault();
606
Brandon Wymana00e7302021-12-21 23:28:29 +0000607 /*
608 * @brief Examine STATUS_WORD value read for IOUT_OC_FAULT.
609 *
610 * "An output overcurrent fault has occurred." If it is on, and fault not
611 * set, trace STATUS_WORD, STATUS_MFR_SPECIFIC, and STATUS_IOUT values.
612 */
613 void analyzeIoutOCFault();
614
Brandon Wymanc2c87132021-12-21 23:22:18 +0000615 /**
Brandon Wyman08378782021-12-21 23:48:15 +0000616 * @brief Examines STATUS_WORD value read to see if there is a UV fault.
617 *
618 * Checks if the VOUT bit is on, indicating "An output voltage fault or
619 * warning has occurred", if it is on, but VOUT_OV_FAULT is off, it is
620 * determined to be an indication of an output under-voltage fault.
621 */
622 void analyzeVoutUVFault();
623
624 /**
Brandon Wymand5d9a222021-12-21 23:59:05 +0000625 * @brief Examine STATUS_WORD for the fan fault/warning bit.
626 *
627 * If fanFault is not on, trace that the bit now came on, include
628 * STATUS_WORD, STATUS_MFR_SPECIFIC, and STATUS_FANS_1_2 values as well, to
629 * help with understanding what may have caused it to be set.
630 */
631 void analyzeFanFault();
632
633 /**
Brandon Wyman52cb3f22021-12-21 23:02:47 +0000634 * @brief Examine STATUS_WORD for temperature fault.
635 */
636 void analyzeTemperatureFault();
637
638 /**
Brandon Wyman993b5542021-12-21 22:55:16 +0000639 * @brief Examine STATUS_WORD for pgood or unit off faults.
640 */
641 void analyzePgoodFault();
642
643 /**
Brandon Wyman39ea02b2021-11-23 23:22:23 +0000644 * @brief Determine possible manufacturer-specific faults from bits in
645 * STATUS_MFR.
646 *
647 * The bits in the STATUS_MFR_SPECIFIC command response have "Manufacturer
648 * Defined" meanings. Determine which faults, if any, are present based on
649 * the power supply (device driver) type.
650 */
651 void determineMFRFault();
652
653 /**
Brandon Wyman6c2ac392021-12-21 22:23:06 +0000654 * @brief Examine STATUS_WORD value read for MFRSPECIFIC bit on.
655 *
656 * "A manufacturer specific fault or warning has occurred."
657 *
658 * If it is on, call the determineMFRFault() helper function to examine the
659 * value read from STATUS_MFR_SPECIFIC.
660 */
661 void analyzeMFRFault();
662
663 /**
Brandon Wymanf087f472021-12-22 00:04:27 +0000664 * @brief Analyzes the STATUS_WORD for a VIN_UV_FAULT indicator.
665 */
666 void analyzeVinUVFault();
667
668 /**
Brandon Wymanaed1f752019-11-25 18:10:52 -0600669 * @brief D-Bus path to use for this power supply's inventory status.
670 **/
671 std::string inventoryPath;
672
B. J. Wyman681b2a32021-04-20 22:31:22 +0000673 /**
Brandon Wyman321a6152022-03-19 00:11:44 +0000674 * @brief Store the short name to avoid string processing.
675 *
676 * The short name will be something like powersupply1, the last part of the
677 * inventoryPath.
678 */
679 std::string shortName;
680
681 /**
682 * @brief Given a full inventory path, returns the last node of the path as
683 * the "short name"
684 */
685 std::string findShortName(const std::string& invPath)
686 {
687 auto const lastSlashPos = invPath.find_last_of('/');
688
689 if ((lastSlashPos == std::string::npos) ||
690 ((lastSlashPos + 1) == invPath.size()))
691 {
692 return invPath;
693 }
694 else
695 {
696 return invPath.substr(lastSlashPos + 1);
697 }
698 }
699
700 /**
B. J. Wyman681b2a32021-04-20 22:31:22 +0000701 * @brief The libgpiod object for monitoring PSU presence
702 */
Adriana Kobylak3ca062a2021-10-20 15:27:23 +0000703 std::unique_ptr<GPIOInterfaceBase> presenceGPIO = nullptr;
B. J. Wyman681b2a32021-04-20 22:31:22 +0000704
Brandon Wymanaed1f752019-11-25 18:10:52 -0600705 /** @brief True if the power supply is present. */
706 bool present = false;
707
Adriana Kobylak572a9052021-03-30 15:58:07 +0000708 /** @brief Power supply model name. */
709 std::string modelName;
710
Brandon Wymanaed1f752019-11-25 18:10:52 -0600711 /** @brief D-Bus match variable used to subscribe to Present property
712 * changes.
713 **/
714 std::unique_ptr<sdbusplus::bus::match_t> presentMatch;
715
716 /** @brief D-Bus match variable used to subscribe for Present property
717 * interface added.
718 */
719 std::unique_ptr<sdbusplus::bus::match_t> presentAddedMatch;
720
721 /**
Brandon Wyman8d195772020-01-27 15:03:51 -0600722 * @brief Pointer to the PMBus interface
723 *
724 * Used to read or write to/from PMBus power supply devices.
725 */
Brandon Wyman9564e942020-11-10 14:01:42 -0600726 std::unique_ptr<phosphor::pmbus::PMBusBase> pmbusIntf = nullptr;
Brandon Wyman8d195772020-01-27 15:03:51 -0600727
Brandon Wymanc9efe412020-10-09 15:42:50 -0500728 /** @brief Stored copy of the firmware version/revision string */
729 std::string fwVersion;
730
Brandon Wyman8d195772020-01-27 15:03:51 -0600731 /**
B. J. Wyman681b2a32021-04-20 22:31:22 +0000732 * @brief The file system path used for binding the device driver.
733 */
734 const std::filesystem::path bindPath;
735
736 /* @brief The string to pass in for binding the device driver. */
737 std::string bindDevice;
738
739 /**
Matt Spinler0975eaf2022-02-14 15:38:30 -0600740 * @brief The result of the most recent availability check
741 *
742 * Saved on the object so changes can be detected.
743 */
744 bool available = false;
745
746 /**
B. J. Wyman681b2a32021-04-20 22:31:22 +0000747 * @brief Binds or unbinds the power supply device driver
748 *
749 * Called when a presence change is detected to either bind the device
750 * driver for the power supply when it is installed, or unbind the device
751 * driver when the power supply is removed.
752 *
753 * Writes <device> to <path>/bind (or unbind)
754 *
755 * @param present - when true, will bind the device driver
756 * when false, will unbind the device driver
757 */
758 void bindOrUnbindDriver(bool present);
759
760 /**
Brandon Wymanaed1f752019-11-25 18:10:52 -0600761 * @brief Updates the presence status by querying D-Bus
762 *
763 * The D-Bus inventory properties for this power supply will be read to
764 * determine if the power supply is present or not and update this
765 * object's present member variable to reflect current status.
766 **/
767 void updatePresence();
768
769 /**
B. J. Wyman681b2a32021-04-20 22:31:22 +0000770 * @brief Updates the power supply presence by reading the GPIO line.
771 */
772 void updatePresenceGPIO();
773
774 /**
Brandon Wymanaed1f752019-11-25 18:10:52 -0600775 * @brief Callback for inventory property changes
776 *
777 * Process change of Present property for power supply.
778 *
B. J. Wyman681b2a32021-04-20 22:31:22 +0000779 * This is used if we are watching the D-Bus properties instead of reading
780 * the GPIO presence line ourselves.
781 *
Brandon Wymanaed1f752019-11-25 18:10:52 -0600782 * @param[in] msg - Data associated with Present change signal
783 **/
784 void inventoryChanged(sdbusplus::message::message& msg);
Brandon Wyman9a507db2021-02-25 16:15:22 -0600785
786 /**
787 * @brief Callback for inventory property added.
788 *
789 * Process add of the interface with the Present property for power supply.
790 *
B. J. Wyman681b2a32021-04-20 22:31:22 +0000791 * This is used if we are watching the D-Bus properties instead of reading
792 * the GPIO presence line ourselves.
793 *
Brandon Wyman9a507db2021-02-25 16:15:22 -0600794 * @param[in] msg - Data associated with Present add signal
795 **/
796 void inventoryAdded(sdbusplus::message::message& msg);
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500797};
798
799} // namespace phosphor::power::psu