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