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 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 124 int I2C::close() const 125 { 126 return ::close(fd); 127 } 128 129 } // namespace phosphor::i2c 130