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 I2CWriteBitAction
30  *
31  * Writes a bit to a device register.  Communicates with the device directly
32  * using the I2C interface.
33  *
34  * Implements the i2c_write_bit action in the JSON config file.
35  */
36 class I2CWriteBitAction : public I2CAction
37 {
38   public:
39     // Specify which compiler-generated methods we want
40     I2CWriteBitAction() = delete;
41     I2CWriteBitAction(const I2CWriteBitAction&) = delete;
42     I2CWriteBitAction(I2CWriteBitAction&&) = delete;
43     I2CWriteBitAction& operator=(const I2CWriteBitAction&) = delete;
44     I2CWriteBitAction& operator=(I2CWriteBitAction&&) = delete;
45     virtual ~I2CWriteBitAction() = 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 Bit value to write.  Must be 0 or 1.
57      */
I2CWriteBitAction(uint8_t reg,uint8_t position,uint8_t value)58     explicit I2CWriteBitAction(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      * Writes a bit to a device register 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
90      */
91     virtual bool execute(ActionEnvironment& environment) override;
92 
93     /**
94      * Returns the device register address.
95      *
96      * @return register address
97      */
getRegister() const98     uint8_t getRegister() const
99     {
100         return reg;
101     }
102 
103     /**
104      * Returns the bit position.
105      *
106      * Value is in the range 0-7.  Bit 0 is the least significant bit.
107      *
108      * @return bit position
109      */
getPosition() const110     uint8_t getPosition() const
111     {
112         return position;
113     }
114 
115     /**
116      * Returns the bit value to write.
117      *
118      * Value is 0 or 1.
119      *
120      * @return bit value
121      */
getValue() const122     uint8_t getValue() const
123     {
124         return value;
125     }
126 
127     /**
128      * Returns a string description of this action.
129      *
130      * @return description of action
131      */
132     virtual std::string toString() const override;
133 
134   private:
135     /**
136      * Device register address.  Note: named 'reg' because 'register' is a
137      * reserved keyword.
138      */
139     const uint8_t reg{0x00};
140 
141     /**
142      * Bit position.  Must be in the range 0-7.  Bit 0 is the least significant
143      * bit.
144      */
145     const uint8_t position{0};
146 
147     /**
148      * Bit value to write.  Must be 0 or 1.
149      */
150     const uint8_t value{0};
151 };
152 
153 } // namespace phosphor::power::regulators
154