xref: /openbmc/phosphor-gpio-monitor/evdev.cpp (revision 2a8848c6fb8e2b98e79baa441d4381a52a1df719)
1dace680fSPatrick Venture #include "evdev.hpp"
2dace680fSPatrick Venture 
3dace680fSPatrick Venture #include "xyz/openbmc_project/Common/error.hpp"
4dace680fSPatrick Venture 
5835dfb88SGunnar Mills #include <fcntl.h>
6dace680fSPatrick Venture #include <libevdev/libevdev.h>
7dace680fSPatrick Venture 
8dace680fSPatrick Venture #include <phosphor-logging/elog-errors.hpp>
9835dfb88SGunnar Mills #include <phosphor-logging/elog.hpp>
10*2a8848c6SGeorge Liu #include <phosphor-logging/lg2.hpp>
11835dfb88SGunnar Mills 
12835dfb88SGunnar Mills namespace phosphor
13835dfb88SGunnar Mills {
14835dfb88SGunnar Mills namespace gpio
15835dfb88SGunnar Mills {
16835dfb88SGunnar Mills 
17835dfb88SGunnar Mills using namespace phosphor::logging;
18835dfb88SGunnar Mills using namespace sdbusplus::xyz::openbmc_project::Common::Error;
19835dfb88SGunnar Mills 
20835dfb88SGunnar Mills // Populate the file descriptor for passed in device
openDevice()21835dfb88SGunnar Mills int Evdev::openDevice()
22835dfb88SGunnar Mills {
23835dfb88SGunnar Mills     auto fd = open(path.c_str(), O_RDONLY | O_NONBLOCK);
24835dfb88SGunnar Mills     if (fd < 0)
25835dfb88SGunnar Mills     {
26*2a8848c6SGeorge Liu         lg2::error("Failed to open {DEVICEPATH}: {ERRNO}", "DEVICEPATH", path,
27*2a8848c6SGeorge Liu                    "ERRNO", errno);
28835dfb88SGunnar Mills         elog<InternalFailure>();
29835dfb88SGunnar Mills     }
30835dfb88SGunnar Mills     return fd;
31835dfb88SGunnar Mills }
32835dfb88SGunnar Mills 
33835dfb88SGunnar Mills // Initializes the event device with the fd
initEvDev()34835dfb88SGunnar Mills void Evdev::initEvDev()
35835dfb88SGunnar Mills {
36835dfb88SGunnar Mills     if (devicePtr)
37835dfb88SGunnar Mills     {
38835dfb88SGunnar Mills         // Init can be done only once per device
39835dfb88SGunnar Mills         return;
40835dfb88SGunnar Mills     }
41835dfb88SGunnar Mills 
42835dfb88SGunnar Mills     struct libevdev* evdev = nullptr;
43835dfb88SGunnar Mills     auto rc = libevdev_new_from_fd((fd)(), &evdev);
44835dfb88SGunnar Mills     if (rc < 0)
45835dfb88SGunnar Mills     {
46*2a8848c6SGeorge Liu         lg2::error("Failed to initialize evdev");
47835dfb88SGunnar Mills         elog<InternalFailure>();
48835dfb88SGunnar Mills         return;
49835dfb88SGunnar Mills     }
50835dfb88SGunnar Mills 
51835dfb88SGunnar Mills     // Packing in the unique_ptr
52835dfb88SGunnar Mills     devicePtr.reset(evdev);
53835dfb88SGunnar Mills }
54835dfb88SGunnar Mills 
55835dfb88SGunnar Mills // Attaches the FD to event loop and registers the callback handler
registerCallback()56835dfb88SGunnar Mills void Evdev::registerCallback()
57835dfb88SGunnar Mills {
58835dfb88SGunnar Mills     decltype(eventSource.get()) sourcePtr = nullptr;
59dace680fSPatrick Venture     auto rc = sd_event_add_io(event.get(), &sourcePtr, (fd)(), EPOLLIN,
60dace680fSPatrick Venture                               callbackHandler, this);
61835dfb88SGunnar Mills     eventSource.reset(sourcePtr);
62835dfb88SGunnar Mills 
63835dfb88SGunnar Mills     if (rc < 0)
64835dfb88SGunnar Mills     {
65*2a8848c6SGeorge Liu         lg2::error("Failed to register callback handler: {RC}", "RC", rc);
66835dfb88SGunnar Mills         elog<InternalFailure>();
67835dfb88SGunnar Mills     }
68835dfb88SGunnar Mills }
69835dfb88SGunnar Mills 
70835dfb88SGunnar Mills } // namespace gpio
71835dfb88SGunnar Mills } // namespace phosphor
72