ALSA: usb-audio: Always create the interrupt pipe for the mixer
[sfrench/cifs-2.6.git] / sound / usb / mixer.c
index bf74e7edc92b011a054d939b9853f4194b4ef78b..b1dcf6dfc27e07469de6498836358eb8a6640bcb 100644 (file)
@@ -598,7 +598,8 @@ int snd_usb_mixer_add_control(struct usb_mixer_elem_list *list,
 
        while (snd_ctl_find_id(mixer->chip->card, &kctl->id))
                kctl->id.index++;
-       if ((err = snd_ctl_add(mixer->chip->card, kctl)) < 0) {
+       err = snd_ctl_add(mixer->chip->card, kctl);
+       if (err < 0) {
                usb_audio_dbg(mixer->chip, "cannot add control (err = %d)\n",
                              err);
                return err;
@@ -1652,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);
@@ -1673,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;
@@ -1682,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.
@@ -1693,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;
@@ -1704,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);
@@ -1850,7 +1851,8 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid,
        }
 
        /* parse the source unit */
-       if ((err = parse_audio_unit(state, hdr->bSourceID)) < 0)
+       err = parse_audio_unit(state, hdr->bSourceID);
+       if (err < 0)
                return err;
 
        /* determine the input source type and name */
@@ -2040,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;
 }
@@ -2270,7 +2272,8 @@ static int build_audio_procunit(struct mixer_build *state, int unitid,
        }
 
        for (i = 0; i < num_ins; i++) {
-               if ((err = parse_audio_unit(state, desc->baSourceID[i])) < 0)
+               err = parse_audio_unit(state, desc->baSourceID[i]);
+               if (err < 0)
                        return err;
        }
 
@@ -2483,7 +2486,8 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid,
        }
 
        for (i = 0; i < desc->bNrInPins; i++) {
-               if ((err = parse_audio_unit(state, desc->baSourceID[i])) < 0)
+               err = parse_audio_unit(state, desc->baSourceID[i]);
+               if (err < 0)
                        return err;
        }
 
@@ -2914,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;
 }
 
@@ -2986,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 */
@@ -3013,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);
                        }
                }
@@ -3310,12 +3331,19 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
 
        if (mixer->protocol == UAC_VERSION_3 &&
                        chip->badd_profile >= UAC3_FUNCTION_SUBCLASS_GENERIC_IO) {
-               if ((err = snd_usb_mixer_controls_badd(mixer, ctrlif)) < 0)
+               err = snd_usb_mixer_controls_badd(mixer, ctrlif);
+               if (err < 0)
+                       goto _error;
+       } else {
+               err = snd_usb_mixer_controls(mixer);
+               if (err < 0)
                        goto _error;
-       } else if ((err = snd_usb_mixer_controls(mixer)) < 0 ||
-                       (err = snd_usb_mixer_status_create(mixer)) < 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;