31 UAC_INFO_T *uac_info = (UAC_INFO_T *)audev->
priv;
43 hdr = (AC_IF_HDR_T *)buffer;
45 if (ifp->bInterfaceSubClass == SUBCLS_AUDIOCONTROL)
47 switch (hdr->bDescriptorSubtype)
49 case AC_DESCRIPTOR_UNDEFINED:
50 USBAS_DBGMSG(
"AC: AC_DESCRIPTOR_UNDEFINED\n");
54 USBAS_DBGMSG(
"AC: HEADER\n");
58 USBAS_DBGMSG(
"AC: INPUT_TERMINAL\n");
59 ac_itd = (AC_IT_T *)buffer;
60 if (ac_itd->wTerminalType == UAC_TT_USB_STREAMING)
62 USBAS_DBGMSG(
"SPEAKER USB streaming terminal found, ID=0x%x\n", ac_itd->bTerminalID);
63 uac_info->it_usbs = ac_itd;
65 else if ((ac_itd->wTerminalType & 0x200) == 0x200)
67 USBAS_DBGMSG(
"MICROPHONE input terminal found, ID=0x%x\n", ac_itd->bTerminalID);
68 uac_info->it_microphone = ac_itd;
72 USBAS_DBGMSG(
"Unsupported INPUT TERMINAL, ignore it!\n");
74 USBAS_DBGMSG(
" bTerminalID: 0%x\n", ac_itd->bTerminalID);
75 USBAS_DBGMSG(
" wTerminalType: 0%x\n", ac_itd->wTerminalType);
76 USBAS_DBGMSG(
" bAssocTerminal: 0%x\n", ac_itd->bAssocTerminal);
77 USBAS_DBGMSG(
" bNrChannels: 0%x\n", ac_itd->bNrChannels);
78 USBAS_DBGMSG(
" wChannelConfig: 0%x\n", ac_itd->wChannelConfig);
82 USBAS_DBGMSG(
"AC: OUTPUT_TERMINAL\n");
83 ac_otd = (AC_OT_T *)buffer;
84 if (ac_otd->wTerminalType == UAC_TT_USB_STREAMING)
86 USBAS_DBGMSG(
"MICROPHONE USB streaming terminal found, ID=0x%x\n", ac_otd->bTerminalID);
87 uac_info->ot_usbs = ac_otd;
89 else if ((ac_otd->wTerminalType & 0x300) == 0x300)
91 USBAS_DBGMSG(
"SPEAKER output terminal found, ID=0x%x\n", ac_otd->bTerminalID);
92 uac_info->ot_speaker = ac_otd;
96 USBAS_DBGMSG(
"Unsupported OUTPUT TERMINAL, ignore it!\n");
98 USBAS_DBGMSG(
" bTerminalID: 0%x\n", ac_otd->bTerminalID);
99 USBAS_DBGMSG(
" wTerminalType: 0%x\n", ac_otd->wTerminalType);
100 USBAS_DBGMSG(
" bAssocTerminal: 0%x\n", ac_otd->bAssocTerminal);
101 USBAS_DBGMSG(
" bSourceID: 0%x\n", ac_otd->bSourceID);
105 USBAS_DBGMSG(
"AC: MIXER_UNIT\n");
107 ac_mxr = (AC_MXR_T *)buffer;
108 USBAS_DBGMSG(
" bUnitID: 0%x\n", ac_mxr->bUnitID);
109 USBAS_DBGMSG(
" bNrInPins: 0%x\n", ac_mxr->bNrInPins);
114 USBAS_DBGMSG(
"AC: SELECTOR_UNIT\n");
116 ac_su = (AC_SU_T *)buffer;
117 USBAS_DBGMSG(
" bUnitID: 0%x\n", ac_su->bUnitID);
118 USBAS_DBGMSG(
" bNrInPins: 0%x\n", ac_su->bNrInPins);
123 USBAS_DBGMSG(
"AC: FEATURE_UNIT\n");
126 funit[fu_cnt] = (AC_FU_T *)buffer;
131 USBAS_ERRMSG(
"Too many FEATURE UNITs, information may be lost!\n");
134 ac_fu = (AC_FU_T *)buffer;
135 USBAS_DBGMSG(
" bUnitID: 0%x\n", ac_fu->bUnitID);
136 USBAS_DBGMSG(
" bSourceID: 0%x\n", ac_fu->bSourceID);
137 USBAS_DBGMSG(
" bControlSize: 0%x\n", ac_fu->bControlSize);
141 case PROCESSING_UNIT:
142 USBAS_DBGMSG(
"AC: PROCESSING_UNIT\n");
144 ac_pu = (AC_PU_T *)buffer;
145 USBAS_DBGMSG(
" bUnitID: 0%x\n", ac_pu->bUnitID);
146 USBAS_DBGMSG(
" wProcessType: 0%x\n", ac_pu->wProcessType);
147 USBAS_DBGMSG(
" bNrInPins: 0%x\n", ac_pu->bNrInPins);
152 USBAS_DBGMSG(
"AC: EXTENSION_UNIT\n");
157 if (ifp->bInterfaceSubClass == SUBCLS_AUDIOSTREAMING)
159 switch (hdr->bDescriptorSubtype)
161 case AS_DESCRIPTOR_UNDEFINED:
162 USBAS_DBGMSG(
"AS: AS_DESCRIPTOR_UNDEFINED\n");
166 USBAS_DBGMSG(
"AS: AS_GENERAL\n");
167 as_gen = (AS_GEN_T *)hdr;
168 uac_info->last_gen = as_gen;
169 USBAS_DBGMSG(
" bTerminalLink: 0%x\n", as_gen->bTerminalLink);
170 USBAS_DBGMSG(
" wFormatTag: 0%x\n", as_gen->wFormatTag);
174 uac_info->last_ft = (AC_FT1_T *)hdr;
175 USBAS_DBGMSG(
"AS: FORMAT_TYPE\n");
178 case FORMAT_SPECIFIC:
179 USBAS_DBGMSG(
"AS: FORMAT_SPECIFIC\n");
188static int uac_parse_interface(
UAC_DEV_T *audev, uint8_t *buffer,
int size)
190 UAC_INFO_T * uac_info = (UAC_INFO_T *)audev->
priv;
191 USB_DESC_HDR_T * header=
NULL;
194 int retval, parsed = 0;
198 while (size >=
sizeof(USB_DESC_HDR_T))
200 header = (USB_DESC_HDR_T *)buffer;
202 if (header->bLength < 2)
204 USBAS_DBGMSG(
"Invalid descriptor length of %d\n", header->bLength);
209 if ((header->bDescriptorType == USB_DT_INTERFACE) ||
210 (header->bDescriptorType == USB_DT_ENDPOINT) ||
211 (header->bDescriptorType == USB_DT_CONFIG) ||
212 (header->bDescriptorType == USB_DT_DEVICE) ||
213 (header->bDescriptorType == CS_INTERFACE) ||
214 (header->bDescriptorType == CS_ENDPOINT))
217 USBAS_DBGMSG(
"IF skipping descriptor 0x%X\n", header->bDescriptorType);
218 buffer += header->bLength;
219 parsed += header->bLength;
220 size -= header->bLength;
223 if (header->bDescriptorType == USB_DT_INTERFACE)
227 USBAS_DBGMSG(
"DT_INTERFACE\n");
228 USBAS_DBGMSG(
" bInterfaceNumber: %d\n", ifp->bInterfaceNumber);
230 uac_info->last_ifd = ifp;
233 buffer += ifp->bLength;
234 parsed += ifp->bLength;
235 size -= ifp->bLength;
237 else if (header->bDescriptorType == CS_INTERFACE)
239 retval = uac_parse_cs_interface(audev, uac_info->last_ifd, buffer, size);
247 else if (header->bDescriptorType == CS_ENDPOINT)
249 USBAS_DBGMSG(
"CS_ENDPOINT\n");
250 buffer += header->bLength;
251 parsed += header->bLength;
252 size -= header->bLength;
254 else if (header->bDescriptorType == USB_DT_ENDPOINT)
257 USBAS_DBGMSG(
"USB_DT_ENDPOINT\n");
258 USBAS_DBGMSG(
" bEndpointAddress: 0x%x, %s\n", ep->bEndpointAddress, (ep->bEndpointAddress & 0x80) ?
"IN" :
"OUT");
259 USBAS_DBGMSG(
" wMaxPacketSize: %d\n", ep->wMaxPacketSize);
260 USBAS_DBGMSG(
" bInterval: %d\n", ep->bInterval);
262 if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_ISOC)
264 if (ep->bEndpointAddress & 0x80)
268 USBAS_ERRMSG(
"IN endpoint packet size is larger than AU_IN_MAX_PKTSZ setting!\n");
271 uac_info->ifd_rec = uac_info->last_ifd;
272 uac_info->epd_rec = ep;
273 uac_info->gen_rec = uac_info->last_gen;
274 if ((uac_info->last_ft->bFormatType == FORMAT_TYPE_I) ||
275 (uac_info->last_ft->bFormatType == FORMAT_TYPE_III))
276 uac_info->ft_rec = uac_info->last_ft;
282 USBAS_ERRMSG(
"OUT endpoint packet size is larger than AU_OUT_MAX_PKTSZ setting!\n");
285 uac_info->ifd_play = uac_info->last_ifd;
286 uac_info->epd_play = ep;
287 uac_info->gen_play = uac_info->last_gen;
288 if ((uac_info->last_ft->bFormatType == FORMAT_TYPE_I) ||
289 (uac_info->last_ft->bFormatType == FORMAT_TYPE_III))
290 uac_info->ft_play = uac_info->last_ft;
294 buffer += header->bLength;
295 parsed += header->bLength;
296 size -= header->bLength;
300 USBAS_DBGMSG(
"Unexpected error occurred on parsing interface descriptor!\n");
312 UAC_INFO_T *uac_info = (UAC_INFO_T *)audev->
priv;
314 USB_DESC_HDR_T *header;
316 int i, length, size, result;
318 buffer = (uint8_t *)uac_info->cfg_desc;
322 USBAS_DBGMSG(
"\n\n");
323 USBAS_DBGMSG(
"+------------------------------+\n");
324 USBAS_DBGMSG(
"| UAC descriptor parser |\n");
325 USBAS_DBGMSG(
"+------------------------------+\n");
338 length = config->wTotalLength;
341 USBAS_ERRMSG(
"The Configuration descriptor of Audio Class device is too large.\n");
342 USBAS_ERRMSG(
"Please enlarge MAX_CFG_DESC_SIZE in usbh_uac.h to be larger than %d.\n", length);
348 if (result != length)
350 USBAS_DBGMSG(
"Failed to get configuration descriptor!\n");
359 buffer = (uint8_t *)uac_info->cfg_desc;
360 buffer += config->bLength;
361 size = config->wTotalLength - config->bLength;
363 for (i = 0; i < config->bNumInterfaces; i++)
367 while (size >=
sizeof(USB_DESC_HDR_T))
369 header = (USB_DESC_HDR_T *)buffer;
371 if ((header->bLength > size) || (header->bLength < 2))
373 USBAS_DBGMSG(
"Error - invalid descriptor length of %d\n", header->bLength);
379 if ((header->bDescriptorType == USB_DT_ENDPOINT) ||
380 (header->bDescriptorType == USB_DT_INTERFACE) ||
381 (header->bDescriptorType == USB_DT_CONFIG) ||
382 (header->bDescriptorType == USB_DT_DEVICE) ||
383 (header->bDescriptorType == CS_INTERFACE) ||
384 (header->bDescriptorType == CS_ENDPOINT))
387 USBAS_DBGMSG(
"CFG skipping descriptor 0x%X\n", header->bDescriptorType);
389 buffer += header->bLength;
390 size -= header->bLength;
393 result = uac_parse_interface(audev, buffer, size);
401 if ((uac_info->gen_play ==
NULL) && (uac_info->gen_rec ==
NULL))
403 USBAS_ERRMSG(
"Audio stream interface not found!\n");
407 for (i = 0; i < fu_cnt; i++)
409 if (funit[i]->bSourceID == uac_info->it_microphone->bTerminalID)
411 uac_info->fu_rec = funit[i];
416 for (i = 0; i < fu_cnt; i++)
418 if (funit[i]->bUnitID == uac_info->ot_speaker->bSourceID)
420 uac_info->fu_play = funit[i];
425 if (uac_info->fu_play)
426 USBAS_DBGMSG(
"FEATURE UNIT for playback is 0x%x\n", uac_info->fu_play->bUnitID);
428 if (uac_info->fu_rec)
429 USBAS_DBGMSG(
"FEATURE UNIT for record is 0x%x\n", uac_info->fu_rec->bUnitID);
435int uac_check_fu_ctrl(UAC_INFO_T *uac_info, uint8_t target,
int channel,
int control)
447 fu = uac_info->fu_play;
448 ft = uac_info->ft_play;
452 fu = uac_info->fu_rec;
453 ft = uac_info->ft_rec;
461 if (channel > ft->bNrChannels)
464 bptr = (uint8_t *)fu + 6 + fu->bControlSize * (channel - 1);
466 if (fu->bControlSize == 1)
469 bitmap = *bptr | (*(bptr+1) << 8);
471 USBAS_DBGMSG(
"channel %d bmaControl is 0x%x\n", channel, bitmap);
473 if (bitmap & (1 << (control-1)))
NUC472/NUC442 peripheral access layer header file. This file contains all the peripheral register's d...
#define UAC_RET_DEV_NOT_SUPPORTED
#define UAC_RET_DRV_NOT_SUPPORTED
#define MAX_CFG_DESC_SIZE
int32_t USBH_GetDescriptor(USB_DEV_T *dev, uint8_t type, uint8_t index, void *buf, int size)
Get a descriptor from device.
HIDDEN_SYMBOLS struct usb_device USB_DEV_T
#define NULL
NULL pointer.
USB Host core driver header file.