Fansensor: Support ast26xx pwm/tach
Add new fantype for ast26xx tach driver.
Use pwm-fan driver to setup ast26xx pwm driver for easier usage.
User must define pwm-fan node in dts as below
pwm-fanX {
compatible = "pwm-fan";
.......
};
refer Documentation/devicetree/bindings/hwmon/pwm-fan.txt for details
and Connector in EM configuration
"Connector": {
"Pwm": X,
......
}
where X is integer
Tested: On Facebook Bletchley (ast26xx) Platform with 1 fan
root@bletchley:/sys/class/leds# busctl set-property xyz.openbmc_project.FanSensor /xyz/openbmc_project/sensors/fan_pwm/Pwm_1 xyz.openbmc_project.Sensor.Value Value d 20
root@bletchley:/sys/class/leds# busctl introspect xyz.openbmc_project.FanSensor /xyz/openbmc_project/sensors/fan_tach/FAN0_TACH_IL xyz.openbmc_project.Sensor.Value
NAME TYPE SIGNATURE RESULT/VALUE FLAGS
.MaxValue property d 25000 emits-change
.MinValue property d 0 emits-change
.Unit property s "xyz.openbmc_project.Sensor.Value.Uni... emits-change
.Value property d 3189 emits-change writable
root@bletchley:/sys/class/leds# busctl introspect xyz.openbmc_project.FanSensor /xyz/openbmc_project/sensors/fan_tach/FAN0_TACH_OL xyz.openbmc_project.Sensor.Value
NAME TYPE SIGNATURE RESULT/VALUE FLAGS
.MaxValue property d 25000 emits-change
.MinValue property d 0 emits-change
.Unit property s "xyz.openbmc_project.Sensor.Value.Uni... emits-change
.Value property d 3006 emits-change writable
Signed-off-by: Howard Chiu <howard.chiu@quantatw.com>
Change-Id: Ifda89310590c9d914fa0a302df412fead807daa8
Signed-off-by: Potin Lai <potin.lai@quantatw.com>
diff --git a/src/FanMain.cpp b/src/FanMain.cpp
index 112848b..a5a5844 100644
--- a/src/FanMain.cpp
+++ b/src/FanMain.cpp
@@ -70,7 +70,8 @@
fs::path linkPath = parentPath / "device";
std::string canonical = fs::read_symlink(linkPath);
if (boost::ends_with(canonical, "1e786000.pwm-tacho-controller") ||
- boost::ends_with(canonical, "1e610000.pwm-tacho-controller"))
+ boost::ends_with(canonical, "1e610000.pwm-tacho-controller") ||
+ boost::ends_with(canonical, "1e610000.pwm_tach:tach"))
{
return FanTypes::aspeed;
}
@@ -97,6 +98,63 @@
enableFile << 1;
}
}
+bool findPwmfanPath(unsigned int configPwmfanIndex, fs::path& pwmPath)
+{
+ /* Search PWM since pwm-fan had separated
+ * PWM from tach directory and 1 channel only*/
+ std::vector<fs::path> pwmfanPaths;
+ std::string pwnfanDevName("pwm-fan");
+
+ pwnfanDevName += std::to_string(configPwmfanIndex);
+
+ if (!findFiles(fs::path("/sys/class/hwmon"), R"(pwm\d+)", pwmfanPaths))
+ {
+ std::cerr << "No PWMs are found!\n";
+ return false;
+ }
+ for (const auto& path : pwmfanPaths)
+ {
+ std::error_code ec;
+ fs::path link = fs::read_symlink(path.parent_path() / "device", ec);
+
+ if (ec)
+ {
+ std::cerr << "read_symlink() failed: " << ec.message() << " ("
+ << ec.value() << ")\n";
+ continue;
+ }
+
+ if (link.filename().string() == pwnfanDevName)
+ {
+ pwmPath = path;
+ return true;
+ }
+ }
+ return false;
+}
+bool findPwmPath(const fs::path& directory, unsigned int pwm, fs::path& pwmPath)
+{
+ std::error_code ec;
+
+ /* Assuming PWM file is appeared in the same directory as fanX_input */
+ auto path = directory / ("pwm" + std::to_string(pwm + 1));
+ bool exists = fs::exists(path, ec);
+
+ if (ec || !exists)
+ {
+ /* PWM file not exist or error happened */
+ if (ec)
+ {
+ std::cerr << "exists() failed: " << ec.message() << " ("
+ << ec.value() << ")\n";
+ }
+ /* try search form pwm-fanX directory */
+ return findPwmfanPath(pwm, pwmPath);
+ }
+
+ pwmPath = path;
+ return true;
+}
void createRedundancySensor(
const boost::container::flat_map<std::string, std::unique_ptr<TachSensor>>&
sensors,
@@ -386,14 +444,21 @@
auto findPwm = connector->second.find("Pwm");
if (findPwm != connector->second.end())
{
- fs::path pwmEnableFile =
- "pwm" + std::to_string(index + 1) + "_enable";
- fs::path enablePath =
- path.parent_path() / pwmEnableFile;
- enablePwm(enablePath);
size_t pwm = std::visit(VariantToUnsignedIntVisitor(),
findPwm->second);
- pwmPath = directory / ("pwm" + std::to_string(pwm + 1));
+ if (!findPwmPath(directory, pwm, pwmPath))
+ {
+ std::cerr << "Connector for " << sensorName
+ << " no pwm channel found!\n";
+ continue;
+ }
+
+ fs::path pwmEnableFile =
+ "pwm" + std::to_string(pwm + 1) + "_enable";
+ fs::path enablePath =
+ pwmPath.parent_path() / pwmEnableFile;
+ enablePwm(enablePath);
+
/* use pwm name override if found in configuration else
* use default */
auto findOverride = connector->second.find("PwmName");