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 <rdbabiera@google.com>
This commit is contained in:
RD Babiera 2024-01-16 20:55:10 +00:00
parent 2877c355a4
commit f1140a12b1
4 changed files with 105 additions and 84 deletions

View file

@ -17,7 +17,6 @@
#define LOG_TAG "android.hardware.usb.gadget.aidl-service"
#include "UsbGadget.h"
#include <dirent.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/inotify.h>
@ -29,23 +28,30 @@
#include<android-base/properties.h>
#include <aidl/android/frameworks/stats/IStats.h>
#include <pixelusb/I2cHelper.h>
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<IUsbGadgetCallback> &callback,
int64_t timeout,
@ -475,15 +458,23 @@ ScopedAStatus UsbGadget::setCurrentUsbFunctions(long functions,
std::unique_lock<std::mutex> 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())

View file

@ -115,6 +115,8 @@ struct UsbGadget : public BnUsbGadget {
ScopedAStatus setVidPid(const char *vid,const char *pid);
std::string mI2cClientPath;
private:
Status tearDownGadget();
Status getUsbGadgetIrqPath();

View file

@ -42,8 +42,9 @@
#include <aidl/android/frameworks/stats/IStats.h>
#include <android_hardware_usb_flags.h>
#include <pixelusb/UsbGadgetAidlCommon.h>
#include <pixelstats/StatsHelper.h>
#include <pixelusb/I2cHelper.h>
#include <pixelusb/UsbGadgetAidlCommon.h>
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<PortStatus> *currentPortStatus) {
string enabled, status, path, DetectedPath;
Status queryMoistureDetectionStatus(android::hardware::usb::Usb *usb,
std::vector<PortStatus> *currentPortStatus) {
string enabled, status, DetectedPath;
(*currentPortStatus)[0].supportedContaminantProtectionModes
.push_back(ContaminantProtectionMode::FORCE_DISABLE);
@ -305,8 +289,18 @@ Status queryMoistureDetectionStatus(std::vector<PortStatus> *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<PortStatus> *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<PortStatus> 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<PortStatus> *currentPortStatus) {
string limitedPath, enabled, path;
Status queryPowerTransferStatus(android::hardware::usb::Usb *usb,
std::vector<PortStatus> *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);

View file

@ -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;