xref: /openbmc/phosphor-power/phosphor-power-sequencer/src/gpio.hpp (revision fdaa950b078e162b99dd1358f66b942a26b3bd19)
1 /**
2  * Copyright © 2025 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 <gpiod.hpp>
19 
20 #include <string>
21 
22 namespace phosphor::power::sequencer
23 {
24 
25 /**
26  * @class GPIO
27  *
28  * Abstract base class for a General-Purpose Input/Output pin.
29  */
30 class GPIO
31 {
32   public:
33     GPIO() = default;
34     GPIO(const GPIO&) = delete;
35     GPIO(GPIO&&) = delete;
36     GPIO& operator=(const GPIO&) = delete;
37     GPIO& operator=(GPIO&&) = delete;
38     virtual ~GPIO() = default;
39 
40     /**
41      * Request ownership of the GPIO for reading.
42      *
43      * Throws an exception if an error occurs.
44      *
45      * This is required before getting the GPIO value.
46      */
47     virtual void requestRead() = 0;
48 
49     /**
50      * Request ownership of the GPIO for writing.
51      *
52      * Throws an exception if an error occurs.
53      *
54      * This is required before setting the GPIO value.
55      *
56      * @param initialValue initial value GPIO will be set to
57      */
58     virtual void requestWrite(int initialValue) = 0;
59 
60     /**
61      * Gets the value of the GPIO.
62      *
63      * Throws an exception if an error occurs.
64      *
65      * @return 0 or 1
66      */
67     virtual int getValue() = 0;
68 
69     /**
70      * Sets the value of the GPIO.
71      *
72      * Throws an exception if an error occurs.
73      *
74      * @param value new value (0 or 1)
75      */
76     virtual void setValue(int value) = 0;
77 
78     /**
79      * Release ownership of the GPIO.
80      *
81      * Throws an exception if an error occurs.
82      */
83     virtual void release() = 0;
84 };
85 
86 /**
87  * @class BMCGPIO
88  *
89  * Implementation of the GPIO interface using the standard BMC API (libgpiod).
90  */
91 class BMCGPIO : public GPIO
92 {
93   public:
94     BMCGPIO() = delete;
95     BMCGPIO(const BMCGPIO&) = delete;
96     BMCGPIO(BMCGPIO&&) = delete;
97     BMCGPIO& operator=(const BMCGPIO&) = delete;
98     BMCGPIO& operator=(BMCGPIO&&) = delete;
99 
100     /**
101      * Constructor.
102      *
103      * Throws an exception if a GPIO with the specified name cannot be found.
104      *
105      * @param name GPIO name
106      */
BMCGPIO(const std::string & name)107     explicit BMCGPIO(const std::string& name)
108     {
109         line = gpiod::find_line(name);
110         if (!line)
111         {
112             throw std::invalid_argument{"Invalid GPIO name: " + name};
113         }
114     }
115 
116     /**
117      * Destructor.
118      *
119      * If requestRead() or requestWrite() was called to claim ownership of the
120      * GPIO, ownership will be automatically released due to the gpiod::line
121      * destructor.
122      */
123     virtual ~BMCGPIO() = default;
124 
125     /** @copydoc GPIO::requestRead() */
requestRead()126     virtual void requestRead() override
127     {
128         line.request({consumer, gpiod::line_request::DIRECTION_INPUT, 0});
129     }
130 
131     /** @copydoc GPIO::requestWrite() */
requestWrite(int initialValue)132     virtual void requestWrite(int initialValue) override
133     {
134         line.request({consumer, gpiod::line_request::DIRECTION_OUTPUT, 0},
135                      initialValue);
136     }
137 
138     /** @copydoc GPIO::getValue() */
getValue()139     virtual int getValue() override
140     {
141         return line.get_value();
142     }
143 
144     /** @copydoc GPIO::setValue() */
setValue(int value)145     virtual void setValue(int value) override
146     {
147         line.set_value(value);
148     }
149 
150     /** @copydoc GPIO::release() */
release()151     virtual void release() override
152     {
153         line.release();
154     }
155 
156   private:
157     /**
158      * Consumer value specified when requesting the GPIO line.
159      */
160     inline static const std::string consumer{"phosphor-power-control"};
161 
162     /**
163      * GPIO line to access the pin.
164      */
165     gpiod::line line;
166 };
167 
168 } // namespace phosphor::power::sequencer
169