1abf8da36SMatt Spinler #pragma once 2abf8da36SMatt Spinler 3abf8da36SMatt Spinler #include <chrono> 4abf8da36SMatt Spinler #include <sdbusplus/bus.hpp> 5abf8da36SMatt Spinler #include <sdbusplus/server.hpp> 6*1cfc2f11SWilliam A. Kennington III #include <sdeventplus/event.hpp> 7a9406a77SMatt Spinler #include "timer.hpp" 8abf8da36SMatt Spinler 9abf8da36SMatt Spinler namespace phosphor 10abf8da36SMatt Spinler { 11abf8da36SMatt Spinler namespace fan 12abf8da36SMatt Spinler { 13abf8da36SMatt Spinler namespace monitor 14abf8da36SMatt Spinler { 15abf8da36SMatt Spinler 16abf8da36SMatt Spinler class Fan; 17abf8da36SMatt Spinler 1878689dd7SMatt Spinler constexpr auto FAN_SENSOR_PATH = "/xyz/openbmc_project/sensors/fan_tach/"; 19abf8da36SMatt Spinler 20abf8da36SMatt Spinler /** 210a9fe160SMatthew Barth * The mode fan monitor will run in: 220a9fe160SMatthew Barth * - init - only do the initialization steps 230a9fe160SMatthew Barth * - monitor - run normal monitoring algorithm 240a9fe160SMatthew Barth */ 250a9fe160SMatthew Barth enum class Mode 260a9fe160SMatthew Barth { 270a9fe160SMatthew Barth init, 280a9fe160SMatthew Barth monitor 290a9fe160SMatthew Barth }; 300a9fe160SMatthew Barth 310a9fe160SMatthew Barth /** 323800ae71SMatthew Barth * The mode that the timer is running in: 333800ae71SMatthew Barth * - func - Transition to functional state timer 343800ae71SMatthew Barth * - nonfunc - Transition to nonfunctional state timer 353800ae71SMatthew Barth */ 363800ae71SMatthew Barth enum class TimerMode 373800ae71SMatthew Barth { 383800ae71SMatthew Barth func, 393800ae71SMatthew Barth nonfunc 403800ae71SMatthew Barth }; 413800ae71SMatthew Barth 423800ae71SMatthew Barth /** 43abf8da36SMatt Spinler * @class TachSensor 44abf8da36SMatt Spinler * 45abf8da36SMatt Spinler * This class represents the sensor that reads a tach value. 46abf8da36SMatt Spinler * It may also support a Target, which is the property used to 47abf8da36SMatt Spinler * set a speed. Since it doesn't necessarily have a Target, it 48abf8da36SMatt Spinler * won't for sure know if it is running too slow, so it leaves 49abf8da36SMatt Spinler * that determination to other code. 50abf8da36SMatt Spinler * 51abf8da36SMatt Spinler * This class has a parent Fan object that knows about all 52abf8da36SMatt Spinler * sensors for that fan. 53abf8da36SMatt Spinler */ 54abf8da36SMatt Spinler class TachSensor 55abf8da36SMatt Spinler { 56abf8da36SMatt Spinler public: 57abf8da36SMatt Spinler 58abf8da36SMatt Spinler TachSensor() = delete; 59abf8da36SMatt Spinler TachSensor(const TachSensor&) = delete; 60fa0766e3SBrad Bishop // TachSensor is not moveable since the this pointer is used as systemd 61fa0766e3SBrad Bishop // callback context. 62fa0766e3SBrad Bishop TachSensor(TachSensor&&) = delete; 63abf8da36SMatt Spinler TachSensor& operator=(const TachSensor&) = delete; 64fa0766e3SBrad Bishop TachSensor& operator=(TachSensor&&) = delete; 65abf8da36SMatt Spinler ~TachSensor() = default; 66abf8da36SMatt Spinler 67abf8da36SMatt Spinler /** 68abf8da36SMatt Spinler * @brief Constructor 69abf8da36SMatt Spinler * 700a9fe160SMatthew Barth * @param[in] mode - mode of fan monitor 71abf8da36SMatt Spinler * @param[in] bus - the dbus object 72abf8da36SMatt Spinler * @param[in] fan - the parent fan object 73abf8da36SMatt Spinler * @param[in] id - the id of the sensor 74abf8da36SMatt Spinler * @param[in] hasTarget - if the sensor supports 75abf8da36SMatt Spinler * setting the speed 769396bcc3SMatthew Barth * @param[in] funcDelay - Delay to mark functional 7780f271b2SLei YU * @param[in] interface - the interface of the target 788e5d197bSLei YU * @param[in] factor - the factor of the sensor target 798e5d197bSLei YU * @param[in] offset - the offset of the sensor target 80abf8da36SMatt Spinler * @param[in] timeout - Normal timeout value to use 81*1cfc2f11SWilliam A. Kennington III * @param[in] event - Event loop reference 82abf8da36SMatt Spinler */ 830a9fe160SMatthew Barth TachSensor(Mode mode, 840a9fe160SMatthew Barth sdbusplus::bus::bus& bus, 85abf8da36SMatt Spinler Fan& fan, 86abf8da36SMatt Spinler const std::string& id, 87abf8da36SMatt Spinler bool hasTarget, 889396bcc3SMatthew Barth size_t funcDelay, 8980f271b2SLei YU const std::string& interface, 908e5d197bSLei YU size_t factor, 918e5d197bSLei YU size_t offset, 92a9406a77SMatt Spinler size_t timeout, 93*1cfc2f11SWilliam A. Kennington III const sdeventplus::Event& event); 94abf8da36SMatt Spinler 95abf8da36SMatt Spinler /** 96abf8da36SMatt Spinler * @brief Returns the target speed value 97abf8da36SMatt Spinler */ 98f552ea5cSMatthew Barth uint64_t getTarget() const; 99abf8da36SMatt Spinler 100abf8da36SMatt Spinler /** 101abf8da36SMatt Spinler * @brief Returns the input speed value 102abf8da36SMatt Spinler */ 103abf8da36SMatt Spinler inline int64_t getInput() const 104abf8da36SMatt Spinler { 105abf8da36SMatt Spinler return _tachInput; 106abf8da36SMatt Spinler } 107abf8da36SMatt Spinler 108abf8da36SMatt Spinler /** 109abf8da36SMatt Spinler * @brief Returns true if sensor has a target 110abf8da36SMatt Spinler */ 111abf8da36SMatt Spinler inline bool hasTarget() const 112abf8da36SMatt Spinler { 113abf8da36SMatt Spinler return _hasTarget; 114abf8da36SMatt Spinler } 115abf8da36SMatt Spinler 116abf8da36SMatt Spinler /** 11780f271b2SLei YU * @brief Returns the interface of the sensor target 11880f271b2SLei YU */ 11980f271b2SLei YU inline std::string getInterface() const 12080f271b2SLei YU { 12180f271b2SLei YU return _interface; 12280f271b2SLei YU } 12380f271b2SLei YU 12480f271b2SLei YU /** 1258e5d197bSLei YU * @brief Returns the factor of the sensor target 1268e5d197bSLei YU */ 1278e5d197bSLei YU inline size_t getFactor() const 1288e5d197bSLei YU { 1298e5d197bSLei YU return _factor; 1308e5d197bSLei YU } 1318e5d197bSLei YU 1328e5d197bSLei YU /** 1338e5d197bSLei YU * @brief Returns the offset of the sensor target 1348e5d197bSLei YU */ 1358e5d197bSLei YU inline size_t getOffset() const 1368e5d197bSLei YU { 1378e5d197bSLei YU return _offset; 1388e5d197bSLei YU } 1398e5d197bSLei YU 1408e5d197bSLei YU /** 141abf8da36SMatt Spinler * Returns true if the hardware behind this 142abf8da36SMatt Spinler * sensor is considered working OK/functional. 143abf8da36SMatt Spinler */ 144abf8da36SMatt Spinler inline bool functional() const 145abf8da36SMatt Spinler { 146abf8da36SMatt Spinler return _functional; 147abf8da36SMatt Spinler } 148abf8da36SMatt Spinler 149abf8da36SMatt Spinler /** 150d199dcdfSMatthew Barth * Set the functional status and update inventory to match 151abf8da36SMatt Spinler */ 152d199dcdfSMatthew Barth void setFunctional(bool functional); 153abf8da36SMatt Spinler 154a9406a77SMatt Spinler /** 1556fa181c7SMatt Spinler * @brief Says if the timer is running or not 1566fa181c7SMatt Spinler * 1576fa181c7SMatt Spinler * @return bool - if timer is currently running 158a9406a77SMatt Spinler */ 1596fa181c7SMatt Spinler inline bool timerRunning() 160a9406a77SMatt Spinler { 1616fa181c7SMatt Spinler return _timer.running(); 1626fa181c7SMatt Spinler } 1636fa181c7SMatt Spinler 1646fa181c7SMatt Spinler /** 1653800ae71SMatthew Barth * @brief Stops the timer when the given mode differs and starts 1663800ae71SMatthew Barth * the associated timer for the mode given if not already running 1673800ae71SMatthew Barth * 1683800ae71SMatthew Barth * @param[in] mode - mode of timer to start 1696fa181c7SMatt Spinler */ 1703800ae71SMatthew Barth void startTimer(TimerMode mode); 1716fa181c7SMatt Spinler 1726fa181c7SMatt Spinler /** 1736fa181c7SMatt Spinler * @brief Stops the timer 1746fa181c7SMatt Spinler */ 1756fa181c7SMatt Spinler inline void stopTimer() 1766fa181c7SMatt Spinler { 1776fa181c7SMatt Spinler _timer.stop(); 178a9406a77SMatt Spinler } 179a9406a77SMatt Spinler 180a9406a77SMatt Spinler /** 1813800ae71SMatthew Barth * @brief Return the given timer mode's delay time 1823800ae71SMatthew Barth * 1833800ae71SMatthew Barth * @param[in] mode - mode of timer to get delay time for 184a9406a77SMatt Spinler */ 1853800ae71SMatthew Barth std::chrono::microseconds getDelay(TimerMode mode); 186a9406a77SMatt Spinler 187ce75b511SMatt Spinler /** 188ce75b511SMatt Spinler * Returns the sensor name 189ce75b511SMatt Spinler */ 190ce75b511SMatt Spinler inline const std::string& name() const 191ce75b511SMatt Spinler { 192ce75b511SMatt Spinler return _name; 193ce75b511SMatt Spinler }; 194ce75b511SMatt Spinler 195abf8da36SMatt Spinler private: 196abf8da36SMatt Spinler 197abf8da36SMatt Spinler /** 198ebaae611SMatt Spinler * @brief Returns the match string to use for matching 199ebaae611SMatt Spinler * on a properties changed signal. 200ebaae611SMatt Spinler */ 201ebaae611SMatt Spinler std::string getMatchString(const std::string& interface); 202ebaae611SMatt Spinler 203ebaae611SMatt Spinler /** 204ebaae611SMatt Spinler * @brief Reads the Target property and stores in _tachTarget. 205ebaae611SMatt Spinler * Also calls Fan::tachChanged(). 206ebaae611SMatt Spinler * 207ebaae611SMatt Spinler * @param[in] msg - the dbus message 208ebaae611SMatt Spinler */ 209771659fcSBrad Bishop void handleTargetChange(sdbusplus::message::message& msg); 210ebaae611SMatt Spinler 211ebaae611SMatt Spinler /** 212ebaae611SMatt Spinler * @brief Reads the Value property and stores in _tachInput. 213ebaae611SMatt Spinler * Also calls Fan::tachChanged(). 214ebaae611SMatt Spinler * 215ebaae611SMatt Spinler * @param[in] msg - the dbus message 216ebaae611SMatt Spinler */ 217771659fcSBrad Bishop void handleTachChange(sdbusplus::message::message& msg); 218ebaae611SMatt Spinler 2194d982856SMatthew Barth /** 2204d982856SMatthew Barth * @brief Updates the Functional property in the inventory 2214d982856SMatthew Barth * for this tach sensor based on the value passed in. 2224d982856SMatthew Barth * 2234d982856SMatthew Barth * @param[in] functional - If the Functional property should 2244d982856SMatthew Barth * be set to true or false. 2254d982856SMatthew Barth */ 2264d982856SMatthew Barth void updateInventory(bool functional); 227ebaae611SMatt Spinler 228ebaae611SMatt Spinler /** 229abf8da36SMatt Spinler * @brief the dbus object 230abf8da36SMatt Spinler */ 231abf8da36SMatt Spinler sdbusplus::bus::bus& _bus; 232abf8da36SMatt Spinler 233abf8da36SMatt Spinler /** 234abf8da36SMatt Spinler * @brief Reference to the parent Fan object 235abf8da36SMatt Spinler */ 236abf8da36SMatt Spinler Fan& _fan; 237abf8da36SMatt Spinler 238abf8da36SMatt Spinler /** 239abf8da36SMatt Spinler * @brief The name of the sensor, including the full path 240abf8da36SMatt Spinler * 241abf8da36SMatt Spinler * For example /xyz/openbmc_project/sensors/fan_tach/fan0 242abf8da36SMatt Spinler */ 243abf8da36SMatt Spinler const std::string _name; 244abf8da36SMatt Spinler 245abf8da36SMatt Spinler /** 2464d982856SMatthew Barth * @brief The inventory name of the sensor, including the full path 2474d982856SMatthew Barth */ 2484d982856SMatthew Barth const std::string _invName; 2494d982856SMatthew Barth 2504d982856SMatthew Barth /** 251abf8da36SMatt Spinler * @brief If functional (not too slow). The parent 252abf8da36SMatt Spinler * fan object sets this. 253abf8da36SMatt Spinler */ 254d199dcdfSMatthew Barth bool _functional; 255abf8da36SMatt Spinler 256abf8da36SMatt Spinler /** 257abf8da36SMatt Spinler * @brief If the sensor has a Target property (can set speed) 258abf8da36SMatt Spinler */ 259abf8da36SMatt Spinler const bool _hasTarget; 260abf8da36SMatt Spinler 261abf8da36SMatt Spinler /** 2629396bcc3SMatthew Barth * @brief Amount of time to delay updating to functional 2639396bcc3SMatthew Barth */ 2649396bcc3SMatthew Barth const size_t _funcDelay; 2659396bcc3SMatthew Barth 2669396bcc3SMatthew Barth /** 26780f271b2SLei YU * @brief The interface that the target implements 26880f271b2SLei YU */ 26980f271b2SLei YU const std::string _interface; 27080f271b2SLei YU 27180f271b2SLei YU /** 2728e5d197bSLei YU * @brief The factor of target to get fan rpm 2738e5d197bSLei YU */ 2748e5d197bSLei YU const size_t _factor; 2758e5d197bSLei YU 2768e5d197bSLei YU /** 2778e5d197bSLei YU * @brief The offset of target to get fan rpm 2788e5d197bSLei YU */ 2798e5d197bSLei YU const size_t _offset; 2808e5d197bSLei YU 2818e5d197bSLei YU /** 282abf8da36SMatt Spinler * @brief The input speed, from the Value dbus property 283abf8da36SMatt Spinler */ 284abf8da36SMatt Spinler int64_t _tachInput = 0; 285abf8da36SMatt Spinler 286abf8da36SMatt Spinler /** 287abf8da36SMatt Spinler * @brief The current target speed, from the Target dbus property 288abf8da36SMatt Spinler * (if applicable) 289abf8da36SMatt Spinler */ 290abf8da36SMatt Spinler uint64_t _tachTarget = 0; 291abf8da36SMatt Spinler 292abf8da36SMatt Spinler /** 293abf8da36SMatt Spinler * @brief The timeout value to use 294abf8da36SMatt Spinler */ 295abf8da36SMatt Spinler const size_t _timeout; 296ebaae611SMatt Spinler 297ebaae611SMatt Spinler /** 2983800ae71SMatthew Barth * @brief Mode that current timer is in 2993800ae71SMatthew Barth */ 3003800ae71SMatthew Barth TimerMode _timerMode; 3013800ae71SMatthew Barth 3023800ae71SMatthew Barth /** 303a9406a77SMatt Spinler * The timer object 304a9406a77SMatt Spinler */ 305a9406a77SMatt Spinler phosphor::fan::util::Timer _timer; 306a9406a77SMatt Spinler 307a9406a77SMatt Spinler /** 308ebaae611SMatt Spinler * @brief The match object for the Value properties changed signal 309ebaae611SMatt Spinler */ 310ebaae611SMatt Spinler std::unique_ptr<sdbusplus::server::match::match> tachSignal; 311ebaae611SMatt Spinler 312ebaae611SMatt Spinler /** 313ebaae611SMatt Spinler * @brief The match object for the Target properties changed signal 314ebaae611SMatt Spinler */ 315ebaae611SMatt Spinler std::unique_ptr<sdbusplus::server::match::match> targetSignal; 316abf8da36SMatt Spinler }; 317abf8da36SMatt Spinler 318abf8da36SMatt Spinler } 319abf8da36SMatt Spinler } 320abf8da36SMatt Spinler } 321