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 compareVoltageToLimit 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 compareVoltageToLimit Specifies whether to compare the output
80      *                              voltage to the undervoltage fault limit when
81      *                              determining the pgood status of the rail
82      * @param gpio Optional GPIO to read to determine the pgood status of the
83      *             rail
84      */
85     explicit Rail(const std::string& name,
86                   const std::optional<std::string>& presence,
87                   const std::optional<uint8_t>& page, bool isPowerSupplyRail,
88                   bool checkStatusVout, bool compareVoltageToLimit,
89                   const std::optional<GPIO>& gpio) :
90         name{name},
91         presence{presence}, page{page}, isPsuRail{isPowerSupplyRail},
92         checkStatusVout{checkStatusVout},
93         compareVoltageToLimit{compareVoltageToLimit}, gpio{gpio}
94     {
95         // If checking STATUS_VOUT or output voltage, verify PAGE was specified
96         if ((checkStatusVout || compareVoltageToLimit) && !page.has_value())
97         {
98             throw std::invalid_argument{"PMBus PAGE is required"};
99         }
100     }
101 
102     /**
103      * Returns the unique name for the rail.
104      *
105      * @return rail name
106      */
107     const std::string& getName() const
108     {
109         return name;
110     }
111 
112     /**
113      * Returns the D-Bus inventory path of a system component which must be
114      * present in order for the rail to be present.
115      *
116      * @return inventory path for presence detection
117      */
118     const std::optional<std::string>& getPresence() const
119     {
120         return presence;
121     }
122 
123     /**
124      * Returns the PMBus PAGE number of the rail.
125      *
126      * @return PAGE number for rail
127      */
128     const std::optional<uint8_t>& getPage() const
129     {
130         return page;
131     }
132 
133     /**
134      * Returns whether the rail is produced by a power supply.
135      *
136      * @return true if rail is produced by a power supply, false otherwise
137      */
138     bool isPowerSupplyRail() const
139     {
140         return isPsuRail;
141     }
142 
143     /**
144      * Returns whether the value of the PMBus STATUS_VOUT command is checked
145      * when determining the pgood status of the rail.
146      *
147      * @return true if STATUS_VOUT is checked, false otherwise
148      */
149     bool getCheckStatusVout() const
150     {
151         return checkStatusVout;
152     }
153 
154     /**
155      * Returns whether the output voltage should be compared to the undervoltage
156      * fault limit when determining the pgood status of the rail.
157      *
158      * @return true if output voltage is compared to limit, false otherwise
159      */
160     bool getCompareVoltageToLimit() const
161     {
162         return compareVoltageToLimit;
163     }
164 
165     /**
166      * Returns the GPIO to read to determine the pgood status of the rail.
167      *
168      * @return GPIO
169      */
170     const std::optional<GPIO>& getGPIO() const
171     {
172         return gpio;
173     }
174 
175   private:
176     /**
177      * Unique name for the rail.
178      */
179     std::string name{};
180 
181     /**
182      * D-Bus inventory path of a system component which must be present in order
183      * for the rail to be present.
184      *
185      * If not specified, the rail is assumed to always be present.
186      */
187     std::optional<std::string> presence{};
188 
189     /**
190      * PMBus PAGE number of the rail.
191      */
192     std::optional<uint8_t> page{};
193 
194     /**
195      * Specifies whether the rail is produced by a power supply.
196      */
197     bool isPsuRail{false};
198 
199     /**
200      * Specifies whether to check the value of the PMBus STATUS_VOUT command
201      * when determining the pgood status of the rail.
202      *
203      * If one of the error bits is set in STATUS_VOUT, the rail pgood will be
204      * considered false.
205      */
206     bool checkStatusVout{false};
207 
208     /**
209      * Specifies whether to compare the output voltage to the undervoltage fault
210      * limit when determining the pgood status of the rail.
211      *
212      * If the output voltage is below this limit, the rail pgood will be
213      * considered false.
214      *
215      * Uses the values of the PMBus READ_VOUT and VOUT_UV_FAULT_LIMIT commands.
216      */
217     bool compareVoltageToLimit{false};
218 
219     /**
220      * GPIO to read to determine the pgood status of the rail.
221      */
222     std::optional<GPIO> gpio{};
223 };
224 
225 } // namespace phosphor::power::sequencer
226