Fansensor: Add psu fan support
Also simplify parsing logic by detecting type of tach.
Change-Id: Ib08bd240313c437275ea0b604d193e720c6e9515
Signed-off-by: James Feist <james.feist@linux.intel.com>
diff --git a/src/FanMain.cpp b/src/FanMain.cpp
index 8401343..ea03ba7 100644
--- a/src/FanMain.cpp
+++ b/src/FanMain.cpp
@@ -32,14 +32,33 @@
namespace fs = std::experimental::filesystem;
namespace variant_ns = sdbusplus::message::variant_ns;
-static constexpr std::array<const char*, 1> sensorTypes = {
- "xyz.openbmc_project.Configuration.AspeedFan"};
+static constexpr std::array<const char*, 2> sensorTypes = {
+ "xyz.openbmc_project.Configuration.AspeedFan",
+ "xyz.openbmc_project.Configuration.I2CFan"};
constexpr const char* redundancyConfiguration =
"xyz.openbmc_project.Configuration.FanRedundancy";
static std::regex inputRegex(R"(fan(\d+)_input)");
+enum class FanTypes
+{
+ aspeed,
+ i2c
+};
+
// todo: power supply fan redundancy
-std::unique_ptr<RedundancySensor> systemRedundancy = nullptr;
+std::shared_ptr<RedundancySensor> systemRedundancy = nullptr;
+
+FanTypes getFanType(const fs::path& parentPath)
+{
+ fs::path linkPath = parentPath / "device";
+ std::string canonical = fs::read_symlink(linkPath);
+ if (boost::ends_with(canonical, "1e786000.pwm-tacho-controller"))
+ {
+ return FanTypes::aspeed;
+ }
+ // todo: will we need to support other types?
+ return FanTypes::i2c;
+}
void createSensors(
boost::asio::io_service& io, sdbusplus::asio::object_server& objectServer,
@@ -74,7 +93,7 @@
// iterate through all found fan sensors, and try to match them with
// configuration
- for (auto& path : paths)
+ for (const auto& path : paths)
{
std::smatch match;
std::string pathStr = path.string();
@@ -83,6 +102,22 @@
std::string indexStr = *(match.begin() + 1);
auto directory = path.parent_path();
+ FanTypes fanType = getFanType(directory);
+ size_t bus = 0;
+ size_t address = 0;
+ if (fanType == FanTypes::i2c)
+ {
+ std::string link =
+ fs::read_symlink(directory / "device").filename();
+
+ size_t findDash = link.find("-");
+ if (findDash == std::string::npos || link.size() <= findDash + 1)
+ {
+ std::cerr << "Error finding device from symlink";
+ }
+ bus = std::stoi(link.substr(0, findDash));
+ address = std::stoi(link.substr(findDash + 1), nullptr, 16);
+ }
// convert to 0 based
size_t index = std::stoul(indexStr) - 1;
@@ -111,41 +146,6 @@
{
continue;
}
- auto connector =
- sensor.second.find(baseType + std::string(".Connector"));
- if (connector == sensor.second.end())
- {
- std::cerr << baseConfiguration->first << " missing connector\n";
- continue;
- }
- auto findPwmIndex = connector->second.find("Pwm");
- if (findPwmIndex == connector->second.end())
- {
- continue;
- }
- uint16_t pwmIndex = variant_ns::visit(VariantToUnsignedIntVisitor(),
- findPwmIndex->second);
- auto oemNamePath = directory.string() + R"(/of_node/oemname)" +
- std::to_string(pwmIndex);
-
- if (DEBUG)
- {
- std::cout << "Checking path " << oemNamePath << "\n";
- }
- std::ifstream nameFile(oemNamePath);
- if (!nameFile.good())
- {
- continue;
- }
- std::string oemName;
- std::getline(nameFile, oemName);
- nameFile.close();
- if (!oemName.size())
- {
- // shouldn't have an empty name file
- continue;
- }
- oemName.pop_back(); // remove trailing null
auto findIndex = baseConfiguration->second.find("Index");
if (findIndex == baseConfiguration->second.end())
{
@@ -154,25 +154,39 @@
}
unsigned int configIndex = variant_ns::visit(
VariantToUnsignedIntVisitor(), findIndex->second);
-
if (configIndex != index)
{
continue;
}
- // now that the indexes match, verify the connector
- auto findConnectorName = connector->second.find("Name");
- if (findConnectorName == connector->second.end())
+ if (fanType == FanTypes::aspeed)
{
- continue;
- }
- std::string connectorName = variant_ns::visit(
- VariantToStringVisitor(), findConnectorName->second);
- boost::replace_all(connectorName, " ", "_");
- if (connectorName == oemName)
- {
+ // there will be only 1 aspeed sensor object in sysfs, we found
+ // the fan
sensorData = &(sensor.second);
break;
}
+ else if (baseType == "xyz.openbmc_project.Configuration.I2CFan")
+ {
+ auto findBus = baseConfiguration->second.find("Bus");
+ auto findAddress = baseConfiguration->second.find("Address");
+ if (findBus == baseConfiguration->second.end() ||
+ findAddress == baseConfiguration->second.end())
+ {
+ std::cerr << baseConfiguration->first
+ << " missing bus or address\n";
+ continue;
+ }
+ unsigned int configBus = variant_ns::visit(
+ VariantToUnsignedIntVisitor(), findBus->second);
+ unsigned int configAddress = variant_ns::visit(
+ VariantToUnsignedIntVisitor(), findAddress->second);
+
+ if (configBus == bus && configAddress == configAddress)
+ {
+ sensorData = &(sensor.second);
+ break;
+ }
+ }
}
if (sensorData == nullptr)
{
@@ -243,10 +257,15 @@
std::make_unique<PresenceSensor>(index, inverted, io);
}
}
+ std::shared_ptr<RedundancySensor> redundancy;
+ if (fanType == FanTypes::aspeed)
+ {
+ redundancy = systemRedundancy;
+ }
tachSensors[sensorName] = std::make_unique<TachSensor>(
path.string(), objectServer, dbusConnection,
- std::move(presenceSensor), systemRedundancy, io, sensorName,
+ std::move(presenceSensor), redundancy, io, sensorName,
std::move(sensorThresholds), *interfacePath);
}
std::vector<fs::path> pwms;
@@ -257,6 +276,10 @@
}
for (const fs::path& pwm : pwms)
{
+ if (pwmSensors.find(pwm) != pwmSensors.end())
+ {
+ continue;
+ }
// only add new elements
pwmSensors.insert(std::pair<std::string, std::unique_ptr<PwmSensor>>(
pwm.string(),