1 #pragma once
2 #include <sdbusplus/bus/match.hpp>
3 #include "device.hpp"
4 #include "pmbus.hpp"
5 #include "timer.hpp"
6 
7 namespace witherspoon
8 {
9 namespace power
10 {
11 namespace psu
12 {
13 
14 namespace sdbusRule = sdbusplus::bus::match::rules;
15 
16 /**
17  * @class PowerSupply
18  * Represents a PMBus power supply device.
19  */
20 class PowerSupply : public Device
21 {
22     public:
23         PowerSupply() = delete;
24         PowerSupply(const PowerSupply&) = delete;
25         PowerSupply(PowerSupply&&) = default;
26         PowerSupply& operator=(const PowerSupply&) = default;
27         PowerSupply& operator=(PowerSupply&&) = default;
28         ~PowerSupply() = default;
29 
30         /**
31          * Constructor
32          *
33          * @param[in] name - the device name
34          * @param[in] inst - the device instance
35          * @param[in] objpath - the path to monitor
36          * @param[in] invpath - the inventory path to use
37          * @param[in] bus - D-Bus bus object
38          * @param[in] e - event object
39          * @param[in] t - time to allow power supply to assert PG#
40          */
41         PowerSupply(const std::string& name, size_t inst,
42                     const std::string& objpath,
43                     const std::string& invpath,
44                     sdbusplus::bus::bus& bus,
45                     event::Event& e,
46                     std::chrono::seconds& t);
47 
48         /**
49          * Power supply specific function to analyze for faults/errors.
50          *
51          * Various PMBus status bits will be checked for fault conditions.
52          * If a certain fault bits are on, the appropriate error will be
53          * committed.
54          */
55         void analyze() override;
56 
57         /**
58          * Write PMBus CLEAR_FAULTS
59          *
60          * This function will be called in various situations in order to clear
61          * any fault status bits that may have been set, in order to start over
62          * with a clean state. Presence changes and power state changes will
63          * want to clear any faults logged.
64          */
65         void clearFaults() override;
66 
67     private:
68         /**
69          * The path to use for reading various PMBus bits/words.
70          */
71         std::string monitorPath;
72 
73         /**
74          * @brief Pointer to the PMBus interface
75          *
76          * Used to read out of or write to the /sysfs tree(s) containing files
77          * that a device driver monitors the PMBus interface to the power
78          * supplies.
79          */
80         witherspoon::pmbus::PMBus pmbusIntf;
81 
82         /**
83          * @brief D-Bus path to use for this power supply's inventory status.
84          */
85         std::string inventoryPath;
86 
87         /** @brief Connection for sdbusplus bus */
88         sdbusplus::bus::bus& bus;
89 
90         /** @brief True if the power supply is present. */
91         bool present = false;
92 
93         /** @brief Used to subscribe to D-Bus property changes for Present */
94         std::unique_ptr<sdbusplus::bus::match_t> presentMatch;
95 
96         /** @brief True if the power is on. */
97         bool powerOn = false;
98 
99         /** @brief True if power on fault has been detected/reported. */
100         bool powerOnFault = false;
101 
102         /** @brief The sd_event structure used by the power on timer. */
103         event::Event& event;
104 
105         /**
106          * @brief Interval to setting powerOn to true.
107          *
108          * The amount of time to wait from power state on to setting the
109          * internal powerOn state to true. The amount of time the power supply
110          * is allowed to delay setting DGood/PG#.
111          */
112         std::chrono::seconds powerOnInterval;
113 
114         /**
115          * @brief Timer used to delay setting the internal powerOn state.
116          *
117          * The timer used to do the callback after the power state has been on
118          * long enough.
119          */
120         Timer powerOnTimer;
121 
122         /** @brief Used to subscribe to D-Bus power on state changes */
123         std::unique_ptr<sdbusplus::bus::match_t> powerOnMatch;
124 
125         /** @brief Has a PMBus read failure already been logged? */
126         bool readFailLogged = false;
127 
128         /**
129          * @brief Set to true when a VIN UV fault has been detected
130          *
131          * This is the VIN_UV_FAULT bit in the low byte from the STATUS_WORD
132          * command response.
133          */
134         bool vinUVFault = false;
135 
136         /**
137          * @brief Set to true when an input fault or warning is detected
138          *
139          * This is the "INPUT FAULT OR WARNING" bit in the high byte from the
140          * STATUS_WORD command response.
141          */
142         bool inputFault = false;
143 
144         /**
145          * @brief Set to true when an output over current fault is detected
146          *
147          * This is the "IOUT_OC_FAULT" bit in the low byte from the STATUS_WORD
148          * command response.
149          */
150         bool outputOCFault = false;
151 
152         /**
153          * @brief Set to true when the output overvoltage fault is detected
154          */
155         bool outputOVFault = false;
156 
157         /**
158          * @brief Set to true when a fan fault or warning condition is detected
159          */
160         bool fanFault = false;
161 
162         /**
163          * @brief Set to true during a temperature fault or warn condition.
164          */
165         bool temperatureFault = false;
166 
167         /**
168          * @brief Callback for inventory property changes
169          *
170          * Process change of Present property for power supply.
171          *
172          * @param[in]  msg - Data associated with Present change signal
173          *
174          */
175         void inventoryChanged(sdbusplus::message::message& msg);
176 
177         /**
178          * Updates the presence status by querying D-Bus
179          *
180          * The D-Bus inventory properties for this power supply will be read to
181          * determine if the power supply is present or not and update this
182          * objects present member variable to reflect current status.
183          */
184         void updatePresence();
185 
186         /**
187          * @brief Updates the poweredOn status by querying D-Bus
188          *
189          * The D-Bus property for the system power state will be read to
190          * determine if the system is powered on or not.
191          */
192         void updatePowerState();
193 
194         /**
195          * @brief Callback for power state property changes
196          *
197          * Process changes to the powered on stat property for the system.
198          *
199          * @param[in] msg - Data associated with the power state signal
200          */
201         void powerStateChanged(sdbusplus::message::message& msg);
202 
203         /**
204          * @brief Checks for input voltage faults and logs error if needed.
205          *
206          * Check for voltage input under voltage fault (VIN_UV_FAULT) and/or
207          * input fault or warning (INPUT_FAULT), and logs appropriate error(s).
208          *
209          * @param[in] statusWord  - 2 byte STATUS_WORD value read from sysfs
210          */
211         void checkInputFault(const uint16_t statusWord);
212 
213         /**
214          * @brief Checks for power good negated or unit is off in wrong state
215          *
216          * @param[in] statusWord  - 2 byte STATUS_WORD value read from sysfs
217          */
218         void checkPGOrUnitOffFault(const uint16_t statusWord);
219 
220         /**
221          * @brief Checks for output current over current fault.
222          *
223          * IOUT_OC_FAULT is checked, if on, appropriate error is logged.
224          *
225          * @param[in] statusWord  - 2 byte STATUS_WORD value read from sysfs
226          */
227         void checkCurrentOutOverCurrentFault(const uint16_t statusWord);
228 
229         /**
230          * @brief Checks for output overvoltage fault.
231          *
232          * VOUT_OV_FAULT is checked, if on, appropriate error is logged.
233          *
234          * @param[in] statusWord  - 2 byte STATUS_WORD value read from sysfs
235          */
236         void checkOutputOvervoltageFault(const uint16_t statusWord);
237 
238         /**
239          * @brief Checks for a fan fault or warning condition.
240          *
241          * The high byte of STATUS_WORD is checked to see if the "FAN FAULT OR
242          * WARNING" bit is turned on. If it is on, log an error.
243          *
244          * @param[in] statusWord - 2 byte STATUS_WORD value read from sysfs
245          */
246         void checkFanFault(const uint16_t statusWord);
247 
248         /**
249          * @brief Checks for a temperature fault or warning condition.
250          *
251          * The low byte of STATUS_WORD is checked to see if the "TEMPERATURE
252          * FAULT OR WARNING" bit is turned on. If it is on, log an error,
253          * call out the power supply indicating the fault/warning condition.
254          *
255          * @parma[in] statusWord - 2 byte STATUS_WORD value read from sysfs
256          */
257         void checkTemperatureFault(const uint16_t statusWord);
258 
259 };
260 
261 }
262 }
263 }
264