diff --git a/usb/usb/Usb.cpp b/usb/usb/Usb.cpp index 7aa4ced0..8115ce27 100644 --- a/usb/usb/Usb.cpp +++ b/usb/usb/Usb.cpp @@ -60,6 +60,8 @@ constexpr char kHsi2cPath[] = "/sys/devices/platform/10d50000.hsi2c"; constexpr char kI2CPath[] = "/sys/devices/platform/10d50000.hsi2c/i2c-"; constexpr char kContaminantDetectionPath[] = "i2c-max77759tcpc/contaminant_detection"; constexpr char kStatusPath[] = "i2c-max77759tcpc/contaminant_detection_status"; +constexpr char kSinkLimitEnable[] = "i2c-max77759tcpc/usb_limit_sink_enable"; +constexpr char kSinkLimitCurrent[] = "i2c-max77759tcpc/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/"; @@ -130,7 +132,7 @@ ScopedAStatus Usb::enableUsbData(const string& in_portName, bool in_enable, return ScopedAStatus::ok(); } -Status getContaminantDetectionNamesHelper(string *name) { +Status getI2cBusHelper(string *name) { DIR *dp; dp = opendir(kHsi2cPath); @@ -163,7 +165,7 @@ Status queryMoistureDetectionStatus(std::vector *currentPortStatus) (*currentPortStatus)[0].supportsEnableContaminantPresenceDetection = true; (*currentPortStatus)[0].supportsEnableContaminantPresenceProtection = false; - getContaminantDetectionNamesHelper(&path); + getI2cBusHelper(&path); enabledPath = kI2CPath + path + "/" + kContaminantDetectionPath; if (!ReadFileToString(enabledPath, &enabled)) { ALOGE("Failed to open moisture_detection_enabled"); @@ -402,6 +404,61 @@ ScopedAStatus Usb::switchRole(const string& in_portName, const PortRole& in_role return ScopedAStatus::ok(); } +ScopedAStatus Usb::limitPowerTransfer(const string& in_portName, bool in_limit, + int64_t in_transactionId) { + bool success = false; + std::vector currentPortStatus; + string path, limitEnablePath, currentLimitPath; + + getI2cBusHelper(&path); + limitEnablePath = kI2CPath + path + "/" + kSinkLimitEnable; + currentLimitPath = kI2CPath + path + "/" + kSinkLimitCurrent; + + if (in_limit) { + success = WriteStringToFile("0", currentLimitPath); + if (!success) { + ALOGE("Failed to set sink current limit"); + } + } + success = WriteStringToFile(in_limit ? "1" : "0", limitEnablePath); + if (!success) { + ALOGE("Failed to %s sink current limit: %s", in_limit ? "enable" : "disable", + limitEnablePath.c_str()); + } + ALOGI("limitPowerTransfer limit:%c opId:%ld", in_limit ? 'y' : 'n', in_transactionId); + pthread_mutex_lock(&mLock); + if (mCallback != NULL && in_transactionId >= 0) { + ScopedAStatus ret = mCallback->notifyLimitPowerTransferStatus( + in_portName, in_limit, success ? Status::SUCCESS : Status::ERROR, in_transactionId); + if (!ret.isOk()) + ALOGE("limitPowerTransfer error %s", ret.getDescription().c_str()); + } else { + ALOGE("Not notifying the userspace. Callback is not set"); + } + + pthread_mutex_unlock(&mLock); + queryVersionHelper(this, ¤tPortStatus); + + return ScopedAStatus::ok(); +} + +Status queryPowerTransferStatus(std::vector *currentPortStatus) { + string limitedPath, enabled, path; + + getI2cBusHelper(&path); + limitedPath = kI2CPath + path + "/" + kSinkLimitEnable; + if (!ReadFileToString(limitedPath, &enabled)) { + ALOGE("Failed to open limit_sink_enable"); + return Status::ERROR; + } + + enabled = Trim(enabled); + (*currentPortStatus)[0].powerTransferLimited = enabled == "1"; + + ALOGI("powerTransferLimited:%d", (*currentPortStatus)[0].powerTransferLimited ? 1 : 0); + return Status::SUCCESS; +} + Status getAccessoryConnected(const string &portName, string *accessory) { string filename = "/sys/class/typec/" + portName + "-partner/accessory_mode"; @@ -571,13 +628,14 @@ Status getPortStatusHelper(android::hardware::usb::Usb *usb, (*currentPortStatus)[i].usbDataEnabled = usb->mUsbDataEnabled; ALOGI("%d:%s connected:%d canChangeMode:%d canChagedata:%d canChangePower:%d " - "usbDataEnabled:%d", + "usbDataEnabled:%d", i, port.first.c_str(), port.second, (*currentPortStatus)[i].canChangeMode, (*currentPortStatus)[i].canChangeDataRole, (*currentPortStatus)[i].canChangePowerRole, (*currentPortStatus)[i].usbDataEnabled ? 1 : 0); } + return Status::SUCCESS; } done: @@ -590,6 +648,7 @@ void queryVersionHelper(android::hardware::usb::Usb *usb, pthread_mutex_lock(&usb->mLock); status = getPortStatusHelper(usb, currentPortStatus); queryMoistureDetectionStatus(currentPortStatus); + queryPowerTransferStatus(currentPortStatus); if (usb->mCallback != NULL) { ScopedAStatus ret = usb->mCallback->notifyPortStatusChange(*currentPortStatus, status); diff --git a/usb/usb/Usb.h b/usb/usb/Usb.h index 51f9d439..a361f84b 100644 --- a/usb/usb/Usb.h +++ b/usb/usb/Usb.h @@ -65,6 +65,8 @@ struct Usb : public BnUsb { int64_t in_transactionId) override; ScopedAStatus enableUsbData(const string& in_portName, bool in_enable, int64_t in_transactionId) override; + ScopedAStatus limitPowerTransfer(const string& in_portName, bool in_limit, + int64_t in_transactionId) override; std::shared_ptr<::aidl::android::hardware::usb::IUsbCallback> mCallback; // Protects mCallback variable @@ -84,7 +86,6 @@ struct Usb : public BnUsb { float mPluggedTemperatureCelsius; // Usb Data status bool mUsbDataEnabled; - private: pthread_t mPoll; }; diff --git a/usb/usb/android.hardware.usb-service.rc b/usb/usb/android.hardware.usb-service.rc index c842877b..e79a672c 100644 --- a/usb/usb/android.hardware.usb-service.rc +++ b/usb/usb/android.hardware.usb-service.rc @@ -10,6 +10,10 @@ on post-fs chown root system /sys/class/typec/port0/port_type chown root system /sys/devices/platform/10d50000.hsi2c/i2c-5/i2c-max77759tcpc/contaminant_detection chown root system /sys/devices/platform/10d50000.hsi2c/i2c-6/i2c-max77759tcpc/contaminant_detection + chown root system /sys/devices/platform/10d50000.hsi2c/i2c-5/i2c-max77759tcpc/usb_limit_sink_current + chown root system /sys/devices/platform/10d50000.hsi2c/i2c-6/i2c-max77759tcpc/usb_limit_sink_current + chown root system /sys/devices/platform/10d50000.hsi2c/i2c-5/i2c-max77759tcpc/usb_limit_sink_enable + chown root system /sys/devices/platform/10d50000.hsi2c/i2c-6/i2c-max77759tcpc/usb_limit_sink_enable chown root system /sys/devices/platform/11110000.usb/dwc3_exynos_otg_b_sess chown root system /sys/devices/platform/11110000.usb/dwc3_exynos_otg_id chown root system /sys/devices/platform/11110000.usb/usb_data_enabled @@ -19,3 +23,9 @@ on post-fs chmod 664 /sys/devices/platform/11110000.usb/dwc3_exynos_otg_b_sess chmod 664 /sys/devices/platform/11110000.usb/dwc3_exynos_otg_id chmod 664 /sys/devices/platform/11110000.usb/usb_data_enabled + chmod 664 /sys/devices/platform/10d50000.hsi2c/i2c-5/i2c-max77759tcpc/contaminant_detection + chmod 664 /sys/devices/platform/10d50000.hsi2c/i2c-6/i2c-max77759tcpc/contaminant_detection + chmod 664 /sys/devices/platform/10d50000.hsi2c/i2c-5/i2c-max77759tcpc/usb_limit_sink_current + chmod 664 /sys/devices/platform/10d50000.hsi2c/i2c-6/i2c-max77759tcpc/usb_limit_sink_current + chmod 664 /sys/devices/platform/10d50000.hsi2c/i2c-5/i2c-max77759tcpc/usb_limit_sink_enable + chmod 664 /sys/devices/platform/10d50000.hsi2c/i2c-6/i2c-max77759tcpc/usb_limit_sink_enable