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/log.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 21 int Evdev::openDevice() 22 { 23 using namespace phosphor::logging; 24 25 auto fd = open(path.c_str(), O_RDONLY | O_NONBLOCK); 26 if (fd < 0) 27 { 28 log<level::ERR>("Failed to open device path", 29 entry("DEVICEPATH=%s", path.c_str()), 30 entry("ERRNO=%d", errno)); 31 elog<InternalFailure>(); 32 } 33 return fd; 34 } 35 36 // Initializes the event device with the fd 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 log<level::ERR>("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 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 log<level::ERR>("Failed to register callback handler", 69 entry("ERROR=%s", strerror(-rc))); 70 elog<InternalFailure>(); 71 } 72 } 73 74 } // namespace gpio 75 } // namespace phosphor 76