xref: /openbmc/phosphor-power/tools/i2c/i2c.hpp (revision d45a9a6d)
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      *
17*d45a9a6dSShawn McCarney      * Automatically opens the I2CDevice if initialState is OPEN.
18*d45a9a6dSShawn McCarney      *
199af82a5cSLei YU      * @param[in] busId - The i2c bus ID
209af82a5cSLei YU      * @param[in] devAddr - The device address of the I2C device
21*d45a9a6dSShawn McCarney      * @param[in] initialState - Initial state of the I2CDevice object
229af82a5cSLei YU      */
23*d45a9a6dSShawn McCarney     explicit I2CDevice(uint8_t busId, uint8_t devAddr,
24*d45a9a6dSShawn McCarney                        InitialState initialState = InitialState::OPEN) :
25*d45a9a6dSShawn McCarney         busId(busId),
26*d45a9a6dSShawn McCarney         devAddr(devAddr), fd(INVALID_FD)
27ab1327c3SLei YU     {
289af82a5cSLei YU         busStr = "/dev/i2c-" + std::to_string(busId);
29*d45a9a6dSShawn McCarney         if (initialState == InitialState::OPEN)
30*d45a9a6dSShawn McCarney         {
319af82a5cSLei YU             open();
32ab1327c3SLei YU         }
33*d45a9a6dSShawn McCarney     }
34ab1327c3SLei YU 
35*d45a9a6dSShawn McCarney     /** @brief Invalid file descriptor */
36*d45a9a6dSShawn McCarney     static constexpr int INVALID_FD = -1;
379af82a5cSLei YU 
389af82a5cSLei YU     /** @brief The I2C bus ID */
399af82a5cSLei YU     uint8_t busId;
409af82a5cSLei YU 
419af82a5cSLei YU     /** @brief The i2c device address in the bus */
429af82a5cSLei YU     uint8_t devAddr;
439af82a5cSLei YU 
449af82a5cSLei YU     /** @brief The file descriptor of the opened i2c device */
459af82a5cSLei YU     int fd;
469af82a5cSLei YU 
479af82a5cSLei YU     /** @brief The i2c bus path in /dev */
489af82a5cSLei YU     std::string busStr;
499af82a5cSLei YU 
50*d45a9a6dSShawn McCarney     /** @brief Check that device interface is open
51*d45a9a6dSShawn McCarney      *
52*d45a9a6dSShawn McCarney      * @throw I2CException if device is not open
53*d45a9a6dSShawn McCarney      */
54*d45a9a6dSShawn McCarney     void checkIsOpen() const
55*d45a9a6dSShawn McCarney     {
56*d45a9a6dSShawn McCarney         if (!isOpen())
57*d45a9a6dSShawn McCarney         {
58*d45a9a6dSShawn McCarney             throw I2CException("Device not open", busStr, devAddr);
59*d45a9a6dSShawn McCarney         }
60*d45a9a6dSShawn McCarney     }
61*d45a9a6dSShawn McCarney 
62*d45a9a6dSShawn McCarney     /** @brief Close device without throwing an exception if an error occurs */
63*d45a9a6dSShawn McCarney     void closeWithoutException() noexcept
64*d45a9a6dSShawn McCarney     {
65*d45a9a6dSShawn McCarney         try
66*d45a9a6dSShawn McCarney         {
67*d45a9a6dSShawn McCarney             close();
68*d45a9a6dSShawn McCarney         }
69*d45a9a6dSShawn McCarney         catch (...)
70*d45a9a6dSShawn McCarney         {
71*d45a9a6dSShawn McCarney         }
72*d45a9a6dSShawn McCarney     }
73*d45a9a6dSShawn McCarney 
7492e89eb5SLei YU     /** @brief Check i2c adapter read functionality
7592e89eb5SLei YU      *
7692e89eb5SLei YU      * Check if the i2c adapter has the functionality specified by the SMBus
7792e89eb5SLei YU      * transaction type
7892e89eb5SLei YU      *
7992e89eb5SLei YU      * @param[in] type - The SMBus transaction type defined in linux/i2c.h
8092e89eb5SLei YU      *
8192e89eb5SLei YU      * @throw I2CException if the function is not supported
8292e89eb5SLei YU      */
8392e89eb5SLei YU     void checkReadFuncs(int type);
8492e89eb5SLei YU 
8534fb8bdaSLei YU     /** @brief Check i2c adapter write functionality
8634fb8bdaSLei YU      *
8734fb8bdaSLei YU      * Check if the i2c adapter has the functionality specified by the SMBus
8834fb8bdaSLei YU      * transaction type
8934fb8bdaSLei YU      *
9034fb8bdaSLei YU      * @param[in] type - The SMBus transaction type defined in linux/i2c.h
9134fb8bdaSLei YU      *
9234fb8bdaSLei YU      * @throw I2CException if the function is not supported
9334fb8bdaSLei YU      */
9434fb8bdaSLei YU     void checkWriteFuncs(int type);
9534fb8bdaSLei YU 
96ab1327c3SLei YU   public:
97*d45a9a6dSShawn McCarney     /** @copydoc I2CInterface::~I2CInterface() */
989af82a5cSLei YU     ~I2CDevice()
999af82a5cSLei YU     {
100*d45a9a6dSShawn McCarney         if (isOpen())
101*d45a9a6dSShawn McCarney         {
102*d45a9a6dSShawn McCarney             // Note: destructors must not throw exceptions
103*d45a9a6dSShawn McCarney             closeWithoutException();
1049af82a5cSLei YU         }
105*d45a9a6dSShawn McCarney     }
106*d45a9a6dSShawn McCarney 
107*d45a9a6dSShawn McCarney     /** @copydoc I2CInterface::open() */
108*d45a9a6dSShawn McCarney     void open();
109*d45a9a6dSShawn McCarney 
110*d45a9a6dSShawn McCarney     /** @copydoc I2CInterface::isOpen() */
111*d45a9a6dSShawn McCarney     bool isOpen() const
112*d45a9a6dSShawn McCarney     {
113*d45a9a6dSShawn McCarney         return (fd != INVALID_FD);
114*d45a9a6dSShawn McCarney     }
115*d45a9a6dSShawn McCarney 
116*d45a9a6dSShawn McCarney     /** @copydoc I2CInterface::close() */
117*d45a9a6dSShawn McCarney     void close();
118ab1327c3SLei YU 
119ab1327c3SLei YU     /** @copydoc I2CInterface::read(uint8_t&) */
120ab1327c3SLei YU     void read(uint8_t& data) override;
121ab1327c3SLei YU 
122ab1327c3SLei YU     /** @copydoc I2CInterface::read(uint8_t,uint8_t&) */
123ab1327c3SLei YU     void read(uint8_t addr, uint8_t& data) override;
124ab1327c3SLei YU 
125ab1327c3SLei YU     /** @copydoc I2CInterface::read(uint8_t,uint16_t&) */
126ab1327c3SLei YU     void read(uint8_t addr, uint16_t& data) override;
127ab1327c3SLei YU 
1281d103428SLei YU     /** @copydoc I2CInterface::read(uint8_t,uint8_t&,uint8_t*,Mode) */
1291d103428SLei YU     void read(uint8_t addr, uint8_t& size, uint8_t* data,
1301d103428SLei YU               Mode mode = Mode::SMBUS) override;
131ab1327c3SLei YU 
132ab1327c3SLei YU     /** @copydoc I2CInterface::write(uint8_t) */
133ab1327c3SLei YU     void write(uint8_t data) override;
134ab1327c3SLei YU 
135ab1327c3SLei YU     /** @copydoc I2CInterface::write(uint8_t,uint8_t) */
136ab1327c3SLei YU     void write(uint8_t addr, uint8_t data) override;
137ab1327c3SLei YU 
138ab1327c3SLei YU     /** @copydoc I2CInterface::write(uint8_t,uint16_t) */
139ab1327c3SLei YU     void write(uint8_t addr, uint16_t data) override;
140ab1327c3SLei YU 
1411d103428SLei YU     /** @copydoc I2CInterface::write(uint8_t,uint8_t,const uint8_t*,Mode) */
1421d103428SLei YU     void write(uint8_t addr, uint8_t size, const uint8_t* data,
1431d103428SLei YU                Mode mode = Mode::SMBUS) override;
144ab1327c3SLei YU 
145ab1327c3SLei YU     /** @brief Create an I2CInterface instance
146ab1327c3SLei YU      *
147*d45a9a6dSShawn McCarney      * Automatically opens the I2CInterface if initialState is OPEN.
148*d45a9a6dSShawn McCarney      *
149ab1327c3SLei YU      * @param[in] busId - The i2c bus ID
150ab1327c3SLei YU      * @param[in] devAddr - The device address of the i2c
151*d45a9a6dSShawn McCarney      * @param[in] initialState - Initial state of the I2CInterface object
152ab1327c3SLei YU      *
153ab1327c3SLei YU      * @return The unique_ptr holding the I2CInterface
154ab1327c3SLei YU      */
155*d45a9a6dSShawn McCarney     static std::unique_ptr<I2CInterface>
156*d45a9a6dSShawn McCarney         create(uint8_t busId, uint8_t devAddr,
157*d45a9a6dSShawn McCarney                InitialState initialState = InitialState::OPEN);
158ab1327c3SLei YU };
159ab1327c3SLei YU 
160ab1327c3SLei YU } // namespace i2c
161