Poll the sysfs attributes that represents usb device state in either of the following states: not attached, powered, default, addressed, configured. The information is useful in detecting non compliant USB cable, which will be supported in later patch sets. This patch lays the ground work to monitor the sysfs attributes in both device and host modes. The thread to poll uevent is re-used to poll sysfs because this serialize type-C port events and usb device state changes, hence prevent potential races. Added a thin abstration layer and a map to keep epoll data so that it's easier to dynamically add/delete files to epoll, which is needed for usb devices in host mode. Bug: 285199434 Test: trigger usb device state changes in device and host mode Change-Id: Ie5389d051deb28dbb486c2f27319b3cc9e89312f
156 lines
5.5 KiB
C++
156 lines
5.5 KiB
C++
/*
|
|
* Copyright (C) 2021 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <android-base/file.h>
|
|
#include <aidl/android/hardware/usb/BnUsb.h>
|
|
#include <aidl/android/hardware/usb/BnUsbCallback.h>
|
|
#include <pixelusb/UsbOverheatEvent.h>
|
|
#include <sys/eventfd.h>
|
|
#include <utils/Log.h>
|
|
|
|
#define UEVENT_MSG_LEN 2048
|
|
// The type-c stack waits for 4.5 - 5.5 secs before declaring a port non-pd.
|
|
// The -partner directory would not be created until this is done.
|
|
// Having a margin of ~3 secs for the directory and other related bookeeping
|
|
// structures created and uvent fired.
|
|
#define PORT_TYPE_TIMEOUT 8
|
|
|
|
namespace aidl {
|
|
namespace android {
|
|
namespace hardware {
|
|
namespace usb {
|
|
|
|
using ::aidl::android::hardware::usb::IUsbCallback;
|
|
using ::aidl::android::hardware::usb::PortRole;
|
|
using ::android::base::ReadFileToString;
|
|
using ::android::base::WriteStringToFile;
|
|
using ::android::base::unique_fd;
|
|
using ::android::hardware::google::pixel::usb::UsbOverheatEvent;
|
|
using ::android::hardware::google::pixel::usb::ZoneInfo;
|
|
using ::android::hardware::thermal::V2_0::TemperatureType;
|
|
using ::android::hardware::thermal::V2_0::ThrottlingSeverity;
|
|
using ::android::sp;
|
|
using ::ndk::ScopedAStatus;
|
|
using ::std::shared_ptr;
|
|
using ::std::string;
|
|
using ::std::thread;
|
|
|
|
constexpr char kGadgetName[] = "11210000.dwc3";
|
|
#define NEW_UDC_PATH "/sys/devices/platform/11210000.usb/"
|
|
|
|
#define ID_PATH NEW_UDC_PATH "dwc3_exynos_otg_id"
|
|
#define VBUS_PATH NEW_UDC_PATH "dwc3_exynos_otg_b_sess"
|
|
#define USB_DATA_PATH NEW_UDC_PATH "usb_data_enabled"
|
|
|
|
#define DISPLAYPORT_SHUTDOWN_CLEAR 0
|
|
#define DISPLAYPORT_SHUTDOWN_SET 1
|
|
#define DISPLAYPORT_IRQ_HPD_COUNT_CHECK 3
|
|
|
|
#define DISPLAYPORT_POLL_WAIT_MS 100
|
|
|
|
struct Usb : public BnUsb {
|
|
Usb();
|
|
|
|
ScopedAStatus enableContaminantPresenceDetection(const std::string& in_portName,
|
|
bool in_enable, int64_t in_transactionId) override;
|
|
ScopedAStatus queryPortStatus(int64_t in_transactionId) override;
|
|
ScopedAStatus setCallback(const shared_ptr<IUsbCallback>& in_callback) override;
|
|
ScopedAStatus switchRole(const string& in_portName, const PortRole& in_role,
|
|
int64_t in_transactionId) override;
|
|
ScopedAStatus enableUsbData(const string& in_portName, bool in_enable,
|
|
int64_t in_transactionId) override;
|
|
ScopedAStatus enableUsbDataWhileDocked(const string& in_portName,
|
|
int64_t in_transactionId) override;
|
|
ScopedAStatus limitPowerTransfer(const string& in_portName, bool in_limit,
|
|
int64_t in_transactionId) override;
|
|
ScopedAStatus resetUsbPort(const string& in_portName, int64_t in_transactionId) override;
|
|
|
|
Status getDisplayPortUsbPathHelper(string *path);
|
|
Status writeDisplayPortAttributeOverride(string attribute, string value);
|
|
Status writeDisplayPortAttribute(string attribute, string usb_path);
|
|
bool determineDisplayPortRetry(string linkPath, string hpdPath);
|
|
void setupDisplayPortPoll();
|
|
void shutdownDisplayPortPollHelper();
|
|
void shutdownDisplayPortPoll(bool force);
|
|
|
|
std::shared_ptr<::aidl::android::hardware::usb::IUsbCallback> mCallback;
|
|
// Protects mCallback variable
|
|
pthread_mutex_t mLock;
|
|
// Protects roleSwitch operation
|
|
pthread_mutex_t mRoleSwitchLock;
|
|
// Threads waiting for the partner to come back wait here
|
|
pthread_cond_t mPartnerCV;
|
|
// lock protecting mPartnerCV
|
|
pthread_mutex_t mPartnerLock;
|
|
// Variable to signal partner coming back online after type switch
|
|
bool mPartnerUp;
|
|
|
|
// Usb Overheat object for push suez event
|
|
UsbOverheatEvent mOverheat;
|
|
// Temperature when connected
|
|
float mPluggedTemperatureCelsius;
|
|
// Usb Data status
|
|
bool mUsbDataEnabled;
|
|
// True when mDisplayPortPoll pthread is running
|
|
volatile bool mDisplayPortPollRunning;
|
|
volatile bool mDisplayPortPollStarting;
|
|
pthread_cond_t mDisplayPortCV;
|
|
pthread_mutex_t mDisplayPortCVLock;
|
|
volatile bool mDisplayPortFirstSetupDone;
|
|
// Used to cache the values read from tcpci's irq_hpd_count.
|
|
// Update drm driver when cached value is not the same as the read value.
|
|
uint32_t mIrqHpdCountCache;
|
|
|
|
// Protects writeDisplayPortToExynos(), setupDisplayPortPoll(), and
|
|
// shutdownDisplayPortPoll()
|
|
pthread_mutex_t mDisplayPortLock;
|
|
// eventfd to signal DisplayPort thread
|
|
int mDisplayPortEventPipe;
|
|
|
|
// USB device state monitoring
|
|
struct usbDeviceState {
|
|
std::string latestState;
|
|
int portResetCount;
|
|
};
|
|
struct usbDeviceState mDeviceState;
|
|
// Map host device path name to usbDeviceState
|
|
std::map<std::string, struct usbDeviceState> mHostStateMap;
|
|
|
|
// File monitoring through epoll
|
|
int mEpollFd;
|
|
struct payload {
|
|
int fd;
|
|
std::string name;
|
|
Usb *usb;
|
|
};
|
|
struct epollEntry {
|
|
struct payload payload;
|
|
std::function<void(uint32_t)> cb;
|
|
};
|
|
std::map<std::string, struct epollEntry> mEpollEntries;
|
|
|
|
private:
|
|
pthread_t mPoll;
|
|
pthread_t mDisplayPortPoll;
|
|
pthread_t mDisplayPortShutdownHelper;
|
|
};
|
|
|
|
} // namespace usb
|
|
} // namespace hardware
|
|
} // namespace android
|
|
} // aidl
|