1 #pragma once
2 
3 #include "power_interface.hpp"
4 #include "utility.hpp"
5 
6 #include <gpiod.hpp>
7 #include <sdbusplus/bus.hpp>
8 #include <sdbusplus/bus/match.hpp>
9 #include <sdbusplus/message.hpp>
10 #include <sdbusplus/server/object.hpp>
11 #include <sdeventplus/clock.hpp>
12 #include <sdeventplus/event.hpp>
13 #include <sdeventplus/utility/timer.hpp>
14 
15 #include <chrono>
16 
17 namespace phosphor::power::sequencer
18 {
19 
20 using PowerObject = sdbusplus::server::object::object<PowerInterface>;
21 
22 /**
23  * @class PowerControl
24  * This class implements GPIO control of power on / off, and monitoring of the
25  * chassis power good.
26  */
27 class PowerControl : public PowerObject
28 {
29   public:
30     PowerControl() = delete;
31     PowerControl(const PowerControl&) = delete;
32     PowerControl& operator=(const PowerControl&) = delete;
33     PowerControl(PowerControl&&) = delete;
34     PowerControl& operator=(PowerControl&&) = delete;
35     ~PowerControl() = default;
36 
37     /**
38      * Creates a controller object for power on and off.
39      * @param[in] bus D-Bus bus object
40      * @param[in] event event object
41      */
42     PowerControl(sdbusplus::bus::bus& bus, const sdeventplus::Event& event);
43 
44     /** @copydoc PowerInterface::getPgood() */
45     int getPgood() const override;
46 
47     /** @copydoc PowerInterface::getPgoodTimeout() */
48     int getPgoodTimeout() const override;
49 
50     /** @copydoc PowerInterface::getState() */
51     int getState() const override;
52 
53     /**
54      * Callback function to handle interfacesAdded D-Bus signals
55      * @param msg Expanded sdbusplus message data
56      */
57     void interfacesAddedHandler(sdbusplus::message::message& msg);
58 
59     /** @copydoc PowerInterface::setPgoodTimeout() */
60     void setPgoodTimeout(int timeout) override;
61 
62     /** @copydoc PowerInterface::setState() */
63     void setState(int state) override;
64 
65   private:
66     /**
67      * The D-Bus bus object
68      */
69     sdbusplus::bus::bus& bus;
70 
71     /**
72      * Indicates if a state transistion is taking place
73      */
74     bool inStateTransition{false};
75 
76     /**
77      * The match to Entity Manager interfaces added.
78      */
79     std::unique_ptr<sdbusplus::bus::match_t> match;
80 
81     /**
82      * Power good
83      */
84     int pgood{0};
85 
86     /**
87      * GPIO line object for chassis power good
88      */
89     gpiod::line pgoodLine;
90 
91     /**
92      * Power good timeout constant
93      */
94     static constexpr std::chrono::seconds pgoodTimeout{
95         std::chrono::seconds(10)};
96 
97     /**
98      * Point in time at which power good timeout will take place
99      */
100     std::chrono::time_point<std::chrono::steady_clock> pgoodTimeoutTime;
101 
102     /**
103      * Poll interval constant
104      */
105     static constexpr std::chrono::milliseconds pollInterval{
106         std::chrono::milliseconds(3000)};
107 
108     /**
109      * GPIO line object for power-on / power-off control
110      */
111     gpiod::line powerControlLine;
112 
113     /**
114      * Power state
115      */
116     int state{0};
117 
118     /**
119      * Power good timeout
120      */
121     std::chrono::seconds timeout{pgoodTimeout};
122 
123     /**
124      * Timer to poll the pgood
125      */
126     sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> timer;
127 
128     /**
129      * Get the device properties
130      * @param[in] properties A map of property names and values
131      */
132     void getDeviceProperties(util::DbusPropertyMap& properties);
133 
134     /**
135      * Polling method for monitoring the system power good
136      */
137     void pollPgood();
138 
139     /**
140      * Set up power sequencer device
141      */
142     void setUpDevice();
143 
144     /**
145      * Set up GPIOs
146      */
147     void setUpGpio();
148 };
149 
150 } // namespace phosphor::power::sequencer
151