13bd1cfcbSNaveen Moses
23bd1cfcbSNaveen Moses #include "hostSelector_switch.hpp"
33bd1cfcbSNaveen Moses
49fb15970SGeorge Liu #include <error.h>
59fb15970SGeorge Liu
69fb15970SGeorge Liu #include <phosphor-logging/lg2.hpp>
79fb15970SGeorge Liu
83bd1cfcbSNaveen Moses // add the button iface class to registry
93bd1cfcbSNaveen Moses static ButtonIFRegister<HostSelector> buttonRegister;
109fb15970SGeorge Liu
getMappedHSConfig(size_t hsPosition)113bd1cfcbSNaveen Moses size_t HostSelector::getMappedHSConfig(size_t hsPosition)
123bd1cfcbSNaveen Moses {
133bd1cfcbSNaveen Moses size_t adjustedPosition = INVALID_INDEX; // set bmc as default value
143bd1cfcbSNaveen Moses std::string hsPosStr;
153bd1cfcbSNaveen Moses hsPosStr = std::to_string(hsPosition);
163bd1cfcbSNaveen Moses
173bd1cfcbSNaveen Moses if (hsPosMap.find(hsPosStr) != hsPosMap.end())
183bd1cfcbSNaveen Moses {
193bd1cfcbSNaveen Moses adjustedPosition = hsPosMap[hsPosStr];
203bd1cfcbSNaveen Moses }
213bd1cfcbSNaveen Moses else
223bd1cfcbSNaveen Moses {
239fb15970SGeorge Liu lg2::debug("getMappedHSConfig : {TYPE}: no valid value in map.", "TYPE",
249fb15970SGeorge Liu getFormFactorType());
253bd1cfcbSNaveen Moses }
263bd1cfcbSNaveen Moses return adjustedPosition;
273bd1cfcbSNaveen Moses }
283bd1cfcbSNaveen Moses
getGpioIndex(int fd)293bd1cfcbSNaveen Moses size_t HostSelector::getGpioIndex(int fd)
303bd1cfcbSNaveen Moses {
313bd1cfcbSNaveen Moses for (size_t index = 0; index < gpioLineCount; index++)
323bd1cfcbSNaveen Moses {
333bd1cfcbSNaveen Moses if (config.gpios[index].fd == fd)
343bd1cfcbSNaveen Moses {
353bd1cfcbSNaveen Moses return index;
363bd1cfcbSNaveen Moses }
373bd1cfcbSNaveen Moses }
383bd1cfcbSNaveen Moses return INVALID_INDEX;
393bd1cfcbSNaveen Moses }
40ccd7db05SDelphine CC Chiu
getValueFromFd(int fd)41ccd7db05SDelphine CC Chiu char HostSelector::getValueFromFd(int fd)
423bd1cfcbSNaveen Moses {
433bd1cfcbSNaveen Moses char buf;
44ccd7db05SDelphine CC Chiu auto result = ::lseek(fd, 0, SEEK_SET);
45ccd7db05SDelphine CC Chiu
46ccd7db05SDelphine CC Chiu if (result < 0)
47ccd7db05SDelphine CC Chiu {
48ccd7db05SDelphine CC Chiu throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
49ccd7db05SDelphine CC Chiu IOError();
50ccd7db05SDelphine CC Chiu }
51ccd7db05SDelphine CC Chiu
52ccd7db05SDelphine CC Chiu result = ::read(fd, &buf, sizeof(buf));
53ccd7db05SDelphine CC Chiu if (result < 0)
54ccd7db05SDelphine CC Chiu {
55ccd7db05SDelphine CC Chiu throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
56ccd7db05SDelphine CC Chiu IOError();
57ccd7db05SDelphine CC Chiu }
58ccd7db05SDelphine CC Chiu return buf;
59ccd7db05SDelphine CC Chiu }
60ccd7db05SDelphine CC Chiu
setInitialHostSelectorValue()61ccd7db05SDelphine CC Chiu void HostSelector::setInitialHostSelectorValue()
62ccd7db05SDelphine CC Chiu {
63ccd7db05SDelphine CC Chiu size_t hsPosMapped = 0;
64ccd7db05SDelphine CC Chiu
65ccd7db05SDelphine CC Chiu try
66ccd7db05SDelphine CC Chiu {
67ccd7db05SDelphine CC Chiu if (config.type == ConfigType::gpio)
68ccd7db05SDelphine CC Chiu {
6994afa4baSGeorge Liu for (size_t index = 0; index < gpioLineCount; index++)
703bd1cfcbSNaveen Moses {
71ccd7db05SDelphine CC Chiu GpioState gpioState =
72ccd7db05SDelphine CC Chiu (getValueFromFd(config.gpios[index].fd) == '0')
73ccd7db05SDelphine CC Chiu ? (GpioState::deassert)
740d038f58SPatrick Williams : (GpioState::assert);
753bd1cfcbSNaveen Moses setHostSelectorValue(config.gpios[index].fd, gpioState);
76ccd7db05SDelphine CC Chiu }
77ccd7db05SDelphine CC Chiu hsPosMapped = getMappedHSConfig(hostSelectorPosition);
78ccd7db05SDelphine CC Chiu }
79ccd7db05SDelphine CC Chiu else if (config.type == ConfigType::cpld)
80ccd7db05SDelphine CC Chiu {
81ccd7db05SDelphine CC Chiu hsPosMapped = getValueFromFd(config.cpld.cpldMappedFd) - '0';
82ccd7db05SDelphine CC Chiu }
83ccd7db05SDelphine CC Chiu }
84ccd7db05SDelphine CC Chiu catch (const std::exception& e)
85ccd7db05SDelphine CC Chiu {
86ccd7db05SDelphine CC Chiu lg2::error("{TYPE}: exception while reading fd : {ERROR}", "TYPE",
87ccd7db05SDelphine CC Chiu getFormFactorType(), "ERROR", e.what());
88ccd7db05SDelphine CC Chiu }
89ccd7db05SDelphine CC Chiu
903bd1cfcbSNaveen Moses if (hsPosMapped != INVALID_INDEX)
913bd1cfcbSNaveen Moses {
923bd1cfcbSNaveen Moses position(hsPosMapped, true);
933bd1cfcbSNaveen Moses }
943bd1cfcbSNaveen Moses }
953bd1cfcbSNaveen Moses
setHostSelectorValue(int fd,GpioState state)963bd1cfcbSNaveen Moses void HostSelector::setHostSelectorValue(int fd, GpioState state)
973bd1cfcbSNaveen Moses {
983bd1cfcbSNaveen Moses size_t pos = getGpioIndex(fd);
993bd1cfcbSNaveen Moses
1003bd1cfcbSNaveen Moses if (pos == INVALID_INDEX)
1013bd1cfcbSNaveen Moses {
1023bd1cfcbSNaveen Moses return;
1033bd1cfcbSNaveen Moses }
1043bd1cfcbSNaveen Moses auto set_bit = [](size_t& val, size_t n) { val |= 0xff & (1 << n); };
1053bd1cfcbSNaveen Moses
1063bd1cfcbSNaveen Moses auto clr_bit = [](size_t& val, size_t n) { val &= ~(0xff & (1 << n)); };
1073bd1cfcbSNaveen Moses
108d219fa3cSNaveen Moses auto bit_op = (state == GpioState::deassert) ? set_bit : clr_bit;
1093bd1cfcbSNaveen Moses
1103bd1cfcbSNaveen Moses bit_op(hostSelectorPosition, pos);
1113bd1cfcbSNaveen Moses return;
1123bd1cfcbSNaveen Moses }
1133bd1cfcbSNaveen Moses /**
1143bd1cfcbSNaveen Moses * @brief This method is called from sd-event provided callback function
1153bd1cfcbSNaveen Moses * callbackHandler if platform specific event handling is needed then a
1163bd1cfcbSNaveen Moses * derived class instance with its specific event handling logic along with
1173bd1cfcbSNaveen Moses * init() function can be created to override the default event handling
1183bd1cfcbSNaveen Moses */
1193bd1cfcbSNaveen Moses
handleEvent(sd_event_source *,int fd,uint32_t)12094afa4baSGeorge Liu void HostSelector::handleEvent(sd_event_source* /* es */, int fd,
12194afa4baSGeorge Liu uint32_t /* revents */)
1223bd1cfcbSNaveen Moses {
1233bd1cfcbSNaveen Moses char buf = '0';
124ccd7db05SDelphine CC Chiu try
1253bd1cfcbSNaveen Moses {
126ccd7db05SDelphine CC Chiu buf = getValueFromFd(fd);
127ccd7db05SDelphine CC Chiu }
128ccd7db05SDelphine CC Chiu catch (const std::exception& e)
129ccd7db05SDelphine CC Chiu {
130ccd7db05SDelphine CC Chiu lg2::error("{TYPE}: exception while reading fd : {ERROR}", "TYPE",
131ccd7db05SDelphine CC Chiu getFormFactorType(), "ERROR", e.what());
1323bd1cfcbSNaveen Moses return;
1333bd1cfcbSNaveen Moses }
1343bd1cfcbSNaveen Moses
135ccd7db05SDelphine CC Chiu size_t hsPosMapped = 0;
136ccd7db05SDelphine CC Chiu if (config.type == ConfigType::gpio)
1373bd1cfcbSNaveen Moses {
1383bd1cfcbSNaveen Moses // read the gpio state for the io event received
139*d36b6b1dSPatrick Williams GpioState gpioState =
140*d36b6b1dSPatrick Williams (buf == '0') ? (GpioState::deassert) : (GpioState::assert);
1413bd1cfcbSNaveen Moses
1423bd1cfcbSNaveen Moses setHostSelectorValue(fd, gpioState);
143ccd7db05SDelphine CC Chiu hsPosMapped = getMappedHSConfig(hostSelectorPosition);
144ccd7db05SDelphine CC Chiu }
145ccd7db05SDelphine CC Chiu else if (config.type == ConfigType::cpld)
146ccd7db05SDelphine CC Chiu {
147ccd7db05SDelphine CC Chiu hsPosMapped = buf - '0';
148ccd7db05SDelphine CC Chiu }
1493bd1cfcbSNaveen Moses
1503bd1cfcbSNaveen Moses if (hsPosMapped != INVALID_INDEX)
1513bd1cfcbSNaveen Moses {
1523bd1cfcbSNaveen Moses position(hsPosMapped);
1533bd1cfcbSNaveen Moses }
1543bd1cfcbSNaveen Moses }
155