1 /**
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 <cstdint>
19 #include <optional>
20 #include <stdexcept>
21 #include <string>
22 
23 namespace phosphor::power::sequencer
24 {
25 
26 /**
27  * @struct GPIO
28  *
29  * General Purpose Input/Output (GPIO) that can be read to obtain the pgood
30  * status of a voltage rail.
31  */
32 struct GPIO
33 {
34     /**
35      * The libgpiod line offset of the GPIO.
36      */
37     unsigned int line{0};
38 
39     /**
40      * Specifies whether the GPIO is active low.
41      *
42      * If true, the GPIO value 0 indicates a true pgood status. If false, the
43      * GPIO value 1 indicates a true pgood status.
44      */
45     bool activeLow{false};
46 };
47 
48 /**
49  * @class Rail
50  *
51  * A voltage rail that is enabled or monitored by the power sequencer device.
52  */
53 class Rail
54 {
55   public:
56     // Specify which compiler-generated methods we want
57     Rail() = delete;
58     Rail(const Rail&) = delete;
59     Rail(Rail&&) = delete;
60     Rail& operator=(const Rail&) = delete;
61     Rail& operator=(Rail&&) = delete;
62     ~Rail() = default;
63 
64     /**
65      * Constructor.
66      *
67      * Throws an exception if any of the input parameters are invalid.
68      *
69      * @param name Unique name for the rail
70      * @param presence Optional D-Bus inventory path of a system component which
71      *                 must be present in order for the rail to be present
72      * @param page Optional PMBus PAGE number of the rail.  Required if
73      *             checkStatusVout or compareVoltageToLimits is true.
74      * @param isPowerSupplyRail Specifies whether the rail is produced by a
75      *                          power supply
76      * @param checkStatusVout Specifies whether to check the value of the PMBus
77      *                        STATUS_VOUT command when determining the pgood
78      *                        status of the rail
79      * @param compareVoltageToLimits Specifies whether to compare the output
80      *                               voltage to the undervoltage and
81      *                               overvoltage limits when determining the
82      *                               pgood status of the rail
83      * @param gpio Optional GPIO to read to determine the pgood status of the
84      *             rail
85      */
86     explicit Rail(const std::string& name,
87                   const std::optional<std::string>& presence,
88                   const std::optional<uint8_t>& page, bool isPowerSupplyRail,
89                   bool checkStatusVout, bool compareVoltageToLimits,
90                   const std::optional<GPIO>& gpio) :
91         name{name},
92         presence{presence}, page{page}, isPsuRail{isPowerSupplyRail},
93         checkStatusVout{checkStatusVout},
94         compareVoltageToLimits{compareVoltageToLimits}, gpio{gpio}
95     {
96         // If checking STATUS_VOUT or output voltage, verify PAGE was specified
97         if ((checkStatusVout || compareVoltageToLimits) && !page.has_value())
98         {
99             throw std::invalid_argument{"PMBus PAGE is required"};
100         }
101     }
102 
103     /**
104      * Returns the unique name for the rail.
105      *
106      * @return rail name
107      */
108     const std::string& getName() const
109     {
110         return name;
111     }
112 
113     /**
114      * Returns the D-Bus inventory path of a system component which must be
115      * present in order for the rail to be present.
116      *
117      * @return inventory path for presence detection
118      */
119     const std::optional<std::string>& getPresence() const
120     {
121         return presence;
122     }
123 
124     /**
125      * Returns the PMBus PAGE number of the rail.
126      *
127      * @return PAGE number for rail
128      */
129     const std::optional<uint8_t>& getPage() const
130     {
131         return page;
132     }
133 
134     /**
135      * Returns whether the rail is produced by a power supply.
136      *
137      * @return true if rail is produced by a power supply, false otherwise
138      */
139     bool isPowerSupplyRail() const
140     {
141         return isPsuRail;
142     }
143 
144     /**
145      * Returns whether the value of the PMBus STATUS_VOUT command is checked
146      * when determining the pgood status of the rail.
147      *
148      * @return true if STATUS_VOUT is checked, false otherwise
149      */
150     bool getCheckStatusVout() const
151     {
152         return checkStatusVout;
153     }
154 
155     /**
156      * Returns whether the output voltage should be compared to the undervoltage
157      * and overvoltage limits when determining the pgood status of the rail.
158      *
159      * @return true if output voltage is compared to limits, false otherwise
160      */
161     bool getCompareVoltageToLimits() const
162     {
163         return compareVoltageToLimits;
164     }
165 
166     /**
167      * Returns the GPIO to read to determine the pgood status of the rail.
168      *
169      * @return GPIO
170      */
171     const std::optional<GPIO>& getGPIO() const
172     {
173         return gpio;
174     }
175 
176   private:
177     /**
178      * Unique name for the rail.
179      */
180     std::string name{};
181 
182     /**
183      * D-Bus inventory path of a system component which must be present in order
184      * for the rail to be present.
185      *
186      * If not specified, the rail is assumed to always be present.
187      */
188     std::optional<std::string> presence{};
189 
190     /**
191      * PMBus PAGE number of the rail.
192      */
193     std::optional<uint8_t> page{};
194 
195     /**
196      * Specifies whether the rail is produced by a power supply.
197      */
198     bool isPsuRail{false};
199 
200     /**
201      * Specifies whether to check the value of the PMBus STATUS_VOUT command
202      * when determining the pgood status of the rail.
203      *
204      * If one of the error bits is set in STATUS_VOUT, the rail pgood will be
205      * considered false.
206      */
207     bool checkStatusVout{false};
208 
209     /**
210      * Specifies whether to compare the output voltage to the undervoltage and
211      * overvoltage limits when determining the pgood status of the rail.
212      *
213      * If the output voltage is beyond those limits, the rail pgood will be
214      * considered false.
215      *
216      * Uses the values of the PMBus READ_VOUT, VOUT_UV_FAULT_LIMIT, and
217      * VOUT_OV_FAULT_LIMIT commands.
218      */
219     bool compareVoltageToLimits{false};
220 
221     /**
222      * GPIO to read to determine the pgood status of the rail.
223      */
224     std::optional<GPIO> gpio{};
225 };
226 
227 } // namespace phosphor::power::sequencer
228