1 #pragma once 2 3 #include "common.hpp" 4 #include "gpio.hpp" 5 #include "xyz/openbmc_project/Chassis/Common/error.hpp" 6 7 #include <phosphor-logging/elog-errors.hpp> 8 // This is the base class for all the button interface types 9 // 10 class ButtonIface 11 { 12 13 public: 14 ButtonIface(sdbusplus::bus::bus& bus, EventPtr& event, 15 buttonConfig& buttonCfg, 16 sd_event_io_handler_t handler = ButtonIface::EventHandler) : 17 bus(bus), 18 event(event), config(buttonCfg), callbackHandler(handler) 19 { 20 int ret = -1; 21 22 // config group gpio based on the gpio defs read from the json file 23 ret = configGroupGpio(config); 24 25 if (ret < 0) 26 { 27 phosphor::logging::log<phosphor::logging::level::ERR>( 28 (getFormFactorType() + " : failed to config GPIO").c_str()); 29 throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error:: 30 IOError(); 31 } 32 } 33 virtual ~ButtonIface() 34 { 35 } 36 37 /** 38 * @brief This method is called from sd-event provided callback function 39 * callbackHandler if platform specific event handling is needed then a 40 * derived class instance with its specific evend handling logic along with 41 * init() function can be created to override the default event handling. 42 */ 43 44 virtual void handleEvent(sd_event_source* es, int fd, uint32_t revents) = 0; 45 static int EventHandler(sd_event_source* es, int fd, uint32_t revents, 46 void* userdata) 47 { 48 if (userdata) 49 { 50 51 ButtonIface* buttonIface = static_cast<ButtonIface*>(userdata); 52 buttonIface->handleEvent(es, fd, revents); 53 return 0; 54 } 55 } 56 57 std::string getFormFactorType() const 58 { 59 return config.formFactorName; 60 } 61 62 protected: 63 /** 64 * @brief oem specific initialization can be done under init function. 65 * if platform specific initialization is needed then 66 * a derived class instance with its own init function to override the 67 * default init() method can be added. 68 */ 69 70 virtual void init() 71 { 72 73 // initialize the button io fd from the buttonConfig 74 // which has fd stored when configGroupGpio is called 75 for (auto gpioCfg : config.gpios) 76 { 77 char buf; 78 int fd = gpioCfg.fd; 79 80 int ret = ::read(fd, &buf, sizeof(buf)); 81 if (ret < 0) 82 { 83 phosphor::logging::log<phosphor::logging::level::ERR>( 84 (getFormFactorType() + " : read error!").c_str()); 85 } 86 87 ret = sd_event_add_io(event.get(), nullptr, fd, EPOLLPRI, 88 callbackHandler, this); 89 if (ret < 0) 90 { 91 phosphor::logging::log<phosphor::logging::level::ERR>( 92 (getFormFactorType() + " : failed to add to event loop") 93 .c_str()); 94 ::closeGpio(fd); 95 throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error:: 96 IOError(); 97 } 98 } 99 } 100 /** 101 * @brief similar to init() oem specific deinitialization can be done under 102 * deInit function. if platform specific deinitialization is needed then a 103 * derived class instance with its own init function to override the default 104 * deinit() method can be added. 105 */ 106 virtual void deInit() 107 { 108 for (auto gpioCfg : config.gpios) 109 { 110 ::closeGpio(gpioCfg.fd); 111 } 112 } 113 114 buttonConfig config; 115 sdbusplus::bus::bus& bus; 116 EventPtr& event; 117 sd_event_io_handler_t callbackHandler; 118 }; 119