Skip to content

Commit 23caaf1

Browse files
Daniel Macktiwai
authored andcommitted
ALSA: usb-mixer: Add support for Audio Class v2.0
USB Audio Class v2.0 compliant devices have different descriptors and a different way of setting/getting min/max/res/cur properties. This patch adds support for them. Signed-off-by: Daniel Mack <daniel@caiaq.de> Cc: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
1 parent 99fc864 commit 23caaf1

File tree

4 files changed

+343
-100
lines changed

4 files changed

+343
-100
lines changed

include/linux/usb/audio-v2.h

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,53 @@ struct uac_clock_selector_descriptor {
4343
__u8 baCSourceID[];
4444
} __attribute__((packed));
4545

46+
/* 4.7.2.4 Input terminal descriptor */
47+
48+
struct uac2_input_terminal_descriptor {
49+
__u8 bLength;
50+
__u8 bDescriptorType;
51+
__u8 bDescriptorSubtype;
52+
__u8 bTerminalID;
53+
__u16 wTerminalType;
54+
__u8 bAssocTerminal;
55+
__u8 bCSourceID;
56+
__u8 bNrChannels;
57+
__u32 bmChannelConfig;
58+
__u8 iChannelNames;
59+
__u16 bmControls;
60+
__u8 iTerminal;
61+
} __attribute__((packed));
62+
63+
/* 4.7.2.5 Output terminal descriptor */
64+
65+
struct uac2_output_terminal_descriptor {
66+
__u8 bLength;
67+
__u8 bDescriptorType;
68+
__u8 bDescriptorSubtype;
69+
__u8 bTerminalID;
70+
__u16 wTerminalType;
71+
__u8 bAssocTerminal;
72+
__u8 bSourceID;
73+
__u8 bCSourceID;
74+
__u16 bmControls;
75+
__u8 iTerminal;
76+
} __attribute__((packed));
77+
78+
79+
80+
/* 4.7.2.8 Feature Unit Descriptor */
81+
82+
struct uac2_feature_unit_descriptor {
83+
__u8 bLength;
84+
__u8 bDescriptorType;
85+
__u8 bDescriptorSubtype;
86+
__u8 bUnitID;
87+
__u8 bSourceID;
88+
/* bmaControls is actually u32,
89+
* but u8 is needed for the hybrid parser */
90+
__u8 bmaControls[0]; /* variable length */
91+
} __attribute__((packed));
92+
4693
/* 4.9.2 Class-Specific AS Interface Descriptor */
4794

