blob: 162a4f8400df65a547c89378336401f0f7fe46ad [file] [log] [blame]
Faisal Awada9ed0f382025-08-14 13:21:46 -05001#pragma once
2
3#include "pmbus.hpp"
4#include "types.hpp"
5#include "util.hpp"
6#include "utility.hpp"
7
8#include <gpiod.hpp>
9#include <sdbusplus/bus/match.hpp>
10#include <xyz/openbmc_project/Association/Definitions/server.hpp>
11#include <xyz/openbmc_project/Sensor/Value/server.hpp>
12#include <xyz/openbmc_project/State/Decorator/Availability/server.hpp>
13#include <xyz/openbmc_project/State/Decorator/OperationalStatus/server.hpp>
14
15#include <filesystem>
16#include <stdexcept>
17
18namespace phosphor::power::psu
19{
20
21#if IBM_VPD
22// PMBus device driver "file name" to read for CCIN value.
23constexpr auto CCIN = "ccin";
24constexpr auto PART_NUMBER = "mfr_revision";
25constexpr auto FRU_NUMBER = "mfr_model";
26constexpr auto SERIAL_HEADER = "mfr_location";
27constexpr auto SERIAL_NUMBER = "mfr_serial";
28constexpr auto FW_VERSION = "fw_version";
29
30// The D-Bus property name to update with the CCIN value.
31constexpr auto MODEL_PROP = "Model";
32constexpr auto PN_PROP = "PartNumber";
33constexpr auto SPARE_PN_PROP = "SparePartNumber";
34constexpr auto SN_PROP = "SerialNumber";
35constexpr auto VERSION_PROP = "Version";
36
37// ipzVPD Keyword sizes
38static constexpr auto FL_KW_SIZE = 20;
39static constexpr auto FN_KW_SIZE = 7;
40static constexpr auto PN_KW_SIZE = 7;
41// For IBM power supplies, the SN is 6-byte header + 6-byte serial.
42static constexpr auto SN_KW_SIZE = 12;
43static constexpr auto CC_KW_SIZE = 4;
44#endif
45
46constexpr auto LOG_LIMIT = 3;
47constexpr auto DEGLITCH_LIMIT = 3;
48constexpr auto PGOOD_DEGLITCH_LIMIT = 5;
49// Number of polls to remember that an AC fault occured. Should remain greater
50// than PGOOD_DEGLITCH_LIMIT.
51constexpr auto AC_FAULT_LIMIT = 6;
52
53constexpr auto IBMCFFPS_DD_NAME = "ibm-cffps";
54constexpr auto ACBEL_FSG032_DD_NAME = "acbel-fsg032";
55
56using AvailabilityInterface =
57 sdbusplus::xyz::openbmc_project::State::Decorator::server::Availability;
58using OperationalStatusInterface = sdbusplus::xyz::openbmc_project::State::
59 Decorator::server::OperationalStatus;
60using AssocDefInterface =
61 sdbusplus::xyz::openbmc_project::Association::server::Definitions;
62using SensorInterface = sdbusplus::xyz::openbmc_project::Sensor::server::Value;
63using SensorObject = sdbusplus::server::object_t<SensorInterface>;
64using PowerSensorObject =
65 sdbusplus::server::object_t<SensorInterface, OperationalStatusInterface,
66 AvailabilityInterface, AssocDefInterface>;
67
68using AssociationTuple = std::tuple<std::string, std::string, std::string>;
69
70/**
71 * @class PowerSupply
72 * Represents a PMBus power supply device.
73 */
74class PowerSupply
75{
76 public:
77 PowerSupply() = delete;
78 PowerSupply(const PowerSupply&) = delete;
79 PowerSupply(PowerSupply&&) = delete;
80 PowerSupply& operator=(const PowerSupply&) = delete;
81 PowerSupply& operator=(PowerSupply&&) = delete;
82 ~PowerSupply() = default;
83
84 /**
85 * @param[in] invpath - String for inventory path to use
86 * @param[in] i2cbus - The bus number this power supply is on
87 * @param[in] i2caddr - The 16-bit I2C address of the power supply
88 * @param[in] driver - i2c driver name for power supply
89 * @param[in] gpioLineName - The gpio-line-name to read for presence. See
90 * https://github.com/openbmc/docs/blob/master/designs/device-tree-gpio-naming.md
91 * @param[in] callback - Get the power on status of the psu manager class
92 */
93 PowerSupply(sdbusplus::bus_t& bus, const std::string& invpath,
94 std::uint8_t i2cbus, const std::uint16_t i2caddr,
95 const std::string& driver, const std::string& gpioLineName,
96 std::function<bool()>&& callback);
97
98 /**
99 * @param[in] invpath - String for inventory path to use
100 * @param[in] i2cbus - The bus number this power supply is on
101 * @param[in] i2caddr - The 16-bit I2C address of the power supply
102 * @param[in] driver - i2c driver name for power supply
103 * @param[in] gpioLineName - The gpio-line-name to read for presence. See
104 * https://github.com/openbmc/docs/blob/master/designs/device-tree-gpio-naming.md
105 * @param[in] callback - Get the power on status of the psu manager class
106 * @param[in] chassisShortName - Chassis name
107 */
108 PowerSupply(sdbusplus::bus_t& bus, const std::string& invpath,
109 std::uint8_t i2cbus, const std::uint16_t i2caddr,
110 const std::string& driver, const std::string& gpioLineName,
111 std::function<bool()>&& callback,
112 const std::string& chassisShortName);
113
114 phosphor::pmbus::PMBusBase& getPMBus()
115 {
116 return *pmbusIntf;
117 }
118
119 GPIOInterfaceBase* getPresenceGPIO()
120 {
121 return presenceGPIO.get();
122 }
123
124 std::string getPresenceGPIOName() const
125 {
126 if (presenceGPIO != nullptr)
127 {
128 return presenceGPIO->getName();
129 }
130 else
131 {
132 return std::string();
133 }
134 }
135
136 /**
137 * Power supply specific function to analyze for faults/errors.
138 *
139 * Various PMBus status bits will be checked for fault conditions.
140 * If a certain fault bits are on, the appropriate error will be
141 * committed.
142 */
143 void analyze();
144
145 /**
146 * Write PMBus ON_OFF_CONFIG
147 *
148 * This function will be called to cause the PMBus device driver to send the
149 * ON_OFF_CONFIG command. Takes one byte of data.
150 *
151 * @param[in] data - The ON_OFF_CONFIG data byte mask.
152 */
153 void onOffConfig(uint8_t data);
154
155 /**
156 * Clears all the member variables that indicate if a fault bit was seen as
157 * on in the STATUS_WORD or STATUS_MFR_SPECIFIC response.
158 */
159 void clearFaultFlags()
160 {
161 inputFault = 0;
162 mfrFault = 0;
163 statusMFR = 0;
164 vinUVFault = 0;
165 cmlFault = 0;
166 voutOVFault = 0;
167 ioutOCFault = 0;
168 voutUVFault = 0;
169 fanFault = 0;
170 tempFault = 0;
171 pgoodFault = 0;
172 psKillFault = 0;
173 ps12VcsFault = 0;
174 psCS12VFault = 0;
175 faultLogged = false;
176 }
177
178 /**
179 * @brief Function to specifically clear VIN_UV/OFF fault(s).
180 *
181 * The PMBus HWMON device driver has various alarm "files" to read out of
182 * sysfs. Reading those files will indicate if various alarms are active or
183 * not, and then specifically clear those faults that go with that alarm.
184 *
185 * The VIN_UV fault, indicated in STATUS_INPUT, goes with in1_lcrit_alarm.
186 * When a VIN_UV fault occurs, the "Unit Off For Insufficient Input Voltage"
187 * may also be active. Reading in1_lcrit_alarm should clear both fault bits,
188 * resulting in the corresponding fault bits in STATUS_WORD also clearing.
189 *
190 * See: https://www.kernel.org/doc/html/latest/hwmon/pmbus.html
191 */
192 void clearVinUVFault();
193
194 /**
195 * Write PMBus CLEAR_FAULTS
196 *
197 * This function will be called in various situations in order to clear
198 * any fault status bits that may have been set, in order to start over
199 * with a clean state. Presence changes and power state changes will
200 * want to clear any faults logged.
201 */
202 void clearFaults();
203
204 /**
205 * @brief Adds properties to the inventory.
206 *
207 * Reads the values from the device and writes them to the
208 * associated power supply D-Bus inventory object.
209 *
210 * This needs to be done on startup, and each time the presence
211 * state changes.
212 *
213 * Properties added:
214 * - Serial Number
215 * - Part Number
216 * - CCIN (Customer Card Identification Number) - added as the Model
217 * - Firmware version
218 */
219 void updateInventory();
220
221 /**
222 * @brief Accessor function to indicate present status
223 */
224 bool isPresent() const
225 {
226 return present;
227 }
228
229 /**
230 * @brief Returns the last read value from STATUS_WORD.
231 */
232 uint64_t getStatusWord() const
233 {
234 return statusWord;
235 }
236
237 /**
238 * @brief Returns the last read value from STATUS_INPUT.
239 */
240 uint64_t getStatusInput() const
241 {
242 return statusInput;
243 }
244
245 /**
246 * @brief Returns the last read value from STATUS_MFR.
247 */
248 uint64_t getMFRFault() const
249 {
250 return statusMFR;
251 }
252
253 /**
254 * @brief Returns the last read value from STATUS_CML.
255 */
256 uint64_t getStatusCML() const
257 {
258 return statusCML;
259 }
260
261 /**
262 * @brief Returns the last read value from STATUS_VOUT.
263 */
264 uint64_t getStatusVout() const
265 {
266 return statusVout;
267 }
268
269 /**
270 * @brief Returns the last value read from STATUS_IOUT.
271 */
272 uint64_t getStatusIout() const
273 {
274 return statusIout;
275 }
276
277 /**
278 * @brief Returns the last value read from STATUS_FANS_1_2.
279 */
280 uint64_t getStatusFans12() const
281 {
282 return statusFans12;
283 }
284
285 /**
286 * @brief Returns the last value read from STATUS_TEMPERATURE.
287 */
288 uint64_t getStatusTemperature() const
289 {
290 return statusTemperature;
291 }
292
293 /**
294 * @brief Returns true if a fault was found.
295 */
296 bool isFaulted() const
297 {
298 return (hasCommFault() || (vinUVFault >= DEGLITCH_LIMIT) ||
299 (inputFault >= DEGLITCH_LIMIT) ||
300 (voutOVFault >= DEGLITCH_LIMIT) ||
301 (ioutOCFault >= DEGLITCH_LIMIT) ||
302 (voutUVFault >= DEGLITCH_LIMIT) ||
303 (fanFault >= DEGLITCH_LIMIT) || (tempFault >= DEGLITCH_LIMIT) ||
304 (pgoodFault >= PGOOD_DEGLITCH_LIMIT) ||
305 (mfrFault >= DEGLITCH_LIMIT));
306 }
307
308 /**
309 * @brief Return whether a fault has been logged for this power supply
310 */
311 bool isFaultLogged() const
312 {
313 return faultLogged;
314 }
315
316 /**
317 * @brief Called when a fault for this power supply has been logged.
318 */
319 void setFaultLogged()
320 {
321 faultLogged = true;
322 }
323
324 /**
325 * @brief Returns true if INPUT fault occurred.
326 */
327 bool hasInputFault() const
328 {
329 return (inputFault >= DEGLITCH_LIMIT);
330 }
331
332 /**
333 * @brief Returns true if MFRSPECIFIC occurred.
334 */
335 bool hasMFRFault() const
336 {
337 return (mfrFault >= DEGLITCH_LIMIT);
338 }
339
340 /**
341 * @brief Returns true if VIN_UV_FAULT occurred.
342 */
343 bool hasVINUVFault() const
344 {
345 return (vinUVFault >= DEGLITCH_LIMIT);
346 }
347
348 /**
349 * @brief Returns true if VOUT_OV_FAULT occurred.
350 */
351 bool hasVoutOVFault() const
352 {
353 return (voutOVFault >= DEGLITCH_LIMIT);
354 }
355
356 /**
357 * @brief Returns true if IOUT_OC fault occurred (bit 4 STATUS_BYTE).
358 */
359 bool hasIoutOCFault() const
360 {
361 return (ioutOCFault >= DEGLITCH_LIMIT);
362 }
363
364 /**
365 * @brief Returns true if VOUT_UV_FAULT occurred.
366 */
367 bool hasVoutUVFault() const
368 {
369 return (voutUVFault >= DEGLITCH_LIMIT);
370 }
371
372 /**
373 *@brief Returns true if fan fault occurred.
374 */
375 bool hasFanFault() const
376 {
377 return (fanFault >= DEGLITCH_LIMIT);
378 }
379
380 /**
381 * @brief Returns true if TEMPERATURE fault occurred.
382 */
383 bool hasTempFault() const
384 {
385 return (tempFault >= DEGLITCH_LIMIT);
386 }
387
388 /**
389 * @brief Returns true if there is a PGood fault (PGOOD# inactive, or OFF
390 * bit on).
391 */
392 bool hasPgoodFault() const
393 {
394 return (pgoodFault >= PGOOD_DEGLITCH_LIMIT);
395 }
396
397 /**
398 * @brief Return true if there is a PS_Kill fault.
399 */
400 bool hasPSKillFault() const
401 {
402 return (psKillFault >= DEGLITCH_LIMIT);
403 }
404
405 /**
406 * @brief Returns true if there is a 12Vcs (standy power) fault.
407 */
408 bool hasPS12VcsFault() const
409 {
410 return (ps12VcsFault >= DEGLITCH_LIMIT);
411 }
412
413 /**
414 * @brief Returns true if there is a 12V current-share fault.
415 */
416 bool hasPSCS12VFault() const
417 {
418 return (psCS12VFault >= DEGLITCH_LIMIT);
419 }
420
421 /**
422 * @brief Returns true if an AC fault has occurred in the window of
423 * interest.
424 */
425 bool hasACFault() const
426 {
427 return acFault != 0;
428 }
429
430 /**
431 * @brief Returns the device path
432 *
433 * This can be used for error call outs.
434 * Example: /sys/bus/i2c/devices/3-0068
435 */
436 const std::string getDevicePath() const
437 {
438 return pmbusIntf->path();
439 }
440
441 /**
442 * @brief Returns this power supply's inventory path.
443 *
444 * This can be used for error call outs.
445 * Example:
446 * /xyz/openbmc_project/inventory/system/chassis/motherboard/powersupply1
447 */
448 const std::string& getInventoryPath() const
449 {
450 return inventoryPath;
451 }
452
453 /**
454 * @brief Returns the short name (last part of inventoryPath).
455 */
456 const std::string& getShortName() const
457 {
458 return shortName;
459 }
460
461 /**
462 * @brief Returns the firmware revision version read from the power supply
463 */
464 const std::string& getFWVersion() const
465 {
466 return fwVersion;
467 }
468
469 /**
470 * @brief Returns the model name of the power supply
471 */
472 const std::string& getModelName() const
473 {
474 return modelName;
475 }
476
477 /**
478 * @brief Returns true if the number of failed reads exceeds limit
479 */
480 bool hasCommFault() const
481 {
482 return (readFail >= LOG_LIMIT);
483 }
484
485 /**
486 * @brief Reads the pmbus input voltage and returns that actual voltage
487 * reading and the calculated input voltage based on thresholds.
488 * @param[out] actualInputVoltage - The actual voltage reading, in Volts.
489 * @param[out] inputVoltage - A rounded up/down value of the actual input
490 * voltage based on thresholds, in Volts.
491 */
492 void getInputVoltage(double& actualInputVoltage, int& inputVoltage) const;
493
494 /**
495 * @brief Check if the PS is considered to be available or not
496 *
497 * It is unavailable if any of:
498 * - not present
499 * - input fault active
500 * - Vin UV fault active
501 * - PS KILL fault active
502 * - Iout OC fault active
503 *
504 * Other faults will, through creating error logs with callouts, already
505 * be setting the Functional property to false.
506 *
507 * On changes, the Available property is updated in the inventory.
508 */
509 void checkAvailability();
510
511 /**
512 * @brief Returns true when INPUT_HISTORY sync is required.
513 */
514 bool isSyncHistoryRequired() const
515 {
516 return syncHistoryRequired;
517 }
518
519 /**
520 * @brief Clears the indicator that sync required for INPUT_HISTORY.
521 *
522 * Sets variable to false to indicate that the sync is no longer required.
523 * This can be used after the PSUManager has reacted to the need for the
524 * INPUT_HISTORY data to be synchronized.
525 */
526 void clearSyncHistoryRequired()
527 {
528 syncHistoryRequired = false;
529 }
530
531 /**
532 * @brief Puts the input voltage rating on D-Bus.
533 *
534 * The rating is like 0, 110, 220.
535 */
536 void setInputVoltageRating();
537
538 /**
539 * @brief Returns the peak input power value if there is one,
540 * otherwise std::nullopt.
541 */
542 std::optional<double> getPeakInputPower() const
543 {
544 std::optional<double> value;
545 if (peakInputPowerSensor)
546 {
547 value = peakInputPowerSensor->value();
548 }
549 return value;
550 }
551
552 /**
553 * @brief Converts a Linear Format power number to an integer
554 *
555 * The PMBus spec describes a 2 byte Linear Format
556 * number that is composed of an exponent and mantissa
557 * in two's complement notation.
558 *
559 * Value = Mantissa * 2**Exponent
560 *
561 * @return double - The converted value
562 */
563 static double linearToInteger(uint16_t data);
564
565 /**
566 * @brief Retrieve device driver name
567 */
568 const std::string& getDriverName() const
569 {
570 return driverName;
571 }
572
573 /**
574 * @brief Set device driver name
575 * @param[in] newDriver - device driver name.
576 */
577 void setDriverName(const std::string& newDriver)
578 {
579 driverName = newDriver;
580 }
581
582 private:
583 /**
584 * @brief Examine STATUS_WORD for CML (communication, memory, logic fault).
585 */
586 void analyzeCMLFault();
587
588 /**
589 * @brief Examine STATUS_WORD for INPUT bit on.
590 *
591 * "An input voltage, input current, or input power fault or warning has
592 * occurred."
593 */
594 void analyzeInputFault();
595
596 /**
597 * @brief Examine STATUS_WORD for VOUT being set.
598 *
599 * If VOUT is on, "An output voltage fault or warning has occurred.", and
600 * VOUT_OV_FAULT is on, there is an output over-voltage fault.
601 */
602 void analyzeVoutOVFault();
603
604 /**
605 * @brief Examine STATUS_WORD value read for IOUT_OC_FAULT.
606 *
607 * "An output overcurrent fault has occurred." If it is on, and fault not
608 * set, trace STATUS_WORD, STATUS_MFR_SPECIFIC, and STATUS_IOUT values.
609 */
610 void analyzeIoutOCFault();
611
612 /**
613 * @brief Examines STATUS_WORD value read to see if there is a UV fault.
614 *
615 * Checks if the VOUT bit is on, indicating "An output voltage fault or
616 * warning has occurred", if it is on, but VOUT_OV_FAULT is off, it is
617 * determined to be an indication of an output under-voltage fault.
618 */
619 void analyzeVoutUVFault();
620
621 /**
622 * @brief Examine STATUS_WORD for the fan fault/warning bit.
623 *
624 * If fanFault is not on, trace that the bit now came on, include
625 * STATUS_WORD, STATUS_MFR_SPECIFIC, and STATUS_FANS_1_2 values as well, to
626 * help with understanding what may have caused it to be set.
627 */
628 void analyzeFanFault();
629
630 /**
631 * @brief Examine STATUS_WORD for temperature fault.
632 */
633 void analyzeTemperatureFault();
634
635 /**
636 * @brief Examine STATUS_WORD for pgood or unit off faults.
637 */
638 void analyzePgoodFault();
639
640 /**
641 * @brief Determine possible manufacturer-specific faults from bits in
642 * STATUS_MFR.
643 *
644 * The bits in the STATUS_MFR_SPECIFIC command response have "Manufacturer
645 * Defined" meanings. Determine which faults, if any, are present based on
646 * the power supply (device driver) type.
647 */
648 void determineMFRFault();
649
650 /**
651 * @brief Examine STATUS_WORD value read for MFRSPECIFIC bit on.
652 *
653 * "A manufacturer specific fault or warning has occurred."
654 *
655 * If it is on, call the determineMFRFault() helper function to examine the
656 * value read from STATUS_MFR_SPECIFIC.
657 */
658 void analyzeMFRFault();
659
660 /**
661 * @brief Analyzes the STATUS_WORD for a VIN_UV_FAULT indicator.
662 */
663 void analyzeVinUVFault();
664
665 /**
666 * @brief Given a full inventory path, returns the last node of the path as
667 * the "short name"
668 */
669 std::string findShortName(const std::string& invPath)
670 {
671 const auto lastSlashPos = invPath.find_last_of('/');
672
673 if ((lastSlashPos == std::string::npos) ||
674 ((lastSlashPos + 1) == invPath.size()))
675 {
676 return invPath;
677 }
678 else
679 {
680 return invPath.substr(lastSlashPos + 1);
681 }
682 }
683
684 /**
685 * @brief Binds or unbinds the power supply device driver
686 *
687 * Called when a presence change is detected to either bind the device
688 * driver for the power supply when it is installed, or unbind the device
689 * driver when the power supply is removed.
690 *
691 * Note:
692 * Bind device when device present and i2cbus-i2caddr does not exist
693 * UnBind device when device not present and i2cbus-i2caddr exist
694
695 * Writes <device> to <path>/bind (or unbind)
696 *
697 * @param present - when true, will bind the device driver
698 * when false, will unbind the device driver
699 */
700 void bindOrUnbindDriver(bool present);
701
702 /**
703 * @brief Updates the presence status by querying D-Bus
704 *
705 * The D-Bus inventory properties for this power supply will be read to
706 * determine if the power supply is present or not and update this
707 * object's present member variable to reflect current status.
708 **/
709 void updatePresence();
710
711 /**
712 * @brief Updates the power supply presence by reading the GPIO line.
713 */
714 void updatePresenceGPIO();
715
716 /**
717 * @brief Callback for inventory property changes
718 *
719 * Process change of Present property for power supply.
720 *
721 * This is used if we are watching the D-Bus properties instead of reading
722 * the GPIO presence line ourselves.
723 *
724 * @param[in] msg - Data associated with Present change signal
725 **/
726 void inventoryChanged(sdbusplus::message_t& msg);
727
728 /**
729 * @brief Callback for inventory property added.
730 *
731 * Process add of the interface with the Present property for power supply.
732 *
733 * This is used if we are watching the D-Bus properties instead of reading
734 * the GPIO presence line ourselves.
735 *
736 * @param[in] msg - Data associated with Present add signal
737 **/
738 void inventoryAdded(sdbusplus::message_t& msg);
739
740 /**
741 * @brief Reads the pmbus MFR_POUT_MAX value.
742 *
743 * "The MFR_POUT_MAX command sets or retrieves the maximum rated output
744 * power, in watts, that the unit is rated to supply."
745 *
746 * @return max_power_out value converted from string.
747 */
748 auto getMaxPowerOut() const;
749
750 /**
751 * @brief Reads a VPD value from PMBus, correct size, and contents.
752 *
753 * If the VPD data read is not the passed in size, resize and fill with
754 * spaces. If the data contains a non-alphanumeric value, replace any of
755 * those values with spaces.
756 *
757 * @param[in] vpdName - The name of the sysfs "file" to read data from.
758 * @param[in] type - The HWMON file type to read from.
759 * @param[in] vpdSize - The expacted size of the data for this VPD/property
760 *
761 * @return A string containing the VPD data read, resized if necessary
762 */
763 auto readVPDValue(const std::string& vpdName,
764 const phosphor::pmbus::Type& type,
765 const std::size_t& vpdSize);
766
767 /**
768 * @brief Retrieve PSU VPD keyword from D-Bus
769 *
770 * It retrieves PSU VPD keyword from D-Bus and assign the associated
771 * string to vpdStr.
772 * @param[in] keyword - The VPD search keyword
773 * @param[out] vpdStr - The VPD string associated with the keyword.
774 */
775 void getPsuVpdFromDbus(const std::string& keyword, std::string& vpdStr);
776
777 /**
778 * @brief Creates the appropriate sensor D-Bus objects.
779 */
780 void setupSensors();
781
782 /**
783 * @brief Monitors sensor values and updates D-Bus.
784 * Called from analyze().
785 */
786 void monitorSensors();
787
788 /**
789 * @brief Creates the peak input power sensor D-Bus object
790 * if the PS supports it.
791 */
792 void setupInputPowerPeakSensor();
793
794 /**
795 * @brief Monitors the peak input power sensor
796 */
797 void monitorPeakInputPowerSensor();
798
799 /**
800 * @brief Sets any sensor objects to Available = false on D-Bus.
801 */
802 void setSensorsNotAvailable();
803
804 /**
805 * @brief Returns the associations to create for a sensor on this
806 * power supply.
807 */
808 std::vector<AssociationTuple> getSensorAssociations();
809
810 /**
811 * @brief systemd bus member
812 */
813 sdbusplus::bus_t& bus;
814
815 /**
816 * @brief D-Bus path to use for this power supply's inventory status.
817 **/
818 std::string inventoryPath;
819
820 /**
821 * @brief The file system path used for binding the device driver.
822 */
823 std::filesystem::path bindPath;
824
825 /**
826 * @brief Get the power on status of the psu manager class.
827 *
828 * This is a callback method used to get the power on status of the psu
829 * manager class.
830 */
831 std::function<bool()> isPowerOn;
832
833 /**
834 * @brief Set to true when INPUT_HISTORY sync is required.
835 *
836 * A power supply will need to synchronize its INPUT_HISTORY data with the
837 * other power supplies installed in the system when it goes from missing to
838 * present.
839 */
840 bool syncHistoryRequired{false};
841
842 /**
843 * @brief Store the short name to avoid string processing.
844 *
845 * The short name will be something like powersupply1, the last part of the
846 * inventoryPath.
847 */
848 std::string shortName;
849
850 /**
851 * @brief The libgpiod object for monitoring PSU presence
852 */
853 std::unique_ptr<GPIOInterfaceBase> presenceGPIO = nullptr;
854
855 /**
856 * @brief True if the power supply is present.
857 */
858 bool present = false;
859
860 /**
861 * @brief Power supply model name.
862 */
863 std::string modelName;
864
865 /**
866 * @brief D-Bus match variable used to subscribe to Present property
867 * changes.
868 **/
869 std::unique_ptr<sdbusplus::bus::match_t> presentMatch;
870
871 /**
872 * @brief D-Bus match variable used to subscribe for Present property
873 * interface added.
874 */
875 std::unique_ptr<sdbusplus::bus::match_t> presentAddedMatch;
876
877 /**
878 * @brief Pointer to the PMBus interface
879 *
880 * Used to read or write to/from PMBus power supply devices.
881 */
882 std::unique_ptr<phosphor::pmbus::PMBusBase> pmbusIntf = nullptr;
883
884 /**
885 * @brief Stored copy of the firmware version/revision string
886 */
887 std::string fwVersion;
888
889 /**
890 * @brief The string to pass in for binding the device driver.
891 */
892 std::string bindDevice;
893
894 /**
895 * @brief The result of the most recent availability check
896 *
897 * Saved on the object so changes can be detected.
898 */
899 bool available = false;
900
901 /**
902 * @brief Will be updated to the latest/lastvalue read from STATUS_WORD.
903 */
904 uint64_t statusWord = 0;
905
906 /**
907 * @brief Will be set to the last read value of STATUS_WORD.
908 */
909 uint64_t statusWordOld = 0;
910
911 /**
912 * @brief Will be updated to the latest/lastvalue read from STATUS_INPUT.
913 */
914 uint64_t statusInput = 0;
915
916 /**
917 * @brief Will be updated to the latest/lastvalue read from STATUS_MFR.
918 */
919 uint64_t statusMFR = 0;
920
921 /**
922 * @brief Will be updated to the latest/last value read from STATUS_CML.
923 */
924 uint64_t statusCML = 0;
925
926 /**
927 * @brief Will be updated to the latest/last value read from STATUS_VOUT.
928 */
929 uint64_t statusVout = 0;
930
931 /**
932 * @brief Will be updated to the latest/last value read from STATUS_IOUT.
933 */
934 uint64_t statusIout = 0;
935
936 /**
937 * @brief Will be updated to the latest/last value read from
938 * STATUS_FANS_1_2.
939 */
940 uint64_t statusFans12 = 0;
941
942 /**
943 * @brief Will be updated to the latest/last value read from
944 * STATUS_TEMPERATURE.
945 */
946 uint64_t statusTemperature = 0;
947
948 /**
949 * @brief Will be updated with latest converted value read from READ_VIN
950 */
951 int inputVoltage = phosphor::pmbus::in_input::VIN_VOLTAGE_0;
952
953 /**
954 * @brief Will be updated with the actual voltage last read from READ_VIN
955 */
956 double actualInputVoltage = 0;
957
958 /**
959 * @brief True if an error for a fault has already been logged.
960 */
961 bool faultLogged = false;
962
963 /**
964 * @brief Incremented if bit 1 of STATUS_WORD low byte is on.
965 *
966 * Considered faulted if reaches DEGLITCH_LIMIT.
967 */
968 size_t cmlFault = 0;
969
970 /**
971 * @brief Incremented if bit 5 of STATUS_WORD high byte is on.
972 *
973 * Considered faulted if reaches DEGLITCH_LIMIT.
974 */
975 size_t inputFault = 0;
976
977 /**
978 * @brief Incremented if bit 4 of STATUS_WORD high byte is on.
979 *
980 * Considered faulted if reaches DEGLITCH_LIMIT.
981 */
982 size_t mfrFault = 0;
983
984 /**
985 * @brief Incremented if bit 3 of STATUS_WORD low byte is on.
986 *
987 * Considered faulted if reaches DEGLITCH_LIMIT.
988 */
989 size_t vinUVFault = 0;
990
991 /**
992 * @brief Incremented if bit 5 of STATUS_WORD low byte is on.
993 *
994 * Considered faulted if reaches DEGLITCH_LIMIT.
995 */
996 size_t voutOVFault = 0;
997
998 /**
999 * @brief Incremented if bit 4 of STATUS_WORD low byte is on.
1000 *
1001 * Considered faulted if reaches DEGLITCH_LIMIT.
1002 */
1003 size_t ioutOCFault = 0;
1004
1005 /**
1006 * @brief Incremented if bit 7 of STATUS_WORD high byte is on and bit 5
1007 * (VOUT_OV) of low byte is off.
1008 *
1009 * Considered faulted if reaches DEGLITCH_LIMIT.
1010 */
1011 size_t voutUVFault = 0;
1012
1013 /**
1014 * @brief Incremented if FANS fault/warn bit on in STATUS_WORD.
1015 *
1016 * Considered faulted if reaches DEGLITCH_LIMIT.
1017 */
1018 size_t fanFault = 0;
1019
1020 /**
1021 * @brief Incremented if bit 2 of STATUS_WORD low byte is on.
1022 *
1023 * Considered faulted if reaches DEGLITCH_LIMIT.
1024 */
1025 size_t tempFault = 0;
1026
1027 /**
1028 * @brief Incremented if bit 11 or 6 of STATUS_WORD is on. PGOOD# is
1029 * inactive, or the unit is off.
1030 *
1031 * Considered faulted if reaches DEGLITCH_LIMIT.
1032 */
1033 size_t pgoodFault = 0;
1034
1035 /**
1036 * @brief Power Supply Kill fault.
1037 *
1038 * Incremented based on bits in STATUS_MFR_SPECIFIC. IBM power supplies use
1039 * bit 4 to indicate this fault. Considered faulted if it reaches
1040 * DEGLITCH_LIMIT.
1041 */
1042 size_t psKillFault = 0;
1043
1044 /**
1045 * @brief Power Supply 12Vcs fault (standby power).
1046 *
1047 * Incremented based on bits in STATUS_MFR_SPECIFIC. IBM power supplies use
1048 * bit 6 to indicate this fault. Considered faulted if it reaches
1049 * DEGLITCH_LIMIT.
1050 */
1051 size_t ps12VcsFault = 0;
1052
1053 /**
1054 * @brief Power Supply Current-Share fault in 12V domain.
1055 *
1056 * Incremented based on bits in STATUS_MFR_SPECIFIC. IBM power supplies use
1057 * bit 7 to indicate this fault. Considered faulted if it reaches
1058 * DEGLITCH_LIMIT.
1059 */
1060 size_t psCS12VFault = 0;
1061
1062 /**
1063 * @brief Set to AC_FAULT_LIMIT when AC fault is detected, decremented when
1064 * AC fault has cleared. Effectively forms a timer since last AC failure.
1065 * Zero indicates being outside the window of concern.
1066 */
1067 size_t acFault = 0;
1068
1069 /**
1070 * @brief Count of the number of read failures.
1071 */
1072 size_t readFail = 0;
1073
1074 /**
1075 * @brief The D-Bus object for the input voltage rating
1076 *
1077 * It is updated at startup and power on. If a power supply is
1078 * added or removed after that, it does not need to be updated
1079 * again (though that could be done as a future improvement).
1080 */
1081 std::unique_ptr<SensorObject> inputVoltageRatingIface;
1082
1083 /**
1084 * @brief The D-Bus object for the peak input power sensor.
1085 */
1086 std::unique_ptr<PowerSensorObject> peakInputPowerSensor;
1087
1088 /**
1089 * @brief The device driver name
1090 */
1091 std::string driverName;
1092
1093 /**
1094 * @brief The chassis unique name
1095 */
1096 std::string chassisName;
1097};
1098
1099} // namespace phosphor::power::psu