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