Merge "usb: reattempt to enter displayport alt mode if driver entry process fails" into main
This commit is contained in:
commit
637426c6a8
2 changed files with 75 additions and 3 deletions
|
@ -550,6 +550,11 @@ Usb::Usb()
|
||||||
ALOGE("mDisplayPortDebounceTimer timerfd failed: %s", strerror(errno));
|
ALOGE("mDisplayPortDebounceTimer timerfd failed: %s", strerror(errno));
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
mDisplayPortActivateTimer = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
|
||||||
|
if (mDisplayPortActivateTimer == -1) {
|
||||||
|
ALOGE("mDisplayPortActivateTimer timerfd failed: %s", strerror(errno));
|
||||||
|
abort();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ScopedAStatus Usb::switchRole(const string& in_portName, const PortRole& in_role,
|
ScopedAStatus Usb::switchRole(const string& in_portName, const PortRole& in_role,
|
||||||
|
@ -1496,6 +1501,10 @@ static int displayPortPollOpenFileHelper(const char *file, int flags) {
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* armTimerFdHelper - Sets timerfd (fd) to trigger after (ms) milliseconds.
|
||||||
|
* Setting ms to 0 disarms the timer.
|
||||||
|
*/
|
||||||
static int armTimerFdHelper(int fd, int ms) {
|
static int armTimerFdHelper(int fd, int ms) {
|
||||||
struct itimerspec ts;
|
struct itimerspec ts;
|
||||||
|
|
||||||
|
@ -1508,23 +1517,31 @@ static int armTimerFdHelper(int fd, int ms) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void *displayPortPollWork(void *param) {
|
void *displayPortPollWork(void *param) {
|
||||||
|
/* USB Payload */
|
||||||
|
::aidl::android::hardware::usb::Usb *usb = (::aidl::android::hardware::usb::Usb *)param;
|
||||||
|
/* Epoll fields */
|
||||||
int epoll_fd;
|
int epoll_fd;
|
||||||
struct epoll_event ev_hpd, ev_pin, ev_orientation, ev_eventfd, ev_link, ev_debounce;
|
struct epoll_event ev_hpd, ev_pin, ev_orientation, ev_eventfd, ev_link, ev_debounce;
|
||||||
|
struct epoll_event ev_activate;
|
||||||
int nevents = 0;
|
int nevents = 0;
|
||||||
int hpd_fd, pin_fd, orientation_fd, link_training_status_fd;
|
int hpd_fd, pin_fd, orientation_fd, link_training_status_fd;
|
||||||
int file_flags = O_RDONLY;
|
int file_flags = O_RDONLY;
|
||||||
int epoll_flags;
|
int epoll_flags;
|
||||||
|
/* DisplayPort link statuses */
|
||||||
bool orientationSet = false;
|
bool orientationSet = false;
|
||||||
bool pinSet = false;
|
bool pinSet = false;
|
||||||
|
int activateRetryCount = 0;
|
||||||
unsigned long res;
|
unsigned long res;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
/* File paths */
|
||||||
string displayPortUsbPath, irqHpdCountPath, hpdPath, pinAssignmentPath, orientationPath;
|
string displayPortUsbPath, irqHpdCountPath, hpdPath, pinAssignmentPath, orientationPath;
|
||||||
string tcpcI2cBus, linkPath;
|
string tcpcI2cBus, linkPath, partnerActivePath, portActivePath;
|
||||||
::aidl::android::hardware::usb::Usb *usb = (::aidl::android::hardware::usb::Usb *)param;
|
|
||||||
|
|
||||||
usb->mDisplayPortPollRunning = true;
|
usb->mDisplayPortPollRunning = true;
|
||||||
usb->mDisplayPortPollStarting = false;
|
usb->mDisplayPortPollStarting = false;
|
||||||
|
|
||||||
|
/*---------- Setup ----------*/
|
||||||
|
|
||||||
if (usb->getDisplayPortUsbPathHelper(&displayPortUsbPath) == Status::ERROR) {
|
if (usb->getDisplayPortUsbPathHelper(&displayPortUsbPath) == Status::ERROR) {
|
||||||
ALOGE("usbdp: worker: could not locate usb displayport directory");
|
ALOGE("usbdp: worker: could not locate usb displayport directory");
|
||||||
goto usb_path_error;
|
goto usb_path_error;
|
||||||
|
@ -1536,6 +1553,9 @@ void *displayPortPollWork(void *param) {
|
||||||
orientationPath = "/sys/class/typec/port0/orientation";
|
orientationPath = "/sys/class/typec/port0/orientation";
|
||||||
linkPath = string(kDisplayPortDrmPath) + "link_status";
|
linkPath = string(kDisplayPortDrmPath) + "link_status";
|
||||||
|
|
||||||
|
partnerActivePath = displayPortUsbPath + "../mode1/active";
|
||||||
|
portActivePath = "/sys/class/typec/port0/port0.0/mode1/active";
|
||||||
|
|
||||||
getI2cBusHelper(&tcpcI2cBus);
|
getI2cBusHelper(&tcpcI2cBus);
|
||||||
irqHpdCountPath = kI2CPath + tcpcI2cBus + "/" + tcpcI2cBus + kIrqHpdCounPath;
|
irqHpdCountPath = kI2CPath + tcpcI2cBus + "/" + tcpcI2cBus + kIrqHpdCounPath;
|
||||||
ALOGI("usbdp: worker: irqHpdCountPath:%s", irqHpdCountPath.c_str());
|
ALOGI("usbdp: worker: irqHpdCountPath:%s", irqHpdCountPath.c_str());
|
||||||
|
@ -1568,12 +1588,15 @@ void *displayPortPollWork(void *param) {
|
||||||
ev_eventfd.events = epoll_flags;
|
ev_eventfd.events = epoll_flags;
|
||||||
ev_link.events = epoll_flags;
|
ev_link.events = epoll_flags;
|
||||||
ev_debounce.events = epoll_flags;
|
ev_debounce.events = epoll_flags;
|
||||||
|
ev_activate.events = epoll_flags;
|
||||||
|
|
||||||
ev_hpd.data.fd = hpd_fd;
|
ev_hpd.data.fd = hpd_fd;
|
||||||
ev_pin.data.fd = pin_fd;
|
ev_pin.data.fd = pin_fd;
|
||||||
ev_orientation.data.fd = orientation_fd;
|
ev_orientation.data.fd = orientation_fd;
|
||||||
ev_eventfd.data.fd = usb->mDisplayPortEventPipe;
|
ev_eventfd.data.fd = usb->mDisplayPortEventPipe;
|
||||||
ev_link.data.fd = link_training_status_fd;
|
ev_link.data.fd = link_training_status_fd;
|
||||||
ev_debounce.data.fd = usb->mDisplayPortDebounceTimer;
|
ev_debounce.data.fd = usb->mDisplayPortDebounceTimer;
|
||||||
|
ev_activate.data.fd = usb->mDisplayPortActivateTimer;
|
||||||
|
|
||||||
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, hpd_fd, &ev_hpd) == -1) {
|
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, hpd_fd, &ev_hpd) == -1) {
|
||||||
ALOGE("usbdp: worker: epoll_ctl failed to add hpd; errno=%d", errno);
|
ALOGE("usbdp: worker: epoll_ctl failed to add hpd; errno=%d", errno);
|
||||||
|
@ -1592,7 +1615,11 @@ void *displayPortPollWork(void *param) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, usb->mDisplayPortDebounceTimer, &ev_debounce) == -1) {
|
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, usb->mDisplayPortDebounceTimer, &ev_debounce) == -1) {
|
||||||
ALOGE("usbdp: worker: epoll_ctl failed to add debounce; errno=%d", errno);
|
ALOGE("usbdp: worker: epoll_ctl failed to add framework update debounce; errno=%d", errno);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, usb->mDisplayPortActivateTimer, &ev_activate) == -1) {
|
||||||
|
ALOGE("usbdp: worker: epoll_ctl failed to add activate debounce; errno=%d", errno);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, usb->mDisplayPortEventPipe, &ev_eventfd) == -1) {
|
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, usb->mDisplayPortEventPipe, &ev_eventfd) == -1) {
|
||||||
|
@ -1600,6 +1627,9 @@ void *displayPortPollWork(void *param) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Arm timer to see if DisplayPort Alt Mode Activates */
|
||||||
|
armTimerFdHelper(usb->mDisplayPortActivateTimer, DISPLAYPORT_ACTIVATE_DEBOUNCE_MS);
|
||||||
|
|
||||||
while (!destroyDisplayPortThread) {
|
while (!destroyDisplayPortThread) {
|
||||||
struct epoll_event events[64];
|
struct epoll_event events[64];
|
||||||
|
|
||||||
|
@ -1649,6 +1679,33 @@ void *displayPortPollWork(void *param) {
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
ALOGE("usbdp: debounce read errno:%d", errno);
|
ALOGE("usbdp: debounce read errno:%d", errno);
|
||||||
queryVersionHelper(usb, ¤tPortStatus);
|
queryVersionHelper(usb, ¤tPortStatus);
|
||||||
|
} else if (events[n].data.fd == usb->mDisplayPortActivateTimer) {
|
||||||
|
string activePartner, activePort;
|
||||||
|
|
||||||
|
if (ReadFileToString(partnerActivePath.c_str(), &activePartner) &&
|
||||||
|
ReadFileToString(portActivePath.c_str(), &activePort)) {
|
||||||
|
// Retry activate signal when DisplayPort Alt Mode is active on port but not
|
||||||
|
// partner.
|
||||||
|
if (!strncmp(activePartner.c_str(), "no", strlen("no")) &&
|
||||||
|
!strncmp(activePort.c_str(), "yes", strlen("yes")) &&
|
||||||
|
activateRetryCount < DISPLAYPORT_ACTIVATE_MAX_RETRIES) {
|
||||||
|
if (!WriteStringToFile("1", partnerActivePath)) {
|
||||||
|
ALOGE("usbdp: Failed to activate port partner Alt Mode");
|
||||||
|
} else {
|
||||||
|
ALOGI("usbdp: Attempting to activate port partner Alt Mode");
|
||||||
|
}
|
||||||
|
activateRetryCount++;
|
||||||
|
armTimerFdHelper(usb->mDisplayPortActivateTimer,
|
||||||
|
DISPLAYPORT_ACTIVATE_DEBOUNCE_MS);
|
||||||
|
} else {
|
||||||
|
ALOGI("usbdp: DisplayPort Alt Mode is active, or disabled on port");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
activateRetryCount++;
|
||||||
|
armTimerFdHelper(usb->mDisplayPortActivateTimer,
|
||||||
|
DISPLAYPORT_ACTIVATE_DEBOUNCE_MS);
|
||||||
|
ALOGE("usbdp: Failed to read active state from port or partner");
|
||||||
|
}
|
||||||
} else if (events[n].data.fd == usb->mDisplayPortEventPipe) {
|
} else if (events[n].data.fd == usb->mDisplayPortEventPipe) {
|
||||||
uint64_t flag = 0;
|
uint64_t flag = 0;
|
||||||
if (!read(usb->mDisplayPortEventPipe, &flag, sizeof(flag))) {
|
if (!read(usb->mDisplayPortEventPipe, &flag, sizeof(flag))) {
|
||||||
|
@ -1670,6 +1727,8 @@ void *displayPortPollWork(void *param) {
|
||||||
}
|
}
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
/* Need to disarm so new threads don't get old event */
|
||||||
|
armTimerFdHelper(usb->mDisplayPortActivateTimer, 0);
|
||||||
close(link_training_status_fd);
|
close(link_training_status_fd);
|
||||||
link_training_status_fd_error:
|
link_training_status_fd_error:
|
||||||
close(orientation_fd);
|
close(orientation_fd);
|
||||||
|
@ -1679,6 +1738,7 @@ pin_fd_error:
|
||||||
close(hpd_fd);
|
close(hpd_fd);
|
||||||
hpd_fd_error:
|
hpd_fd_error:
|
||||||
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, usb->mDisplayPortDebounceTimer, &ev_debounce);
|
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, usb->mDisplayPortDebounceTimer, &ev_debounce);
|
||||||
|
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, usb->mDisplayPortActivateTimer, &ev_activate);
|
||||||
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, usb->mDisplayPortEventPipe, &ev_eventfd);
|
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, usb->mDisplayPortEventPipe, &ev_eventfd);
|
||||||
close(epoll_fd);
|
close(epoll_fd);
|
||||||
epoll_fd_error:
|
epoll_fd_error:
|
||||||
|
|
|
@ -31,6 +31,13 @@
|
||||||
#define PORT_TYPE_TIMEOUT 8
|
#define PORT_TYPE_TIMEOUT 8
|
||||||
#define DISPLAYPORT_CAPABILITIES_RECEPTACLE_BIT 6
|
#define DISPLAYPORT_CAPABILITIES_RECEPTACLE_BIT 6
|
||||||
#define DISPLAYPORT_STATUS_DEBOUNCE_MS 2000
|
#define DISPLAYPORT_STATUS_DEBOUNCE_MS 2000
|
||||||
|
/*
|
||||||
|
* Type-C HAL should wait 2 seconds to reattempt DisplayPort Alt Mode entry to
|
||||||
|
* allow the port and port partner to settle Role Swaps.
|
||||||
|
*/
|
||||||
|
#define DISPLAYPORT_ACTIVATE_DEBOUNCE_MS 2000
|
||||||
|
// Number of times the HAL should reattempt to enter DisplayPort Alt Mode
|
||||||
|
#define DISPLAYPORT_ACTIVATE_MAX_RETRIES 2
|
||||||
|
|
||||||
namespace aidl {
|
namespace aidl {
|
||||||
namespace android {
|
namespace android {
|
||||||
|
@ -142,6 +149,11 @@ struct Usb : public BnUsb {
|
||||||
* sending notifications to the frameworks layer.
|
* sending notifications to the frameworks layer.
|
||||||
*/
|
*/
|
||||||
int mDisplayPortDebounceTimer;
|
int mDisplayPortDebounceTimer;
|
||||||
|
/*
|
||||||
|
* eventfd to monitor whether a connection results in DisplayPort Alt Mode activating.
|
||||||
|
*/
|
||||||
|
int mDisplayPortActivateTimer;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
pthread_t mPoll;
|
pthread_t mPoll;
|
||||||
pthread_t mDisplayPortPoll;
|
pthread_t mDisplayPortPoll;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue