Blob Blame History Raw
From e5b6d24c5de9039606953bf8159f94ea6611e84d Mon Sep 17 00:00:00 2001
From: Michael Drake <michael.drake@codethink.co.uk>
Date: Thu, 7 Jun 2018 11:40:30 +0100
Subject: [PATCH 8/9] lsusb: Add support for audio processing unit
 type-specific fields.

Previously the data was rendered as hex as a "Process-specific"
array type field.  Now the data is interpreted properly as
descriptor fields.

Signed-off-by: Michael Drake <michael.drake@codethink.co.uk>
---
 desc-defs.c | 177 +++++++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 159 insertions(+), 18 deletions(-)

diff --git a/desc-defs.c b/desc-defs.c
index 60cc603..d348abc 100644
--- a/desc-defs.c
+++ b/desc-defs.c
@@ -16,6 +16,15 @@
 /** Macro for computing number of elements in array. */
 #define ARRAY_LEN(a) ((sizeof(a)) / (sizeof(a[0])))
 
+/**
+ * Undefined descriptor
+ *
+ * Ensures remaining data is dumped as garbage at end of descriptor.
+ */
+const struct desc desc_undefined[] = {
+	{ .field = NULL }
+};
+
 /** USB Audio Device Class 1 Channel Names.  (Note: Order matters.) */
 static const char * const uac1_channel_names[] = {
 	"Left Front (L)", "Right Front (R)", "Center Front (C)",
@@ -401,10 +410,38 @@ const struct desc * const desc_audio_ac_selector_unit[3] = {
 	desc_audio_3_ac_selector_unit,
 };
 
+/** UAC1: Table A-7: Processing Unit Process Types */
+static const char * const uac1_proc_unit_types[] = {
+	[0] = "Undefined",
+	[1] = "Up/Down-mix",
+	[2] = "Dolby Prologic",
+	[3] = "3D Stereo Extender",
+	[4] = "Reverberation",
+	[5] = "Chorus",
+	[6] = "Dyn Range Comp",
+	[7] = NULL
+};
+
+/** UAC1: Up/Down-mix and Dolby Prologic proc unit descriptor extensions Table 4-9, Table 4-10. */
+static const struct desc desc_audio_1_ac_proc_unit_extended[] = {
+	{ .field = "bNrModes",         .size = 1, .type = DESC_NUMBER },
+	{ .field = "waModes",          .size = 2, .type = DESC_BITMAP,
+			.array = { .array = true, .length_field1 = "bNrModes" } },
+	{ .field = NULL }
+};
+
+/** UAC1: Table A-7: Processing Unit Process Types */
+static const struct desc_ext desc_audio_1_ac_proc_unit_specific[] = {
+	{ .type = 1, .desc = desc_audio_1_ac_proc_unit_extended },
+	{ .type = 2, .desc = desc_audio_1_ac_proc_unit_extended },
+	{ .desc = NULL }
+};
+
 /** UAC1: 4.3.2.6 Processing Unit Descriptor; Table 4-8. */
 static const struct desc desc_audio_1_ac_processing_unit[] = {
 	{ .field = "bUnitID",          .size = 1, .type = DESC_NUMBER },
-	{ .field = "wProcessType",     .size = 2, .type = DESC_CONSTANT },
+	{ .field = "wProcessType",     .size = 2, .type = DESC_NUMBER_STRINGS,
+			.number_strings = uac1_proc_unit_types },
 	{ .field = "bNrInPins",        .size = 1, .type = DESC_NUMBER },
 	{ .field = "baSourceID",       .size = 1, .type = DESC_NUMBER,
 			.array = { .array = true, .length_field1 = "bNrInPins" } },
@@ -416,15 +453,48 @@ static const struct desc desc_audio_1_ac_processing_unit[] = {
 	{ .field = "bmControls",       .size = 1, .type = DESC_BITMAP,
 			.array = { .array = true, .length_field1 = "bControlSize" } },
 	{ .field = "iProcessing",      .size = 1, .type = DESC_STR_DESC_INDEX },
-	{ .field = "Process-specific", .size = 1, .type = DESC_BITMAP,
-			.array = { .array = true } },
+	{ .field = "Process-specific", .size = 1, .type = DESC_EXTENSION,
+		.extension = { .type_field = "wProcessType", .d = desc_audio_1_ac_proc_unit_specific } },
+	{ .field = NULL }
+};
+
+/** UAC2: 4.7.2.11.1 Up/Down-mix Processing Unit Descriptor; Table 4-21. */
+static const struct desc desc_audio_2_ac_proc_unit_up_down_mix[] = {
+	{ .field = "bNrModes",         .size = 1, .type = DESC_NUMBER },
+	{ .field = "daModes",          .size = 4, .type = DESC_BITMAP,
+			.array = { .array = true, .length_field1 = "bNrModes" } },
+	{ .field = NULL }
+};
+
+/** UAC2: 4.7.2.11.2 Dolby prologic Processing Unit Descriptor; Table 4-22. */
+static const struct desc desc_audio_2_ac_proc_unit_dolby_prologic[] = {
+	{ .field = "bNrModes",         .size = 1, .type = DESC_NUMBER },
+	{ .field = "daModes",          .size = 4, .type = DESC_BITMAP,
+			.array = { .array = true, .length_field1 = "bNrModes" } },
 	{ .field = NULL }
 };
 
+/** UAC2: Table A-12: Processing Unit Process Types */
+static const struct desc_ext desc_audio_2_ac_proc_unit_specific[] = {
+	{ .type = 1, .desc = desc_audio_2_ac_proc_unit_up_down_mix },
+	{ .type = 2, .desc = desc_audio_2_ac_proc_unit_dolby_prologic },
+	{ .desc = NULL }
+};
+
+/** UAC2: Table A-12: Processing Unit Process Types */
+static const char * const uac2_proc_unit_types[] = {
+	[0] = "Undefined",
+	[1] = "Up/Down-mix",
+	[2] = "Dolby Prologic",
+	[3] = "Stereo Extender",
+	[4] = NULL
+};
+
 /** UAC2: 4.7.2.11 Processing Unit Descriptor; Table 4-20. */
 static const struct desc desc_audio_2_ac_processing_unit[] = {
 	{ .field = "bUnitID",          .size = 1, .type = DESC_NUMBER },
-	{ .field = "wProcessType",     .size = 2, .type = DESC_CONSTANT },
+	{ .field = "wProcessType",     .size = 2, .type = DESC_NUMBER_STRINGS,
+			.number_strings = uac2_proc_unit_types },
 	{ .field = "bNrInPins",        .size = 1, .type = DESC_NUMBER },
 	{ .field = "baSourceID",       .size = 1, .type = DESC_NUMBER,
 			.array = { .array = true, .length_field1 = "bNrInPins" } },
@@ -432,34 +502,105 @@ static const struct desc desc_audio_2_ac_processing_unit[] = {
 	{ .field = "bmChannelConfig",  .size = 4, .type = DESC_BITMAP_STRINGS,
 			.bitmap_strings = { .strings = uac2_channel_names, .count = 26 } },
 	{ .field = "iChannelNames",    .size = 1, .type = DESC_STR_DESC_INDEX },
-	{ .field = "bControlSize",     .size = 1, .type = DESC_NUMBER },
-	{ .field = "bmControls",       .size = 2, .type = DESC_BITMAP,
-			.array = { .array = true, .length_field1 = "bControlSize" } },
+	{ .field = "bmControls",       .size = 2, .type = DESC_BITMAP },
 	{ .field = "iProcessing",      .size = 1, .type = DESC_STR_DESC_INDEX },
-	{ .field = "Process-specific", .size = 1, .type = DESC_BITMAP,
-			.array = { .array = true } },
+	{ .field = "Process-specific", .size = 1, .type = DESC_EXTENSION,
+		.extension = { .type_field = "wProcessType", .d = desc_audio_2_ac_proc_unit_specific } },
 	{ .field = NULL }
 };
 
-/**
- * Undefined descriptor
- *
- * Ensures remaining data is dumped as garbage at end of descriptor.
- */
-const struct desc desc_undefined[] = {
+/** Processor unit Up/Down-mix bmControls; Human readable bit meanings. */
+static const char * const uac3_proc_unit_up_down_mix_bmcontrols[] = {
+	[0] = "Mode Select",
+	[1] = "Underflow",
+	[2] = "Overflow",
+	[3] = NULL
+};
+
+/** UAC3: 4.5.2.10.1 Up/Down-mix Processing Unit Descriptor; Table 4-39. */
+static const struct desc desc_audio_3_ac_proc_unit_up_down_mix[] = {
+	{ .field = "bmControls",       .size = 4, .type = DESC_BMCONTROL_2,
+			.bmcontrol = uac3_proc_unit_up_down_mix_bmcontrols },
+	{ .field = "bNrModes",         .size = 1, .type = DESC_NUMBER },
+	{ .field = "waClusterDescrID", .size = 2, .type = DESC_NUMBER,
+			.array = { .array = true, .length_field1 = "bNrModes" } },
+	{ .field = NULL }
+};
+
+/** Processor unit stereo extender bmControls; Human readable bit meanings. */
+static const char * const uac3_proc_unit_stereo_extender_bmcontrols[] = {
+	[0] = "Width",
+	[1] = "Underflow",
+	[2] = "Overflow",
+	[3] = NULL
+};
+
+/** UAC3: 4.5.2.10.2 Stereo Extender Processing Unit Descriptor; Table 4-40. */
+static const struct desc desc_audio_3_ac_proc_unit_stereo_extender[] = {
+	{ .field = "bmControls", .size = 4, .type = DESC_BMCONTROL_2,
+			.bmcontrol = uac3_proc_unit_stereo_extender_bmcontrols },
+	{ .field = NULL }
+};
+
+/** UAC3: 4.5.2.10.3 Multi Func Proc Unit Descriptor; Algorithms; Table 4-41. */
+static const char *uac3_proc_unit_multi_func_algorithms[] = {
+	[0] = "Algorithm Undefined.",
+	[1] = "Beam Forming.",
+	[2] = "Acoustic Echo Cancellation.",
+	[3] = "Active Noise Cancellation.",
+	[4] = "Blind Source Separation.",
+	[5] = "Noise Suppression/Reduction.",
+	[6] = NULL
+};
+
+/** Processor unit Multi Func bmControls; Human readable bit meanings. */
+static const char * const uac3_proc_unit_multi_func_bmcontrols[] = {
+	[0] = "Underflow",
+	[1] = "Overflow",
+	[2] = NULL
+};
+
+/** UAC3: 4.5.2.10.3 Multi Function Processing Unit Descriptor; Table 4-41. */
+static const struct desc desc_audio_3_ac_proc_unit_multi_function[] = {
+	{ .field = "bmControls",       .size = 4, .type = DESC_BMCONTROL_2,
+			.bmcontrol = uac3_proc_unit_multi_func_bmcontrols },
+	{ .field = "wClusterDescrID",  .size = 2, .type = DESC_NUMBER, },
+	{ .field = "bmAlgorithms", .size = 4, .type = DESC_BITMAP_STRINGS,
+			.bitmap_strings = {
+				.strings = uac3_proc_unit_multi_func_algorithms,
+				.count = 6
+			} },
 	{ .field = NULL }
 };
 
+/** UAC3: Table A-20: Processing Unit Process Types */
+static const char * const uac3_proc_unit_types[] = {
+	[0] = "Undefined",
+	[1] = "Up/Down-mix",
+	[2] = "Stereo Extender",
+	[3] = "Multi-Function",
+	[4] = NULL
+};
+
+/** UAC3: Table A-20: Processing Unit Process Types */
+static const struct desc_ext desc_audio_3_ac_proc_unit_specific[] = {
+	{ .type = 1, .desc = desc_audio_3_ac_proc_unit_up_down_mix },
+	{ .type = 2, .desc = desc_audio_3_ac_proc_unit_stereo_extender },
+	{ .type = 3, .desc = desc_audio_3_ac_proc_unit_multi_function },
+	{ .desc = NULL }
+};
+
 /** UAC3: 4.5.2.10 Processing Unit Descriptor; Table 4-38. */
 static const struct desc desc_audio_3_ac_processing_unit[] = {
 	{ .field = "bUnitID",             .size = 1, .type = DESC_NUMBER },
-	{ .field = "wProcessType",        .size = 2, .type = DESC_CONSTANT },
+	{ .field = "wProcessType",        .size = 2, .type = DESC_NUMBER_STRINGS,
+			.number_strings = uac3_proc_unit_types },
 	{ .field = "bNrInPins",           .size = 1, .type = DESC_NUMBER },
 	{ .field = "baSourceID",          .size = 1, .type = DESC_NUMBER,
 			.array = { .array = true, .length_field1 = "bNrInPins" } },
 	{ .field = "wProcessingDescrStr", .size = 2, .type = DESC_CS_STR_DESC_ID },
-	{ .field = "Process-specific",    .size = 1, .type = DESC_BITMAP,
-			.array = { .array = true } },
+	{ .field = "Process-specific",    .size = 1, .type = DESC_EXTENSION,
+		.extension = { .type_field = "wProcessType", .d = desc_audio_3_ac_proc_unit_specific } },
 	{ .field = NULL }
 };
 
-- 
2.14.4