1abf8da36SMatt Spinler #pragma once 2abf8da36SMatt Spinler 3abf8da36SMatt Spinler #include <chrono> 4abf8da36SMatt Spinler #include <sdbusplus/bus.hpp> 5abf8da36SMatt Spinler #include <sdbusplus/server.hpp> 6e824f985SMatt Spinler #include "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 18*78689dd7SMatt Spinler constexpr auto FAN_SENSOR_PATH = "/xyz/openbmc_project/sensors/fan_tach/"; 19abf8da36SMatt Spinler 20abf8da36SMatt Spinler /** 21abf8da36SMatt Spinler * @class TachSensor 22abf8da36SMatt Spinler * 23abf8da36SMatt Spinler * This class represents the sensor that reads a tach value. 24abf8da36SMatt Spinler * It may also support a Target, which is the property used to 25abf8da36SMatt Spinler * set a speed. Since it doesn't necessarily have a Target, it 26abf8da36SMatt Spinler * won't for sure know if it is running too slow, so it leaves 27abf8da36SMatt Spinler * that determination to other code. 28abf8da36SMatt Spinler * 29abf8da36SMatt Spinler * This class has a parent Fan object that knows about all 30abf8da36SMatt Spinler * sensors for that fan. 31abf8da36SMatt Spinler */ 32abf8da36SMatt Spinler class TachSensor 33abf8da36SMatt Spinler { 34abf8da36SMatt Spinler public: 35abf8da36SMatt Spinler 36abf8da36SMatt Spinler TachSensor() = delete; 37abf8da36SMatt Spinler TachSensor(const TachSensor&) = delete; 38fa0766e3SBrad Bishop // TachSensor is not moveable since the this pointer is used as systemd 39fa0766e3SBrad Bishop // callback context. 40fa0766e3SBrad Bishop TachSensor(TachSensor&&) = delete; 41abf8da36SMatt Spinler TachSensor& operator=(const TachSensor&) = delete; 42fa0766e3SBrad Bishop TachSensor& operator=(TachSensor&&) = delete; 43abf8da36SMatt Spinler ~TachSensor() = default; 44abf8da36SMatt Spinler 45abf8da36SMatt Spinler /** 46abf8da36SMatt Spinler * @brief Constructor 47abf8da36SMatt Spinler * 48abf8da36SMatt Spinler * @param[in] bus - the dbus object 49abf8da36SMatt Spinler * @param[in] fan - the parent fan object 50abf8da36SMatt Spinler * @param[in] id - the id of the sensor 51abf8da36SMatt Spinler * @param[in] hasTarget - if the sensor supports 52abf8da36SMatt Spinler * setting the speed 53abf8da36SMatt Spinler * @param[in] timeout - Normal timeout value to use 54a9406a77SMatt Spinler * @param[in] events - sd_event pointer 55abf8da36SMatt Spinler */ 56abf8da36SMatt Spinler TachSensor(sdbusplus::bus::bus& bus, 57abf8da36SMatt Spinler Fan& fan, 58abf8da36SMatt Spinler const std::string& id, 59abf8da36SMatt Spinler bool hasTarget, 60a9406a77SMatt Spinler size_t timeout, 61e824f985SMatt Spinler phosphor::fan::event::EventPtr& events); 62abf8da36SMatt Spinler 63abf8da36SMatt Spinler /** 64abf8da36SMatt Spinler * @brief Returns the target speed value 65abf8da36SMatt Spinler */ 66abf8da36SMatt Spinler inline uint64_t getTarget() const 67abf8da36SMatt Spinler { 68abf8da36SMatt Spinler return _tachTarget; 69abf8da36SMatt Spinler } 70abf8da36SMatt Spinler 71abf8da36SMatt Spinler /** 72abf8da36SMatt Spinler * @brief Returns the input speed value 73abf8da36SMatt Spinler */ 74abf8da36SMatt Spinler inline int64_t getInput() const 75abf8da36SMatt Spinler { 76abf8da36SMatt Spinler return _tachInput; 77abf8da36SMatt Spinler } 78abf8da36SMatt Spinler 79abf8da36SMatt Spinler /** 80abf8da36SMatt Spinler * @brief Returns true if sensor has a target 81abf8da36SMatt Spinler */ 82abf8da36SMatt Spinler inline bool hasTarget() const 83abf8da36SMatt Spinler { 84abf8da36SMatt Spinler return _hasTarget; 85abf8da36SMatt Spinler } 86abf8da36SMatt Spinler 87abf8da36SMatt Spinler /** 88abf8da36SMatt Spinler * Returns true if the hardware behind this 89abf8da36SMatt Spinler * sensor is considered working OK/functional. 90abf8da36SMatt Spinler */ 91abf8da36SMatt Spinler inline bool functional() const 92abf8da36SMatt Spinler { 93abf8da36SMatt Spinler return _functional; 94abf8da36SMatt Spinler } 95abf8da36SMatt Spinler 96abf8da36SMatt Spinler /** 97abf8da36SMatt Spinler * Sets functional status 98abf8da36SMatt Spinler */ 99abf8da36SMatt Spinler inline void setFunctional(bool functional) 100abf8da36SMatt Spinler { 101abf8da36SMatt Spinler _functional = functional; 102abf8da36SMatt Spinler } 103abf8da36SMatt Spinler 104a9406a77SMatt Spinler /** 1056fa181c7SMatt Spinler * @brief Says if the timer is running or not 1066fa181c7SMatt Spinler * 1076fa181c7SMatt Spinler * @return bool - if timer is currently running 108a9406a77SMatt Spinler */ 1096fa181c7SMatt Spinler inline bool timerRunning() 110a9406a77SMatt Spinler { 1116fa181c7SMatt Spinler return _timer.running(); 1126fa181c7SMatt Spinler } 1136fa181c7SMatt Spinler 1146fa181c7SMatt Spinler /** 1156fa181c7SMatt Spinler * @brief Starts the timer for the amount of time 1166fa181c7SMatt Spinler * specified in the constructor 1176fa181c7SMatt Spinler */ 1186fa181c7SMatt Spinler inline void startTimer() 1196fa181c7SMatt Spinler { 1206fa181c7SMatt Spinler _timer.start( 1216fa181c7SMatt Spinler getTimeout(), 1226fa181c7SMatt Spinler phosphor::fan::util::Timer::TimerType::oneshot); 1236fa181c7SMatt Spinler } 1246fa181c7SMatt Spinler 1256fa181c7SMatt Spinler /** 1266fa181c7SMatt Spinler * @brief Stops the timer 1276fa181c7SMatt Spinler */ 1286fa181c7SMatt Spinler inline void stopTimer() 1296fa181c7SMatt Spinler { 1306fa181c7SMatt Spinler _timer.stop(); 131a9406a77SMatt Spinler } 132a9406a77SMatt Spinler 133a9406a77SMatt Spinler /** 134a9406a77SMatt Spinler * @brief Returns the timeout value to use for the sensor 135a9406a77SMatt Spinler */ 136a9406a77SMatt Spinler std::chrono::microseconds getTimeout(); 137a9406a77SMatt Spinler 138ce75b511SMatt Spinler /** 139ce75b511SMatt Spinler * Returns the sensor name 140ce75b511SMatt Spinler */ 141ce75b511SMatt Spinler inline const std::string& name() const 142ce75b511SMatt Spinler { 143ce75b511SMatt Spinler return _name; 144ce75b511SMatt Spinler }; 145ce75b511SMatt Spinler 146abf8da36SMatt Spinler private: 147abf8da36SMatt Spinler 148abf8da36SMatt Spinler /** 149ebaae611SMatt Spinler * @brief Returns the match string to use for matching 150ebaae611SMatt Spinler * on a properties changed signal. 151ebaae611SMatt Spinler */ 152ebaae611SMatt Spinler std::string getMatchString(const std::string& interface); 153ebaae611SMatt Spinler 154ebaae611SMatt Spinler /** 155ebaae611SMatt Spinler * @brief Reads the Target property and stores in _tachTarget. 156ebaae611SMatt Spinler * Also calls Fan::tachChanged(). 157ebaae611SMatt Spinler * 158ebaae611SMatt Spinler * @param[in] msg - the dbus message 159ebaae611SMatt Spinler */ 160771659fcSBrad Bishop void handleTargetChange(sdbusplus::message::message& msg); 161ebaae611SMatt Spinler 162ebaae611SMatt Spinler /** 163ebaae611SMatt Spinler * @brief Reads the Value property and stores in _tachInput. 164ebaae611SMatt Spinler * Also calls Fan::tachChanged(). 165ebaae611SMatt Spinler * 166ebaae611SMatt Spinler * @param[in] msg - the dbus message 167ebaae611SMatt Spinler */ 168771659fcSBrad Bishop void handleTachChange(sdbusplus::message::message& msg); 169ebaae611SMatt Spinler 170ebaae611SMatt Spinler 171ebaae611SMatt Spinler /** 172abf8da36SMatt Spinler * @brief the dbus object 173abf8da36SMatt Spinler */ 174abf8da36SMatt Spinler sdbusplus::bus::bus& _bus; 175abf8da36SMatt Spinler 176abf8da36SMatt Spinler /** 177abf8da36SMatt Spinler * @brief Reference to the parent Fan object 178abf8da36SMatt Spinler */ 179abf8da36SMatt Spinler Fan& _fan; 180abf8da36SMatt Spinler 181abf8da36SMatt Spinler /** 182abf8da36SMatt Spinler * @brief The name of the sensor, including the full path 183abf8da36SMatt Spinler * 184abf8da36SMatt Spinler * For example /xyz/openbmc_project/sensors/fan_tach/fan0 185abf8da36SMatt Spinler */ 186abf8da36SMatt Spinler const std::string _name; 187abf8da36SMatt Spinler 188abf8da36SMatt Spinler /** 189abf8da36SMatt Spinler * @brief If functional (not too slow). The parent 190abf8da36SMatt Spinler * fan object sets this. 191abf8da36SMatt Spinler */ 192abf8da36SMatt Spinler bool _functional = true; 193abf8da36SMatt Spinler 194abf8da36SMatt Spinler /** 195abf8da36SMatt Spinler * @brief If the sensor has a Target property (can set speed) 196abf8da36SMatt Spinler */ 197abf8da36SMatt Spinler const bool _hasTarget; 198abf8da36SMatt Spinler 199abf8da36SMatt Spinler /** 200abf8da36SMatt Spinler * @brief The input speed, from the Value dbus property 201abf8da36SMatt Spinler */ 202abf8da36SMatt Spinler int64_t _tachInput = 0; 203abf8da36SMatt Spinler 204abf8da36SMatt Spinler /** 205abf8da36SMatt Spinler * @brief The current target speed, from the Target dbus property 206abf8da36SMatt Spinler * (if applicable) 207abf8da36SMatt Spinler */ 208abf8da36SMatt Spinler uint64_t _tachTarget = 0; 209abf8da36SMatt Spinler 210abf8da36SMatt Spinler /** 211abf8da36SMatt Spinler * @brief The timeout value to use 212abf8da36SMatt Spinler */ 213abf8da36SMatt Spinler const size_t _timeout; 214ebaae611SMatt Spinler 215ebaae611SMatt Spinler /** 216a9406a77SMatt Spinler * The timer object 217a9406a77SMatt Spinler */ 218a9406a77SMatt Spinler phosphor::fan::util::Timer _timer; 219a9406a77SMatt Spinler 220a9406a77SMatt Spinler /** 221ebaae611SMatt Spinler * @brief The match object for the Value properties changed signal 222ebaae611SMatt Spinler */ 223ebaae611SMatt Spinler std::unique_ptr<sdbusplus::server::match::match> tachSignal; 224ebaae611SMatt Spinler 225ebaae611SMatt Spinler /** 226ebaae611SMatt Spinler * @brief The match object for the Target properties changed signal 227ebaae611SMatt Spinler */ 228ebaae611SMatt Spinler std::unique_ptr<sdbusplus::server::match::match> targetSignal; 229abf8da36SMatt Spinler }; 230abf8da36SMatt Spinler 231abf8da36SMatt Spinler } 232abf8da36SMatt Spinler } 233abf8da36SMatt Spinler } 234