1 /*
2  * Copyright (c) 2015, Freescale Semiconductor, Inc.
3  * Copyright 2016 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #ifndef _USB_HOST_HUB_H_
10 #define _USB_HOST_HUB_H_
11 
12 #if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
13 
14 /*******************************************************************************
15  * Definitions
16  ******************************************************************************/
17 
18 /*! @brief USB host HUB maximum port count */
19 #define USB_HOST_HUB_MAX_PORT (7U)
20 
21 /*! @brief HUB class code */
22 #define USB_HOST_HUB_CLASS_CODE (9U)
23 /*! @brief HUB sub-class code */
24 #define USB_HOST_HUB_SUBCLASS_CODE_NONE (0U)
25 
26 /* HUB and PORT status according to Table 11-17 in chapter 11.*/
27 /*! @brief Local Power Status Change: This field indicates that a change has occurred in the HUB's Local Power Source */
28 #define C_HUB_LOCAL_POWER (0U)
29 /*! @brief Over-Current Change: This field indicates if a change has occurred in the Over-Current field*/
30 #define C_HUB_OVER_CURRENT (1U)
31 /*! @brief Current Connect Status: This field reflects whether or not a device is currently connected to this port*/
32 #define PORT_CONNECTION (0U)
33 /*! @brief Port Enabled/Disabled: Ports can be enabled by the USB System Software only. Ports
34 can be disabled by either a fault condition (disconnect event or other fault condition) or by the USB System
35 Software*/
36 #define PORT_ENABLE (1U)
37 /*! @brief Suspend: This field indicates whether or not the device on this port is suspended */
38 #define PORT_SUSPEND (2U)
39 /*! @brief this field indicate that the current drain on the port exceeds the specified maximum. */
40 #define PORT_OVER_CURRENT (3U)
41 /*! @brief This field is set when the host wishes to reset the attached device */
42 #define PORT_RESET (4U)
43 /*! @brief This field reflects a port's logical, power control state */
44 #define PORT_POWER (8U)
45 /*! @brief Low- Speed Device Attached: This is relevant only if a device is attached */
46 #define PORT_LOW_SPEED (9U)
47 /*! @brief High-speed Device Attached: This is relevant only if a device is attached */
48 #define PORT_HIGH_SPEED (10U)
49 /*! @brief Connect Status Change: Indicates a change has occurred in the port's Current Connect Status */
50 #define C_PORT_CONNECTION (16U)
51 /*! @brief Port Enable/Disable Change: This field is set to one when a port is disabled because of a Port_Error
52  * condition */
53 #define C_PORT_ENABLE (17U)
54 /*! @brief Suspend Change: This field indicates a change in the host-visible suspend state of the attached device */
55 #define C_PORT_SUSPEND (18U)
56 /*! @brief Over-Current Indicator Change: This field applies only to HUBs that report over-current conditions on a
57  * per-port basis */
58 #define C_PORT_OVER_CURRENT (19U)
59 /*! @brief Reset Change: This field is set when reset processing on this port is complete */
60 #define C_PORT_RESET (20U)
61 
62 /*! @brief Get HUB think time value */
63 #define USB_HOST_HUB_DESCRIPTOR_CHARACTERISTICS_THINK_TIME_MASK (0x60U)
64 /*! @brief Get HUB think time value */
65 #define USB_HOST_HUB_DESCRIPTOR_CHARACTERISTICS_THINK_TIME_SHIFT (5U)
66 
67 /*******************************************************************************
68  * Prototypes
69  ******************************************************************************/
70 
71 /*! @brief HUB descriptor structure */
72 typedef struct _usb_host_hub_descriptor
73 {
74     uint8_t blength;                /*!< Number of bytes in this descriptor*/
75     uint8_t bdescriptortype;        /*!< Descriptor Type*/
76     uint8_t bnrports;               /*!< Number of downstream facing ports that this HUB supports*/
77     uint8_t whubcharacteristics[2]; /*!< HUB characteristics please reference to Table 11-13 in usb2.0 specification*/
78     uint8_t bpwron2pwrgood;   /*!< Time (in 2 ms intervals) from the time the power-on sequence begins on a port until
79                                  power is good on that port.*/
80     uint8_t bhubcontrcurrent; /*!< Maximum current requirements of the HUB Controller electronics in mA*/
81     uint8_t deviceremovable;  /*!< Indicates if a port has a removable device attached*/
82 } usb_host_hub_descriptor_t;
83 
84 /*! @brief HUB port instance structure */
85 typedef struct _usb_host_hub_port_instance
86 {
87     usb_device_handle deviceHandle; /*!< Device handle*/
88     uint8_t portStatus;             /*!< Port running status*/
89     uint8_t resetCount;             /*!< Port reset time*/
90     uint8_t speed;                  /*!< Port's device speed*/
91 } usb_host_hub_port_instance_t;
92 
93 /*! @brief HUB instance structure */
94 typedef struct _usb_host_hub_instance
95 {
96     struct _usb_host_hub_instance *next;       /*!< Next HUB instance*/
97     usb_host_handle hostHandle;                /*!< Host handle*/
98     usb_device_handle deviceHandle;            /*!< Device handle*/
99     usb_host_interface_handle interfaceHandle; /*!< Interface handle*/
100     usb_host_pipe_handle controlPipe;          /*!< Control pipe handle*/
101     usb_host_pipe_handle interruptPipe;        /*!< HUB interrupt in pipe handle*/
102     usb_host_hub_port_instance_t *portList;    /*!< HUB's port instance list*/
103     usb_host_transfer_t *controlTransfer;      /*!< Control transfer in progress*/
104     transfer_callback_t inCallbackFn;          /*!< Interrupt in callback*/
105     void *inCallbackParam;                     /*!< Interrupt in callback parameter*/
106     transfer_callback_t controlCallbackFn;     /*!< Control callback*/
107     void *controlCallbackParam;                /*!< Control callback parameter*/
108                                                /*   HUB property */
109     uint16_t totalThinktime;                   /*!< HUB total think time*/
110     uint8_t hubLevel;                          /*!< HUB level, the root HUB's level is 1*/
111 
112     /* HUB application parameter */
113 #if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
114     uint8_t *hubDescriptor;    /*!< HUB descriptor buffer*/
115     uint8_t *hubBitmapBuffer;  /*!< HUB receiving bitmap data buffer*/
116     uint8_t *hubStatusBuffer;  /*!< HUB status buffer*/
117     uint8_t *portStatusBuffer; /*!< Port status buffer*/
118 #else
119     uint8_t hubDescriptor[7 + (USB_HOST_HUB_MAX_PORT >> 3) + 1]; /*!< HUB descriptor buffer*/
120     uint8_t hubBitmapBuffer[(USB_HOST_HUB_MAX_PORT >> 3) + 1];   /*!< HUB receiving bitmap data buffer*/
121     uint8_t hubStatusBuffer[4];                                  /*!< HUB status buffer*/
122     uint8_t portStatusBuffer[4];                                 /*!< Port status buffer*/
123 #endif
124     uint8_t hubStatus;   /*!< HUB instance running status*/
125     uint8_t portCount;   /*!< HUB port count*/
126     uint8_t portIndex;   /*!< Record the index when processing ports in turn*/
127     uint8_t portProcess; /*!< The port that is processing*/
128     uint8_t primeStatus; /*!< Data prime transfer status*/
129     uint8_t invalid;     /*!< 0/1, when invalid, cannot send transfer to the class*/
130 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
131     uint8_t supportRemoteWakeup; /*!< The HUB supports remote wakeup or not*/
132     uint8_t controlRetry;        /*!< Retry count for set remote wakeup feature*/
133 #endif
134 } usb_host_hub_instance_t;
135 
136 /*******************************************************************************
137  * Variables
138  ******************************************************************************/
139 
140 /*******************************************************************************
141  * Code
142  ******************************************************************************/
143 
144 #ifdef __cplusplus
145 extern "C" {
146 #endif
147 
148 /*!
149  * @brief Initializes the HUB instance.
150  *
151  * This function allocates the resource for HUB instance.
152  *
153  * @param deviceHandle  The device handle.
154  * @param classHandle   Return class handle.
155  *
156  * @retval kStatus_USB_Success        The device is initialized successfully.
157  * @retval kStatus_USB_AllocFail      Allocate memory fail.
158  */
159 extern usb_status_t USB_HostHubInit(usb_device_handle deviceHandle, usb_host_class_handle *classHandle);
160 
161 /*!
162  * @brief Sets interface.
163  *
164  * This function binds the interfaces with the HUB instance.
165  *
166  * @param classHandle      The class handle.
167  * @param interfaceHandle  The interface handle.
168  * @param alternateSetting The alternate setting value.
169  * @param callbackFn       This callback is called after this function completes.
170  * @param callbackParam    The first parameter in the callback function.
171  *
172  * @retval kStatus_USB_Success        The device is initialized successfully.
173  * @retval kStatus_USB_InvalidHandle  The classHandle is NULL pointer.
174  * @retval kStatus_USB_Busy           There is no idle transfer.
175  * @retval kStatus_USB_Error          Open pipe fail. See the USB_HostOpenPipe.
176  *                                    Or send transfer fail. See the USB_HostSendSetup,
177  */
178 extern usb_status_t USB_HostHubSetInterface(usb_host_class_handle classHandle,
179                                             usb_host_interface_handle interfaceHandle,
180                                             uint8_t alternateSetting,
181                                             transfer_callback_t callbackFn,
182                                             void *callbackParam);
183 
184 /*!
185  * @brief Deinitializes the HUB instance.
186  *
187  * This function releases the resource for HUB instance.
188  *
189  * @param deviceHandle   The device handle.
190  * @param classHandle    The class handle.
191  *
192  * @retval kStatus_USB_Success        The device is deinitialized successfully.
193  */
194 extern usb_status_t USB_HostHubDeinit(usb_device_handle deviceHandle, usb_host_class_handle classHandle);
195 
196 /*!
197  * @brief Receives data.
198  *
199  * This function implements the HUB receiving data.
200  *
201  * @param classHandle   The class handle.
202  * @param buffer        The buffer pointer.
203  * @param bufferLength  The buffer length.
204  * @param callbackFn    This callback is called after this function completes.
205  * @param callbackParam The first parameter in the callback function.
206  *
207  * @retval kStatus_USB_Success        Receive request successfully.
208  * @retval kStatus_USB_InvalidHandle  The classHandle is NULL pointer.
209  * @retval kStatus_USB_Busy           There is no idle transfer.
210  * @retval kStatus_USB_Error          Pipe is not initialized.
211  *                                    Or, send transfer fail. See the USB_HostRecv.
212  */
213 extern usb_status_t USB_HostHubInterruptRecv(usb_host_class_handle classHandle,
214                                              uint8_t *buffer,
215                                              uint16_t bufferLength,
216                                              transfer_callback_t callbackFn,
217                                              void *callbackParam);
218 
219 /*!
220  * @brief Port reset setup.
221  *
222  * This function sends the HUB port reset transfer.
223  *
224  * @param classHandle   The class handle.
225  * @param portNumber    Port number.
226  *
227  * @retval kStatus_USB_Success        Send successfully.
228  * @retval kStatus_USB_InvalidHandle  The classHandle is NULL pointer.
229  * @retval kStatus_USB_Busy           There is no idle transfer.
230  * @retval kStatus_USB_Error          Pipe is not initialized.
231  *                                    Or, send transfer fail. See the USB_HostSendSetup.
232  */
233 extern usb_status_t USB_HostHubSendPortReset(usb_host_class_handle classHandle, uint8_t portNumber);
234 
235 /*!
236  * @brief HUB get descriptor.
237  *
238  * This function implements get HUB descriptor-specific request.
239  *
240  * @param classHandle   The class handle.
241  * @param buffer        The buffer pointer.
242  * @param bufferLength  The buffer length.
243  * @param callbackFn    This callback is called after this function completes.
244  * @param callbackParam The first parameter in the callback function.
245  *
246  * @retval kStatus_USB_Success        Send successfully.
247  * @retval kStatus_USB_InvalidHandle  The classHandle is NULL pointer.
248  * @retval kStatus_USB_Busy           There is no idle transfer.
249  * @retval kStatus_USB_Error          Pipe is not initialized.
250  *                                    Or, send transfer fail. See the USB_HostSendSetup.
251  */
252 extern usb_status_t USB_HostHubGetDescriptor(usb_host_class_handle classHandle,
253                                              uint8_t *buffer,
254                                              uint16_t bufferLength,
255                                              transfer_callback_t callbackFn,
256                                              void *callbackParam);
257 
258 /*!
259  * @brief HUB clear feature.
260  *
261  * This function implements clear HUB feature specific request.
262  *
263  * @param classHandle   the class handle.
264  * @param buffer        the buffer pointer.
265  * @param bufferLength  the buffer length.
266  * @param callbackFn    this callback is called after this function completes.
267  * @param callbackParam the first parameter in the callback function.
268  *
269  * @retval kStatus_USB_Success        send successfully.
270  * @retval kStatus_USB_InvalidHandle  The classHandle is NULL pointer.
271  * @retval kStatus_USB_Busy           There is no idle transfer.
272  * @retval kStatus_USB_Error          pipe is not initialized.
273  *                                    Or, send transfer fail, please reference to USB_HostSendSetup.
274  */
275 extern usb_status_t USB_HostHubClearFeature(usb_host_class_handle classHandle,
276                                             uint8_t feature,
277                                             transfer_callback_t callbackFn,
278                                             void *callbackParam);
279 
280 /*!
281  * @brief HUB get status.
282  *
283  * This function implements the get HUB status-specific request.
284  *
285  * @param classHandle   The class handle.
286  * @param buffer        The buffer pointer.
287  * @param bufferLength  The buffer length.
288  * @param callbackFn    This callback is called after this function completes.
289  * @param callbackParam The first parameter in the callback function.
290  *
291  * @retval kStatus_USB_Success        Send successfully.
292  * @retval kStatus_USB_InvalidHandle  The classHandle is NULL pointer.
293  * @retval kStatus_USB_Busy           There is no idle transfer.
294  * @retval kStatus_USB_Error          Pipe is not initialized.
295  *                                    Or, send transfer fail. See the USB_HostSendSetup.
296  */
297 extern usb_status_t USB_HostHubGetStatus(usb_host_class_handle classHandle,
298                                          uint8_t *buffer,
299                                          uint16_t bufferLength,
300                                          transfer_callback_t callbackFn,
301                                          void *callbackParam);
302 
303 /*!
304  * @brief HUB set feature.
305  *
306  * This function implements the set HUB feature-specific request.
307  *
308  * @param classHandle   The class handle.
309  * @param buffer        The buffer pointer.
310  * @param bufferLength  The buffer length.
311  * @param callbackFn    This callback is called after this function completes.
312  * @param callbackParam The first parameter in the callback function.
313  *
314  * @retval kStatus_USB_Success        Send successfully.
315  * @retval kStatus_USB_InvalidHandle  The classHandle is NULL pointer.
316  * @retval kStatus_USB_Busy           There is no idle transfer.
317  * @retval kStatus_USB_Error          Pipe is not initialized.
318  *                                    Or, send transfer fail. See the USB_HostSendSetup.
319  */
320 extern usb_status_t USB_HostHubSetPortFeature(usb_host_class_handle classHandle,
321                                               uint8_t portNumber,
322                                               uint8_t feature,
323                                               transfer_callback_t callbackFn,
324                                               void *callbackParam);
325 
326 /*!
327  * @brief HUB clear port feature.
328  *
329  * This function implements the clear HUB port feature-specific request.
330  *
331  * @param classHandle   The class handle.
332  * @param buffer        The buffer pointer.
333  * @param bufferLength  The buffer length.
334  * @param callbackFn    This callback is called after this function completes.
335  * @param callbackParam The first parameter in the callback function.
336  *
337  * @retval kStatus_USB_Success        Send successfully.
338  * @retval kStatus_USB_InvalidHandle  The classHandle is NULL pointer.
339  * @retval kStatus_USB_Busy           There is no idle transfer.
340  * @retval kStatus_USB_Error          Pipe is not initialized.
341  *                                    Or, send transfer fail. See the USB_HostSendSetup.
342  */
343 extern usb_status_t USB_HostHubClearPortFeature(usb_host_class_handle classHandle,
344                                                 uint8_t portNumber,
345                                                 uint8_t feature,
346                                                 transfer_callback_t callbackFn,
347                                                 void *callbackParam);
348 
349 /*!
350  * @brief HUB port get status.
351  *
352  * This function implements the get HUB port status-specific request.
353  *
354  * @param classHandle   The class handle.
355  * @param buffer        The buffer pointer.
356  * @param bufferLength  The buffer length.
357  * @param callbackFn    This callback is called after this function completes.
358  * @param callbackParam The first parameter in the callback function.
359  *
360  * @retval kStatus_USB_Success        Send successfully.
361  * @retval kStatus_USB_InvalidHandle  The classHandle is NULL pointer.
362  * @retval kStatus_USB_Busy           There is no idle transfer.
363  * @retval kStatus_USB_Error          Pipe is not initialized.
364  *                                    Or, send transfer fail. See the USB_HostSendSetup.
365  */
366 extern usb_status_t USB_HostHubGetPortStatus(usb_host_class_handle classHandle,
367                                              uint8_t portNumber,
368                                              uint8_t *buffer,
369                                              uint16_t bufferLength,
370                                              transfer_callback_t callbackFn,
371                                              void *callbackParam);
372 
373 #ifdef __cplusplus
374 }
375 #endif
376 
377 #endif /* USB_HOST_CONFIG_HUB */
378 
379 #endif /* _USB_HSOT_HUB_H_ */
380