Support host selector using cpld definitions
Description:
- Support host selector using cpld definitions
Design:
- Because the current structure only supports config defined by GPIO
(Yosemite V2), but there are also have the system (Yosemite V3.5)
gets the host-selector's selection from CPLD.
- So this commit is to extend the current configuration to use CPLD
definitions. Also, support adding event io from the register file
which was exported from the CLD driver.
- For example with config json below:
{
"cpld_definitions": [
{
"name": "HOST_SELECTOR",
"i2c_address": 15,
"i2c_bus": 12,
"register_name": "uart-selection-debug-card",
"max_position": 4
}
]
}
Dependency:
- CLD driver is required (link: https://lore.kernel.org/lkml/20230117094425.19004-1-Delphine_CC_Chiu@Wiwynn.com/)
Test Case:
- When ocp debug card uart button is pressed the position property on
dbus is correct.
Signed-off-by: Delphine CC Chiu <Delphine_CC_Chiu@wiwynn.com>
Change-Id: I6746afa6d905bd3c681e2921c643b3cd4cb9944c
diff --git a/inc/button_config.hpp b/inc/button_config.hpp
new file mode 100644
index 0000000..7678d25
--- /dev/null
+++ b/inc/button_config.hpp
@@ -0,0 +1,27 @@
+#pragma once
+#include "config.h"
+
+#include "cpld.hpp"
+#include "gpio.hpp"
+
+#include <nlohmann/json.hpp>
+
+#include <iostream>
+
+enum class ConfigType
+{
+ gpio,
+ cpld
+};
+
+// this struct represents button interface
+struct ButtonConfig
+{
+ ConfigType type;
+ std::string formFactorName; // name of the button interface
+ std::vector<GpioInfo> gpios; // holds single or group gpio config
+ CpldInfo cpld; // holds single cpld config
+ std::vector<int> fds; // store all the fds listen io event which
+ // mapped with the gpio or cpld
+ nlohmann::json extraJsonInfo; // corresponding to button interface
+};
diff --git a/inc/button_factory.hpp b/inc/button_factory.hpp
index faf948d..29fb990 100644
--- a/inc/button_factory.hpp
+++ b/inc/button_factory.hpp
@@ -1,14 +1,14 @@
#pragma once
+#include "button_config.hpp"
#include "button_interface.hpp"
-#include "gpio.hpp"
#include <phosphor-logging/elog-errors.hpp>
#include <unordered_map>
using buttonIfCreatorMethod = std::function<std::unique_ptr<ButtonIface>(
- sdbusplus::bus_t& bus, EventPtr& event, buttonConfig& buttonCfg)>;
+ sdbusplus::bus_t& bus, EventPtr& event, ButtonConfig& buttonCfg)>;
/**
* @brief This is abstract factory for the creating phosphor buttons objects
@@ -37,7 +37,7 @@
{
buttonIfaceRegistry[std::string(T::getFormFactorName())] =
[](sdbusplus::bus_t& bus, EventPtr& event,
- buttonConfig& buttonCfg) {
+ ButtonConfig& buttonCfg) {
return std::make_unique<T>(bus, T::getDbusObjectPath(), event,
buttonCfg);
};
@@ -49,7 +49,7 @@
std::unique_ptr<ButtonIface> createInstance(const std::string& name,
sdbusplus::bus_t& bus,
EventPtr& event,
- buttonConfig& buttonCfg)
+ ButtonConfig& buttonCfg)
{
// find matching name in the registry and call factory method.
auto objectIter = buttonIfaceRegistry.find(name);
diff --git a/inc/button_interface.hpp b/inc/button_interface.hpp
index 9905304..b3a98cc 100644
--- a/inc/button_interface.hpp
+++ b/inc/button_interface.hpp
@@ -1,7 +1,7 @@
#pragma once
+#include "button_config.hpp"
#include "common.hpp"
-#include "gpio.hpp"
#include "xyz/openbmc_project/Chassis/Common/error.hpp"
#include <phosphor-logging/elog-errors.hpp>
@@ -10,20 +10,31 @@
class ButtonIface
{
public:
- ButtonIface(sdbusplus::bus_t& bus, EventPtr& event, buttonConfig& buttonCfg,
+ ButtonIface(sdbusplus::bus_t& bus, EventPtr& event, ButtonConfig& buttonCfg,
sd_event_io_handler_t handler = ButtonIface::EventHandler) :
bus(bus),
event(event), config(buttonCfg), callbackHandler(handler)
{
int ret = -1;
+ std::string configType;
- // config group gpio based on the gpio defs read from the json file
- ret = configGroupGpio(config);
+ // config group gpio or cpld based on the defs read from the json file
+ if (buttonCfg.type == ConfigType::gpio)
+ {
+ configType = "GPIO";
+ ret = configGroupGpio(config);
+ }
+ else if (buttonCfg.type == ConfigType::cpld)
+ {
+ configType = "CPLD";
+ ret = configCpld(config);
+ }
if (ret < 0)
{
phosphor::logging::log<phosphor::logging::level::ERR>(
- (getFormFactorType() + " : failed to config GPIO").c_str());
+ (getFormFactorType() + " : failed to config " + configType)
+ .c_str());
throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
IOError();
}
@@ -65,12 +76,11 @@
virtual void init()
{
- // initialize the button io fd from the buttonConfig
- // which has fd stored when configGroupGpio is called
- for (auto gpioCfg : config.gpios)
+ // initialize the button io fd from the ButtonConfig
+ // which has fd stored when configGroupGpio or configCpld is called
+ for (auto fd : config.fds)
{
char buf;
- int fd = gpioCfg.fd;
int ret = ::read(fd, &buf, sizeof(buf));
if (ret < 0)
@@ -86,7 +96,10 @@
phosphor::logging::log<phosphor::logging::level::ERR>(
(getFormFactorType() + " : failed to add to event loop")
.c_str());
- ::closeGpio(fd);
+ if (fd > 0)
+ {
+ ::close(fd);
+ }
throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
IOError();
}
@@ -100,14 +113,17 @@
*/
virtual void deInit()
{
- for (auto gpioCfg : config.gpios)
+ for (auto fd : config.fds)
{
- ::closeGpio(gpioCfg.fd);
+ if (fd > 0)
+ {
+ ::close(fd);
+ }
}
}
sdbusplus::bus_t& bus;
EventPtr& event;
- buttonConfig config;
+ ButtonConfig config;
sd_event_io_handler_t callbackHandler;
};
diff --git a/inc/cpld.hpp b/inc/cpld.hpp
new file mode 100644
index 0000000..206f0c6
--- /dev/null
+++ b/inc/cpld.hpp
@@ -0,0 +1,18 @@
+
+#pragma once
+#include "config.h"
+
+#include <cstdint>
+#include <string>
+
+struct ButtonConfig;
+
+struct CpldInfo
+{
+ std::string registerName;
+ uint32_t i2cAddress;
+ uint32_t i2cBus;
+ int cpldMappedFd; // io fd mapped with the cpld
+};
+
+int configCpld(ButtonConfig& buttonCfg);
diff --git a/inc/debugHostSelector_button.hpp b/inc/debugHostSelector_button.hpp
index fa13d02..ea5dd5f 100644
--- a/inc/debugHostSelector_button.hpp
+++ b/inc/debugHostSelector_button.hpp
@@ -25,7 +25,7 @@
{
public:
DebugHostSelector(sdbusplus::bus_t& bus, const char* path, EventPtr& event,
- buttonConfig& buttonCfg) :
+ ButtonConfig& buttonCfg) :
sdbusplus::server::object_t<
sdbusplus::xyz::openbmc_project::Chassis::Buttons::server::Button>(
bus, path, action::defer_emit),
diff --git a/inc/gpio.hpp b/inc/gpio.hpp
index 9cfd57d..2351da9 100644
--- a/inc/gpio.hpp
+++ b/inc/gpio.hpp
@@ -21,6 +21,8 @@
#include <string>
#include <vector>
+struct ButtonConfig;
+
// enum to represent gpio states
enum class GpioState
{
@@ -42,7 +44,7 @@
};
// this struct has the gpio config for single gpio
-struct gpioInfo
+struct GpioInfo
{
int fd; // io fd mapped with the gpio
uint32_t number;
@@ -51,29 +53,21 @@
GpioPolarity polarity;
};
-// this struct represents button interface
-struct buttonConfig
-{
- std::string formFactorName; // name of the button interface
- std::vector<gpioInfo> gpios; // holds single or group gpio config
- nlohmann::json extraJsonInfo; // corresponding to button interface
-};
-
/**
* @brief iterates over the list of gpios and configures gpios them
* config which is set from gpio defs json file.
- * The fd of the configured gpio is stored in buttonConfig.gpios container
+ * The fd of the configured gpio is stored in ButtonConfig.gpios container
* @return int returns 0 on successful config of all gpios
*/
-int configGroupGpio(buttonConfig& buttonCfg);
+int configGroupGpio(ButtonConfig& buttonCfg);
/**
* @brief configures and initializes the single gpio
* @return int returns 0 on successful config of all gpios
*/
-int configGpio(gpioInfo& gpioConfig);
+int configGpio(GpioInfo& gpioConfig, ButtonConfig& buttonIFConfig);
uint32_t getGpioNum(const std::string& gpioPin);
// Set gpio state based on polarity
@@ -81,6 +75,5 @@
// Get gpio state based on polarity
GpioState getGpioState(int fd, GpioPolarity polarity);
-void closeGpio(int fd);
// global json object which holds gpio_defs.json configs
extern nlohmann::json gpioDefs;
diff --git a/inc/hostSelector_switch.hpp b/inc/hostSelector_switch.hpp
index 8030564..806da06 100644
--- a/inc/hostSelector_switch.hpp
+++ b/inc/hostSelector_switch.hpp
@@ -28,7 +28,7 @@
{
public:
HostSelector(sdbusplus::bus_t& bus, const char* path, EventPtr& event,
- buttonConfig& buttonCfg) :
+ ButtonConfig& buttonCfg) :
sdbusplus::server::object_t<sdbusplus::xyz::openbmc_project::Chassis::
Buttons::server::HostSelector>(
bus, path, action::defer_emit),
@@ -36,11 +36,14 @@
{
init();
// read and store the host selector position Map
- hsPosMap = buttonCfg.extraJsonInfo.at("host_selector_map")
- .get<std::map<std::string, int>>();
- maxPosition(buttonCfg.extraJsonInfo["max_position"], true);
- gpioLineCount = buttonCfg.gpios.size();
+ if (buttonCfg.type == ConfigType::gpio)
+ {
+ hsPosMap = buttonCfg.extraJsonInfo.at("host_selector_map")
+ .get<std::map<std::string, int>>();
+ gpioLineCount = buttonCfg.gpios.size();
+ }
setInitialHostSelectorValue();
+ maxPosition(buttonCfg.extraJsonInfo["max_position"], true);
emit_object_added();
}
@@ -63,6 +66,7 @@
size_t getGpioIndex(int fd);
void setInitialHostSelectorValue(void);
void setHostSelectorValue(int fd, GpioState state);
+ char getValueFromFd(int fd);
protected:
size_t hostSelectorPosition = 0;
diff --git a/inc/id_button.hpp b/inc/id_button.hpp
index e48843b..24514d9 100644
--- a/inc/id_button.hpp
+++ b/inc/id_button.hpp
@@ -37,7 +37,7 @@
{
public:
IDButton(sdbusplus::bus_t& bus, const char* path, EventPtr& event,
- buttonConfig& buttonCfg) :
+ ButtonConfig& buttonCfg) :
sdbusplus::server::object_t<
sdbusplus::xyz::openbmc_project::Chassis::Buttons::server::ID>(
bus, path),
diff --git a/inc/power_button.hpp b/inc/power_button.hpp
index 90076f3..549b51f 100644
--- a/inc/power_button.hpp
+++ b/inc/power_button.hpp
@@ -39,7 +39,7 @@
{
public:
PowerButton(sdbusplus::bus_t& bus, const char* path, EventPtr& event,
- buttonConfig& buttonCfg) :
+ ButtonConfig& buttonCfg) :
sdbusplus::server::object_t<
sdbusplus::xyz::openbmc_project::Chassis::Buttons::server::Power>(
bus, path),
diff --git a/inc/reset_button.hpp b/inc/reset_button.hpp
index 925bed1..918d0de 100644
--- a/inc/reset_button.hpp
+++ b/inc/reset_button.hpp
@@ -37,7 +37,7 @@
{
public:
ResetButton(sdbusplus::bus_t& bus, const char* path, EventPtr& event,
- buttonConfig& buttonCfg) :
+ ButtonConfig& buttonCfg) :
sdbusplus::server::object_t<
sdbusplus::xyz::openbmc_project::Chassis::Buttons::server::Reset>(
bus, path),
diff --git a/inc/serial_uart_mux.hpp b/inc/serial_uart_mux.hpp
index c1ad166..6898e8f 100644
--- a/inc/serial_uart_mux.hpp
+++ b/inc/serial_uart_mux.hpp
@@ -23,7 +23,7 @@
{
public:
SerialUartMux(sdbusplus::bus_t& bus, [[maybe_unused]] const char* path,
- EventPtr& event, buttonConfig& buttonCfg) :
+ EventPtr& event, ButtonConfig& buttonCfg) :
ButtonIface(bus, event, buttonCfg)
{
init();
@@ -77,6 +77,6 @@
protected:
size_t gpioLineCount;
std::unique_ptr<sdbusplus::bus::match_t> hostPositionChanged;
- gpioInfo debugCardPresentGpio;
+ GpioInfo debugCardPresentGpio;
std::unordered_map<size_t, size_t> serialUartMuxMap;
};