blob: 653f823a9f68a91a28d35bd4cf0b59c9577806a1 [file] [log] [blame]
Christopher Meis7e446a42024-10-22 09:36:41 +02001#include "i2c.hpp"
2
3#include <unistd.h>
4
5extern "C"
6{
7#include <i2c/smbus.h>
8#include <linux/i2c-dev.h>
9#include <linux/i2c.h>
10}
11
12namespace phosphor::i2c
13{
14
15int 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
Christopher Meis7e446a42024-10-22 09:36:41 +020034sdbusplus::async::task<bool> I2C::sendReceive(
35 uint8_t* writeData, uint8_t writeSize, uint8_t* readData,
36 uint8_t readSize) const
Christopher Meis7e446a42024-10-22 09:36:41 +020037{
Daniel Hsuf6470b52025-02-26 15:03:47 +080038 bool result = true;
39
Christopher Meis7e446a42024-10-22 09:36:41 +020040 if (fd <= 0)
41 {
Daniel Hsuf6470b52025-02-26 15:03:47 +080042 result = false;
Christopher Meis7e446a42024-10-22 09:36:41 +020043 }
Daniel Hsuf6470b52025-02-26 15:03:47 +080044 else
Christopher Meis7e446a42024-10-22 09:36:41 +020045 {
Daniel Hsuf6470b52025-02-26 15:03:47 +080046 struct i2c_msg msg[2];
47 struct i2c_rdwr_ioctl_data readWriteData;
48 int msgIndex = 0;
Christopher Meis7e446a42024-10-22 09:36:41 +020049
Daniel Hsuf6470b52025-02-26 15:03:47 +080050 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 }
Christopher Meis7e446a42024-10-22 09:36:41 +020058
Daniel Hsuf6470b52025-02-26 15:03:47 +080059 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 }
Christopher Meis7e446a42024-10-22 09:36:41 +020067
Daniel Hsuf6470b52025-02-26 15:03:47 +080068 readWriteData.msgs = msg;
69 readWriteData.nmsgs = msgIndex;
70
71 if (ioctl(fd, I2C_RDWR, &readWriteData) < 0)
72 {
73 result = false;
74 }
Christopher Meis7e446a42024-10-22 09:36:41 +020075 }
Daniel Hsuf6470b52025-02-26 15:03:47 +080076 co_return result;
Christopher Meis7e446a42024-10-22 09:36:41 +020077}
78
Daniel Hsu37a30142025-06-12 17:57:24 +080079bool 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
Christopher Meis7e446a42024-10-22 09:36:41 +0200124int I2C::close() const
125{
126 return ::close(fd);
127}
128
129} // namespace phosphor::i2c