1 /**************************************************************************/ 2 /* */ 3 /* Copyright (c) Microsoft Corporation. All rights reserved. */ 4 /* */ 5 /* This software is licensed under the Microsoft Software License */ 6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */ 7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ 8 /* and in the root directory of this software. */ 9 /* */ 10 /**************************************************************************/ 11 12 /**************************************************************************/ 13 /** */ 14 /** USBX Component */ 15 /** */ 16 /** Device Audio Class */ 17 /** */ 18 /**************************************************************************/ 19 /**************************************************************************/ 20 21 #define UX_SOURCE_CODE 22 23 24 /* Include necessary system files. */ 25 26 #include "ux_api.h" 27 #include "ux_device_class_audio.h" 28 #include "ux_device_stack.h" 29 30 31 /**************************************************************************/ 32 /* */ 33 /* FUNCTION RELEASE */ 34 /* */ 35 /* _ux_device_class_audio_activate PORTABLE C */ 36 /* 6.2.0 */ 37 /* AUTHOR */ 38 /* */ 39 /* Chaoqiong Xiao, Microsoft Corporation */ 40 /* */ 41 /* DESCRIPTION */ 42 /* */ 43 /* This function initializes the USB Audio device. */ 44 /* */ 45 /* INPUT */ 46 /* */ 47 /* command Pointer to audio command */ 48 /* */ 49 /* OUTPUT */ 50 /* */ 51 /* Completion Status */ 52 /* */ 53 /* CALLS */ 54 /* */ 55 /* _ux_system_error_handler System error trap */ 56 /* */ 57 /* CALLED BY */ 58 /* */ 59 /* Device Audio Class */ 60 /* */ 61 /* RELEASE HISTORY */ 62 /* */ 63 /* DATE NAME DESCRIPTION */ 64 /* */ 65 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ 66 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ 67 /* resulting in version 6.1 */ 68 /* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ 69 /* fixed parameter/variable */ 70 /* names conflict C++ keyword, */ 71 /* added interrupt support, */ 72 /* resulting in version 6.1.12 */ 73 /* 10-31-2022 Yajun Xia Modified comment(s), */ 74 /* added standalone support, */ 75 /* resulting in version 6.2.0 */ 76 /* */ 77 /**************************************************************************/ _ux_device_class_audio_activate(UX_SLAVE_CLASS_COMMAND * command)78UINT _ux_device_class_audio_activate(UX_SLAVE_CLASS_COMMAND *command) 79 { 80 81 UX_SLAVE_DEVICE *device; 82 UX_SLAVE_INTERFACE *audio_interface; 83 UX_SLAVE_INTERFACE *control_interface; 84 UX_SLAVE_INTERFACE *stream_interface; 85 UX_DEVICE_CLASS_AUDIO *audio; 86 UX_DEVICE_CLASS_AUDIO_STREAM *stream; 87 UX_SLAVE_CLASS *audio_class; 88 ULONG stream_index; 89 90 91 /* Get the class container. */ 92 audio_class = command -> ux_slave_class_command_class_ptr; 93 94 /* Get the class instance in the container. */ 95 audio = (UX_DEVICE_CLASS_AUDIO *) audio_class -> ux_slave_class_instance; 96 97 /* Get the interface that owns this instance. */ 98 audio_interface = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface; 99 100 /* Get the device instance. */ 101 device = &_ux_system_slave -> ux_system_slave_device; 102 audio -> ux_device_class_audio_device = device; 103 104 /* We only support audio interface here. */ 105 if (audio_interface -> ux_slave_interface_descriptor.bInterfaceClass != UX_DEVICE_CLASS_AUDIO_CLASS) 106 return(UX_NO_CLASS_MATCH); 107 108 /* It's control interface? */ 109 if (audio_interface -> ux_slave_interface_descriptor.bInterfaceSubClass == UX_DEVICE_CLASS_AUDIO_SUBCLASS_CONTROL) 110 { 111 112 /* Store the interface in the class instance. */ 113 audio -> ux_device_class_audio_interface = audio_interface; 114 115 /* Store the class instance into the interface. */ 116 audio_interface -> ux_slave_interface_class_instance = (VOID *)audio; 117 118 #if defined(UX_DEVICE_CLASS_AUDIO_INTERRUPT_SUPPORT) 119 120 /* Find interrupt endpoint (only endpoint in this AC interface). */ 121 audio -> ux_device_class_audio_interrupt = audio_interface -> ux_slave_interface_first_endpoint; 122 audio -> ux_device_class_audio_status_queued = 0; 123 audio -> ux_device_class_audio_status_head = audio -> ux_device_class_audio_status_queue; 124 audio -> ux_device_class_audio_status_tail = audio -> ux_device_class_audio_status_queue; 125 #endif 126 } 127 else 128 { 129 130 /* It's streaming interface. */ 131 stream_interface = audio_interface; 132 133 /* Separate driver for each interface (IAD not used)? */ 134 if (audio -> ux_device_class_audio_interface == UX_NULL) 135 { 136 137 /* Always use just 1 stream for 1 interface. */ 138 stream_index = 0; 139 } 140 141 /* Re-use the same driver (IAD used)? */ 142 else 143 { 144 145 /* Re-use saved control interface. */ 146 control_interface = audio -> ux_device_class_audio_interface; 147 148 /* Calculate stream index. */ 149 stream_index = stream_interface -> ux_slave_interface_descriptor.bInterfaceNumber; 150 stream_index -= control_interface -> ux_slave_interface_descriptor.bInterfaceNumber; 151 stream_index --; 152 153 } 154 155 /* Sanity check. */ 156 if (stream_index >= audio -> ux_device_class_audio_streams_nb) 157 { 158 159 /* Error trap! */ 160 _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_MEMORY_INSUFFICIENT); 161 return(UX_MEMORY_INSUFFICIENT); 162 } 163 164 /* Locate stream based on interface number. */ 165 stream = &audio -> ux_device_class_audio_streams[stream_index]; 166 167 /* Store the interface for the stream. */ 168 stream -> ux_device_class_audio_stream_interface = stream_interface; 169 170 /* Store the class instance into the interface. */ 171 stream_interface -> ux_slave_interface_class_instance = (VOID *)audio; 172 #if defined(UX_DEVICE_STANDALONE) 173 174 /* Reset stream task state. */ 175 stream -> ux_device_class_audio_stream_task_state = UX_STATE_RESET; 176 stream -> ux_device_class_audio_stream_task_state = UX_SUCCESS; 177 #endif 178 } 179 180 /* If there is a activate function call it. */ 181 if (audio -> ux_device_class_audio_callbacks.ux_slave_class_audio_instance_activate != UX_NULL) 182 { 183 184 /* Invoke the application. */ 185 audio -> ux_device_class_audio_callbacks.ux_slave_class_audio_instance_activate(audio); 186 } 187 188 /* Return completion status. */ 189 return(UX_SUCCESS); 190 } 191 192