blob: c398e35451f4c99f82608aaa1de6cdd9a598edd5 [file] [log] [blame]
Naveen Moses3bd1cfc2022-02-14 18:04:20 +05301
2#include "hostSelector_switch.hpp"
3
George Liu9fb15972022-06-20 14:54:38 +08004#include <error.h>
5
6#include <phosphor-logging/lg2.hpp>
7
Naveen Moses3bd1cfc2022-02-14 18:04:20 +05308// add the button iface class to registry
9static ButtonIFRegister<HostSelector> buttonRegister;
George Liu9fb15972022-06-20 14:54:38 +080010
Naveen Moses3bd1cfc2022-02-14 18:04:20 +053011size_t HostSelector::getMappedHSConfig(size_t hsPosition)
12{
13 size_t adjustedPosition = INVALID_INDEX; // set bmc as default value
14 std::string hsPosStr;
15 hsPosStr = std::to_string(hsPosition);
16
17 if (hsPosMap.find(hsPosStr) != hsPosMap.end())
18 {
19 adjustedPosition = hsPosMap[hsPosStr];
20 }
21 else
22 {
George Liu9fb15972022-06-20 14:54:38 +080023 lg2::debug("getMappedHSConfig : {TYPE}: no valid value in map.", "TYPE",
24 getFormFactorType());
Naveen Moses3bd1cfc2022-02-14 18:04:20 +053025 }
26 return adjustedPosition;
27}
28
29size_t HostSelector::getGpioIndex(int fd)
30{
31 for (size_t index = 0; index < gpioLineCount; index++)
32 {
33 if (config.gpios[index].fd == fd)
34 {
35 return index;
36 }
37 }
38 return INVALID_INDEX;
39}
Delphine CC Chiuccd7db02023-02-09 14:48:53 +080040
41char HostSelector::getValueFromFd(int fd)
Naveen Moses3bd1cfc2022-02-14 18:04:20 +053042{
43 char buf;
Delphine CC Chiuccd7db02023-02-09 14:48:53 +080044 auto result = ::lseek(fd, 0, SEEK_SET);
45
46 if (result < 0)
Naveen Moses3bd1cfc2022-02-14 18:04:20 +053047 {
Delphine CC Chiuccd7db02023-02-09 14:48:53 +080048 throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
49 IOError();
50 }
Naveen Moses3bd1cfc2022-02-14 18:04:20 +053051
Delphine CC Chiuccd7db02023-02-09 14:48:53 +080052 result = ::read(fd, &buf, sizeof(buf));
53 if (result < 0)
54 {
55 throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
56 IOError();
57 }
58 return buf;
59}
Naveen Moses3bd1cfc2022-02-14 18:04:20 +053060
Delphine CC Chiuccd7db02023-02-09 14:48:53 +080061void HostSelector::setInitialHostSelectorValue()
62{
63 size_t hsPosMapped = 0;
64
65 try
66 {
67 if (config.type == ConfigType::gpio)
Naveen Moses3bd1cfc2022-02-14 18:04:20 +053068 {
Delphine CC Chiuccd7db02023-02-09 14:48:53 +080069 for (size_t index = 0; index < gpioLineCount; index++)
70 {
71 GpioState gpioState =
72 (getValueFromFd(config.gpios[index].fd) == '0')
73 ? (GpioState::deassert)
74 : (GpioState::assert);
75 setHostSelectorValue(config.gpios[index].fd, gpioState);
76 }
77 hsPosMapped = getMappedHSConfig(hostSelectorPosition);
Naveen Moses3bd1cfc2022-02-14 18:04:20 +053078 }
Delphine CC Chiuccd7db02023-02-09 14:48:53 +080079 else if (config.type == ConfigType::cpld)
Naveen Moses3bd1cfc2022-02-14 18:04:20 +053080 {
Delphine CC Chiuccd7db02023-02-09 14:48:53 +080081 hsPosMapped = getValueFromFd(config.cpld.cpldMappedFd) - '0';
Naveen Moses3bd1cfc2022-02-14 18:04:20 +053082 }
83 }
Delphine CC Chiuccd7db02023-02-09 14:48:53 +080084 catch (const std::exception& e)
85 {
86 lg2::error("{TYPE}: exception while reading fd : {ERROR}", "TYPE",
87 getFormFactorType(), "ERROR", e.what());
88 }
89
90 if (hsPosMapped != INVALID_INDEX)
91 {
92 position(hsPosMapped, true);
93 }
Naveen Moses3bd1cfc2022-02-14 18:04:20 +053094}
95
96void HostSelector::setHostSelectorValue(int fd, GpioState state)
97{
98 size_t pos = getGpioIndex(fd);
99
100 if (pos == INVALID_INDEX)
101 {
102 return;
103 }
104 auto set_bit = [](size_t& val, size_t n) { val |= 0xff & (1 << n); };
105
106 auto clr_bit = [](size_t& val, size_t n) { val &= ~(0xff & (1 << n)); };
107
Naveen Mosesd219fa32022-07-20 00:01:46 +0530108 auto bit_op = (state == GpioState::deassert) ? set_bit : clr_bit;
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530109
110 bit_op(hostSelectorPosition, pos);
111 return;
112}
113/**
114 * @brief This method is called from sd-event provided callback function
115 * callbackHandler if platform specific event handling is needed then a
116 * derived class instance with its specific event handling logic along with
117 * init() function can be created to override the default event handling
118 */
119
George Liu94afa4b2022-06-20 13:36:43 +0800120void HostSelector::handleEvent(sd_event_source* /* es */, int fd,
121 uint32_t /* revents */)
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530122{
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530123 char buf = '0';
Delphine CC Chiuccd7db02023-02-09 14:48:53 +0800124 try
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530125 {
Delphine CC Chiuccd7db02023-02-09 14:48:53 +0800126 buf = getValueFromFd(fd);
127 }
128 catch (const std::exception& e)
129 {
130 lg2::error("{TYPE}: exception while reading fd : {ERROR}", "TYPE",
131 getFormFactorType(), "ERROR", e.what());
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530132 return;
133 }
134
Delphine CC Chiuccd7db02023-02-09 14:48:53 +0800135 size_t hsPosMapped = 0;
136 if (config.type == ConfigType::gpio)
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530137 {
Delphine CC Chiuccd7db02023-02-09 14:48:53 +0800138 // read the gpio state for the io event received
Patrick Williamsd36b6b12024-08-16 15:20:34 -0400139 GpioState gpioState =
140 (buf == '0') ? (GpioState::deassert) : (GpioState::assert);
Delphine CC Chiuccd7db02023-02-09 14:48:53 +0800141
142 setHostSelectorValue(fd, gpioState);
143 hsPosMapped = getMappedHSConfig(hostSelectorPosition);
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530144 }
Delphine CC Chiuccd7db02023-02-09 14:48:53 +0800145 else if (config.type == ConfigType::cpld)
146 {
147 hsPosMapped = buf - '0';
148 }
Naveen Moses3bd1cfc2022-02-14 18:04:20 +0530149
150 if (hsPosMapped != INVALID_INDEX)
151 {
152 position(hsPosMapped);
153 }
Patrick Williams0d038f52023-05-10 07:50:40 -0500154}