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
open()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
sendReceive(uint8_t * writeData,uint8_t writeSize,uint8_t * readData,uint8_t readSize) const34 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
sendReceive(const std::vector<uint8_t> & writeData,std::vector<uint8_t> & readData) const79 bool I2C::sendReceive(const std::vector<uint8_t>& writeData,
80 std::vector<uint8_t>& readData) const
81 {
82 bool result = true;
83
84 if (fd <= 0)
85 {
86 return false;
87 }
88 else
89 {
90 struct i2c_msg msg[2];
91 struct i2c_rdwr_ioctl_data readWriteData;
92 int msgIndex = 0;
93
94 if (!writeData.empty())
95 {
96 msg[msgIndex].addr = deviceNode;
97 msg[msgIndex].flags = 0;
98 msg[msgIndex].len = writeData.size();
99 msg[msgIndex].buf = const_cast<uint8_t*>(writeData.data());
100 msgIndex++;
101 }
102
103 if (!readData.empty())
104 {
105 msg[msgIndex].addr = deviceNode;
106 msg[msgIndex].flags = I2C_M_RD;
107 msg[msgIndex].len = readData.size();
108 msg[msgIndex].buf = readData.data();
109 msgIndex++;
110 }
111
112 readWriteData.msgs = msg;
113 readWriteData.nmsgs = msgIndex;
114
115 if (ioctl(fd, I2C_RDWR, &readWriteData) < 0)
116 {
117 result = false;
118 }
119 }
120
121 return result;
122 }
123
close() const124 int I2C::close() const
125 {
126 return ::close(fd);
127 }
128
129 } // namespace phosphor::i2c
130