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