blob: 0b8cd478139e98bec28d77b28fb34c48a53f6e10 [file] [log] [blame]
Naveen Mosesa1af3292021-12-15 11:47:01 +05301#pragma once
2
Delphine CC Chiuccd7db02023-02-09 14:48:53 +08003#include "button_config.hpp"
Naveen Mosesa1af3292021-12-15 11:47:01 +05304#include "common.hpp"
Naveen Mosesa1af3292021-12-15 11:47:01 +05305#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{
Naveen Mosesa1af3292021-12-15 11:47:01 +053012 public:
Delphine CC Chiuccd7db02023-02-09 14:48:53 +080013 ButtonIface(sdbusplus::bus_t& bus, EventPtr& event, ButtonConfig& buttonCfg,
Naveen Mosesa1af3292021-12-15 11:47:01 +053014 sd_event_io_handler_t handler = ButtonIface::EventHandler) :
Patrick Williamsd36b6b12024-08-16 15:20:34 -040015 bus(bus), event(event), config(buttonCfg), callbackHandler(handler)
Naveen Mosesa1af3292021-12-15 11:47:01 +053016 {
17 int ret = -1;
Delphine CC Chiuccd7db02023-02-09 14:48:53 +080018 std::string configType;
Naveen Mosesa1af3292021-12-15 11:47:01 +053019
Delphine CC Chiuccd7db02023-02-09 14:48:53 +080020 // config group gpio or cpld based on the defs read from the json file
21 if (buttonCfg.type == ConfigType::gpio)
22 {
23 configType = "GPIO";
24 ret = configGroupGpio(config);
25 }
26 else if (buttonCfg.type == ConfigType::cpld)
27 {
28 configType = "CPLD";
29 ret = configCpld(config);
30 }
Naveen Mosesa1af3292021-12-15 11:47:01 +053031
32 if (ret < 0)
33 {
34 phosphor::logging::log<phosphor::logging::level::ERR>(
Delphine CC Chiuccd7db02023-02-09 14:48:53 +080035 (getFormFactorType() + " : failed to config " + configType)
36 .c_str());
Naveen Mosesa1af3292021-12-15 11:47:01 +053037 throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
38 IOError();
39 }
40 }
Patrick Williams0d038f52023-05-10 07:50:40 -050041 virtual ~ButtonIface() {}
Naveen Mosesa1af3292021-12-15 11:47:01 +053042
43 /**
44 * @brief This method is called from sd-event provided callback function
45 * callbackHandler if platform specific event handling is needed then a
46 * derived class instance with its specific evend handling logic along with
47 * init() function can be created to override the default event handling.
48 */
49
50 virtual void handleEvent(sd_event_source* es, int fd, uint32_t revents) = 0;
51 static int EventHandler(sd_event_source* es, int fd, uint32_t revents,
52 void* userdata)
53 {
54 if (userdata)
55 {
Naveen Mosesa1af3292021-12-15 11:47:01 +053056 ButtonIface* buttonIface = static_cast<ButtonIface*>(userdata);
57 buttonIface->handleEvent(es, fd, revents);
Naveen Mosesa1af3292021-12-15 11:47:01 +053058 }
Naveen Moses3bd1cfc2022-02-14 18:04:20 +053059
60 return 0;
Naveen Mosesa1af3292021-12-15 11:47:01 +053061 }
62
63 std::string getFormFactorType() const
64 {
65 return config.formFactorName;
66 }
67
68 protected:
69 /**
70 * @brief oem specific initialization can be done under init function.
71 * if platform specific initialization is needed then
72 * a derived class instance with its own init function to override the
73 * default init() method can be added.
74 */
75
76 virtual void init()
77 {
Delphine CC Chiuccd7db02023-02-09 14:48:53 +080078 // initialize the button io fd from the ButtonConfig
79 // which has fd stored when configGroupGpio or configCpld is called
80 for (auto fd : config.fds)
Naveen Mosesa1af3292021-12-15 11:47:01 +053081 {
82 char buf;
Naveen Mosesa1af3292021-12-15 11:47:01 +053083
84 int ret = ::read(fd, &buf, sizeof(buf));
85 if (ret < 0)
86 {
87 phosphor::logging::log<phosphor::logging::level::ERR>(
88 (getFormFactorType() + " : read error!").c_str());
89 }
90
91 ret = sd_event_add_io(event.get(), nullptr, fd, EPOLLPRI,
92 callbackHandler, this);
93 if (ret < 0)
94 {
95 phosphor::logging::log<phosphor::logging::level::ERR>(
96 (getFormFactorType() + " : failed to add to event loop")
97 .c_str());
Delphine CC Chiuccd7db02023-02-09 14:48:53 +080098 if (fd > 0)
99 {
100 ::close(fd);
101 }
Naveen Mosesa1af3292021-12-15 11:47:01 +0530102 throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
103 IOError();
104 }
105 }
106 }
107 /**
108 * @brief similar to init() oem specific deinitialization can be done under
109 * deInit function. if platform specific deinitialization is needed then a
110 * derived class instance with its own init function to override the default
111 * deinit() method can be added.
112 */
113 virtual void deInit()
114 {
Delphine CC Chiuccd7db02023-02-09 14:48:53 +0800115 for (auto fd : config.fds)
Naveen Mosesa1af3292021-12-15 11:47:01 +0530116 {
Delphine CC Chiuccd7db02023-02-09 14:48:53 +0800117 if (fd > 0)
118 {
119 ::close(fd);
120 }
Naveen Mosesa1af3292021-12-15 11:47:01 +0530121 }
122 }
123
Patrick Williams9a529a62022-07-22 19:26:54 -0500124 sdbusplus::bus_t& bus;
Naveen Mosesa1af3292021-12-15 11:47:01 +0530125 EventPtr& event;
Delphine CC Chiuccd7db02023-02-09 14:48:53 +0800126 ButtonConfig config;
Naveen Mosesa1af3292021-12-15 11:47:01 +0530127 sd_event_io_handler_t callbackHandler;
128};