1 /**
2  * Copyright © 2019 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 "configuration.hpp"
19 #include "i2c_interface.hpp"
20 #include "id_map.hpp"
21 #include "phase_fault_detection.hpp"
22 #include "presence_detection.hpp"
23 #include "rail.hpp"
24 #include "services.hpp"
25 
26 #include <memory>
27 #include <string>
28 #include <utility>
29 #include <vector>
30 
31 namespace phosphor::power::regulators
32 {
33 
34 // Forward declarations to avoid circular dependencies
35 class Chassis;
36 class System;
37 
38 /**
39  * @class Device
40  *
41  * A hardware device, such as a voltage regulator or I/O expander.
42  */
43 class Device
44 {
45   public:
46     // Specify which compiler-generated methods we want
47     Device() = delete;
48     Device(const Device&) = delete;
49     Device(Device&&) = delete;
50     Device& operator=(const Device&) = delete;
51     Device& operator=(Device&&) = delete;
52     ~Device() = default;
53 
54     /**
55      * Constructor.
56      *
57      * @param id unique device ID
58      * @param isRegulator indicates whether this device is a voltage regulator
59      * @param fru Field-Replaceable Unit (FRU) for this device
60      * @param i2cInterface I2C interface to this device
61      * @param presenceDetection presence detection for this device, if any
62      * @param configuration configuration changes to apply to this device, if
63      *                      any
64      * @param phaseFaultDetection phase fault detection for this device, if any
65      * @param rails voltage rails produced by this device, if any
66      */
Device(const std::string & id,bool isRegulator,const std::string & fru,std::unique_ptr<i2c::I2CInterface> i2cInterface,std::unique_ptr<PresenceDetection> presenceDetection=nullptr,std::unique_ptr<Configuration> configuration=nullptr,std::unique_ptr<PhaseFaultDetection> phaseFaultDetection=nullptr,std::vector<std::unique_ptr<Rail>> rails=std::vector<std::unique_ptr<Rail>>{})67     explicit Device(
68         const std::string& id, bool isRegulator, const std::string& fru,
69         std::unique_ptr<i2c::I2CInterface> i2cInterface,
70         std::unique_ptr<PresenceDetection> presenceDetection = nullptr,
71         std::unique_ptr<Configuration> configuration = nullptr,
72         std::unique_ptr<PhaseFaultDetection> phaseFaultDetection = nullptr,
73         std::vector<std::unique_ptr<Rail>> rails =
74             std::vector<std::unique_ptr<Rail>>{}) :
75         id{id}, isRegulatorDevice{isRegulator}, fru{fru},
76         i2cInterface{std::move(i2cInterface)},
77         presenceDetection{std::move(presenceDetection)},
78         configuration{std::move(configuration)},
79         phaseFaultDetection{std::move(phaseFaultDetection)},
80         rails{std::move(rails)}
81     {}
82 
83     /**
84      * Adds this Device object to the specified IDMap.
85      *
86      * Also adds any Rail objects in this Device to the IDMap.
87      *
88      * @param idMap mapping from IDs to the associated Device/Rail/Rule objects
89      */
90     void addToIDMap(IDMap& idMap);
91 
92     /**
93      * Clear any cached data about hardware devices.
94      */
95     void clearCache();
96 
97     /**
98      * Clears all error history.
99      *
100      * All data on previously logged errors will be deleted.  If errors occur
101      * again in the future they will be logged again.
102      *
103      * This method is normally called when the system is being powered on.
104      */
105     void clearErrorHistory();
106 
107     /**
108      * Closes this device.
109      *
110      * Closes any interfaces that are open to this device.  Releases any other
111      * operating system resources associated with this device.
112      *
113      * @param services system services like error logging and the journal
114      */
115     void close(Services& services);
116 
117     /**
118      * Configure this device.
119      *
120      * Applies the configuration changes that are defined for this device, if
121      * any.
122      *
123      * Also configures the voltage rails produced by this device, if any.
124      *
125      * This method should be called during the boot before regulators are
126      * enabled.
127      *
128      * @param services system services like error logging and the journal
129      * @param system system that contains the chassis
130      * @param chassis chassis that contains this device
131      */
132     void configure(Services& services, System& system, Chassis& chassis);
133 
134     /**
135      * Detect redundant phase faults in this device.
136      *
137      * Does nothing if phase fault detection is not defined for this device.
138      *
139      * This method should be called repeatedly based on a timer.
140      *
141      * @param services system services like error logging and the journal
142      * @param system system that contains the chassis
143      * @param chassis chassis that contains the device
144      */
145     void detectPhaseFaults(Services& services, System& system,
146                            Chassis& chassis);
147 
148     /**
149      * Returns the configuration changes to apply to this device, if any.
150      *
151      * @return Pointer to Configuration object.  Will equal nullptr if no
152      *         configuration changes are defined for this device.
153      */
getConfiguration() const154     const std::unique_ptr<Configuration>& getConfiguration() const
155     {
156         return configuration;
157     }
158 
159     /**
160      * Returns the Field-Replaceable Unit (FRU) for this device.
161      *
162      * Returns the D-Bus inventory path of the FRU.  If the device itself is not
163      * a FRU, returns the FRU that contains the device.
164      *
165      * @return FRU for this device
166      */
getFRU() const167     const std::string& getFRU() const
168     {
169         return fru;
170     }
171 
172     /**
173      * Returns the I2C interface to this device.
174      *
175      * @return I2C interface to device
176      */
getI2CInterface()177     i2c::I2CInterface& getI2CInterface()
178     {
179         return *i2cInterface;
180     }
181 
182     /**
183      * Returns the unique ID of this device.
184      *
185      * @return device ID
186      */
getID() const187     const std::string& getID() const
188     {
189         return id;
190     }
191 
192     /**
193      * Returns the phase fault detection for this device, if any.
194      *
195      * @return Pointer to PhaseFaultDetection object.  Will equal nullptr if no
196      *         phase fault detection is defined for this device.
197      */
getPhaseFaultDetection() const198     const std::unique_ptr<PhaseFaultDetection>& getPhaseFaultDetection() const
199     {
200         return phaseFaultDetection;
201     }
202 
203     /**
204      * Returns the presence detection for this device, if any.
205      *
206      * @return Pointer to PresenceDetection object.  Will equal nullptr if no
207      *         presence detection is defined for this device.
208      */
getPresenceDetection() const209     const std::unique_ptr<PresenceDetection>& getPresenceDetection() const
210     {
211         return presenceDetection;
212     }
213 
214     /**
215      * Returns the voltage rails produced by this device, if any.
216      *
217      * @return voltage rails
218      */
getRails() const219     const std::vector<std::unique_ptr<Rail>>& getRails() const
220     {
221         return rails;
222     }
223 
224     /**
225      * Returns whether this device is present.
226      *
227      * @return true if device is present, false otherwise
228      */
isPresent(Services & services,System & system,Chassis & chassis)229     bool isPresent(Services& services, System& system, Chassis& chassis)
230     {
231         if (presenceDetection)
232         {
233             // Execute presence detection to determine if device is present
234             return presenceDetection->execute(services, system, chassis, *this);
235         }
236         else
237         {
238             // No presence detection defined; assume device is present
239             return true;
240         }
241     }
242 
243     /**
244      * Returns whether this device is a voltage regulator.
245      *
246      * @return true if device is a voltage regulator, false otherwise
247      */
isRegulator() const248     bool isRegulator() const
249     {
250         return isRegulatorDevice;
251     }
252 
253     /**
254      * Monitors the sensors for the voltage rails produced by this device, if
255      * any.
256      *
257      * This method should be called repeatedly based on a timer.
258      *
259      * @param services system services like error logging and the journal
260      * @param system system that contains the chassis
261      * @param chassis chassis that contains the device
262      */
263     void monitorSensors(Services& services, System& system, Chassis& chassis);
264 
265   private:
266     /**
267      * Unique ID of this device.
268      */
269     const std::string id{};
270 
271     /**
272      * Indicates whether this device is a voltage regulator.
273      */
274     const bool isRegulatorDevice{false};
275 
276     /**
277      * Field-Replaceable Unit (FRU) for this device.
278      *
279      * Set to the D-Bus inventory path of the FRU.  If the device itself is not
280      * a FRU, set to the FRU that contains the device.
281      */
282     const std::string fru{};
283 
284     /**
285      * I2C interface to this device.
286      */
287     std::unique_ptr<i2c::I2CInterface> i2cInterface{};
288 
289     /**
290      * Presence detection for this device, if any.  Set to nullptr if no
291      * presence detection is defined for this device.
292      */
293     std::unique_ptr<PresenceDetection> presenceDetection{};
294 
295     /**
296      * Configuration changes to apply to this device, if any.  Set to nullptr if
297      * no configuration changes are defined for this device.
298      */
299     std::unique_ptr<Configuration> configuration{};
300 
301     /**
302      * Phase fault detection for this device, if any.  Set to nullptr if no
303      * phase fault detection is defined for this device.
304      */
305     std::unique_ptr<PhaseFaultDetection> phaseFaultDetection{};
306 
307     /**
308      * Voltage rails produced by this device, if any.  Vector is empty if no
309      * voltage rails are defined for this device.
310      */
311     std::vector<std::unique_ptr<Rail>> rails{};
312 };
313 
314 } // namespace phosphor::power::regulators
315