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