xref: /openbmc/phosphor-buttons/src/serial_uart_mux.cpp (revision 31ce375e7e71ff6b3da460dc63c1ab4f16cf4df6)
1  #include "serial_uart_mux.hpp"
2  
3  #include "xyz/openbmc_project/Chassis/Buttons/HostSelector/server.hpp"
4  
5  #include <error.h>
6  
7  #include <phosphor-logging/lg2.hpp>
8  namespace sdbusRule = sdbusplus::bus::match::rules;
9  // add the button iface class to registry
10  static ButtonIFRegister<SerialUartMux> buttonRegister;
11  using HostSelectorServerObj =
12      sdbusplus::server::xyz::openbmc_project::chassis::buttons::HostSelector;
13  using HostSelectorClientObj =
14      sdbusplus::common::xyz::openbmc_project::chassis::buttons::HostSelector;
15  
16  static constexpr auto SERIAL_UART_RX_GPIO = "serial_uart_rx";
init()17  void SerialUartMux::init()
18  {
19      try
20      {
21          // when Host Selector Position is changed call the handler
22  
23          std::string matchPattern = sdbusRule::propertiesChanged(
24              HS_DBUS_OBJECT_NAME, HostSelectorClientObj::interface);
25  
26          hostPositionChanged = std::make_unique<sdbusplus::bus::match_t>(
27              bus, matchPattern,
28              std::bind(std::mem_fn(&SerialUartMux::hostSelectorPositionChanged),
29                        this, std::placeholders::_1));
30      }
31      catch (const std::exception& e)
32      {
33          lg2::error(
34              "Failed binding to matching function : {BUTTON_TYPE},Exception : {ERROR}",
35              "BUTTON_TYPE", getFormFactorName(), "ERROR", e);
36          throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
37              IOError();
38      }
39  }
40  // check the debug card present pin
isOCPDebugCardPresent()41  bool SerialUartMux::isOCPDebugCardPresent()
42  {
43      auto gpioState =
44          getGpioState(debugCardPresentGpio.fd, debugCardPresentGpio.polarity);
45      return (gpioState == GpioState::assert);
46  }
47  // set the serial uart MUX to select the console w.r.t host selector position
configSerialConsoleMux(size_t position)48  void SerialUartMux::configSerialConsoleMux(size_t position)
49  {
50      auto debugCardPresent = isOCPDebugCardPresent();
51  
52      if (debugCardPresent)
53      {
54          lg2::info("Debug card is present ");
55      }
56      else
57      {
58          lg2::info("Debug card not present ");
59      }
60  
61      for (size_t uartMuxSel = 0; uartMuxSel < gpioLineCount; uartMuxSel++)
62      {
63          auto gpioState = GpioState::invalid;
64          GpioInfo gpioConfig = config.gpios[uartMuxSel];
65  
66          if (gpioConfig.name == SERIAL_UART_RX_GPIO)
67          {
68              gpioState =
69                  debugCardPresent ? GpioState::assert : GpioState::deassert;
70          }
71          else
72          {
73              gpioState = (serialUartMuxMap[position] & (0x1 << uartMuxSel))
74                              ? GpioState::assert
75                              : GpioState::deassert;
76          }
77          setGpioState(gpioConfig.fd, gpioConfig.polarity, gpioState);
78      }
79  }
80  
hostSelectorPositionChanged(sdbusplus::message_t & msg)81  void SerialUartMux::hostSelectorPositionChanged(sdbusplus::message_t& msg)
82  {
83      std::string interface;
84      std::map<std::string, HostSelectorServerObj::PropertiesVariant>
85          propertiesChanged;
86      lg2::info("hostSelectorPositionChanged callback : {BUTTON_TYPE}",
87                "BUTTON_TYPE", getFormFactorName());
88  
89      try
90      {
91          msg.read(interface, propertiesChanged);
92          for (auto& property : propertiesChanged)
93          {
94              auto propertyName = property.first;
95              if (propertyName == "Position")
96              {
97                  size_t hostPosition = std::get<size_t>(property.second);
98                  lg2::debug("property changed : {VALUE}", "VALUE", hostPosition);
99                  configSerialConsoleMux(hostPosition);
100                  return;
101              }
102          }
103      }
104      catch (const std::exception& e)
105      {
106          lg2::error("exception while reading dbus property : {ERROR}", "ERROR",
107                     e.what());
108          return;
109      }
110  }
111