4895
struct uac_as_header_descriptor_v2 {

include/linux/usb/audio.h

Lines changed: 51 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -196,20 +196,33 @@ static inline __u8 uac_mixer_unit_bNrChannels(struct uac_mixer_unit_descriptor *
196196
return desc->baSourceID[desc->bNrInPins];
197197
}
198198

199-
static inline __u16 uac_mixer_unit_wChannelConfig(struct uac_mixer_unit_descriptor *desc)
199+
static inline __u32 uac_mixer_unit_wChannelConfig(struct uac_mixer_unit_descriptor *desc,
200+
int protocol)
200201
{
201-
return (desc->baSourceID[desc->bNrInPins + 2] << 8) |
202-
desc->baSourceID[desc->bNrInPins + 1];
202+
if (protocol == UAC_VERSION_1)
203+
return (desc->baSourceID[desc->bNrInPins + 2] << 8) |
204+
desc->baSourceID[desc->bNrInPins + 1];
205+
else
206+
return (desc->baSourceID[desc->bNrInPins + 4] << 24) |
207+
(desc->baSourceID[desc->bNrInPins + 3] << 16) |
208+
(desc->baSourceID[desc->bNrInPins + 2] << 8) |
209+
(desc->baSourceID[desc->bNrInPins + 1]);
203210
}
204211

205-
static inline __u8 uac_mixer_unit_iChannelNames(struct uac_mixer_unit_descriptor *desc)
212+
static inline __u8 uac_mixer_unit_iChannelNames(struct uac_mixer_unit_descriptor *desc,
213+
int protocol)
206214
{
207-
return desc->baSourceID[desc->bNrInPins + 3];
215+
return (protocol == UAC_VERSION_1) ?
216+
desc->baSourceID[desc->bNrInPins + 3] :
217+
desc->baSourceID[desc->bNrInPins + 5];
208218
}
209219

210-
static inline __u8 *uac_mixer_unit_bmControls(struct uac_mixer_unit_descriptor *desc)
220+
static inline __u8 *uac_mixer_unit_bmControls(struct uac_mixer_unit_descriptor *desc,
221+
int protocol)
211222
{
212-
return &desc->baSourceID[desc->bNrInPins + 4];
223+
return (protocol == UAC_VERSION_1) ?
224+
&desc->baSourceID[desc->bNrInPins + 4] :
225+
&desc->baSourceID[desc->bNrInPins + 6];
213226
}
214227

215228
static inline __u8 uac_mixer_unit_iMixer(struct uac_mixer_unit_descriptor *desc)
@@ -267,36 +280,54 @@ static inline __u8 uac_processing_unit_bNrChannels(struct uac_processing_unit_de
267280
return desc->baSourceID[desc->bNrInPins];
268281
}
269282

270-
static inline __u16 uac_processing_unit_wChannelConfig(struct uac_processing_unit_descriptor *desc)
283+
static inline __u32 uac_processing_unit_wChannelConfig(struct uac_processing_unit_descriptor *desc,
284+
int protocol)
271285
{
272-
return (desc->baSourceID[desc->bNrInPins + 2] << 8) |
273-
desc->baSourceID[desc->bNrInPins + 1];
286+
if (protocol == UAC_VERSION_1)
287+
return (desc->baSourceID[desc->bNrInPins + 2] << 8) |
288+
desc->baSourceID[desc->bNrInPins + 1];
289+
else
290+
return (desc->baSourceID[desc->bNrInPins + 4] << 24) |
291+
(desc->baSourceID[desc->bNrInPins + 3] << 16) |
292+
(desc->baSourceID[desc->bNrInPins + 2] << 8) |
293+
(desc->baSourceID[desc->bNrInPins + 1]);
274294
}
275295

276-
static inline __u8 uac_processing_unit_iChannelNames(struct uac_processing_unit_descriptor *desc)
296+
static inline __u8 uac_processing_unit_iChannelNames(struct uac_processing_unit_descriptor *desc,
297+
int protocol)
277298
{
278-
return desc->baSourceID[desc->bNrInPins + 3];
299+
return (protocol == UAC_VERSION_1) ?
300+
desc->baSourceID[desc->bNrInPins + 3] :
301+
desc->baSourceID[desc->bNrInPins + 5];
279302
}
280303

281-
static inline __u8 uac_processing_unit_bControlSize(struct uac_processing_unit_descriptor *desc)
304+
static inline __u8 uac_processing_unit_bControlSize(struct uac_processing_unit_descriptor *desc,
305+
int protocol)
282306
{
283-
return desc->baSourceID[desc->bNrInPins + 4];
307+
return (protocol == UAC_VERSION_1) ?
308+
desc->baSourceID[desc->bNrInPins + 4] :
309+
desc->baSourceID[desc->bNrInPins + 6];
284310
}
285311

286-
static inline __u8 *uac_processing_unit_bmControls(struct uac_processing_unit_descriptor *desc)
312+
static inline __u8 *uac_processing_unit_bmControls(struct uac_processing_unit_descriptor *desc,
313+
int protocol)
287314
{
288-
return &desc->baSourceID[desc->bNrInPins + 5];
315+
return (protocol == UAC_VERSION_1) ?
316+
&desc->baSourceID[desc->bNrInPins + 5] :
317+
&desc->baSourceID[desc->bNrInPins + 7];
289318
}
290319

291-
static inline __u8 uac_processing_unit_iProcessing(struct uac_processing_unit_descriptor *desc)
320+
static inline __u8 uac_processing_unit_iProcessing(struct uac_processing_unit_descriptor *desc,
321+
int protocol)
292322
{
293-
__u8 control_size = uac_processing_unit_bControlSize(desc);
323+
__u8 control_size = uac_processing_unit_bControlSize(desc, protocol);
294324
return desc->baSourceID[desc->bNrInPins + control_size];
295325
}
296326

297-
static inline __u8 *uac_processing_unit_specific(struct uac_processing_unit_descriptor *desc)
327+
static inline __u8 *uac_processing_unit_specific(struct uac_processing_unit_descriptor *desc,
328+
int protocol)
298329
{
299-
__u8 control_size = uac_processing_unit_bControlSize(desc);
330+
__u8 control_size = uac_processing_unit_bControlSize(desc, protocol);
300331
return &desc->baSourceID[desc->bNrInPins + control_size + 1];
301332
}
302333

0 commit comments

Comments
 (0)