Blame SOURCES/0008-lsusb-Add-support-for-audio-processing-unit-type-spe.patch

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