diff options
Diffstat (limited to 'usb/usb/Usb.cpp')
-rw-r--r-- | usb/usb/Usb.cpp | 174 |
1 files changed, 93 insertions, 81 deletions
diff --git a/usb/usb/Usb.cpp b/usb/usb/Usb.cpp index 3e4f8a1..270a222 100644 --- a/usb/usb/Usb.cpp +++ b/usb/usb/Usb.cpp @@ -17,6 +17,7 @@ #define LOG_TAG "android.hardware.usb.aidl-service" #include <android-base/logging.h> +#include <android-base/parseint.h> #include <android-base/properties.h> #include <android-base/strings.h> #include <assert.h> @@ -95,6 +96,9 @@ void queryVersionHelper(android::hardware::usb::Usb *usb, #define GL852G_PRODUCT_ID1 0x0608 #define GL852G_PRODUCT_ID2 0x0610 #define GL852G_VENDOR_CMD_REQ 0xe3 +// GL852G port 1 and port 2 JK level default settings +#define GL852G_VENDOR_CMD_VALUE_DEFAULT 0x0008 +#define GL852G_VENDOR_CMD_INDEX_DEFAULT 0x0404 ScopedAStatus Usb::enableUsbData(const string& in_portName, bool in_enable, int64_t in_transactionId) { @@ -452,6 +456,61 @@ bool switchMode(const string &portName, const PortRole &in_role, struct Usb *usb return roleSwitch; } +static int usbDeviceRemoved(const char *devname, void* client_data) { + return 0; +} + +static int usbDeviceAdded(const char *devname, void* client_data) { + uint16_t vendorId, productId; + struct usb_device *device; + ::aidl::android::hardware::usb::Usb *usb; + int value, index; + + device = usb_device_open(devname); + if (!device) { + ALOGE("usb_device_open failed\n"); + return 0; + } + + usb = (::aidl::android::hardware::usb::Usb *)client_data; + value = usb->mUsbHubVendorCmdValue; + index = usb->mUsbHubVendorCmdIndex; + + // The vendor cmd only applies to USB Hubs of Genesys Logic, Inc. + // The request field of vendor cmd is fixed to 0xe3. + vendorId = usb_device_get_vendor_id(device); + productId = usb_device_get_product_id(device); + if (vendorId == GL852G_VENDOR_ID && + (productId == GL852G_PRODUCT_ID1 || productId == GL852G_PRODUCT_ID2)) { + int ret = usb_device_control_transfer(device, + USB_DIR_OUT | USB_TYPE_VENDOR, GL852G_VENDOR_CMD_REQ, value, index, + NULL, 0, CTRL_TRANSFER_TIMEOUT_MSEC); + ALOGI("USB hub vendor cmd %s (wValue 0x%x, wIndex 0x%x, return %d)\n", + ret? "failed" : "succeeded", value, index, ret); + } + + usb_device_close(device); + + return 0; +} + +void *usbHostWork(void *param) { + struct usb_host_context *ctx; + + ALOGI("creating USB host thread\n"); + + ctx = usb_host_init(); + if (!ctx) { + ALOGE("usb_host_init failed\n"); + return NULL; + } + + // This will never return, it will keep monitoring USB sysfs inotify events + usb_host_run(ctx, usbDeviceAdded, usbDeviceRemoved, NULL, param); + + return NULL; +} + Usb::Usb() : mLock(PTHREAD_MUTEX_INITIALIZER), mRoleSwitchLock(PTHREAD_MUTEX_INITIALIZER), @@ -465,7 +524,9 @@ Usb::Usb() ThrottlingSeverity::NONE), ZoneInfo(TemperatureType::UNKNOWN, kThermalZoneForTempReadSecondary2, ThrottlingSeverity::NONE)}, kSamplingIntervalSec), - mUsbDataEnabled(true) { + mUsbDataEnabled(true), + mUsbHubVendorCmdValue(GL852G_VENDOR_CMD_VALUE_DEFAULT), + mUsbHubVendorCmdIndex(GL852G_VENDOR_CMD_INDEX_DEFAULT) { pthread_condattr_t attr; if (pthread_condattr_init(&attr)) { ALOGE("pthread_condattr_init failed: %s", strerror(errno)); @@ -483,6 +544,10 @@ Usb::Usb() ALOGE("pthread_condattr_destroy failed: %s", strerror(errno)); abort(); } + if (pthread_create(&mUsbHost, NULL, usbHostWork, this)) { + ALOGE("pthread creation failed %d\n", errno); + abort(); + } } ScopedAStatus Usb::switchRole(const string& in_portName, const PortRole& in_role, @@ -777,7 +842,13 @@ Status getPortStatusHelper(android::hardware::usb::Usb *usb, string pogoUsbActive = "0"; if (ReadFileToString(string(kPogoUsbActive), &pogoUsbActive) && stoi(Trim(pogoUsbActive)) == 1) { - (*currentPortStatus)[i].usbDataStatus.push_back(UsbDataStatus::DISABLED_DOCK); + /* + * Always signal USB device mode disabled irrespective of hub enabled while docked. + * Hub gets automatically enabled as needed. Signalling DISABLED_DOCK_HOST_MODE & + * DEVICE_MODE during pogo direct can cause notifications to show for brief windows + * when the state machine is still moving to steady state. + */ + (*currentPortStatus)[i].usbDataStatus.push_back(UsbDataStatus::DISABLED_DOCK_DEVICE_MODE); dataEnabled = false; } if (!usb->mUsbDataEnabled) { @@ -831,7 +902,9 @@ void queryVersionHelper(android::hardware::usb::Usb *usb, status = getPortStatusHelper(usb, currentPortStatus); queryMoistureDetectionStatus(currentPortStatus); queryPowerTransferStatus(currentPortStatus); +#if 0 /* b/278018111 disable compliance warning; revert it after fixing the issue */ queryNonCompliantChargerStatus(currentPortStatus); +#endif if (usb->mCallback != NULL) { ScopedAStatus ret = usb->mCallback->notifyPortStatusChange(*currentPortStatus, status); @@ -1089,82 +1162,6 @@ ScopedAStatus Usb::setCallback(const shared_ptr<IUsbCallback>& in_callback) { return ScopedAStatus::ok(); } -struct hub_vendor_cmd { - // wValue filed of standard device request - int value; - // wIndex field of standard device request - int index; - // Output pipe to shell command - int out; - // Whether the hub is found - bool found; -}; - -static int usbDeviceAdded(const char *devname, void* client_data) { - struct hub_vendor_cmd *cmd = (struct hub_vendor_cmd *)client_data; - uint16_t vendorId, productId; - struct usb_device *device = usb_device_open(devname); - - if (!device) { - dprintf(cmd->out, "usb_device_open failed\n"); - return 0; - } - - // The vendor cmd only applies to USB Hubs of Genesys Logic, Inc. - // The request field of vendor cmd is fixed to 0xe3. - vendorId = usb_device_get_vendor_id(device); - productId = usb_device_get_product_id(device); - if (vendorId == GL852G_VENDOR_ID && - (productId == GL852G_PRODUCT_ID1 || productId == GL852G_PRODUCT_ID2)) { - int ret = usb_device_control_transfer( - device, USB_DIR_OUT | USB_TYPE_VENDOR, - GL852G_VENDOR_CMD_REQ, cmd->value, cmd->index, NULL, 0, - CTRL_TRANSFER_TIMEOUT_MSEC); - dprintf(cmd->out, "Vendor cmd %s (wValue %x, wIndex %x, return %d)\n", - ret? "failed" : "succeeded", cmd->value, cmd->index, ret); - // Stop iterating through usb devices once the hub is found. - cmd->found = true; - return 1; - } - - return 0; -} - -static int usbDiscoveryDone(void *client_data) -{ - struct hub_vendor_cmd *cmd = (struct hub_vendor_cmd *)client_data; - - dprintf(cmd->out, "Done USB discovery, hub %s found\n", - cmd->found ? "is" : "not"); - - return 1; -} - -static status_t sendHubVendorCmd(int out, Vector<String8>& args) { - if (args.size() < 3) { - dprintf(out, "Incorrect number of argument supplied\n"); - return ::android::UNKNOWN_ERROR; - } - struct hub_vendor_cmd cmd = { - .value = std::stoi(args[1].c_str(), NULL, 16), - .index = std::stoi(args[2].c_str(), NULL, 16), - .out = out, - .found = false - }; - - struct usb_host_context *ctx; - ctx = usb_host_init(); - if (!ctx) { - dprintf(out, "usb_host_init failed\n"); - return ::android::UNKNOWN_ERROR; - } - - usb_host_run(ctx, usbDeviceAdded, NULL, usbDiscoveryDone, &cmd); - usb_host_cleanup(ctx); - - return ::android::NO_ERROR; -} - status_t Usb::handleShellCommand(int in, int out, int err, const char** argv, uint32_t argc) { uid_t uid = AIBinder_getCallingUid(); @@ -1180,13 +1177,28 @@ status_t Usb::handleShellCommand(int in, int out, int err, const char** argv, if (argc >= 1) { if (!utf8Args[0].compare(String8("hub-vendor-cmd"))) { - return sendHubVendorCmd(out, utf8Args); + if (utf8Args.size() < 3) { + dprintf(out, "Incorrect number of argument supplied\n"); + return ::android::UNKNOWN_ERROR; + } + int value, index; + if (!::android::base::ParseInt(utf8Args[1].c_str(), &value) || + !::android::base::ParseInt(utf8Args[2].c_str(), &index)) { + dprintf(out, "Fail to parse arguments\n"); + return ::android::UNKNOWN_ERROR; + } + mUsbHubVendorCmdValue = value; + mUsbHubVendorCmdIndex = index; + ALOGI("USB hub vendor cmd update (wValue 0x%x, wIndex 0x%x)\n", + mUsbHubVendorCmdValue, mUsbHubVendorCmdIndex); + return ::android::NO_ERROR; } } dprintf(out, "usage: adb shell cmd hub-vendor-cmd VALUE INDEX\n" - " VALUE wValue field in hex format, e.g. f321\n" - " INDEX wIndex field in hex format, e.g. f321\n"); + " VALUE wValue field in hex format, e.g. 0xf321\n" + " INDEX wIndex field in hex format, e.g. 0xf321\n" + " The settings take effect next time the hub is enabled\n"); return ::android::NO_ERROR; } |