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