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