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