blob: 54c3a01695de00d96a95b1d555cd953ef05e825d [file] [log] [blame]
Shawn McCarney472101c2024-04-17 16:31:09 -05001/**
2 * Copyright © 2024 IBM Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#pragma once
17
18#include "power_sequencer_device.hpp"
19#include "rail.hpp"
20#include "services.hpp"
21
Shawn McCarney31234452025-10-28 12:32:05 -050022#include <cstdint>
Shawn McCarney472101c2024-04-17 16:31:09 -050023#include <map>
24#include <memory>
25#include <string>
26#include <utility>
27#include <vector>
28
29namespace phosphor::power::sequencer
30{
31
32/**
33 * @class StandardDevice
34 *
35 * PowerSequencerDevice sub-class that implements the standard pgood fault
36 * detection algorithm.
37 *
38 * When adding support for a new power sequencer device type, create a sub-class
39 * of StandardDevice if possible. This will ensure that pgood fault detection
40 * works consistently across device types.
41 */
42class StandardDevice : public PowerSequencerDevice
43{
44 public:
45 // Specify which compiler-generated methods we want
46 StandardDevice() = delete;
47 StandardDevice(const StandardDevice&) = delete;
48 StandardDevice(StandardDevice&&) = delete;
49 StandardDevice& operator=(const StandardDevice&) = delete;
50 StandardDevice& operator=(StandardDevice&&) = delete;
51 virtual ~StandardDevice() = default;
52
53 /**
54 * Constructor.
55 *
56 * @param name device name
Shawn McCarney31234452025-10-28 12:32:05 -050057 * @param bus I2C bus for the device
58 * @param address I2C address for the device
Shawn McCarneyfe536672025-10-29 12:44:08 -050059 * @param powerControlGPIOName name of the GPIO that turns this device on
60 * and off
61 * @param powerGoodGPIOName name of the GPIO that reads the power good
62 * signal from this device
Shawn McCarney472101c2024-04-17 16:31:09 -050063 * @param rails voltage rails that are enabled and monitored by this device
64 */
Shawn McCarney31234452025-10-28 12:32:05 -050065 explicit StandardDevice(const std::string& name, uint8_t bus,
66 uint16_t address,
Shawn McCarneyfe536672025-10-29 12:44:08 -050067 const std::string& powerControlGPIOName,
68 const std::string& powerGoodGPIOName,
Shawn McCarney472101c2024-04-17 16:31:09 -050069 std::vector<std::unique_ptr<Rail>> rails) :
Shawn McCarneyfe536672025-10-29 12:44:08 -050070 name{name}, bus{bus}, address{address},
71 powerControlGPIOName{powerControlGPIOName},
72 powerGoodGPIOName{powerGoodGPIOName}, rails{std::move(rails)}
Shawn McCarney472101c2024-04-17 16:31:09 -050073 {}
74
75 /** @copydoc PowerSequencerDevice::getName() */
76 virtual const std::string& getName() const override
77 {
78 return name;
79 }
80
Shawn McCarney31234452025-10-28 12:32:05 -050081 /** @copydoc PowerSequencerDevice::getBus() */
82 virtual uint8_t getBus() const override
83 {
84 return bus;
85 }
86
87 /** @copydoc PowerSequencerDevice::getAddress() */
88 virtual uint16_t getAddress() const override
89 {
90 return address;
91 }
92
Shawn McCarneyfe536672025-10-29 12:44:08 -050093 /** @copydoc PowerSequencerDevice::getPowerControlGPIOName() */
94 virtual const std::string& getPowerControlGPIOName() const override
95 {
96 return powerControlGPIOName;
97 }
98
99 /** @copydoc PowerSequencerDevice::getPowerGoodGPIOName() */
100 virtual const std::string& getPowerGoodGPIOName() const override
101 {
102 return powerGoodGPIOName;
103 }
104
Shawn McCarney472101c2024-04-17 16:31:09 -0500105 /** @copydoc PowerSequencerDevice::getRails() */
106 virtual const std::vector<std::unique_ptr<Rail>>& getRails() const override
107 {
108 return rails;
109 }
110
111 /** @copydoc PowerSequencerDevice::findPgoodFault()
112 *
113 * Calls prepareForPgoodFaultDetection() before starting detection. If a
114 * pgood fault is detected, calls storePgoodFaultDebugData().
115 */
116 virtual std::string findPgoodFault(
117 Services& services, const std::string& powerSupplyError,
118 std::map<std::string, std::string>& additionalData) override;
119
120 protected:
121 /**
122 * Prepare for pgood fault detection.
123 *
124 * Perform any actions that are necessary to prepare for fault detection.
125 * For example, cache information that is slow to obtain and is used
126 * multiple times during detection.
127 *
128 * Default implementation does nothing. Override in sub-classes if needed.
129 *
130 * @param services System services like hardware presence and the journal
131 */
Patrick Williams92261f82025-02-01 08:22:34 -0500132 virtual void prepareForPgoodFaultDetection(
133 [[maybe_unused]] Services& services)
Shawn McCarney472101c2024-04-17 16:31:09 -0500134 {}
135
136 /**
137 * Returns the GPIO values that can be read from the device, if possible.
138 *
139 * If the device does not support reading GPIO values or an error occurs, an
140 * empty vector is returned.
141 *
Shawn McCarneyfc3f31f2024-04-23 17:02:44 -0500142 * @param services System services like hardware presence and the journal
Shawn McCarney472101c2024-04-17 16:31:09 -0500143 * @return GPIO values, or empty vector if values could not be read
144 */
Shawn McCarneyfc3f31f2024-04-23 17:02:44 -0500145 virtual std::vector<int> getGPIOValuesIfPossible(Services& services);
Shawn McCarney472101c2024-04-17 16:31:09 -0500146
147 /**
Shawn McCarney16275832024-06-27 10:14:11 -0500148 * Checks whether a pgood fault has occurred on one of the rails being
149 * monitored by this device.
150 *
151 * If a pgood fault was found in a rail, a pointer to the Rail object is
152 * returned.
153 *
154 * Throws an exception if an error occurs while trying to obtain the status
155 * of the rails.
156 *
157 * @param services System services like hardware presence and the journal
158 * @param gpioValues GPIO values obtained from the device (if any)
159 * @param additionalData Additional data to include in the error log if
160 * a pgood fault was found
161 * @return pointer to Rail object where fault was found, or nullptr if no
162 * Rail found
163 */
164 virtual Rail* findRailWithPgoodFault(
165 Services& services, const std::vector<int>& gpioValues,
166 std::map<std::string, std::string>& additionalData);
167
168 /**
Shawn McCarney472101c2024-04-17 16:31:09 -0500169 * Store pgood fault debug data in the specified additional data map.
170 *
Shawn McCarneyfe78c172024-05-02 14:01:46 -0500171 * The default implementation stores the device name and then calls
172 * storeGPIOValues().
Shawn McCarney472101c2024-04-17 16:31:09 -0500173 *
Shawn McCarneyfe78c172024-05-02 14:01:46 -0500174 * Sub-classes should override if needed to store device-specific data.
Shawn McCarney472101c2024-04-17 16:31:09 -0500175 *
176 * This method should NOT throw exceptions. If debug data cannot be
177 * obtained, the error should be caught and ignored so that pgood error
178 * handling can continue.
179 *
180 * @param services System services like hardware presence and the journal
181 * @param gpioValues GPIO values obtained from the device (if any)
182 * @param additionalData Additional data to include in an error log
183 */
184 virtual void storePgoodFaultDebugData(
185 Services& services, const std::vector<int>& gpioValues,
186 std::map<std::string, std::string>& additionalData);
187
188 /**
Shawn McCarneyfe78c172024-05-02 14:01:46 -0500189 * Store GPIO values in the specified additional data map.
190 *
191 * The default implementation stores the values as a simple list of
192 * integers.
193 *
194 * Sub-classes should override if more advanced formatting is needed. For
195 * example, GPIOs could be stored individually with a name and value, or
196 * related GPIOs could be formatted as a group.
197 *
198 * @param services System services like hardware presence and the journal
199 * @param values GPIO values obtained from the device (if any)
200 * @param additionalData Additional data to include in an error log
201 */
Patrick Williams92261f82025-02-01 08:22:34 -0500202 virtual void storeGPIOValues(
203 Services& services, const std::vector<int>& values,
204 std::map<std::string, std::string>& additionalData);
Shawn McCarneyfe78c172024-05-02 14:01:46 -0500205
206 /**
Shawn McCarney472101c2024-04-17 16:31:09 -0500207 * Device name.
208 */
209 std::string name{};
210
211 /**
Shawn McCarney31234452025-10-28 12:32:05 -0500212 * I2C bus for the device.
213 */
214 uint8_t bus;
215
216 /**
217 * I2C address for the device.
218 */
219 uint16_t address;
220
221 /**
Shawn McCarneyfe536672025-10-29 12:44:08 -0500222 * Name of the GPIO that turns this device on and off.
223 */
224 std::string powerControlGPIOName{};
225
226 /**
227 * Name of the GPIO that reads the power good signal from this device.
228 */
229 std::string powerGoodGPIOName{};
230
231 /**
Shawn McCarney472101c2024-04-17 16:31:09 -0500232 * Voltage rails that are enabled and monitored by this device.
233 */
234 std::vector<std::unique_ptr<Rail>> rails{};
235};
236
237} // namespace phosphor::power::sequencer