aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2012-02-20 06:30:59 -0500
committerTakashi Iwai <tiwai@suse.de>2012-02-29 11:38:51 -0500
commit07cafff288266c3aa082f4bda3d47989e73ee85d (patch)
tree1557aee6baa4039240c927153a8c53d5d03da6f2 /sound/pci
parent3e93f5efaf9cd48bae97ae6436cbc5f91be8003c (diff)
ALSA: hda/conexant - Clear unsol events on unused pins
It seems that Lenovo machines (or codec chip itself?) leave the unsol event tags and the enablement-flag from other pins bogusly even on the unused pins. Although this shouldn't be too critical, it's better to clear them up sanely. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/patch_conexant.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 6bbdbb6dd4e5..f3b79031fcca 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -3931,6 +3931,50 @@ static void enable_unsol_pins(struct hda_codec *codec, int num_pins,
3931 snd_hda_jack_detect_enable(codec, pins[i], action); 3931 snd_hda_jack_detect_enable(codec, pins[i], action);
3932} 3932}
3933 3933
3934static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
3935{
3936 int i;
3937 for (i = 0; i < nums; i++)
3938 if (list[i] == nid)
3939 return true;
3940 return false;
3941}
3942
3943/* is the given NID found in any of autocfg items? */
3944static bool found_in_autocfg(struct auto_pin_cfg *cfg, hda_nid_t nid)
3945{
3946 int i;
3947
3948 if (found_in_nid_list(nid, cfg->line_out_pins, cfg->line_outs) ||
3949 found_in_nid_list(nid, cfg->hp_pins, cfg->hp_outs) ||
3950 found_in_nid_list(nid, cfg->speaker_pins, cfg->speaker_outs) ||
3951 found_in_nid_list(nid, cfg->dig_out_pins, cfg->dig_outs))
3952 return true;
3953 for (i = 0; i < cfg->num_inputs; i++)
3954 if (cfg->inputs[i].pin == nid)
3955 return true;
3956 if (cfg->dig_in_pin == nid)
3957 return true;
3958 return false;
3959}
3960
3961/* clear unsol-event tags on unused pins; Conexant codecs seem to leave
3962 * invalid unsol tags by some reason
3963 */
3964static void clear_unsol_on_unused_pins(struct hda_codec *codec)
3965{
3966 struct conexant_spec *spec = codec->spec;
3967 struct auto_pin_cfg *cfg = &spec->autocfg;
3968 int i;
3969
3970 for (i = 0; i < codec->init_pins.used; i++) {
3971 struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
3972 if (!found_in_autocfg(cfg, pin->nid))
3973 snd_hda_codec_write(codec, pin->nid, 0,
3974 AC_VERB_SET_UNSOLICITED_ENABLE, 0);
3975 }
3976}
3977
3934static void cx_auto_init_output(struct hda_codec *codec) 3978static void cx_auto_init_output(struct hda_codec *codec)
3935{ 3979{
3936 struct conexant_spec *spec = codec->spec; 3980 struct conexant_spec *spec = codec->spec;
@@ -3971,6 +4015,7 @@ static void cx_auto_init_output(struct hda_codec *codec)
3971 /* turn on all EAPDs if no individual EAPD control is available */ 4015 /* turn on all EAPDs if no individual EAPD control is available */
3972 if (!spec->pin_eapd_ctrls) 4016 if (!spec->pin_eapd_ctrls)
3973 cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true); 4017 cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true);
4018 clear_unsol_on_unused_pins(codec);
3974} 4019}
3975 4020
3976static void cx_auto_init_input(struct hda_codec *codec) 4021static void cx_auto_init_input(struct hda_codec *codec)