diff options
Diffstat (limited to 'dumpstate/dump_power.cpp')
-rw-r--r-- | dumpstate/dump_power.cpp | 935 |
1 files changed, 935 insertions, 0 deletions
diff --git a/dumpstate/dump_power.cpp b/dumpstate/dump_power.cpp new file mode 100644 index 0000000..a79921b --- /dev/null +++ b/dumpstate/dump_power.cpp @@ -0,0 +1,935 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <cstring> +#include <dirent.h> +#include <dump/pixel_dump.h> +#include <fstream> +#include <stdio.h> +#include <stdlib.h> +#include <sys/sysinfo.h> +#include <time.h> +#include <vector> + +#include <android-base/file.h> +#include <android-base/strings.h> +#include "DumpstateUtil.h" + + +void printTitle(const char *msg) { + printf("\n------ %s ------\n", msg); +} + +int getCommandOutput(const char *cmd, std::string *output) { + char buffer[1024]; + FILE *pipe = popen(cmd, "r"); + if (!pipe) { + return -1; + } + + while (fgets(buffer, sizeof buffer, pipe) != NULL) { + *output += buffer; + } + pclose(pipe); + + if (output->back() == '\n') + output->pop_back(); + + return 0; +} + +bool isValidFile(const char *file) { + FILE *fp = fopen(file, "r"); + if (fp != NULL) { + fclose(fp); + return true; + } + return false; +} + +bool isValidDir(const char *directory) { + DIR *dir = opendir(directory); + if (dir == NULL) + return false; + + closedir(dir); + return true; +} + +bool isUserBuild() { + return ::android::os::dumpstate::PropertiesHelper::IsUserBuild(); +} + +int getFilesInDir(const char *directory, std::vector<std::string> *files) { + std::string content; + struct dirent *entry; + + DIR *dir = opendir(directory); + if (dir == NULL) + return -1; + + files->clear(); + while ((entry = readdir(dir)) != NULL) + files->push_back(entry->d_name); + closedir(dir); + + sort(files->begin(), files->end()); + return 0; +} + +void dumpPowerStatsTimes() { + const char *title = "Power Stats Times"; + char rBuff[128]; + struct timespec rTs; + struct sysinfo info; + int ret; + + printTitle(title); + + sysinfo(&info); + + const time_t boottime = time(NULL) - info.uptime; + + ret = clock_gettime(CLOCK_REALTIME, &rTs); + if (ret) + return; + + struct tm *nowTime = std::localtime(&rTs.tv_sec); + + std::strftime(rBuff, sizeof(rBuff), "%m/%d/%Y %H:%M:%S", nowTime); + printf("Boot: %s", ctime(&boottime)); + printf("Now: %s\n", rBuff); +} + +int readContentsOfDir(const char* title, const char* directory, const char* strMatch, + bool useStrMatch = false, bool printDirectory = false) { + std::vector<std::string> files; + std::string content; + std::string fileLocation; + int ret; + + ret = getFilesInDir(directory, &files); + if (ret < 0) + return ret; + + printTitle(title); + for (auto &file : files) { + if (useStrMatch && std::string::npos == std::string(file).find(strMatch)) { + continue; + } + + fileLocation = std::string(directory) + std::string(file); + if (!android::base::ReadFileToString(fileLocation, &content)) { + continue; + } + if (printDirectory) { + printf("\n\n%s\n", fileLocation.c_str()); + } + if (content.back() == '\n') + content.pop_back(); + printf("%s\n", content.c_str()); + } + return 0; +} + +void dumpAcpmStats() { + const char* acpmDir = "/sys/devices/platform/acpm_stats/"; + const char* statsSubStr = "_stats"; + const char* acpmTitle = "ACPM stats"; + readContentsOfDir(acpmTitle, acpmDir, statsSubStr, true, true); +} + +void dumpPowerSupplyStats() { + const char* dumpList[][2] = { + {"CPU PM stats", "/sys/devices/system/cpu/cpupm/cpupm/time_in_state"}, + {"GENPD summary", "/d/pm_genpd/pm_genpd_summary"}, + {"Power supply property battery", "/sys/class/power_supply/battery/uevent"}, + {"Power supply property dc", "/sys/class/power_supply/dc/uevent"}, + {"Power supply property gcpm", "/sys/class/power_supply/gcpm/uevent"}, + {"Power supply property gcpm_pps", "/sys/class/power_supply/gcpm_pps/uevent"}, + {"Power supply property main-charger", "/sys/class/power_supply/main-charger/uevent"}, + {"Power supply property dc-mains", "/sys/class/power_supply/dc-mains/uevent"}, + {"Power supply property tcpm", "/sys/class/power_supply/tcpm-source-psy-11-0025/uevent"}, + {"Power supply property usb", "/sys/class/power_supply/usb/uevent"}, + {"Power supply property wireless", "/sys/class/power_supply/wireless/uevent"}, + }; + + for (const auto &row : dumpList) { + dumpFileContent(row[0], row[1]); + } +} + +void dumpMaxFg() { + const char *maxfgLoc = "/sys/class/power_supply/maxfg"; + + const char *maxfg [][2] = { + {"Power supply property maxfg", "/sys/class/power_supply/maxfg/uevent"}, + {"m5_state", "/sys/class/power_supply/maxfg/m5_model_state"}, + {"maxfg logbuffer", "/dev/logbuffer_maxfg"}, + {"maxfg_monitor logbuffer", "/dev/logbuffer_maxfg_monitor"}, + }; + + const char *maxfgFlip [][2] = { + {"Power supply property maxfg_base", "/sys/class/power_supply/maxfg_base/uevent"}, + {"Power supply property maxfg_flip", "/sys/class/power_supply/maxfg_flip/uevent"}, + {"m5_state", "/sys/class/power_supply/maxfg_base/m5_model_state"}, + {"maxfg_base", "/dev/logbuffer_maxfg_base"}, + {"maxfg_flip", "/dev/logbuffer_maxfg_flip"}, + {"maxfg_base", "/dev/logbuffer_maxfg_base_monitor"}, + {"maxfg_flip", "/dev/logbuffer_maxfg_flip_monitor"}, + }; + + const char *maxfgHistoryName = "Maxim FG History"; + const char *maxfgHistoryDir = "/dev/maxfg_history"; + + std::string content; + + + if (isValidDir(maxfgLoc)) { + for (const auto &row : maxfg) { + dumpFileContent(row[0], row[1]); + } + } else { + for (const auto &row : maxfgFlip) { + dumpFileContent(row[0], row[1]); + } + } + + if (isValidFile(maxfgHistoryDir)) { + dumpFileContent(maxfgHistoryName, maxfgHistoryDir); + } +} + +void dumpPowerSupplyDock() { + const char* powerSupplyPropertyDockTitle = "Power supply property dock"; + const char* powerSupplyPropertyDockFile = "/sys/class/power_supply/dock/uevent"; + if (isValidFile(powerSupplyPropertyDockFile)) { + dumpFileContent(powerSupplyPropertyDockTitle, powerSupplyPropertyDockFile); + } +} + +void dumpLogBufferTcpm() { + const char* logbufferTcpmTitle = "Logbuffer TCPM"; + const char* logbufferTcpmFile = "/dev/logbuffer_tcpm"; + const char* debugTcpmFile = "/sys/kernel/debug/tcpm"; + const char* tcpmLogTitle = "TCPM logs"; + const char* tcpmFile = "/sys/kernel/debug/tcpm"; + const char* tcpmFileAlt = "/sys/kernel/debug/usb/tcpm"; + int retCode; + + dumpFileContent(logbufferTcpmTitle, logbufferTcpmFile); + + retCode = readContentsOfDir(tcpmLogTitle, isValidFile(debugTcpmFile) ? tcpmFile : tcpmFileAlt, + NULL); + if (retCode < 0) + printTitle(tcpmLogTitle); +} + +void dumpTcpc() { + int ret; + const char* max77759TcpcHead = "TCPC"; + const char* i2cSubDirMatch = "i2c-"; + const char* directory = "/sys/devices/platform/10d60000.hsi2c/"; + const char* max77759Tcpc [][2] { + {"registers:", "/i2c-max77759tcpc/registers"}, + {"frs:", "/i2c-max77759tcpc/frs"}, + {"auto_discharge:", "/i2c-max77759tcpc/auto_discharge"}, + {"bcl2_enabled:", "/i2c-max77759tcpc/bcl2_enabled"}, + {"cc_toggle_enable:", "/i2c-max77759tcpc/cc_toggle_enable"}, + {"containment_detection:", "/i2c-max77759tcpc/containment_detection"}, + {"containment_detection_status:", "/i2c-max77759tcpc/containment_detection_status"}, + }; + + std::vector<std::string> files; + std::string content; + + printTitle(max77759TcpcHead); + + ret = getFilesInDir(directory, &files); + if (ret < 0) { + for (auto &tcpcVal : max77759Tcpc) + printf("%s\n", tcpcVal[0]); + return; + } + + for (auto &file : files) { + for (auto &tcpcVal : max77759Tcpc) { + printf("%s ", tcpcVal[0]); + if (std::string::npos == std::string(file).find(i2cSubDirMatch)) { + continue; + } + + std::string fileName = directory + file + "/" + std::string(tcpcVal[1]); + + if (!android::base::ReadFileToString(fileName, &content)) { + continue; + } + + printf("%s\n", content.c_str()); + } + } +} + +void dumpPdEngine() { + const char* pdEngine [][2] { + {"PD Engine", "/dev/logbuffer_usbpd"}, + {"PPS-google_cpm", "/dev/logbuffer_cpm"}, + {"PPS-dc", "/dev/logbuffer_pca9468"}, + }; + + for (const auto &row : pdEngine) { + dumpFileContent(row[0], row[1]); + } +} + +void dumpEusbRepeater() { + const char* dumpTitle = "registers dump of eUSB repeater"; + const char* dumpFile = "/d/eusb_repeater/registers"; + + if (isValidFile(dumpFile)) { + dumpFileContent(dumpTitle, dumpFile); + } +} + +void dumpWc68() { + const char* wc68Title = "WC68"; + const char* wc68File = "/dev/logbuffer_wc68"; + + if (isValidFile(wc68File)) { + dumpFileContent(wc68Title, wc68File); + } +} + +void dumpLn8411() { + const char* ln8411Title = "LN8411"; + const char* ln8411File = "/dev/logbuffer_ln8411"; + + if (isValidFile(ln8411File)) { + dumpFileContent(ln8411Title, ln8411File); + } +} + +void dumpBatteryHealth() { + const char* batteryHealth [][2] { + {"Battery Health", "/sys/class/power_supply/battery/health_index_stats"}, + {"BMS", "/dev/logbuffer_ssoc"}, + {"TTF", "/dev/logbuffer_ttf"}, + {"TTF details", "/sys/class/power_supply/battery/ttf_details"}, + {"TTF stats", "/sys/class/power_supply/battery/ttf_stats"}, + {"aacr_state", "/sys/class/power_supply/battery/aacr_state"}, + {"maxq", "/dev/logbuffer_maxq"}, + {"TEMP/DOCK-DEFEND", "/dev/logbuffer_bd"}, + }; + + for (const auto &row : batteryHealth) { + dumpFileContent(row[0], row[1]); + } +} + +void dumpBatteryDefend() { + const char* defendConfig [][4] { + {"TRICKLE-DEFEND Config", + "/sys/devices/platform/google,battery/power_supply/battery/", "bd_"}, + {"DWELL-DEFEND Config", "/sys/devices/platform/google,charger/", "charge_s"}, + {"DWELL-DEFEND Time", "/mnt/vendor/persist/battery/", "defender_"}, + {"TEMP-DEFEND Config", "/sys/devices/platform/google,charger/", "bd_"}, + }; + + std::vector<std::string> files; + struct dirent *entry; + std::string content; + std::string fileLocation; + + for (auto &config : defendConfig) { + DIR *dir = opendir(config[1]); + if (dir == NULL) + continue; + + printTitle(config[0]); + while ((entry = readdir(dir)) != NULL) { + if (std::string(entry->d_name).find(config[2]) != std::string::npos && + strncmp(config[2], entry->d_name, strlen(config[2])) == 0) { + files.push_back(entry->d_name); + } + } + closedir(dir); + + sort(files.begin(), files.end()); + + for (auto &file : files) { + fileLocation = std::string(config[1]) + std::string(file); + if (!android::base::ReadFileToString(fileLocation, &content) || content.empty()) { + content = "\n"; + } + + printf("%s: %s", file.c_str(), content.c_str()); + + if (content.back() != '\n') + printf("\n"); + } + + files.clear(); + } +} + +void printValuesOfDirectory(const char *directory, std::string debugfs, const char *strMatch) { + std::vector<std::string> files; + auto info = directory; + std::string content; + struct dirent *entry; + DIR *dir = opendir(debugfs.c_str()); + if (dir == NULL) + return; + + printTitle((debugfs + std::string(strMatch) + "/" + std::string(info)).c_str()); + while ((entry = readdir(dir)) != NULL) + if (std::string(entry->d_name).find(strMatch) != std::string::npos) + files.push_back(entry->d_name); + closedir(dir); + + sort(files.begin(), files.end()); + + for (auto &file : files) { + std::string fileDirectory = debugfs + file; + std::string fileLocation = fileDirectory + "/" + std::string(info); + if (!android::base::ReadFileToString(fileLocation, &content)) { + content = "\n"; + } + + printf("%s:\n%s", fileDirectory.c_str(), content.c_str()); + + if (content.back() != '\n') + printf("\n"); + } + files.clear(); +} + +void dumpChgUserDebug() { + const char *chgDebugMax77759 [][2] { + {"max77759_chg registers dump", "/d/max77759_chg/registers"}, + {"max77729_pmic registers dump", "/d/max77729_pmic/registers"}, + }; + const char *chgDebugMax77779 [][2] { + {"max77779_chg registers dump", "/d/max77779_chg/registers"}, + {"max77779_pmic registers dump", "/d/max77779_pmic/registers"}, + }; + + const std::string debugfs = "/d/"; + + const char *maxFgDir = "/d/maxfg"; + const char *maxFgStrMatch = "maxfg"; + const char *maxFg77779StrMatch = "max77779fg"; + const char *baseChgDir = "/d/max77759_chg"; + const char *dcRegName = "DC_registers dump"; + const char *dcRegDir = "/sys/class/power_supply/dc-mains/device/registers_dump"; + const char *chgTblName = "Charging table dump"; + const char *chgTblDir = "/d/google_battery/chg_raw_profile"; + + const char *maxFgInfo [] { + "fg_model", + "algo_ver", + "model_ok", + "registers", + "nv_registers", + }; + + const char *max77779FgInfo [] { + "fg_model", + "algo_ver", + "model_ok", + "registers", + "debug_registers", + }; + + if (isUserBuild()) + return; + + if (isValidFile(dcRegDir)) { + dumpFileContent(dcRegName, dcRegDir); + } + + if (isValidDir(baseChgDir)) { + for (auto &row : chgDebugMax77759) { + dumpFileContent(row[0], row[1]); + } + } else { + for (auto &row : chgDebugMax77779) { + dumpFileContent(row[0], row[1]); + } + } + + dumpFileContent(chgTblName, chgTblDir); + + if (isValidDir(maxFgDir)) { + for (auto & directory : maxFgInfo) { + printValuesOfDirectory(directory, debugfs, maxFgStrMatch); + } + } else { + for (auto & directory : max77779FgInfo) { + printValuesOfDirectory(directory, debugfs, maxFg77779StrMatch); + } + } +} + +void dumpBatteryEeprom() { + const char *title = "Battery EEPROM"; + const char *files[] { + "/sys/devices/platform/10c90000.hsi2c/i2c-9/9-0050/eeprom", + }; + std::string result; + std::string xxdCmd; + + printTitle(title); + for (auto &file : files) { + if (!isValidFile(file)) + continue; + + xxdCmd = "xxd " + std::string(file); + + int ret = getCommandOutput(xxdCmd.c_str(), &result); + if (ret < 0) + return; + + printf("%s\n", result.c_str()); + } +} + +void dumpChargerStats() { + const char *chgStatsTitle = "Charger Stats"; + const char *chgStatsLocation = "/sys/class/power_supply/battery/charge_details"; + const char *chargerStats [][3] { + {"Google Charger", "/sys/kernel/debug/google_charger/", "pps_"}, + {"Google Battery", "/sys/kernel/debug/google_battery/", "ssoc_"}, + }; + std::vector<std::string> files; + std::string content; + struct dirent *entry; + + dumpFileContent(chgStatsTitle, chgStatsLocation); + + if (isUserBuild()) + return; + + for (auto &stat : chargerStats) { + DIR *dir = opendir(stat[1]); + if (dir == NULL) + return; + + printTitle(stat[0]); + while ((entry = readdir(dir)) != NULL) + if (std::string(entry->d_name).find(stat[2]) != std::string::npos) + files.push_back(entry->d_name); + closedir(dir); + + sort(files.begin(), files.end()); + + for (auto &file : files) { + std::string fileLocation = std::string(stat[1]) + file; + if (!android::base::ReadFileToString(fileLocation, &content)) { + content = "\n"; + } + + printf("%s: %s", file.c_str(), content.c_str()); + + if (content.back() != '\n') + printf("\n"); + } + files.clear(); + } +} + +void dumpWlcLogs() { + const char *dumpWlcList [][2] { + {"WLC Logs", "/dev/logbuffer_wireless"}, + {"WLC VER", "/sys/class/power_supply/wireless/device/version"}, + {"WLC STATUS", "/sys/class/power_supply/wireless/device/status"}, + {"WLC FW Version", "/sys/class/power_supply/wireless/device/fw_rev"}, + {"RTX", "/dev/logbuffer_rtx"}, + }; + + for (auto &row : dumpWlcList) { + if (!isValidFile(row[1])) + printTitle(row[0]); + dumpFileContent(row[0], row[1]); + } +} + +void dumpGvoteables() { + const char *directory = "/sys/kernel/debug/gvotables/"; + const char *statusName = "/status"; + const char *title = "gvotables"; + std::string content; + std::vector<std::string> files; + int ret; + + if (isUserBuild()) + return; + + ret = getFilesInDir(directory, &files); + if (ret < 0) + return; + + printTitle(title); + for (auto &file : files) { + std::string fileLocation = std::string(directory) + file + std::string(statusName); + if (!android::base::ReadFileToString(fileLocation, &content)) { + continue; + } + + printf("%s: %s", file.c_str(), content.c_str()); + + if (content.back() != '\n') + printf("\n"); + } + files.clear(); +} + +void dumpMitigation() { + const char *mitigationList [][2] { + {"Lastmeal" , "/data/vendor/mitigation/lastmeal.txt"}, + {"Thismeal" , "/data/vendor/mitigation/thismeal.txt"}, + }; + + for (auto &row : mitigationList) { + if (!isValidFile(row[1])) + printTitle(row[0]); + dumpFileContent(row[0], row[1]); + } +} + +void dumpMitigationStats() { + int ret; + const char *directory = "/sys/devices/virtual/pmic/mitigation/last_triggered_count/"; + const char *capacityDirectory = "/sys/devices/virtual/pmic/mitigation/last_triggered_capacity/"; + const char *timestampDirectory = + "/sys/devices/virtual/pmic/mitigation/last_triggered_timestamp/"; + const char *voltageDirectory = "/sys/devices/virtual/pmic/mitigation/last_triggered_voltage/"; + const char *capacitySuffix = "_cap"; + const char *timeSuffix = "_time"; + const char *voltageSuffix = "_volt"; + const char *countSuffix = "_count"; + const char *title = "Mitigation Stats"; + + std::vector<std::string> files; + std::string content; + std::string fileLocation; + std::string source; + std::string subModuleName; + int count; + int soc; + int time; + int voltage; + + ret = getFilesInDir(directory, &files); + if (ret < 0) + return; + + printTitle(title); + printf("Source\t\tCount\tSOC\tTime\tVoltage\n"); + + for (auto &file : files) { + fileLocation = std::string(directory) + std::string(file); + if (!android::base::ReadFileToString(fileLocation, &content)) { + continue; + } + + ret = atoi(android::base::Trim(content).c_str()); + if (ret == -1) + continue; + count = ret; + + subModuleName = std::string(file); + subModuleName.erase(subModuleName.find(countSuffix), strlen(countSuffix)); + + fileLocation = std::string(capacityDirectory) + std::string(subModuleName) + + std::string(capacitySuffix); + if (!android::base::ReadFileToString(fileLocation, &content)) { + continue; + } + ret = atoi(android::base::Trim(content).c_str()); + if (ret == -1) + continue; + soc = ret; + + fileLocation = std::string(timestampDirectory) + std::string(subModuleName) + + std::string(timeSuffix); + if (!android::base::ReadFileToString(fileLocation, &content)) { + continue; + } + ret = atoi(android::base::Trim(content).c_str()); + if (ret == -1) + continue; + time = ret; + + fileLocation = std::string(voltageDirectory) + std::string(subModuleName) + + std::string(voltageSuffix); + if (!android::base::ReadFileToString(fileLocation, &content)) { + continue; + } + ret = atoi(android::base::Trim(content).c_str()); + if (ret == -1) + continue; + voltage = ret; + printf("%s \t%i\t%i\t%i\t%i\n", subModuleName.c_str(), count, soc, time, voltage); + } +} + +void dumpMitigationDirs() { + const int paramCount = 4; + const char *titles[] = { + "Clock Divider Ratio", + "Clock Stats", + "Triggered Level", + "Instruction", + }; + const char *directories[] = { + "/sys/devices/virtual/pmic/mitigation/clock_ratio/", + "/sys/devices/virtual/pmic/mitigation/clock_stats/", + "/sys/devices/virtual/pmic/mitigation/triggered_lvl/", + "/sys/devices/virtual/pmic/mitigation/instruction/", + }; + const char *paramSuffix[] = {"_ratio", "_stats", "_lvl", ""}; + const char *titleRowVal[] = { + "Source\t\tRatio", + "Source\t\tStats", + "Source\t\tLevel", + "", + }; + const int eraseCnt[] = {6, 6, 4, 0}; + const bool useTitleRow[] = {true, true, true, false}; + + std::vector<std::string> files; + std::string content; + std::string fileLocation; + std::string source; + std::string subModuleName; + std::string readout; + + for (int i = 0; i < paramCount; i++) { + printTitle(titles[i]); + if (useTitleRow[i]) { + printf("%s\n", titleRowVal[i]); + } + + getFilesInDir(directories[i], &files); + + for (auto &file : files) { + fileLocation = std::string(directories[i]) + std::string(file); + if (!android::base::ReadFileToString(fileLocation, &content)) { + continue; + } + + readout = android::base::Trim(content); + + subModuleName = std::string(file); + subModuleName.erase(subModuleName.find(paramSuffix[i]), eraseCnt[i]); + + if (useTitleRow[i]) { + printf("%s \t%s\n", subModuleName.c_str(), readout.c_str()); + } else { + printf("%s=%s\n", subModuleName.c_str(), readout.c_str()); + } + } + } +} + +void dumpIrqDurationCounts() { + const char *title = "IRQ Duration Counts"; + const char *colNames = "Source\t\t\t\tlt_5ms_cnt\tbt_5ms_to_10ms_cnt\tgt_10ms_cnt\tCode" + "\tCurrent Threshold (uA)\tCurrent Reading (uA)\n"; + const int nonOdpmChannelCnt = 9; + const int odpmChCnt = 12; + + enum Duration { + LT_5MS, + BT_5MS_10MS, + GT_10MS, + DUR_MAX, + }; + const char *irqDurDirectories[] = { + "/sys/devices/virtual/pmic/mitigation/irq_dur_cnt/less_than_5ms_count", + "/sys/devices/virtual/pmic/mitigation/irq_dur_cnt/between_5ms_to_10ms_count", + "/sys/devices/virtual/pmic/mitigation/irq_dur_cnt/greater_than_10ms_count", + }; + + enum PowerWarn { + MAIN, + SUB, + PWRWARN_MAX, + }; + const char *pwrwarnDirectories[] = { + "/sys/devices/virtual/pmic/mitigation/main_pwrwarn/", + "/sys/devices/virtual/pmic/mitigation/sub_pwrwarn/", + }; + + const char *lpfCurrentDirs[] = { + "/sys/devices/platform/acpm_mfd_bus@15500000/i2c-7/7-001f/s2mpg14-meter/" + "s2mpg14-odpm/iio:device1/lpf_current", + "/sys/devices/platform/acpm_mfd_bus@15510000/i2c-8/8-002f/s2mpg15-meter/" + "s2mpg15-odpm/iio:device0/lpf_current", + }; + + bool titlesInitialized = false; + + std::vector<std::string> channelNames; + std::vector<std::string> channelData[DUR_MAX]; + std::vector<std::string> pwrwarnThreshold[PWRWARN_MAX]; + std::vector<std::string> pwrwarnCode[PWRWARN_MAX]; + std::vector<std::string> lpfCurrentVals[PWRWARN_MAX]; + std::vector<std::string> files; + + std::string content; + std::string token; + std::string tokenCh; + std::string fileLocation; + + for (int i = 0; i < DUR_MAX; i++) { + if (!android::base::ReadFileToString(irqDurDirectories[i], &content)) { + return; + } + + std::istringstream tokenStream(content); + + while (std::getline(tokenStream, token, '\n')) { + if (!titlesInitialized) { + tokenCh = token; + tokenCh.erase(tokenCh.find(':'), tokenCh.length()); + channelNames.push_back(tokenCh); + } + + // there is a space after the ':' which needs to be removed + token.erase(0, token.find(':') + 1); + channelData[i].push_back(token); + + } + if (!titlesInitialized) + titlesInitialized = true; + } + + for (int i = 0; i < PWRWARN_MAX; i++) { + getFilesInDir(pwrwarnDirectories[i], &files); + + for (auto &file : files) { + fileLocation = std::string(pwrwarnDirectories[i]) + std::string(file); + if (!android::base::ReadFileToString(fileLocation, &content)) { + continue; + } + + std::string readout; + + readout = android::base::Trim(content); + + std::string readoutThreshold = readout; + readoutThreshold.erase(0, readoutThreshold.find('=') + 1); + + std::string readoutCode = readout; + readoutCode.erase(readoutCode.find('='), readoutCode.length()); + + pwrwarnThreshold[i].push_back(readoutThreshold); + pwrwarnCode[i].push_back(readoutCode); + } + } + + for (int i = 0; i < PWRWARN_MAX; i++) { + if (!android::base::ReadFileToString(lpfCurrentDirs[i], &content)) { + continue; + } + + std::istringstream tokenStream(content); + + bool first = true; + while (std::getline(tokenStream, token, '\n')) { + token.erase(0, token.find(' ')); + if (first) { + first = false; + continue; + } + lpfCurrentVals[i].push_back(token); + } + } + + printTitle(title); + printf("%s", colNames); + + for (uint i = 0; i < channelNames.size(); i++) { + std::string code = ""; + std::string threshold = ""; + std::string current = ""; + std::string ltDataMsg = ""; + std::string btDataMsg = ""; + std::string gtDataMsg = ""; + int pmicSel = 0; + int offset = 0; + std::string channelNameSuffix = " \t"; + if (i >= nonOdpmChannelCnt) { + offset = nonOdpmChannelCnt; + if (i >= (odpmChCnt + nonOdpmChannelCnt)) { + pmicSel = 1; + offset = odpmChCnt + nonOdpmChannelCnt; + } + channelNameSuffix = ""; + + code = pwrwarnCode[pmicSel][i - offset]; + threshold = pwrwarnThreshold[pmicSel][i - offset]; + current = lpfCurrentVals[pmicSel][i - offset]; + } + + if (i < channelData[0].size()) + ltDataMsg = channelData[0][i]; + + if (i < channelData[1].size()) + btDataMsg = channelData[1][i]; + + if (i < channelData[2].size()) + gtDataMsg = channelData[2][i]; + + std::string adjustedChannelName = channelNames[i] + channelNameSuffix; + printf("%s \t%s\t\t%s\t\t\t%s\t\t%s \t%s \t\t%s\n", + adjustedChannelName.c_str(), + ltDataMsg.c_str(), + btDataMsg.c_str(), + gtDataMsg.c_str(), + code.c_str(), + threshold.c_str(), + current.c_str()); + } +} + +int main() { + dumpPowerStatsTimes(); + dumpAcpmStats(); + dumpPowerSupplyStats(); + dumpMaxFg(); + dumpPowerSupplyDock(); + dumpLogBufferTcpm(); + dumpTcpc(); + dumpPdEngine(); + dumpEusbRepeater(); + dumpWc68(); + dumpLn8411(); + dumpBatteryHealth(); + dumpBatteryDefend(); + dumpChgUserDebug(); + dumpBatteryEeprom(); + dumpChargerStats(); + dumpWlcLogs(); + dumpGvoteables(); + dumpMitigation(); + dumpMitigationStats(); + dumpMitigationDirs(); + dumpIrqDurationCounts(); +} + |