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