blob: f37a29c0da64917b1defd6bc17735cc74f090f80 [file] [log] [blame]
Naveen Mosesa1af3292021-12-15 11:47:01 +05301#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//
10class 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);
Naveen Mosesa1af3292021-12-15 11:47:01 +053053 }
Naveen Moses3bd1cfc2022-02-14 18:04:20 +053054
55 return 0;
Naveen Mosesa1af3292021-12-15 11:47:01 +053056 }
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};