mirror of
https://github.com/armbian/linux-cix.git
synced 2026-01-06 12:30:45 -08:00
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>
This commit is contained in:
committed by
Takashi Iwai
parent
99fc86450c
commit
23caaf19b1
@@ -43,6 +43,53 @@ struct uac_clock_selector_descriptor {
|
||||
__u8 baCSourceID[];
|
||||
} __attribute__((packed));
|
||||
|
||||
/* 4.7.2.4 Input terminal descriptor */
|
||||
|
||||
struct uac2_input_terminal_descriptor {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
__u8 bDescriptorSubtype;
|
||||
__u8 bTerminalID;
|
||||
__u16 wTerminalType;
|
||||
__u8 bAssocTerminal;
|
||||
__u8 bCSourceID;
|
||||
__u8 bNrChannels;
|
||||
__u32 bmChannelConfig;
|
||||
__u8 iChannelNames;
|
||||
__u16 bmControls;
|
||||
__u8 iTerminal;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* 4.7.2.5 Output terminal descriptor */
|
||||
|
||||
struct uac2_output_terminal_descriptor {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
__u8 bDescriptorSubtype;
|
||||
__u8 bTerminalID;
|
||||
__u16 wTerminalType;
|
||||
__u8 bAssocTerminal;
|
||||
__u8 bSourceID;
|
||||
__u8 bCSourceID;
|
||||
__u16 bmControls;
|
||||
__u8 iTerminal;
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
|
||||
/* 4.7.2.8 Feature Unit Descriptor */
|
||||
|
||||
struct uac2_feature_unit_descriptor {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
__u8 bDescriptorSubtype;
|
||||
__u8 bUnitID;
|
||||
__u8 bSourceID;
|
||||
/* bmaControls is actually u32,
|
||||
* but u8 is needed for the hybrid parser */
|
||||
__u8 bmaControls[0]; /* variable length */
|
||||
} __attribute__((packed));
|
||||
|
||||
/* 4.9.2 Class-Specific AS Interface Descriptor */
|
||||
|
||||
struct uac_as_header_descriptor_v2 {
|
||||
|
||||
@@ -196,20 +196,33 @@ static inline __u8 uac_mixer_unit_bNrChannels(struct uac_mixer_unit_descriptor *
|
||||
return desc->baSourceID[desc->bNrInPins];
|
||||
}
|
||||
|
||||
static inline __u16 uac_mixer_unit_wChannelConfig(struct uac_mixer_unit_descriptor *desc)
|
||||
static inline __u32 uac_mixer_unit_wChannelConfig(struct uac_mixer_unit_descriptor *desc,
|
||||
int protocol)
|
||||
{
|
||||
return (desc->baSourceID[desc->bNrInPins + 2] << 8) |
|
||||
desc->baSourceID[desc->bNrInPins + 1];
|
||||
if (protocol == UAC_VERSION_1)
|
||||
return (desc->baSourceID[desc->bNrInPins + 2] << 8) |
|
||||
desc->baSourceID[desc->bNrInPins + 1];
|
||||
else
|
||||
return (desc->baSourceID[desc->bNrInPins + 4] << 24) |
|
||||
(desc->baSourceID[desc->bNrInPins + 3] << 16) |
|
||||
(desc->baSourceID[desc->bNrInPins + 2] << 8) |
|
||||
(desc->baSourceID[desc->bNrInPins + 1]);
|
||||
}
|
||||
|
||||
static inline __u8 uac_mixer_unit_iChannelNames(struct uac_mixer_unit_descriptor *desc)
|
||||
static inline __u8 uac_mixer_unit_iChannelNames(struct uac_mixer_unit_descriptor *desc,
|
||||
int protocol)
|
||||
{
|
||||
return desc->baSourceID[desc->bNrInPins + 3];
|
||||
return (protocol == UAC_VERSION_1) ?
|
||||
desc->baSourceID[desc->bNrInPins + 3] :
|
||||
desc->baSourceID[desc->bNrInPins + 5];
|
||||
}
|
||||
|
||||
static inline __u8 *uac_mixer_unit_bmControls(struct uac_mixer_unit_descriptor *desc)
|
||||
static inline __u8 *uac_mixer_unit_bmControls(struct uac_mixer_unit_descriptor *desc,
|
||||
int protocol)
|
||||
{
|
||||
return &desc->baSourceID[desc->bNrInPins + 4];
|
||||
return (protocol == UAC_VERSION_1) ?
|
||||
&desc->baSourceID[desc->bNrInPins + 4] :
|
||||
&desc->baSourceID[desc->bNrInPins + 6];
|
||||
}
|
||||
|
||||
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
|
||||
return desc->baSourceID[desc->bNrInPins];
|
||||
}
|
||||
|
||||
static inline __u16 uac_processing_unit_wChannelConfig(struct uac_processing_unit_descriptor *desc)
|
||||
static inline __u32 uac_processing_unit_wChannelConfig(struct uac_processing_unit_descriptor *desc,
|
||||
int protocol)
|
||||
{
|
||||
return (desc->baSourceID[desc->bNrInPins + 2] << 8) |
|
||||
desc->baSourceID[desc->bNrInPins + 1];
|
||||
if (protocol == UAC_VERSION_1)
|
||||
return (desc->baSourceID[desc->bNrInPins + 2] << 8) |
|
||||
desc->baSourceID[desc->bNrInPins + 1];
|
||||
else
|
||||
return (desc->baSourceID[desc->bNrInPins + 4] << 24) |
|
||||
(desc->baSourceID[desc->bNrInPins + 3] << 16) |
|
||||
(desc->baSourceID[desc->bNrInPins + 2] << 8) |
|
||||
(desc->baSourceID[desc->bNrInPins + 1]);
|
||||
}
|
||||
|
||||
static inline __u8 uac_processing_unit_iChannelNames(struct uac_processing_unit_descriptor *desc)
|
||||
static inline __u8 uac_processing_unit_iChannelNames(struct uac_processing_unit_descriptor *desc,
|
||||
int protocol)
|
||||
{
|
||||
return desc->baSourceID[desc->bNrInPins + 3];
|
||||
return (protocol == UAC_VERSION_1) ?
|
||||
desc->baSourceID[desc->bNrInPins + 3] :
|
||||
desc->baSourceID[desc->bNrInPins + 5];
|
||||
}
|
||||
|
||||
static inline __u8 uac_processing_unit_bControlSize(struct uac_processing_unit_descriptor *desc)
|
||||
static inline __u8 uac_processing_unit_bControlSize(struct uac_processing_unit_descriptor *desc,
|
||||
int protocol)
|
||||
{
|
||||
return desc->baSourceID[desc->bNrInPins + 4];
|
||||
return (protocol == UAC_VERSION_1) ?
|
||||
desc->baSourceID[desc->bNrInPins + 4] :
|
||||
desc->baSourceID[desc->bNrInPins + 6];
|
||||
}
|
||||
|
||||
static inline __u8 *uac_processing_unit_bmControls(struct uac_processing_unit_descriptor *desc)
|
||||
static inline __u8 *uac_processing_unit_bmControls(struct uac_processing_unit_descriptor *desc,
|
||||
int protocol)
|
||||
{
|
||||
return &desc->baSourceID[desc->bNrInPins + 5];
|
||||
return (protocol == UAC_VERSION_1) ?
|
||||
&desc->baSourceID[desc->bNrInPins + 5] :
|
||||
&desc->baSourceID[desc->bNrInPins + 7];
|
||||
}
|
||||
|
||||
static inline __u8 uac_processing_unit_iProcessing(struct uac_processing_unit_descriptor *desc)
|
||||
static inline __u8 uac_processing_unit_iProcessing(struct uac_processing_unit_descriptor *desc,
|
||||
int protocol)
|
||||
{
|
||||
__u8 control_size = uac_processing_unit_bControlSize(desc);
|
||||
__u8 control_size = uac_processing_unit_bControlSize(desc, protocol);
|
||||
return desc->baSourceID[desc->bNrInPins + control_size];
|
||||
}
|
||||
|
||||
static inline __u8 *uac_processing_unit_specific(struct uac_processing_unit_descriptor *desc)
|
||||
static inline __u8 *uac_processing_unit_specific(struct uac_processing_unit_descriptor *desc,
|
||||
int protocol)
|
||||
{
|
||||
__u8 control_size = uac_processing_unit_bControlSize(desc);
|
||||
__u8 control_size = uac_processing_unit_bControlSize(desc, protocol);
|
||||
return &desc->baSourceID[desc->bNrInPins + control_size + 1];
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -10,6 +10,9 @@ struct usb_mixer_interface {
|
||||
/* array[MAX_ID_ELEMS], indexed by unit id */
|
||||
struct usb_mixer_elem_info **id_elems;
|
||||
|
||||
/* the usb audio specification version this interface complies to */
|
||||
int protocol;
|
||||
|
||||
/* Sound Blaster remote control stuff */
|
||||
const struct rc_config *rc_cfg;
|
||||
u32 rc_code;
|
||||
|
||||
Reference in New Issue
Block a user