1 /*
2  * Copyright (c) 2015, Freescale Semiconductor, Inc.
3  * Copyright 2016,2019 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #ifndef _USB_HOST_CONTROLLER_EHCI_H_
10 #define _USB_HOST_CONTROLLER_EHCI_H_
11 
12 /*******************************************************************************
13  * KHCI private public structures, enumerations, macros, functions
14  ******************************************************************************/
15 
16 /*******************************************************************************
17  * Definitions
18  ******************************************************************************/
19 /* EHCI host macros */
20 #define EHCI_HOST_T_INVALID_VALUE      (1U)
21 #define EHCI_HOST_POINTER_TYPE_ITD     (0x00U)
22 #define EHCI_HOST_POINTER_TYPE_QH      (0x00000002U)
23 #define EHCI_HOST_POINTER_TYPE_SITD    (0x00000004U)
24 #define EHCI_HOST_POINTER_TYPE_FSTN    (0x00000006U)
25 #define EHCI_HOST_POINTER_TYPE_MASK    (0x00000006U)
26 #define EHCI_HOST_POINTER_ADDRESS_MASK (0xFFFFFFE0U)
27 #define EHCI_HOST_PID_OUT              (0UL)
28 #define EHCI_HOST_PID_IN               (1UL)
29 #define EHCI_HOST_PID_SETUP            (2UL)
30 
31 #define EHCI_HOST_QH_RL_SHIFT                  (28U)
32 #define EHCI_HOST_QH_RL_MASK                   (0xF0000000U)
33 #define EHCI_HOST_QH_C_SHIFT                   (27U)
34 #define EHCI_HOST_QH_MAX_PACKET_LENGTH_SHIFT   (16U)
35 #define EHCI_HOST_QH_MAX_PACKET_LENGTH_MASK    (0x07FF0000U)
36 #define EHCI_HOST_QH_H_SHIFT                   (15U)
37 #define EHCI_HOST_QH_DTC_SHIFT                 (14U)
38 #define EHCI_HOST_QH_EPS_SHIFT                 (12U)
39 #define EHCI_HOST_QH_ENDPT_SHIFT               (8U)
40 #define EHCI_HOST_QH_I_SHIFT                   (7U)
41 #define EHCI_HOST_QH_DEVICE_ADDRESS_SHIFT      (0U)
42 #define EHCI_HOST_QH_MULT_SHIFT                (30U)
43 #define EHCI_HOST_QH_PORT_NUMBER_SHIFT         (23U)
44 #define EHCI_HOST_QH_HUB_ADDR_SHIFT            (16U)
45 #define EHCI_HOST_QH_UFRAME_CMASK_SHIFT        (8U)
46 #define EHCI_HOST_QH_UFRAME_SMASK_SHIFT        (0U)
47 #define EHCI_HOST_QH_STATUS_ERROR_MASK         (0x0000007EU)
48 #define EHCI_HOST_QH_STATUS_NOSTALL_ERROR_MASK (0x0000003EU)
49 
50 #define EHCI_HOST_QTD_DT_SHIFT                (31U)
51 #define EHCI_HOST_QTD_DT_MASK                 (0x80000000U)
52 #define EHCI_HOST_QTD_TOTAL_BYTES_SHIFT       (16U)
53 #define EHCI_HOST_QTD_TOTAL_BYTES_MASK        (0x7FFF0000U)
54 #define EHCI_HOST_QTD_IOC_MASK                (0x00008000U)
55 #define EHCI_HOST_QTD_C_PAGE_SHIFT            (12U)
56 #define EHCI_HOST_QTD_CERR_SHIFT              (10U)
57 #define EHCI_HOST_QTD_CERR_MAX_VALUE          (0x00000003UL)
58 #define EHCI_HOST_QTD_PID_CODE_SHIFT          (8U)
59 #define EHCI_HOST_QTD_STATUS_SHIFT            (0U)
60 #define EHCI_HOST_QTD_CURRENT_OFFSET_MASK     (0x00000FFFU)
61 #define EHCI_HOST_QTD_BUFFER_POINTER_SHIFT    (12U)
62 #define EHCI_HOST_QTD_STATUS_ACTIVE_MASK      (0x00000080U)
63 #define EHCI_HOST_QTD_STATUS_MASK             (0x000000ffU)
64 #define EHCI_HOST_QTD_STATUS_ERROR_MASK       (0x0000007EU)
65 #define EHCI_HOST_QTD_STATUS_STALL_ERROR_MASK (0x00000040U)
66 
67 #define EHCI_HOST_ITD_STATUS_ACTIVE_MASK       (0x80000000U)
68 #define EHCI_HOST_ITD_TRANSACTION_LEN_SHIFT    (16U)
69 #define EHCI_HOST_ITD_TRANSACTION_LEN_MASK     (0x0FFF0000U)
70 #define EHCI_HOST_ITD_IOC_SHIFT                (15U)
71 #define EHCI_HOST_ITD_PG_SHIFT                 (12U)
72 #define EHCI_HOST_ITD_TRANSACTION_OFFSET_SHIFT (0U)
73 #define EHCI_HOST_ITD_TRANSACTION_OFFSET_MASK  (0x00000FFFU)
74 #define EHCI_HOST_ITD_BUFFER_POINTER_SHIFT     (12U)
75 #define EHCI_HOST_ITD_ENDPT_SHIFT              (8U)
76 #define EHCI_HOST_ITD_DEVICE_ADDRESS_SHIFT     (0U)
77 #define EHCI_HOST_ITD_MAX_PACKET_SIZE_SHIFT    (0U)
78 #define EHCI_HOST_ITD_MULT_SHIFT               (0U)
79 #define EHCI_HOST_ITD_DIRECTION_SHIFT          (11U)
80 
81 #define EHCI_HOST_SITD_STATUS_ACTIVE_MASK   (0x00000080U)
82 #define EHCI_HOST_SITD_DIRECTION_SHIFT      (31U)
83 #define EHCI_HOST_SITD_PORT_NUMBER_SHIFT    (24U)
84 #define EHCI_HOST_SITD_HUB_ADDR_SHIFT       (16U)
85 #define EHCI_HOST_SITD_ENDPT_SHIFT          (8U)
86 #define EHCI_HOST_SITD_DEVICE_ADDRESS_SHIFT (0U)
87 #define EHCI_HOST_SITD_CMASK_SHIFT          (8U)
88 #define EHCI_HOST_SITD_SMASK_SHIFT          (0U)
89 #define EHCI_HOST_SITD_TOTAL_BYTES_SHIFT    (16U)
90 #define EHCI_HOST_SITD_TOTAL_BYTES_MASK     (0x03FF0000U)
91 #define EHCI_HOST_SITD_TP_SHIFT             (3U)
92 #define EHCI_HOST_SITD_TCOUNT_SHIFT         (0U)
93 #define EHCI_HOST_SITD_IOC_SHIFT            (31U)
94 
95 /* register related MACROs */
96 #define EHCI_PORTSC1_W1_BITS  (0x0000002AU)
97 #define EHCI_MAX_UFRAME_VALUE (0x00003FFFU)
98 
99 /* task event */
100 #define EHCI_TASK_EVENT_DEVICE_ATTACH    (0x01U)
101 #define EHCI_TASK_EVENT_TRANSACTION_DONE (0x02U)
102 #define EHCI_TASK_EVENT_DEVICE_DETACH    (0x04U)
103 #define EHCI_TASK_EVENT_PORT_CHANGE      (0x08U)
104 #define EHCI_TASK_EVENT_TIMER0           (0x10U)
105 #define EHCI_TASK_EVENT_TIMER1           (0x20U)
106 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
107 #if ((defined(USB_HOST_CONFIG_LPM_L1)) && (USB_HOST_CONFIG_LPM_L1 > 0U))
108 #define EHCI_TASK_EVENT_HOST_COMPLETED_LPM  (0x40U)
109 #endif
110 #endif
111 
112 #define USB_HostEhciLock()   (void)OSA_MutexLock(ehciInstance->ehciMutex, USB_OSA_WAIT_TIMEOUT)
113 #define USB_HostEhciUnlock() (void)OSA_MutexUnlock(ehciInstance->ehciMutex)
114 
115 /*******************************************************************************
116  * KHCI driver public structures, enumerations, macros, functions
117  ******************************************************************************/
118 
119 /*!
120  * @addtogroup usb_host_controller_ehci
121  * @{
122  */
123 
124 /*! @brief The maximum supported ISO pipe number */
125 #define USB_HOST_EHCI_ISO_NUMBER USB_HOST_CONFIG_EHCI_MAX_ITD
126 /*! @brief Check the port connect state delay if the state is unstable */
127 #define USB_HOST_EHCI_PORT_CONNECT_DEBOUNCE_DELAY (101U)
128 /*! @brief Delay for port reset */
129 #define USB_HOST_EHCI_PORT_RESET_DELAY (11U)
130 /*! @brief The MAX continuous transfers that application can send. */
131 #define USB_HOST_EHCI_ISO_MAX_CONTINUOUS_TRANSFER (8U)
132 /*! @brief The SITD inserts a frame interval for putting more SITD continuously.
133  * There is an interval when an application sends two FS/LS ISO transfers.
134  * When the interval is less than the macro, the two transfers are continuous in the frame list. Otherwise, the two
135  * transfers
136  * are not continuous.
137  * For example:
138  * - Use case 1: when inserting the SITD first, the inserted frame = the current frame value + this MACRO value.
139  * - Use case 2: when inserting SITD is not first, choose between the last inserted frame value and the
140  * current frame value according to the following criteria:
141  *           If the interval is less than the MACRO value, the new SITD is continuous with the last SITD.
142  *           If not, the new SITD inserting frame = the current frame value + this MACRO value.
143  */
144 #define USB_HOST_EHCI_ISO_BOUNCE_FRAME_NUMBER (2U)
145 /*! @brief The ITD inserts a micro-frame interval for putting more ITD continuously.
146  * There is an interval when an application sends two HS ISO transfers.
147  * When the interval is less than the macro, the two transfers are continuous in the frame list. Otherwise, the two
148  * transfers
149  * are not continuous.
150  * For example:
151  * - Use case 1: when inserting ITD first, the inserted micro-frame = the current micro-frame value + this MACRO value.
152  * - Use case 2: when inserting ITD is not first, choose between the last inserted micro-frame value and the
153  * current micro-frame value according to the following criteria:
154  *           If the interval is less than this MACRO value, the new ITD is continuous with the last ITD.
155  *           If not, the new ITD inserting micro-frame = the current micro-frame value + this MACRO value.
156  */
157 #define USB_HOST_EHCI_ISO_BOUNCE_UFRAME_NUMBER (16U)
158 /*! @brief Control or bulk transaction timeout value (unit: 100 ms) */
159 #define USB_HOST_EHCI_CONTROL_BULK_TIME_OUT_VALUE (50U)
160 
161 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
162 typedef enum _bus_ehci_suspend_request_state
163 {
164     kBus_EhciIdle = 0U,
165     kBus_EhciStartSuspend,
166     kBus_EhciSuspended,
167     kBus_EhciStartResume,
168     kBus_EhciL1StartSleep,
169     kBus_EhciL1Sleeped,
170     kBus_EhciL1StartResume,
171     kBus_EhciHsError,
172 } bus_ehci_suspend_request_state_t;
173 #endif
174 
175 /*! @brief EHCI state for device attachment/detachment. */
176 typedef enum _host_ehci_device_state_
177 {
178     kEHCIDevicePhyAttached = 1, /*!< Device is physically attached */
179     kEHCIDeviceAttached,        /*!< Device is attached and initialized */
180     kEHCIDeviceDetached,        /*!< Device is detached and de-initialized */
181 } host_ehci_device_state_t;
182 
183 /*! @brief EHCI pipe structure */
184 typedef struct _usb_host_ehci_pipe
185 {
186     usb_host_pipe_t pipeCommon; /*!< Common pipe information */
187     void *ehciQh;               /*!< Control/bulk/interrupt: QH; ISO: usb_host_ehci_iso_t*/
188 
189     /* bandwidth */
190     uint16_t uframeInterval;    /*!< Micro-frame interval value */
191     uint16_t startFrame;        /*!<
192                                      Bandwidth start frame: its value is from 0 to frame_list.
193                                  */
194     uint16_t dataTime;          /*!<
195                                      Bandwidth time value:
196                                      - When the host works as HS: it's the data bandwidth value.
197                                      - When the host works as FS/LS:
198                                          - For FS/LS device, it's the data bandwidth value when transferring the data by FS/LS.
199                                          - For HS device, it's the data bandwidth value when transferring the data by HS.
200                                  */
201     uint16_t startSplitTime;    /*!<
202                                       Start splitting the bandwidth time value:
203                                       - When the host works as HS, it is the start split bandwidth value.
204                                   */
205     uint16_t completeSplitTime; /*!<
206                                       Complete splitting the bandwidth time value:
207                                       - When host works as HS, it is the complete split bandwidth value.
208                                   */
209     uint8_t startUframe;        /*!<
210                                      Bandwidth start micro-frame: its value is from 0 to 7.
211                                  */
212     uint8_t uframeSmask;        /*!<
213                                      Start micro-frame.
214                                      - When host works as an HS:
215                                         - For FS/LS device, it's the interrupt or ISO transfer start-split mask.
216                                          - For HS device, it's the interrupt transfer start micro-frame mask.
217                                      - When host works as FS/LS, it's the interrupt and ISO start micro-frame mask
218                                  */
219     uint8_t uframeCmask;        /*!<
220                                      Complete micro-frame
221                                      - When host works as HS:
222                                          - For FS/LS device, it's the interrupt or ISO transfer complete-split mask.
223                                  */
224 } usb_host_ehci_pipe_t;
225 
226 /*! @brief EHCI QH structure. See the USB EHCI specification */
227 typedef struct _usb_host_ehci_qh
228 {
229     uint32_t horizontalLinkPointer; /*!< QH specification filed, queue head a horizontal link pointer */
230     uint32_t
231         staticEndpointStates[2]; /*!< QH specification filed, static endpoint state and configuration information */
232     uint32_t currentQtdPointer;  /*!< QH specification filed, current qTD pointer */
233     uint32_t nextQtdPointer;     /*!< QH specification filed, next qTD pointer */
234     uint32_t alternateNextQtdPointer; /*!< QH specification filed, alternate next qTD pointer */
235     uint32_t
236         transferOverlayResults[6]; /*!< QH specification filed, transfer overlay configuration and transfer results */
237 
238     /* reserved space */
239     usb_host_ehci_pipe_t *ehciPipePointer; /*!< EHCI pipe pointer */
240     usb_host_transfer_t *ehciTransferHead; /*!< Transfer list head on this QH */
241     usb_host_transfer_t *ehciTransferTail; /*!< Transfer list tail on this QH */
242     uint16_t timeOutValue; /*!< Its maximum value is USB_HOST_EHCI_CONTROL_BULK_TIME_OUT_VALUE. When the value is
243                                 zero, the transfer times out. */
244     uint16_t timeOutLabel; /*!< It's used to judge the transfer timeout. The EHCI driver maintain the value */
245 } usb_host_ehci_qh_t;
246 
247 /*! @brief EHCI QTD structure. See the USB EHCI specification. */
248 typedef struct _usb_host_ehci_qtd
249 {
250     uint32_t nextQtdPointer;          /*!< QTD specification filed, the next QTD pointer */
251     uint32_t alternateNextQtdPointer; /*!< QTD specification filed, alternate next QTD pointer */
252     uint32_t transferResults[2];      /*!< QTD specification filed, transfer results fields */
253     uint32_t bufferPointers[4];       /*!< QTD specification filed, transfer buffer fields */
254 } usb_host_ehci_qtd_t;
255 
256 /*! @brief EHCI ITD structure. See the USB EHCI specification. */
257 typedef struct _usb_host_ehci_itd
258 {
259     uint32_t nextLinkPointer;   /*!< ITD specification filed, the next linker pointer */
260     uint32_t transactions[8];   /*!< ITD specification filed, transactions information */
261     uint32_t bufferPointers[7]; /*!< ITD specification filed, transfer buffer fields */
262 
263     /* add space */
264     struct _usb_host_ehci_itd *nextItdPointer; /*!< Next ITD pointer */
265     uint32_t frameEntryIndex;                  /*!< The ITD inserted frame value */
266     uint32_t reserved[6];                      /*!< Reserved fields for 32 bytes align */
267 } usb_host_ehci_itd_t;
268 
269 /*! @brief EHCI SITD structure. See the USB EHCI specification. */
270 typedef struct _usb_host_ehci_sitd
271 {
272     uint32_t nextLinkPointer;    /*!< SITD specification filed, the next linker pointer */
273     uint32_t endpointStates[2];  /*!< SITD specification filed, endpoint configuration information */
274     uint32_t transferResults[3]; /*!< SITD specification filed, transfer result fields */
275     uint32_t backPointer;        /*!< SITD specification filed, back pointer */
276 
277     /* reserved space */
278     uint16_t frameEntryIndex; /*!< The SITD inserted frame value */
279     uint8_t nextSitdIndex;    /*!< The next SITD index; Get the next SITD pointer through adding base address with the
280                                  index. 0xFF means invalid. */
281     uint8_t reserved;         /*!< Reserved fields for 32 bytes align */
282 } usb_host_ehci_sitd_t;
283 
284 /*! @brief EHCI ISO structure; An ISO pipe has an instance of this structure to keep the ISO pipe-specific information.
285  */
286 typedef struct _usb_host_ehci_iso
287 {
288     struct _usb_host_ehci_iso *next;       /*!< Next instance pointer */
289     usb_host_pipe_t *ehciPipePointer;      /*!< This ISO's EHCI pipe pointer */
290     usb_host_transfer_t *ehciTransferHead; /*!< Transfer list head on this ISO pipe */
291     usb_host_transfer_t *ehciTransferTail; /*!< Transfer list head on this ISO pipe */
292 
293     uint16_t lastLinkFrame; /*!< It means that the inserted frame for ISO ITD/SITD. 0xFFFF is invalid. For ITD, it is a
294                                micro-frame value. For SITD, it is a frame value */
295 } usb_host_ehci_iso_t;
296 
297 /*! @brief EHCI instance structure */
298 typedef struct _usb_host_ehci_instance
299 {
300     usb_host_handle hostHandle;                /*!< Related host handle*/
301     uint32_t *ehciUnitBase;                    /*!< Keep the QH/QTD/ITD/SITD buffer pointer for release*/
302     uint8_t *ehciFrameList;                    /*!< The frame list of the current ehci instance*/
303     usb_host_ehci_qh_t *ehciQhList;            /*!< Idle QH list pointer */
304     usb_host_ehci_qtd_t *ehciQtdHead;          /*!< Idle QTD list pointer head */
305     usb_host_ehci_qtd_t *ehciQtdTail;          /*!< Idle QTD list pointer tail (recently used qTD will be used)*/
306     usb_host_ehci_itd_t *ehciItdList;          /*!< Idle ITD list pointer*/
307     usb_host_ehci_sitd_t *ehciSitdIndexBase;   /*!< SITD buffer's start pointer*/
308     usb_host_ehci_sitd_t *ehciSitdList;        /*!< Idle SITD list pointer*/
309     usb_host_ehci_iso_t *ehciIsoList;          /*!< Idle ISO list pointer*/
310     USBHS_Type *ehciIpBase;                    /*!< EHCI IP base address*/
311     usb_host_ehci_qh_t *shedFirstQh;           /*!< First async QH*/
312     usb_host_ehci_pipe_t *ehciPipeIndexBase;   /*!< Pipe buffer's start pointer*/
313     usb_host_ehci_pipe_t *ehciPipeList;        /*!< Idle pipe list pointer*/
314     usb_host_ehci_pipe_t *ehciRunningPipeList; /*!< Running pipe list pointer*/
315     osa_mutex_handle_t ehciMutex;              /*!< EHCI mutex*/
316     uint32_t mutexBuffer[(OSA_MUTEX_HANDLE_SIZE + 3) / 4];           /*!< The mutex buffer. */
317     osa_event_handle_t taskEventHandle;                              /*!< EHCI task event*/
318     uint32_t taskEventHandleBuffer[(OSA_EVENT_HANDLE_SIZE + 3) / 4]; /*!< EHCI task event handle buffer*/
319 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
320     uint64_t matchTick;
321 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
322     USBPHY_Type *registerPhyBase; /*!< The base address of the PHY register */
323 #endif
324 #if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U))
325     USBNC_Type *registerNcBase; /*!< The base address of the USBNC register */
326 #endif
327 
328 #endif
329     uint8_t controllerId;     /*!< EHCI controller ID*/
330     uint8_t deviceAttached;   /*!< Device attach/detach state, see #host_ehci_device_state_t */
331     uint8_t firstDeviceSpeed; /*!< The first device's speed, the controller's work speed*/
332     uint8_t ehciItdNumber;    /*!< Idle ITD number*/
333     uint8_t ehciSitdNumber;   /*!< Idle SITD number*/
334     uint8_t ehciQtdNumber;    /*!< Idle QTD number*/
335 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
336 #if ((defined(USB_HOST_CONFIG_LPM_L1)) && (USB_HOST_CONFIG_LPM_L1 > 0U))
337     uint8_t hirdValue;
338     uint8_t L1remoteWakeupEnable;
339 #endif
340     bus_ehci_suspend_request_state_t busSuspendStatus; /*!< Bus Suspend Status*/
341 #endif
342 } usb_host_ehci_instance_t;
343 
344 /*! @brief EHCI data structure */
345 typedef struct _usb_host_ehci_data
346 {
347 #if ((defined(USB_HOST_CONFIG_EHCI_MAX_QH)) && (USB_HOST_CONFIG_EHCI_MAX_QH > 0U))
348     usb_host_ehci_qh_t ehciQh[USB_HOST_CONFIG_EHCI_MAX_QH]; /*!< Idle QH list array*/
349 #endif
350 #if ((defined(USB_HOST_CONFIG_EHCI_MAX_QTD)) && (USB_HOST_CONFIG_EHCI_MAX_QTD > 0U))
351     usb_host_ehci_qtd_t ehciQtd[USB_HOST_CONFIG_EHCI_MAX_QTD]; /*!< Idle QTD list array*/
352 #endif
353 #if ((defined(USB_HOST_CONFIG_EHCI_MAX_ITD)) && (USB_HOST_CONFIG_EHCI_MAX_ITD > 0U))
354     usb_host_ehci_itd_t ehciItd[USB_HOST_CONFIG_EHCI_MAX_ITD]; /*!< Idle ITD list array*/
355     /* add additional 32bytes because the itd cannot cross over 4K boundary,
356      * If one ITD cross over 4K boundary, the code will move 32 bytes for ITD.
357      */
358     uint32_t reserved[8];
359 #endif
360 #if ((defined(USB_HOST_CONFIG_EHCI_MAX_SITD)) && (USB_HOST_CONFIG_EHCI_MAX_SITD > 0U))
361     usb_host_ehci_sitd_t ehciSitd[USB_HOST_CONFIG_EHCI_MAX_SITD]; /*!< Idle SITD list array*/
362 #endif
363 #if ((defined(USB_HOST_EHCI_ISO_NUMBER)) && (USB_HOST_EHCI_ISO_NUMBER > 0U))
364     usb_host_ehci_iso_t ehciIso[USB_HOST_EHCI_ISO_NUMBER]; /*!< Idle ISO list array*/
365 #endif
366 #if ((defined(USB_HOST_CONFIG_MAX_PIPES)) && (USB_HOST_CONFIG_MAX_PIPES > 0U))
367     usb_host_ehci_pipe_t ehciPipe[USB_HOST_CONFIG_MAX_PIPES]; /*!< Idle pipe list array*/
368 #endif
369 } usb_host_ehci_data_t;
370 
371 /*******************************************************************************
372  * API
373  ******************************************************************************/
374 
375 #ifdef __cplusplus
376 extern "C" {
377 #endif
378 /*!
379  * @name USB host EHCI APIs
380  * @{
381  */
382 
383 /*!
384  * @brief Creates the USB host EHCI instance.
385  *
386  * This function initializes the USB host EHCI controller driver.
387  *
388  * @param[in] controllerId      The controller ID of the USB IP. Please refer to the enumeration usb_controller_index_t.
389  * @param[in] upperLayerHandle  The host level handle.
390  * @param[out] controllerHandle return the controller instance handle.
391  *
392  * @retval kStatus_USB_Success              The host is initialized successfully.
393  * @retval kStatus_USB_AllocFail            Allocating memory failed.
394  * @retval kStatus_USB_Error                Host mutex create fail, KHCI/EHCI mutex or KHCI/EHCI event create fail.
395  *                                          Or, KHCI/EHCI IP initialize fail.
396  */
397 extern usb_status_t USB_HostEhciCreate(uint8_t controllerId,
398                                        usb_host_handle upperLayerHandle,
399                                        usb_host_controller_handle *controllerHandle);
400 
401 /*!
402  * @brief Destroys the USB host EHCI instance.
403  *
404  * This function de-initializes The USB host EHCI controller driver.
405  *
406  * @param[in] controllerHandle  The controller handle.
407  *
408  * @retval kStatus_USB_Success              The host is initialized successfully.
409  */
410 extern usb_status_t USB_HostEhciDestory(usb_host_controller_handle controllerHandle);
411 
412 /*!
413  * @brief Opens the USB host pipe.
414  *
415  * This function opens a pipe according to the pipe_init_ptr parameter.
416  *
417  * @param[in] controllerHandle The controller handle.
418  * @param[out] pipeHandle      The pipe handle pointer, it is used to return the pipe handle.
419  * @param[in] pipeInit         It is used to initialize the pipe.
420  *
421  * @retval kStatus_USB_Success              The host is initialized successfully.
422  * @retval kStatus_USB_Error                There is no idle pipe.
423  *                                          Or, there is no idle QH for EHCI.
424  *                                          Or, bandwidth allocate fail for EHCI.
425  */
426 extern usb_status_t USB_HostEhciOpenPipe(usb_host_controller_handle controllerHandle,
427                                          usb_host_pipe_handle *pipeHandle,
428                                          usb_host_pipe_init_t *pipeInit);
429 
430 /*!
431  * @brief Closes the USB host pipe.
432  *
433  * This function closes a pipe and releases related resources.
434  *
435  * @param[in] controllerHandle The controller handle.
436  * @param[in] pipeHandle       The closing pipe handle.
437  *
438  * @retval kStatus_USB_Success              The host is initialized successfully.
439  */
440 extern usb_status_t USB_HostEhciClosePipe(usb_host_controller_handle controllerHandle, usb_host_pipe_handle pipeHandle);
441 
442 /*!
443  * @brief Sends data to the pipe.
444  *
445  * This function requests to send the transfer to the specified pipe.
446  *
447  * @param[in] controllerHandle The controller handle.
448  * @param[in] pipeHandle       The sending pipe handle.
449  * @param[in] transfer          The transfer information.
450  *
451  * @retval kStatus_USB_Success              Sent successfully.
452  * @retval kStatus_USB_LackSwapBuffer       There is no swap buffer for KHCI.
453  * @retval kStatus_USB_Error                There is no idle QTD/ITD/SITD for EHCI.
454  */
455 extern usb_status_t USB_HostEhciWritePipe(usb_host_controller_handle controllerHandle,
456                                           usb_host_pipe_handle pipeHandle,
457                                           usb_host_transfer_t *transfer);
458 
459 /*!
460  * @brief Receives data from the pipe.
461  *
462  * This function requests to receive the transfer from the specified pipe.
463  *
464  * @param[in] controllerHandle The controller handle.
465  * @param[in] pipeHandle       The receiving pipe handle.
466  * @param[in] transfer         The transfer information.
467 
468  * @retval kStatus_USB_Success              Send successfully.
469  * @retval kStatus_USB_LackSwapBuffer       There is no swap buffer for KHCI.
470  * @retval kStatus_USB_Error                There is no idle QTD/ITD/SITD for EHCI.
471  */
472 extern usb_status_t USB_HostEhciReadpipe(usb_host_controller_handle controllerHandle,
473                                          usb_host_pipe_handle pipeHandle,
474                                          usb_host_transfer_t *transfer);
475 
476 /*!
477  * @brief Controls the EHCI.
478  *
479  * This function controls the EHCI.
480  *
481  * @param[in] controllerHandle The controller handle.
482  * @param[in] ioctlEvent       See enumeration host_bus_control_t.
483  * @param[in] ioctlParam       The control parameter.
484  *
485  * @retval kStatus_USB_Success              Cancel successfully.
486  * @retval kStatus_USB_InvalidHandle        The controllerHandle is a NULL pointer.
487  */
488 extern usb_status_t USB_HostEhciIoctl(usb_host_controller_handle controllerHandle,
489                                       uint32_t ioctlEvent,
490                                       void *ioctlParam);
491 
492 /*! @}*/
493 
494 #ifdef __cplusplus
495 }
496 #endif
497 
498 /*! @}*/
499 
500 #endif /* _USB_HOST_CONTROLLER_EHCI_H_ */
501