Commit 934b9659 authored by Takashi Iwai's avatar Takashi Iwai

ALSA: usb-audio: Check mapping at creating connector controls, too

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.deSigned-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 7dc3c5a0
...@@ -1771,11 +1771,15 @@ static void get_connector_control_name(struct usb_mixer_interface *mixer, ...@@ -1771,11 +1771,15 @@ static void get_connector_control_name(struct usb_mixer_interface *mixer,
/* Build a mixer control for a UAC connector control (jack-detect) */ /* Build a mixer control for a UAC connector control (jack-detect) */
static void build_connector_control(struct usb_mixer_interface *mixer, 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 usb_audio_term *term, bool is_input)
{ {
struct snd_kcontrol *kctl; struct snd_kcontrol *kctl;
struct usb_mixer_elem_info *cval; struct usb_mixer_elem_info *cval;
if (check_ignored_ctl(find_map(imap, term->id, 0)))
return;
cval = kzalloc(sizeof(*cval), GFP_KERNEL); cval = kzalloc(sizeof(*cval), GFP_KERNEL);
if (!cval) if (!cval)
return; return;
...@@ -2111,7 +2115,7 @@ static int parse_audio_input_terminal(struct mixer_build *state, int unitid, ...@@ -2111,7 +2115,7 @@ static int parse_audio_input_terminal(struct mixer_build *state, int unitid,
/* Check for jack detection. */ /* Check for jack detection. */
if ((iterm.type & 0xff00) != 0x0100 && if ((iterm.type & 0xff00) != 0x0100 &&
uac_v2v3_control_is_readable(bmctls, control)) 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; return 0;
} }
...@@ -3072,13 +3076,13 @@ static int snd_usb_mixer_controls_badd(struct usb_mixer_interface *mixer, ...@@ -3072,13 +3076,13 @@ static int snd_usb_mixer_controls_badd(struct usb_mixer_interface *mixer,
memset(&iterm, 0, sizeof(iterm)); memset(&iterm, 0, sizeof(iterm));
iterm.id = UAC3_BADD_IT_ID4; iterm.id = UAC3_BADD_IT_ID4;
iterm.type = UAC_BIDIR_TERMINAL_HEADSET; iterm.type = UAC_BIDIR_TERMINAL_HEADSET;
build_connector_control(mixer, &iterm, true); build_connector_control(mixer, map->map, &iterm, true);
/* Output Term - Insertion control */ /* Output Term - Insertion control */
memset(&oterm, 0, sizeof(oterm)); memset(&oterm, 0, sizeof(oterm));
oterm.id = UAC3_BADD_OT_ID3; oterm.id = UAC3_BADD_OT_ID3;
oterm.type = UAC_BIDIR_TERMINAL_HEADSET; oterm.type = UAC_BIDIR_TERMINAL_HEADSET;
build_connector_control(mixer, &oterm, false); build_connector_control(mixer, map->map, &oterm, false);
} }
return 0; return 0;
...@@ -3153,8 +3157,8 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) ...@@ -3153,8 +3157,8 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
if ((state.oterm.type & 0xff00) != 0x0100 && if ((state.oterm.type & 0xff00) != 0x0100 &&
uac_v2v3_control_is_readable(le16_to_cpu(desc->bmControls), uac_v2v3_control_is_readable(le16_to_cpu(desc->bmControls),
UAC2_TE_CONNECTOR)) { UAC2_TE_CONNECTOR)) {
build_connector_control(state.mixer, &state.oterm, build_connector_control(state.mixer, state.map,
false); &state.oterm, false);
} }
} else { /* UAC_VERSION_3 */ } else { /* UAC_VERSION_3 */
struct uac3_output_terminal_descriptor *desc = p; struct uac3_output_terminal_descriptor *desc = p;
...@@ -3179,8 +3183,8 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) ...@@ -3179,8 +3183,8 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
if ((state.oterm.type & 0xff00) != 0x0100 && if ((state.oterm.type & 0xff00) != 0x0100 &&
uac_v2v3_control_is_readable(le32_to_cpu(desc->bmControls), uac_v2v3_control_is_readable(le32_to_cpu(desc->bmControls),
UAC3_TE_INSERTION)) { UAC3_TE_INSERTION)) {
build_connector_control(state.mixer, &state.oterm, build_connector_control(state.mixer, state.map,
false); &state.oterm, false);
} }
} }
} }
......
...@@ -360,9 +360,11 @@ static const struct usbmix_name_map corsair_virtuoso_map[] = { ...@@ -360,9 +360,11 @@ static const struct usbmix_name_map corsair_virtuoso_map[] = {
}; };
/* Some mobos shipped with a dummy HD-audio show the invalid GET_MIN/GET_MAX /* 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[] = { static const struct usbmix_name_map asus_rog_map[] = {
{ 18, NULL }, /* OT, connector control */
{ 19, NULL, 12 }, /* FU, Input Gain Pad */ { 19, NULL, 12 }, /* FU, Input Gain Pad */
{} {}
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment