blob: f1220fd3c3494b62b644fc860e0029d6282e8a0a [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"
Brandon Wyman3f1242f2020-01-28 13:11:25 -06005#include "utility.hpp"
Brandon Wymanaed1f752019-11-25 18:10:52 -06006
7#include <sdbusplus/bus/match.hpp>
8
Brandon Wyman1d7a7df2020-03-26 10:14:05 -05009#include <stdexcept>
10
Brandon Wymana0f33ce2019-10-17 18:32:29 -050011namespace phosphor::power::psu
12{
Brandon Wyman3f1242f2020-01-28 13:11:25 -060013
Brandon Wyman1d7a7df2020-03-26 10:14:05 -050014#ifdef IBM_VPD
15// PMBus device driver "file name" to read for CCIN value.
16constexpr auto CCIN = "ccin";
17constexpr auto PART_NUMBER = "part_number";
18constexpr auto FRU_NUMBER = "fru";
19constexpr auto SERIAL_HEADER = "header";
20constexpr auto SERIAL_NUMBER = "serial_number";
21constexpr auto FW_VERSION = "fw_version";
22
23// The D-Bus property name to update with the CCIN value.
24constexpr auto MODEL_PROP = "Model";
25constexpr auto PN_PROP = "PartNumber";
26constexpr auto SN_PROP = "SerialNumber";
27constexpr auto VERSION_PROP = "Version";
28
29// ipzVPD Keyword sizes
30static constexpr auto FL_KW_SIZE = 20;
31#endif
32
Brandon Wymana0f33ce2019-10-17 18:32:29 -050033/**
34 * @class PowerSupply
35 * Represents a PMBus power supply device.
36 */
37class PowerSupply
38{
39 public:
Brandon Wymanaed1f752019-11-25 18:10:52 -060040 PowerSupply() = delete;
Brandon Wymana0f33ce2019-10-17 18:32:29 -050041 PowerSupply(const PowerSupply&) = delete;
42 PowerSupply(PowerSupply&&) = delete;
43 PowerSupply& operator=(const PowerSupply&) = delete;
44 PowerSupply& operator=(PowerSupply&&) = delete;
45 ~PowerSupply() = default;
46
47 /**
Brandon Wymanc63941c2020-01-27 16:49:33 -060048 * @param[in] invpath - String for inventory path to use
49 * @param[in] i2cbus - The bus number this power supply is on
50 * @param[in] i2caddr - The 16-bit I2C address of the power supply
Brandon Wymanaed1f752019-11-25 18:10:52 -060051 */
Brandon Wymanc63941c2020-01-27 16:49:33 -060052 PowerSupply(sdbusplus::bus::bus& bus, const std::string& invpath,
53 std::uint8_t i2cbus, const std::string& i2caddr) :
54 bus(bus),
Brandon Wyman8d195772020-01-27 15:03:51 -060055 inventoryPath(invpath),
56 pmbusIntf(phosphor::pmbus::createPMBus(i2cbus, i2caddr))
Brandon Wymanaed1f752019-11-25 18:10:52 -060057 {
Brandon Wyman1d7a7df2020-03-26 10:14:05 -050058 if (inventoryPath.empty())
59 {
60 throw std::invalid_argument{"Invalid empty inventoryPath"};
61 }
62
Brandon Wymanaed1f752019-11-25 18:10:52 -060063 // Setup the functions to call when the D-Bus inventory path for the
64 // Present property changes.
65 presentMatch = std::make_unique<sdbusplus::bus::match_t>(
66 bus,
67 sdbusplus::bus::match::rules::propertiesChanged(inventoryPath,
68 INVENTORY_IFACE),
69 [this](auto& msg) { this->inventoryChanged(msg); });
70 presentAddedMatch = std::make_unique<sdbusplus::bus::match_t>(
71 bus,
72 sdbusplus::bus::match::rules::interfacesAdded() +
73 sdbusplus::bus::match::rules::path_namespace(inventoryPath),
74 [this](auto& msg) { this->inventoryChanged(msg); });
75 // Get the current state of the Present property.
76 updatePresence();
77 }
78
Brandon Wyman3f1242f2020-01-28 13:11:25 -060079 phosphor::pmbus::PMBusBase& getPMBus()
80 {
81 return *pmbusIntf;
82 }
83
Brandon Wymanaed1f752019-11-25 18:10:52 -060084 /**
Brandon Wymana0f33ce2019-10-17 18:32:29 -050085 * Power supply specific function to analyze for faults/errors.
86 *
87 * Various PMBus status bits will be checked for fault conditions.
88 * If a certain fault bits are on, the appropriate error will be
89 * committed.
90 */
Brandon Wyman3f1242f2020-01-28 13:11:25 -060091 void analyze();
Brandon Wymana0f33ce2019-10-17 18:32:29 -050092
93 /**
Brandon Wyman59a35792020-06-04 12:37:40 -050094 * Write PMBus ON_OFF_CONFIG
95 *
96 * This function will be called to cause the PMBus device driver to send the
97 * ON_OFF_CONFIG command. Takes one byte of data.
98 *
99 * @param[in] data - The ON_OFF_CONFIG data byte mask.
100 */
101 void onOffConfig(uint8_t data);
102
103 /**
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500104 * Write PMBus CLEAR_FAULTS
105 *
106 * This function will be called in various situations in order to clear
107 * any fault status bits that may have been set, in order to start over
108 * with a clean state. Presence changes and power state changes will
109 * want to clear any faults logged.
110 */
Brandon Wyman3c208462020-05-13 16:25:58 -0500111 void clearFaults();
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500112
113 /**
114 * @brief Adds properties to the inventory.
115 *
116 * Reads the values from the device and writes them to the
117 * associated power supply D-Bus inventory object.
118 *
119 * This needs to be done on startup, and each time the presence
120 * state changes.
121 *
122 * Properties added:
123 * - Serial Number
124 * - Part Number
125 * - CCIN (Customer Card Identification Number) - added as the Model
126 * - Firmware version
127 */
Brandon Wyman1d7a7df2020-03-26 10:14:05 -0500128 void updateInventory();
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500129
Brandon Wymanaed1f752019-11-25 18:10:52 -0600130 /**
131 * @brief Accessor function to indicate present status
132 */
133 bool isPresent() const
134 {
135 return present;
136 }
137
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600138 /**
Brandon Wymanfed0ba22020-09-26 20:02:51 -0500139 * @brief Returns the last read value from STATUS_WORD.
140 */
141 uint64_t getStatusWord() const
142 {
143 return statusWord;
144 }
145
146 /**
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600147 * @brief Returns true if a fault was found.
148 */
149 bool isFaulted() const
150 {
151 return faultFound;
152 }
153
154 /**
Brandon Wymanb76ab242020-09-16 18:06:06 -0500155 * @brief Return whether a fault has been logged for this power supply
156 */
157 bool isFaultLogged() const
158 {
159 return faultLogged;
160 }
161
162 /**
163 * @brief Called when a fault for this power supply has been logged.
164 */
165 void setFaultLogged()
166 {
167 faultLogged = true;
168 }
169
170 /**
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600171 * @brief Returns true if INPUT fault occurred.
172 */
173 bool hasInputFault() const
174 {
175 return inputFault;
176 }
177
178 /**
179 * @brief Returns true if MFRSPECIFIC occurred.
180 */
181 bool hasMFRFault() const
182 {
183 return mfrFault;
184 }
185
186 /**
187 * @brief Returns true if VIN_UV_FAULT occurred.
188 */
189 bool hasVINUVFault() const
190 {
191 return vinUVFault;
192 }
193
Brandon Wyman7e495272020-09-26 19:57:46 -0500194 const std::string& getInventoryPath() const
195 {
196 return inventoryPath;
197 }
198
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500199 private:
Brandon Wymanaed1f752019-11-25 18:10:52 -0600200 /** @brief systemd bus member */
201 sdbusplus::bus::bus& bus;
202
Brandon Wymanfed0ba22020-09-26 20:02:51 -0500203 /** @brief Will be updated to the latest/lastvalue read from STATUS_WORD. */
204 uint64_t statusWord = 0;
205
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500206 /** @brief True if a fault has already been found and not cleared */
207 bool faultFound = false;
Brandon Wymanaed1f752019-11-25 18:10:52 -0600208
Brandon Wymanb76ab242020-09-16 18:06:06 -0500209 /** @brief True if an error for a fault has already been logged. */
210 bool faultLogged = false;
211
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600212 /** @brief True if bit 5 of STATUS_WORD high byte is on. */
213 bool inputFault = false;
214
215 /** @brief True if bit 4 of STATUS_WORD high byte is on. */
216 bool mfrFault = false;
217
218 /** @brief True if bit 3 of STATUS_WORD low byte is on. */
219 bool vinUVFault = false;
220
Brandon Wymanaed1f752019-11-25 18:10:52 -0600221 /**
222 * @brief D-Bus path to use for this power supply's inventory status.
223 **/
224 std::string inventoryPath;
225
226 /** @brief True if the power supply is present. */
227 bool present = false;
228
229 /** @brief D-Bus match variable used to subscribe to Present property
230 * changes.
231 **/
232 std::unique_ptr<sdbusplus::bus::match_t> presentMatch;
233
234 /** @brief D-Bus match variable used to subscribe for Present property
235 * interface added.
236 */
237 std::unique_ptr<sdbusplus::bus::match_t> presentAddedMatch;
238
239 /**
Brandon Wyman8d195772020-01-27 15:03:51 -0600240 * @brief Pointer to the PMBus interface
241 *
242 * Used to read or write to/from PMBus power supply devices.
243 */
244 std::unique_ptr<phosphor::pmbus::PMBusBase> pmbusIntf;
245
246 /**
Brandon Wymanaed1f752019-11-25 18:10:52 -0600247 * @brief Updates the presence status by querying D-Bus
248 *
249 * The D-Bus inventory properties for this power supply will be read to
250 * determine if the power supply is present or not and update this
251 * object's present member variable to reflect current status.
252 **/
253 void updatePresence();
254
255 /**
256 * @brief Callback for inventory property changes
257 *
258 * Process change of Present property for power supply.
259 *
260 * @param[in] msg - Data associated with Present change signal
261 **/
262 void inventoryChanged(sdbusplus::message::message& msg);
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500263};
264
265} // namespace phosphor::power::psu