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