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 
21 #include <cstdint>
22 #include <stdexcept>
23 #include <string>
24 
25 namespace phosphor::power::regulators
26 {
27 
28 /**
29  * @class I2CCompareBitAction
30  *
31  * Compares a bit in a device register to a value.  Communicates with the device
32  * directly using the I2C interface.
33  *
34  * Implements the i2c_compare_bit action in the JSON config file.
35  */
36 class I2CCompareBitAction : public I2CAction
37 {
38   public:
39     // Specify which compiler-generated methods we want
40     I2CCompareBitAction() = delete;
41     I2CCompareBitAction(const I2CCompareBitAction&) = delete;
42     I2CCompareBitAction(I2CCompareBitAction&&) = delete;
43     I2CCompareBitAction& operator=(const I2CCompareBitAction&) = delete;
44     I2CCompareBitAction& operator=(I2CCompareBitAction&&) = delete;
45     virtual ~I2CCompareBitAction() = default;
46 
47     /**
48      * Constructor.
49      *
50      * Throws an exception if any of the input parameters are invalid.
51      *
52      * @param reg Device register address.  Note: named 'reg' because 'register'
53      *            is a reserved keyword.
54      * @param position Bit position.  Must be in the range 0-7.  Bit 0 is the
55      *                 least significant bit.
56      * @param value Expected bit value.  Must be 0 or 1.
57      */
I2CCompareBitAction(uint8_t reg,uint8_t position,uint8_t value)58     explicit I2CCompareBitAction(uint8_t reg, uint8_t position, uint8_t value) :
59         reg{reg}, position{position}, value{value}
60     {
61         if (position > 7)
62         {
63             throw std::invalid_argument{
64                 "Invalid bit position: " +
65                 std::to_string(static_cast<unsigned>(position))};
66         }
67 
68         if (value > 1)
69         {
70             throw std::invalid_argument{
71                 "Invalid bit value: " +
72                 std::to_string(static_cast<unsigned>(value))};
73         }
74     }
75 
76     /**
77      * Executes this action.
78      *
79      * Compares a bit in a device register to a value using the I2C interface.
80      *
81      * The device register, bit position, and bit value were specified in the
82      * constructor.
83      *
84      * The device is obtained from the specified action environment.
85      *
86      * Throws an exception if an error occurs.
87      *
88      * @param environment action execution environment
89      * @return true if the register bit contained the expected value, otherwise
90      *         returns false.
91      */
92     virtual bool execute(ActionEnvironment& environment) override;
93 
94     /**
95      * Returns the device register address.
96      *
97      * @return register address
98      */
getRegister() const99     uint8_t getRegister() const
100     {
101         return reg;
102     }
103 
104     /**
105      * Returns the bit position.
106      *
107      * Value is in the range 0-7.  Bit 0 is the least significant bit.
108      *
109      * @return bit position
110      */
getPosition() const111     uint8_t getPosition() const
112     {
113         return position;
114     }
115 
116     /**
117      * Returns the expected bit value.
118      *
119      * Value is 0 or 1.
120      *
121      * @return expected bit value
122      */
getValue() const123     uint8_t getValue() const
124     {
125         return value;
126     }
127 
128     /**
129      * Returns a string description of this action.
130      *
131      * @return description of action
132      */
133     virtual std::string toString() const override;
134 
135   private:
136     /**
137      * Device register address.  Note: named 'reg' because 'register' is a
138      * reserved keyword.
139      */
140     const uint8_t reg{0x00};
141 
142     /**
143      * Bit position.  Must be in the range 0-7.  Bit 0 is the least significant
144      * bit.
145      */
146     const uint8_t position{0};
147 
148     /**
149      * Expected bit value.  Must be 0 or 1.
150      */
151     const uint8_t value{0};
152 };
153 
154 } // namespace phosphor::power::regulators
155