aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/hda/patch_conexant.c44
-rw-r--r--sound/pci/hda/patch_realtek.c86
-rw-r--r--sound/pci/hda/patch_sigmatel.c20
3 files changed, 49 insertions, 101 deletions
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index c03d3b8e42b2..902ea0b0cd00 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -3402,7 +3402,7 @@ static void cx_auto_update_speakers(struct hda_codec *codec)
3402 do_automute(codec, cfg->line_outs, cfg->line_out_pins, on); 3402 do_automute(codec, cfg->line_outs, cfg->line_out_pins, on);
3403} 3403}
3404 3404
3405static void cx_auto_hp_automute(struct hda_codec *codec) 3405static void cx_auto_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack)
3406{ 3406{
3407 struct conexant_spec *spec = codec->spec; 3407 struct conexant_spec *spec = codec->spec;
3408 struct auto_pin_cfg *cfg = &spec->autocfg; 3408 struct auto_pin_cfg *cfg = &spec->autocfg;
@@ -3413,7 +3413,7 @@ static void cx_auto_hp_automute(struct hda_codec *codec)
3413 cx_auto_update_speakers(codec); 3413 cx_auto_update_speakers(codec);
3414} 3414}
3415 3415
3416static void cx_auto_line_automute(struct hda_codec *codec) 3416static void cx_auto_line_automute(struct hda_codec *codec, struct hda_jack_tbl *jack)
3417{ 3417{
3418 struct conexant_spec *spec = codec->spec; 3418 struct conexant_spec *spec = codec->spec;
3419 struct auto_pin_cfg *cfg = &spec->autocfg; 3419 struct auto_pin_cfg *cfg = &spec->autocfg;
@@ -3664,7 +3664,7 @@ static bool select_automic(struct hda_codec *codec, int idx, bool detect)
3664} 3664}
3665 3665
3666/* automatic switch internal and external mic */ 3666/* automatic switch internal and external mic */
3667static void cx_auto_automic(struct hda_codec *codec) 3667static void cx_auto_automic(struct hda_codec *codec, struct hda_jack_tbl *jack)
3668{ 3668{
3669 struct conexant_spec *spec = codec->spec; 3669 struct conexant_spec *spec = codec->spec;
3670 3670
@@ -3675,22 +3675,6 @@ static void cx_auto_automic(struct hda_codec *codec)
3675 select_automic(codec, spec->auto_mic_int, false); 3675 select_automic(codec, spec->auto_mic_int, false);
3676} 3676}
3677 3677
3678static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res)
3679{
3680 switch (snd_hda_jack_get_action(codec, res >> 26)) {
3681 case CONEXANT_HP_EVENT:
3682 cx_auto_hp_automute(codec);
3683 break;
3684 case CONEXANT_LINE_EVENT:
3685 cx_auto_line_automute(codec);
3686 break;
3687 case CONEXANT_MIC_EVENT:
3688 cx_auto_automic(codec);
3689 break;
3690 }
3691 snd_hda_jack_report_sync(codec);
3692}
3693
3694/* check whether the pin config is suitable for auto-mic switching; 3678/* check whether the pin config is suitable for auto-mic switching;
3695 * auto-mic is enabled only when one int-mic and one ext- and/or 3679 * auto-mic is enabled only when one int-mic and one ext- and/or
3696 * one dock-mic exist 3680 * one dock-mic exist
@@ -3900,11 +3884,12 @@ static void mute_outputs(struct hda_codec *codec, int num_nids,
3900} 3884}
3901 3885
3902static void enable_unsol_pins(struct hda_codec *codec, int num_pins, 3886static void enable_unsol_pins(struct hda_codec *codec, int num_pins,
3903 hda_nid_t *pins, unsigned int action) 3887 hda_nid_t *pins, unsigned int action,
3888 hda_jack_callback cb)
3904{ 3889{
3905 int i; 3890 int i;
3906 for (i = 0; i < num_pins; i++) 3891 for (i = 0; i < num_pins; i++)
3907 snd_hda_jack_detect_enable(codec, pins[i], action); 3892 snd_hda_jack_detect_enable_callback(codec, pins[i], action, cb);
3908} 3893}
3909 3894
3910static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) 3895static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
@@ -3992,13 +3977,14 @@ static void cx_auto_init_output(struct hda_codec *codec)
3992 } 3977 }
3993 if (spec->auto_mute) { 3978 if (spec->auto_mute) {
3994 enable_unsol_pins(codec, cfg->hp_outs, cfg->hp_pins, 3979 enable_unsol_pins(codec, cfg->hp_outs, cfg->hp_pins,
3995 CONEXANT_HP_EVENT); 3980 CONEXANT_HP_EVENT, cx_auto_hp_automute);
3996 spec->hp_present = detect_jacks(codec, cfg->hp_outs, 3981 spec->hp_present = detect_jacks(codec, cfg->hp_outs,
3997 cfg->hp_pins); 3982 cfg->hp_pins);
3998 if (spec->detect_line) { 3983 if (spec->detect_line) {
3999 enable_unsol_pins(codec, cfg->line_outs, 3984 enable_unsol_pins(codec, cfg->line_outs,
4000 cfg->line_out_pins, 3985 cfg->line_out_pins,
4001 CONEXANT_LINE_EVENT); 3986 CONEXANT_LINE_EVENT,
3987 cx_auto_line_automute);
4002 spec->line_present = 3988 spec->line_present =
4003 detect_jacks(codec, cfg->line_outs, 3989 detect_jacks(codec, cfg->line_outs,
4004 cfg->line_out_pins); 3990 cfg->line_out_pins);
@@ -4039,16 +4025,16 @@ static void cx_auto_init_input(struct hda_codec *codec)
4039 4025
4040 if (spec->auto_mic) { 4026 if (spec->auto_mic) {
4041 if (spec->auto_mic_ext >= 0) { 4027 if (spec->auto_mic_ext >= 0) {
4042 snd_hda_jack_detect_enable(codec, 4028 snd_hda_jack_detect_enable_callback(codec,
4043 cfg->inputs[spec->auto_mic_ext].pin, 4029 cfg->inputs[spec->auto_mic_ext].pin,
4044 CONEXANT_MIC_EVENT); 4030 CONEXANT_MIC_EVENT, cx_auto_automic);
4045 } 4031 }
4046 if (spec->auto_mic_dock >= 0) { 4032 if (spec->auto_mic_dock >= 0) {
4047 snd_hda_jack_detect_enable(codec, 4033 snd_hda_jack_detect_enable_callback(codec,
4048 cfg->inputs[spec->auto_mic_dock].pin, 4034 cfg->inputs[spec->auto_mic_dock].pin,
4049 CONEXANT_MIC_EVENT); 4035 CONEXANT_MIC_EVENT, cx_auto_automic);
4050 } 4036 }
4051 cx_auto_automic(codec); 4037 cx_auto_automic(codec, NULL);
4052 } else { 4038 } else {
4053 select_input_connection(codec, spec->imux_info[0].adc, 4039 select_input_connection(codec, spec->imux_info[0].adc,
4054 spec->imux_info[0].pin); 4040 spec->imux_info[0].pin);
@@ -4406,7 +4392,7 @@ static const struct hda_codec_ops cx_auto_patch_ops = {
4406 .build_pcms = conexant_build_pcms, 4392 .build_pcms = conexant_build_pcms,
4407 .init = cx_auto_init, 4393 .init = cx_auto_init,
4408 .free = conexant_free, 4394 .free = conexant_free,
4409 .unsol_event = cx_auto_unsol_event, 4395 .unsol_event = snd_hda_jack_unsol_event,
4410#ifdef CONFIG_PM 4396#ifdef CONFIG_PM
4411 .suspend = conexant_suspend, 4397 .suspend = conexant_suspend,
4412#endif 4398#endif
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 3d440fc7c200..847702978732 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -594,7 +594,7 @@ static void call_update_outputs(struct hda_codec *codec)
594} 594}
595 595
596/* standard HP-automute helper */ 596/* standard HP-automute helper */
597static void alc_hp_automute(struct hda_codec *codec) 597static void alc_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack)
598{ 598{
599 struct alc_spec *spec = codec->spec; 599 struct alc_spec *spec = codec->spec;
600 600
@@ -607,7 +607,7 @@ static void alc_hp_automute(struct hda_codec *codec)
607} 607}
608 608
609/* standard line-out-automute helper */ 609/* standard line-out-automute helper */
610static void alc_line_automute(struct hda_codec *codec) 610static void alc_line_automute(struct hda_codec *codec, struct hda_jack_tbl *jack)
611{ 611{
612 struct alc_spec *spec = codec->spec; 612 struct alc_spec *spec = codec->spec;
613 613
@@ -627,7 +627,7 @@ static void alc_line_automute(struct hda_codec *codec)
627 snd_hda_get_conn_index(codec, mux, nid, 0) 627 snd_hda_get_conn_index(codec, mux, nid, 0)
628 628
629/* standard mic auto-switch helper */ 629/* standard mic auto-switch helper */
630static void alc_mic_automute(struct hda_codec *codec) 630static void alc_mic_automute(struct hda_codec *codec, struct hda_jack_tbl *jack)
631{ 631{
632 struct alc_spec *spec = codec->spec; 632 struct alc_spec *spec = codec->spec;
633 hda_nid_t *pins = spec->imux_pins; 633 hda_nid_t *pins = spec->imux_pins;
@@ -648,25 +648,8 @@ static void alc_mic_automute(struct hda_codec *codec)
648 alc_mux_select(codec, 0, spec->int_mic_idx, false); 648 alc_mux_select(codec, 0, spec->int_mic_idx, false);
649} 649}
650 650
651/* handle the specified unsol action (ALC_XXX_EVENT) */
652static void alc_exec_unsol_event(struct hda_codec *codec, int action)
653{
654 switch (action) {
655 case ALC_HP_EVENT:
656 alc_hp_automute(codec);
657 break;
658 case ALC_FRONT_EVENT:
659 alc_line_automute(codec);
660 break;
661 case ALC_MIC_EVENT:
662 alc_mic_automute(codec);
663 break;
664 }
665 snd_hda_jack_report_sync(codec);
666}
667
668/* update the master volume per volume-knob's unsol event */ 651/* update the master volume per volume-knob's unsol event */
669static void alc_update_knob_master(struct hda_codec *codec, hda_nid_t nid) 652static void alc_update_knob_master(struct hda_codec *codec, struct hda_jack_tbl *jack)
670{ 653{
671 unsigned int val; 654 unsigned int val;
672 struct snd_kcontrol *kctl; 655 struct snd_kcontrol *kctl;
@@ -678,7 +661,7 @@ static void alc_update_knob_master(struct hda_codec *codec, hda_nid_t nid)
678 uctl = kzalloc(sizeof(*uctl), GFP_KERNEL); 661 uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
679 if (!uctl) 662 if (!uctl)
680 return; 663 return;
681 val = snd_hda_codec_read(codec, nid, 0, 664 val = snd_hda_codec_read(codec, jack->nid, 0,
682 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0); 665 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
683 val &= HDA_AMP_VOLMASK; 666 val &= HDA_AMP_VOLMASK;
684 uctl->value.integer.value[0] = val; 667 uctl->value.integer.value[0] = val;
@@ -687,37 +670,19 @@ static void alc_update_knob_master(struct hda_codec *codec, hda_nid_t nid)
687 kfree(uctl); 670 kfree(uctl);
688} 671}
689 672
690/* unsolicited event for HP jack sensing */ 673static void alc880_unsol_event(struct hda_codec *codec, unsigned int res)
691static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
692{ 674{
693 int action; 675 /* For some reason, the res given from ALC880 is broken.
694 676 Here we adjust it properly. */
695 if (codec->vendor_id == 0x10ec0880) 677 snd_hda_jack_unsol_event(codec, res >> 2);
696 res >>= 28;
697 else
698 res >>= 26;
699 action = snd_hda_jack_get_action(codec, res);
700 if (action == ALC_DCVOL_EVENT) {
701 /* Execute the dc-vol event here as it requires the NID
702 * but we don't pass NID to alc_exec_unsol_event().
703 * Once when we convert all static quirks to the auto-parser,
704 * this can be integerated into there.
705 */
706 struct hda_jack_tbl *jack;
707 jack = snd_hda_jack_tbl_get_from_tag(codec, res);
708 if (jack)
709 alc_update_knob_master(codec, jack->nid);
710 return;
711 }
712 alc_exec_unsol_event(codec, action);
713} 678}
714 679
715/* call init functions of standard auto-mute helpers */ 680/* call init functions of standard auto-mute helpers */
716static void alc_inithook(struct hda_codec *codec) 681static void alc_inithook(struct hda_codec *codec)
717{ 682{
718 alc_hp_automute(codec); 683 alc_hp_automute(codec, NULL);
719 alc_line_automute(codec); 684 alc_line_automute(codec, NULL);
720 alc_mic_automute(codec); 685 alc_mic_automute(codec, NULL);
721} 686}
722 687
723/* additional initialization for ALC888 variants */ 688/* additional initialization for ALC888 variants */
@@ -999,7 +964,8 @@ static void alc_init_automute(struct hda_codec *codec)
999 continue; 964 continue;
1000 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n", 965 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1001 nid); 966 nid);
1002 snd_hda_jack_detect_enable(codec, nid, ALC_HP_EVENT); 967 snd_hda_jack_detect_enable_callback(codec, nid, ALC_HP_EVENT,
968 alc_hp_automute);
1003 spec->detect_hp = 1; 969 spec->detect_hp = 1;
1004 } 970 }
1005 971
@@ -1011,10 +977,10 @@ static void alc_init_automute(struct hda_codec *codec)
1011 continue; 977 continue;
1012 snd_printdd("realtek: Enable Line-Out " 978 snd_printdd("realtek: Enable Line-Out "
1013 "auto-muting on NID 0x%x\n", nid); 979 "auto-muting on NID 0x%x\n", nid);
1014 snd_hda_jack_detect_enable(codec, nid, 980 snd_hda_jack_detect_enable_callback(codec, nid, ALC_FRONT_EVENT,
1015 ALC_FRONT_EVENT); 981 alc_line_automute);
1016 spec->detect_lo = 1; 982 spec->detect_lo = 1;
1017 } 983 }
1018 spec->automute_lo_possible = spec->detect_hp; 984 spec->automute_lo_possible = spec->detect_hp;
1019 } 985 }
1020 986
@@ -1110,10 +1076,12 @@ static bool alc_auto_mic_check_imux(struct hda_codec *codec)
1110 return false; /* no corresponding imux */ 1076 return false; /* no corresponding imux */
1111 } 1077 }
1112 1078
1113 snd_hda_jack_detect_enable(codec, spec->ext_mic_pin, ALC_MIC_EVENT); 1079 snd_hda_jack_detect_enable_callback(codec, spec->ext_mic_pin,
1080 ALC_MIC_EVENT, alc_mic_automute);
1114 if (spec->dock_mic_pin) 1081 if (spec->dock_mic_pin)
1115 snd_hda_jack_detect_enable(codec, spec->dock_mic_pin, 1082 snd_hda_jack_detect_enable_callback(codec, spec->dock_mic_pin,
1116 ALC_MIC_EVENT); 1083 ALC_MIC_EVENT,
1084 alc_mic_automute);
1117 1085
1118 spec->auto_mic_valid_imux = 1; 1086 spec->auto_mic_valid_imux = 1;
1119 spec->auto_mic = 1; 1087 spec->auto_mic = 1;
@@ -2473,7 +2441,7 @@ static const struct hda_codec_ops alc_patch_ops = {
2473 .build_pcms = alc_build_pcms, 2441 .build_pcms = alc_build_pcms,
2474 .init = alc_init, 2442 .init = alc_init,
2475 .free = alc_free, 2443 .free = alc_free,
2476 .unsol_event = alc_unsol_event, 2444 .unsol_event = snd_hda_jack_unsol_event,
2477#ifdef CONFIG_PM 2445#ifdef CONFIG_PM
2478 .resume = alc_resume, 2446 .resume = alc_resume,
2479#endif 2447#endif
@@ -2484,6 +2452,7 @@ static const struct hda_codec_ops alc_patch_ops = {
2484 .reboot_notify = alc_shutup, 2452 .reboot_notify = alc_shutup,
2485}; 2453};
2486 2454
2455
2487/* replace the codec chip_name with the given string */ 2456/* replace the codec chip_name with the given string */
2488static int alc_codec_rename(struct hda_codec *codec, const char *name) 2457static int alc_codec_rename(struct hda_codec *codec, const char *name)
2489{ 2458{
@@ -4447,7 +4416,7 @@ static void alc880_fixup_vol_knob(struct hda_codec *codec,
4447 const struct alc_fixup *fix, int action) 4416 const struct alc_fixup *fix, int action)
4448{ 4417{
4449 if (action == ALC_FIXUP_ACT_PROBE) 4418 if (action == ALC_FIXUP_ACT_PROBE)
4450 snd_hda_jack_detect_enable(codec, 0x21, ALC_DCVOL_EVENT); 4419 snd_hda_jack_detect_enable_callback(codec, 0x21, ALC_DCVOL_EVENT, alc_update_knob_master);
4451} 4420}
4452 4421
4453static const struct alc_fixup alc880_fixups[] = { 4422static const struct alc_fixup alc880_fixups[] = {
@@ -4812,6 +4781,8 @@ static int patch_alc880(struct hda_codec *codec)
4812 } 4781 }
4813 4782
4814 codec->patch_ops = alc_patch_ops; 4783 codec->patch_ops = alc_patch_ops;
4784 codec->patch_ops.unsol_event = alc880_unsol_event;
4785
4815 4786
4816 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 4787 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
4817 4788
@@ -4866,7 +4837,8 @@ static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
4866 spec->detect_hp = 1; 4837 spec->detect_hp = 1;
4867 spec->automute_speaker = 1; 4838 spec->automute_speaker = 1;
4868 spec->autocfg.hp_pins[0] = 0x0f; /* copy it for automute */ 4839 spec->autocfg.hp_pins[0] = 0x0f; /* copy it for automute */
4869 snd_hda_jack_detect_enable(codec, 0x0f, ALC_HP_EVENT); 4840 snd_hda_jack_detect_enable_callback(codec, 0x0f, ALC_HP_EVENT,
4841 alc_hp_automute);
4870 snd_hda_gen_add_verbs(&spec->gen, alc_gpio1_init_verbs); 4842 snd_hda_gen_add_verbs(&spec->gen, alc_gpio1_init_verbs);
4871 } 4843 }
4872} 4844}
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index bb6c50e7b5da..fe163547f906 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -4212,6 +4212,9 @@ static int stac_add_event(struct hda_codec *codec, hda_nid_t nid,
4212 return 0; 4212 return 0;
4213} 4213}
4214 4214
4215static void handle_unsol_event(struct hda_codec *codec,
4216 struct hda_jack_tbl *event);
4217
4215/* check if given nid is a valid pin and no other events are assigned 4218/* check if given nid is a valid pin and no other events are assigned
4216 * to it. If OK, assign the event, set the unsol flag, and returns 1. 4219 * to it. If OK, assign the event, set the unsol flag, and returns 1.
4217 * Otherwise, returns zero. 4220 * Otherwise, returns zero.
@@ -4229,6 +4232,7 @@ static int enable_pin_detect(struct hda_codec *codec, hda_nid_t nid,
4229 if (event->action && event->action != type) 4232 if (event->action && event->action != type)
4230 return 0; 4233 return 0;
4231 event->action = type; 4234 event->action = type;
4235 event->callback = handle_unsol_event;
4232 snd_hda_jack_detect_enable(codec, nid, 0); 4236 snd_hda_jack_detect_enable(codec, nid, 0);
4233 return 1; 4237 return 1;
4234} 4238}
@@ -4867,20 +4871,6 @@ static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid)
4867 handle_unsol_event(codec, event); 4871 handle_unsol_event(codec, event);
4868} 4872}
4869 4873
4870static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
4871{
4872 struct hda_jack_tbl *event;
4873 int tag;
4874
4875 tag = (res >> 26) & 0x7f;
4876 event = snd_hda_jack_tbl_get_from_tag(codec, tag);
4877 if (!event)
4878 return;
4879 event->jack_dirty = 1;
4880 handle_unsol_event(codec, event);
4881 snd_hda_jack_report_sync(codec);
4882}
4883
4884static int hp_blike_system(u32 subsystem_id); 4874static int hp_blike_system(u32 subsystem_id);
4885 4875
4886static void set_hp_led_gpio(struct hda_codec *codec) 4876static void set_hp_led_gpio(struct hda_codec *codec)
@@ -5131,7 +5121,7 @@ static const struct hda_codec_ops stac92xx_patch_ops = {
5131 .build_pcms = stac92xx_build_pcms, 5121 .build_pcms = stac92xx_build_pcms,
5132 .init = stac92xx_init, 5122 .init = stac92xx_init,
5133 .free = stac92xx_free, 5123 .free = stac92xx_free,
5134 .unsol_event = stac92xx_unsol_event, 5124 .unsol_event = snd_hda_jack_unsol_event,
5135#ifdef CONFIG_PM 5125#ifdef CONFIG_PM
5136 .suspend = stac92xx_suspend, 5126 .suspend = stac92xx_suspend,
5137 .resume = stac92xx_resume, 5127 .resume = stac92xx_resume,