ALSA: usb-audio: Check mapping at creating connector controls, too
authorTakashi Iwai <tiwai@suse.de>
Sun, 12 Apr 2020 08:13:31 +0000 (10:13 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 21 Apr 2020 07:04:57 +0000 (09:04 +0200)
commit 934b96594ed66b07dbc7e576d28814466df3a494 upstream.

Add the mapping check to build_connector_control() so that the device
specific quirk can provide the node to skip for the badly behaving
connector controls.  As an example, ALC1220-VB-based codec implements
the skip entry for the broken SPDIF connector detection.

BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=206873
Cc: <stable@vger.kernel.org>
Link: https://lore.kernel.org/r/20200412081331.4742-5-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
sound/usb/mixer.c
sound/usb/mixer_maps.c

index 2575056..5661994 100644 (file)
@@ -1750,11 +1750,15 @@ static void get_connector_control_name(struct usb_mixer_interface *mixer,
 
 /* Build a mixer control for a UAC connector control (jack-detect) */
 static void build_connector_control(struct usb_mixer_interface *mixer,
+                                   const struct usbmix_name_map *imap,
                                    struct usb_audio_term *term, bool is_input)
 {
        struct snd_kcontrol *kctl;
        struct usb_mixer_elem_info *cval;
 
+       if (check_ignored_ctl(find_map(imap, term->id, 0)))
+               return;
+
        cval = kzalloc(sizeof(*cval), GFP_KERNEL);
        if (!cval)
                return;
@@ -2090,7 +2094,7 @@ static int parse_audio_input_terminal(struct mixer_build *state, int unitid,
        /* Check for jack detection. */
        if ((iterm.type & 0xff00) != 0x0100 &&
            uac_v2v3_control_is_readable(bmctls, control))
-               build_connector_control(state->mixer, &iterm, true);
+               build_connector_control(state->mixer, state->map, &iterm, true);
 
        return 0;
 }
@@ -3051,13 +3055,13 @@ static int snd_usb_mixer_controls_badd(struct usb_mixer_interface *mixer,
                memset(&iterm, 0, sizeof(iterm));
                iterm.id = UAC3_BADD_IT_ID4;
                iterm.type = UAC_BIDIR_TERMINAL_HEADSET;
-               build_connector_control(mixer, &iterm, true);
+               build_connector_control(mixer, map->map, &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);
+               build_connector_control(mixer, map->map, &oterm, false);
        }
 
        return 0;
@@ -3132,8 +3136,8 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
                        if ((state.oterm.type & 0xff00) != 0x0100 &&
                            uac_v2v3_control_is_readable(le16_to_cpu(desc->bmControls),
                                                         UAC2_TE_CONNECTOR)) {
-                               build_connector_control(state.mixer, &state.oterm,
-                                                       false);
+                               build_connector_control(state.mixer, state.map,
+                                                       &state.oterm, false);
                        }
                } else {  /* UAC_VERSION_3 */
                        struct uac3_output_terminal_descriptor *desc = p;
@@ -3158,8 +3162,8 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
                        if ((state.oterm.type & 0xff00) != 0x0100 &&
                            uac_v2v3_control_is_readable(le32_to_cpu(desc->bmControls),
                                                         UAC3_TE_INSERTION)) {
-                               build_connector_control(state.mixer, &state.oterm,
-                                                       false);
+                               build_connector_control(state.mixer, state.map,
+                                                       &state.oterm, false);
                        }
                }
        }
index f6a67ee..3a54ca0 100644 (file)
@@ -350,9 +350,11 @@ static const struct usbmix_name_map dell_alc4020_map[] = {
 };
 
 /* Some mobos shipped with a dummy HD-audio show the invalid GET_MIN/GET_MAX
- * response for Input Gain Pad (id=19, control=12).  Skip it.
+ * response for Input Gain Pad (id=19, control=12) and the connector status
+ * for SPDIF terminal (id=18).  Skip them.
  */
 static const struct usbmix_name_map asus_rog_map[] = {
+       { 18, NULL }, /* OT, connector control */
        { 19, NULL, 12 }, /* FU, Input Gain Pad */
        {}
 };