xref: /haiku/src/bin/listusb/usb_audio.cpp (revision 8251b2c8f6c7bffe42318b2251bd1163d3c86326)
156f749a6SAdrien Destugues /*
256f749a6SAdrien Destugues  * Originally released under the Be Sample Code License.
356f749a6SAdrien Destugues  * Copyright 2000, Be Incorporated. All rights reserved.
456f749a6SAdrien Destugues  *
5*8251b2c8SGreg Crain  * Modified for Haiku by François Revol, Michael Lotz and Greg Crain.
6*8251b2c8SGreg Crain  * Copyright 2007-2024, Haiku Inc. All rights reserved.
756f749a6SAdrien Destugues  */
856f749a6SAdrien Destugues 
956f749a6SAdrien Destugues #include <MediaDefs.h>
1056f749a6SAdrien Destugues #include <USBKit.h>
1156f749a6SAdrien Destugues #include <stdio.h>
1256f749a6SAdrien Destugues 
1356f749a6SAdrien Destugues #include <usb/USB_audio.h>
1456f749a6SAdrien Destugues #include <usb/USB_midi.h>
1556f749a6SAdrien Destugues 
1656f749a6SAdrien Destugues #include "listusb.h"
1756f749a6SAdrien Destugues 
18*8251b2c8SGreg Crain 
1956f749a6SAdrien Destugues void
DumpClockSource(uint8 attributes)20*8251b2c8SGreg Crain DumpClockSource(uint8 attributes)
21*8251b2c8SGreg Crain {
22*8251b2c8SGreg Crain 	switch (attributes & 0x3){
23*8251b2c8SGreg Crain 	case 0:
24*8251b2c8SGreg Crain 		printf("  External clock.");
25*8251b2c8SGreg Crain 		break;
26*8251b2c8SGreg Crain 	case 1:
27*8251b2c8SGreg Crain 		printf("  Internal fixed clock.");
28*8251b2c8SGreg Crain 		break;
29*8251b2c8SGreg Crain 	case 2:
30*8251b2c8SGreg Crain 		printf("  Internal variable clock.");
31*8251b2c8SGreg Crain 		break;
32*8251b2c8SGreg Crain 	case 3:
33*8251b2c8SGreg Crain 		printf("  Internal programmable clock.");
34*8251b2c8SGreg Crain 		break;
35*8251b2c8SGreg Crain 	}
36*8251b2c8SGreg Crain 	if (attributes & 0x4){
37*8251b2c8SGreg Crain 		printf("  Clock synchronized to SOF.");
38*8251b2c8SGreg Crain 	}
39*8251b2c8SGreg Crain 	printf("\n");
40*8251b2c8SGreg Crain }
41*8251b2c8SGreg Crain 
42*8251b2c8SGreg Crain 
43*8251b2c8SGreg Crain void
DumpAudioCSInterfaceDescriptorClockSourceUnit(const usb_audio_clocksource_descriptor * descriptor)44*8251b2c8SGreg Crain DumpAudioCSInterfaceDescriptorClockSourceUnit(
45*8251b2c8SGreg Crain 	const usb_audio_clocksource_descriptor* descriptor)
46*8251b2c8SGreg Crain {
47*8251b2c8SGreg Crain 	printf("                    Length............. 0x%02x\n", descriptor->length);
48*8251b2c8SGreg Crain 	printf("                    Type .............. 0x%02x\n", descriptor->descriptor_type);
49*8251b2c8SGreg Crain 	printf("                    Subtype ........... 0x%02x (Clock Source)\n",
50*8251b2c8SGreg Crain 		descriptor->descriptor_subtype);
51*8251b2c8SGreg Crain 	printf("                    Clock ID .......... 0x%02x\n", descriptor->clock_id);
52*8251b2c8SGreg Crain 	printf("                    Attributes......... 0x%02x", descriptor->bm_attributes);
53*8251b2c8SGreg Crain 	DumpClockSource(descriptor->bm_attributes);
54*8251b2c8SGreg Crain 	printf("                    bm controls ....... 0x%02x", descriptor->bm_controls);
55*8251b2c8SGreg Crain 	if (descriptor->bm_controls & 0x3)
56*8251b2c8SGreg Crain 	 printf("  Clock Valid.");
57*8251b2c8SGreg Crain 	printf("\n");
58*8251b2c8SGreg Crain 	printf("                    Assoc Term ........ 0x%02x\n", descriptor->assoc_terminal);
59*8251b2c8SGreg Crain 	printf("                    Clock Src Idx ..... 0x%02x\n", descriptor->clock_source_idx);
60*8251b2c8SGreg Crain }
61*8251b2c8SGreg Crain 
62*8251b2c8SGreg Crain 
63*8251b2c8SGreg Crain void
DumpAudioCSInterfaceDescriptorClockSelectorUnit(const usb_audio_clockselector_descriptor * descriptor)64*8251b2c8SGreg Crain DumpAudioCSInterfaceDescriptorClockSelectorUnit(
65*8251b2c8SGreg Crain 	const usb_audio_clockselector_descriptor* descriptor)
66*8251b2c8SGreg Crain {
67*8251b2c8SGreg Crain 	printf("                    Length ............ 0x%02x\n", descriptor->length);
68*8251b2c8SGreg Crain 	printf("                    Type .............. 0x%02x\n", descriptor->descriptor_type);
69*8251b2c8SGreg Crain 	printf("                    Subtype ........... 0x%02x (Clock Selector)\n",
70*8251b2c8SGreg Crain 		descriptor->descriptor_subtype);
71*8251b2c8SGreg Crain 	printf("                    Clock ID .......... 0x%02x\n", descriptor->clock_id);
72*8251b2c8SGreg Crain 	printf("                    Num Of Input Pins .. 0x%02x\n", descriptor->nrinpins);
73*8251b2c8SGreg Crain 	printf("                    Clock Src Entity ... 0x%02x\n", descriptor->Csourceid[0]);
74*8251b2c8SGreg Crain 	printf("                    Controls ........... 0x%02x\n", descriptor->bm_controls);
75*8251b2c8SGreg Crain 	printf("                    Clock Selector...... 0x%02x\n", descriptor->clockselector);
76*8251b2c8SGreg Crain }
77*8251b2c8SGreg Crain 
78*8251b2c8SGreg Crain 
79*8251b2c8SGreg Crain void
DumpAudioCSInterfaceDescriptorClockMultiplier(const usb_audio_clockmultiplier_descriptor * descriptor)80*8251b2c8SGreg Crain DumpAudioCSInterfaceDescriptorClockMultiplier(
81*8251b2c8SGreg Crain 	const usb_audio_clockmultiplier_descriptor* descriptor)
82*8251b2c8SGreg Crain {
83*8251b2c8SGreg Crain 	printf("                    Length ............ 0x%02x\n", descriptor->length);
84*8251b2c8SGreg Crain 	printf("                    Type .............. 0x%02x\n", descriptor->descriptor_type);
85*8251b2c8SGreg Crain 	printf("                    Subtype ........... 0x%02x (Clock Multiplier)\n",
86*8251b2c8SGreg Crain 		descriptor->descriptor_subtype);
87*8251b2c8SGreg Crain 	printf("                    Clock ID .......... 0x%02x\n", descriptor->clockid);
88*8251b2c8SGreg Crain 	printf("                    Clock Src Entity ... 0x%02x\n", descriptor->clksourceid);
89*8251b2c8SGreg Crain 	printf("                    bm_controls ........ 0x%02x\n", descriptor->bm_controls);
90*8251b2c8SGreg Crain 	printf("                    Clock Multipler .... 0x%02x\n", descriptor->clockmultiplier);
91*8251b2c8SGreg Crain }
92*8251b2c8SGreg Crain 
93*8251b2c8SGreg Crain uint16
DumpAudioCSInterfaceDescriptorHeader(const usb_audiocontrol_header_descriptor * descriptor)9456f749a6SAdrien Destugues DumpAudioCSInterfaceDescriptorHeader(
9556f749a6SAdrien Destugues 	const usb_audiocontrol_header_descriptor* descriptor)
9656f749a6SAdrien Destugues {
97e6464087SAdrien Destugues 	printf("                    Type .............. 0x%02x\n",
98e6464087SAdrien Destugues 		descriptor->descriptor_type);
9956f749a6SAdrien Destugues 	printf("                    Subtype ........... 0x%02x (Header)\n",
10056f749a6SAdrien Destugues 		descriptor->descriptor_subtype);
101*8251b2c8SGreg Crain 	printf("                    Audio codec version .. %d.%d\n",
102e6464087SAdrien Destugues 		descriptor->bcd_release_no >> 8, descriptor->bcd_release_no & 0xFF);
103*8251b2c8SGreg Crain 
104*8251b2c8SGreg Crain 	if (descriptor->bcd_release_no < USB_AUDIO_CLASS_VERSION_2) {
10556f749a6SAdrien Destugues 		printf("                    Total Length ...... %u\n",
10656f749a6SAdrien Destugues 			descriptor->r1.total_length);
10756f749a6SAdrien Destugues 		printf("                    Interfaces ........ ");
10856f749a6SAdrien Destugues 
10956f749a6SAdrien Destugues 		for (uint8 i = 0; i < descriptor->r1.in_collection; i++)
11056f749a6SAdrien Destugues 			printf("%u, ", descriptor->r1.interface_numbers[i]);
11156f749a6SAdrien Destugues 		printf("\n");
112*8251b2c8SGreg Crain 	} else {
113*8251b2c8SGreg Crain 		// Audio 2.0
114*8251b2c8SGreg Crain 		printf("                    Function Category...... %u\n", descriptor->r2.function_category);
115*8251b2c8SGreg Crain 		printf("                    Total Length ...........%d\n", descriptor->r2.total_length);
116*8251b2c8SGreg Crain 		printf("                    bm Controls ............0x%02x\n", descriptor->r2.bm_controls);
117*8251b2c8SGreg Crain 	}
118*8251b2c8SGreg Crain 
119*8251b2c8SGreg Crain 	return descriptor->bcd_release_no;
12056f749a6SAdrien Destugues }
12156f749a6SAdrien Destugues 
12256f749a6SAdrien Destugues 
12356f749a6SAdrien Destugues void
DumpChannelConfig(uint32 wChannelConfig)12456f749a6SAdrien Destugues DumpChannelConfig(uint32 wChannelConfig)
12556f749a6SAdrien Destugues {
12656f749a6SAdrien Destugues 	struct _Entry {
12756f749a6SAdrien Destugues 		const char* name;
12856f749a6SAdrien Destugues 		uint32 mask;
12956f749a6SAdrien Destugues 	} aClusters[] = {
13056f749a6SAdrien Destugues 		{ "Front .......... ", B_CHANNEL_LEFT | B_CHANNEL_RIGHT
13156f749a6SAdrien Destugues 			| B_CHANNEL_CENTER },
13256f749a6SAdrien Destugues 		{ "L.F.E .......... ", B_CHANNEL_SUB },
13356f749a6SAdrien Destugues 		{ "Back ........... ", B_CHANNEL_REARLEFT | B_CHANNEL_REARRIGHT
13456f749a6SAdrien Destugues 			| B_CHANNEL_BACK_CENTER },
13556f749a6SAdrien Destugues 		{ "Center ......... ", B_CHANNEL_FRONT_LEFT_CENTER
13656f749a6SAdrien Destugues 			| B_CHANNEL_FRONT_RIGHT_CENTER },
13756f749a6SAdrien Destugues 		{ "Side ........... ", B_CHANNEL_SIDE_LEFT | B_CHANNEL_SIDE_RIGHT },
13856f749a6SAdrien Destugues 		{ "Top ............ ", B_CHANNEL_TOP_CENTER },
13956f749a6SAdrien Destugues 		{ "Top Front ...... ", B_CHANNEL_TOP_FRONT_LEFT
14056f749a6SAdrien Destugues 			| B_CHANNEL_TOP_FRONT_CENTER | B_CHANNEL_TOP_FRONT_RIGHT },
14156f749a6SAdrien Destugues 		{ "Top Back ....... ", B_CHANNEL_TOP_BACK_LEFT
14256f749a6SAdrien Destugues 			| B_CHANNEL_TOP_BACK_CENTER | B_CHANNEL_TOP_BACK_RIGHT }
14356f749a6SAdrien Destugues 	};
14456f749a6SAdrien Destugues 
14556f749a6SAdrien Destugues 	struct _Entry aChannels[] = {
14656f749a6SAdrien Destugues 		{ "Left", B_CHANNEL_LEFT | B_CHANNEL_FRONT_LEFT_CENTER
14756f749a6SAdrien Destugues 			| B_CHANNEL_REARLEFT | B_CHANNEL_SIDE_LEFT | B_CHANNEL_TOP_BACK_LEFT
14856f749a6SAdrien Destugues 			| B_CHANNEL_TOP_FRONT_LEFT },
14956f749a6SAdrien Destugues 		{ "Right", B_CHANNEL_FRONT_RIGHT_CENTER | B_CHANNEL_TOP_FRONT_RIGHT
15056f749a6SAdrien Destugues 			| B_CHANNEL_REARRIGHT | B_CHANNEL_RIGHT | B_CHANNEL_SIDE_RIGHT
15156f749a6SAdrien Destugues 			| B_CHANNEL_TOP_BACK_RIGHT },
15256f749a6SAdrien Destugues 		{ "Center", B_CHANNEL_BACK_CENTER | B_CHANNEL_CENTER
15356f749a6SAdrien Destugues 			| B_CHANNEL_TOP_BACK_CENTER | B_CHANNEL_TOP_CENTER
15456f749a6SAdrien Destugues 			| B_CHANNEL_TOP_FRONT_CENTER },
15556f749a6SAdrien Destugues 		{ "L.F.E.", B_CHANNEL_SUB }
15656f749a6SAdrien Destugues 	};
15756f749a6SAdrien Destugues 
15856f749a6SAdrien Destugues 	for (size_t i = 0; i < sizeof(aClusters) / sizeof(aClusters[0]); i++) {
15956f749a6SAdrien Destugues 		uint32 mask = aClusters[i].mask & wChannelConfig;
16056f749a6SAdrien Destugues 		if (mask != 0) {
16156f749a6SAdrien Destugues 			printf("                       %s", aClusters[i].name);
16256f749a6SAdrien Destugues 			for (size_t j = 0; j < sizeof(aChannels) / sizeof(aChannels[0]); j++)
16356f749a6SAdrien Destugues 				if ((aChannels[j].mask & mask) != 0)
16456f749a6SAdrien Destugues 					printf("%s ", aChannels[j].name);
16556f749a6SAdrien Destugues 			printf("\n");
16656f749a6SAdrien Destugues 		}
16756f749a6SAdrien Destugues 	}
16856f749a6SAdrien Destugues }
16956f749a6SAdrien Destugues 
17056f749a6SAdrien Destugues 
171e6464087SAdrien Destugues static const char*
TerminalTypeName(uint16 terminalType)17256f749a6SAdrien Destugues TerminalTypeName(uint16 terminalType)
17356f749a6SAdrien Destugues {
17456f749a6SAdrien Destugues 	switch (terminalType) {
17556f749a6SAdrien Destugues 		case USB_AUDIO_UNDEFINED_USB_IO:
17656f749a6SAdrien Destugues 			return "USB Undefined";
17756f749a6SAdrien Destugues 		case USB_AUDIO_STREAMING_USB_IO:
17856f749a6SAdrien Destugues 			return "USB Streaming";
17956f749a6SAdrien Destugues 		case USB_AUDIO_VENDOR_USB_IO:
18056f749a6SAdrien Destugues 			return "USB vendor specific";
18156f749a6SAdrien Destugues 
18256f749a6SAdrien Destugues 		case USB_AUDIO_UNDEFINED_IN:
18356f749a6SAdrien Destugues 			return "Undefined";
18456f749a6SAdrien Destugues 		case USB_AUDIO_MICROPHONE_IN:
18556f749a6SAdrien Destugues 			return "Microphone";
18656f749a6SAdrien Destugues 		case USB_AUDIO_DESKTOPMIC_IN:
18756f749a6SAdrien Destugues 			return "Desktop microphone";
18856f749a6SAdrien Destugues 		case USB_AUDIO_PERSONALMIC_IN:
18956f749a6SAdrien Destugues 			return "Personal microphone";
19056f749a6SAdrien Destugues 		case USB_AUDIO_OMNI_MIC_IN:
19156f749a6SAdrien Destugues 			return "Omni-directional microphone";
19256f749a6SAdrien Destugues 		case USB_AUDIO_MICS_ARRAY_IN:
19356f749a6SAdrien Destugues 			return "Microphone array";
19456f749a6SAdrien Destugues 		case USB_AUDIO_PROC_MICS_ARRAY_IN:
19556f749a6SAdrien Destugues 			return "Processing microphone array";
19656f749a6SAdrien Destugues 		case USB_AUDIO_LINE_CONNECTOR_IO:
19756f749a6SAdrien Destugues 			return "Line I/O";
19856f749a6SAdrien Destugues 		case USB_AUDIO_SPDIF_INTERFACE_IO:
19956f749a6SAdrien Destugues 			return "S/PDIF";
20056f749a6SAdrien Destugues 
20156f749a6SAdrien Destugues 		case USB_AUDIO_UNDEFINED_OUT:
20256f749a6SAdrien Destugues 			return "Undefined";
20356f749a6SAdrien Destugues 		case USB_AUDIO_SPEAKER_OUT:
20456f749a6SAdrien Destugues 			return "Speaker";
20556f749a6SAdrien Destugues 		case USB_AUDIO_HEAD_PHONES_OUT:
20656f749a6SAdrien Destugues 			return "Headphones";
20756f749a6SAdrien Destugues 		case USB_AUDIO_HMD_AUDIO_OUT:
20856f749a6SAdrien Destugues 			return "Head Mounted Display Audio";
20956f749a6SAdrien Destugues 		case USB_AUDIO_DESKTOP_SPEAKER:
21056f749a6SAdrien Destugues 			return "Desktop speaker";
21156f749a6SAdrien Destugues 		case USB_AUDIO_ROOM_SPEAKER:
21256f749a6SAdrien Destugues 			return "Room speaker";
21356f749a6SAdrien Destugues 		case USB_AUDIO_COMM_SPEAKER:
21456f749a6SAdrien Destugues 			return "Communication speaker";
21556f749a6SAdrien Destugues 		case USB_AUDIO_LFE_SPEAKER:
21656f749a6SAdrien Destugues 			return "Low frequency effects speaker";
21756f749a6SAdrien Destugues 
21856f749a6SAdrien Destugues 		default:
21956f749a6SAdrien Destugues 			return "Unknown";
22056f749a6SAdrien Destugues 	}
22156f749a6SAdrien Destugues }
22256f749a6SAdrien Destugues 
22356f749a6SAdrien Destugues 
22456f749a6SAdrien Destugues void
DumpAudioCSInterfaceDescriptorInputTerminal(const usb_audio_input_terminal_descriptor * descriptor,uint16 bcd_release_no)22556f749a6SAdrien Destugues DumpAudioCSInterfaceDescriptorInputTerminal(
226*8251b2c8SGreg Crain 	const usb_audio_input_terminal_descriptor* descriptor,
227*8251b2c8SGreg Crain 	 uint16 bcd_release_no)
22856f749a6SAdrien Destugues {
229*8251b2c8SGreg Crain 	printf("                    Length............. %u\n", descriptor->length);
230e6464087SAdrien Destugues 	printf("                    Type .............. 0x%02x\n",
231e6464087SAdrien Destugues 		descriptor->descriptor_type);
23256f749a6SAdrien Destugues 	printf("                    Subtype ........... 0x%02x (Input Terminal)\n",
23356f749a6SAdrien Destugues 		descriptor->descriptor_subtype);
23456f749a6SAdrien Destugues 	printf("                    Terminal ID ....... %u\n",
23556f749a6SAdrien Destugues 		descriptor->terminal_id);
23656f749a6SAdrien Destugues 	printf("                    Terminal Type ..... 0x%04x (%s)\n",
23756f749a6SAdrien Destugues 		descriptor->terminal_type,
23856f749a6SAdrien Destugues 			TerminalTypeName(descriptor->terminal_type));
23956f749a6SAdrien Destugues 	printf("                    Associated Terminal %u\n",
24056f749a6SAdrien Destugues 		descriptor->assoc_terminal);
24156f749a6SAdrien Destugues 
242*8251b2c8SGreg Crain 	if (bcd_release_no < USB_AUDIO_CLASS_VERSION_2){
243*8251b2c8SGreg Crain 		printf("                    Nr Channels ....... %u\n", descriptor->r1.num_channels);
244*8251b2c8SGreg Crain 		printf("                    Channel Config .... 0x%x\n", descriptor->r1.channel_config);
245*8251b2c8SGreg Crain 		DumpChannelConfig(descriptor->r1.channel_config);
246*8251b2c8SGreg Crain 		printf("                    Channel Names ..... %u\n", descriptor->r1.channel_names);
247*8251b2c8SGreg Crain 		printf("                    Terminal .......... %u\n", descriptor->r1.terminal);
248*8251b2c8SGreg Crain 	} else {
249*8251b2c8SGreg Crain 		// Audio 2.0
250*8251b2c8SGreg Crain 		printf("                    Clock Source ID.....0x%02x\n", descriptor->r2.clock_source_id);
251*8251b2c8SGreg Crain 		printf("                    Nr Channels ....... %u\n", descriptor->r2.num_channels);
252*8251b2c8SGreg Crain 		printf("                    Channel Config .... 0x%08" B_PRIx32 "\n",
253*8251b2c8SGreg Crain 			descriptor->r2.channel_config);
254*8251b2c8SGreg Crain 		DumpChannelConfig(descriptor->r2.channel_config);
255*8251b2c8SGreg Crain 		printf("                    Channel Names ..... %u\n", descriptor->r2.channel_names);
256*8251b2c8SGreg Crain 		printf("                    bm_controls.........0x%04x\n", descriptor->r2.bm_controls);
257*8251b2c8SGreg Crain 		printf("                    Terminal .......... %u\n", descriptor->r2.terminal);
258*8251b2c8SGreg Crain 	}
25956f749a6SAdrien Destugues }
26056f749a6SAdrien Destugues 
26156f749a6SAdrien Destugues 
26256f749a6SAdrien Destugues void
DumpAudioCSInterfaceDescriptorOutputTerminal(const usb_audio_output_terminal_descriptor * descriptor,uint16 bcd_release_no)26356f749a6SAdrien Destugues DumpAudioCSInterfaceDescriptorOutputTerminal(
264*8251b2c8SGreg Crain 	const usb_audio_output_terminal_descriptor* descriptor,
265*8251b2c8SGreg Crain 	 uint16 bcd_release_no)
26656f749a6SAdrien Destugues {
267*8251b2c8SGreg Crain 	printf("                    Length............. %u\n", descriptor->length);
268e6464087SAdrien Destugues 	printf("                    Type .............. 0x%02x\n",
269e6464087SAdrien Destugues 		descriptor->descriptor_type);
27056f749a6SAdrien Destugues 	printf("                    Subtype ........... 0x%02x (Output Terminal)\n",
27156f749a6SAdrien Destugues 		descriptor->descriptor_subtype);
27256f749a6SAdrien Destugues 	printf("                    Terminal ID ....... %u\n",
27356f749a6SAdrien Destugues 		descriptor->terminal_id);
27456f749a6SAdrien Destugues 	printf("                    Terminal Type ..... 0x%04x (%s)\n",
27556f749a6SAdrien Destugues 		descriptor->terminal_type,
27656f749a6SAdrien Destugues 			TerminalTypeName(descriptor->terminal_type));
27756f749a6SAdrien Destugues 	printf("                    Associated Terminal %u\n",
27856f749a6SAdrien Destugues 		descriptor->assoc_terminal);
279*8251b2c8SGreg Crain 	printf("                    Source ID ......... 0x%02x\n", descriptor->source_id);
280*8251b2c8SGreg Crain 
281*8251b2c8SGreg Crain 	if (bcd_release_no < USB_AUDIO_CLASS_VERSION_2) {
282*8251b2c8SGreg Crain 		printf("                    Terminal .......... %u\n", descriptor->r1.terminal);
283*8251b2c8SGreg Crain 	} else {
284*8251b2c8SGreg Crain 		// Audio 2.0
285*8251b2c8SGreg Crain 		printf("                    Clock Source ID.....0x%02x\n", descriptor->r2.clock_source_id);
286*8251b2c8SGreg Crain 		printf("                    bm_controls.........0x%04x\n", descriptor->r2.bm_controls);
287*8251b2c8SGreg Crain 		printf("                    Terminal .......... %u\n", descriptor->r2.terminal);
288*8251b2c8SGreg Crain 	}
28956f749a6SAdrien Destugues }
29056f749a6SAdrien Destugues 
29156f749a6SAdrien Destugues 
29256f749a6SAdrien Destugues void
DumpAudioCSInterfaceDescriptorMixerUnit(const usb_audio_mixer_unit_descriptor * descriptor)29356f749a6SAdrien Destugues DumpAudioCSInterfaceDescriptorMixerUnit(
29456f749a6SAdrien Destugues 	const usb_audio_mixer_unit_descriptor* descriptor)
29556f749a6SAdrien Destugues {
296*8251b2c8SGreg Crain 	printf("                    Length............. %u\n", descriptor->length);
297e6464087SAdrien Destugues 	printf("                    Type .............. 0x%02x\n",
298e6464087SAdrien Destugues 		descriptor->descriptor_type);
29956f749a6SAdrien Destugues 	printf("                    Subtype ........... 0x%02x (Mixer Unit)\n",
30056f749a6SAdrien Destugues 		descriptor->descriptor_subtype);
30156f749a6SAdrien Destugues 	printf("                    Unit ID ........... %u\n",
30256f749a6SAdrien Destugues 		descriptor->unit_id);
30356f749a6SAdrien Destugues 
30456f749a6SAdrien Destugues 	printf("                    Source IDs ........ ");
30556f749a6SAdrien Destugues 	for (uint8 i = 0; i < descriptor->num_input_pins; i++)
30656f749a6SAdrien Destugues 		printf("%u, ", descriptor->input_pins[i]);
30756f749a6SAdrien Destugues 	printf("\n");
30856f749a6SAdrien Destugues 
30956f749a6SAdrien Destugues 	usb_audio_output_channels_descriptor_r1* channels
31056f749a6SAdrien Destugues 		= (usb_audio_output_channels_descriptor_r1*)
31156f749a6SAdrien Destugues 			&descriptor->input_pins[descriptor->num_input_pins];
31256f749a6SAdrien Destugues 
31356f749a6SAdrien Destugues 	printf("                    Channels .......... %u\n",
31456f749a6SAdrien Destugues 		channels->num_output_pins);
31556f749a6SAdrien Destugues 	printf("                    Channel Config .... 0x%x\n",
31656f749a6SAdrien Destugues 			channels->channel_config);
31756f749a6SAdrien Destugues 	DumpChannelConfig(channels->channel_config);
31856f749a6SAdrien Destugues 	printf("                    Channel Names ..... %u\n",
31956f749a6SAdrien Destugues 		channels->channel_names);
32056f749a6SAdrien Destugues 
32156f749a6SAdrien Destugues 	usb_generic_descriptor* generic = (usb_generic_descriptor*)descriptor;
32256f749a6SAdrien Destugues 	uint8 idx = 7 + descriptor->num_input_pins;
32356f749a6SAdrien Destugues 		printf("                    Bitmap Control .... 0x");
32456f749a6SAdrien Destugues 	for (uint i = 1; idx < descriptor->length - 3; idx++, i++)
32556f749a6SAdrien Destugues 		printf("%02x ", (uint8)generic->data[idx]);
32656f749a6SAdrien Destugues 	printf("\n");
32756f749a6SAdrien Destugues 
32856f749a6SAdrien Destugues 	printf("                    Mixer ............. %u\n",
32956f749a6SAdrien Destugues 			generic->data[generic->length - 3]);
33056f749a6SAdrien Destugues }
33156f749a6SAdrien Destugues 
33256f749a6SAdrien Destugues 
33356f749a6SAdrien Destugues void
DumpAudioCSInterfaceDescriptorSelectorUnit(const usb_audio_selector_unit_descriptor * descriptor)33456f749a6SAdrien Destugues DumpAudioCSInterfaceDescriptorSelectorUnit(
33556f749a6SAdrien Destugues 	const usb_audio_selector_unit_descriptor* descriptor)
33656f749a6SAdrien Destugues {
337e6464087SAdrien Destugues 	printf("                    Type .............. 0x%02x\n",
338e6464087SAdrien Destugues 		descriptor->descriptor_type);
33956f749a6SAdrien Destugues 	printf("                    Subtype ........... 0x%02x (Selector Unit)\n",
34056f749a6SAdrien Destugues 		descriptor->descriptor_subtype);
34156f749a6SAdrien Destugues 	printf("                    Unit ID ........... %u\n",
34256f749a6SAdrien Destugues 		descriptor->unit_id);
34356f749a6SAdrien Destugues 
34456f749a6SAdrien Destugues 	printf("                    Source IDs ........ ");
34556f749a6SAdrien Destugues 	for (uint8 i = 0; i < descriptor->num_input_pins; i++)
34656f749a6SAdrien Destugues 		printf("%u, ", descriptor->input_pins[i]);
34756f749a6SAdrien Destugues 	printf("\n");
34856f749a6SAdrien Destugues 
34956f749a6SAdrien Destugues 	usb_generic_descriptor* generic = (usb_generic_descriptor*)descriptor;
35056f749a6SAdrien Destugues 	printf("                    Selector .......... %u\n",
35156f749a6SAdrien Destugues 		(uint8)generic->data[descriptor->num_input_pins + 2]);
35256f749a6SAdrien Destugues }
35356f749a6SAdrien Destugues 
35456f749a6SAdrien Destugues 
35556f749a6SAdrien Destugues void
DumpBMAControl(uint8 channel,uint32 bma,uint16 bcd_release_no)356*8251b2c8SGreg Crain DumpBMAControl(uint8 channel, uint32 bma, uint16 bcd_release_no)
35756f749a6SAdrien Destugues {
35856f749a6SAdrien Destugues 	const char* BMAControls[] = {
35956f749a6SAdrien Destugues 		"Mute",
36056f749a6SAdrien Destugues 		"Volume",
36156f749a6SAdrien Destugues 		"Bass",
36256f749a6SAdrien Destugues 		"Mid",
36356f749a6SAdrien Destugues 		"Treble",
36456f749a6SAdrien Destugues 		"Graphic Equalizer",
36556f749a6SAdrien Destugues 		"Automatic Gain",
36656f749a6SAdrien Destugues 		"Delay",
36756f749a6SAdrien Destugues 		"Bass Boost",
36856f749a6SAdrien Destugues 		"Loudness"
36956f749a6SAdrien Destugues 	};
37056f749a6SAdrien Destugues 
37156f749a6SAdrien Destugues 	if (bma == 0)
37256f749a6SAdrien Destugues 		return;
37356f749a6SAdrien Destugues 
37456f749a6SAdrien Destugues 	if (channel == 0)
37556f749a6SAdrien Destugues 		printf("                       Master Channel . ");
37656f749a6SAdrien Destugues 	else
37756f749a6SAdrien Destugues 		printf("                       Channel %u ...... ", channel);
37856f749a6SAdrien Destugues 
37956f749a6SAdrien Destugues 	int mask = 1;
380*8251b2c8SGreg Crain 	if (bcd_release_no < USB_AUDIO_CLASS_VERSION_2) {
38156f749a6SAdrien Destugues 	for (uint8 i = 0;
38256f749a6SAdrien Destugues 			i < sizeof(BMAControls) / sizeof(BMAControls[0]); i++, mask <<= 1)
38356f749a6SAdrien Destugues 		if (bma & mask)
38456f749a6SAdrien Destugues 			printf("%s ", BMAControls[i]);
385*8251b2c8SGreg Crain 	} else {
386*8251b2c8SGreg Crain 		// Audio 2.0
387*8251b2c8SGreg Crain 		mask = 0x3;
388*8251b2c8SGreg Crain 		for (uint8 i = 0; i < sizeof(BMAControls) / sizeof(BMAControls[0]); i++, mask <<= 2) {
389*8251b2c8SGreg Crain 			if (bma & mask) {
390*8251b2c8SGreg Crain 				printf("%s ", BMAControls[i]);
391*8251b2c8SGreg Crain 			}
392*8251b2c8SGreg Crain 		}
393*8251b2c8SGreg Crain 	}
39456f749a6SAdrien Destugues 	printf("\n");
39556f749a6SAdrien Destugues }
39656f749a6SAdrien Destugues 
39756f749a6SAdrien Destugues 
39856f749a6SAdrien Destugues void
DumpAudioCSInterfaceDescriptorFeatureUnit(const usb_audio_feature_unit_descriptor * descriptor,uint16 bcd_release_no)39956f749a6SAdrien Destugues DumpAudioCSInterfaceDescriptorFeatureUnit(
400*8251b2c8SGreg Crain 	const usb_audio_feature_unit_descriptor* descriptor,
401*8251b2c8SGreg Crain 	uint16 bcd_release_no)
40256f749a6SAdrien Destugues {
403*8251b2c8SGreg Crain 	printf("                    Length............. %u\n", descriptor->length);
404e6464087SAdrien Destugues 	printf("                    Type .............. 0x%02x\n",
405e6464087SAdrien Destugues 		descriptor->descriptor_type);
40656f749a6SAdrien Destugues 	printf("                    Subtype ........... 0x%02x (Feature Unit)\n",
40756f749a6SAdrien Destugues 		descriptor->descriptor_subtype);
40856f749a6SAdrien Destugues 	printf("                    Unit ID ........... %u\n",
40956f749a6SAdrien Destugues 			descriptor->unit_id);
410*8251b2c8SGreg Crain 	printf("                    Source ID ......... 0x%02x\n", descriptor->source_id);
41156f749a6SAdrien Destugues 
412*8251b2c8SGreg Crain 	if (bcd_release_no < USB_AUDIO_CLASS_VERSION_2) {
413*8251b2c8SGreg Crain 		printf("                    Control Size ...... %u\n", descriptor->r1.control_size);
414a1bc100aSJérôme Duval 		uint8 channels = 0;
415a1bc100aSJérôme Duval 		if (descriptor->r1.control_size > 0)
416a1bc100aSJérôme Duval 			channels = (descriptor->length - 6) / descriptor->r1.control_size;
41756f749a6SAdrien Destugues 		for (uint8 i = 0; i < channels; i++) {
41856f749a6SAdrien Destugues 			switch (descriptor->r1.control_size) {
41956f749a6SAdrien Destugues 				case 1:
420*8251b2c8SGreg Crain 					DumpBMAControl(i, descriptor->r1.bma_controls[i], bcd_release_no);
42156f749a6SAdrien Destugues 					break;
42256f749a6SAdrien Destugues 				case 2:
423*8251b2c8SGreg Crain 					DumpBMAControl(i, *(uint16*)&descriptor->r1.bma_controls[i * 2],
424*8251b2c8SGreg Crain 						bcd_release_no);
42556f749a6SAdrien Destugues 					break;
42656f749a6SAdrien Destugues 				case 4:
427*8251b2c8SGreg Crain 					DumpBMAControl(i, *(uint32*)&descriptor->r1.bma_controls[i * 4],
428*8251b2c8SGreg Crain 						bcd_release_no);
42956f749a6SAdrien Destugues 					break;
43056f749a6SAdrien Destugues 				default:
43156f749a6SAdrien Destugues 					printf("                    BMA Channel %u ... ", i);
43256f749a6SAdrien Destugues 					for (uint8 j = 0; j < descriptor->r1.control_size; j++)
43356f749a6SAdrien Destugues 						printf("%02x ", descriptor->r1.bma_controls[i + j]);
434a1bc100aSJérôme Duval 					printf("\n");
43556f749a6SAdrien Destugues 					break;
43656f749a6SAdrien Destugues 			}
437*8251b2c8SGreg Crain 			//	usb_generic_descriptor* generic = (usb_generic_descriptor*)descriptor;
438*8251b2c8SGreg Crain 			//	printf("                    Feature ........... %u\n",
439*8251b2c8SGreg Crain 			//			(uint8)generic->data[descriptor->length - 3]);
44056f749a6SAdrien Destugues 		}
441*8251b2c8SGreg Crain 	} else {
442*8251b2c8SGreg Crain 			// Audio 2.0
443*8251b2c8SGreg Crain 			printf("                    BMA Controls ....... 0x%08" B_PRIx32 "\n",
444*8251b2c8SGreg Crain 				descriptor->r2.bma_controls[0]);
445*8251b2c8SGreg Crain 			DumpBMAControl(0, descriptor->r2.bma_controls[0], bcd_release_no);
44656f749a6SAdrien Destugues 		}
447*8251b2c8SGreg Crain }
44856f749a6SAdrien Destugues 
44956f749a6SAdrien Destugues void
DumpAudioCSInterfaceDescriptorAssociated(const usb_generic_descriptor * descriptor)45056f749a6SAdrien Destugues DumpAudioCSInterfaceDescriptorAssociated(
45156f749a6SAdrien Destugues 	const usb_generic_descriptor* descriptor)
45256f749a6SAdrien Destugues {
453e6464087SAdrien Destugues 	printf("                    Type .............. 0x%02x\n",
454e6464087SAdrien Destugues 		descriptor->descriptor_type);
45556f749a6SAdrien Destugues 	printf("                    Subtype ........... 0x%02x (Associate Interface)\n",
45656f749a6SAdrien Destugues 		(uint8)descriptor->data[0]);
45756f749a6SAdrien Destugues 	printf("                    Interface ......... %u\n",
45856f749a6SAdrien Destugues 		(uint8)descriptor->data[1]);
45956f749a6SAdrien Destugues 
46056f749a6SAdrien Destugues 	printf("                    Data .............. ");
46156f749a6SAdrien Destugues 	for (uint8 i = 0; i < descriptor->length - 2; i++)
46256f749a6SAdrien Destugues 		printf("%02x ", descriptor->data[i]);
463e6464087SAdrien Destugues 	printf("\n");
46456f749a6SAdrien Destugues }
46556f749a6SAdrien Destugues 
46656f749a6SAdrien Destugues 
46756f749a6SAdrien Destugues void
DumpAudioControlCSInterfaceDescriptor(const usb_generic_descriptor * descriptor)46856f749a6SAdrien Destugues DumpAudioControlCSInterfaceDescriptor(const usb_generic_descriptor* descriptor)
46956f749a6SAdrien Destugues {
47056f749a6SAdrien Destugues 	uint8 descriptorSubtype = descriptor->data[0];
471*8251b2c8SGreg Crain 	static uint16 bcd_release_no;
472*8251b2c8SGreg Crain 
47356f749a6SAdrien Destugues 	switch (descriptorSubtype) {
47456f749a6SAdrien Destugues 		case USB_AUDIO_AC_HEADER:
475*8251b2c8SGreg Crain 			bcd_release_no = DumpAudioCSInterfaceDescriptorHeader(
47656f749a6SAdrien Destugues 				(usb_audiocontrol_header_descriptor*)descriptor);
47756f749a6SAdrien Destugues 			break;
47856f749a6SAdrien Destugues 		case USB_AUDIO_AC_INPUT_TERMINAL:
47956f749a6SAdrien Destugues 			DumpAudioCSInterfaceDescriptorInputTerminal(
480*8251b2c8SGreg Crain 				(usb_audio_input_terminal_descriptor*)descriptor, bcd_release_no);
48156f749a6SAdrien Destugues 			break;
48256f749a6SAdrien Destugues 		case USB_AUDIO_AC_OUTPUT_TERMINAL:
48356f749a6SAdrien Destugues 			DumpAudioCSInterfaceDescriptorOutputTerminal(
484*8251b2c8SGreg Crain 				(usb_audio_output_terminal_descriptor*)descriptor, bcd_release_no);
48556f749a6SAdrien Destugues 			break;
48656f749a6SAdrien Destugues 		case USB_AUDIO_AC_MIXER_UNIT:
48756f749a6SAdrien Destugues 			DumpAudioCSInterfaceDescriptorMixerUnit(
48856f749a6SAdrien Destugues 				(usb_audio_mixer_unit_descriptor*)descriptor);
48956f749a6SAdrien Destugues 			break;
49056f749a6SAdrien Destugues 		case USB_AUDIO_AC_SELECTOR_UNIT:
49156f749a6SAdrien Destugues 			DumpAudioCSInterfaceDescriptorSelectorUnit(
49256f749a6SAdrien Destugues 				(usb_audio_selector_unit_descriptor*)descriptor);
49356f749a6SAdrien Destugues 			break;
49456f749a6SAdrien Destugues 		case USB_AUDIO_AC_FEATURE_UNIT:
49556f749a6SAdrien Destugues 			DumpAudioCSInterfaceDescriptorFeatureUnit(
496*8251b2c8SGreg Crain 				(usb_audio_feature_unit_descriptor*)descriptor, bcd_release_no);
49756f749a6SAdrien Destugues 			break;
49856f749a6SAdrien Destugues 		case USB_AUDIO_AC_EXTENSION_UNIT:
499*8251b2c8SGreg Crain 			// USB_AUDIO_AC_PROCESSING_UNIT_R2 == USB_AUDIO_AC_EXTENSION_UNIT
500*8251b2c8SGreg Crain 			if (bcd_release_no < USB_AUDIO_CLASS_VERSION_2)
50156f749a6SAdrien Destugues 				DumpAudioCSInterfaceDescriptorAssociated(descriptor);
50256f749a6SAdrien Destugues 			break;
503*8251b2c8SGreg Crain 		case USB_AUDIO_AC_PROCESSING_UNIT:
504*8251b2c8SGreg Crain 			// USB_AUDIO_AC_EFFECT_UNIT_R2 == USB_AUDIO_AC_PROCESSING_UNIT
505*8251b2c8SGreg Crain 			break;
506*8251b2c8SGreg Crain 		case USB_AUDIO_AC_EXTENSION_UNIT_R2:
507*8251b2c8SGreg Crain 			break;
508*8251b2c8SGreg Crain 		case USB_AUDIO_AC_CLOCK_SOURCE_R2:
509*8251b2c8SGreg Crain 			DumpAudioCSInterfaceDescriptorClockSourceUnit(
510*8251b2c8SGreg Crain 				(usb_audio_clocksource_descriptor*)descriptor);
511*8251b2c8SGreg Crain 			break;
512*8251b2c8SGreg Crain 		case USB_AUDIO_AC_CLOCK_SELECTOR_R2:
513*8251b2c8SGreg Crain 			DumpAudioCSInterfaceDescriptorClockSelectorUnit(
514*8251b2c8SGreg Crain 				(usb_audio_clockselector_descriptor*)descriptor);
515*8251b2c8SGreg Crain 			break;
516*8251b2c8SGreg Crain 		case USB_AUDIO_AC_CLOCK_MULTIPLIER_R2:
517*8251b2c8SGreg Crain 			DumpAudioCSInterfaceDescriptorClockMultiplier(
518*8251b2c8SGreg Crain 			(usb_audio_clockmultiplier_descriptor*)descriptor);
519*8251b2c8SGreg Crain 			break;
520*8251b2c8SGreg Crain 		case USB_AUDIO_AC_SAMPLE_RATE_CONVERTER_R2:
521*8251b2c8SGreg Crain 			break;
522*8251b2c8SGreg Crain 
52356f749a6SAdrien Destugues 		default:
52456f749a6SAdrien Destugues 			DumpDescriptorData(descriptor);
52556f749a6SAdrien Destugues 	}
52656f749a6SAdrien Destugues }
52756f749a6SAdrien Destugues 
52856f749a6SAdrien Destugues 
52956f749a6SAdrien Destugues void
DumpGeneralASInterfaceDescriptor(const usb_audio_streaming_interface_descriptor * descriptor)53056f749a6SAdrien Destugues DumpGeneralASInterfaceDescriptor(
53156f749a6SAdrien Destugues 	const usb_audio_streaming_interface_descriptor* descriptor)
53256f749a6SAdrien Destugues {
53356f749a6SAdrien Destugues 	printf("                    Subtype ........... %u (AS_GENERAL)\n",
53456f749a6SAdrien Destugues 		descriptor->descriptor_subtype);
53556f749a6SAdrien Destugues 	printf("                    Terminal link ..... %u\n",
53656f749a6SAdrien Destugues 		descriptor->terminal_link);
53756f749a6SAdrien Destugues 	printf("                    Delay ............. %u\n",
53856f749a6SAdrien Destugues 		descriptor->r1.delay);
53956f749a6SAdrien Destugues 	printf("                    Format tag ........ %u\n",
54056f749a6SAdrien Destugues 		descriptor->r1.format_tag);
54156f749a6SAdrien Destugues }
54256f749a6SAdrien Destugues 
54356f749a6SAdrien Destugues 
54456f749a6SAdrien Destugues uint32
GetSamplingFrequency(const usb_audio_sampling_freq & freq)54556f749a6SAdrien Destugues GetSamplingFrequency(const usb_audio_sampling_freq& freq)
54656f749a6SAdrien Destugues {
54756f749a6SAdrien Destugues 	return freq.bytes[0] | freq.bytes[1] << 8 | freq.bytes[2] << 16;
54856f749a6SAdrien Destugues }
54956f749a6SAdrien Destugues 
55056f749a6SAdrien Destugues 
55156f749a6SAdrien Destugues void
DumpSamplingFrequencies(uint8 type,const usb_audio_sampling_freq * freqs)55256f749a6SAdrien Destugues DumpSamplingFrequencies(uint8 type, const usb_audio_sampling_freq* freqs)
55356f749a6SAdrien Destugues {
55456f749a6SAdrien Destugues 	if (type > 0) {
55556f749a6SAdrien Destugues 		printf("                    Sampling Freq ..... ");
55656f749a6SAdrien Destugues 		for (uint8 i = 0; i < type; i++)
55756f749a6SAdrien Destugues 			printf("%" B_PRIu32 ", ", GetSamplingFrequency(freqs[i]));
55856f749a6SAdrien Destugues 		printf("\n");
55956f749a6SAdrien Destugues 	} else {
56056f749a6SAdrien Destugues 		printf("                    Sampling Freq ..... %" B_PRIu32 " to %"
56156f749a6SAdrien Destugues 			B_PRIu32 "\n", GetSamplingFrequency(freqs[0]),
56256f749a6SAdrien Destugues 			GetSamplingFrequency(freqs[1]));
56356f749a6SAdrien Destugues 	}
56456f749a6SAdrien Destugues }
56556f749a6SAdrien Destugues 
56656f749a6SAdrien Destugues 
56756f749a6SAdrien Destugues void
DumpASFormatTypeI(const usb_audio_format_descriptor * descriptor)56856f749a6SAdrien Destugues DumpASFormatTypeI(const usb_audio_format_descriptor* descriptor)
56956f749a6SAdrien Destugues {
57056f749a6SAdrien Destugues 	printf("                    Subtype ........... %u (FORMAT_TYPE)\n",
57156f749a6SAdrien Destugues 		descriptor->descriptor_subtype);
57256f749a6SAdrien Destugues 	printf("                    Format Type ....... %u (FORMAT_TYPE_I)\n",
57356f749a6SAdrien Destugues 		descriptor->format_type);
57456f749a6SAdrien Destugues 	printf("                    Channels .......... %u\n",
57556f749a6SAdrien Destugues 		descriptor->typeI.nr_channels);
57656f749a6SAdrien Destugues 	printf("                    Subframe size ..... %u\n",
57756f749a6SAdrien Destugues 		descriptor->typeI.subframe_size);
57886b6d54bSAugustin Cavalier 	printf("                    Bit resolution .... %u\n",
57956f749a6SAdrien Destugues 		descriptor->typeI.bit_resolution);
58056f749a6SAdrien Destugues 
58156f749a6SAdrien Destugues 	DumpSamplingFrequencies(descriptor->typeI.sam_freq_type,
58256f749a6SAdrien Destugues 			descriptor->typeI.sam_freqs);
58356f749a6SAdrien Destugues }
58456f749a6SAdrien Destugues 
58556f749a6SAdrien Destugues 
58656f749a6SAdrien Destugues void
DumpASFormatTypeIII(const usb_audio_format_descriptor * descriptor)58756f749a6SAdrien Destugues DumpASFormatTypeIII(const usb_audio_format_descriptor* descriptor)
58856f749a6SAdrien Destugues {
58956f749a6SAdrien Destugues 	printf("                    Subtype ........... %u (FORMAT_TYPE)\n",
59056f749a6SAdrien Destugues 		descriptor->descriptor_subtype);
59156f749a6SAdrien Destugues 	printf("                    Format Type ....... %u (FORMAT_TYPE_III)\n",
59256f749a6SAdrien Destugues 		descriptor->format_type);
59356f749a6SAdrien Destugues 	printf("                    Channels .......... %u\n",
59456f749a6SAdrien Destugues 		descriptor->typeIII.nr_channels);
59556f749a6SAdrien Destugues 	printf("                    Subframe size ..... %u\n",
59656f749a6SAdrien Destugues 		descriptor->typeIII.subframe_size);
59786b6d54bSAugustin Cavalier 	printf("                    Bit resolution .... %u\n",
59856f749a6SAdrien Destugues 		descriptor->typeIII.bit_resolution);
59956f749a6SAdrien Destugues 
60056f749a6SAdrien Destugues 	DumpSamplingFrequencies(descriptor->typeIII.sam_freq_type,
60156f749a6SAdrien Destugues 			descriptor->typeIII.sam_freqs);
60256f749a6SAdrien Destugues }
60356f749a6SAdrien Destugues 
60456f749a6SAdrien Destugues 
60556f749a6SAdrien Destugues void
DumpASFormatTypeII(const usb_audio_format_descriptor * descriptor)60656f749a6SAdrien Destugues DumpASFormatTypeII(const usb_audio_format_descriptor* descriptor)
60756f749a6SAdrien Destugues {
60856f749a6SAdrien Destugues 	printf("                    Subtype ........... %u (FORMAT_TYPE)\n",
60956f749a6SAdrien Destugues 		descriptor->descriptor_subtype);
61056f749a6SAdrien Destugues 	printf("                    Format Type ....... %u (FORMAT_TYPE_II)\n",
61156f749a6SAdrien Destugues 		descriptor->format_type);
61256f749a6SAdrien Destugues 	printf("                    Max Bitrate ....... %u\n",
61356f749a6SAdrien Destugues 		descriptor->typeII.max_bit_rate);
61456f749a6SAdrien Destugues 	printf("                    Samples per Frame . %u\n",
61556f749a6SAdrien Destugues 		descriptor->typeII.samples_per_frame);
61656f749a6SAdrien Destugues 
61756f749a6SAdrien Destugues 	DumpSamplingFrequencies(descriptor->typeII.sam_freq_type,
61856f749a6SAdrien Destugues 			descriptor->typeII.sam_freqs);
61956f749a6SAdrien Destugues }
62056f749a6SAdrien Destugues 
62156f749a6SAdrien Destugues 
62256f749a6SAdrien Destugues void
DumpASFmtType(const usb_audio_format_descriptor * descriptor)62356f749a6SAdrien Destugues DumpASFmtType(const usb_audio_format_descriptor* descriptor)
62456f749a6SAdrien Destugues {
62556f749a6SAdrien Destugues 	uint8 format = descriptor->format_type;
62656f749a6SAdrien Destugues 	switch (format) {
62756f749a6SAdrien Destugues 		case USB_AUDIO_FORMAT_TYPE_I:
62856f749a6SAdrien Destugues 			DumpASFormatTypeI(descriptor);
62956f749a6SAdrien Destugues 			break;
63056f749a6SAdrien Destugues 		case USB_AUDIO_FORMAT_TYPE_II:
63156f749a6SAdrien Destugues 			DumpASFormatTypeII(descriptor);
63256f749a6SAdrien Destugues 			break;
63356f749a6SAdrien Destugues 		case USB_AUDIO_FORMAT_TYPE_III:
63456f749a6SAdrien Destugues 			DumpASFormatTypeIII(descriptor);
63556f749a6SAdrien Destugues 			break;
63656f749a6SAdrien Destugues 		default:
63756f749a6SAdrien Destugues 			DumpDescriptorData((usb_generic_descriptor*)descriptor);
63856f749a6SAdrien Destugues 			break;
63956f749a6SAdrien Destugues 	}
64056f749a6SAdrien Destugues }
64156f749a6SAdrien Destugues 
64256f749a6SAdrien Destugues 
64356f749a6SAdrien Destugues void
DumpMPEGCapabilities(uint16 capabilities)64456f749a6SAdrien Destugues DumpMPEGCapabilities(uint16 capabilities)
64556f749a6SAdrien Destugues {
64656f749a6SAdrien Destugues 	const char* MPEGCapabilities[] = {
64756f749a6SAdrien Destugues 		"Layer I",
64856f749a6SAdrien Destugues 		"Layer II",
64956f749a6SAdrien Destugues 		"Layer III",
65056f749a6SAdrien Destugues 
65156f749a6SAdrien Destugues 		"MPEG-1 only",
65256f749a6SAdrien Destugues 		"MPEG-1 dual-channel",
65356f749a6SAdrien Destugues 		"MPEG-2 second stereo",
65456f749a6SAdrien Destugues 		"MPEG-2 7.1 channel augumentation",
65556f749a6SAdrien Destugues 		"Adaptive multi-channel predicion"
65656f749a6SAdrien Destugues 	};
65756f749a6SAdrien Destugues 
65856f749a6SAdrien Destugues 	uint16 mask = 1;
65956f749a6SAdrien Destugues 	for (uint8 i = 0;
66056f749a6SAdrien Destugues 			i < sizeof(MPEGCapabilities) / sizeof(MPEGCapabilities[0]); i++) {
66156f749a6SAdrien Destugues 		if (capabilities & mask)
66256f749a6SAdrien Destugues 			printf("                         %s\n", MPEGCapabilities[i]);
66356f749a6SAdrien Destugues 		mask <<= 1;
66456f749a6SAdrien Destugues 	}
66556f749a6SAdrien Destugues 
66656f749a6SAdrien Destugues 	mask = 0x300; // bits 8 and 9
66756f749a6SAdrien Destugues 	uint16 multilingualSupport = (capabilities & mask) >> 8;
66856f749a6SAdrien Destugues 	switch (multilingualSupport) {
66956f749a6SAdrien Destugues 		case 0:
67056f749a6SAdrien Destugues 			printf("                         No Multilingual support\n");
67156f749a6SAdrien Destugues 			break;
67256f749a6SAdrien Destugues 		case 1:
67356f749a6SAdrien Destugues 			printf("                         Supported at Fs\n");
67456f749a6SAdrien Destugues 			break;
67556f749a6SAdrien Destugues 		case 3:
67656f749a6SAdrien Destugues 			printf("                         Supported at Fs and 1/2Fs\n");
67756f749a6SAdrien Destugues 			break;
67856f749a6SAdrien Destugues 		default:
67956f749a6SAdrien Destugues 			break;
68056f749a6SAdrien Destugues 	}
68156f749a6SAdrien Destugues }
68256f749a6SAdrien Destugues 
68356f749a6SAdrien Destugues 
68456f749a6SAdrien Destugues void
DumpMPEGFeatures(uint8 features)68556f749a6SAdrien Destugues DumpMPEGFeatures(uint8 features)
68656f749a6SAdrien Destugues {
68756f749a6SAdrien Destugues 	uint8 mask = 0x30; // bits 4 and 5
68856f749a6SAdrien Destugues 	uint8 dynRangeControl = (features & mask) >> 4;
68956f749a6SAdrien Destugues 	switch (dynRangeControl) {
69056f749a6SAdrien Destugues 		case 0:
69156f749a6SAdrien Destugues 			printf("                         Not supported\n");
69256f749a6SAdrien Destugues 			break;
69356f749a6SAdrien Destugues 		case 1:
69456f749a6SAdrien Destugues 			printf("                         Supported, not scalable\n");
69556f749a6SAdrien Destugues 			break;
69656f749a6SAdrien Destugues 		case 2:
69756f749a6SAdrien Destugues 			printf("                         Scalable, common boost, "
69856f749a6SAdrien Destugues 				"cut scaling value\n");
69956f749a6SAdrien Destugues 			break;
70056f749a6SAdrien Destugues 		case 3:
70156f749a6SAdrien Destugues 			printf("                         Scalable, separate boost, "
70256f749a6SAdrien Destugues 				"cut scaling value\n");
70356f749a6SAdrien Destugues 		default:
70456f749a6SAdrien Destugues 			break;
70556f749a6SAdrien Destugues 	}
70656f749a6SAdrien Destugues }
70756f749a6SAdrien Destugues 
70856f749a6SAdrien Destugues 
70956f749a6SAdrien Destugues void
DumpASFmtSpecificMPEG(const usb_generic_descriptor * descriptor)71056f749a6SAdrien Destugues DumpASFmtSpecificMPEG(const usb_generic_descriptor* descriptor)
71156f749a6SAdrien Destugues {
71256f749a6SAdrien Destugues 	printf("                    Subtype ........... %u (FORMAT_SPECIFIC)\n",
71356f749a6SAdrien Destugues 		descriptor->data[0]);
71456f749a6SAdrien Destugues 	printf("                    Format Tag ........ %u\n",
71556f749a6SAdrien Destugues 		*(uint16*)&descriptor->data[1]);
71656f749a6SAdrien Destugues 	printf("                    MPEG Capabilities . %u\n",
71756f749a6SAdrien Destugues 		*(uint16*)&descriptor->data[3]);
71856f749a6SAdrien Destugues 	DumpMPEGCapabilities(*(uint16*)&descriptor->data[3]);
71956f749a6SAdrien Destugues 	printf("                    MPEG Features ..... %u\n",
72056f749a6SAdrien Destugues 		descriptor->data[5]);
72156f749a6SAdrien Destugues 	DumpMPEGFeatures(descriptor->data[5]);
72256f749a6SAdrien Destugues }
72356f749a6SAdrien Destugues 
72456f749a6SAdrien Destugues 
72556f749a6SAdrien Destugues void
DumpAC_3Features(uint8 features)72656f749a6SAdrien Destugues DumpAC_3Features(uint8 features)
72756f749a6SAdrien Destugues {
72856f749a6SAdrien Destugues 	const char* featuresStr[] = {
72956f749a6SAdrien Destugues 		"RF mode",
73056f749a6SAdrien Destugues 		"Line mode",
73156f749a6SAdrien Destugues 		"Custom0 mode",
73256f749a6SAdrien Destugues 		"Custom1 mode"
73356f749a6SAdrien Destugues 	};
73456f749a6SAdrien Destugues 
73556f749a6SAdrien Destugues 	uint8 mask = 1;
73656f749a6SAdrien Destugues 	for (uint8 i = 0; i < sizeof(featuresStr) / sizeof(const char*); i++) {
73756f749a6SAdrien Destugues 		if (features & mask)
73856f749a6SAdrien Destugues 			printf("                         %s\n", featuresStr[i]);
73956f749a6SAdrien Destugues 		mask <<= 1;
74056f749a6SAdrien Destugues 	}
74156f749a6SAdrien Destugues 
74256f749a6SAdrien Destugues 	mask = 0x30; // bits 4 and 5
74356f749a6SAdrien Destugues 	uint8 dynRangeControl = (features & mask) >> 4;
74456f749a6SAdrien Destugues 	switch (dynRangeControl) {
74556f749a6SAdrien Destugues 		case 0:
74656f749a6SAdrien Destugues 			printf("                         Not supported\n");
74756f749a6SAdrien Destugues 			break;
74856f749a6SAdrien Destugues 		case 1:
74956f749a6SAdrien Destugues 			printf("                         Supported, not scalable\n");
75056f749a6SAdrien Destugues 			break;
75156f749a6SAdrien Destugues 		case 2:
75256f749a6SAdrien Destugues 			printf("                         Scalable, common boost, "
75356f749a6SAdrien Destugues 				"cut scaling value\n");
75456f749a6SAdrien Destugues 			break;
75556f749a6SAdrien Destugues 		case 3:
75656f749a6SAdrien Destugues 			printf("                         Scalable, separate boost, "
75756f749a6SAdrien Destugues 				"cut scaling value\n");
75856f749a6SAdrien Destugues 		default:
75956f749a6SAdrien Destugues 			break;
76056f749a6SAdrien Destugues 	}
76156f749a6SAdrien Destugues }
76256f749a6SAdrien Destugues 
76356f749a6SAdrien Destugues 
76456f749a6SAdrien Destugues void
DumpASFmtSpecificAC_3(const usb_generic_descriptor * descriptor)76556f749a6SAdrien Destugues DumpASFmtSpecificAC_3(const usb_generic_descriptor* descriptor)
76656f749a6SAdrien Destugues {
76756f749a6SAdrien Destugues 	printf("                    Subtype ........... %u (FORMAT_TYPE)\n",
76856f749a6SAdrien Destugues 		descriptor->data[0]);
76956f749a6SAdrien Destugues 	printf("                    Format Tag ........ %u\n",
77056f749a6SAdrien Destugues 		*(uint16*)&descriptor->data[1]);
77156f749a6SAdrien Destugues 	printf("                    BSID .............. %" B_PRIx32 "\n",
77256f749a6SAdrien Destugues 		*(uint32*)&descriptor->data[2]);
77356f749a6SAdrien Destugues 	printf("                    AC3 Features ...... %u\n",
77456f749a6SAdrien Destugues 		descriptor->data[6]);
77556f749a6SAdrien Destugues 	DumpAC_3Features(descriptor->data[6]);
77656f749a6SAdrien Destugues }
77756f749a6SAdrien Destugues 
77856f749a6SAdrien Destugues 
77956f749a6SAdrien Destugues void
DumpASFmtSpecific(const usb_generic_descriptor * descriptor)78056f749a6SAdrien Destugues DumpASFmtSpecific(const usb_generic_descriptor* descriptor)
78156f749a6SAdrien Destugues {
78256f749a6SAdrien Destugues 	enum {
78356f749a6SAdrien Destugues 		TYPE_II_UNDEFINED = 0x1000,
78456f749a6SAdrien Destugues 		MPEG =				0x1001,
78556f749a6SAdrien Destugues 		AC_3 =				0x1002
78656f749a6SAdrien Destugues 	};
78756f749a6SAdrien Destugues 
78856f749a6SAdrien Destugues 	uint16 formatTag = *(uint16*)&descriptor->data[1];
78956f749a6SAdrien Destugues 	switch (formatTag) {
79056f749a6SAdrien Destugues 		case MPEG:
79156f749a6SAdrien Destugues 			DumpASFmtSpecificMPEG(descriptor);
79256f749a6SAdrien Destugues 			break;
79356f749a6SAdrien Destugues 		case AC_3:
79456f749a6SAdrien Destugues 			DumpASFmtSpecificAC_3(descriptor);
79556f749a6SAdrien Destugues 			break;
79656f749a6SAdrien Destugues 		default:
79756f749a6SAdrien Destugues 			DumpDescriptorData(descriptor);
79856f749a6SAdrien Destugues 			break;
79956f749a6SAdrien Destugues 	}
80056f749a6SAdrien Destugues }
80156f749a6SAdrien Destugues 
80256f749a6SAdrien Destugues 
80356f749a6SAdrien Destugues void
DumpAudioStreamCSInterfaceDescriptor(const usb_generic_descriptor * descriptor)80456f749a6SAdrien Destugues DumpAudioStreamCSInterfaceDescriptor(const usb_generic_descriptor* descriptor)
80556f749a6SAdrien Destugues {
80656f749a6SAdrien Destugues 	uint8 subtype = descriptor->data[0];
80756f749a6SAdrien Destugues 	switch (subtype) {
80856f749a6SAdrien Destugues 		case USB_AUDIO_AS_GENERAL:
80956f749a6SAdrien Destugues 			DumpGeneralASInterfaceDescriptor(
81056f749a6SAdrien Destugues 				(usb_audio_streaming_interface_descriptor*)descriptor);
81156f749a6SAdrien Destugues 			break;
81256f749a6SAdrien Destugues 		case USB_AUDIO_AS_FORMAT_TYPE:
81356f749a6SAdrien Destugues 			DumpASFmtType(
81456f749a6SAdrien Destugues 				(usb_audio_format_descriptor*)descriptor);
81556f749a6SAdrien Destugues 			break;
81656f749a6SAdrien Destugues 		case USB_AUDIO_AS_FORMAT_SPECIFIC:
81756f749a6SAdrien Destugues 			DumpASFmtSpecific(descriptor);
81856f749a6SAdrien Destugues 			break;
81956f749a6SAdrien Destugues 		default:
82056f749a6SAdrien Destugues 			DumpDescriptorData(descriptor);
82156f749a6SAdrien Destugues 			break;
82256f749a6SAdrien Destugues 	}
82356f749a6SAdrien Destugues }
82456f749a6SAdrien Destugues 
82556f749a6SAdrien Destugues 
82656f749a6SAdrien Destugues void
DumpAudioStreamCSEndpointDescriptor(const usb_audio_streaming_endpoint_descriptor * descriptor)82756f749a6SAdrien Destugues DumpAudioStreamCSEndpointDescriptor(
82856f749a6SAdrien Destugues 	const usb_audio_streaming_endpoint_descriptor* descriptor)
82956f749a6SAdrien Destugues {
83056f749a6SAdrien Destugues 	printf("                    Type .............. 0x%02x (CS_ENDPOINT)\n",
83156f749a6SAdrien Destugues 		descriptor->descriptor_type);
83256f749a6SAdrien Destugues 	printf("                    Subtype ........... 0x%02x (EP_GENERAL)\n",
83356f749a6SAdrien Destugues 		descriptor->descriptor_subtype);
83456f749a6SAdrien Destugues 	printf("                    Attributes ........ 0x%02x ",
83556f749a6SAdrien Destugues 		descriptor->attributes);
83656f749a6SAdrien Destugues 
83756f749a6SAdrien Destugues 	const char* attributes[] = {
83856f749a6SAdrien Destugues 		"Sampling Frequency",
83956f749a6SAdrien Destugues 		"Pitch",
84056f749a6SAdrien Destugues 		"", "", "", "", "",
84156f749a6SAdrien Destugues 		"Max Packet Only"
84256f749a6SAdrien Destugues 	};
84356f749a6SAdrien Destugues 
84456f749a6SAdrien Destugues 	uint8 mask = 1;
84556f749a6SAdrien Destugues 	for (uint8 i = 0; i < sizeof(attributes) / sizeof(attributes[0]); i++) {
84656f749a6SAdrien Destugues 		if ((descriptor->attributes & mask) != 0)
84756f749a6SAdrien Destugues 			printf("%s ", attributes[i]);
84856f749a6SAdrien Destugues 		mask <<= 1;
84956f749a6SAdrien Destugues 	}
85056f749a6SAdrien Destugues 	printf("\n");
85156f749a6SAdrien Destugues 
85256f749a6SAdrien Destugues 	const char* aUnits[] = {
85356f749a6SAdrien Destugues 		"Undefined",
85456f749a6SAdrien Destugues 		"Milliseconds",
85556f749a6SAdrien Destugues 		"Decoded PCM samples",
85656f749a6SAdrien Destugues 		"Unknown (%u)"
85756f749a6SAdrien Destugues 	};
85856f749a6SAdrien Destugues 
85956f749a6SAdrien Destugues 	const char* units = descriptor->lock_delay_units >= 4
86056f749a6SAdrien Destugues 		? aUnits[3] : aUnits[descriptor->lock_delay_units];
86156f749a6SAdrien Destugues 
86256f749a6SAdrien Destugues 	printf("                    Lock Delay Units .. %u (%s)\n",
86356f749a6SAdrien Destugues 		descriptor->lock_delay_units, units);
86456f749a6SAdrien Destugues 	printf("                    Lock Delay ........ %u\n",
86556f749a6SAdrien Destugues 		descriptor->lock_delay);
86656f749a6SAdrien Destugues }
86756f749a6SAdrien Destugues 
86856f749a6SAdrien Destugues 
86956f749a6SAdrien Destugues void
DumpMidiInterfaceHeaderDescriptor(const usb_midi_interface_header_descriptor * descriptor)87056f749a6SAdrien Destugues DumpMidiInterfaceHeaderDescriptor(
87156f749a6SAdrien Destugues 	const usb_midi_interface_header_descriptor* descriptor)
87256f749a6SAdrien Destugues {
87356f749a6SAdrien Destugues 	printf("                    Type .............. 0x%02x (CS_ENDPOINT)\n",
87456f749a6SAdrien Destugues 		descriptor->descriptor_type);
87556f749a6SAdrien Destugues 	printf("                    Subtype ........... 0x%02x (MS_HEADER)\n",
87656f749a6SAdrien Destugues 		descriptor->descriptor_subtype);
87756f749a6SAdrien Destugues 	printf("                    MSC Version ....... 0x%04x\n",
87856f749a6SAdrien Destugues 		descriptor->ms_version);
87956f749a6SAdrien Destugues 	printf("                    Length ............ 0x%04x\n",
88056f749a6SAdrien Destugues 		descriptor->total_length);
88156f749a6SAdrien Destugues }
88256f749a6SAdrien Destugues 
88356f749a6SAdrien Destugues 
88456f749a6SAdrien Destugues void
DumpMidiInJackDescriptor(const usb_midi_in_jack_descriptor * descriptor)88556f749a6SAdrien Destugues DumpMidiInJackDescriptor(
88656f749a6SAdrien Destugues 	const usb_midi_in_jack_descriptor* descriptor)
88756f749a6SAdrien Destugues {
88856f749a6SAdrien Destugues 	printf("                    Type .............. 0x%02x (CS_INTERFACE)\n",
88956f749a6SAdrien Destugues 		descriptor->descriptor_type);
89056f749a6SAdrien Destugues 	printf("                    Subtype ........... 0x%02x (MIDI_IN_JACK)\n",
89156f749a6SAdrien Destugues 		descriptor->descriptor_subtype);
89256f749a6SAdrien Destugues 	printf("                    Jack ID ........... 0x%02x\n",
89356f749a6SAdrien Destugues 		descriptor->id);
89456f749a6SAdrien Destugues 	// TODO can we get the string?
89556f749a6SAdrien Destugues 	printf("                    String ............ 0x%02x\n",
89656f749a6SAdrien Destugues 		descriptor->string_descriptor);
89756f749a6SAdrien Destugues 
89856f749a6SAdrien Destugues 	switch (descriptor->type) {
89956f749a6SAdrien Destugues 		case USB_MIDI_EMBEDDED_JACK:
90056f749a6SAdrien Destugues 			printf("                    Jack Type ......... Embedded\n");
90156f749a6SAdrien Destugues 			break;
90256f749a6SAdrien Destugues 		case USB_MIDI_EXTERNAL_JACK:
90356f749a6SAdrien Destugues 			printf("                    Jack Type ......... External\n");
90456f749a6SAdrien Destugues 			break;
90556f749a6SAdrien Destugues 		default:
90656f749a6SAdrien Destugues 			printf("                    Jack Type ......... 0x%02x (unknown)\n",
90756f749a6SAdrien Destugues 				descriptor->type);
90856f749a6SAdrien Destugues 			break;
90956f749a6SAdrien Destugues 	}
91056f749a6SAdrien Destugues }
91156f749a6SAdrien Destugues 
91256f749a6SAdrien Destugues 
91356f749a6SAdrien Destugues void
DumpMidiOutJackDescriptor(const usb_midi_out_jack_descriptor * descriptor)91456f749a6SAdrien Destugues DumpMidiOutJackDescriptor(
91556f749a6SAdrien Destugues 	const usb_midi_out_jack_descriptor* descriptor)
91656f749a6SAdrien Destugues {
91756f749a6SAdrien Destugues 	printf("                    Type .............. 0x%02x (CS_INTERFACE)\n",
91856f749a6SAdrien Destugues 		descriptor->descriptor_type);
91956f749a6SAdrien Destugues 	printf("                    Subtype ........... 0x%02x (MIDI_OUT_JACK)\n",
92056f749a6SAdrien Destugues 		descriptor->descriptor_subtype);
92156f749a6SAdrien Destugues 	printf("                    Jack ID ........... 0x%02x\n",
92256f749a6SAdrien Destugues 		descriptor->id);
92356f749a6SAdrien Destugues 
92456f749a6SAdrien Destugues 	switch (descriptor->type) {
92556f749a6SAdrien Destugues 		case USB_MIDI_EMBEDDED_JACK:
92656f749a6SAdrien Destugues 			printf("                    Jack Type ......... Embedded\n");
92756f749a6SAdrien Destugues 			break;
92856f749a6SAdrien Destugues 		case USB_MIDI_EXTERNAL_JACK:
92956f749a6SAdrien Destugues 			printf("                    Jack Type ......... External\n");
93056f749a6SAdrien Destugues 			break;
93156f749a6SAdrien Destugues 		default:
93256f749a6SAdrien Destugues 			printf("                    Jack Type ......... 0x%02x (unknown)\n",
93356f749a6SAdrien Destugues 				descriptor->type);
93456f749a6SAdrien Destugues 			break;
93556f749a6SAdrien Destugues 	}
93656f749a6SAdrien Destugues 
93756f749a6SAdrien Destugues 	for (int i = 0; i < descriptor->inputs_count; i++) {
93856f749a6SAdrien Destugues 		printf("                    Pin %02d ............ (%d,%d)\n", i,
93956f749a6SAdrien Destugues 			descriptor->input_source[i].source_id,
94056f749a6SAdrien Destugues 			descriptor->input_source[i].source_pin);
94156f749a6SAdrien Destugues 	}
94256f749a6SAdrien Destugues }
94356f749a6SAdrien Destugues 
94456f749a6SAdrien Destugues 
94556f749a6SAdrien Destugues void
DumpMidiStreamCSInterfaceDescriptor(const usb_generic_descriptor * descriptor)94656f749a6SAdrien Destugues DumpMidiStreamCSInterfaceDescriptor(const usb_generic_descriptor* descriptor)
94756f749a6SAdrien Destugues {
94856f749a6SAdrien Destugues 	uint8 subtype = descriptor->data[0];
94956f749a6SAdrien Destugues 	switch (subtype) {
95056f749a6SAdrien Destugues 		case USB_MS_HEADER_DESCRIPTOR:
95156f749a6SAdrien Destugues 			DumpMidiInterfaceHeaderDescriptor(
95256f749a6SAdrien Destugues 				(usb_midi_interface_header_descriptor*)descriptor);
95356f749a6SAdrien Destugues 			break;
95456f749a6SAdrien Destugues 		case USB_MS_MIDI_IN_JACK_DESCRIPTOR:
95556f749a6SAdrien Destugues 			DumpMidiInJackDescriptor(
95656f749a6SAdrien Destugues 				(usb_midi_in_jack_descriptor*)descriptor);
95756f749a6SAdrien Destugues 			break;
95856f749a6SAdrien Destugues 		case USB_MS_MIDI_OUT_JACK_DESCRIPTOR:
95956f749a6SAdrien Destugues 			DumpMidiOutJackDescriptor(
96056f749a6SAdrien Destugues 				(usb_midi_out_jack_descriptor*)descriptor);
96156f749a6SAdrien Destugues 			break;
96256f749a6SAdrien Destugues 		case USB_MS_ELEMENT_DESCRIPTOR:
96356f749a6SAdrien Destugues 			// TODO
96456f749a6SAdrien Destugues 			DumpDescriptorData(descriptor);
96556f749a6SAdrien Destugues 			break;
96656f749a6SAdrien Destugues 		default:
96756f749a6SAdrien Destugues 			DumpDescriptorData(descriptor);
96856f749a6SAdrien Destugues 			break;
96956f749a6SAdrien Destugues 	}
97056f749a6SAdrien Destugues }
97156f749a6SAdrien Destugues 
97256f749a6SAdrien Destugues 
97356f749a6SAdrien Destugues void
DumpMidiStreamCSEndpointDescriptor(const usb_midi_endpoint_descriptor * descriptor)97456f749a6SAdrien Destugues DumpMidiStreamCSEndpointDescriptor(
97556f749a6SAdrien Destugues 	const usb_midi_endpoint_descriptor* descriptor)
97656f749a6SAdrien Destugues {
97756f749a6SAdrien Destugues 	printf("                    Type .............. 0x%02x (CS_ENDPOINT)\n",
97856f749a6SAdrien Destugues 		descriptor->descriptor_type);
97956f749a6SAdrien Destugues 	printf("                    Subtype ........... 0x%02x (MS_GENERAL)\n",
98056f749a6SAdrien Destugues 		descriptor->descriptor_subtype);
98156f749a6SAdrien Destugues 	printf("                    Jacks ............. ");
98256f749a6SAdrien Destugues 
98356f749a6SAdrien Destugues 	for (int i = 0; i < descriptor->jacks_count; i++)
98456f749a6SAdrien Destugues 		printf("%d, ", descriptor->jacks_id[i]);
98556f749a6SAdrien Destugues 
98656f749a6SAdrien Destugues 	printf("\n");
98756f749a6SAdrien Destugues }
98856f749a6SAdrien Destugues 
98956f749a6SAdrien Destugues 
99056f749a6SAdrien Destugues void
DumpAudioStreamInterfaceDescriptor(const usb_interface_descriptor * descriptor)99156f749a6SAdrien Destugues DumpAudioStreamInterfaceDescriptor(const usb_interface_descriptor* descriptor)
99256f749a6SAdrien Destugues {
99356f749a6SAdrien Destugues 	printf("                    Type .............. %u (INTERFACE)\n",
99456f749a6SAdrien Destugues 		descriptor->descriptor_type);
99556f749a6SAdrien Destugues 	printf("                    Interface ........... %u\n",
99656f749a6SAdrien Destugues 		descriptor->interface_number);
99756f749a6SAdrien Destugues 	printf("                    Alternate setting ... %u\n",
99856f749a6SAdrien Destugues 		descriptor->alternate_setting);
99956f749a6SAdrien Destugues 	printf("                    Endpoints ........... %u\n",
100056f749a6SAdrien Destugues 		descriptor->num_endpoints);
100156f749a6SAdrien Destugues 	printf("                    Interface class ..... %u (AUDIO)\n",
100256f749a6SAdrien Destugues 		descriptor->interface_class);
100356f749a6SAdrien Destugues 	printf("                    Interface subclass .. %u (AUDIO_STREAMING)\n",
100456f749a6SAdrien Destugues 		descriptor->interface_subclass);
100556f749a6SAdrien Destugues 	printf("                    Interface ........... %u\n",
100656f749a6SAdrien Destugues 		descriptor->interface);
100756f749a6SAdrien Destugues }
100856f749a6SAdrien Destugues 
100956f749a6SAdrien Destugues 
101056f749a6SAdrien Destugues void
DumpAudioDescriptor(const usb_generic_descriptor * descriptor,int subclass)101156f749a6SAdrien Destugues DumpAudioDescriptor(const usb_generic_descriptor* descriptor, int subclass)
101256f749a6SAdrien Destugues {
101356f749a6SAdrien Destugues 	const uint8 USB_AUDIO_INTERFACE = 0x04;
101456f749a6SAdrien Destugues 
101556f749a6SAdrien Destugues 	switch (subclass) {
101656f749a6SAdrien Destugues 		case USB_AUDIO_INTERFACE_AUDIOCONTROL_SUBCLASS:
101756f749a6SAdrien Destugues 			switch (descriptor->descriptor_type) {
101856f749a6SAdrien Destugues 				case USB_AUDIO_CS_INTERFACE:
101956f749a6SAdrien Destugues 					DumpAudioControlCSInterfaceDescriptor(descriptor);
102056f749a6SAdrien Destugues 					break;
102156f749a6SAdrien Destugues 				default:
102256f749a6SAdrien Destugues 					DumpDescriptorData(descriptor);
102356f749a6SAdrien Destugues 					break;
102456f749a6SAdrien Destugues 			}
102556f749a6SAdrien Destugues 			break;
102656f749a6SAdrien Destugues 		case USB_AUDIO_INTERFACE_AUDIOSTREAMING_SUBCLASS:
102756f749a6SAdrien Destugues 			switch (descriptor->descriptor_type) {
102856f749a6SAdrien Destugues 				case USB_AUDIO_INTERFACE:
102956f749a6SAdrien Destugues 					DumpAudioStreamInterfaceDescriptor(
103056f749a6SAdrien Destugues 						(const usb_interface_descriptor*)descriptor);
103156f749a6SAdrien Destugues 					break;
103256f749a6SAdrien Destugues 				case USB_AUDIO_CS_INTERFACE:
103356f749a6SAdrien Destugues 					DumpAudioStreamCSInterfaceDescriptor(descriptor);
103456f749a6SAdrien Destugues 					break;
103556f749a6SAdrien Destugues 				case USB_AUDIO_CS_ENDPOINT:
103656f749a6SAdrien Destugues 					DumpAudioStreamCSEndpointDescriptor(
103756f749a6SAdrien Destugues 						(const usb_audio_streaming_endpoint_descriptor*)descriptor);
103856f749a6SAdrien Destugues 					break;
103956f749a6SAdrien Destugues 				default:
104056f749a6SAdrien Destugues 					DumpDescriptorData(descriptor);
104156f749a6SAdrien Destugues 					break;
104256f749a6SAdrien Destugues 			}
104356f749a6SAdrien Destugues 			break;
104456f749a6SAdrien Destugues 		case USB_AUDIO_INTERFACE_MIDISTREAMING_SUBCLASS:
104556f749a6SAdrien Destugues 			switch (descriptor->descriptor_type) {
104656f749a6SAdrien Destugues 				case USB_AUDIO_CS_INTERFACE:
104756f749a6SAdrien Destugues 					DumpMidiStreamCSInterfaceDescriptor(descriptor);
104856f749a6SAdrien Destugues 					break;
104956f749a6SAdrien Destugues 				case USB_AUDIO_CS_ENDPOINT:
105056f749a6SAdrien Destugues 					DumpMidiStreamCSEndpointDescriptor(
105156f749a6SAdrien Destugues 						(const usb_midi_endpoint_descriptor*)descriptor);
105256f749a6SAdrien Destugues 					break;
105356f749a6SAdrien Destugues 				default:
105456f749a6SAdrien Destugues 					DumpDescriptorData(descriptor);
105556f749a6SAdrien Destugues 					break;
105656f749a6SAdrien Destugues 			}
105756f749a6SAdrien Destugues 			break;
105856f749a6SAdrien Destugues 		default:
105956f749a6SAdrien Destugues 			DumpDescriptorData(descriptor);
106056f749a6SAdrien Destugues 			break;
106156f749a6SAdrien Destugues 	}
106256f749a6SAdrien Destugues }
1063