diff options
author | Takashi Iwai <tiwai@suse.de> | 2012-01-19 06:10:29 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2012-01-19 06:10:29 -0500 |
commit | f21d78e2698b6380a5387461e3b126bb2dee23aa (patch) | |
tree | a6d580a92a6f8f3e2af7ca6bf53bf27749a60448 /sound | |
parent | b90bf1de7cb65e7f61798fcfbcf74ae72207b0dc (diff) |
ALSA: hda/realtek - Avoid conflict of unsol-events with static quirks
The recently added jack-kctl support sets the unsol event tags
dynamically, while static quirks usually set the fixed tags in the
init_verbs array. Due to this conflict, the own unsol event handler
can't retrieve the tag and handle it properly any more.
For fixing this, avoid calling snd_hda_jack_add_kctls() for static
quirks, and always let them use own handlers instead of the standard
one for the auto-pareser.
Reported-by: David Henningsson <david.henningsson@canonical.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/hda/alc880_quirks.c | 17 | ||||
-rw-r--r-- | sound/pci/hda/alc882_quirks.c | 15 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 45 |
3 files changed, 53 insertions, 24 deletions
diff --git a/sound/pci/hda/alc880_quirks.c b/sound/pci/hda/alc880_quirks.c index 5b68435d195b..501501ef36a9 100644 --- a/sound/pci/hda/alc880_quirks.c +++ b/sound/pci/hda/alc880_quirks.c | |||
@@ -762,16 +762,22 @@ static void alc880_uniwill_unsol_event(struct hda_codec *codec, | |||
762 | /* Looks like the unsol event is incompatible with the standard | 762 | /* Looks like the unsol event is incompatible with the standard |
763 | * definition. 4bit tag is placed at 28 bit! | 763 | * definition. 4bit tag is placed at 28 bit! |
764 | */ | 764 | */ |
765 | switch (res >> 28) { | 765 | res >>= 28; |
766 | switch (res) { | ||
766 | case ALC_MIC_EVENT: | 767 | case ALC_MIC_EVENT: |
767 | alc88x_simple_mic_automute(codec); | 768 | alc88x_simple_mic_automute(codec); |
768 | break; | 769 | break; |
769 | default: | 770 | default: |
770 | alc_sku_unsol_event(codec, res); | 771 | alc_exec_unsol_event(codec, res); |
771 | break; | 772 | break; |
772 | } | 773 | } |
773 | } | 774 | } |
774 | 775 | ||
776 | static void alc880_unsol_event(struct hda_codec *codec, unsigned int res) | ||
777 | { | ||
778 | alc_exec_unsol_event(codec, res >> 28); | ||
779 | } | ||
780 | |||
775 | static void alc880_uniwill_p53_setup(struct hda_codec *codec) | 781 | static void alc880_uniwill_p53_setup(struct hda_codec *codec) |
776 | { | 782 | { |
777 | struct alc_spec *spec = codec->spec; | 783 | struct alc_spec *spec = codec->spec; |
@@ -800,10 +806,11 @@ static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec, | |||
800 | /* Looks like the unsol event is incompatible with the standard | 806 | /* Looks like the unsol event is incompatible with the standard |
801 | * definition. 4bit tag is placed at 28 bit! | 807 | * definition. 4bit tag is placed at 28 bit! |
802 | */ | 808 | */ |
803 | if ((res >> 28) == ALC_DCVOL_EVENT) | 809 | res >>= 28; |
810 | if (res == ALC_DCVOL_EVENT) | ||
804 | alc880_uniwill_p53_dcvol_automute(codec); | 811 | alc880_uniwill_p53_dcvol_automute(codec); |
805 | else | 812 | else |
806 | alc_sku_unsol_event(codec, res); | 813 | alc_exec_unsol_event(codec, res); |
807 | } | 814 | } |
808 | 815 | ||
809 | /* | 816 | /* |
@@ -1677,7 +1684,7 @@ static const struct alc_config_preset alc880_presets[] = { | |||
1677 | .channel_mode = alc880_lg_ch_modes, | 1684 | .channel_mode = alc880_lg_ch_modes, |
1678 | .need_dac_fix = 1, | 1685 | .need_dac_fix = 1, |
1679 | .input_mux = &alc880_lg_capture_source, | 1686 | .input_mux = &alc880_lg_capture_source, |
1680 | .unsol_event = alc_sku_unsol_event, | 1687 | .unsol_event = alc880_unsol_event, |
1681 | .setup = alc880_lg_setup, | 1688 | .setup = alc880_lg_setup, |
1682 | .init_hook = alc_hp_automute, | 1689 | .init_hook = alc_hp_automute, |
1683 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 1690 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
diff --git a/sound/pci/hda/alc882_quirks.c b/sound/pci/hda/alc882_quirks.c index bdf0ed4ab3e2..bb364a53f546 100644 --- a/sound/pci/hda/alc882_quirks.c +++ b/sound/pci/hda/alc882_quirks.c | |||
@@ -730,6 +730,11 @@ static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res) | |||
730 | alc889A_mb31_automute(codec); | 730 | alc889A_mb31_automute(codec); |
731 | } | 731 | } |
732 | 732 | ||
733 | static void alc882_unsol_event(struct hda_codec *codec, unsigned int res) | ||
734 | { | ||
735 | alc_exec_unsol_event(codec, res >> 26); | ||
736 | } | ||
737 | |||
733 | /* | 738 | /* |
734 | * configuration and preset | 739 | * configuration and preset |
735 | */ | 740 | */ |
@@ -775,7 +780,7 @@ static const struct alc_config_preset alc882_presets[] = { | |||
775 | .channel_mode = alc885_mba21_ch_modes, | 780 | .channel_mode = alc885_mba21_ch_modes, |
776 | .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes), | 781 | .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes), |
777 | .input_mux = &alc882_capture_source, | 782 | .input_mux = &alc882_capture_source, |
778 | .unsol_event = alc_sku_unsol_event, | 783 | .unsol_event = alc882_unsol_event, |
779 | .setup = alc885_mba21_setup, | 784 | .setup = alc885_mba21_setup, |
780 | .init_hook = alc_hp_automute, | 785 | .init_hook = alc_hp_automute, |
781 | }, | 786 | }, |
@@ -791,7 +796,7 @@ static const struct alc_config_preset alc882_presets[] = { | |||
791 | .input_mux = &alc882_capture_source, | 796 | .input_mux = &alc882_capture_source, |
792 | .dig_out_nid = ALC882_DIGOUT_NID, | 797 | .dig_out_nid = ALC882_DIGOUT_NID, |
793 | .dig_in_nid = ALC882_DIGIN_NID, | 798 | .dig_in_nid = ALC882_DIGIN_NID, |
794 | .unsol_event = alc_sku_unsol_event, | 799 | .unsol_event = alc882_unsol_event, |
795 | .setup = alc885_mbp3_setup, | 800 | .setup = alc885_mbp3_setup, |
796 | .init_hook = alc_hp_automute, | 801 | .init_hook = alc_hp_automute, |
797 | }, | 802 | }, |
@@ -806,7 +811,7 @@ static const struct alc_config_preset alc882_presets[] = { | |||
806 | .input_mux = &mb5_capture_source, | 811 | .input_mux = &mb5_capture_source, |
807 | .dig_out_nid = ALC882_DIGOUT_NID, | 812 | .dig_out_nid = ALC882_DIGOUT_NID, |
808 | .dig_in_nid = ALC882_DIGIN_NID, | 813 | .dig_in_nid = ALC882_DIGIN_NID, |
809 | .unsol_event = alc_sku_unsol_event, | 814 | .unsol_event = alc882_unsol_event, |
810 | .setup = alc885_mb5_setup, | 815 | .setup = alc885_mb5_setup, |
811 | .init_hook = alc_hp_automute, | 816 | .init_hook = alc_hp_automute, |
812 | }, | 817 | }, |
@@ -821,7 +826,7 @@ static const struct alc_config_preset alc882_presets[] = { | |||
821 | .input_mux = &macmini3_capture_source, | 826 | .input_mux = &macmini3_capture_source, |
822 | .dig_out_nid = ALC882_DIGOUT_NID, | 827 | .dig_out_nid = ALC882_DIGOUT_NID, |
823 | .dig_in_nid = ALC882_DIGIN_NID, | 828 | .dig_in_nid = ALC882_DIGIN_NID, |
824 | .unsol_event = alc_sku_unsol_event, | 829 | .unsol_event = alc882_unsol_event, |
825 | .setup = alc885_macmini3_setup, | 830 | .setup = alc885_macmini3_setup, |
826 | .init_hook = alc_hp_automute, | 831 | .init_hook = alc_hp_automute, |
827 | }, | 832 | }, |
@@ -836,7 +841,7 @@ static const struct alc_config_preset alc882_presets[] = { | |||
836 | .input_mux = &alc889A_imac91_capture_source, | 841 | .input_mux = &alc889A_imac91_capture_source, |
837 | .dig_out_nid = ALC882_DIGOUT_NID, | 842 | .dig_out_nid = ALC882_DIGOUT_NID, |
838 | .dig_in_nid = ALC882_DIGIN_NID, | 843 | .dig_in_nid = ALC882_DIGIN_NID, |
839 | .unsol_event = alc_sku_unsol_event, | 844 | .unsol_event = alc882_unsol_event, |
840 | .setup = alc885_imac91_setup, | 845 | .setup = alc885_imac91_setup, |
841 | .init_hook = alc_hp_automute, | 846 | .init_hook = alc_hp_automute, |
842 | }, | 847 | }, |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 61ccbe832b75..2326bf379525 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -621,17 +621,10 @@ static void alc_mic_automute(struct hda_codec *codec) | |||
621 | alc_mux_select(codec, 0, spec->int_mic_idx, false); | 621 | alc_mux_select(codec, 0, spec->int_mic_idx, false); |
622 | } | 622 | } |
623 | 623 | ||
624 | /* unsolicited event for HP jack sensing */ | 624 | /* handle the specified unsol action (ALC_XXX_EVENT) */ |
625 | static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) | 625 | static void alc_exec_unsol_event(struct hda_codec *codec, int action) |
626 | { | 626 | { |
627 | struct alc_spec *spec = codec->spec; | 627 | switch (action) { |
628 | if (codec->vendor_id == 0x10ec0880) | ||
629 | res >>= 28; | ||
630 | else | ||
631 | res >>= 26; | ||
632 | if (spec->use_jack_tbl) | ||
633 | res = snd_hda_jack_get_action(codec, res); | ||
634 | switch (res) { | ||
635 | case ALC_HP_EVENT: | 628 | case ALC_HP_EVENT: |
636 | alc_hp_automute(codec); | 629 | alc_hp_automute(codec); |
637 | break; | 630 | break; |
@@ -645,6 +638,19 @@ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) | |||
645 | snd_hda_jack_report_sync(codec); | 638 | snd_hda_jack_report_sync(codec); |
646 | } | 639 | } |
647 | 640 | ||
641 | /* unsolicited event for HP jack sensing */ | ||
642 | static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) | ||
643 | { | ||
644 | struct alc_spec *spec = codec->spec; | ||
645 | if (codec->vendor_id == 0x10ec0880) | ||
646 | res >>= 28; | ||
647 | else | ||
648 | res >>= 26; | ||
649 | if (spec->use_jack_tbl) | ||
650 | res = snd_hda_jack_get_action(codec, res); | ||
651 | alc_exec_unsol_event(codec, res); | ||
652 | } | ||
653 | |||
648 | /* call init functions of standard auto-mute helpers */ | 654 | /* call init functions of standard auto-mute helpers */ |
649 | static void alc_inithook(struct hda_codec *codec) | 655 | static void alc_inithook(struct hda_codec *codec) |
650 | { | 656 | { |
@@ -1883,7 +1889,7 @@ static const struct snd_kcontrol_new alc_beep_mixer[] = { | |||
1883 | }; | 1889 | }; |
1884 | #endif | 1890 | #endif |
1885 | 1891 | ||
1886 | static int alc_build_controls(struct hda_codec *codec) | 1892 | static int __alc_build_controls(struct hda_codec *codec) |
1887 | { | 1893 | { |
1888 | struct alc_spec *spec = codec->spec; | 1894 | struct alc_spec *spec = codec->spec; |
1889 | struct snd_kcontrol *kctl = NULL; | 1895 | struct snd_kcontrol *kctl = NULL; |
@@ -2029,11 +2035,16 @@ static int alc_build_controls(struct hda_codec *codec) | |||
2029 | 2035 | ||
2030 | alc_free_kctls(codec); /* no longer needed */ | 2036 | alc_free_kctls(codec); /* no longer needed */ |
2031 | 2037 | ||
2032 | err = snd_hda_jack_add_kctls(codec, &spec->autocfg); | 2038 | return 0; |
2039 | } | ||
2040 | |||
2041 | static int alc_build_controls(struct hda_codec *codec) | ||
2042 | { | ||
2043 | struct alc_spec *spec = codec->spec; | ||
2044 | int err = __alc_build_controls(codec); | ||
2033 | if (err < 0) | 2045 | if (err < 0) |
2034 | return err; | 2046 | return err; |
2035 | 2047 | return snd_hda_jack_add_kctls(codec, &spec->autocfg); | |
2036 | return 0; | ||
2037 | } | 2048 | } |
2038 | 2049 | ||
2039 | 2050 | ||
@@ -4168,6 +4179,8 @@ static int patch_alc880(struct hda_codec *codec) | |||
4168 | codec->patch_ops = alc_patch_ops; | 4179 | codec->patch_ops = alc_patch_ops; |
4169 | if (board_config == ALC_MODEL_AUTO) | 4180 | if (board_config == ALC_MODEL_AUTO) |
4170 | spec->init_hook = alc_auto_init_std; | 4181 | spec->init_hook = alc_auto_init_std; |
4182 | else | ||
4183 | codec->patch_ops.build_controls = __alc_build_controls; | ||
4171 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 4184 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
4172 | if (!spec->loopback.amplist) | 4185 | if (!spec->loopback.amplist) |
4173 | spec->loopback.amplist = alc880_loopbacks; | 4186 | spec->loopback.amplist = alc880_loopbacks; |
@@ -4297,6 +4310,8 @@ static int patch_alc260(struct hda_codec *codec) | |||
4297 | codec->patch_ops = alc_patch_ops; | 4310 | codec->patch_ops = alc_patch_ops; |
4298 | if (board_config == ALC_MODEL_AUTO) | 4311 | if (board_config == ALC_MODEL_AUTO) |
4299 | spec->init_hook = alc_auto_init_std; | 4312 | spec->init_hook = alc_auto_init_std; |
4313 | else | ||
4314 | codec->patch_ops.build_controls = __alc_build_controls; | ||
4300 | spec->shutup = alc_eapd_shutup; | 4315 | spec->shutup = alc_eapd_shutup; |
4301 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 4316 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
4302 | if (!spec->loopback.amplist) | 4317 | if (!spec->loopback.amplist) |
@@ -4691,6 +4706,8 @@ static int patch_alc882(struct hda_codec *codec) | |||
4691 | codec->patch_ops = alc_patch_ops; | 4706 | codec->patch_ops = alc_patch_ops; |
4692 | if (board_config == ALC_MODEL_AUTO) | 4707 | if (board_config == ALC_MODEL_AUTO) |
4693 | spec->init_hook = alc_auto_init_std; | 4708 | spec->init_hook = alc_auto_init_std; |
4709 | else | ||
4710 | codec->patch_ops.build_controls = __alc_build_controls; | ||
4694 | 4711 | ||
4695 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 4712 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
4696 | if (!spec->loopback.amplist) | 4713 | if (!spec->loopback.amplist) |