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