xref: /openbmc/phosphor-gpio-monitor/evdev.hpp (revision 8377d59c61c653a34df1c3c4ca72219eceb0b43b)
1835dfb88SGunnar Mills #pragma once
2835dfb88SGunnar Mills #include "file.hpp"
3835dfb88SGunnar Mills 
4dace680fSPatrick Venture #include <libevdev/libevdev.h>
5dace680fSPatrick Venture #include <systemd/sd-event.h>
6dace680fSPatrick Venture 
739084b4aSPatrick Williams #include <sdbusplus/message.hpp>
839084b4aSPatrick Williams 
9dace680fSPatrick Venture #include <map>
10dace680fSPatrick Venture #include <memory>
11dace680fSPatrick Venture #include <string>
12dace680fSPatrick Venture 
13835dfb88SGunnar Mills namespace phosphor
14835dfb88SGunnar Mills {
15835dfb88SGunnar Mills namespace gpio
16835dfb88SGunnar Mills {
17835dfb88SGunnar Mills 
18835dfb88SGunnar Mills /* Need a custom deleter for freeing up sd_event */
19835dfb88SGunnar Mills struct EventDeleter
20835dfb88SGunnar Mills {
operator ()phosphor::gpio::EventDeleter21835dfb88SGunnar Mills     void operator()(sd_event* event) const
22835dfb88SGunnar Mills     {
239b4c6cf7SGeorge Liu         sd_event_unref(event);
24835dfb88SGunnar Mills     }
25835dfb88SGunnar Mills };
26835dfb88SGunnar Mills using EventPtr = std::unique_ptr<sd_event, EventDeleter>;
27835dfb88SGunnar Mills 
28835dfb88SGunnar Mills /* Need a custom deleter for freeing up sd_event_source */
29835dfb88SGunnar Mills struct EventSourceDeleter
30835dfb88SGunnar Mills {
operator ()phosphor::gpio::EventSourceDeleter31835dfb88SGunnar Mills     void operator()(sd_event_source* eventSource) const
32835dfb88SGunnar Mills     {
339b4c6cf7SGeorge Liu         sd_event_source_unref(eventSource);
34835dfb88SGunnar Mills     }
35835dfb88SGunnar Mills };
36835dfb88SGunnar Mills using EventSourcePtr = std::unique_ptr<sd_event_source, EventSourceDeleter>;
37835dfb88SGunnar Mills 
38835dfb88SGunnar Mills /* Need a custom deleter for freeing up evdev struct */
39835dfb88SGunnar Mills struct FreeEvDev
40835dfb88SGunnar Mills {
operator ()phosphor::gpio::FreeEvDev41835dfb88SGunnar Mills     void operator()(struct libevdev* device) const
42835dfb88SGunnar Mills     {
43835dfb88SGunnar Mills         libevdev_free(device);
44835dfb88SGunnar Mills     }
45835dfb88SGunnar Mills };
46835dfb88SGunnar Mills using EvdevPtr = std::unique_ptr<struct libevdev, FreeEvDev>;
47835dfb88SGunnar Mills 
48835dfb88SGunnar Mills /** @class Evdev
49835dfb88SGunnar Mills  *  @brief Responsible for catching GPIO state changes conditions and taking
50835dfb88SGunnar Mills  *  actions
51835dfb88SGunnar Mills  */
52835dfb88SGunnar Mills class Evdev
53835dfb88SGunnar Mills {
54835dfb88SGunnar Mills     using Property = std::string;
553ce88a7bSPatrick Williams     using Value = std::variant<bool, std::string>;
56835dfb88SGunnar Mills     // Association between property and its value
57835dfb88SGunnar Mills     using PropertyMap = std::map<Property, Value>;
58835dfb88SGunnar Mills     using Interface = std::string;
59835dfb88SGunnar Mills     // Association between interface and the D-Bus property
60835dfb88SGunnar Mills     using InterfaceMap = std::map<Interface, PropertyMap>;
61835dfb88SGunnar Mills     using Object = sdbusplus::message::object_path;
62835dfb88SGunnar Mills     // Association between object and the interface
63835dfb88SGunnar Mills     using ObjectMap = std::map<Object, InterfaceMap>;
64835dfb88SGunnar Mills 
65835dfb88SGunnar Mills   public:
66835dfb88SGunnar Mills     Evdev() = delete;
67835dfb88SGunnar Mills     ~Evdev() = default;
68835dfb88SGunnar Mills     Evdev(const Evdev&) = delete;
69835dfb88SGunnar Mills     Evdev& operator=(const Evdev&) = delete;
70835dfb88SGunnar Mills     Evdev(Evdev&&) = delete;
71835dfb88SGunnar Mills     Evdev& operator=(Evdev&&) = delete;
72835dfb88SGunnar Mills 
73835dfb88SGunnar Mills     /** @brief Constructs Evdev object.
74835dfb88SGunnar Mills      *
75835dfb88SGunnar Mills      *  @param[in] path      - Device path to read for GPIO pin state
76835dfb88SGunnar Mills      *  @param[in] key       - GPIO key to monitor
77835dfb88SGunnar Mills      *  @param[in] event     - sd_event handler
789925857aSGunnar Mills      *  @param[in] handler   - IO callback handler.
79835dfb88SGunnar Mills      *  @param[in] useEvDev  - Whether to use EvDev to retrieve events
80835dfb88SGunnar Mills      */
Evdev(const std::string & path,const unsigned int key,EventPtr & event,sd_event_io_handler_t handler,bool useEvDev=true)81dace680fSPatrick Venture     Evdev(const std::string& path, const unsigned int key, EventPtr& event,
82dace680fSPatrick Venture           sd_event_io_handler_t handler, bool useEvDev = true) :
83*8377d59cSPatrick Williams         path(path), key(key), event(event), callbackHandler(handler),
84*8377d59cSPatrick Williams         fd(openDevice())
85835dfb88SGunnar Mills 
86835dfb88SGunnar Mills     {
87835dfb88SGunnar Mills         if (useEvDev)
88835dfb88SGunnar Mills         {
89835dfb88SGunnar Mills             // If we are asked to use EvDev, do that initialization.
90835dfb88SGunnar Mills             initEvDev();
91835dfb88SGunnar Mills         }
92835dfb88SGunnar Mills 
93835dfb88SGunnar Mills         // Register callback handler when FD has some data
94835dfb88SGunnar Mills         registerCallback();
95835dfb88SGunnar Mills     }
96835dfb88SGunnar Mills 
97835dfb88SGunnar Mills   protected:
98835dfb88SGunnar Mills     /** @brief Device path to read for GPIO pin state */
99835dfb88SGunnar Mills     const std::string path;
100835dfb88SGunnar Mills 
101835dfb88SGunnar Mills     /** @brief GPIO key to monitor */
102835dfb88SGunnar Mills     const unsigned int key;
103835dfb88SGunnar Mills 
104835dfb88SGunnar Mills     /** @brief Event structure */
105835dfb88SGunnar Mills     EvdevPtr devicePtr;
106835dfb88SGunnar Mills 
107835dfb88SGunnar Mills     /** @brief Monitor to sd_event */
108835dfb88SGunnar Mills     EventPtr& event;
109835dfb88SGunnar Mills 
110835dfb88SGunnar Mills     /** @brief Callback handler when the FD has some data */
111835dfb88SGunnar Mills     sd_event_io_handler_t callbackHandler;
112835dfb88SGunnar Mills 
113835dfb88SGunnar Mills     /** @brief event source */
114835dfb88SGunnar Mills     EventSourcePtr eventSource;
115835dfb88SGunnar Mills 
116835dfb88SGunnar Mills     /** @brief Opens the device and populates the descriptor */
117835dfb88SGunnar Mills     int openDevice();
118835dfb88SGunnar Mills 
119835dfb88SGunnar Mills     /** @brief attaches FD to events and sets up callback handler */
120835dfb88SGunnar Mills     void registerCallback();
121835dfb88SGunnar Mills 
122835dfb88SGunnar Mills     /** @brief File descriptor manager */
123835dfb88SGunnar Mills     FileDescriptor fd;
124835dfb88SGunnar Mills 
125835dfb88SGunnar Mills     /** @brief Initializes evdev handle with the fd */
126835dfb88SGunnar Mills     void initEvDev();
127835dfb88SGunnar Mills };
128835dfb88SGunnar Mills 
129835dfb88SGunnar Mills } // namespace gpio
130835dfb88SGunnar Mills } // namespace phosphor
131