1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef HARDWARE_GOOGLE_PIXEL_USB_USBDPUTILS_H_
18 #define HARDWARE_GOOGLE_PIXEL_USB_USBDPUTILS_H_
19 
20 #include <aidl/android/hardware/usb/AltModeData.h>
21 #include <aidl/android/hardware/usb/DisplayPortAltModePinAssignment.h>
22 #include <aidl/android/hardware/usb/DisplayPortAltModeStatus.h>
23 #include <aidl/android/hardware/usb/LinkTrainingStatus.h>
24 #include <aidl/android/hardware/usb/Status.h>
25 
26 #include <string>
27 
28 using aidl::android::hardware::usb::AltModeData;
29 using aidl::android::hardware::usb::DisplayPortAltModePinAssignment;
30 using aidl::android::hardware::usb::LinkTrainingStatus;
31 using aidl::android::hardware::usb::Status;
32 
33 using std::string;
34 
35 #define DISPLAYPORT_SHUTDOWN_CLEAR 0
36 #define DISPLAYPORT_SHUTDOWN_SET 1
37 #define DISPLAYPORT_IRQ_HPD_COUNT_CHECK 3
38 
39 #define DISPLAYPORT_POLL_WAIT_MS 100
40 
41 #define SVID_DISPLAYPORT "ff01"
42 #define SVID_THUNDERBOLT "8087"
43 
44 namespace android {
45 namespace hardware {
46 namespace google {
47 namespace pixel {
48 namespace usb {
49 
50 class UsbDp {
51   private:
52     string mDrmPath;
53     string mClientPath;
54 
55     // True when mPoll thread is running
56     volatile bool mPollRunning;
57     volatile bool mPollStarting;
58 
59     pthread_cond_t mCV;
60     pthread_mutex_t mCVLock;
61 
62     volatile bool mFirstSetupDone;
63 
64     // Used to cache the values read from tcpci's irq_hpd_count.
65     // Update drm driver when cached value is not the same as the read value.
66     uint32_t mIrqCountCache;
67 
68     pthread_t mPoll;
69     pthread_t mDisplayPortShutdownHelper;
70 
71     // Callback called when mDisplayPortDebounceTimer is triggered
72     void (*mCallback)(void *payload);
73     void *mPayload;
74 
75     // eventfd to signal DisplayPort thread from typec kernel driver
76     int mDisplayPortEventPipe;
77 
78     /*
79      * eventfd to set DisplayPort framework update debounce timer. Debounce
80      * timer is necessary for
81      *     1) allowing enough time for each sysfs node needed to set HPD high
82      *        in the drm to populate
83      *     2) preventing multiple IRQs that trigger link training failures
84      *        from continuously sending notifications to the frameworks layer.
85      */
86     int mDisplayPortDebounceTimer;
87 
88     /*
89      * eventfd to monitor whether a connection results in DisplayPort Alt Mode activating.
90      */
91     int mActivateTimer;
92 
93     /*
94      * Indicates whether or not port partner supports DisplayPort, and is used to
95      * communicate to the drm when the port partner physically disconnects.
96      */
97     bool mPartnerSupportsDisplayPort;
98 
99     Status writeDisplayPortAttribute(string attribute, string usb_path);
100 
101   public:
102     UsbDp(const char *const drmPath);
103 
104     /* Internal to Library */
105     // For thread setup
106     void displayPortPollWorkHelper();
107     void shutdownDisplayPortPollHelper();
108 
109     /* For HAL Use */
110     // Protects writeDisplayPortAttribute(), setupDisplayPortPoll(),
111     // and shutdownDisplayPortPoll()
112     pthread_mutex_t mLock;
113 
114     // Setup and Shutdown Thread
115     void setupDisplayPortPoll();
116     void shutdownDisplayPortPoll(bool force);
117 
118     bool isFirstSetupDone();
119     // i2cClientPath
120     void setClientPath(string path);
121     // mPollRunning
122     bool getPollRunning();
123     // mPartnerSupportsDisplayPort
124     void setPartnerSupportsDisplayPort(bool supportsDp);
125     bool getPartnerSupportsDisplayPort();
126 
127     void updateDisplayPortEventPipe(uint64_t flag);
128 
129     Status readDisplayPortAttribute(string attribute, string usb_path, string *value);
130     Status writeHpdOverride(string attribute, string value);
131 
132     void registerCallback(void (*callback)(void *(payload)), void *payload);
133 };
134 
135 /* Sysfs Helper Functions */
136 Status getDisplayPortUsbPathHelper(string *path);
137 Status queryPartnerSvids(std::vector<string> *svids);
138 
139 /* AIDL Helper Functions */
140 AltModeData::DisplayPortAltModeData constructAltModeData(string hpd, string pin_assignment,
141                                                          string link_status, string vdo);
142 
143 }  // namespace usb
144 }  // namespace pixel
145 }  // namespace google
146 }  // namespace hardware
147 }  // namespace android
148 
149 #endif  // HARDWARE_GOOGLE_PIXEL_USB_USBDPUTILS_H_
150