xref: /openbmc/phosphor-gpio-monitor/evdev.cpp (revision dace680fa404d7c02a68db105fd7b958b4681442)
1*dace680fSPatrick Venture #include "evdev.hpp"
2*dace680fSPatrick Venture 
3*dace680fSPatrick Venture #include "xyz/openbmc_project/Common/error.hpp"
4*dace680fSPatrick Venture 
5835dfb88SGunnar Mills #include <fcntl.h>
6*dace680fSPatrick Venture #include <libevdev/libevdev.h>
7*dace680fSPatrick Venture 
8*dace680fSPatrick Venture #include <phosphor-logging/elog-errors.hpp>
9835dfb88SGunnar Mills #include <phosphor-logging/elog.hpp>
10835dfb88SGunnar Mills #include <phosphor-logging/log.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
21835dfb88SGunnar Mills int Evdev::openDevice()
22835dfb88SGunnar Mills {
23835dfb88SGunnar Mills     using namespace phosphor::logging;
24835dfb88SGunnar Mills 
25835dfb88SGunnar Mills     auto fd = open(path.c_str(), O_RDONLY | O_NONBLOCK);
26835dfb88SGunnar Mills     if (fd < 0)
27835dfb88SGunnar Mills     {
28835dfb88SGunnar Mills         log<level::ERR>("Failed to open device path",
29835dfb88SGunnar Mills                         entry("DEVICEPATH=%s", path.c_str()),
30835dfb88SGunnar Mills                         entry("ERRNO=%d", errno));
31835dfb88SGunnar Mills         elog<InternalFailure>();
32835dfb88SGunnar Mills     }
33835dfb88SGunnar Mills     return fd;
34835dfb88SGunnar Mills }
35835dfb88SGunnar Mills 
36835dfb88SGunnar Mills // Initializes the event device with the fd
37835dfb88SGunnar Mills void Evdev::initEvDev()
38835dfb88SGunnar Mills {
39835dfb88SGunnar Mills     if (devicePtr)
40835dfb88SGunnar Mills     {
41835dfb88SGunnar Mills         // Init can be done only once per device
42835dfb88SGunnar Mills         return;
43835dfb88SGunnar Mills     }
44835dfb88SGunnar Mills 
45835dfb88SGunnar Mills     struct libevdev* evdev = nullptr;
46835dfb88SGunnar Mills     auto rc = libevdev_new_from_fd((fd)(), &evdev);
47835dfb88SGunnar Mills     if (rc < 0)
48835dfb88SGunnar Mills     {
49835dfb88SGunnar Mills         log<level::ERR>("Failed to initialize evdev");
50835dfb88SGunnar Mills         elog<InternalFailure>();
51835dfb88SGunnar Mills         return;
52835dfb88SGunnar Mills     }
53835dfb88SGunnar Mills 
54835dfb88SGunnar Mills     // Packing in the unique_ptr
55835dfb88SGunnar Mills     devicePtr.reset(evdev);
56835dfb88SGunnar Mills }
57835dfb88SGunnar Mills 
58835dfb88SGunnar Mills // Attaches the FD to event loop and registers the callback handler
59835dfb88SGunnar Mills void Evdev::registerCallback()
60835dfb88SGunnar Mills {
61835dfb88SGunnar Mills     decltype(eventSource.get()) sourcePtr = nullptr;
62*dace680fSPatrick Venture     auto rc = sd_event_add_io(event.get(), &sourcePtr, (fd)(), EPOLLIN,
63*dace680fSPatrick Venture                               callbackHandler, this);
64835dfb88SGunnar Mills     eventSource.reset(sourcePtr);
65835dfb88SGunnar Mills 
66835dfb88SGunnar Mills     if (rc < 0)
67835dfb88SGunnar Mills     {
68835dfb88SGunnar Mills         log<level::ERR>("Failed to register callback handler",
69835dfb88SGunnar Mills                         entry("ERROR=%s", strerror(-rc)));
70835dfb88SGunnar Mills         elog<InternalFailure>();
71835dfb88SGunnar Mills     }
72835dfb88SGunnar Mills }
73835dfb88SGunnar Mills 
74835dfb88SGunnar Mills } // namespace gpio
75835dfb88SGunnar Mills } // namespace phosphor
76