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 #include <stdexcept> 10 11 namespace phosphor::power::psu 12 { 13 14 #ifdef IBM_VPD 15 // PMBus device driver "file name" to read for CCIN value. 16 constexpr auto CCIN = "ccin"; 17 constexpr auto PART_NUMBER = "part_number"; 18 constexpr auto FRU_NUMBER = "fru"; 19 constexpr auto SERIAL_HEADER = "header"; 20 constexpr auto SERIAL_NUMBER = "serial_number"; 21 constexpr auto FW_VERSION = "fw_version"; 22 23 // The D-Bus property name to update with the CCIN value. 24 constexpr auto MODEL_PROP = "Model"; 25 constexpr auto PN_PROP = "PartNumber"; 26 constexpr auto SN_PROP = "SerialNumber"; 27 constexpr auto VERSION_PROP = "Version"; 28 29 // ipzVPD Keyword sizes 30 static constexpr auto FL_KW_SIZE = 20; 31 #endif 32 33 /** 34 * @class PowerSupply 35 * Represents a PMBus power supply device. 36 */ 37 class PowerSupply 38 { 39 public: 40 PowerSupply() = delete; 41 PowerSupply(const PowerSupply&) = delete; 42 PowerSupply(PowerSupply&&) = delete; 43 PowerSupply& operator=(const PowerSupply&) = delete; 44 PowerSupply& operator=(PowerSupply&&) = delete; 45 ~PowerSupply() = default; 46 47 /** 48 * @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 51 */ 52 PowerSupply(sdbusplus::bus::bus& bus, const std::string& invpath, 53 std::uint8_t i2cbus, const std::string& i2caddr) : 54 bus(bus), 55 inventoryPath(invpath), 56 pmbusIntf(phosphor::pmbus::createPMBus(i2cbus, i2caddr)) 57 { 58 if (inventoryPath.empty()) 59 { 60 throw std::invalid_argument{"Invalid empty inventoryPath"}; 61 } 62 63 // 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 79 phosphor::pmbus::PMBusBase& getPMBus() 80 { 81 return *pmbusIntf; 82 } 83 84 /** 85 * 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 */ 91 void analyze(); 92 93 /** 94 * 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 /** 104 * 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 */ 111 void clearFaults(); 112 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 */ 128 void updateInventory(); 129 130 /** 131 * @brief Accessor function to indicate present status 132 */ 133 bool isPresent() const 134 { 135 return present; 136 } 137 138 /** 139 * @brief Returns true if a fault was found. 140 */ 141 bool isFaulted() const 142 { 143 return faultFound; 144 } 145 146 /** 147 * @brief Returns true if INPUT fault occurred. 148 */ 149 bool hasInputFault() const 150 { 151 return inputFault; 152 } 153 154 /** 155 * @brief Returns true if MFRSPECIFIC occurred. 156 */ 157 bool hasMFRFault() const 158 { 159 return mfrFault; 160 } 161 162 /** 163 * @brief Returns true if VIN_UV_FAULT occurred. 164 */ 165 bool hasVINUVFault() const 166 { 167 return vinUVFault; 168 } 169 170 private: 171 /** @brief systemd bus member */ 172 sdbusplus::bus::bus& bus; 173 174 /** @brief True if a fault has already been found and not cleared */ 175 bool faultFound = false; 176 177 /** @brief True if bit 5 of STATUS_WORD high byte is on. */ 178 bool inputFault = false; 179 180 /** @brief True if bit 4 of STATUS_WORD high byte is on. */ 181 bool mfrFault = false; 182 183 /** @brief True if bit 3 of STATUS_WORD low byte is on. */ 184 bool vinUVFault = false; 185 186 /** 187 * @brief D-Bus path to use for this power supply's inventory status. 188 **/ 189 std::string inventoryPath; 190 191 /** @brief True if the power supply is present. */ 192 bool present = false; 193 194 /** @brief D-Bus match variable used to subscribe to Present property 195 * changes. 196 **/ 197 std::unique_ptr<sdbusplus::bus::match_t> presentMatch; 198 199 /** @brief D-Bus match variable used to subscribe for Present property 200 * interface added. 201 */ 202 std::unique_ptr<sdbusplus::bus::match_t> presentAddedMatch; 203 204 /** 205 * @brief Pointer to the PMBus interface 206 * 207 * Used to read or write to/from PMBus power supply devices. 208 */ 209 std::unique_ptr<phosphor::pmbus::PMBusBase> pmbusIntf; 210 211 /** 212 * @brief Updates the presence status by querying D-Bus 213 * 214 * The D-Bus inventory properties for this power supply will be read to 215 * determine if the power supply is present or not and update this 216 * object's present member variable to reflect current status. 217 **/ 218 void updatePresence(); 219 220 /** 221 * @brief Callback for inventory property changes 222 * 223 * Process change of Present property for power supply. 224 * 225 * @param[in] msg - Data associated with Present change signal 226 **/ 227 void inventoryChanged(sdbusplus::message::message& msg); 228 }; 229 230 } // namespace phosphor::power::psu 231