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 */ 69 explicit PMBusReadSensorAction(SensorType type, 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 * Executes this action. 78 * 79 * Reads one sensor using the I2C interface. 80 * 81 * The sensor type is specified in the constructor. 82 * 83 * The PMBus command code is specified in the constructor. 84 * It is the register to read on the device. 85 * 86 * The sensor data format is specified in the constructor. Currently 87 * the linear_11 and linear_16 formats are supported. 88 * 89 * The linear_16 data format requires an exponent value. 90 * If an exponent value was specified in the constructor, that 91 * value will be used. Otherwise the exponent value will be obtained from 92 * the VOUT_MODE command. 93 * 94 * The device is obtained from the ActionEnvironment. 95 * 96 * Throws an exception if an error occurs. 97 * 98 * @param environment Action execution environment. 99 * @return true 100 */ 101 virtual bool execute(ActionEnvironment& environment) override; 102 103 /** 104 * Returns the PMBus command code. 105 * 106 * @return command 107 */ 108 uint8_t getCommand() const 109 { 110 return command; 111 } 112 113 /** 114 * Returns the optional exponent value for linear_16 data format. 115 * 116 * @return optional exponent value 117 */ 118 std::optional<int8_t> getExponent() const 119 { 120 return exponent; 121 } 122 123 /** 124 * Returns the data format of the sensor value returned by the device. 125 * 126 * @return data format 127 */ 128 pmbus_utils::SensorDataFormat getFormat() const 129 { 130 return format; 131 } 132 133 /** 134 * Returns the sensor type. 135 * 136 * @return sensor type. 137 */ 138 SensorType getType() const 139 { 140 return type; 141 } 142 143 /** 144 * Returns a string description of this action. 145 * 146 * @return description of action 147 */ 148 virtual std::string toString() const override; 149 150 private: 151 /** 152 * Gets the exponent value to use to convert a linear_16 format value to a 153 * decimal volts value. 154 * 155 * If an exponent value is defined for this action, that value is returned. 156 * Otherwise VOUT_MODE is read from the current device to obtain the 157 * exponent value. 158 * 159 * Throws an exception if an error occurs. 160 * 161 * @param environment action execution environment 162 * @param interface I2C interface to the current device 163 * @return exponent value 164 */ 165 int8_t getExponentValue(ActionEnvironment& environment, 166 i2c::I2CInterface& interface); 167 168 /** 169 * Sensor type. 170 */ 171 const SensorType type{}; 172 173 /** 174 * PMBus command code. 175 */ 176 const uint8_t command{}; 177 178 /** 179 * Data format of the sensor value returned by the device. 180 */ 181 const pmbus_utils::SensorDataFormat format{}; 182 183 /** 184 * Optional exponent value for linear_16 data format. 185 */ 186 const std::optional<int8_t> exponent{}; 187 }; 188 189 } // namespace phosphor::power::regulators 190