1 #include <libevdev/libevdev.h> 2 #include <fcntl.h> 3 #include <phosphor-logging/elog.hpp> 4 #include <phosphor-logging/log.hpp> 5 #include <phosphor-logging/elog-errors.hpp> 6 #include "xyz/openbmc_project/Common/error.hpp" 7 #include "evdev.hpp" 8 9 namespace phosphor 10 { 11 namespace gpio 12 { 13 14 using namespace phosphor::logging; 15 using namespace sdbusplus::xyz::openbmc_project::Common::Error; 16 17 // Populate the file descriptor for passed in device 18 int Evdev::openDevice() 19 { 20 using namespace phosphor::logging; 21 22 auto fd = open(path.c_str(), O_RDONLY | O_NONBLOCK); 23 if (fd < 0) 24 { 25 log<level::ERR>("Failed to open device path", 26 entry("DEVICEPATH=%s", path.c_str()), 27 entry("ERRNO=%d", errno)); 28 elog<InternalFailure>(); 29 } 30 return fd; 31 } 32 33 // Initializes the event device with the fd 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 log<level::ERR>("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 56 void Evdev::registerCallback() 57 { 58 decltype(eventSource.get()) sourcePtr = nullptr; 59 auto rc = sd_event_add_io(event.get(), &sourcePtr, (fd)(), 60 EPOLLIN, callbackHandler, this); 61 eventSource.reset(sourcePtr); 62 63 if (rc < 0) 64 { 65 log<level::ERR>("Failed to register callback handler", 66 entry("ERROR=%s", strerror(-rc))); 67 elog<InternalFailure>(); 68 } 69 } 70 71 } // namespace gpio 72 } // namespace phosphor 73