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