blob: 7ad3c79f58ae8c5e3ebe6b1eb1b46ab661a89959 [file] [log] [blame]
Matt Spinlerabf8da32017-04-27 14:08:45 -05001#pragma once
2
Matt Spinlerabf8da32017-04-27 14:08:45 -05003#include <sdbusplus/bus.hpp>
4#include <sdbusplus/server.hpp>
William A. Kennington III8fd879f2018-10-30 19:49:29 -07005#include <sdeventplus/clock.hpp>
William A. Kennington III1cfc2f12018-10-19 17:29:46 -07006#include <sdeventplus/event.hpp>
William A. Kennington III8fd879f2018-10-30 19:49:29 -07007#include <sdeventplus/utility/timer.hpp>
Matt Spinlerabf8da32017-04-27 14:08:45 -05008
Matthew Barth177fe982020-05-26 11:05:19 -05009#include <chrono>
10
Matt Spinlerabf8da32017-04-27 14:08:45 -050011namespace phosphor
12{
13namespace fan
14{
15namespace monitor
16{
17
18class Fan;
19
Matt Spinler78689dd2017-09-28 10:12:07 -050020constexpr auto FAN_SENSOR_PATH = "/xyz/openbmc_project/sensors/fan_tach/";
Matt Spinlerabf8da32017-04-27 14:08:45 -050021
22/**
Matthew Barth0a9fe162018-01-26 12:53:15 -060023 * The mode fan monitor will run in:
24 * - init - only do the initialization steps
25 * - monitor - run normal monitoring algorithm
26 */
27enum class Mode
28{
29 init,
30 monitor
31};
32
33/**
Matthew Barth3800ae72018-02-19 16:08:04 -060034 * The mode that the timer is running in:
35 * - func - Transition to functional state timer
36 * - nonfunc - Transition to nonfunctional state timer
37 */
38enum class TimerMode
39{
40 func,
41 nonfunc
42};
43
44/**
Matt Spinlerabf8da32017-04-27 14:08:45 -050045 * @class TachSensor
46 *
47 * This class represents the sensor that reads a tach value.
48 * It may also support a Target, which is the property used to
49 * set a speed. Since it doesn't necessarily have a Target, it
50 * won't for sure know if it is running too slow, so it leaves
51 * that determination to other code.
52 *
53 * This class has a parent Fan object that knows about all
54 * sensors for that fan.
55 */
56class TachSensor
57{
Matthew Barth177fe982020-05-26 11:05:19 -050058 public:
59 TachSensor() = delete;
60 TachSensor(const TachSensor&) = delete;
61 // TachSensor is not moveable since the this pointer is used as systemd
62 // callback context.
63 TachSensor(TachSensor&&) = delete;
64 TachSensor& operator=(const TachSensor&) = delete;
65 TachSensor& operator=(TachSensor&&) = delete;
66 ~TachSensor() = default;
Matt Spinlerabf8da32017-04-27 14:08:45 -050067
Matthew Barth177fe982020-05-26 11:05:19 -050068 /**
69 * @brief Constructor
70 *
71 * @param[in] mode - mode of fan monitor
72 * @param[in] bus - the dbus object
73 * @param[in] fan - the parent fan object
74 * @param[in] id - the id of the sensor
75 * @param[in] hasTarget - if the sensor supports
76 * setting the speed
77 * @param[in] funcDelay - Delay to mark functional
78 * @param[in] interface - the interface of the target
79 * @param[in] factor - the factor of the sensor target
80 * @param[in] offset - the offset of the sensor target
81 * @param[in] timeout - Normal timeout value to use
82 * @param[in] event - Event loop reference
83 */
84 TachSensor(Mode mode, sdbusplus::bus::bus& bus, Fan& fan,
85 const std::string& id, bool hasTarget, size_t funcDelay,
86 const std::string& interface, double factor, int64_t offset,
87 size_t timeout, const sdeventplus::Event& event);
Matt Spinlerabf8da32017-04-27 14:08:45 -050088
Matthew Barth177fe982020-05-26 11:05:19 -050089 /**
90 * @brief Returns the target speed value
91 */
92 uint64_t getTarget() const;
Matt Spinlerabf8da32017-04-27 14:08:45 -050093
Matthew Barth177fe982020-05-26 11:05:19 -050094 /**
95 * @brief Returns the input speed value
96 */
97 inline int64_t getInput() const
98 {
99 return _tachInput;
100 }
Matt Spinlerabf8da32017-04-27 14:08:45 -0500101
Matthew Barth177fe982020-05-26 11:05:19 -0500102 /**
103 * @brief Returns true if sensor has a target
104 */
105 inline bool hasTarget() const
106 {
107 return _hasTarget;
108 }
Matt Spinlerabf8da32017-04-27 14:08:45 -0500109
Matthew Barth177fe982020-05-26 11:05:19 -0500110 /**
111 * @brief Returns the interface of the sensor target
112 */
113 inline std::string getInterface() const
114 {
115 return _interface;
116 }
Matt Spinlerabf8da32017-04-27 14:08:45 -0500117
Matthew Barth177fe982020-05-26 11:05:19 -0500118 /**
119 * @brief Returns the factor of the sensor target
120 */
121 inline double getFactor() const
122 {
123 return _factor;
124 }
Lei YU80f271b2018-01-31 15:24:46 +0800125
Matthew Barth177fe982020-05-26 11:05:19 -0500126 /**
127 * @brief Returns the offset of the sensor target
128 */
129 inline int64_t getOffset() const
130 {
131 return _offset;
132 }
Lei YU8e5d1972018-01-26 17:14:00 +0800133
Matthew Barth177fe982020-05-26 11:05:19 -0500134 /**
135 * Returns true if the hardware behind this
136 * sensor is considered working OK/functional.
137 */
138 inline bool functional() const
139 {
140 return _functional;
141 }
Lei YU8e5d1972018-01-26 17:14:00 +0800142
Matthew Barth177fe982020-05-26 11:05:19 -0500143 /**
144 * Set the functional status and update inventory to match
145 */
146 void setFunctional(bool functional);
Matt Spinlerabf8da32017-04-27 14:08:45 -0500147
Matthew Barth177fe982020-05-26 11:05:19 -0500148 /**
149 * @brief Says if the timer is running or not
150 *
151 * @return bool - if timer is currently running
152 */
153 inline bool timerRunning()
154 {
155 return _timer.isEnabled();
156 }
Matt Spinlerabf8da32017-04-27 14:08:45 -0500157
Matthew Barth177fe982020-05-26 11:05:19 -0500158 /**
159 * @brief Stops the timer when the given mode differs and starts
160 * the associated timer for the mode given if not already running
161 *
162 * @param[in] mode - mode of timer to start
163 */
164 void startTimer(TimerMode mode);
Matt Spinler6fa181c2017-09-27 16:24:45 -0500165
Matthew Barth177fe982020-05-26 11:05:19 -0500166 /**
167 * @brief Stops the timer
168 */
169 inline void stopTimer()
170 {
171 _timer.setEnabled(false);
172 }
Matt Spinler6fa181c2017-09-27 16:24:45 -0500173
Matthew Barth177fe982020-05-26 11:05:19 -0500174 /**
175 * @brief Return the given timer mode's delay time
176 *
177 * @param[in] mode - mode of timer to get delay time for
178 */
179 std::chrono::microseconds getDelay(TimerMode mode);
Matt Spinlera9406a72017-04-27 14:29:24 -0500180
Matthew Barth177fe982020-05-26 11:05:19 -0500181 /**
182 * Returns the sensor name
183 */
184 inline const std::string& name() const
185 {
186 return _name;
187 };
Matt Spinlera9406a72017-04-27 14:29:24 -0500188
Matthew Barth177fe982020-05-26 11:05:19 -0500189 private:
190 /**
191 * @brief Returns the match string to use for matching
192 * on a properties changed signal.
193 */
194 std::string getMatchString(const std::string& interface);
Matt Spinlerce75b512017-07-26 15:10:48 -0500195
Matthew Barth177fe982020-05-26 11:05:19 -0500196 /**
197 * @brief Reads the Target property and stores in _tachTarget.
198 * Also calls Fan::tachChanged().
199 *
200 * @param[in] msg - the dbus message
201 */
202 void handleTargetChange(sdbusplus::message::message& msg);
Matt Spinlerabf8da32017-04-27 14:08:45 -0500203
Matthew Barth177fe982020-05-26 11:05:19 -0500204 /**
205 * @brief Reads the Value property and stores in _tachInput.
206 * Also calls Fan::tachChanged().
207 *
208 * @param[in] msg - the dbus message
209 */
210 void handleTachChange(sdbusplus::message::message& msg);
Matt Spinlerebaae612017-04-27 14:21:48 -0500211
Matthew Barth177fe982020-05-26 11:05:19 -0500212 /**
213 * @brief Updates the Functional property in the inventory
214 * for this tach sensor based on the value passed in.
215 *
216 * @param[in] functional - If the Functional property should
217 * be set to true or false.
218 */
219 void updateInventory(bool functional);
Matt Spinlerebaae612017-04-27 14:21:48 -0500220
Matthew Barth177fe982020-05-26 11:05:19 -0500221 /**
222 * @brief the dbus object
223 */
224 sdbusplus::bus::bus& _bus;
Matt Spinlerebaae612017-04-27 14:21:48 -0500225
Matthew Barth177fe982020-05-26 11:05:19 -0500226 /**
227 * @brief Reference to the parent Fan object
228 */
229 Fan& _fan;
Matt Spinlerebaae612017-04-27 14:21:48 -0500230
Matthew Barth177fe982020-05-26 11:05:19 -0500231 /**
232 * @brief The name of the sensor, including the full path
233 *
234 * For example /xyz/openbmc_project/sensors/fan_tach/fan0
235 */
236 const std::string _name;
Matt Spinlerabf8da32017-04-27 14:08:45 -0500237
Matthew Barth177fe982020-05-26 11:05:19 -0500238 /**
239 * @brief The inventory name of the sensor, including the full path
240 */
241 const std::string _invName;
Matt Spinlerabf8da32017-04-27 14:08:45 -0500242
Matthew Barth177fe982020-05-26 11:05:19 -0500243 /**
244 * @brief If functional (not too slow). The parent
245 * fan object sets this.
246 */
247 bool _functional;
Matt Spinlerabf8da32017-04-27 14:08:45 -0500248
Matthew Barth177fe982020-05-26 11:05:19 -0500249 /**
250 * @brief If the sensor has a Target property (can set speed)
251 */
252 const bool _hasTarget;
Matthew Barth4d982852017-11-17 09:37:13 -0600253
Matthew Barth177fe982020-05-26 11:05:19 -0500254 /**
255 * @brief Amount of time to delay updating to functional
256 */
257 const size_t _funcDelay;
Matt Spinlerabf8da32017-04-27 14:08:45 -0500258
Matthew Barth177fe982020-05-26 11:05:19 -0500259 /**
260 * @brief The interface that the target implements
261 */
262 const std::string _interface;
Matt Spinlerabf8da32017-04-27 14:08:45 -0500263
Matthew Barth177fe982020-05-26 11:05:19 -0500264 /**
265 * @brief The factor of target to get fan rpm
266 */
267 const double _factor;
Matthew Barth9396bcc2018-02-19 14:13:20 -0600268
Matthew Barth177fe982020-05-26 11:05:19 -0500269 /**
270 * @brief The offset of target to get fan rpm
271 */
272 const int64_t _offset;
Lei YU80f271b2018-01-31 15:24:46 +0800273
Matthew Barth177fe982020-05-26 11:05:19 -0500274 /**
275 * @brief The input speed, from the Value dbus property
276 */
277 int64_t _tachInput = 0;
Lei YU8e5d1972018-01-26 17:14:00 +0800278
Matthew Barth177fe982020-05-26 11:05:19 -0500279 /**
280 * @brief The current target speed, from the Target dbus property
281 * (if applicable)
282 */
283 uint64_t _tachTarget = 0;
Lei YU8e5d1972018-01-26 17:14:00 +0800284
Matthew Barth177fe982020-05-26 11:05:19 -0500285 /**
286 * @brief The timeout value to use
287 */
288 const size_t _timeout;
Matt Spinlerabf8da32017-04-27 14:08:45 -0500289
Matthew Barth177fe982020-05-26 11:05:19 -0500290 /**
291 * @brief Mode that current timer is in
292 */
293 TimerMode _timerMode;
Matt Spinlerabf8da32017-04-27 14:08:45 -0500294
Matthew Barth177fe982020-05-26 11:05:19 -0500295 /**
296 * The timer object
297 */
298 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> _timer;
Matt Spinlerebaae612017-04-27 14:21:48 -0500299
Matthew Barth177fe982020-05-26 11:05:19 -0500300 /**
301 * @brief The match object for the Value properties changed signal
302 */
303 std::unique_ptr<sdbusplus::server::match::match> tachSignal;
Matthew Barth3800ae72018-02-19 16:08:04 -0600304
Matthew Barth177fe982020-05-26 11:05:19 -0500305 /**
306 * @brief The match object for the Target properties changed signal
307 */
308 std::unique_ptr<sdbusplus::server::match::match> targetSignal;
Matt Spinlerabf8da32017-04-27 14:08:45 -0500309};
310
Matthew Barth177fe982020-05-26 11:05:19 -0500311} // namespace monitor
312} // namespace fan
313} // namespace phosphor