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