1 #include "evdev.hpp"
2 
3 #include "xyz/openbmc_project/Common/error.hpp"
4 
5 #include <fcntl.h>
6 #include <libevdev/libevdev.h>
7 
8 #include <phosphor-logging/elog-errors.hpp>
9 #include <phosphor-logging/elog.hpp>
10 #include <phosphor-logging/lg2.hpp>
11 
12 namespace phosphor
13 {
14 namespace gpio
15 {
16 
17 using namespace phosphor::logging;
18 using namespace sdbusplus::xyz::openbmc_project::Common::Error;
19 
20 // Populate the file descriptor for passed in device
openDevice()21 int Evdev::openDevice()
22 {
23     auto fd = open(path.c_str(), O_RDONLY | O_NONBLOCK);
24     if (fd < 0)
25     {
26         lg2::error("Failed to open {DEVICEPATH}: {ERRNO}", "DEVICEPATH", path,
27                    "ERRNO", errno);
28         elog<InternalFailure>();
29     }
30     return fd;
31 }
32 
33 // Initializes the event device with the fd
initEvDev()34 void Evdev::initEvDev()
35 {
36     if (devicePtr)
37     {
38         // Init can be done only once per device
39         return;
40     }
41 
42     struct libevdev* evdev = nullptr;
43     auto rc = libevdev_new_from_fd((fd)(), &evdev);
44     if (rc < 0)
45     {
46         lg2::error("Failed to initialize evdev");
47         elog<InternalFailure>();
48         return;
49     }
50 
51     // Packing in the unique_ptr
52     devicePtr.reset(evdev);
53 }
54 
55 // Attaches the FD to event loop and registers the callback handler
registerCallback()56 void Evdev::registerCallback()
57 {
58     decltype(eventSource.get()) sourcePtr = nullptr;
59     auto rc = sd_event_add_io(event.get(), &sourcePtr, (fd)(), EPOLLIN,
60                               callbackHandler, this);
61     eventSource.reset(sourcePtr);
62 
63     if (rc < 0)
64     {
65         lg2::error("Failed to register callback handler: {RC}", "RC", rc);
66         elog<InternalFailure>();
67     }
68 }
69 
70 } // namespace gpio
71 } // namespace phosphor
72