xref: /openbmc/phosphor-bmc-code-mgmt/common/i2c/i2c.cpp (revision bd5081f0b99a27dde8101576524b2c02a4a580b6)
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 sdbusplus::async::task<bool> I2C::sendReceive(
35     uint8_t* writeData, uint8_t writeSize, uint8_t* readData,
36     uint8_t readSize) const
37 {
38     bool result = true;
39 
40     if (fd <= 0)
41     {
42         result = false;
43     }
44     else
45     {
46         struct i2c_msg msg[2];
47         struct i2c_rdwr_ioctl_data readWriteData;
48         int msgIndex = 0;
49 
50         if (writeSize)
51         {
52             msg[msgIndex].addr = deviceNode;
53             msg[msgIndex].flags = 0;
54             msg[msgIndex].len = writeSize;
55             msg[msgIndex].buf = writeData;
56             msgIndex++;
57         }
58 
59         if (readSize)
60         {
61             msg[msgIndex].addr = deviceNode;
62             msg[msgIndex].flags = I2C_M_RD;
63             msg[msgIndex].len = readSize;
64             msg[msgIndex].buf = readData;
65             msgIndex++;
66         }
67 
68         readWriteData.msgs = msg;
69         readWriteData.nmsgs = msgIndex;
70 
71         if (ioctl(fd, I2C_RDWR, &readWriteData) < 0)
72         {
73             result = false;
74         }
75     }
76     co_return result;
77 }
78 
79 int I2C::close() const
80 {
81     return ::close(fd);
82 }
83 
84 } // namespace phosphor::i2c
85