1 /*
2 * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
3 * Copyright 2016,2019 - 2020 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "usb_host_config.h"
10 #if ((defined USB_HOST_CONFIG_AUDIO) && (USB_HOST_CONFIG_AUDIO))
11 #include "usb_host.h"
12 #include "usb_host_audio.h"
13
14 /*******************************************************************************
15 * Definitions
16 ******************************************************************************/
17 typedef union usb_audio_ctrl_common_fu_desc_t
18 {
19 usb_audio_ctrl_fu_desc_t fuDesc10;
20 usb_audio_2_0_ctrl_fu_desc_t fuDesc20;
21 } usb_audio_ctrl_common_fu_desc;
22 /*******************************************************************************
23 * Variables
24 ******************************************************************************/
25
26 /* usb audio feature uint command request declaration */
27 static usb_audio_request_t s_usbAudioFuRequests[NUMBER_OF_FEATURE_COMMANDS] = {
28 /* Mute command request */
29 {AUDIO_FU_MUTE_MASK, ITF_REQUEST, CUR_REQUEST, AUDIO_FU_MUTE, 1U},
30 /* Volume command request */
31 {AUDIO_FU_VOLUME_MASK, ITF_REQUEST, CUR_REQUEST, AUDIO_FU_VOLUME, 2U},
32 {AUDIO_FU_VOLUME_MASK, ITF_REQUEST, MIN_REQUEST, AUDIO_FU_VOLUME, 2U},
33 {AUDIO_FU_VOLUME_MASK, ITF_REQUEST, MAX_REQUEST, AUDIO_FU_VOLUME, 2U},
34 {AUDIO_FU_VOLUME_MASK, ITF_REQUEST, RES_REQUEST, AUDIO_FU_VOLUME, 2U},
35 };
36 /* USB audio endpoint command declaration */
37 static usb_audio_request_t s_usbAudioEpRequests[NUMBER_OF_ENDPOINT_COMMANDS] = {
38 /* USB audio Pitch command request */
39 {AUDIO_PITCH_MASK, EP_REQUEST, CUR_REQUEST, AUDIO_PITCH_CONTROL, 1U},
40
41 /* USB audio Sampling frequency command request */
42 {AUDIO_SAMPLING_FREQ_MASK, EP_REQUEST, CUR_REQUEST, AUDIO_SAMPLING_FREQ_CONTROL, 3U},
43 {AUDIO_SAMPLING_FREQ_MASK, EP_REQUEST, MIN_REQUEST, AUDIO_SAMPLING_FREQ_CONTROL, 3U},
44 {AUDIO_SAMPLING_FREQ_MASK, EP_REQUEST, MAX_REQUEST, AUDIO_SAMPLING_FREQ_CONTROL, 3U},
45 {AUDIO_SAMPLING_FREQ_MASK, EP_REQUEST, RES_REQUEST, AUDIO_SAMPLING_FREQ_CONTROL, 3U},
46 };
47
48 /*******************************************************************************
49 * Code
50 ******************************************************************************/
51 /*!
52 * @brief initialize the audio instance.
53 *
54 * This function allocate the resource for audio instance.
55 *
56 * @param deviceHandle The device handle.
57 * @param classHandlePtr return class handle.
58 *
59 * @retval kStatus_USB_Success The device is initialized successfully.
60 * @retval kStatus_USB_AllocFail Allocate memory fail.
61 */
USB_HostAudioInit(usb_device_handle deviceHandle,usb_host_class_handle * classHandlePtr)62 usb_status_t USB_HostAudioInit(usb_device_handle deviceHandle, usb_host_class_handle *classHandlePtr)
63 {
64 audio_instance_t *audioPtr = (audio_instance_t *)OSA_MemoryAllocate(sizeof(audio_instance_t));
65 uint32_t info_value = 0U;
66 uint32_t *temp;
67
68 if (audioPtr == NULL)
69 {
70 return kStatus_USB_AllocFail;
71 }
72
73 audioPtr->deviceHandle = deviceHandle;
74 audioPtr->controlIntfHandle = NULL;
75 audioPtr->streamIntfHandle = NULL;
76 (void)USB_HostHelperGetPeripheralInformation(deviceHandle, (uint32_t)kUSB_HostGetHostHandle, &info_value);
77 temp = (uint32_t *)info_value;
78 audioPtr->hostHandle = (usb_host_handle)temp;
79 (void)USB_HostHelperGetPeripheralInformation(deviceHandle, (uint32_t)kUSB_HostGetDeviceControlPipe, &info_value);
80 temp = (uint32_t *)info_value;
81 audioPtr->controlPipe = (usb_host_pipe_handle)temp;
82
83 *classHandlePtr = audioPtr;
84 return kStatus_USB_Success;
85 }
86
87 /*!
88 * @brief de-initialize the audio instance.
89 *
90 * This function release the resource for audio instance.
91 *
92 * @param deviceHandle the device handle.
93 * @param classHandle the class handle.
94 *
95 * @retval kStatus_USB_Success The device is de-initialized successfully.
96 */
USB_HostAudioDeinit(usb_device_handle deviceHandle,usb_host_class_handle classHandle)97 usb_status_t USB_HostAudioDeinit(usb_device_handle deviceHandle, usb_host_class_handle classHandle)
98 {
99 usb_status_t status = kStatus_USB_Success;
100 audio_instance_t *audioPtr = (audio_instance_t *)classHandle;
101
102 if (deviceHandle == NULL)
103 {
104 return kStatus_USB_InvalidHandle;
105 }
106
107 if (classHandle != NULL)
108 {
109 if (audioPtr->isoInPipe != NULL)
110 {
111 status = USB_HostCancelTransfer(audioPtr->hostHandle, audioPtr->isoInPipe, NULL);
112 if (status != kStatus_USB_Success)
113 {
114 #ifdef HOST_ECHO
115 usb_echo("error when cancel pipe\r\n");
116 #endif
117 }
118 status = USB_HostClosePipe(audioPtr->hostHandle, audioPtr->isoInPipe);
119
120 if (status != kStatus_USB_Success)
121 {
122 #ifdef HOST_ECHO
123 usb_echo("error when close pipe\r\n");
124 #endif
125 }
126 audioPtr->isoInPipe = NULL;
127 }
128 if (audioPtr->isoOutPipe != NULL)
129 {
130 status = USB_HostCancelTransfer(audioPtr->hostHandle, audioPtr->isoOutPipe, NULL);
131 if (status != kStatus_USB_Success)
132 {
133 #ifdef HOST_ECHO
134 usb_echo("error when cancel pipe\r\n");
135 #endif
136 }
137 status = USB_HostClosePipe(audioPtr->hostHandle, audioPtr->isoOutPipe);
138
139 if (status != kStatus_USB_Success)
140 {
141 #ifdef HOST_ECHO
142 usb_echo("error when close pipe\r\n");
143 #endif
144 }
145 audioPtr->isoOutPipe = NULL;
146 }
147 (void)USB_HostCloseDeviceInterface(deviceHandle, audioPtr->streamIntfHandle);
148
149 if ((audioPtr->controlPipe != NULL) && (audioPtr->controlTransfer != NULL))
150 {
151 status = USB_HostCancelTransfer(audioPtr->hostHandle, audioPtr->controlPipe, audioPtr->controlTransfer);
152 }
153 (void)USB_HostCloseDeviceInterface(deviceHandle, audioPtr->controlIntfHandle);
154 OSA_MemoryFree(audioPtr);
155 }
156 else
157 {
158 (void)USB_HostCloseDeviceInterface(deviceHandle, NULL);
159 }
160
161 return status;
162 }
163
164 /*!
165 * @brief audiostream iso in pipe transfer callback.
166 *
167 * @param param callback parameter.
168 * @param transfer callback transfer.
169 * @param status transfer status.
170 */
_USB_HostAudioStreamIsoInPipeCallback(void * param,usb_host_transfer_t * transfer,usb_status_t status)171 static void _USB_HostAudioStreamIsoInPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
172 {
173 audio_instance_t *audioPtr = (audio_instance_t *)param;
174
175 if (audioPtr->inCallbackFn != NULL)
176 {
177 /* callback function is initialized in USB_HostAudioStreamRecv */
178 audioPtr->inCallbackFn(audioPtr->inCallbackParam, transfer->transferBuffer, transfer->transferSofar, status);
179 }
180 (void)USB_HostFreeTransfer(audioPtr->hostHandle, transfer);
181 }
182
183 /*!
184 * @brief audiostream iso out pipe transfer callback.
185 *
186 * @param param callback parameter.
187 * @param transfer callback transfer.
188 * @param status transfer status.
189 */
_USB_HostAudioStreamIsoOutPipeCallback(void * param,usb_host_transfer_t * transfer,usb_status_t status)190 static void _USB_HostAudioStreamIsoOutPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
191 {
192 audio_instance_t *audioPtr = (audio_instance_t *)param;
193
194 if (audioPtr->outCallbackFn != NULL)
195 {
196 /* callback function is initialized in USB_HostAudioStreamSend */
197 audioPtr->outCallbackFn(audioPtr->outCallbackParam, transfer->transferBuffer, transfer->transferSofar, status);
198 }
199 (void)USB_HostFreeTransfer(audioPtr->hostHandle, transfer);
200 }
201
202 /*!
203 * @brief audiocontrol pipe transfer callback.
204 *
205 * @param param callback parameter.
206 * @param transfer callback transfer.
207 * @param status transfer status.
208 */
_USB_HostAudioControlCallback(void * param,usb_host_transfer_t * transfer,usb_status_t status)209 static void _USB_HostAudioControlCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
210 {
211 audio_instance_t *audioPtr = (audio_instance_t *)param;
212
213 audioPtr->controlTransfer = NULL;
214 if (audioPtr->controlCallbackFn != NULL)
215 {
216 /* callback to application, callback function is initialized in the _USB_HostAudioControl,
217 USB_HostAudioStreamSetInterface
218 or USB_HostAudioControlSetInterface, but is the same function */
219 audioPtr->controlCallbackFn(audioPtr->controlCallbackParam, transfer->transferBuffer, transfer->transferSofar,
220 status);
221 }
222 (void)USB_HostFreeTransfer(audioPtr->hostHandle, transfer);
223 audioPtr->isSetup = 0U;
224 }
225
226 /*!
227 * @brief hid send control transfer common code.
228 *
229 * @param classHandle the class handle.
230 * @param typeRequest setup packet request type.
231 * @param request setup packet request value.
232 * @param wvalue setup packet wvalue value.
233 * @param windex setup packet index value.
234 * @param wlength setup packet wlength value.
235 * @param data data buffer pointer will be transfer.
236 * @param callbackFn this callback is called after this function completes.
237 * @param callbackParam the first parameter in the callback function.
238 *
239 * @return An error code or kStatus_USB_Success.
240 */
_USB_HostAudioControl(usb_host_class_handle classHandle,uint8_t typeRequest,uint8_t request,uint16_t wvalue,uint16_t windex,uint16_t wlength,uint8_t * data,transfer_callback_t callbackFn,void * callbackParam)241 static usb_status_t _USB_HostAudioControl(usb_host_class_handle classHandle,
242 uint8_t typeRequest,
243 uint8_t request,
244 uint16_t wvalue,
245 uint16_t windex,
246 uint16_t wlength,
247 uint8_t *data,
248 transfer_callback_t callbackFn,
249 void *callbackParam)
250 {
251 audio_instance_t *audioPtr = (audio_instance_t *)classHandle;
252 usb_host_transfer_t *transfer;
253
254 if (classHandle == NULL)
255 {
256 return kStatus_USB_InvalidHandle;
257 }
258
259 if (USB_HostMallocTransfer(audioPtr->hostHandle, &transfer) != kStatus_USB_Success)
260 {
261 #ifdef HOST_ECHO
262 usb_echo("error to get transfer\r\n");
263 #endif
264 return kStatus_USB_Error;
265 }
266 audioPtr->controlCallbackFn = callbackFn;
267 audioPtr->controlCallbackParam = callbackParam;
268
269 transfer->transferBuffer = data;
270 transfer->transferLength = wlength;
271 transfer->callbackFn = _USB_HostAudioControlCallback;
272 transfer->callbackParam = audioPtr;
273 transfer->setupPacket->bmRequestType = typeRequest;
274 transfer->setupPacket->bRequest = request;
275 transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN(wvalue);
276 transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(windex);
277
278 transfer->setupPacket->wLength = USB_SHORT_TO_LITTLE_ENDIAN(wlength);
279 audioPtr->isSetup = 1;
280
281 if (USB_HostSendSetup(audioPtr->hostHandle, audioPtr->controlPipe, transfer) != kStatus_USB_Success)
282 {
283 #ifdef HOST_ECHO
284 usb_echo("failed for USB_HostSendSetup\r\n");
285 #endif
286 (void)USB_HostFreeTransfer(audioPtr->hostHandle, transfer);
287 return kStatus_USB_Error;
288 }
289 audioPtr->controlTransfer = transfer;
290
291 return kStatus_USB_Success;
292 }
293
_USB_HostAudioInitEndpoint(audio_instance_t * audioPtr,usb_descriptor_endpoint_t * ep_desc)294 static usb_status_t _USB_HostAudioInitEndpoint(audio_instance_t *audioPtr, usb_descriptor_endpoint_t *ep_desc)
295 {
296 usb_host_pipe_init_t pipe_init;
297 usb_status_t status;
298
299 pipe_init.devInstance = audioPtr->deviceHandle;
300 pipe_init.pipeType = USB_ENDPOINT_ISOCHRONOUS;
301 pipe_init.direction = ((ep_desc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
302 USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT);
303 pipe_init.endpointAddress = (ep_desc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK);
304 pipe_init.interval = ep_desc->bInterval;
305 pipe_init.maxPacketSize = (uint16_t)((USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(ep_desc->wMaxPacketSize) &
306 USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK));
307 pipe_init.numberPerUframe = (uint8_t)((USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(ep_desc->wMaxPacketSize) &
308 USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK));
309 pipe_init.nakCount = USB_HOST_CONFIG_MAX_NAK;
310
311 if (pipe_init.direction == USB_IN)
312 {
313 audioPtr->inPacketSize = pipe_init.maxPacketSize;
314 audioPtr->isoEpNum = pipe_init.endpointAddress;
315 status = USB_HostOpenPipe(audioPtr->hostHandle, &audioPtr->isoInPipe, &pipe_init);
316 }
317 else
318 {
319 audioPtr->outPacketSize = pipe_init.maxPacketSize;
320 audioPtr->isoEpNum = pipe_init.endpointAddress;
321 status = USB_HostOpenPipe(audioPtr->hostHandle, &audioPtr->isoOutPipe, &pipe_init);
322 }
323
324 return status;
325 }
326
327 /*!
328 * @brief audio open interface.
329 *
330 * @param audioPtr audio instance pointer.
331 *
332 * @return kStatus_USB_Success or error codes.
333 */
_USB_HostAudioOpenInterface(audio_instance_t * audioPtr)334 static usb_status_t _USB_HostAudioOpenInterface(audio_instance_t *audioPtr)
335 {
336 usb_status_t status;
337 uint8_t ep_index = 0U;
338 usb_descriptor_endpoint_t *ep_desc = NULL;
339 usb_host_interface_t *interface_ptr;
340
341 if (audioPtr->isoInPipe != NULL)
342 {
343 status = USB_HostClosePipe(audioPtr->hostHandle, audioPtr->isoInPipe);
344
345 if (status != kStatus_USB_Success)
346 {
347 #ifdef HOST_ECHO
348 usb_echo("error when close pipe\r\n");
349 #endif
350 }
351 audioPtr->isoInPipe = NULL;
352 }
353 if (audioPtr->isoOutPipe != NULL)
354 {
355 status = USB_HostClosePipe(audioPtr->hostHandle, audioPtr->isoOutPipe);
356
357 if (status != kStatus_USB_Success)
358 {
359 #ifdef HOST_ECHO
360 usb_echo("error when close pipe\r\n");
361 #endif
362 }
363 audioPtr->isoOutPipe = NULL;
364 }
365
366 /* open interface pipes */
367 interface_ptr = (usb_host_interface_t *)audioPtr->streamIntfHandle;
368 for (ep_index = 0U; ep_index < interface_ptr->epCount; ++ep_index)
369 {
370 ep_desc = interface_ptr->epList[ep_index].epDesc;
371 if (((ep_desc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
372 USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN) &&
373 ((ep_desc->bmAttributes & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK) == USB_ENDPOINT_ISOCHRONOUS))
374 {
375 status = _USB_HostAudioInitEndpoint(audioPtr, ep_desc);
376 if (status != kStatus_USB_Success)
377 {
378 #ifdef HOST_ECHO
379 usb_echo("usb_host_audio_stream_set_interface fail to open pipe\r\n");
380 #endif
381 return kStatus_USB_Error;
382 }
383 }
384 else if (((ep_desc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
385 USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_OUT) &&
386 ((ep_desc->bmAttributes & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK) == USB_ENDPOINT_ISOCHRONOUS))
387 {
388 status = _USB_HostAudioInitEndpoint(audioPtr, ep_desc);
389 if (status != kStatus_USB_Success)
390 {
391 #ifdef HOST_ECHO
392 usb_echo("usb_host_audio_stream_set_interface fail to open pipe\r\n");
393 #endif
394 return kStatus_USB_Error;
395 }
396 }
397 else
398 {
399 }
400 }
401
402 return kStatus_USB_Success;
403 }
404
405 /*!
406 * @brief audio set interface callback, open pipes.
407 *
408 * @param param callback parameter.
409 * @param transfer callback transfer.
410 * @param status transfer status.
411 */
_USB_HostAudioSetInterfaceCallback(void * param,usb_host_transfer_t * transfer,usb_status_t status)412 static void _USB_HostAudioSetInterfaceCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
413 {
414 audio_instance_t *audioPtr = (audio_instance_t *)param;
415
416 audioPtr->controlTransfer = NULL;
417 if (status == kStatus_USB_Success)
418 {
419 status = _USB_HostAudioOpenInterface(audioPtr);
420 }
421
422 if (audioPtr->controlCallbackFn != NULL)
423 {
424 /* callback to application, callback function is initialized in the _USB_HostAudioControl,
425 USB_HostAudioStreamSetInterface
426 or USB_HostAudioControlSetInterface, but is the same function */
427 audioPtr->controlCallbackFn(audioPtr->controlCallbackParam, NULL, 0U, status);
428 }
429 (void)USB_HostFreeTransfer(audioPtr->hostHandle, transfer);
430 }
431
432 /*!
433 * @brief set audioclass stream interface.
434 *
435 * This function bind the interface with the audio instance.
436 *
437 * @param classHandle The class handle.
438 * @param interfaceHandle The interface handle.
439 * @param alternateSetting The alternate setting value.
440 * @param callbackFn This callback is called after this function completes.
441 * @param callbackParam The first parameter in the callback function.
442 *
443 * @retval kStatus_USB_Success The device is initialized successfully.
444 * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
445 * @retval kStatus_USB_Busy There is no idle transfer.
446 * @retval kStatus_USB_Error send transfer fail, please reference to USB_HostSendSetup.
447 * @retval kStatus_USB_Busy callback return status, there is no idle pipe.
448 * @retval kStatus_USB_TransferStall callback return status, the transfer is stall by device.
449 * @retval kStatus_USB_Error callback return status, open pipe fail, please reference to USB_HostOpenPipe.
450 */
USB_HostAudioStreamSetInterface(usb_host_class_handle classHandle,usb_host_interface_handle interfaceHandle,uint8_t alternateSetting,transfer_callback_t callbackFn,void * callbackParam)451 usb_status_t USB_HostAudioStreamSetInterface(usb_host_class_handle classHandle,
452 usb_host_interface_handle interfaceHandle,
453 uint8_t alternateSetting,
454 transfer_callback_t callbackFn,
455 void *callbackParam)
456 {
457 usb_status_t status;
458 audio_instance_t *audioPtr = (audio_instance_t *)classHandle;
459 usb_host_interface_t *interface_ptr;
460 usb_host_transfer_t *transfer;
461 audio_descriptor_union_t ptr1;
462 uint32_t length = 0U, ep = 0U;
463 void *temp;
464 usb_descriptor_endpoint_t *endpointDesc;
465 if (classHandle == NULL)
466 {
467 return kStatus_USB_InvalidParameter;
468 }
469
470 audioPtr->streamIntfHandle = interfaceHandle;
471
472 status = USB_HostOpenDeviceInterface(audioPtr->deviceHandle, interfaceHandle);
473 if (status != kStatus_USB_Success)
474 {
475 return status;
476 }
477
478 if (audioPtr->isoInPipe != NULL)
479 {
480 status = USB_HostCancelTransfer(audioPtr->hostHandle, audioPtr->isoInPipe, NULL);
481
482 if (status != kStatus_USB_Success)
483 {
484 #ifdef HOST_ECHO
485 usb_echo("error when cancel pipe\r\n");
486 #endif
487 }
488 }
489
490 if (audioPtr->isoOutPipe != NULL)
491 {
492 status = USB_HostCancelTransfer(audioPtr->hostHandle, audioPtr->isoOutPipe, NULL);
493
494 if (status != kStatus_USB_Success)
495 {
496 #ifdef HOST_ECHO
497 usb_echo("error when cancel pipe\r\n");
498 #endif
499 }
500 }
501 /* open interface pipes */
502 interface_ptr = (usb_host_interface_t *)interfaceHandle;
503 ptr1.bufr = interface_ptr->interfaceExtension;
504
505 length = 0U;
506 while (length < interface_ptr->interfaceExtensionLength)
507 {
508 if ((ptr1.common->bDescriptorType == 0x04U) && (ptr1.interface->bAlternateSetting == alternateSetting))
509 {
510 interface_ptr->epCount = ptr1.interface->bNumEndpoints;
511 break;
512 }
513 ptr1.bufr += ptr1.common->bLength;
514 length += ptr1.common->bLength;
515 }
516 while (ep < interface_ptr->epCount)
517 {
518 if (ptr1.common->bDescriptorType == 0x24U)
519 {
520 temp = (void *)ptr1.bufr;
521 if (AUDIO_DEVICE_VERSION_01 == audioPtr->deviceAudioVersion)
522 {
523 if (ptr1.common->bData[0] == USB_AUDIO_DESC_SUBTYPE_AS_GENERAL)
524 {
525 audioPtr->asIntfDesc = temp;
526 }
527 else if (ptr1.common->bData[0] == USB_AUDIO_DESC_SUBTYPE_AS_FORMAT_TYPE)
528 {
529 audioPtr->formatTypeDesc = temp;
530 }
531 else
532 {
533 /*no action*/
534 }
535 }
536 else if (AUDIO_DEVICE_VERSION_02 == audioPtr->deviceAudioVersion)
537 {
538 if (ptr1.common->bData[0] == USB_AUDIO_DESC_SUBTYPE_AS_GENERAL_20)
539 {
540 audioPtr->asIntfDesc = temp;
541 }
542 else if (ptr1.common->bData[0] == USB_AUDIO_DESC_SUBTYPE_AS_FORMAT_TYPE_20)
543 {
544 audioPtr->formatTypeDesc = temp;
545 }
546 else
547 {
548 /*no action*/
549 }
550 }
551 else
552 {
553 /*no action*/
554 }
555 }
556 else
557 {
558 /*no action*/
559 }
560
561 if (ptr1.common->bDescriptorType == 0x05U)
562 {
563 uint32_t descLength = 0;
564 temp = (void *)ptr1.bufr;
565 /*Bits 5..4: Usage Type,
566 00 = Data endpoint
567 01 = Feedback endpoint
568 10 = Implicit feedback Data endpoit, usb Spec 9.6*/
569 endpointDesc = (usb_descriptor_endpoint_t *)temp;
570 if (0x00U == ((endpointDesc->bmAttributes >> 4U) & 0x3U))
571 {
572 interface_ptr->epList[ep].epDesc = (usb_descriptor_endpoint_t *)temp;
573 audioPtr->isoEndpDesc = (usb_descriptor_endpoint_t *)temp;
574 }
575 else if (0x01U == ((endpointDesc->bmAttributes >> 4U) & 0x3U))
576 {
577 /*feedback endpoint*/
578 }
579 else
580 {
581 /*TO DO*/
582 }
583
584 descLength = ptr1.common->bLength;
585 ptr1.bufr += ptr1.common->bLength;
586
587 if ((0x25U == ptr1.common->bDescriptorType))
588 {
589 interface_ptr->epList[ep].epExtension = ptr1.bufr;
590 interface_ptr->epList[ep].epExtensionLength = ptr1.common->bLength;
591 }
592 else
593 {
594 ptr1.bufr -= descLength;
595 }
596 ep++;
597 }
598 ptr1.bufr += ptr1.common->bLength;
599 }
600
601 if (alternateSetting == 0U)
602 {
603 if (callbackFn != NULL)
604 {
605 status = _USB_HostAudioOpenInterface(audioPtr);
606 callbackFn(callbackParam, NULL, 0U, kStatus_USB_Success);
607 }
608 }
609 else
610 {
611 if (USB_HostMallocTransfer(audioPtr->hostHandle, &transfer) != kStatus_USB_Success)
612 {
613 #ifdef HOST_ECHO
614 usb_echo("error to get transfer\r\n");
615 #endif
616 return kStatus_USB_Error;
617 }
618 audioPtr->controlCallbackFn = callbackFn;
619 audioPtr->controlCallbackParam = callbackParam;
620 /* initialize transfer */
621 transfer->callbackFn = _USB_HostAudioSetInterfaceCallback;
622 transfer->callbackParam = audioPtr;
623 transfer->setupPacket->bRequest = USB_REQUEST_STANDARD_SET_INTERFACE;
624 transfer->setupPacket->bmRequestType = USB_REQUEST_TYPE_RECIPIENT_INTERFACE;
625 transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(
626 ((usb_host_interface_t *)audioPtr->streamIntfHandle)->interfaceDesc->bInterfaceNumber);
627 transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN(alternateSetting);
628 transfer->setupPacket->wLength = 0;
629 transfer->transferBuffer = NULL;
630 transfer->transferLength = 0;
631 status = USB_HostSendSetup(audioPtr->hostHandle, audioPtr->controlPipe, transfer);
632
633 if (status == kStatus_USB_Success)
634 {
635 audioPtr->controlTransfer = transfer;
636 }
637 else
638 {
639 (void)USB_HostFreeTransfer(audioPtr->hostHandle, transfer);
640 }
641 }
642
643 return status;
644 }
645
646 /*!
647 * @brief set audioclass control interface.
648 *
649 * This function bind the interface with the audio instance.
650 *
651 * @param classHandle The class handle.
652 * @param interfaceHandle The interface handle.
653 * @param alternateSetting The alternate setting value.
654 * @param callbackFn This callback is called after this function completes.
655 * @param callbackParam The first parameter in the callback function.
656 *
657 * @retval kStatus_USB_Success The device is initialized successfully.
658 * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
659 * @retval kStatus_USB_Busy There is no idle transfer.
660 * @retval kStatus_USB_Error send transfer fail, please reference to USB_HostSendSetup.
661 * @retval kStatus_USB_Busy callback return status, there is no idle pipe.
662 * @retval kStatus_USB_TransferStall callback return status, the transfer is stall by device.
663 * @retval kStatus_USB_Error callback return status, open pipe fail, please reference to USB_HostOpenPipe.
664 */
USB_HostAudioControlSetInterface(usb_host_class_handle classHandle,usb_host_interface_handle interfaceHandle,uint8_t alternateSetting,transfer_callback_t callbackFn,void * callbackParam)665 usb_status_t USB_HostAudioControlSetInterface(usb_host_class_handle classHandle,
666 usb_host_interface_handle interfaceHandle,
667 uint8_t alternateSetting,
668 transfer_callback_t callbackFn,
669 void *callbackParam)
670 {
671 usb_status_t status;
672 audio_instance_t *audioPtr = (audio_instance_t *)classHandle;
673 usb_host_interface_t *interface_ptr;
674 usb_host_transfer_t *transfer;
675 audio_descriptor_union_t ptr1;
676 void *temp;
677 void *header;
678 usb_audio_ctrl_common_header_desc_t *commonHeader;
679 uint32_t length = 0U;
680
681 if (classHandle == NULL)
682 {
683 return kStatus_USB_InvalidParameter;
684 }
685 audioPtr->controlIntfHandle = interfaceHandle;
686 interface_ptr = (usb_host_interface_t *)interfaceHandle;
687
688 status = USB_HostOpenDeviceInterface(audioPtr->deviceHandle, interfaceHandle);
689 if (status != kStatus_USB_Success)
690 {
691 return status;
692 }
693 ptr1.bufr = interface_ptr->interfaceExtension;
694
695 length = 0U;
696
697 while (length < interface_ptr->interfaceExtensionLength)
698 {
699 if (((interface_ptr->interfaceDesc->bDescriptorType == 0x04U) &&
700 (interface_ptr->interfaceDesc->bAlternateSetting == alternateSetting)) ||
701 ((ptr1.common->bDescriptorType == 0x04U) && (ptr1.interface->bAlternateSetting == alternateSetting)))
702 {
703 break;
704 }
705
706 ptr1.bufr += ptr1.common->bLength;
707 length += ptr1.common->bLength;
708 }
709 while (length < interface_ptr->interfaceExtensionLength)
710 {
711 if (ptr1.common->bDescriptorType == 0x24U)
712 {
713 temp = (void *)ptr1.bufr;
714 if (ptr1.common->bData[0] == USB_AUDIO_DESC_SUBTYPE_CS_HEADER)
715 {
716 audioPtr->headerDesc = (void *)temp;
717 commonHeader = (usb_audio_ctrl_common_header_desc_t *)temp;
718 header = (void *)&commonHeader->bcdcdc;
719 audioPtr->deviceAudioVersion = USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(((uint8_t *)header));
720 }
721 else if (ptr1.common->bData[0] == USB_AUDIO_DESC_SUBTYPE_CS_INPUT)
722 {
723 if (audioPtr->itDesc == NULL)
724 {
725 audioPtr->itDesc = (void *)temp;
726 }
727 }
728 else if (ptr1.common->bData[0] == USB_AUDIO_DESC_SUBTYPE_CS_OUTPUT)
729 {
730 if (audioPtr->otDesc == NULL)
731 {
732 audioPtr->otDesc = (void *)temp;
733 }
734 }
735 else if (ptr1.common->bData[0] == USB_AUDIO_DESC_SUBTYPE_CS_FEATURE)
736 {
737 if (audioPtr->fuDesc == NULL)
738 {
739 audioPtr->fuDesc = (void *)temp;
740 }
741 }
742 else if (ptr1.common->bData[0] == USB_AUDIO_DESC_SUBTYPE_CS_CLOCK_SOURE)
743 {
744 if (audioPtr->clockSource == NULL)
745 {
746 audioPtr->clockSource = (void *)temp;
747 }
748 }
749 else
750 {
751 /*no action*/
752 }
753 }
754 ptr1.bufr += ptr1.common->bLength;
755 length += ptr1.common->bLength;
756 }
757
758 if (alternateSetting == 0U)
759 {
760 if (callbackFn != NULL)
761 {
762 callbackFn(callbackParam, NULL, 0U, kStatus_USB_Success);
763 }
764 }
765 else
766 {
767 if (USB_HostMallocTransfer(audioPtr->hostHandle, &transfer) != kStatus_USB_Success)
768 {
769 #ifdef HOST_ECHO
770 usb_echo("error to get transfer\r\n");
771 #endif
772 return kStatus_USB_Error;
773 }
774 audioPtr->controlCallbackFn = callbackFn;
775 audioPtr->controlCallbackParam = callbackParam;
776 /* initialize transfer */
777 transfer->callbackFn = _USB_HostAudioControlCallback;
778 transfer->callbackParam = audioPtr;
779 transfer->setupPacket->bRequest = USB_REQUEST_STANDARD_SET_INTERFACE;
780 transfer->setupPacket->bmRequestType = USB_REQUEST_TYPE_RECIPIENT_INTERFACE;
781 transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(
782 ((usb_host_interface_t *)audioPtr->controlIntfHandle)->interfaceDesc->bInterfaceNumber);
783 transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN(alternateSetting);
784 transfer->setupPacket->wLength = 0;
785 transfer->transferBuffer = NULL;
786 transfer->transferLength = 0;
787 status = USB_HostSendSetup(audioPtr->hostHandle, audioPtr->controlPipe, transfer);
788
789 if (status == kStatus_USB_Success)
790 {
791 audioPtr->controlTransfer = transfer;
792 }
793 else
794 {
795 (void)USB_HostFreeTransfer(audioPtr->hostHandle, transfer);
796 }
797 }
798
799 return status;
800 }
801
802 /*!
803 * @brief get pipe max packet size.
804 *
805 * @param classHandle the class handle.
806 * @param pipeType It's value is USB_ENDPOINT_CONTROL, USB_ENDPOINT_ISOCHRONOUS, USB_ENDPOINT_BULK or
807 * USB_ENDPOINT_INTERRUPT.
808 * Please reference to usb_spec.h
809 * @param direction pipe direction.
810 *
811 * @retval 0 The classHandle is NULL.
812 * @retval max packet size.
813 */
USB_HostAudioPacketSize(usb_host_class_handle classHandle,uint8_t pipeType,uint8_t direction)814 uint16_t USB_HostAudioPacketSize(usb_host_class_handle classHandle, uint8_t pipeType, uint8_t direction)
815 {
816 audio_instance_t *audioPtr = (audio_instance_t *)classHandle;
817 if (classHandle == NULL)
818 {
819 return 0U;
820 }
821
822 if (pipeType == USB_ENDPOINT_ISOCHRONOUS)
823 {
824 if (direction == USB_IN)
825 {
826 return audioPtr->inPacketSize;
827 }
828 else
829 {
830 return audioPtr->outPacketSize;
831 }
832 }
833 return 0U;
834 }
835
836 /*!
837 * @brief audio stream receive data.
838 *
839 * This function implements audioreceiving data.
840 *
841 * @param classHandle The class handle.
842 * @param buffer The buffer pointer.
843 * @param bufferLen The buffer length.
844 * @param callbackFn This callback is called after this function completes.
845 * @param callbackParam The first parameter in the callback function.
846 *
847 * @retval kStatus_USB_Success Receive request successfully.
848 * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
849 * @retval kStatus_USB_Busy There is no idle transfer.
850 * @retval kStatus_USB_Error pipe is not initialized.
851 * Or, send transfer fail, please reference to USB_HostRecv.
852 */
USB_HostAudioStreamRecv(usb_host_class_handle classHandle,uint8_t * buffer,uint32_t bufferLen,transfer_callback_t callbackFn,void * callbackParam)853 usb_status_t USB_HostAudioStreamRecv(usb_host_class_handle classHandle,
854 uint8_t *buffer,
855 uint32_t bufferLen,
856 transfer_callback_t callbackFn,
857 void *callbackParam)
858 {
859 audio_instance_t *audioPtr = (audio_instance_t *)classHandle;
860 usb_host_transfer_t *transfer;
861
862 if (classHandle == NULL)
863 {
864 return kStatus_USB_InvalidHandle;
865 }
866
867 if (audioPtr->isoInPipe == NULL)
868 {
869 return kStatus_USB_Error;
870 }
871
872 if (USB_HostMallocTransfer(audioPtr->hostHandle, &transfer) != kStatus_USB_Success)
873 {
874 #ifdef HOST_ECHO
875 usb_echo("error to get transfer\r\n");
876 #endif
877 return kStatus_USB_Error;
878 }
879 audioPtr->inCallbackFn = callbackFn;
880 audioPtr->inCallbackParam = callbackParam;
881 transfer->transferBuffer = buffer;
882 transfer->transferLength = bufferLen;
883 transfer->callbackFn = _USB_HostAudioStreamIsoInPipeCallback;
884 transfer->callbackParam = audioPtr;
885
886 if (USB_HostRecv(audioPtr->hostHandle, audioPtr->isoInPipe, transfer) != kStatus_USB_Success)
887 {
888 #ifdef HOST_ECHO
889 usb_echo("failed to USB_HostRecv\r\n");
890 #endif
891 (void)USB_HostFreeTransfer(audioPtr->hostHandle, transfer);
892 return kStatus_USB_Error;
893 }
894
895 return kStatus_USB_Success;
896 }
897
898 /*!
899 * @brief audio stream send data.
900 *
901 * This function implements audio sending data.
902 *
903 * @param classHandle The class handle.
904 * @param buffer The buffer pointer.
905 * @param bufferLen The buffer length.
906 * @param callbackFn This callback is called after this function completes.
907 * @param callbackParam The first parameter in the callback function.
908 *
909 * @retval kStatus_USB_Success Receive request successfully.
910 * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
911 * @retval kStatus_USB_Busy There is no idle transfer.
912 * @retval kStatus_USB_Error pipe is not initialized.
913 * Or, send transfer fail, please reference to USB_HostSend.
914 */
USB_HostAudioStreamSend(usb_host_class_handle classHandle,uint8_t * buffer,uint32_t bufferLen,transfer_callback_t callbackFn,void * callbackParam)915 usb_status_t USB_HostAudioStreamSend(usb_host_class_handle classHandle,
916 uint8_t *buffer,
917 uint32_t bufferLen,
918 transfer_callback_t callbackFn,
919 void *callbackParam)
920 {
921 audio_instance_t *audioPtr = (audio_instance_t *)classHandle;
922 usb_host_transfer_t *transfer;
923
924 if (classHandle == NULL)
925 {
926 return kStatus_USB_InvalidHandle;
927 }
928
929 if (audioPtr->isoOutPipe == NULL)
930 {
931 return kStatus_USB_Error;
932 }
933
934 if (USB_HostMallocTransfer(audioPtr->hostHandle, &transfer) != kStatus_USB_Success)
935 {
936 #ifdef HOST_ECHO
937 usb_echo("error to get transfer\r\n");
938 #endif
939 return kStatus_USB_Error;
940 }
941 audioPtr->outCallbackFn = callbackFn;
942 audioPtr->outCallbackParam = callbackParam;
943 transfer->transferBuffer = buffer;
944 transfer->transferLength = bufferLen;
945 transfer->callbackFn = _USB_HostAudioStreamIsoOutPipeCallback;
946 transfer->callbackParam = audioPtr;
947
948 if (USB_HostSend(audioPtr->hostHandle, audioPtr->isoOutPipe, transfer) != kStatus_USB_Success)
949 {
950 #ifdef HOST_ECHO
951 usb_echo("failed to USB_HostSend\r\n");
952 #endif
953 (void)USB_HostFreeTransfer(audioPtr->hostHandle, transfer);
954 return kStatus_USB_Error;
955 }
956
957 return kStatus_USB_Success;
958 }
959 /*!
960 * @brief get audio control current altsetting descriptor.
961 *
962 * This function implements get audio stream current altsetting descriptor.
963 *
964 * @param classHandle The class handle.
965 * @param DescriptorType The descriptor type.
966 * @param DescriptorSubType The descriptor subtype, 0 for no subtype.
967 * @param Descriptor The pointer of descriptor pointer.
968 *
969 * @retval kStatus_USB_Success Get audio stream current altsetting descriptor request successfully.
970 * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
971 *
972 */
USB_HostAudioControlGetCurrentAltsettingSpecificDescriptors(usb_host_class_handle classHandle,uint32_t DescriptorType,uint32_t DescriptorSubType,void ** Descriptor)973 usb_status_t USB_HostAudioControlGetCurrentAltsettingSpecificDescriptors(
974
975 usb_host_class_handle classHandle, uint32_t DescriptorType, uint32_t DescriptorSubType, void **Descriptor)
976 {
977 audio_instance_t *audioPtr = (audio_instance_t *)classHandle;
978 usb_status_t status = kStatus_USB_Error;
979 uint32_t **descriptorPointer = (uint32_t **)Descriptor;
980 if ((classHandle == NULL) || NULL == Descriptor)
981 {
982 return kStatus_USB_InvalidParameter;
983 }
984
985 if (USB_AUDIO_DESCRIPTOR_TYPE_CS_INTERFACE == DescriptorType)
986 {
987 if (AUDIO_DEVICE_VERSION_01 == audioPtr->deviceAudioVersion)
988 {
989 if (USB_AUDIO_DESC_SUBTYPE_CS_EXTENSION <= DescriptorSubType)
990 {
991 /*descriptor type code bigger than EXTENSION is not support by audio 1.0*/
992 return kStatus_USB_InvalidParameter;
993 }
994 }
995 switch (DescriptorSubType)
996 {
997 case USB_AUDIO_DESC_SUBTYPE_CS_HEADER:
998 *descriptorPointer = (uint32_t *)audioPtr->headerDesc;
999 status = kStatus_USB_Success;
1000 break;
1001 case USB_AUDIO_DESC_SUBTYPE_CS_INPUT:
1002 *descriptorPointer = (uint32_t *)audioPtr->itDesc;
1003 status = kStatus_USB_Success;
1004 break;
1005 case USB_AUDIO_DESC_SUBTYPE_CS_OUTPUT:
1006 *descriptorPointer = (uint32_t *)audioPtr->otDesc;
1007 status = kStatus_USB_Success;
1008 break;
1009 case USB_AUDIO_DESC_SUBTYPE_CS_FEATURE:
1010 *descriptorPointer = (uint32_t *)audioPtr->fuDesc;
1011 status = kStatus_USB_Success;
1012 break;
1013 default:
1014 /*no action*/
1015 break;
1016 }
1017 }
1018
1019 return status;
1020 }
1021 /*!
1022 * @brief get audio control current altsetting descriptor.
1023 *
1024 * This function implements get audio stream current altsetting descriptor.
1025 *
1026 * @param classHandle The class handle.
1027 * @param DescriptorType The descriptor type.
1028 * @param DescriptorSubType The descriptor subtype, default 0.
1029 * @param Descriptor The pointer of descriptor pointer.
1030 *
1031 * @retval kStatus_USB_Success Get audio stream current altsetting descriptor request successfully.
1032 * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
1033 *
1034 */
USB_HostAudioStreamGetCurrentAltsettingSpecificDescriptors(usb_host_class_handle classHandle,uint32_t DescriptorType,uint32_t DescriptorSubType,void ** Descriptor)1035 usb_status_t USB_HostAudioStreamGetCurrentAltsettingSpecificDescriptors(
1036
1037 usb_host_class_handle classHandle, uint32_t DescriptorType, uint32_t DescriptorSubType, void **Descriptor)
1038 {
1039 audio_instance_t *audioPtr = (audio_instance_t *)classHandle;
1040 usb_status_t status = kStatus_USB_Error;
1041 uint32_t **descriptorPointer = (uint32_t **)Descriptor;
1042 void *temp;
1043
1044 if ((classHandle == NULL) || NULL == Descriptor)
1045 {
1046 return kStatus_USB_InvalidParameter;
1047 }
1048
1049 if (USB_AUDIO_DESCRIPTOR_TYPE_CS_INTERFACE == DescriptorType)
1050 {
1051 if (AUDIO_DEVICE_VERSION_01 == audioPtr->deviceAudioVersion)
1052 {
1053 switch (DescriptorSubType)
1054 {
1055 case USB_AUDIO_DESC_SUBTYPE_AS_GENERAL:
1056 *descriptorPointer = (uint32_t *)audioPtr->asIntfDesc;
1057 status = kStatus_USB_Success;
1058 break;
1059 case USB_AUDIO_DESC_SUBTYPE_AS_FORMAT_TYPE:
1060 *descriptorPointer = (uint32_t *)audioPtr->formatTypeDesc;
1061 status = kStatus_USB_Success;
1062 break;
1063 default:
1064 /*no action*/
1065 break;
1066 }
1067 }
1068 else if (AUDIO_DEVICE_VERSION_02 == audioPtr->deviceAudioVersion)
1069 {
1070 switch (DescriptorSubType)
1071 {
1072 case USB_AUDIO_DESC_SUBTYPE_AS_GENERAL_20:
1073 *descriptorPointer = (uint32_t *)audioPtr->asIntfDesc;
1074 status = kStatus_USB_Success;
1075 break;
1076 case USB_AUDIO_DESC_SUBTYPE_AS_FORMAT_TYPE_20:
1077 *descriptorPointer = (uint32_t *)audioPtr->formatTypeDesc;
1078 status = kStatus_USB_Success;
1079 break;
1080 case USB_AUDIO_DESC_SUBTYPE_AS_FORMAT_ENCODER_20:
1081 /*no action*/
1082 break;
1083 default:
1084 /*no action*/
1085 break;
1086 }
1087 }
1088 else
1089 {
1090 /*To DO*/
1091 }
1092 }
1093 else if (USB_DESCRIPTOR_TYPE_ENDPOINT == DescriptorType)
1094 {
1095 if (0x0U == DescriptorSubType)
1096 {
1097 /*iso data endpoint descriptor*/
1098 temp = (void *)audioPtr->isoEndpDesc;
1099 *descriptorPointer = (uint32_t *)temp;
1100 status = kStatus_USB_Success;
1101 }
1102 else
1103 {
1104 /*TO DO*/
1105 }
1106 }
1107 else
1108 {
1109 /*To DO*/
1110 }
1111
1112 return status;
1113 }
1114
1115 /*!
1116 * @brief get audio stream current altsetting descriptor.
1117 * @deprecated Do not use this function. It has been superceded by @ref
1118 * USB_HostAudioStreamGetCurrentAltsettingSpecificDescriptors.
1119 *
1120 * This function implements get audio stream current altsetting descriptor.
1121 *
1122 * @param classHandle The class handle.
1123 * @param asIntfDesc The pointer of class specific AS interface descriptor.
1124 * @param formatTypeDesc The pointer of format type descriptor.
1125 * @param isoEndpDesc The pointer of specific iso endp descriptor.
1126 *
1127 * @retval kStatus_USB_Success Get audio stream current altsetting descriptor request successfully.
1128 * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
1129 *
1130 */
USB_HostAudioStreamGetCurrentAltsettingDescriptors(usb_host_class_handle classHandle,usb_audio_stream_spepific_as_intf_desc_t ** asIntfDesc,usb_audio_stream_format_type_desc_t ** formatTypeDesc,usb_descriptor_endpoint_t ** isoEndpDesc)1131 usb_status_t USB_HostAudioStreamGetCurrentAltsettingDescriptors(
1132
1133 usb_host_class_handle classHandle,
1134 usb_audio_stream_spepific_as_intf_desc_t **asIntfDesc,
1135 usb_audio_stream_format_type_desc_t **formatTypeDesc,
1136 usb_descriptor_endpoint_t **isoEndpDesc)
1137 {
1138 audio_instance_t *audioPtr = (audio_instance_t *)classHandle;
1139
1140 if (classHandle == NULL)
1141 {
1142 return kStatus_USB_InvalidHandle;
1143 }
1144 *asIntfDesc = (usb_audio_stream_spepific_as_intf_desc_t *)audioPtr->asIntfDesc;
1145 *formatTypeDesc = (usb_audio_stream_format_type_desc_t *)audioPtr->formatTypeDesc;
1146 *isoEndpDesc = (usb_descriptor_endpoint_t *)audioPtr->isoEndpDesc;
1147
1148 return kStatus_USB_Success;
1149 }
1150 /*!
1151 * @brief usb audio set/get feature unit request.
1152 *
1153 * This function implements usb audio feature unit request.
1154 *
1155 * @param classHandle The class handle.
1156 * @param csAndCn The CS and CN or MCN for wValue field in setup Request.
1157 * @param cmdCode The bRequest code in lower 8bit of lower word and get(1)/set(0) flag in higher 8bit of lower
1158 * word.
1159 * @param buf The feature unit request buffer pointer.
1160 * @param callbackFn This callback is called after this function completes.
1161 * @param callbackParam The first parameter in the callback function.
1162 *
1163 * @retval kStatus_USB_Success Feature unit request successfully.
1164 * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
1165 * @retval kStatus_USB_Busy There is no idle transfer.
1166 * @retval kStatus_USB_Error Send transfer fail, please reference to USB_HostSendSetup.
1167 *
1168 */
USB_HostAudioGetSetFeatureUnitRequest(usb_host_class_handle classHandle,uint32_t csAndCn,uint32_t cmdCode,void * buf,uint32_t bufLen,transfer_callback_t callbackFn,void * callbackParam)1169 usb_status_t USB_HostAudioGetSetFeatureUnitRequest(usb_host_class_handle classHandle,
1170 uint32_t csAndCn,
1171 uint32_t cmdCode,
1172 void *buf,
1173 uint32_t bufLen,
1174 transfer_callback_t callbackFn,
1175 void *callbackParam)
1176 {
1177 audio_instance_t *if_ptr;
1178 uint8_t *bmacontrols = NULL;
1179 usb_audio_ctrl_common_fu_desc *fuDesc;
1180 uint16_t windex;
1181 uint8_t request;
1182 uint8_t atribute_index;
1183 uint16_t length = 0U;
1184 uint8_t typeRequest;
1185 uint8_t controlSelector;
1186
1187 usb_status_t status = kStatus_USB_Error;
1188
1189 if (classHandle == NULL)
1190 {
1191 return kStatus_USB_InvalidHandle;
1192 }
1193
1194 if_ptr = (audio_instance_t *)classHandle;
1195
1196 /* Check whether this attribute valid or not */
1197 if (if_ptr->fuDesc == NULL)
1198 {
1199 return kStatus_USB_Error;
1200 }
1201 fuDesc = (usb_audio_ctrl_common_fu_desc *)if_ptr->fuDesc;
1202 if (AUDIO_DEVICE_VERSION_01 == if_ptr->deviceAudioVersion)
1203 {
1204 windex = (uint16_t)((uint16_t)((uint16_t)(fuDesc->fuDesc10.bunitid) << 8U) | (if_ptr->streamIfnum));
1205 atribute_index = (uint8_t)(fuDesc->fuDesc10.bcontrolsize * ((uint16_t)csAndCn & 0xFFU));
1206 /*Size of this descriptor, in bytes: 7+(ch+1)*n*/
1207 if (atribute_index < (fuDesc->fuDesc10.blength - 7U))
1208 {
1209 bmacontrols = &(fuDesc->fuDesc10.bcontrolsize);
1210 }
1211 }
1212 else if (AUDIO_DEVICE_VERSION_02 == if_ptr->deviceAudioVersion)
1213 {
1214 windex = (uint16_t)((uint16_t)((uint16_t)(fuDesc->fuDesc20.bunitid) << 8U) | (if_ptr->streamIfnum));
1215 /*BmControl is 4byte, refer to *audio2.0 4.7.2.8 Size of this descriptor, in bytes: 6+(ch+1)*4*/
1216 atribute_index = (uint8_t)(4U * ((uint16_t)csAndCn & 0xFFU));
1217
1218 if (atribute_index < (fuDesc->fuDesc20.blength - 6U))
1219 {
1220 bmacontrols = &(fuDesc->fuDesc20.bmaControls0[0]);
1221 }
1222 }
1223 else
1224 {
1225 /*TO DO*/
1226 }
1227 if (bmacontrols == NULL)
1228 {
1229 return kStatus_USB_Error;
1230 }
1231 request = (uint8_t)(((uint16_t)cmdCode & 0xFFU));
1232
1233 controlSelector = (uint8_t)((uint16_t)(csAndCn >> 8) & 0xFFU);
1234 if (AUDIO_DEVICE_VERSION_01 == if_ptr->deviceAudioVersion)
1235 {
1236 /*control selector */
1237 switch (controlSelector)
1238 {
1239 /*note ,all the length is defined in audio1.0 Spec chapter 5.2.2.4.3*/
1240 case AUDIO_FU_MUTE:
1241 status = kStatus_USB_Success;
1242 length = 1U;
1243 break;
1244 case AUDIO_FU_VOLUME:
1245 status = kStatus_USB_Success;
1246 length = 2U;
1247 break;
1248 case AUDIO_FU_BASS:
1249 /*TO DO*/
1250 break;
1251 default:
1252 /*no action*/
1253 break;
1254 }
1255 }
1256 else if (AUDIO_DEVICE_VERSION_02 == if_ptr->deviceAudioVersion)
1257 {
1258 if ((request != USB_AUDIO_CS_REQUEST_CODE_RANGE_20) && (request != USB_AUDIO_CS_REQUEST_CODE_CUR_20))
1259 {
1260 return kStatus_USB_Error;
1261 }
1262 switch (controlSelector)
1263 {
1264 /*note ,all the length is defined in audio2.0 Spec chapter 5.2.5.7*/
1265 case AUDIO_FU_MUTE:
1266
1267 if (bufLen != 1U)
1268 {
1269 return kStatus_USB_Error;
1270 }
1271 status = kStatus_USB_Success;
1272 length = 1U;
1273 break;
1274 case AUDIO_FU_VOLUME:
1275 status = kStatus_USB_Success;
1276
1277 if (USB_AUDIO_CS_REQUEST_CODE_RANGE_20 == request)
1278 {
1279 /*the len for volume is 2+6*n*/
1280 if (bufLen < 8U)
1281 {
1282 return kStatus_USB_Error;
1283 }
1284 }
1285 else if (USB_AUDIO_CS_REQUEST_CODE_CUR_20 == request)
1286 {
1287 if (bufLen != 2U)
1288 {
1289 return kStatus_USB_Error;
1290 }
1291 }
1292 else
1293 {
1294 /*TO DO*/
1295 }
1296 length = (uint16_t)bufLen;
1297
1298 break;
1299 case AUDIO_FU_BASS:
1300 /*TO DO*/
1301 break;
1302 default:
1303 /*no action*/
1304 break;
1305 }
1306 }
1307 else
1308 {
1309 /*TO DO*/
1310 }
1311
1312 if (status != kStatus_USB_Success)
1313 {
1314 /*the request is not support*/
1315 return kStatus_USB_Error;
1316 }
1317 if (0U == ((uint16_t)(cmdCode >> 8U) & 0xFFU))
1318 {
1319 /*refer to audio Spec 2.0 chapter 5.2.2*/
1320 typeRequest = 0x21U;
1321 }
1322 else
1323 {
1324 typeRequest = 0xA1U;
1325 }
1326
1327 status = _USB_HostAudioControl(classHandle, typeRequest, request, (uint16_t)csAndCn, windex, length, (uint8_t *)buf,
1328 callbackFn, callbackParam);
1329
1330 return status;
1331 }
1332 /*!
1333 * @brief usb audio set/get feature unit request.
1334 *
1335 * This function implements usb audio feature unit request.
1336 *
1337 * @param classHandle The class handle.
1338 * @param csAndCn The CS and CN or MCN for wValue field in setup Request.
1339 * @param cmdCode The bRequest code in lower 8bit of lower word and get(1)/set(0) flag in higher 8bit of lower
1340 word.
1341 * @param buf The feature unit request buffer pointer.
1342
1343 * @param callbackFn This callback is called after this function completes.
1344 * @param callbackParam The first parameter in the callback function.
1345 *
1346 * @retval kStatus_USB_Success Feature unit request successfully.
1347 * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
1348 * @retval kStatus_USB_Busy There is no idle transfer.
1349 * @retval kStatus_USB_Error Send transfer fail, please reference to USB_HostSendSetup.
1350 *
1351 */
USB_HostAudioGetSetClockSourceRequest(usb_host_class_handle classHandle,uint32_t csAndCn,uint32_t cmdCode,void * buf,uint32_t bufLen,transfer_callback_t callbackFn,void * callbackParam)1352 usb_status_t USB_HostAudioGetSetClockSourceRequest(usb_host_class_handle classHandle,
1353 uint32_t csAndCn,
1354 uint32_t cmdCode,
1355 void *buf,
1356 uint32_t bufLen,
1357 transfer_callback_t callbackFn,
1358 void *callbackParam)
1359 {
1360 audio_instance_t *if_ptr;
1361 usb_audio_2_0_ctrl_clock_source_desc_t *clockDesc;
1362 uint16_t windex;
1363 uint16_t controlSelector;
1364 uint8_t length = 0U;
1365 uint8_t typeRequest;
1366 uint8_t request;
1367
1368 usb_status_t status = kStatus_USB_Error;
1369
1370 if (classHandle == NULL)
1371 {
1372 return kStatus_USB_InvalidParameter;
1373 }
1374
1375 if_ptr = (audio_instance_t *)classHandle;
1376
1377 if (AUDIO_DEVICE_VERSION_02 == if_ptr->deviceAudioVersion)
1378 {
1379 clockDesc = (usb_audio_2_0_ctrl_clock_source_desc_t *)if_ptr->clockSource;
1380 windex = (uint16_t)((uint16_t)((uint16_t)(clockDesc->bClockID) << 8U) | (if_ptr->streamIfnum));
1381 }
1382 else
1383 {
1384 return kStatus_USB_Error;
1385 }
1386 request = (uint8_t)(((uint16_t)cmdCode & 0xFFU));
1387 controlSelector = (uint8_t)((uint16_t)(csAndCn >> 8U) & 0xFFU);
1388
1389 if (USB_AUDIO_CS_SAM_FREQ_CONTROL_20 == controlSelector)
1390 {
1391 /*note ,all the length is defined in audio2.0 Spec chapter 5.2.5.1.1*/
1392
1393 if (USB_AUDIO_CS_REQUEST_CODE_RANGE_20 == request)
1394 {
1395 /*the len for volume is 2+6*n*/
1396 if (bufLen < 12U)
1397 {
1398 return kStatus_USB_Error;
1399 }
1400 else
1401 {
1402 length = (uint8_t)bufLen;
1403 }
1404 }
1405 else if (USB_AUDIO_CS_REQUEST_CODE_CUR_20 == request)
1406 {
1407 if (bufLen != 4U)
1408 {
1409 return kStatus_USB_Error;
1410 }
1411 length = (uint8_t)bufLen;
1412 }
1413 else
1414 {
1415 return kStatus_USB_Error;
1416 }
1417 status = kStatus_USB_Success;
1418 }
1419 else if (USB_AUDIO_CS_CLOCK_VALID_CONTROL_20 == controlSelector)
1420 {
1421 status = kStatus_USB_Success;
1422 if (bufLen < 1U)
1423 {
1424 return kStatus_USB_Error;
1425 }
1426 length = 1U;
1427 }
1428 else
1429 {
1430 /**TO DO*/
1431 }
1432
1433 if (status != kStatus_USB_Success)
1434 {
1435 /*the request is not support*/
1436 return kStatus_USB_Error;
1437 }
1438
1439 if (0U == ((uint16_t)(cmdCode >> 8U) & 0xFFU))
1440 {
1441 /*refer to audio Spec 2.0 chapter 5.2.2*/
1442 typeRequest = 0x21U;
1443 }
1444 else
1445 {
1446 typeRequest = 0xA1U;
1447 }
1448
1449 status = _USB_HostAudioControl(classHandle, typeRequest, request, (uint16_t)csAndCn, windex, length, (uint8_t *)buf,
1450 callbackFn, callbackParam);
1451
1452 return status;
1453 }
1454
1455 /*!
1456 * @brief usb audio feature unit request.
1457 * @deprecated Do not use this function. It has been superceded by @ref USB_HostAudioGetSetFeatureUnitRequest.
1458 *
1459 * This function implements usb audio feature unit request.
1460 *
1461 * @param classHandle The class handle.
1462 * @param channelNo The channel number of audio feature unit.
1463 * @param buf The feature unit request buffer pointer.
1464 * @param cmdCode The feature unit command code, for example USB_AUDIO_GET_CUR_MUTE etc.
1465 * @param callbackFn This callback is called after this function completes.
1466 * @param callbackParam The first parameter in the callback function.
1467 *
1468 * @retval kStatus_USB_Success Feature unit request successfully.
1469 * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
1470 * @retval kStatus_USB_Busy There is no idle transfer.
1471 * @retval kStatus_USB_Error Send transfer fail, please reference to USB_HostSendSetup.
1472 *
1473 */
USB_HostAudioFeatureUnitRequest(usb_host_class_handle classHandle,uint8_t channelNo,void * buf,uint32_t cmdCode,transfer_callback_t callbackFn,void * callbackParam)1474 usb_status_t USB_HostAudioFeatureUnitRequest(usb_host_class_handle classHandle,
1475 uint8_t channelNo,
1476 void *buf,
1477 uint32_t cmdCode,
1478 transfer_callback_t callbackFn,
1479 void *callbackParam)
1480 { /* Body */
1481 uint16_t windex;
1482 uint16_t request_value;
1483 audio_instance_t *if_ptr;
1484 usb_audio_request_t *p_feature_request;
1485 usb_audio_ctrl_fu_desc_t *fuDesc;
1486 uint8_t *bmacontrols = NULL;
1487 uint8_t atribute_index;
1488 usb_status_t status;
1489
1490 if ((classHandle == NULL))
1491 {
1492 return kStatus_USB_InvalidHandle;
1493 }
1494
1495 if_ptr = (audio_instance_t *)classHandle;
1496 if (AUDIO_DEVICE_VERSION_01 != if_ptr->deviceAudioVersion)
1497 {
1498 return kStatus_USB_Error;
1499 }
1500 /* pointer to command */
1501 p_feature_request = &(s_usbAudioFuRequests[(uint8_t)cmdCode & 0xfU]);
1502 /* get request value */
1503 request_value = (uint16_t)((uint16_t)((uint16_t)p_feature_request->requestValue << 8U) | channelNo);
1504
1505 /* Check whether this attribute valid or not */
1506 if (if_ptr->fuDesc == NULL)
1507 {
1508 return kStatus_USB_Error;
1509 }
1510 fuDesc = (usb_audio_ctrl_fu_desc_t *)if_ptr->fuDesc;
1511 windex = (uint16_t)((uint16_t)((uint16_t)(fuDesc->bunitid) << 8U) | (if_ptr->streamIfnum));
1512 atribute_index = fuDesc->bcontrolsize * channelNo;
1513
1514 if (atribute_index < (fuDesc->blength - 7U))
1515 {
1516 bmacontrols = &(fuDesc->bcontrolsize);
1517 }
1518
1519 if (bmacontrols == NULL)
1520 {
1521 return kStatus_USB_Error;
1522 }
1523
1524 status = _USB_HostAudioControl(classHandle, (p_feature_request->typeRequest | ((uint8_t)cmdCode & 0x80U)),
1525 (p_feature_request->codeRequest | ((uint8_t)cmdCode & 0x80U)), request_value, windex,
1526 p_feature_request->length, (uint8_t *)buf, callbackFn, callbackParam);
1527
1528 return status;
1529 }
1530 /*!
1531 * @brief usb audio set/get endp unit request.
1532 *
1533 * This function implements usb audio feature unit request.
1534 *
1535 * @param classHandle The class handle.
1536 * @param csAndCn The CS for wValue field in setup Request.
1537 * @param cmdCode The bRequest code in lower 8bit of lower word and get(1)/set(0) flag in higher 8bit of lower
1538 word.
1539 * @param buf The feature unit request buffer pointer.
1540
1541 * @param callbackFn This callback is called after this function completes.
1542 * @param callbackParam The first parameter in the callback function.
1543 *
1544 * @retval kStatus_USB_Success Feature unit request successfully.
1545 * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
1546 * @retval kStatus_USB_Busy There is no idle transfer.
1547 * @retval kStatus_USB_Error Send transfer fail, please reference to USB_HostSendSetup.
1548 *
1549 */
USB_HostAudioGetSetEndpointRequest(usb_host_class_handle classHandle,uint32_t csAndCn,uint32_t cmdCode,void * buf,uint32_t bufLen,transfer_callback_t callbackFn,void * callbackParam)1550 usb_status_t USB_HostAudioGetSetEndpointRequest(usb_host_class_handle classHandle,
1551 uint32_t csAndCn,
1552 uint32_t cmdCode,
1553 void *buf,
1554 uint32_t bufLen,
1555 transfer_callback_t callbackFn,
1556 void *callbackParam)
1557 {
1558 audio_instance_t *if_ptr;
1559 uint16_t windex;
1560 uint8_t request;
1561 uint8_t length = 0U;
1562 uint8_t typeRequest;
1563 uint8_t controlSelector;
1564
1565 usb_status_t status = kStatus_USB_Error;
1566
1567 if (classHandle == NULL)
1568 {
1569 return kStatus_USB_InvalidHandle;
1570 }
1571
1572 if_ptr = (audio_instance_t *)classHandle;
1573
1574 if (AUDIO_DEVICE_VERSION_01 == if_ptr->deviceAudioVersion)
1575 {
1576 if ((NULL == if_ptr->isoInPipe) && (NULL == if_ptr->isoOutPipe))
1577 {
1578 return kStatus_USB_InvalidParameter;
1579 }
1580 else if (NULL != if_ptr->isoInPipe)
1581 {
1582 windex = (((uint16_t)if_ptr->isoEpNum) | 0x80U);
1583 }
1584 else
1585 {
1586 windex = if_ptr->isoEpNum;
1587 }
1588 }
1589 else if (AUDIO_DEVICE_VERSION_02 == if_ptr->deviceAudioVersion)
1590 {
1591 /*TO DO*/
1592 }
1593 else
1594 {
1595 /*TO DO*/
1596 }
1597
1598 request = (uint8_t)(((uint16_t)cmdCode & 0xFFU));
1599
1600 controlSelector = (uint8_t)((uint16_t)(csAndCn >> 8U) & 0xFFU);
1601 if (AUDIO_DEVICE_VERSION_01 == if_ptr->deviceAudioVersion)
1602 {
1603 /*control selector */
1604 /*note ,all the length is defined in audio1.0 Spec chapter 5.2.3.2.3*/
1605 if (USB_AUDIO_EP_CS_SAMPING_FREQ_CONTROL == controlSelector)
1606 {
1607 if (bufLen > 3U)
1608 {
1609 /*fixed length*/
1610 length = 3U;
1611 status = kStatus_USB_Success;
1612 }
1613 else
1614 {
1615 /*TO DO*/
1616 }
1617 }
1618 else if (USB_AUDIO_EP_CS_PINTCH_CONTROL == controlSelector)
1619 {
1620 /*TO DO*/
1621 }
1622 else
1623 {
1624 /*TO DO*/
1625 }
1626 }
1627 else if (AUDIO_DEVICE_VERSION_02 == if_ptr->deviceAudioVersion)
1628 {
1629 switch (controlSelector)
1630 {
1631 /*note ,all the length is defined in audio2.0 Spec chapter 5.2.6*/
1632 case USB_AUDIO_EP_CS_PINTCH_CONTROL_20:
1633 /*TO DO*/
1634 break;
1635 case USB_AUDIO_EP_CS_OVERRUN_CONTROL_20:
1636 /*TO DO*/
1637 break;
1638 case USB_AUDIO_EP_CS_UNDERRUN_CONTROL_20:
1639 /*TO DO*/
1640 break;
1641 default:
1642 /*no action*/
1643 break;
1644 }
1645 }
1646 else
1647 {
1648 /*TO DO*/
1649 }
1650
1651 if (status != kStatus_USB_Success)
1652 {
1653 /*the request is not support*/
1654 return kStatus_USB_Error;
1655 }
1656 if (0U == ((uint16_t)(cmdCode >> 8U) & 0xFFU))
1657 {
1658 /*refer to audio Spec 2.0 chapter 5.2.2*/
1659 typeRequest = 0x22U;
1660 }
1661 else
1662 {
1663 typeRequest = 0xA2U;
1664 }
1665
1666 status = _USB_HostAudioControl(classHandle, typeRequest, request, (uint16_t)csAndCn, windex, length, (uint8_t *)buf,
1667 callbackFn, callbackParam);
1668
1669 return status;
1670 }
1671 /*!
1672 * @brief usb audio endpoint request.
1673 * @deprecated Do not use this function. It has been superceded by @ref USB_HostAudioGetSetEndpointRequest.
1674 *
1675 * This function implements usb audio endpoint request.
1676 *
1677 * @param classHandle The class handle.
1678 * @param buf The feature unit buffer pointer.
1679 * @param cmdCode The feature unit command code, for example USB_AUDIO_GET_CUR_PITCH etc .
1680 * @param callbackFn This callback is called after this function completes.
1681 * @param callbackParam The first parameter in the callback function.
1682 *
1683 * @retval kStatus_USB_Success Endpoint request successfully.
1684 * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
1685 * @retval kStatus_USB_Busy There is no idle transfer.
1686 * @retval kStatus_USB_Error Send transfer fail, please reference to USB_HostSendSetup.
1687 *
1688 */
USB_HostAudioEndpointRequest(usb_host_class_handle classHandle,void * buf,uint32_t cmdCode,transfer_callback_t callbackFn,void * callbackParam)1689 usb_status_t USB_HostAudioEndpointRequest(
1690 usb_host_class_handle classHandle, void *buf, uint32_t cmdCode, transfer_callback_t callbackFn, void *callbackParam)
1691 {
1692 uint8_t endp_num;
1693 usb_status_t status;
1694 uint16_t request_value;
1695 usb_audio_request_t *p_endpoint_request;
1696 audio_instance_t *audioPtr;
1697
1698 if (classHandle == NULL)
1699 {
1700 return kStatus_USB_InvalidHandle;
1701 }
1702
1703 audioPtr = (audio_instance_t *)classHandle;
1704 if (AUDIO_DEVICE_VERSION_01 != audioPtr->deviceAudioVersion)
1705 {
1706 return kStatus_USB_Error;
1707 }
1708 /* pointer to command */
1709 p_endpoint_request = &(s_usbAudioEpRequests[(uint8_t)cmdCode & 0xfU]);
1710 /* get request value */
1711 request_value = (uint16_t)((uint16_t)((uint16_t)p_endpoint_request->requestValue << 8U));
1712
1713 /* Check whether this attribute valid or not */
1714 if (audioPtr->isoEndpDesc == NULL)
1715 {
1716 return kStatus_USB_Error;
1717 }
1718 if ((0U != audioPtr->isoEndpDesc->bmAttributes) && (0U != p_endpoint_request->controlMask))
1719 {
1720 status = kStatus_USB_Success;
1721 }
1722 else
1723 {
1724 status = kStatus_USB_InvalidRequest;
1725 }
1726
1727 if (kStatus_USB_Success == status)
1728 {
1729 /* Any isochronous pipe is supported? */
1730 if ((NULL == audioPtr->isoInPipe) && (NULL == audioPtr->isoOutPipe))
1731 {
1732 return kStatus_USB_InvalidParameter;
1733 }
1734 else if (NULL != audioPtr->isoInPipe)
1735 {
1736 endp_num = (audioPtr->isoEpNum | 0x80U);
1737 }
1738 else
1739 {
1740 endp_num = audioPtr->isoEpNum;
1741 } /* Endif */
1742
1743 status = _USB_HostAudioControl(classHandle, (p_endpoint_request->typeRequest | ((uint8_t)cmdCode & 0x80U)),
1744 (p_endpoint_request->codeRequest | ((uint8_t)cmdCode & 0x80U)), request_value,
1745 endp_num, p_endpoint_request->length, (uint8_t *)buf, callbackFn, callbackParam);
1746 }
1747
1748 return status;
1749 }
1750
USB_HostAudioSetStreamOutDataInterval(usb_host_class_handle classHandle,uint8_t intervalValue)1751 usb_status_t USB_HostAudioSetStreamOutDataInterval(usb_host_class_handle classHandle, uint8_t intervalValue)
1752 {
1753 audio_instance_t *audioPtr = (audio_instance_t *)classHandle;
1754 usb_status_t status = kStatus_USB_Error;
1755 uint8_t ep_index = 0U;
1756 usb_descriptor_endpoint_t *ep_desc = NULL;
1757 usb_host_interface_t *interface_ptr;
1758
1759 if (classHandle == NULL)
1760 {
1761 return kStatus_USB_InvalidHandle;
1762 }
1763
1764 if (audioPtr->isoOutPipe != NULL)
1765 {
1766 (void)USB_HostClosePipe(audioPtr->hostHandle, audioPtr->isoOutPipe);
1767 audioPtr->isoOutPipe = NULL;
1768 }
1769
1770 /* open interface pipes */
1771 interface_ptr = (usb_host_interface_t *)audioPtr->streamIntfHandle;
1772 for (ep_index = 0U; ep_index < interface_ptr->epCount; ++ep_index)
1773 {
1774 ep_desc = interface_ptr->epList[ep_index].epDesc;
1775 if (((ep_desc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
1776 USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_OUT) &&
1777 ((ep_desc->bmAttributes & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK) == USB_ENDPOINT_ISOCHRONOUS))
1778 {
1779 uint8_t intervalBackUp = ep_desc->bInterval;
1780 ep_desc->bInterval = intervalValue;
1781 status = _USB_HostAudioInitEndpoint(audioPtr, ep_desc);
1782 ep_desc->bInterval = intervalBackUp;
1783 }
1784 }
1785
1786 return status;
1787 }
1788 #endif /* USB_HOST_CONFIG_AUDIO */
1789