Support GL852G USB hub JK level tuning am: fdb65f4d14 am: a9bdbe4633

Original change: https://googleplex-android-review.googlesource.com/c/device/google/gs201/+/22122915

Change-Id: I5f10b6305b7a67daa88072cb146db429bb037174
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Roy Luo 2023-04-06 02:51:28 +00:00 committed by Automerger Merge Worker
commit ea517e30e5
2 changed files with 88 additions and 80 deletions

View file

@ -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,
@ -1095,82 +1160,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();
@ -1186,13 +1175,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;
}

View file

@ -93,8 +93,12 @@ struct Usb : public BnUsb {
float mPluggedTemperatureCelsius;
// Usb Data status
bool mUsbDataEnabled;
// Usb hub vendor command settings for JK level tuning
int mUsbHubVendorCmdValue;
int mUsbHubVendorCmdIndex;
private:
pthread_t mPoll;
pthread_t mUsbHost;
};
} // namespace usb