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      * Closes this device.
91      *
92      * Closes any interfaces that are open to this device.  Releases any other
93      * operating system resources associated with this device.
94      *
95      * @param services system services like error logging and the journal
96      */
97     void close(Services& services);
98 
99     /**
100      * Configure this device.
101      *
102      * Applies the configuration changes that are defined for this device, if
103      * any.
104      *
105      * Also configures the voltage rails produced by this device, if any.
106      *
107      * This method should be called during the boot before regulators are
108      * enabled.
109      *
110      * @param services system services like error logging and the journal
111      * @param system system that contains the chassis
112      * @param chassis chassis that contains this device
113      */
114     void configure(Services& services, System& system, Chassis& chassis);
115 
116     /**
117      * Returns the configuration changes to apply to this device, if any.
118      *
119      * @return Pointer to Configuration object.  Will equal nullptr if no
120      *         configuration changes are defined for this device.
121      */
122     const std::unique_ptr<Configuration>& getConfiguration() const
123     {
124         return configuration;
125     }
126 
127     /**
128      * Returns the Field-Replaceable Unit (FRU) for this device.
129      *
130      * Returns the D-Bus inventory path of the FRU.  If the device itself is not
131      * a FRU, returns the FRU that contains the device.
132      *
133      * @return FRU for this device
134      */
135     const std::string& getFRU() const
136     {
137         return fru;
138     }
139 
140     /**
141      * Returns the I2C interface to this device.
142      *
143      * @return I2C interface to device
144      */
145     i2c::I2CInterface& getI2CInterface()
146     {
147         return *i2cInterface;
148     }
149 
150     /**
151      * Returns the unique ID of this device.
152      *
153      * @return device ID
154      */
155     const std::string& getID() const
156     {
157         return id;
158     }
159 
160     /**
161      * Returns the presence detection for this device, if any.
162      *
163      * @return Pointer to PresenceDetection object.  Will equal nullptr if no
164      *         presence detection is defined for this device.
165      */
166     const std::unique_ptr<PresenceDetection>& getPresenceDetection() const
167     {
168         return presenceDetection;
169     }
170 
171     /**
172      * Returns the voltage rails produced by this device, if any.
173      *
174      * @return voltage rails
175      */
176     const std::vector<std::unique_ptr<Rail>>& getRails() const
177     {
178         return rails;
179     }
180 
181     /**
182      * Returns whether this device is a voltage regulator.
183      *
184      * @return true if device is a voltage regulator, false otherwise
185      */
186     bool isRegulator() const
187     {
188         return isRegulatorDevice;
189     }
190 
191     /**
192      * Monitors the sensors for the voltage rails produced by this device, if
193      * any.
194      *
195      * This method should be called once per second.
196      *
197      * @param services system services like error logging and the journal
198      * @param system system that contains the chassis
199      * @param chassis chassis that contains the device
200      */
201     void monitorSensors(Services& services, System& system, Chassis& chassis);
202 
203   private:
204     /**
205      * Unique ID of this device.
206      */
207     const std::string id{};
208 
209     /**
210      * Indicates whether this device is a voltage regulator.
211      */
212     const bool isRegulatorDevice{false};
213 
214     /**
215      * Field-Replaceable Unit (FRU) for this device.
216      *
217      * Set to the D-Bus inventory path of the FRU.  If the device itself is not
218      * a FRU, set to the FRU that contains the device.
219      */
220     const std::string fru{};
221 
222     /**
223      * I2C interface to this device.
224      */
225     std::unique_ptr<i2c::I2CInterface> i2cInterface{};
226 
227     /**
228      * Presence detection for this device, if any.  Set to nullptr if no
229      * presence detection is defined for this device.
230      */
231     std::unique_ptr<PresenceDetection> presenceDetection{};
232 
233     /**
234      * Configuration changes to apply to this device, if any.  Set to nullptr if
235      * no configuration changes are defined for this device.
236      */
237     std::unique_ptr<Configuration> configuration{};
238 
239     /**
240      * Voltage rails produced by this device, if any.  Vector is empty if no
241      * voltage rails are defined for this device.
242      */
243     std::vector<std::unique_ptr<Rail>> rails{};
244 };
245 
246 } // namespace phosphor::power::regulators
247