xref: /openbmc/phosphor-power/phosphor-regulators/src/actions/pmbus_read_sensor_action.hpp (revision f54021972b91be5058b50e9046bb0dd5a3b22a80)
1 /**
2  * Copyright © 2020 IBM Corporation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
18 #include "action_environment.hpp"
19 #include "i2c_action.hpp"
20 #include "i2c_interface.hpp"
21 #include "pmbus_utils.hpp"
22 #include "sensors.hpp"
23 
24 #include <cstdint>
25 #include <optional>
26 #include <string>
27 
28 namespace phosphor::power::regulators
29 {
30 
31 /**
32  * @class PMBusReadSensorAction
33  *
34  * Reads one sensor for a PMBus regulator rail. Communicates with the device
35  * directly using the I2C interface.
36  *
37  * Implements the pmbus_read_sensor action in the JSON config file.
38  *
39  * Currently supports the linear_11 and linear_16 sensor data formats.
40  *
41  * The linear_16 data format requires an exponent value.  The exponent value
42  * can be specified in the constructor.  Otherwise the exponent value will be
43  * obtained from the PMBus VOUT_MODE command.  Note that some PMBus devices do
44  * not support the VOUT_MODE command.  The exponent value for a device is often
45  * found in the device documentation (data sheet).
46  */
47 class PMBusReadSensorAction : public I2CAction
48 {
49   public:
50     // Specify which compiler-generated methods we want
51     PMBusReadSensorAction() = delete;
52     PMBusReadSensorAction(const PMBusReadSensorAction&) = delete;
53     PMBusReadSensorAction(PMBusReadSensorAction&&) = delete;
54     PMBusReadSensorAction& operator=(const PMBusReadSensorAction&) = delete;
55     PMBusReadSensorAction& operator=(PMBusReadSensorAction&&) = delete;
56     virtual ~PMBusReadSensorAction() = default;
57 
58     /**
59      * Constructor.
60      *
61      * @param type Sensor type.
62      * @param command PMBus command code.
63      * @param format Data format of the sensor value returned by the device.
64      * @param exponent Exponent value for linear_16 data format.
65      *                 Can be positive or negative. If not specified, the
66      *                 exponent value will be read from VOUT_MODE.
67      *                 Should not be specified if the data format is linear_11.
68      */
PMBusReadSensorAction(SensorType type,uint8_t command,pmbus_utils::SensorDataFormat format,std::optional<int8_t> exponent)69     explicit PMBusReadSensorAction(SensorType type, uint8_t command,
70                                    pmbus_utils::SensorDataFormat format,
71                                    std::optional<int8_t> exponent) :
72         type{type}, command{command}, format{format}, exponent{exponent}
73     {}
74 
75     /**
76      * Executes this action.
77      *
78      * Reads one sensor using the I2C interface.
79      *
80      * The sensor type is specified in the constructor.
81      *
82      * The PMBus command code is specified in the constructor.
83      * It is the register to read on the device.
84      *
85      * The sensor data format is specified in the constructor. Currently
86      * the linear_11 and linear_16 formats are supported.
87      *
88      * The linear_16 data format requires an exponent value.
89      * If an exponent value was specified in the constructor, that
90      * value will be used.  Otherwise the exponent value will be obtained from
91      * the VOUT_MODE command.
92      *
93      * The device is obtained from the ActionEnvironment.
94      *
95      * Throws an exception if an error occurs.
96      *
97      * @param environment Action execution environment.
98      * @return true
99      */
100     virtual bool execute(ActionEnvironment& environment) override;
101 
102     /**
103      * Returns the PMBus command code.
104      *
105      * @return command
106      */
getCommand() const107     uint8_t getCommand() const
108     {
109         return command;
110     }
111 
112     /**
113      * Returns the optional exponent value for linear_16 data format.
114      *
115      * @return optional exponent value
116      */
getExponent() const117     std::optional<int8_t> getExponent() const
118     {
119         return exponent;
120     }
121 
122     /**
123      * Returns the data format of the sensor value returned by the device.
124      *
125      * @return data format
126      */
getFormat() const127     pmbus_utils::SensorDataFormat getFormat() const
128     {
129         return format;
130     }
131 
132     /**
133      * Returns the sensor type.
134      *
135      * @return sensor type.
136      */
getType() const137     SensorType getType() const
138     {
139         return type;
140     }
141 
142     /**
143      * Returns a string description of this action.
144      *
145      * @return description of action
146      */
147     virtual std::string toString() const override;
148 
149   private:
150     /**
151      * Gets the exponent value to use to convert a linear_16 format value to a
152      * decimal volts value.
153      *
154      * If an exponent value is defined for this action, that value is returned.
155      * Otherwise VOUT_MODE is read from the current device to obtain the
156      * exponent value.
157      *
158      * Throws an exception if an error occurs.
159      *
160      * @param environment action execution environment
161      * @param interface I2C interface to the current device
162      * @return exponent value
163      */
164     int8_t getExponentValue(ActionEnvironment& environment,
165                             i2c::I2CInterface& interface);
166 
167     /**
168      * Sensor type.
169      */
170     const SensorType type{};
171 
172     /**
173      * PMBus command code.
174      */
175     const uint8_t command{};
176 
177     /**
178      * Data format of the sensor value returned by the device.
179      */
180     const pmbus_utils::SensorDataFormat format{};
181 
182     /**
183      * Optional exponent value for linear_16 data format.
184      */
185     const std::optional<int8_t> exponent{};
186 };
187 
188 } // namespace phosphor::power::regulators
189