xref: /openbmc/phosphor-bmc-code-mgmt/common/i2c/i2c.cpp (revision 994a77ff25aeb28b2cce7142d081af767f9eb542)
1 #include "i2c.hpp"
2 
3 #include <unistd.h>
4 
5 extern "C"
6 {
7 #include <i2c/smbus.h>
8 #include <linux/i2c-dev.h>
9 #include <linux/i2c.h>
10 }
11 
12 namespace phosphor::i2c
13 {
14 
15 int I2C::open()
16 {
17     int ret = 0;
18     fd = ::open(busStr.c_str(), O_RDWR);
19     if (fd < 0)
20     {
21         return fd;
22     }
23 
24     ret = ioctl(fd, I2C_SLAVE_FORCE, deviceNode);
25     if (ret < 0)
26     {
27         close();
28         return ret;
29     }
30 
31     return 0;
32 }
33 
34 // NOLINTBEGIN(readability-static-accessed-through-instance)
35 sdbusplus::async::task<bool> I2C::sendReceive(
36     uint8_t* writeData, uint8_t writeSize, uint8_t* readData,
37     uint8_t readSize) const
38 // NOLINTEND(readability-static-accessed-through-instance)
39 {
40     if (fd <= 0)
41     {
42         co_return false;
43     }
44 
45     struct i2c_msg msg[2];
46     struct i2c_rdwr_ioctl_data readWriteData;
47     int msgIndex = 0;
48 
49     if (writeSize)
50     {
51         msg[msgIndex].addr = deviceNode;
52         msg[msgIndex].flags = 0;
53         msg[msgIndex].len = writeSize;
54         msg[msgIndex].buf = writeData;
55         msgIndex++;
56     }
57 
58     if (readSize)
59     {
60         msg[msgIndex].addr = deviceNode;
61         msg[msgIndex].flags = I2C_M_RD;
62         msg[msgIndex].len = readSize;
63         msg[msgIndex].buf = readData;
64         msgIndex++;
65     }
66 
67     readWriteData.msgs = msg;
68     readWriteData.nmsgs = msgIndex;
69 
70     if (ioctl(fd, I2C_RDWR, &readWriteData) < 0)
71     {
72         co_return false;
73     }
74     co_return true;
75 }
76 
77 int I2C::close() const
78 {
79     return ::close(fd);
80 }
81 
82 } // namespace phosphor::i2c
83