[alsa-devel] [PATCH 0/2] ALSA: usb-audio: Insertion Control for BADD Adaptors.
This patchset adds support for the Insertion Control for BADD devices (subset of UAC3).
This control is only pressent in the HEADSET ADAPTER BADD profile. The USB interrupt pipe shall be present for this profile so the status pipe creation should also happen for BADD devices.
Also, the bi-directional type codes have been defined so they can be used as inferred values for the Input and Output terminals for this adapter profile.
Define the bi-directional USB terminal types for audio devices.
Signed-off-by: Jorge Sanjuan jorge.sanjuan@codethink.co.uk --- include/uapi/linux/usb/audio.h | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/include/uapi/linux/usb/audio.h b/include/uapi/linux/usb/audio.h index 13d98e6e0db1..74e520fb944f 100644 --- a/include/uapi/linux/usb/audio.h +++ b/include/uapi/linux/usb/audio.h @@ -230,6 +230,14 @@ struct uac1_output_terminal_descriptor { #define UAC_OUTPUT_TERMINAL_COMMUNICATION_SPEAKER 0x306 #define UAC_OUTPUT_TERMINAL_LOW_FREQ_EFFECTS_SPEAKER 0x307
+/* Terminals - 2.4 Bi-directional Terminal Types */ +#define UAC_BIDIR_TERMINAL_UNDEFINED 0x400 +#define UAC_BIDIR_TERMINAL_HANDSET 0x401 +#define UAC_BIDIR_TERMINAL_HEADSET 0x402 +#define UAC_BIDIR_TERMINAL_SPEAKER_PHONE 0x403 +#define UAC_BIDIR_TERMINAL_ECHO_SUPPRESSING 0x404 +#define UAC_BIDIR_TERMINAL_ECHO_CANCELING 0x405 + /* Set bControlSize = 2 as default setting */ #define UAC_DT_FEATURE_UNIT_SIZE(ch) (7 + ((ch) + 1) * 2)
The HEADSET ADAPTER profile for BADD devices is meant to support Insertion Control for the Input and Output Terminals of the headset. Furthermore, this profile may also include the interrupt status pipe to report changes on these terminals.
This patch creates the jack-detect controls for the Headset Adapter profile and enables the interrupt status pipe creation for BADD devices.
Signed-off-by: Jorge Sanjuan jorge.sanjuan@codethink.co.uk --- sound/usb/mixer.c | 45 ++++++++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 13 deletions(-)
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 898afd3001ea..b1dcf6dfc27e 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -1653,11 +1653,11 @@ static void build_feature_ctl_badd(struct usb_mixer_interface *mixer, NULL, NULL, unitid, 0, 0); }
-static void get_connector_control_name(struct mixer_build *state, +static void get_connector_control_name(struct usb_mixer_interface *mixer, struct usb_audio_term *term, bool is_input, char *name, int name_size) { - int name_len = get_term_name(state->chip, term, name, name_size, 0); + int name_len = get_term_name(mixer->chip, term, name, name_size, 0);
if (name_len == 0) strlcpy(name, "Unknown", name_size); @@ -1674,7 +1674,7 @@ static void get_connector_control_name(struct mixer_build *state, }
/* Build a mixer control for a UAC connector control (jack-detect) */ -static void build_connector_control(struct mixer_build *state, +static void build_connector_control(struct usb_mixer_interface *mixer, struct usb_audio_term *term, bool is_input) { struct snd_kcontrol *kctl; @@ -1683,7 +1683,7 @@ static void build_connector_control(struct mixer_build *state, cval = kzalloc(sizeof(*cval), GFP_KERNEL); if (!cval) return; - snd_usb_mixer_elem_init_std(&cval->head, state->mixer, term->id); + snd_usb_mixer_elem_init_std(&cval->head, mixer, term->id); /* * UAC2: The first byte from reading the UAC2_TE_CONNECTOR control returns the * number of channels connected. @@ -1694,7 +1694,7 @@ static void build_connector_control(struct mixer_build *state, * This boolean ctl will simply report if any channels are connected * or not. */ - if (state->mixer->protocol == UAC_VERSION_2) + if (mixer->protocol == UAC_VERSION_2) cval->control = UAC2_TE_CONNECTOR; else /* UAC_VERSION_3 */ cval->control = UAC3_TE_INSERTION; @@ -1705,11 +1705,11 @@ static void build_connector_control(struct mixer_build *state, cval->max = 1; kctl = snd_ctl_new1(&usb_connector_ctl_ro, cval); if (!kctl) { - usb_audio_err(state->chip, "cannot malloc kcontrol\n"); + usb_audio_err(mixer->chip, "cannot malloc kcontrol\n"); kfree(cval); return; } - get_connector_control_name(state, term, is_input, kctl->id.name, + get_connector_control_name(mixer, term, is_input, kctl->id.name, sizeof(kctl->id.name)); kctl->private_free = snd_usb_mixer_elem_free; snd_usb_mixer_add_control(&cval->head, kctl); @@ -2042,7 +2042,7 @@ static int parse_audio_input_terminal(struct mixer_build *state, int unitid,
/* Check for jack detection. */ if (uac_v2v3_control_is_readable(bmctls, control)) - build_connector_control(state, &iterm, true); + build_connector_control(state->mixer, &iterm, true);
return 0; } @@ -2918,6 +2918,23 @@ static int snd_usb_mixer_controls_badd(struct usb_mixer_interface *mixer, UAC3_BADD_FU_ID7, map->map); }
+ /* Insertion Control */ + if (f->subclass == UAC3_FUNCTION_SUBCLASS_HEADSET_ADAPTER) { + struct usb_audio_term iterm, oterm; + + /* Input Term - Insertion control */ + memset(&iterm, 0, sizeof(iterm)); + iterm.id = UAC3_BADD_IT_ID4; + iterm.type = UAC_BIDIR_TERMINAL_HEADSET; + build_connector_control(mixer, &iterm, true); + + /* Output Term - Insertion control */ + memset(&oterm, 0, sizeof(oterm)); + oterm.id = UAC3_BADD_OT_ID3; + oterm.type = UAC_BIDIR_TERMINAL_HEADSET; + build_connector_control(mixer, &oterm, false); + } + return 0; }
@@ -2990,7 +3007,7 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
if (uac_v2v3_control_is_readable(le16_to_cpu(desc->bmControls), UAC2_TE_CONNECTOR)) { - build_connector_control(&state, &state.oterm, + build_connector_control(state.mixer, &state.oterm, false); } } else { /* UAC_VERSION_3 */ @@ -3017,7 +3034,7 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
if (uac_v2v3_control_is_readable(le32_to_cpu(desc->bmControls), UAC3_TE_INSERTION)) { - build_connector_control(&state, &state.oterm, + build_connector_control(state.mixer, &state.oterm, false); } } @@ -3321,10 +3338,12 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, err = snd_usb_mixer_controls(mixer); if (err < 0) goto _error; - err = snd_usb_mixer_status_create(mixer); - if (err < 0) - goto _error; } + + err = snd_usb_mixer_status_create(mixer); + if (err < 0) + goto _error; + err = create_keep_iface_ctl(mixer); if (err < 0) goto _error;
On Tue, 12 Jun 2018 16:32:01 +0200, Jorge Sanjuan wrote:
The HEADSET ADAPTER profile for BADD devices is meant to support Insertion Control for the Input and Output Terminals of the headset. Furthermore, this profile may also include the interrupt status pipe to report changes on these terminals.
This patch creates the jack-detect controls for the Headset Adapter profile and enables the interrupt status pipe creation for BADD devices.
Signed-off-by: Jorge Sanjuan jorge.sanjuan@codethink.co.uk
The changes look good, but I'd prefer splitting this:
- A preliminary work to change get_connector_control_name() and build_connector_control() to receive usb_mixer_interface; this is no functional change
- Add build_connector_control() calls for UAC3 BADD
- Apply snd_usb_mixer_status_create() for UAC3 BADD, too
thanks,
Takashi
Thanks for review!
Here is what's new in this V2: - Split the patchset into a more sensible series.
This patchset adds support for the Insertion Control for BADD devices (subset of UAC3).
This control is only pressent in the HEADSET ADAPTER BADD profile. The USB interrupt pipe shall be present for this profile so the status pipe creation should also happen for BADD devices.
Also, the bi-directional type codes have been defined so they can be used as inferred values for the Input and Output terminals for this adapter profile.
Based on tag: next-20180612
Jorge Sanjuan (4): ALSA: usb-audio: Add bi-directional terminal types. ALSA: usb-audio: Change in connectors control creation interface ALSA: usb-audio: UAC3. Add insertion control for BADD. ALSA: usb-audio: Always create the interrupt pipe for the mixer
include/uapi/linux/usb/audio.h | 8 ++++++++ sound/usb/mixer.c | 45 ++++++++++++++++++++++++++++++------------ 2 files changed, 40 insertions(+), 13 deletions(-)
Define the bi-directional USB terminal types for audio devices.
Signed-off-by: Jorge Sanjuan jorge.sanjuan@codethink.co.uk --- include/uapi/linux/usb/audio.h | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/include/uapi/linux/usb/audio.h b/include/uapi/linux/usb/audio.h index 13d98e6e0db1..74e520fb944f 100644 --- a/include/uapi/linux/usb/audio.h +++ b/include/uapi/linux/usb/audio.h @@ -230,6 +230,14 @@ struct uac1_output_terminal_descriptor { #define UAC_OUTPUT_TERMINAL_COMMUNICATION_SPEAKER 0x306 #define UAC_OUTPUT_TERMINAL_LOW_FREQ_EFFECTS_SPEAKER 0x307
+/* Terminals - 2.4 Bi-directional Terminal Types */ +#define UAC_BIDIR_TERMINAL_UNDEFINED 0x400 +#define UAC_BIDIR_TERMINAL_HANDSET 0x401 +#define UAC_BIDIR_TERMINAL_HEADSET 0x402 +#define UAC_BIDIR_TERMINAL_SPEAKER_PHONE 0x403 +#define UAC_BIDIR_TERMINAL_ECHO_SUPPRESSING 0x404 +#define UAC_BIDIR_TERMINAL_ECHO_CANCELING 0x405 + /* Set bControlSize = 2 as default setting */ #define UAC_DT_FEATURE_UNIT_SIZE(ch) (7 + ((ch) + 1) * 2)
Change build_connector_control() and get_connector_control_name() so they take `struct usb_mixer_interface` as input argument instead of `struct mixer_build`.
This is preliminary work to add support for connectors control for UAC3 BADD devices. No functional change.
Signed-off-by: Jorge Sanjuan jorge.sanjuan@codethink.co.uk --- sound/usb/mixer.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 898afd3001ea..34fef71e0330 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -1653,11 +1653,11 @@ static void build_feature_ctl_badd(struct usb_mixer_interface *mixer, NULL, NULL, unitid, 0, 0); }
-static void get_connector_control_name(struct mixer_build *state, +static void get_connector_control_name(struct usb_mixer_interface *mixer, struct usb_audio_term *term, bool is_input, char *name, int name_size) { - int name_len = get_term_name(state->chip, term, name, name_size, 0); + int name_len = get_term_name(mixer->chip, term, name, name_size, 0);
if (name_len == 0) strlcpy(name, "Unknown", name_size); @@ -1674,7 +1674,7 @@ static void get_connector_control_name(struct mixer_build *state, }
/* Build a mixer control for a UAC connector control (jack-detect) */ -static void build_connector_control(struct mixer_build *state, +static void build_connector_control(struct usb_mixer_interface *mixer, struct usb_audio_term *term, bool is_input) { struct snd_kcontrol *kctl; @@ -1683,7 +1683,7 @@ static void build_connector_control(struct mixer_build *state, cval = kzalloc(sizeof(*cval), GFP_KERNEL); if (!cval) return; - snd_usb_mixer_elem_init_std(&cval->head, state->mixer, term->id); + snd_usb_mixer_elem_init_std(&cval->head, mixer, term->id); /* * UAC2: The first byte from reading the UAC2_TE_CONNECTOR control returns the * number of channels connected. @@ -1694,7 +1694,7 @@ static void build_connector_control(struct mixer_build *state, * This boolean ctl will simply report if any channels are connected * or not. */ - if (state->mixer->protocol == UAC_VERSION_2) + if (mixer->protocol == UAC_VERSION_2) cval->control = UAC2_TE_CONNECTOR; else /* UAC_VERSION_3 */ cval->control = UAC3_TE_INSERTION; @@ -1705,11 +1705,11 @@ static void build_connector_control(struct mixer_build *state, cval->max = 1; kctl = snd_ctl_new1(&usb_connector_ctl_ro, cval); if (!kctl) { - usb_audio_err(state->chip, "cannot malloc kcontrol\n"); + usb_audio_err(mixer->chip, "cannot malloc kcontrol\n"); kfree(cval); return; } - get_connector_control_name(state, term, is_input, kctl->id.name, + get_connector_control_name(mixer, term, is_input, kctl->id.name, sizeof(kctl->id.name)); kctl->private_free = snd_usb_mixer_elem_free; snd_usb_mixer_add_control(&cval->head, kctl); @@ -2042,7 +2042,7 @@ static int parse_audio_input_terminal(struct mixer_build *state, int unitid,
/* Check for jack detection. */ if (uac_v2v3_control_is_readable(bmctls, control)) - build_connector_control(state, &iterm, true); + build_connector_control(state->mixer, &iterm, true);
return 0; } @@ -2990,7 +2990,7 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
if (uac_v2v3_control_is_readable(le16_to_cpu(desc->bmControls), UAC2_TE_CONNECTOR)) { - build_connector_control(&state, &state.oterm, + build_connector_control(state.mixer, &state.oterm, false); } } else { /* UAC_VERSION_3 */ @@ -3017,7 +3017,7 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
if (uac_v2v3_control_is_readable(le32_to_cpu(desc->bmControls), UAC3_TE_INSERTION)) { - build_connector_control(&state, &state.oterm, + build_connector_control(state.mixer, &state.oterm, false); } }
The HEADSET ADAPTER profile for BADD devices is meant to support Insertion Control for the Input and Output Terminals of the headset.
This patch defines the BADD inferred input and output terminals and builds the connector controls.
Signed-off-by: Jorge Sanjuan jorge.sanjuan@codethink.co.uk --- sound/usb/mixer.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 34fef71e0330..03b8a2ac93c8 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -2918,6 +2918,23 @@ static int snd_usb_mixer_controls_badd(struct usb_mixer_interface *mixer, UAC3_BADD_FU_ID7, map->map); }
+ /* Insertion Control */ + if (f->subclass == UAC3_FUNCTION_SUBCLASS_HEADSET_ADAPTER) { + struct usb_audio_term iterm, oterm; + + /* Input Term - Insertion control */ + memset(&iterm, 0, sizeof(iterm)); + iterm.id = UAC3_BADD_IT_ID4; + iterm.type = UAC_BIDIR_TERMINAL_HEADSET; + build_connector_control(mixer, &iterm, true); + + /* Output Term - Insertion control */ + memset(&oterm, 0, sizeof(oterm)); + oterm.id = UAC3_BADD_OT_ID3; + oterm.type = UAC_BIDIR_TERMINAL_HEADSET; + build_connector_control(mixer, &oterm, false); + } + return 0; }
An UAC3 BADD device may also include an interrupt status pipe to report changes on the HEADSET ADAPTER terminals. The creation of the status pipe is dependent on the device reporting that it has it.
Signed-off-by: Jorge Sanjuan jorge.sanjuan@codethink.co.uk --- sound/usb/mixer.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 03b8a2ac93c8..b1dcf6dfc27e 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -3338,10 +3338,12 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, err = snd_usb_mixer_controls(mixer); if (err < 0) goto _error; - err = snd_usb_mixer_status_create(mixer); - if (err < 0) - goto _error; } + + err = snd_usb_mixer_status_create(mixer); + if (err < 0) + goto _error; + err = create_keep_iface_ctl(mixer); if (err < 0) goto _error;
On Thu, 14 Jun 2018 16:05:54 +0200, Jorge Sanjuan wrote:
Thanks for review!
Here is what's new in this V2:
- Split the patchset into a more sensible series.
This patchset adds support for the Insertion Control for BADD devices (subset of UAC3).
This control is only pressent in the HEADSET ADAPTER BADD profile. The USB interrupt pipe shall be present for this profile so the status pipe creation should also happen for BADD devices.
Also, the bi-directional type codes have been defined so they can be used as inferred values for the Input and Output terminals for this adapter profile.
Based on tag: next-20180612
Jorge Sanjuan (4): ALSA: usb-audio: Add bi-directional terminal types. ALSA: usb-audio: Change in connectors control creation interface ALSA: usb-audio: UAC3. Add insertion control for BADD. ALSA: usb-audio: Always create the interrupt pipe for the mixer
Thanks, this looks nicer, each of changes is smaller and clearer. Although it's a bit too late for the merge window, this is a change that is fairly safe for the existing UAC1/UAC2, I merged it now.
Oh, and the subjects were slightly fixed; no need of period at the tail in a subject line.
Takashi
On Thu, Jun 14, 2018 at 7:07 PM, Takashi Iwai tiwai@suse.de wrote:
On Thu, 14 Jun 2018 16:05:54 +0200, Jorge Sanjuan wrote:
Thanks for review!
Here is what's new in this V2:
- Split the patchset into a more sensible series.
This patchset adds support for the Insertion Control for BADD devices (subset of UAC3).
This control is only pressent in the HEADSET ADAPTER BADD profile. The USB interrupt pipe shall be present for this profile so the status pipe creation should also happen for BADD devices.
Also, the bi-directional type codes have been defined so they can be used as inferred values for the Input and Output terminals for this adapter profile.
Based on tag: next-20180612
Jorge Sanjuan (4): ALSA: usb-audio: Add bi-directional terminal types. ALSA: usb-audio: Change in connectors control creation interface ALSA: usb-audio: UAC3. Add insertion control for BADD. ALSA: usb-audio: Always create the interrupt pipe for the mixer
Thanks, this looks nicer, each of changes is smaller and clearer. Although it's a bit too late for the merge window, this is a change that is fairly safe for the existing UAC1/UAC2, I merged it now.
It's too late probably, but I just finished reviewing these patches and don't have any objections.
Thanks, Ruslan
On Thu, 14 Jun 2018 21:18:10 +0200, Ruslan Bilovol wrote:
On Thu, Jun 14, 2018 at 7:07 PM, Takashi Iwai tiwai@suse.de wrote:
On Thu, 14 Jun 2018 16:05:54 +0200, Jorge Sanjuan wrote:
Thanks for review!
Here is what's new in this V2:
- Split the patchset into a more sensible series.
This patchset adds support for the Insertion Control for BADD devices (subset of UAC3).
This control is only pressent in the HEADSET ADAPTER BADD profile. The USB interrupt pipe shall be present for this profile so the status pipe creation should also happen for BADD devices.
Also, the bi-directional type codes have been defined so they can be used as inferred values for the Input and Output terminals for this adapter profile.
Based on tag: next-20180612
Jorge Sanjuan (4): ALSA: usb-audio: Add bi-directional terminal types. ALSA: usb-audio: Change in connectors control creation interface ALSA: usb-audio: UAC3. Add insertion control for BADD. ALSA: usb-audio: Always create the interrupt pipe for the mixer
Thanks, this looks nicer, each of changes is smaller and clearer. Although it's a bit too late for the merge window, this is a change that is fairly safe for the existing UAC1/UAC2, I merged it now.
It's too late probably, but I just finished reviewing these patches and don't have any objections.
Yeah, I already pushed out. But thanks for reviewing.
Takashi
participants (3)
-
Jorge Sanjuan
-
Ruslan Bilovol
-
Takashi Iwai