xref: /openbmc/phosphor-buttons/src/hostSelector_switch.cpp (revision d36b6b1d3887f8545b1558f8f0d946a9c9785a72)
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