ALSA: hda - Allow setting automute/automic hooks after parsing

Some codec drivers (VIA codecs and some Realtek fixups) set the
automute and automic hooks after calling
snd_hda_gen_parse_auto_config().  In the current code, the hook
pointers are referred only in snd_hda_gen_parse_auto_config() and
passed to snd_hda_jack_detect_enable_callback(), thus changing the
hook values won't change the actually called callbacks properly.

This patch fixes this bug by setting the static functions as the
primary callback functions for the jack detection, and let them
calling the appropriate hooks dynamically.

Cc: <stable@vger.kernel.org> [v3.9]
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Takashi Iwai 2013-05-31 14:10:03 +02:00
parent 087c2e3b4e
commit 77afe0e948

View File

@ -3875,6 +3875,36 @@ static void update_automute_all(struct hda_codec *codec)
snd_hda_gen_mic_autoswitch(codec, NULL);
}
/* call appropriate hooks */
static void call_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack)
{
struct hda_gen_spec *spec = codec->spec;
if (spec->hp_automute_hook)
spec->hp_automute_hook(codec, jack);
else
snd_hda_gen_hp_automute(codec, jack);
}
static void call_line_automute(struct hda_codec *codec,
struct hda_jack_tbl *jack)
{
struct hda_gen_spec *spec = codec->spec;
if (spec->line_automute_hook)
spec->line_automute_hook(codec, jack);
else
snd_hda_gen_line_automute(codec, jack);
}
static void call_mic_autoswitch(struct hda_codec *codec,
struct hda_jack_tbl *jack)
{
struct hda_gen_spec *spec = codec->spec;
if (spec->mic_autoswitch_hook)
spec->mic_autoswitch_hook(codec, jack);
else
snd_hda_gen_mic_autoswitch(codec, jack);
}
/*
* Auto-Mute mode mixer enum support
*/
@ -4009,9 +4039,7 @@ static int check_auto_mute_availability(struct hda_codec *codec)
snd_printdd("hda-codec: Enable HP auto-muting on NID 0x%x\n",
nid);
snd_hda_jack_detect_enable_callback(codec, nid, HDA_GEN_HP_EVENT,
spec->hp_automute_hook ?
spec->hp_automute_hook :
snd_hda_gen_hp_automute);
call_hp_automute);
spec->detect_hp = 1;
}
@ -4024,9 +4052,7 @@ static int check_auto_mute_availability(struct hda_codec *codec)
snd_printdd("hda-codec: Enable Line-Out auto-muting on NID 0x%x\n", nid);
snd_hda_jack_detect_enable_callback(codec, nid,
HDA_GEN_FRONT_EVENT,
spec->line_automute_hook ?
spec->line_automute_hook :
snd_hda_gen_line_automute);
call_line_automute);
spec->detect_lo = 1;
}
spec->automute_lo_possible = spec->detect_hp;
@ -4068,9 +4094,7 @@ static bool auto_mic_check_imux(struct hda_codec *codec)
snd_hda_jack_detect_enable_callback(codec,
spec->am_entry[i].pin,
HDA_GEN_MIC_EVENT,
spec->mic_autoswitch_hook ?
spec->mic_autoswitch_hook :
snd_hda_gen_mic_autoswitch);
call_mic_autoswitch);
return true;
}