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