From f1140a12b1e80af364fe16ae5889a2fef475cdaa Mon Sep 17 00:00:00 2001 From: RD Babiera Date: Tue, 16 Jan 2024 20:55:10 +0000 Subject: [PATCH] usb: Runtime search the i2c path The paths of sysfs nodes are different across kernel versions and i2c bus assignement. Runtime search the correct ones. Test: Manual test on device. Confirm that file reads related to file path error do not trigger error. Bug: 318820040 Change-Id: I1217fcea012865cebe12c935917f12903003fd5b (ported from commit 0b768c8fbe1e59a4b9efa7b5f7b6a017a81d46fb) Signed-off-by: RD Babiera --- usb/gadget/UsbGadget.cpp | 59 ++++++++---------- usb/gadget/UsbGadget.h | 2 + usb/usb/Usb.cpp | 126 +++++++++++++++++++++++---------------- usb/usb/Usb.h | 2 + 4 files changed, 105 insertions(+), 84 deletions(-) diff --git a/usb/gadget/UsbGadget.cpp b/usb/gadget/UsbGadget.cpp index 14f65b7..5dbf304 100644 --- a/usb/gadget/UsbGadget.cpp +++ b/usb/gadget/UsbGadget.cpp @@ -17,7 +17,6 @@ #define LOG_TAG "android.hardware.usb.gadget.aidl-service" #include "UsbGadget.h" -#include #include #include #include @@ -29,23 +28,30 @@ #include #include +#include namespace aidl { namespace android { namespace hardware { namespace usb { namespace gadget { +#define NUM_HSI2C_PATHS 2 + +using ::android::hardware::google::pixel::usb::getI2cClientPath; using ::android::base::GetBoolProperty; using ::android::hardware::google::pixel::usb::kUvcEnabled; string enabledPath; -constexpr char kHsi2cPath[] = "/sys/devices/platform/108d0000.hsi2c"; -constexpr char kI2CPath[] = "/sys/devices/platform/108d0000.hsi2c/i2c-"; -constexpr char kAccessoryLimitCurrent[] = "-0025/usb_limit_accessory_current"; -constexpr char kAccessoryLimitCurrentEnable[] = "-0025/usb_limit_accessory_enable"; +constexpr char* kHsi2cPaths[] = { (char *) "/sys/devices/platform/108d0000.hsi2c", + (char *) "/sys/devices/platform/10cb0000.hsi2c" }; +constexpr char kTcpcDevName[] = "i2c-max77759tcpc"; +constexpr char kI2cClientId[] = "0025"; +constexpr char kAccessoryLimitCurrent[] = "usb_limit_accessory_current"; +constexpr char kAccessoryLimitCurrentEnable[] = "usb_limit_accessory_enable"; -UsbGadget::UsbGadget() : mGadgetIrqPath("") { +UsbGadget::UsbGadget() : mGadgetIrqPath(""), + mI2cClientPath("") { if (access(OS_DESC_PATH, R_OK) != 0) { ALOGE("configfs setup not done yet"); abort(); @@ -445,29 +451,6 @@ Status UsbGadget::setupFunctions(long functions, return Status::SUCCESS; } -Status getI2cBusHelper(string *name) { - DIR *dp; - - dp = opendir(kHsi2cPath); - if (dp != NULL) { - struct dirent *ep; - - while ((ep = readdir(dp))) { - if (ep->d_type == DT_DIR) { - if (string::npos != string(ep->d_name).find("i2c-")) { - std::strtok(ep->d_name, "-"); - *name = std::strtok(NULL, "-"); - } - } - } - closedir(dp); - return Status::SUCCESS; - } - - ALOGE("Failed to open %s", kHsi2cPath); - return Status::ERROR; -} - ScopedAStatus UsbGadget::setCurrentUsbFunctions(long functions, const shared_ptr &callback, int64_t timeout, @@ -475,15 +458,23 @@ ScopedAStatus UsbGadget::setCurrentUsbFunctions(long functions, std::unique_lock lk(mLockSetCurrentFunction); std::string current_usb_power_operation_mode, current_usb_type; std::string usb_limit_sink_enable; - - string accessoryCurrentLimitEnablePath, accessoryCurrentLimitPath, path; + std::string accessoryCurrentLimitEnablePath, accessoryCurrentLimitPath; mCurrentUsbFunctions = functions; mCurrentUsbFunctionsApplied = false; - getI2cBusHelper(&path); - accessoryCurrentLimitPath = kI2CPath + path + "/" + path + kAccessoryLimitCurrent; - accessoryCurrentLimitEnablePath = kI2CPath + path + "/" + path + kAccessoryLimitCurrentEnable; + if (mI2cClientPath.empty()) { + for (int i = 0; i < NUM_HSI2C_PATHS; i++) { + mI2cClientPath = getI2cClientPath(kHsi2cPaths[i], kTcpcDevName, kI2cClientId); + if (mI2cClientPath.empty()) { + ALOGE("%s: Unable to locate i2c bus node", __func__); + } else { + break; + } + } + } + accessoryCurrentLimitPath = mI2cClientPath + kAccessoryLimitCurrent; + accessoryCurrentLimitEnablePath = mI2cClientPath + kAccessoryLimitCurrentEnable; // Get the gadget IRQ number before tearDownGadget() if (mGadgetIrqPath.empty()) diff --git a/usb/gadget/UsbGadget.h b/usb/gadget/UsbGadget.h index 4079b01..eac32a4 100644 --- a/usb/gadget/UsbGadget.h +++ b/usb/gadget/UsbGadget.h @@ -115,6 +115,8 @@ struct UsbGadget : public BnUsbGadget { ScopedAStatus setVidPid(const char *vid,const char *pid); + std::string mI2cClientPath; + private: Status tearDownGadget(); Status getUsbGadgetIrqPath(); diff --git a/usb/usb/Usb.cpp b/usb/usb/Usb.cpp index 473e9c3..74686e5 100644 --- a/usb/usb/Usb.cpp +++ b/usb/usb/Usb.cpp @@ -42,8 +42,9 @@ #include #include -#include #include +#include +#include namespace usb_flags = android::hardware::usb::flags; @@ -56,19 +57,23 @@ using android::base::Trim; using android::hardware::google::pixel::getStatsService; using android::hardware::google::pixel::PixelAtoms::VendorUsbPortOverheat; using android::hardware::google::pixel::reportUsbPortOverheat; +using android::hardware::google::pixel::usb::getI2cClientPath; namespace aidl { namespace android { namespace hardware { namespace usb { +#define NUM_HSI2C_PATHS 2 + // Set by the signal handler to destroy the thread volatile bool destroyThread; volatile bool destroyDisplayPortThread; string enabledPath; -constexpr char kHsi2cPath[] = "/sys/devices/platform/108d0000.hsi2c"; -constexpr char kI2CPath[] = "/sys/devices/platform/108d0000.hsi2c/i2c-"; -constexpr char kContaminantDetectionPath[] = "-0025/contaminant_detection"; +constexpr char *kHsi2cPaths[] = { (char *) "/sys/devices/platform/108d0000.hsi2c", + (char *) "/sys/devices/platform/10cb0000.hsi2c" }; +constexpr char kTcpcDevName[] = "i2c-max77759tcpc"; +constexpr char kI2cClientId[] = "0025"; constexpr char kDisplayPortDrmPath[] = "/sys/devices/platform/110f0000.drmdp/drm-displayport/"; constexpr char kDisplayPortUsbPath[] = "/sys/class/typec/port0-partner/"; constexpr char kComplianceWarningsPath[] = "device/non_compliant_reasons"; @@ -77,10 +82,11 @@ constexpr char kComplianceWarningDebugAccessory[] = "debug-accessory"; constexpr char kComplianceWarningMissingRp[] = "missing_rp"; constexpr char kComplianceWarningOther[] = "other"; constexpr char kComplianceWarningInputPowerLimited[] = "input_power_limited"; -constexpr char kStatusPath[] = "-0025/contaminant_detection_status"; -constexpr char kSinkLimitEnable[] = "-0025/usb_limit_sink_enable"; -constexpr char kSourceLimitEnable[] = "-0025/usb_limit_source_enable"; -constexpr char kSinkLimitCurrent[] = "-0025/usb_limit_sink_current"; +constexpr char kContaminantDetectionPath[] = "contaminant_detection"; +constexpr char kStatusPath[] = "contaminant_detection_status"; +constexpr char kSinkLimitEnable[] = "usb_limit_sink_enable"; +constexpr char kSourceLimitEnable[] = "usb_limit_source_enable"; +constexpr char kSinkLimitCurrent[] = "usb_limit_sink_current"; constexpr char kTypecPath[] = "/sys/class/typec"; constexpr char kDisableContatminantDetection[] = "vendor.usb.contaminantdisable"; constexpr char kOverheatStatsPath[] = "/sys/devices/platform/google,usbc_port_cooling_dev/"; @@ -92,7 +98,7 @@ constexpr char kThermalZoneForTempReadSecondary2[] = "qi_therm"; constexpr char kPogoUsbActive[] = "/sys/devices/platform/google,pogo/pogo_usb_active"; constexpr char kPogoEnableUsb[] = "/sys/devices/platform/google,pogo/enable_usb"; constexpr char kPowerSupplyUsbType[] = "/sys/class/power_supply/usb/usb_type"; -constexpr char kIrqHpdCounPath[] = "-0025/irq_hpd_count"; +constexpr char kIrqHpdCount[] = "irq_hpd_count"; constexpr char kUdcUeventRegex[] = "/devices/platform/11210000.usb/11210000.dwc3/udc/11210000.dwc3"; constexpr char kUdcStatePath[] = @@ -272,31 +278,9 @@ ScopedAStatus Usb::resetUsbPort(const std::string& in_portName, int64_t in_trans return ::ndk::ScopedAStatus::ok(); } -Status getI2cBusHelper(string *name) { - DIR *dp; - - dp = opendir(kHsi2cPath); - if (dp != NULL) { - struct dirent *ep; - - while ((ep = readdir(dp))) { - if (ep->d_type == DT_DIR) { - if (string::npos != string(ep->d_name).find("i2c-")) { - std::strtok(ep->d_name, "-"); - *name = std::strtok(NULL, "-"); - } - } - } - closedir(dp); - return Status::SUCCESS; - } - - ALOGE("Failed to open %s", kHsi2cPath); - return Status::ERROR; -} - -Status queryMoistureDetectionStatus(std::vector *currentPortStatus) { - string enabled, status, path, DetectedPath; +Status queryMoistureDetectionStatus(android::hardware::usb::Usb *usb, + std::vector *currentPortStatus) { + string enabled, status, DetectedPath; (*currentPortStatus)[0].supportedContaminantProtectionModes .push_back(ContaminantProtectionMode::FORCE_DISABLE); @@ -305,8 +289,18 @@ Status queryMoistureDetectionStatus(std::vector *currentPortStatus) (*currentPortStatus)[0].supportsEnableContaminantPresenceDetection = true; (*currentPortStatus)[0].supportsEnableContaminantPresenceProtection = false; - getI2cBusHelper(&path); - enabledPath = kI2CPath + path + "/" + path + kContaminantDetectionPath; + if (usb->mI2cClientPath.empty()) { + for (int i = 0; i < NUM_HSI2C_PATHS; i++) { + usb->mI2cClientPath = getI2cClientPath(kHsi2cPaths[i], kTcpcDevName, kI2cClientId); + if (usb->mI2cClientPath.empty()) { + ALOGE("%s: Unable to locate i2c bus node", __func__); + } else { + break; + } + } + } + + enabledPath = usb->mI2cClientPath + kContaminantDetectionPath; if (!ReadFileToString(enabledPath, &enabled)) { ALOGE("Failed to open moisture_detection_enabled"); return Status::ERROR; @@ -314,7 +308,7 @@ Status queryMoistureDetectionStatus(std::vector *currentPortStatus) enabled = Trim(enabled); if (enabled == "1") { - DetectedPath = kI2CPath + path + "/" + path + kStatusPath; + DetectedPath = usb->mI2cClientPath + kStatusPath; if (!ReadFileToString(DetectedPath, &status)) { ALOGE("Failed to open moisture_detected"); return Status::ERROR; @@ -533,6 +527,7 @@ Usb::Usb() ZoneInfo(TemperatureType::UNKNOWN, kThermalZoneForTempReadSecondary2, ThrottlingSeverity::NONE)}, kSamplingIntervalSec), mUsbDataEnabled(true), + mI2cClientPath(""), mDisplayPortPollRunning(false), mDisplayPortPollStarting(false), mDisplayPortCVLock(PTHREAD_MUTEX_INITIALIZER), @@ -639,12 +634,22 @@ ScopedAStatus Usb::limitPowerTransfer(const string& in_portName, bool in_limit, int64_t in_transactionId) { bool sessionFail = false, success; std::vector currentPortStatus; - string path, sinkLimitEnablePath, currentLimitPath, sourceLimitEnablePath; + string sinkLimitEnablePath, currentLimitPath, sourceLimitEnablePath; - getI2cBusHelper(&path); - sinkLimitEnablePath = kI2CPath + path + "/" + path + kSinkLimitEnable; - currentLimitPath = kI2CPath + path + "/" + path + kSinkLimitCurrent; - sourceLimitEnablePath = kI2CPath + path + "/" + path + kSourceLimitEnable; + if (mI2cClientPath.empty()) { + for (int i = 0; i < NUM_HSI2C_PATHS; i++) { + mI2cClientPath = getI2cClientPath(kHsi2cPaths[i], kTcpcDevName, kI2cClientId); + if (mI2cClientPath.empty()) { + ALOGE("%s: Unable to locate i2c bus node", __func__); + } else { + break; + } + } + } + + sinkLimitEnablePath = mI2cClientPath + kSinkLimitEnable; + currentLimitPath = mI2cClientPath + kSinkLimitCurrent; + sourceLimitEnablePath = mI2cClientPath + kSourceLimitEnable; pthread_mutex_lock(&mLock); if (in_limit) { @@ -684,11 +689,22 @@ ScopedAStatus Usb::limitPowerTransfer(const string& in_portName, bool in_limit, return ScopedAStatus::ok(); } -Status queryPowerTransferStatus(std::vector *currentPortStatus) { - string limitedPath, enabled, path; +Status queryPowerTransferStatus(android::hardware::usb::Usb *usb, + std::vector *currentPortStatus) { + string limitedPath, enabled; - getI2cBusHelper(&path); - limitedPath = kI2CPath + path + "/" + path + kSinkLimitEnable; + if (usb->mI2cClientPath.empty()) { + for (int i = 0; i < NUM_HSI2C_PATHS; i++) { + usb->mI2cClientPath = getI2cClientPath(kHsi2cPaths[i], kTcpcDevName, kI2cClientId); + if (usb->mI2cClientPath.empty()) { + ALOGE("%s: Unable to locate i2c bus node", __func__); + } else { + break; + } + } + } + + limitedPath = usb->mI2cClientPath + kSinkLimitEnable; if (!ReadFileToString(limitedPath, &enabled)) { ALOGE("Failed to open limit_sink_enable"); return Status::ERROR; @@ -1085,8 +1101,8 @@ void queryVersionHelper(android::hardware::usb::Usb *usb, pthread_mutex_lock(&usb->mLock); status = getPortStatusHelper(usb, currentPortStatus); - queryMoistureDetectionStatus(currentPortStatus); - queryPowerTransferStatus(currentPortStatus); + queryMoistureDetectionStatus(usb, currentPortStatus); + queryPowerTransferStatus(usb, currentPortStatus); queryNonCompliantChargerStatus(currentPortStatus); pthread_mutex_lock(&usb->mDisplayPortLock); if (!usb->mDisplayPortFirstSetupDone && @@ -1603,8 +1619,18 @@ void *displayPortPollWork(void *param) { partnerActivePath = displayPortUsbPath + "../mode1/active"; portActivePath = "/sys/class/typec/port0/port0.0/mode1/active"; - getI2cBusHelper(&tcpcI2cBus); - irqHpdCountPath = kI2CPath + tcpcI2cBus + "/" + tcpcI2cBus + kIrqHpdCounPath; + if (usb->mI2cClientPath.empty()) { + for (int i = 0; i < NUM_HSI2C_PATHS; i++) { + usb->mI2cClientPath = getI2cClientPath(kHsi2cPaths[i], kTcpcDevName, kI2cClientId); + if (usb->mI2cClientPath.empty()) { + ALOGE("%s: Unable to locate i2c bus node", __func__); + } else { + break; + } + } + } + + irqHpdCountPath = usb->mI2cClientPath + kIrqHpdCount; ALOGI("usbdp: worker: irqHpdCountPath:%s", irqHpdCountPath.c_str()); epoll_fd = epoll_create(64); diff --git a/usb/usb/Usb.h b/usb/usb/Usb.h index 6006451..4ac6a44 100644 --- a/usb/usb/Usb.h +++ b/usb/usb/Usb.h @@ -129,6 +129,8 @@ struct Usb : public BnUsb { float mPluggedTemperatureCelsius; // Usb Data status bool mUsbDataEnabled; + std::string mI2cClientPath; + // True when mDisplayPortPoll pthread is running volatile bool mDisplayPortPollRunning; volatile bool mDisplayPortPollStarting;