xref: /openbmc/phosphor-power/tools/i2c/i2c.hpp (revision 0c9a33d6)
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
229af82a5cSLei YU      */
23d45a9a6dSShawn McCarney     explicit I2CDevice(uint8_t busId, uint8_t devAddr,
24d45a9a6dSShawn McCarney                        InitialState initialState = InitialState::OPEN) :
25d45a9a6dSShawn McCarney         busId(busId),
2638ed88d6SShawn McCarney         devAddr(devAddr)
27ab1327c3SLei YU     {
289af82a5cSLei YU         busStr = "/dev/i2c-" + std::to_string(busId);
29d45a9a6dSShawn McCarney         if (initialState == InitialState::OPEN)
30d45a9a6dSShawn McCarney         {
319af82a5cSLei YU             open();
32ab1327c3SLei YU         }
33d45a9a6dSShawn McCarney     }
34ab1327c3SLei YU 
35d45a9a6dSShawn McCarney     /** @brief Invalid file descriptor */
36d45a9a6dSShawn McCarney     static constexpr int INVALID_FD = -1;
379af82a5cSLei YU 
3838ed88d6SShawn McCarney     /** @brief Empty adapter functionality value with no bit flags set */
3938ed88d6SShawn McCarney     static constexpr unsigned long NO_FUNCS = 0;
4038ed88d6SShawn McCarney 
419af82a5cSLei YU     /** @brief The I2C bus ID */
429af82a5cSLei YU     uint8_t busId;
439af82a5cSLei YU 
449af82a5cSLei YU     /** @brief The i2c device address in the bus */
459af82a5cSLei YU     uint8_t devAddr;
469af82a5cSLei YU 
479af82a5cSLei YU     /** @brief The file descriptor of the opened i2c device */
4838ed88d6SShawn McCarney     int fd = INVALID_FD;
499af82a5cSLei YU 
509af82a5cSLei YU     /** @brief The i2c bus path in /dev */
519af82a5cSLei YU     std::string busStr;
529af82a5cSLei YU 
5338ed88d6SShawn McCarney     /** @brief Cached I2C adapter functionality value */
5438ed88d6SShawn McCarney     unsigned long cachedFuncs = NO_FUNCS;
5538ed88d6SShawn McCarney 
56d45a9a6dSShawn McCarney     /** @brief Check that device interface is open
57d45a9a6dSShawn McCarney      *
58d45a9a6dSShawn McCarney      * @throw I2CException if device is not open
59d45a9a6dSShawn McCarney      */
60d45a9a6dSShawn McCarney     void checkIsOpen() const
61d45a9a6dSShawn McCarney     {
62d45a9a6dSShawn McCarney         if (!isOpen())
63d45a9a6dSShawn McCarney         {
64d45a9a6dSShawn McCarney             throw I2CException("Device not open", busStr, devAddr);
65d45a9a6dSShawn McCarney         }
66d45a9a6dSShawn McCarney     }
67d45a9a6dSShawn McCarney 
68d45a9a6dSShawn McCarney     /** @brief Close device without throwing an exception if an error occurs */
69d45a9a6dSShawn McCarney     void closeWithoutException() noexcept
70d45a9a6dSShawn McCarney     {
71d45a9a6dSShawn McCarney         try
72d45a9a6dSShawn McCarney         {
73d45a9a6dSShawn McCarney             close();
74d45a9a6dSShawn McCarney         }
75d45a9a6dSShawn McCarney         catch (...)
76*0c9a33d6SAdriana Kobylak         {}
77d45a9a6dSShawn McCarney     }
78d45a9a6dSShawn McCarney 
7938ed88d6SShawn McCarney     /** @brief Get I2C adapter functionality
8038ed88d6SShawn McCarney      *
8138ed88d6SShawn McCarney      * Caches the adapter functionality value since it shouldn't change after
8238ed88d6SShawn McCarney      * opening the device.
8338ed88d6SShawn McCarney      *
8438ed88d6SShawn McCarney      * @throw I2CException on error
8538ed88d6SShawn McCarney      * @return Adapter functionality value
8638ed88d6SShawn McCarney      */
8738ed88d6SShawn McCarney     unsigned long getFuncs();
8838ed88d6SShawn McCarney 
8992e89eb5SLei YU     /** @brief Check i2c adapter read functionality
9092e89eb5SLei YU      *
9192e89eb5SLei YU      * Check if the i2c adapter has the functionality specified by the SMBus
9292e89eb5SLei YU      * transaction type
9392e89eb5SLei YU      *
9492e89eb5SLei YU      * @param[in] type - The SMBus transaction type defined in linux/i2c.h
9592e89eb5SLei YU      *
9692e89eb5SLei YU      * @throw I2CException if the function is not supported
9792e89eb5SLei YU      */
9892e89eb5SLei YU     void checkReadFuncs(int type);
9992e89eb5SLei YU 
10034fb8bdaSLei YU     /** @brief Check i2c adapter write functionality
10134fb8bdaSLei YU      *
10234fb8bdaSLei YU      * Check if the i2c adapter has the functionality specified by the SMBus
10334fb8bdaSLei YU      * transaction type
10434fb8bdaSLei YU      *
10534fb8bdaSLei YU      * @param[in] type - The SMBus transaction type defined in linux/i2c.h
10634fb8bdaSLei YU      *
10734fb8bdaSLei YU      * @throw I2CException if the function is not supported
10834fb8bdaSLei YU      */
10934fb8bdaSLei YU     void checkWriteFuncs(int type);
11034fb8bdaSLei YU 
111ab1327c3SLei YU   public:
112d45a9a6dSShawn McCarney     /** @copydoc I2CInterface::~I2CInterface() */
1139af82a5cSLei YU     ~I2CDevice()
1149af82a5cSLei YU     {
115d45a9a6dSShawn McCarney         if (isOpen())
116d45a9a6dSShawn McCarney         {
117d45a9a6dSShawn McCarney             // Note: destructors must not throw exceptions
118d45a9a6dSShawn McCarney             closeWithoutException();
1199af82a5cSLei YU         }
120d45a9a6dSShawn McCarney     }
121d45a9a6dSShawn McCarney 
122d45a9a6dSShawn McCarney     /** @copydoc I2CInterface::open() */
123d45a9a6dSShawn McCarney     void open();
124d45a9a6dSShawn McCarney 
125d45a9a6dSShawn McCarney     /** @copydoc I2CInterface::isOpen() */
126d45a9a6dSShawn McCarney     bool isOpen() const
127d45a9a6dSShawn McCarney     {
128d45a9a6dSShawn McCarney         return (fd != INVALID_FD);
129d45a9a6dSShawn McCarney     }
130d45a9a6dSShawn McCarney 
131d45a9a6dSShawn McCarney     /** @copydoc I2CInterface::close() */
132d45a9a6dSShawn McCarney     void close();
133ab1327c3SLei YU 
134ab1327c3SLei YU     /** @copydoc I2CInterface::read(uint8_t&) */
135ab1327c3SLei YU     void read(uint8_t& data) override;
136ab1327c3SLei YU 
137ab1327c3SLei YU     /** @copydoc I2CInterface::read(uint8_t,uint8_t&) */
138ab1327c3SLei YU     void read(uint8_t addr, uint8_t& data) override;
139ab1327c3SLei YU 
140ab1327c3SLei YU     /** @copydoc I2CInterface::read(uint8_t,uint16_t&) */
141ab1327c3SLei YU     void read(uint8_t addr, uint16_t& data) override;
142ab1327c3SLei YU 
1431d103428SLei YU     /** @copydoc I2CInterface::read(uint8_t,uint8_t&,uint8_t*,Mode) */
1441d103428SLei YU     void read(uint8_t addr, uint8_t& size, uint8_t* data,
1451d103428SLei YU               Mode mode = Mode::SMBUS) override;
146ab1327c3SLei YU 
147ab1327c3SLei YU     /** @copydoc I2CInterface::write(uint8_t) */
148ab1327c3SLei YU     void write(uint8_t data) override;
149ab1327c3SLei YU 
150ab1327c3SLei YU     /** @copydoc I2CInterface::write(uint8_t,uint8_t) */
151ab1327c3SLei YU     void write(uint8_t addr, uint8_t data) override;
152ab1327c3SLei YU 
153ab1327c3SLei YU     /** @copydoc I2CInterface::write(uint8_t,uint16_t) */
154ab1327c3SLei YU     void write(uint8_t addr, uint16_t data) override;
155ab1327c3SLei YU 
1561d103428SLei YU     /** @copydoc I2CInterface::write(uint8_t,uint8_t,const uint8_t*,Mode) */
1571d103428SLei YU     void write(uint8_t addr, uint8_t size, const uint8_t* data,
1581d103428SLei YU                Mode mode = Mode::SMBUS) override;
159ab1327c3SLei YU 
160ab1327c3SLei YU     /** @brief Create an I2CInterface instance
161ab1327c3SLei YU      *
162d45a9a6dSShawn McCarney      * Automatically opens the I2CInterface if initialState is OPEN.
163d45a9a6dSShawn McCarney      *
164ab1327c3SLei YU      * @param[in] busId - The i2c bus ID
165ab1327c3SLei YU      * @param[in] devAddr - The device address of the i2c
166d45a9a6dSShawn McCarney      * @param[in] initialState - Initial state of the I2CInterface object
167ab1327c3SLei YU      *
168ab1327c3SLei YU      * @return The unique_ptr holding the I2CInterface
169ab1327c3SLei YU      */
170d45a9a6dSShawn McCarney     static std::unique_ptr<I2CInterface>
171d45a9a6dSShawn McCarney         create(uint8_t busId, uint8_t devAddr,
172d45a9a6dSShawn McCarney                InitialState initialState = InitialState::OPEN);
173ab1327c3SLei YU };
174ab1327c3SLei YU 
175ab1327c3SLei YU } // namespace i2c
176