1a8119f26SShawn McCarney /** 2a8119f26SShawn McCarney * Copyright © 2020 IBM Corporation 3a8119f26SShawn McCarney * 4a8119f26SShawn McCarney * Licensed under the Apache License, Version 2.0 (the "License"); 5a8119f26SShawn McCarney * you may not use this file except in compliance with the License. 6a8119f26SShawn McCarney * You may obtain a copy of the License at 7a8119f26SShawn McCarney * 8a8119f26SShawn McCarney * http://www.apache.org/licenses/LICENSE-2.0 9a8119f26SShawn McCarney * 10a8119f26SShawn McCarney * Unless required by applicable law or agreed to in writing, software 11a8119f26SShawn McCarney * distributed under the License is distributed on an "AS IS" BASIS, 12a8119f26SShawn McCarney * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a8119f26SShawn McCarney * See the License for the specific language governing permissions and 14a8119f26SShawn McCarney * limitations under the License. 15a8119f26SShawn McCarney */ 16a8119f26SShawn McCarney #pragma once 17a8119f26SShawn McCarney 18a8119f26SShawn McCarney #include "action_environment.hpp" 19a8119f26SShawn McCarney #include "i2c_action.hpp" 20a8119f26SShawn McCarney #include "i2c_interface.hpp" 21a8119f26SShawn McCarney #include "pmbus_utils.hpp" 22a8119f26SShawn McCarney 23a8119f26SShawn McCarney #include <cstdint> 24a8119f26SShawn McCarney #include <optional> 25a8119f26SShawn McCarney #include <stdexcept> 26a8119f26SShawn McCarney #include <string> 27a8119f26SShawn McCarney 28a8119f26SShawn McCarney namespace phosphor::power::regulators 29a8119f26SShawn McCarney { 30a8119f26SShawn McCarney 31a8119f26SShawn McCarney /** 32a8119f26SShawn McCarney * @class PMBusWriteVoutCommandAction 33a8119f26SShawn McCarney * 34a8119f26SShawn McCarney * Writes the value of VOUT_COMMAND to set the output voltage of a PMBus 35a8119f26SShawn McCarney * regulator rail. Communicates with the device directly using the I2C 36a8119f26SShawn McCarney * interface. 37a8119f26SShawn McCarney * 38a8119f26SShawn McCarney * Implements the pmbus_write_vout_command action in the JSON config file. 39a8119f26SShawn McCarney * 40a8119f26SShawn McCarney * The volts value to write can be specified in the constructor. Otherwise, the 41a8119f26SShawn McCarney * volts value will be obtained from the ActionEnvironment. 42a8119f26SShawn McCarney * 43a8119f26SShawn McCarney * The PMBus specification defines four data formats for the value of 44a8119f26SShawn McCarney * VOUT_COMMAND: 45a8119f26SShawn McCarney * - Linear 46a8119f26SShawn McCarney * - VID 47a8119f26SShawn McCarney * - Direct 48a8119f26SShawn McCarney * - IEEE Half-Precision Floating Point 49a8119f26SShawn McCarney * Currently only the linear data format is supported. The volts value is 50a8119f26SShawn McCarney * converted into linear format before being written. 51a8119f26SShawn McCarney * 52a8119f26SShawn McCarney * The linear data format requires an exponent value. The exponent value can be 53a8119f26SShawn McCarney * specified in the constructor. Otherwise the exponent value will be obtained 54a8119f26SShawn McCarney * from the PMBus VOUT_MODE command. Note that some PMBus devices do not 55a8119f26SShawn McCarney * support the VOUT_MODE command. The exponent value for a device is often 56a8119f26SShawn McCarney * found in the device documentation (data sheet). 57a8119f26SShawn McCarney * 58a8119f26SShawn McCarney * If desired, write verification can be performed. The value of VOUT_COMMAND 59a8119f26SShawn McCarney * will be read from the device after it is written to ensure that it contains 60a8119f26SShawn McCarney * the expected value. If VOUT_COMMAND contains an unexpected value, a 61a8119f26SShawn McCarney * WriteVerificationError is thrown. To perform verification, the device must 62a8119f26SShawn McCarney * return all 16 bits of voltage data that were written to VOUT_COMMAND. 63a8119f26SShawn McCarney */ 64a8119f26SShawn McCarney class PMBusWriteVoutCommandAction : public I2CAction 65a8119f26SShawn McCarney { 66a8119f26SShawn McCarney public: 67a8119f26SShawn McCarney // Specify which compiler-generated methods we want 68a8119f26SShawn McCarney PMBusWriteVoutCommandAction() = delete; 69a8119f26SShawn McCarney PMBusWriteVoutCommandAction(const PMBusWriteVoutCommandAction&) = delete; 70a8119f26SShawn McCarney PMBusWriteVoutCommandAction(PMBusWriteVoutCommandAction&&) = delete; 71a8119f26SShawn McCarney PMBusWriteVoutCommandAction& 72a8119f26SShawn McCarney operator=(const PMBusWriteVoutCommandAction&) = delete; 73a8119f26SShawn McCarney PMBusWriteVoutCommandAction& 74a8119f26SShawn McCarney operator=(PMBusWriteVoutCommandAction&&) = delete; 75a8119f26SShawn McCarney virtual ~PMBusWriteVoutCommandAction() = default; 76a8119f26SShawn McCarney 77a8119f26SShawn McCarney /** 78a8119f26SShawn McCarney * Constructor. 79a8119f26SShawn McCarney * 80a8119f26SShawn McCarney * Throws an exception if any of the input parameters are invalid. 81a8119f26SShawn McCarney * 82a8119f26SShawn McCarney * @param volts Optional volts value to write to VOUT_COMMAND. 83a8119f26SShawn McCarney * @param format Data format of the volts value written to VOUT_COMMAND. 84a8119f26SShawn McCarney * Currently the only supported format is linear. 85a8119f26SShawn McCarney * @param exponent Optional exponent to use to convert the volts value to 86a8119f26SShawn McCarney * linear data format. 87a8119f26SShawn McCarney * @param isVerified Specifies whether the updated value of VOUT_COMMAND is 88a8119f26SShawn McCarney * verified by reading it from the device. 89a8119f26SShawn McCarney */ PMBusWriteVoutCommandAction(std::optional<double> volts,pmbus_utils::VoutDataFormat format,std::optional<int8_t> exponent,bool isVerified)90a8119f26SShawn McCarney explicit PMBusWriteVoutCommandAction(std::optional<double> volts, 91a8119f26SShawn McCarney pmbus_utils::VoutDataFormat format, 92a8119f26SShawn McCarney std::optional<int8_t> exponent, 93a8119f26SShawn McCarney bool isVerified) : 94a8119f26SShawn McCarney volts{volts}, 95a8119f26SShawn McCarney format{format}, exponent{exponent}, isWriteVerified{isVerified} 96a8119f26SShawn McCarney { 97a8119f26SShawn McCarney // Currently only linear format is supported 98a8119f26SShawn McCarney if (format != pmbus_utils::VoutDataFormat::linear) 99a8119f26SShawn McCarney { 100a8119f26SShawn McCarney throw std::invalid_argument{"Unsupported data format specified"}; 101a8119f26SShawn McCarney } 102a8119f26SShawn McCarney } 103a8119f26SShawn McCarney 104a8119f26SShawn McCarney /** 105a8119f26SShawn McCarney * Executes this action. 106a8119f26SShawn McCarney * 107a8119f26SShawn McCarney * Writes a volts value to VOUT_COMMAND using the I2C interface. 108a8119f26SShawn McCarney * 109a8119f26SShawn McCarney * If a volts value was specified in the constructor, that value will be 110a8119f26SShawn McCarney * used. Otherwise the volts value will be obtained from the 111a8119f26SShawn McCarney * ActionEnvironment. 112a8119f26SShawn McCarney * 113a8119f26SShawn McCarney * The data format is specified in the constructor. Currently only the 114a8119f26SShawn McCarney * linear format is supported. 115a8119f26SShawn McCarney * 116a8119f26SShawn McCarney * An exponent value is required to convert the volts value to linear 117a8119f26SShawn McCarney * format. If an exponent value was specified in the constructor, that 118a8119f26SShawn McCarney * value will be used. Otherwise the exponent value will be obtained from 119a8119f26SShawn McCarney * the VOUT_MODE command. 120a8119f26SShawn McCarney * 121a8119f26SShawn McCarney * Write verification will be performed if specified in the constructor. 122a8119f26SShawn McCarney * 123a8119f26SShawn McCarney * The device is obtained from the ActionEnvironment. 124a8119f26SShawn McCarney * 125a8119f26SShawn McCarney * Throws an exception if an error occurs. 126a8119f26SShawn McCarney * 127a8119f26SShawn McCarney * @param environment action execution environment 128a8119f26SShawn McCarney * @return true 129a8119f26SShawn McCarney */ 130a8119f26SShawn McCarney virtual bool execute(ActionEnvironment& environment) override; 131a8119f26SShawn McCarney 132a8119f26SShawn McCarney /** 133a8119f26SShawn McCarney * Returns the optional exponent value used to convert the volts value to 134a8119f26SShawn McCarney * linear data format. 135a8119f26SShawn McCarney * 136a8119f26SShawn McCarney * @return optional exponent value 137a8119f26SShawn McCarney */ getExponent() const138a8119f26SShawn McCarney std::optional<int8_t> getExponent() const 139a8119f26SShawn McCarney { 140a8119f26SShawn McCarney return exponent; 141a8119f26SShawn McCarney } 142a8119f26SShawn McCarney 143a8119f26SShawn McCarney /** 144a8119f26SShawn McCarney * Returns the data format of the value written to VOUT_COMMAND. 145a8119f26SShawn McCarney * 146a8119f26SShawn McCarney * @return data format 147a8119f26SShawn McCarney */ getFormat() const148a8119f26SShawn McCarney pmbus_utils::VoutDataFormat getFormat() const 149a8119f26SShawn McCarney { 150a8119f26SShawn McCarney return format; 151a8119f26SShawn McCarney } 152a8119f26SShawn McCarney 153a8119f26SShawn McCarney /** 154a8119f26SShawn McCarney * Returns the optional volts value to write to VOUT_COMMAND. 155a8119f26SShawn McCarney * 156a8119f26SShawn McCarney * @return optional volts value 157a8119f26SShawn McCarney */ getVolts() const158a8119f26SShawn McCarney std::optional<double> getVolts() const 159a8119f26SShawn McCarney { 160a8119f26SShawn McCarney return volts; 161a8119f26SShawn McCarney } 162a8119f26SShawn McCarney 163a8119f26SShawn McCarney /** 164a8119f26SShawn McCarney * Returns whether write verification will be performed when writing to 165a8119f26SShawn McCarney * VOUT_COMMAND. 166a8119f26SShawn McCarney * 167a8119f26SShawn McCarney * @return true if write verification will be performed, false otherwise 168a8119f26SShawn McCarney */ isVerified() const169a8119f26SShawn McCarney bool isVerified() const 170a8119f26SShawn McCarney { 171a8119f26SShawn McCarney return isWriteVerified; 172a8119f26SShawn McCarney } 173a8119f26SShawn McCarney 174a8119f26SShawn McCarney /** 175a8119f26SShawn McCarney * Returns a string description of this action. 176a8119f26SShawn McCarney * 177a8119f26SShawn McCarney * @return description of action 178a8119f26SShawn McCarney */ 179a8119f26SShawn McCarney virtual std::string toString() const override; 180a8119f26SShawn McCarney 181a8119f26SShawn McCarney private: 182a8119f26SShawn McCarney /** 183a8119f26SShawn McCarney * Gets the exponent value to use to convert the volts value to linear data 184a8119f26SShawn McCarney * format. 185a8119f26SShawn McCarney * 186a8119f26SShawn McCarney * If an exponent value is defined for this action, that value is returned. 187a8119f26SShawn McCarney * Otherwise VOUT_MODE is read from the current device to obtain the 188a8119f26SShawn McCarney * exponent value. 189a8119f26SShawn McCarney * 190a8119f26SShawn McCarney * Throws an exception if an error occurs. 191a8119f26SShawn McCarney * 192*5b819f44SShawn McCarney * @param environment action execution environment 193a8119f26SShawn McCarney * @param interface I2C interface to the current device 194a8119f26SShawn McCarney * @return exponent value 195a8119f26SShawn McCarney */ 196*5b819f44SShawn McCarney int8_t getExponentValue(ActionEnvironment& environment, 197*5b819f44SShawn McCarney i2c::I2CInterface& interface); 198a8119f26SShawn McCarney 199a8119f26SShawn McCarney /** 200a8119f26SShawn McCarney * Gets the volts value to write to VOUT_COMMAND. 201a8119f26SShawn McCarney * 202a8119f26SShawn McCarney * If a volts value is defined for this action, that value is returned. 203a8119f26SShawn McCarney * Otherwise the volts value is obtained from the specified 204a8119f26SShawn McCarney * ActionEnvironment. 205a8119f26SShawn McCarney * 206a8119f26SShawn McCarney * Throws an exception if no volts value is defined. 207a8119f26SShawn McCarney * 208a8119f26SShawn McCarney * @param environment action execution environment 209a8119f26SShawn McCarney * @return volts value 210a8119f26SShawn McCarney */ 211a8119f26SShawn McCarney double getVoltsValue(ActionEnvironment& environment); 212a8119f26SShawn McCarney 213a8119f26SShawn McCarney /** 214a8119f26SShawn McCarney * Verifies the value written to VOUT_COMMAND. Reads the current value of 215a8119f26SShawn McCarney * VOUT_COMMAND and ensures that it matches the value written. 216a8119f26SShawn McCarney * 217a8119f26SShawn McCarney * Throws an exception if the values do not match or a communication error 218a8119f26SShawn McCarney * occurs. 219a8119f26SShawn McCarney * 220a8119f26SShawn McCarney * @param environment action execution environment 221a8119f26SShawn McCarney * @param interface I2C interface to the current device 222a8119f26SShawn McCarney * @param valueWritten linear format volts value written to VOUT_COMMAND 223a8119f26SShawn McCarney */ 224a8119f26SShawn McCarney void verifyWrite(ActionEnvironment& environment, 225a8119f26SShawn McCarney i2c::I2CInterface& interface, uint16_t valueWritten); 226a8119f26SShawn McCarney 227a8119f26SShawn McCarney /** 228a8119f26SShawn McCarney * Optional volts value to write. 229a8119f26SShawn McCarney */ 230a8119f26SShawn McCarney const std::optional<double> volts{}; 231a8119f26SShawn McCarney 232a8119f26SShawn McCarney /** 233a8119f26SShawn McCarney * Data format of the volts value written to VOUT_COMMAND. 234a8119f26SShawn McCarney */ 235a8119f26SShawn McCarney const pmbus_utils::VoutDataFormat format{}; 236a8119f26SShawn McCarney 237a8119f26SShawn McCarney /** 238a8119f26SShawn McCarney * Optional exponent value to use to convert the volts value to linear data 239a8119f26SShawn McCarney * format. 240a8119f26SShawn McCarney */ 241a8119f26SShawn McCarney const std::optional<int8_t> exponent{}; 242a8119f26SShawn McCarney 243a8119f26SShawn McCarney /** 244a8119f26SShawn McCarney * Indicates whether write verification will be performed when writing to 245a8119f26SShawn McCarney * VOUT_COMMAND. 246a8119f26SShawn McCarney */ 247a8119f26SShawn McCarney const bool isWriteVerified{false}; 248a8119f26SShawn McCarney }; 249a8119f26SShawn McCarney 250a8119f26SShawn McCarney } // namespace phosphor::power::regulators 251