1 #pragma once
2 
3 #include "pmbus.hpp"
4 #include "types.hpp"
5 #include "utility.hpp"
6 
7 #include <sdbusplus/bus/match.hpp>
8 
9 namespace phosphor::power::psu
10 {
11 
12 /**
13  * @class PowerSupply
14  * Represents a PMBus power supply device.
15  */
16 class PowerSupply
17 {
18   public:
19     PowerSupply() = delete;
20     PowerSupply(const PowerSupply&) = delete;
21     PowerSupply(PowerSupply&&) = delete;
22     PowerSupply& operator=(const PowerSupply&) = delete;
23     PowerSupply& operator=(PowerSupply&&) = delete;
24     ~PowerSupply() = default;
25 
26     /**
27      * @param[in] invpath - String for inventory path to use
28      * @param[in] i2cbus - The bus number this power supply is on
29      * @param[in] i2caddr - The 16-bit I2C address of the power supply
30      */
31     PowerSupply(sdbusplus::bus::bus& bus, const std::string& invpath,
32                 std::uint8_t i2cbus, const std::string& i2caddr) :
33         bus(bus),
34         inventoryPath(invpath),
35         pmbusIntf(phosphor::pmbus::createPMBus(i2cbus, i2caddr))
36     {
37         // Setup the functions to call when the D-Bus inventory path for the
38         // Present property changes.
39         presentMatch = std::make_unique<sdbusplus::bus::match_t>(
40             bus,
41             sdbusplus::bus::match::rules::propertiesChanged(inventoryPath,
42                                                             INVENTORY_IFACE),
43             [this](auto& msg) { this->inventoryChanged(msg); });
44         presentAddedMatch = std::make_unique<sdbusplus::bus::match_t>(
45             bus,
46             sdbusplus::bus::match::rules::interfacesAdded() +
47                 sdbusplus::bus::match::rules::path_namespace(inventoryPath),
48             [this](auto& msg) { this->inventoryChanged(msg); });
49         // Get the current state of the Present property.
50         updatePresence();
51     }
52 
53     phosphor::pmbus::PMBusBase& getPMBus()
54     {
55         return *pmbusIntf;
56     }
57 
58     /**
59      * Power supply specific function to analyze for faults/errors.
60      *
61      * Various PMBus status bits will be checked for fault conditions.
62      * If a certain fault bits are on, the appropriate error will be
63      * committed.
64      */
65     void analyze();
66 
67     /**
68      * Write PMBus CLEAR_FAULTS
69      *
70      * This function will be called in various situations in order to clear
71      * any fault status bits that may have been set, in order to start over
72      * with a clean state. Presence changes and power state changes will
73      * want to clear any faults logged.
74      */
75     void clearFaults()
76     {
77         faultFound = false;
78         inputFault = false;
79         mfrFault = false;
80         vinUVFault = false;
81     }
82 
83     /**
84      * @brief Adds properties to the inventory.
85      *
86      * Reads the values from the device and writes them to the
87      * associated power supply D-Bus inventory object.
88      *
89      * This needs to be done on startup, and each time the presence
90      * state changes.
91      *
92      * Properties added:
93      * - Serial Number
94      * - Part Number
95      * - CCIN (Customer Card Identification Number) - added as the Model
96      * - Firmware version
97      */
98     void updateInventory()
99     {
100     }
101 
102     /**
103      * @brief Accessor function to indicate present status
104      */
105     bool isPresent() const
106     {
107         return present;
108     }
109 
110     /**
111      * @brief Returns true if a fault was found.
112      */
113     bool isFaulted() const
114     {
115         return faultFound;
116     }
117 
118     /**
119      * @brief Returns true if INPUT fault occurred.
120      */
121     bool hasInputFault() const
122     {
123         return inputFault;
124     }
125 
126     /**
127      * @brief Returns true if MFRSPECIFIC occurred.
128      */
129     bool hasMFRFault() const
130     {
131         return mfrFault;
132     }
133 
134     /**
135      * @brief Returns true if VIN_UV_FAULT occurred.
136      */
137     bool hasVINUVFault() const
138     {
139         return vinUVFault;
140     }
141 
142   private:
143     /** @brief systemd bus member */
144     sdbusplus::bus::bus& bus;
145 
146     /** @brief True if a fault has already been found and not cleared */
147     bool faultFound = false;
148 
149     /** @brief True if bit 5 of STATUS_WORD high byte is on. */
150     bool inputFault = false;
151 
152     /** @brief True if bit 4 of STATUS_WORD high byte is on. */
153     bool mfrFault = false;
154 
155     /** @brief True if bit 3 of STATUS_WORD low byte is on. */
156     bool vinUVFault = false;
157 
158     /**
159      * @brief D-Bus path to use for this power supply's inventory status.
160      **/
161     std::string inventoryPath;
162 
163     /** @brief True if the power supply is present. */
164     bool present = false;
165 
166     /** @brief D-Bus match variable used to subscribe to Present property
167      * changes.
168      **/
169     std::unique_ptr<sdbusplus::bus::match_t> presentMatch;
170 
171     /** @brief D-Bus match variable used to subscribe for Present property
172      * interface added.
173      */
174     std::unique_ptr<sdbusplus::bus::match_t> presentAddedMatch;
175 
176     /**
177      * @brief Pointer to the PMBus interface
178      *
179      * Used to read or write to/from PMBus power supply devices.
180      */
181     std::unique_ptr<phosphor::pmbus::PMBusBase> pmbusIntf;
182 
183     /**
184      *  @brief Updates the presence status by querying D-Bus
185      *
186      * The D-Bus inventory properties for this power supply will be read to
187      * determine if the power supply is present or not and update this
188      * object's present member variable to reflect current status.
189      **/
190     void updatePresence();
191 
192     /**
193      * @brief Callback for inventory property changes
194      *
195      * Process change of Present property for power supply.
196      *
197      * @param[in]  msg - Data associated with Present change signal
198      **/
199     void inventoryChanged(sdbusplus::message::message& msg);
200 };
201 
202 } // namespace phosphor::power::psu
203