summaryrefslogtreecommitdiff
path: root/usb/usb/Usb.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'usb/usb/Usb.cpp')
-rw-r--r--usb/usb/Usb.cpp174
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;
}