xref: /openbmc/phosphor-power/tools/i2c/i2c.hpp (revision b9cf0d2b)
1ab1327c3SLei YU #pragma once
2ab1327c3SLei YU 
3ab1327c3SLei YU #include "i2c_interface.hpp"
4ab1327c3SLei YU 
5ab1327c3SLei YU namespace i2c
6ab1327c3SLei YU {
7ab1327c3SLei YU 
8ab1327c3SLei YU class I2CDevice : public I2CInterface
9ab1327c3SLei YU {
10ab1327c3SLei YU   private:
11ab1327c3SLei YU     I2CDevice() = delete;
12ab1327c3SLei YU 
139af82a5cSLei YU     /** @brief Constructor
149af82a5cSLei YU      *
159af82a5cSLei YU      * Construct I2CDevice object from the bus id and device address
169af82a5cSLei YU      *
17d45a9a6dSShawn McCarney      * Automatically opens the I2CDevice if initialState is OPEN.
18d45a9a6dSShawn McCarney      *
199af82a5cSLei YU      * @param[in] busId - The i2c bus ID
209af82a5cSLei YU      * @param[in] devAddr - The device address of the I2C device
21d45a9a6dSShawn McCarney      * @param[in] initialState - Initial state of the I2CDevice object
22770de580SShawn McCarney      * @param[in] maxRetries - Maximum number of times to retry an I2C operation
239af82a5cSLei YU      */
I2CDevice(uint8_t busId,uint8_t devAddr,InitialState initialState=InitialState::OPEN,int maxRetries=0)24d45a9a6dSShawn McCarney     explicit I2CDevice(uint8_t busId, uint8_t devAddr,
25770de580SShawn McCarney                        InitialState initialState = InitialState::OPEN,
26770de580SShawn McCarney                        int maxRetries = 0) :
27d45a9a6dSShawn McCarney         busId(busId),
28*b9cf0d2bSGeorge Liu         devAddr(devAddr), maxRetries(maxRetries),
29*b9cf0d2bSGeorge Liu         busStr("/dev/i2c-" + std::to_string(busId))
30ab1327c3SLei YU     {
31d45a9a6dSShawn McCarney         if (initialState == InitialState::OPEN)
32d45a9a6dSShawn McCarney         {
339af82a5cSLei YU             open();
34ab1327c3SLei YU         }
35d45a9a6dSShawn McCarney     }
36ab1327c3SLei YU 
37d45a9a6dSShawn McCarney     /** @brief Invalid file descriptor */
38d45a9a6dSShawn McCarney     static constexpr int INVALID_FD = -1;
399af82a5cSLei YU 
4038ed88d6SShawn McCarney     /** @brief Empty adapter functionality value with no bit flags set */
4138ed88d6SShawn McCarney     static constexpr unsigned long NO_FUNCS = 0;
4238ed88d6SShawn McCarney 
439af82a5cSLei YU     /** @brief The I2C bus ID */
449af82a5cSLei YU     uint8_t busId;
459af82a5cSLei YU 
469af82a5cSLei YU     /** @brief The i2c device address in the bus */
479af82a5cSLei YU     uint8_t devAddr;
489af82a5cSLei YU 
49770de580SShawn McCarney     /** @brief Maximum number of times to retry an I2C operation */
50770de580SShawn McCarney     int maxRetries = 0;
51770de580SShawn McCarney 
529af82a5cSLei YU     /** @brief The file descriptor of the opened i2c device */
5338ed88d6SShawn McCarney     int fd = INVALID_FD;
549af82a5cSLei YU 
559af82a5cSLei YU     /** @brief The i2c bus path in /dev */
569af82a5cSLei YU     std::string busStr;
579af82a5cSLei YU 
5838ed88d6SShawn McCarney     /** @brief Cached I2C adapter functionality value */
5938ed88d6SShawn McCarney     unsigned long cachedFuncs = NO_FUNCS;
6038ed88d6SShawn McCarney 
61d45a9a6dSShawn McCarney     /** @brief Check that device interface is open
62d45a9a6dSShawn McCarney      *
63d45a9a6dSShawn McCarney      * @throw I2CException if device is not open
64d45a9a6dSShawn McCarney      */
checkIsOpen() const65d45a9a6dSShawn McCarney     void checkIsOpen() const
66d45a9a6dSShawn McCarney     {
67d45a9a6dSShawn McCarney         if (!isOpen())
68d45a9a6dSShawn McCarney         {
69d45a9a6dSShawn McCarney             throw I2CException("Device not open", busStr, devAddr);
70d45a9a6dSShawn McCarney         }
71d45a9a6dSShawn McCarney     }
72d45a9a6dSShawn McCarney 
73d45a9a6dSShawn McCarney     /** @brief Close device without throwing an exception if an error occurs */
closeWithoutException()74d45a9a6dSShawn McCarney     void closeWithoutException() noexcept
75d45a9a6dSShawn McCarney     {
76d45a9a6dSShawn McCarney         try
77d45a9a6dSShawn McCarney         {
78d45a9a6dSShawn McCarney             close();
79d45a9a6dSShawn McCarney         }
80d45a9a6dSShawn McCarney         catch (...)
810c9a33d6SAdriana Kobylak         {}
82d45a9a6dSShawn McCarney     }
83d45a9a6dSShawn McCarney 
8438ed88d6SShawn McCarney     /** @brief Get I2C adapter functionality
8538ed88d6SShawn McCarney      *
8638ed88d6SShawn McCarney      * Caches the adapter functionality value since it shouldn't change after
8738ed88d6SShawn McCarney      * opening the device.
8838ed88d6SShawn McCarney      *
8938ed88d6SShawn McCarney      * @throw I2CException on error
9038ed88d6SShawn McCarney      * @return Adapter functionality value
9138ed88d6SShawn McCarney      */
9238ed88d6SShawn McCarney     unsigned long getFuncs();
9338ed88d6SShawn McCarney 
9492e89eb5SLei YU     /** @brief Check i2c adapter read functionality
9592e89eb5SLei YU      *
9692e89eb5SLei YU      * Check if the i2c adapter has the functionality specified by the SMBus
9792e89eb5SLei YU      * transaction type
9892e89eb5SLei YU      *
9992e89eb5SLei YU      * @param[in] type - The SMBus transaction type defined in linux/i2c.h
10092e89eb5SLei YU      *
10192e89eb5SLei YU      * @throw I2CException if the function is not supported
10292e89eb5SLei YU      */
10392e89eb5SLei YU     void checkReadFuncs(int type);
10492e89eb5SLei YU 
10534fb8bdaSLei YU     /** @brief Check i2c adapter write functionality
10634fb8bdaSLei YU      *
10734fb8bdaSLei YU      * Check if the i2c adapter has the functionality specified by the SMBus
10834fb8bdaSLei YU      * transaction type
10934fb8bdaSLei YU      *
11034fb8bdaSLei YU      * @param[in] type - The SMBus transaction type defined in linux/i2c.h
11134fb8bdaSLei YU      *
11234fb8bdaSLei YU      * @throw I2CException if the function is not supported
11334fb8bdaSLei YU      */
11434fb8bdaSLei YU     void checkWriteFuncs(int type);
11534fb8bdaSLei YU 
116ab1327c3SLei YU   public:
117d45a9a6dSShawn McCarney     /** @copydoc I2CInterface::~I2CInterface() */
~I2CDevice()1189af82a5cSLei YU     ~I2CDevice()
1199af82a5cSLei YU     {
120d45a9a6dSShawn McCarney         if (isOpen())
121d45a9a6dSShawn McCarney         {
122d45a9a6dSShawn McCarney             // Note: destructors must not throw exceptions
123d45a9a6dSShawn McCarney             closeWithoutException();
1249af82a5cSLei YU         }
125d45a9a6dSShawn McCarney     }
126d45a9a6dSShawn McCarney 
127d45a9a6dSShawn McCarney     /** @copydoc I2CInterface::open() */
128d45a9a6dSShawn McCarney     void open();
129d45a9a6dSShawn McCarney 
130d45a9a6dSShawn McCarney     /** @copydoc I2CInterface::isOpen() */
isOpen() const131d45a9a6dSShawn McCarney     bool isOpen() const
132d45a9a6dSShawn McCarney     {
133d45a9a6dSShawn McCarney         return (fd != INVALID_FD);
134d45a9a6dSShawn McCarney     }
135d45a9a6dSShawn McCarney 
136d45a9a6dSShawn McCarney     /** @copydoc I2CInterface::close() */
137d45a9a6dSShawn McCarney     void close();
138ab1327c3SLei YU 
139ab1327c3SLei YU     /** @copydoc I2CInterface::read(uint8_t&) */
140ab1327c3SLei YU     void read(uint8_t& data) override;
141ab1327c3SLei YU 
142ab1327c3SLei YU     /** @copydoc I2CInterface::read(uint8_t,uint8_t&) */
143ab1327c3SLei YU     void read(uint8_t addr, uint8_t& data) override;
144ab1327c3SLei YU 
145ab1327c3SLei YU     /** @copydoc I2CInterface::read(uint8_t,uint16_t&) */
146ab1327c3SLei YU     void read(uint8_t addr, uint16_t& data) override;
147ab1327c3SLei YU 
1481d103428SLei YU     /** @copydoc I2CInterface::read(uint8_t,uint8_t&,uint8_t*,Mode) */
1491d103428SLei YU     void read(uint8_t addr, uint8_t& size, uint8_t* data,
1501d103428SLei YU               Mode mode = Mode::SMBUS) override;
151ab1327c3SLei YU 
152ab1327c3SLei YU     /** @copydoc I2CInterface::write(uint8_t) */
153ab1327c3SLei YU     void write(uint8_t data) override;
154ab1327c3SLei YU 
155ab1327c3SLei YU     /** @copydoc I2CInterface::write(uint8_t,uint8_t) */
156ab1327c3SLei YU     void write(uint8_t addr, uint8_t data) override;
157ab1327c3SLei YU 
158ab1327c3SLei YU     /** @copydoc I2CInterface::write(uint8_t,uint16_t) */
159ab1327c3SLei YU     void write(uint8_t addr, uint16_t data) override;
160ab1327c3SLei YU 
1611d103428SLei YU     /** @copydoc I2CInterface::write(uint8_t,uint8_t,const uint8_t*,Mode) */
1621d103428SLei YU     void write(uint8_t addr, uint8_t size, const uint8_t* data,
1631d103428SLei YU                Mode mode = Mode::SMBUS) override;
164ab1327c3SLei YU 
165ab1327c3SLei YU     /** @brief Create an I2CInterface instance
166ab1327c3SLei YU      *
167d45a9a6dSShawn McCarney      * Automatically opens the I2CInterface if initialState is OPEN.
168d45a9a6dSShawn McCarney      *
169ab1327c3SLei YU      * @param[in] busId - The i2c bus ID
170ab1327c3SLei YU      * @param[in] devAddr - The device address of the i2c
171d45a9a6dSShawn McCarney      * @param[in] initialState - Initial state of the I2CInterface object
172770de580SShawn McCarney      * @param[in] maxRetries - Maximum number of times to retry an I2C operation
173ab1327c3SLei YU      *
174ab1327c3SLei YU      * @return The unique_ptr holding the I2CInterface
175ab1327c3SLei YU      */
176d45a9a6dSShawn McCarney     static std::unique_ptr<I2CInterface>
177d45a9a6dSShawn McCarney         create(uint8_t busId, uint8_t devAddr,
178770de580SShawn McCarney                InitialState initialState = InitialState::OPEN,
179770de580SShawn McCarney                int maxRetries = 0);
180ab1327c3SLei YU };
181ab1327c3SLei YU 
182ab1327c3SLei YU } // namespace i2c
183