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 } 54 55 return 0; 56 } 57 58 std::string getFormFactorType() const 59 { 60 return config.formFactorName; 61 } 62 63 protected: 64 /** 65 * @brief oem specific initialization can be done under init function. 66 * if platform specific initialization is needed then 67 * a derived class instance with its own init function to override the 68 * default init() method can be added. 69 */ 70 71 virtual void init() 72 { 73 74 // initialize the button io fd from the buttonConfig 75 // which has fd stored when configGroupGpio is called 76 for (auto gpioCfg : config.gpios) 77 { 78 char buf; 79 int fd = gpioCfg.fd; 80 81 int ret = ::read(fd, &buf, sizeof(buf)); 82 if (ret < 0) 83 { 84 phosphor::logging::log<phosphor::logging::level::ERR>( 85 (getFormFactorType() + " : read error!").c_str()); 86 } 87 88 ret = sd_event_add_io(event.get(), nullptr, fd, EPOLLPRI, 89 callbackHandler, this); 90 if (ret < 0) 91 { 92 phosphor::logging::log<phosphor::logging::level::ERR>( 93 (getFormFactorType() + " : failed to add to event loop") 94 .c_str()); 95 ::closeGpio(fd); 96 throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error:: 97 IOError(); 98 } 99 } 100 } 101 /** 102 * @brief similar to init() oem specific deinitialization can be done under 103 * deInit function. if platform specific deinitialization is needed then a 104 * derived class instance with its own init function to override the default 105 * deinit() method can be added. 106 */ 107 virtual void deInit() 108 { 109 for (auto gpioCfg : config.gpios) 110 { 111 ::closeGpio(gpioCfg.fd); 112 } 113 } 114 115 buttonConfig config; 116 sdbusplus::bus::bus& bus; 117 EventPtr& event; 118 sd_event_io_handler_t callbackHandler; 119 }; 120