165 lines
4.0 KiB
Diff
Executable File
165 lines
4.0 KiB
Diff
Executable File
From fa312c462de18b25a67f08c8f7be51f9fbdc4df5 Mon Sep 17 00:00:00 2001
|
|
From: wangjue <jue.wang2@luxshare-ict.com>
|
|
Date: Thu, 19 Sep 2024 15:11:18 +0800
|
|
Subject: [PATCH] Implement power reset control
|
|
|
|
Signed-off-by: wangjue <jue.wang2@luxshare-ict.com>
|
|
---
|
|
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 <nlohmann/json.hpp>
|
|
#include <phosphor-logging/lg2.hpp>
|
|
#include <sdbusplus/asio/object_server.hpp>
|
|
-
|
|
#include <filesystem>
|
|
#include <fstream>
|
|
#include <string_view>
|
|
+#include <thread>
|
|
+#include <chrono>
|
|
+#include <iostream>
|
|
+
|
|
+extern "C"
|
|
+{
|
|
+#include <i2c/smbus.h>
|
|
+#include <linux/i2c-dev.h>
|
|
+}
|
|
|
|
namespace power_control
|
|
{
|
|
@@ -1408,9 +1416,125 @@ static void forcePowerOff()
|
|
});
|
|
}
|
|
|
|
+int i2cWriteRead(std::string& i2cDev, const uint8_t slaveAddr,
|
|
+ std::vector<uint8_t> writeData,
|
|
+ std::vector<uint8_t>& 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<uint8_t> readBuf(1);
|
|
+ std::vector<uint8_t> 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
|
|
|