From fa312c462de18b25a67f08c8f7be51f9fbdc4df5 Mon Sep 17 00:00:00 2001 From: wangjue Date: Thu, 19 Sep 2024 15:11:18 +0800 Subject: [PATCH] Implement power reset control Signed-off-by: wangjue --- src/power_control.cpp | 128 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 126 insertions(+), 2 deletions(-) diff --git a/src/power_control.cpp b/src/power_control.cpp index 7a47957..586d1e3 100644 --- a/src/power_control.cpp +++ b/src/power_control.cpp @@ -27,10 +27,18 @@ #include #include #include - #include #include #include +#include +#include +#include + +extern "C" +{ +#include +#include +} namespace power_control { @@ -1408,9 +1416,125 @@ static void forcePowerOff() }); } +int i2cWriteRead(std::string& i2cDev, const uint8_t slaveAddr, + std::vector writeData, + std::vector& readBuf) +{ + int fd = open(i2cDev.c_str(), O_RDWR | O_CLOEXEC); + if (fd < 0) + { + lg2::error("unable to open i2c device"); + return -1; + } + + const size_t writeCount = writeData.size(); + const size_t readCount = readBuf.size(); + + int msgCount = 0; + struct i2c_msg i2cmsg[2]; + + memset(i2cmsg, 0, sizeof(i2cmsg)); + + if (writeCount) + { + // Data will be writtern to the slave address + i2cmsg[msgCount].addr = slaveAddr; + i2cmsg[msgCount].flags = 0x00; + i2cmsg[msgCount].len = writeCount; + i2cmsg[msgCount].buf = writeData.data(); + msgCount++; + } + + if (readCount) + { + // Data will be read into the buffer from the slave address + i2cmsg[msgCount].addr = slaveAddr; + i2cmsg[msgCount].flags = I2C_M_RD; + i2cmsg[msgCount].len = readCount; + i2cmsg[msgCount].buf = readBuf.data(); + msgCount++; + } + + struct i2c_rdwr_ioctl_data msgReadWrite; + memset((void*)&msgReadWrite, 0, sizeof(msgReadWrite)); + msgReadWrite.msgs = i2cmsg; + msgReadWrite.nmsgs = msgCount; + + int ret = ioctl(fd, I2C_RDWR, &msgReadWrite); + close(fd); + if (ret < 0) + { + lg2::error("I2C Read Write Failed."); + return -1; + } + + if (readCount) + { + readBuf.resize(msgReadWrite.msgs[msgCount - 1].len); + } + + return 0; +} + +#define BIT2 (1 << 2) +void luxResetChassis() +{ + int ret = 0; + std::string i2cDev = "/dev/i2c-0"; + // Perform the combined write/read + + std::vector readBuf(1); + std::vector writeData = {0x30, 0x01}; + const uint8_t slaveAddr = 0x0D; + uint8_t regVal, tmp; + + ret = i2cWriteRead(i2cDev, slaveAddr, writeData, readBuf); + if (ret < 0) + { + lg2::error("i2c failed to read regVal."); + goto err; + } + + regVal = readBuf[0]; + readBuf.resize(0); + tmp = regVal & (~BIT2); + writeData.push_back(tmp); + + ret = i2cWriteRead(i2cDev, slaveAddr, writeData, readBuf); + if (ret < 0) + { + lg2::error("i2c WriteRead failed."); + goto err; + } + + writeData.pop_back(); + tmp = regVal | BIT2; + writeData.push_back(tmp); + + std::this_thread::sleep_for(std::chrono::milliseconds(400)); + + ret = i2cWriteRead(i2cDev, slaveAddr, writeData, readBuf); + if (ret < 0) + { + lg2::error("i2c WriteRead failed."); + goto err; + } + + lg2::error("Success to reset Host."); + return; +err: + lg2::error("Fail to reset Host."); + return; +} + static void reset() { - assertGPIOForMs(resetOutConfig, TimerMap["ResetPulseMs"]); + if (!resetOutConfig.lineName.empty()) + assertGPIOForMs(resetOutConfig, TimerMap["ResetPulseMs"]); + else { + std::thread myThread(luxResetChassis); + myThread.join(); + } } static void gracefulPowerOffTimerStart() -- 2.34.1