blob: 620a81494d6b72babcc353caa2b4326ed1fc3562 [file] [log] [blame]
Bob Kingd6820bb2020-04-28 15:37:02 +08001/**
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
23#include <cstdint>
24#include <optional>
Bob Kingd6820bb2020-04-28 15:37:02 +080025#include <string>
26
27namespace phosphor::power::regulators
28{
29
30/**
31 * @class PMBusReadSensorAction
32 *
33 * Reads one sensor for a PMBus regulator rail. Communicates with the device
34 * directly using the I2C interface.
35 *
36 * Implements the pmbus_read_sensor action in the JSON config file.
37 *
38 * Currently supports the linear_11 and linear_16 sensor data formats.
39 *
40 * The linear_16 data format requires an exponent value. The exponent value
41 * can be specified in the constructor. Otherwise the exponent value will be
42 * obtained from the PMBus VOUT_MODE command. Note that some PMBus devices do
43 * not support the VOUT_MODE command. The exponent value for a device is often
44 * found in the device documentation (data sheet).
45 */
46class PMBusReadSensorAction : public I2CAction
47{
48 public:
49 // Specify which compiler-generated methods we want
50 PMBusReadSensorAction() = delete;
51 PMBusReadSensorAction(const PMBusReadSensorAction&) = delete;
52 PMBusReadSensorAction(PMBusReadSensorAction&&) = delete;
53 PMBusReadSensorAction& operator=(const PMBusReadSensorAction&) = delete;
54 PMBusReadSensorAction& operator=(PMBusReadSensorAction&&) = delete;
55 virtual ~PMBusReadSensorAction() = default;
56
57 /**
58 * Constructor.
59 *
60 * @param type Sensor value type.
61 * @param command PMBus command code.
62 * @param format Data format of the sensor value returned by the device.
63 * @param exponent Exponent value for linear_16 data format.
64 * Can be positive or negative. If not specified, the
65 * exponent value will be read from VOUT_MODE.
66 * Should not be specified if the data format is linear_11.
67 */
68 explicit PMBusReadSensorAction(pmbus_utils::SensorValueType type,
69 uint8_t command,
70 pmbus_utils::SensorDataFormat format,
71 std::optional<int8_t> exponent) :
72 type{type},
73 command{command}, format{format}, exponent{exponent}
74 {
75 }
76
77 /**
78 * Executes this action.
79 *
Bob King717d2da2020-06-02 11:11:15 +080080 * Reads one sensor using the I2C interface.
81 *
82 * The sensor value type is specified in the constructor.
83 *
84 * The PMBus command code is specified in the constructor.
85 * It is the register to read on the device.
86 *
87 * The sensor data format is specified in the constructor. Currently
88 * the linear_11 and linear_16 formats are supported.
89 *
90 * The linear_16 data format requires an exponent value.
91 * If an exponent value was specified in the constructor, that
92 * value will be used. Otherwise the exponent value will be obtained from
93 * the VOUT_MODE command.
94 *
95 * The device is obtained from the ActionEnvironment.
96 *
97 * Throws an exception if an error occurs.
Bob Kingd6820bb2020-04-28 15:37:02 +080098 *
99 * @param environment Action execution environment.
100 * @return true
101 */
Bob King717d2da2020-06-02 11:11:15 +0800102 virtual bool execute(ActionEnvironment& environment) override;
Bob Kingd6820bb2020-04-28 15:37:02 +0800103
104 /**
105 * Returns the PMBus command code.
106 *
107 * @return command
108 */
109 uint8_t getCommand() const
110 {
111 return command;
112 }
113
114 /**
115 * Returns the optional exponent value for linear_16 data format.
116 *
117 * @return optional exponent value
118 */
119 std::optional<int8_t> getExponent() const
120 {
121 return exponent;
122 }
123
124 /**
125 * Returns the data format of the sensor value returned by the device.
126 *
127 * @return data format
128 */
129 pmbus_utils::SensorDataFormat getFormat() const
130 {
131 return format;
132 }
133
134 /**
135 * Returns the sensor value type.
136 *
137 * @return sensor value type.
138 */
139 pmbus_utils::SensorValueType getType() const
140 {
141 return type;
142 }
143
144 /**
145 * Returns a string description of this action.
146 *
147 * @return description of action
148 */
Bob King717d2da2020-06-02 11:11:15 +0800149 virtual std::string toString() const override;
Bob Kingd6820bb2020-04-28 15:37:02 +0800150
151 private:
152 /**
Bob King717d2da2020-06-02 11:11:15 +0800153 * Gets the exponent value to use to convert a linear_16 format value to a
154 * decimal volts value.
155 *
156 * If an exponent value is defined for this action, that value is returned.
157 * Otherwise VOUT_MODE is read from the current device to obtain the
158 * exponent value.
159 *
160 * Throws an exception if an error occurs.
161 *
Shawn McCarney5b819f42021-03-16 14:41:15 -0500162 * @param environment action execution environment
Bob King717d2da2020-06-02 11:11:15 +0800163 * @param interface I2C interface to the current device
164 * @return exponent value
165 */
Shawn McCarney5b819f42021-03-16 14:41:15 -0500166 int8_t getExponentValue(ActionEnvironment& environment,
167 i2c::I2CInterface& interface);
Bob King717d2da2020-06-02 11:11:15 +0800168
169 /**
Bob Kingd6820bb2020-04-28 15:37:02 +0800170 * Sensor value type.
171 */
172 const pmbus_utils::SensorValueType type{};
173
174 /**
175 * PMBus command code.
176 */
177 const uint8_t command{};
178
179 /**
180 * Data format of the sensor value returned by the device.
181 */
182 const pmbus_utils::SensorDataFormat format{};
183
184 /**
185 * Optional exponent value for linear_16 data format.
186 */
187 const std::optional<int8_t> exponent{};
188};
189
190} // namespace phosphor::power::regulators