UAC1 and UAC2 have different different meanings for the same subtype
value. This splits the subtype mapping out.
---
lsusb.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 79 insertions(+), 21 deletions(-)
diff --git a/lsusb.c b/lsusb.c
index f611f2e..c35d92e 100644
--- a/lsusb.c
+++ b/lsusb.c
@@ -1000,8 +1000,85 @@ static const char * const chconfig_uac2[] = {
"Back Left of Center (BLC)", "Back Right of Center (BRC)"
};
+/* USB Audio Class subtypes */
+enum uac_interface_subtype {
+ UAC_INTERFACE_SUBTYPE_AC_DESCRIPTOR_UNDEFINED = 0x00,
+ UAC_INTERFACE_SUBTYPE_HEADER = 0x01,
+ UAC_INTERFACE_SUBTYPE_INPUT_TERMINAL = 0x02,
+ UAC_INTERFACE_SUBTYPE_OUTPUT_TERMINAL = 0x03,
+ UAC_INTERFACE_SUBTYPE_EXTENDED_TERMINAL = 0x04,
+ UAC_INTERFACE_SUBTYPE_MIXER_UNIT = 0x05,
+ UAC_INTERFACE_SUBTYPE_SELECTOR_UNIT = 0x06,
+ UAC_INTERFACE_SUBTYPE_FEATURE_UNIT = 0x07,
+ UAC_INTERFACE_SUBTYPE_EFFECT_UNIT = 0x08,
+ UAC_INTERFACE_SUBTYPE_PROCESSING_UNIT = 0x09,
+ UAC_INTERFACE_SUBTYPE_EXTENSION_UNIT = 0x0a,
+ UAC_INTERFACE_SUBTYPE_CLOCK_SOURCE = 0x0b,
+ UAC_INTERFACE_SUBTYPE_CLOCK_SELECTOR = 0x0c,
+ UAC_INTERFACE_SUBTYPE_CLOCK_MULTIPLIER = 0x0d,
+ UAC_INTERFACE_SUBTYPE_SAMPLE_RATE_CONVERTER = 0x0e,
+ UAC_INTERFACE_SUBTYPE_CONNECTORS = 0x0f,
+ UAC_INTERFACE_SUBTYPE_POWER_DOMAIN = 0x10,
+};
+
+
+/*
+ * UAC1, and UAC2 define bDescriptorSubtype differently for the
+ * AudioControl interface, so we need to do some ugly remapping:
+ *
+ * val | UAC1 | UAC2
+ * -----|-----------------|----------------------
+ * 0x00 | AC UNDEFINED | AC UNDEFINED
+ * 0x01 | HEADER | HEADER
+ * 0x02 | INPUT_TERMINAL | INPUT_TERMINAL
+ * 0x03 | OUTPUT_TERMINAL | OUTPUT_TERMINAL
+ * 0x04 | MIXER_UNIT | MIXER_UNIT
+ * 0x05 | SELECTOR_UNIT | SELECTOR_UNIT
+ * 0x06 | FEATURE_UNIT | FEATURE_UNIT
+ * 0x07 | PROCESSING_UNIT | EFFECT_UNIT
+ * 0x08 | EXTENSION_UNIT | PROCESSING_UNIT
+ * 0x09 | - | EXTENSION_UNIT
+ * 0x0a | - | CLOCK_SOURCE
+ * 0x0b | - | CLOCK_SELECTOR
+ * 0x0c | - | CLOCK_MULTIPLIER
+ * 0x0d | - | SAMPLE_RATE_CONVERTER
+ */
+static enum uac_interface_subtype get_uac_interface_subtype(unsigned char c,
int protocol)
+{
+ switch (protocol) {
+ case USB_AUDIO_CLASS_1:
+ switch(c) {
+ case 0x04: return UAC_INTERFACE_SUBTYPE_MIXER_UNIT;
+ case 0x05: return UAC_INTERFACE_SUBTYPE_SELECTOR_UNIT;
+ case 0x06: return UAC_INTERFACE_SUBTYPE_FEATURE_UNIT;
+ case 0x07: return UAC_INTERFACE_SUBTYPE_PROCESSING_UNIT;
+ case 0x08: return UAC_INTERFACE_SUBTYPE_EXTENSION_UNIT;
+ }
+ break;
+ case USB_AUDIO_CLASS_2:
+ switch(c) {
+ case 0x04: return UAC_INTERFACE_SUBTYPE_MIXER_UNIT;
+ case 0x05: return UAC_INTERFACE_SUBTYPE_SELECTOR_UNIT;
+ case 0x06: return UAC_INTERFACE_SUBTYPE_FEATURE_UNIT;
+ case 0x07: return UAC_INTERFACE_SUBTYPE_EFFECT_UNIT;
+ case 0x08: return UAC_INTERFACE_SUBTYPE_PROCESSING_UNIT;
+ case 0x09: return UAC_INTERFACE_SUBTYPE_EXTENSION_UNIT;
+ case 0x0a: return UAC_INTERFACE_SUBTYPE_CLOCK_SOURCE;
+ case 0x0b: return UAC_INTERFACE_SUBTYPE_CLOCK_SELECTOR;
+ case 0x0c: return UAC_INTERFACE_SUBTYPE_CLOCK_MULTIPLIER;
+ case 0x0d: return UAC_INTERFACE_SUBTYPE_SAMPLE_RATE_CONVERTER;
+ }
+ break;
+ }
+
+ return c;
+}
+
+
+
static void dump_audiocontrol_interface(libusb_device_handle *dev, const
unsigned char *buf, int protocol)
{
+ enum uac_interface_subtype subtype;
static const char * const chconfig[] = {
"Left Front (L)", "Right Front (R)", "Center Front (C)", "Low
Frequency Enhancement (LFE)",
"Left Surround (LS)", "Right Surround (RS)", "Left of Center
(LC)", "Right of Center (RC)",
@@ -1010,7 +1087,7 @@ static void
dump_audiocontrol_interface(libusb_device_handle *dev, const unsigne
static const char * const clock_source_attrs[] = {
"External", "Internal fixed", "Internal variable", "Internal
programmable"
};
- unsigned int i, chcfg, j, k, N, termt, subtype;
+ unsigned int i, chcfg, j, k, N, termt;
char *chnames = NULL, *term = NULL, termts[128];
if (buf[1] != USB_DT_CS_INTERFACE)
@@ -1023,26 +1100,7 @@ static void
dump_audiocontrol_interface(libusb_device_handle *dev, const unsigne
" bDescriptorSubtype %5u ",
buf[0], buf[1], buf[2]);
- /*
- * This is an utter mess - UAC2 defines some bDescriptorSubtype
differently, so we have to do some ugly remapping here:
- *
- * bDescriptorSubtype UAC1 UAC2
- *
------------------------------------------------------------------------
- * 0x07 PROCESSING_UNIT EFFECT_UNIT
- * 0x08 EXTENSION_UNIT PROCESSING_UNIT
- * 0x09 - EXTENSION_UNIT
- *
- */
-
- if (protocol == USB_AUDIO_CLASS_2)
- switch(buf[2]) {
- case 0x07: subtype = 0xf0; break; /* effect unit */
- case 0x08: subtype = 0x07; break; /* processing unit */
- case 0x09: subtype = 0x08; break; /* extension unit */
- default: subtype = buf[2]; break; /* everything else is
identical */
- }
- else
- subtype = buf[2];
+ subtype = get_uac_interface_subtype(buf[2], protocol);
switch (subtype) {
case 0x01: /* HEADER */
--
2.11.0
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html