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},
76         isRegulatorDevice{isRegulator}, fru{fru},
77         i2cInterface{std::move(i2cInterface)},
78         presenceDetection{std::move(presenceDetection)},
79         configuration{std::move(configuration)},
80         phaseFaultDetection{std::move(phaseFaultDetection)},
81         rails{std::move(rails)}
82     {}
83 
84     /**
85      * Adds this Device object to the specified IDMap.
86      *
87      * Also adds any Rail objects in this Device to the IDMap.
88      *
89      * @param idMap mapping from IDs to the associated Device/Rail/Rule objects
90      */
91     void addToIDMap(IDMap& idMap);
92 
93     /**
94      * Clear any cached data about hardware devices.
95      */
96     void clearCache();
97 
98     /**
99      * Clears all error history.
100      *
101      * All data on previously logged errors will be deleted.  If errors occur
102      * again in the future they will be logged again.
103      *
104      * This method is normally called when the system is being powered on.
105      */
106     void clearErrorHistory();
107 
108     /**
109      * Closes this device.
110      *
111      * Closes any interfaces that are open to this device.  Releases any other
112      * operating system resources associated with this device.
113      *
114      * @param services system services like error logging and the journal
115      */
116     void close(Services& services);
117 
118     /**
119      * Configure this device.
120      *
121      * Applies the configuration changes that are defined for this device, if
122      * any.
123      *
124      * Also configures the voltage rails produced by this device, if any.
125      *
126      * This method should be called during the boot before regulators are
127      * enabled.
128      *
129      * @param services system services like error logging and the journal
130      * @param system system that contains the chassis
131      * @param chassis chassis that contains this device
132      */
133     void configure(Services& services, System& system, Chassis& chassis);
134 
135     /**
136      * Detect redundant phase faults in this device.
137      *
138      * Does nothing if phase fault detection is not defined for this device.
139      *
140      * This method should be called repeatedly based on a timer.
141      *
142      * @param services system services like error logging and the journal
143      * @param system system that contains the chassis
144      * @param chassis chassis that contains the device
145      */
146     void detectPhaseFaults(Services& services, System& system,
147                            Chassis& chassis);
148 
149     /**
150      * Returns the configuration changes to apply to this device, if any.
151      *
152      * @return Pointer to Configuration object.  Will equal nullptr if no
153      *         configuration changes are defined for this device.
154      */
getConfiguration() const155     const std::unique_ptr<Configuration>& getConfiguration() const
156     {
157         return configuration;
158     }
159 
160     /**
161      * Returns the Field-Replaceable Unit (FRU) for this device.
162      *
163      * Returns the D-Bus inventory path of the FRU.  If the device itself is not
164      * a FRU, returns the FRU that contains the device.
165      *
166      * @return FRU for this device
167      */
getFRU() const168     const std::string& getFRU() const
169     {
170         return fru;
171     }
172 
173     /**
174      * Returns the I2C interface to this device.
175      *
176      * @return I2C interface to device
177      */
getI2CInterface()178     i2c::I2CInterface& getI2CInterface()
179     {
180         return *i2cInterface;
181     }
182 
183     /**
184      * Returns the unique ID of this device.
185      *
186      * @return device ID
187      */
getID() const188     const std::string& getID() const
189     {
190         return id;
191     }
192 
193     /**
194      * Returns the phase fault detection for this device, if any.
195      *
196      * @return Pointer to PhaseFaultDetection object.  Will equal nullptr if no
197      *         phase fault detection is defined for this device.
198      */
getPhaseFaultDetection() const199     const std::unique_ptr<PhaseFaultDetection>& getPhaseFaultDetection() const
200     {
201         return phaseFaultDetection;
202     }
203 
204     /**
205      * Returns the presence detection for this device, if any.
206      *
207      * @return Pointer to PresenceDetection object.  Will equal nullptr if no
208      *         presence detection is defined for this device.
209      */
getPresenceDetection() const210     const std::unique_ptr<PresenceDetection>& getPresenceDetection() const
211     {
212         return presenceDetection;
213     }
214 
215     /**
216      * Returns the voltage rails produced by this device, if any.
217      *
218      * @return voltage rails
219      */
getRails() const220     const std::vector<std::unique_ptr<Rail>>& getRails() const
221     {
222         return rails;
223     }
224 
225     /**
226      * Returns whether this device is present.
227      *
228      * @return true if device is present, false otherwise
229      */
isPresent(Services & services,System & system,Chassis & chassis)230     bool isPresent(Services& services, System& system, Chassis& chassis)
231     {
232         if (presenceDetection)
233         {
234             // Execute presence detection to determine if device is present
235             return presenceDetection->execute(services, system, chassis, *this);
236         }
237         else
238         {
239             // No presence detection defined; assume device is present
240             return true;
241         }
242     }
243 
244     /**
245      * Returns whether this device is a voltage regulator.
246      *
247      * @return true if device is a voltage regulator, false otherwise
248      */
isRegulator() const249     bool isRegulator() const
250     {
251         return isRegulatorDevice;
252     }
253 
254     /**
255      * Monitors the sensors for the voltage rails produced by this device, if
256      * any.
257      *
258      * This method should be called repeatedly based on a timer.
259      *
260      * @param services system services like error logging and the journal
261      * @param system system that contains the chassis
262      * @param chassis chassis that contains the device
263      */
264     void monitorSensors(Services& services, System& system, Chassis& chassis);
265 
266   private:
267     /**
268      * Unique ID of this device.
269      */
270     const std::string id{};
271 
272     /**
273      * Indicates whether this device is a voltage regulator.
274      */
275     const bool isRegulatorDevice{false};
276 
277     /**
278      * Field-Replaceable Unit (FRU) for this device.
279      *
280      * Set to the D-Bus inventory path of the FRU.  If the device itself is not
281      * a FRU, set to the FRU that contains the device.
282      */
283     const std::string fru{};
284 
285     /**
286      * I2C interface to this device.
287      */
288     std::unique_ptr<i2c::I2CInterface> i2cInterface{};
289 
290     /**
291      * Presence detection for this device, if any.  Set to nullptr if no
292      * presence detection is defined for this device.
293      */
294     std::unique_ptr<PresenceDetection> presenceDetection{};
295 
296     /**
297      * Configuration changes to apply to this device, if any.  Set to nullptr if
298      * no configuration changes are defined for this device.
299      */
300     std::unique_ptr<Configuration> configuration{};
301 
302     /**
303      * Phase fault detection for this device, if any.  Set to nullptr if no
304      * phase fault detection is defined for this device.
305      */
306     std::unique_ptr<PhaseFaultDetection> phaseFaultDetection{};
307 
308     /**
309      * Voltage rails produced by this device, if any.  Vector is empty if no
310      * voltage rails are defined for this device.
311      */
312     std::vector<std::unique_ptr<Rail>> rails{};
313 };
314 
315 } // namespace phosphor::power::regulators
316