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