aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorKailang Yang <kailang@realtek.com>2013-08-22 04:03:50 -0400
committerTakashi Iwai <tiwai@suse.de>2013-08-22 05:54:58 -0400
commit2af02be71a8ae28ae4e3b82a2866b1aa1f43d8fb (patch)
treed50d04bc2e1023eec373aea08ddbad1f3de8f824 /sound/pci
parent528ba522e18b95d25adc62367f04290776c390e5 (diff)
ALSA: hda - Fix ALC283 headphone pop-noise better
Fixed ALC283 D3 to D0 and D0 to D3 Headphone pop noise. The previous fix [c5177c86: ALSA: hda - Fix the noise after suspend on ALC283 codec] doesn't work sufficiently for some laptops. Signed-off-by: Kailang Yang <kailang@realtek.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/patch_realtek.c111
1 files changed, 76 insertions, 35 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 7d0063959400..4bdccd1a415c 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -2527,6 +2527,7 @@ enum {
2527 ALC269_TYPE_ALC269VD, 2527 ALC269_TYPE_ALC269VD,
2528 ALC269_TYPE_ALC280, 2528 ALC269_TYPE_ALC280,
2529 ALC269_TYPE_ALC282, 2529 ALC269_TYPE_ALC282,
2530 ALC269_TYPE_ALC283,
2530 ALC269_TYPE_ALC284, 2531 ALC269_TYPE_ALC284,
2531 ALC269_TYPE_ALC286, 2532 ALC269_TYPE_ALC286,
2532}; 2533};
@@ -2552,6 +2553,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
2552 case ALC269_TYPE_ALC269VB: 2553 case ALC269_TYPE_ALC269VB:
2553 case ALC269_TYPE_ALC269VD: 2554 case ALC269_TYPE_ALC269VD:
2554 case ALC269_TYPE_ALC282: 2555 case ALC269_TYPE_ALC282:
2556 case ALC269_TYPE_ALC283:
2555 case ALC269_TYPE_ALC286: 2557 case ALC269_TYPE_ALC286:
2556 ssids = alc269_ssids; 2558 ssids = alc269_ssids;
2557 break; 2559 break;
@@ -2586,6 +2588,74 @@ static void alc269_shutup(struct hda_codec *codec)
2586 snd_hda_shutup_pins(codec); 2588 snd_hda_shutup_pins(codec);
2587} 2589}
2588 2590
2591static void alc283_init(struct hda_codec *codec)
2592{
2593 struct alc_spec *spec = codec->spec;
2594 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
2595 bool hp_pin_sense;
2596 int val;
2597
2598 if (!hp_pin)
2599 return;
2600 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
2601
2602 /* Index 0x43 Direct Drive HP AMP LPM Control 1 */
2603 /* Headphone capless set to high power mode */
2604 alc_write_coef_idx(codec, 0x43, 0x9004);
2605
2606 snd_hda_codec_write(codec, hp_pin, 0,
2607 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
2608
2609 if (hp_pin_sense)
2610 msleep(85);
2611
2612 snd_hda_codec_write(codec, hp_pin, 0,
2613 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
2614
2615 if (hp_pin_sense)
2616 msleep(85);
2617 /* Index 0x46 Combo jack auto switch control 2 */
2618 /* 3k pull low control for Headset jack. */
2619 val = alc_read_coef_idx(codec, 0x46);
2620 alc_write_coef_idx(codec, 0x46, val & ~(3 << 12));
2621 /* Headphone capless set to normal mode */
2622 alc_write_coef_idx(codec, 0x43, 0x9614);
2623}
2624
2625static void alc283_shutup(struct hda_codec *codec)
2626{
2627 struct alc_spec *spec = codec->spec;
2628 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
2629 bool hp_pin_sense;
2630 int val;
2631
2632 if (!hp_pin) {
2633 alc269_shutup(codec);
2634 return;
2635 }
2636
2637 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
2638
2639 alc_write_coef_idx(codec, 0x43, 0x9004);
2640
2641 snd_hda_codec_write(codec, hp_pin, 0,
2642 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
2643
2644 if (hp_pin_sense)
2645 msleep(85);
2646
2647 snd_hda_codec_write(codec, hp_pin, 0,
2648 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
2649
2650 val = alc_read_coef_idx(codec, 0x46);
2651 alc_write_coef_idx(codec, 0x46, val | (3 << 12));
2652
2653 if (hp_pin_sense)
2654 msleep(85);
2655 snd_hda_shutup_pins(codec);
2656 alc_write_coef_idx(codec, 0x43, 0x9614);
2657}
2658
2589static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg, 2659static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg,
2590 unsigned int val) 2660 unsigned int val)
2591{ 2661{
@@ -2715,12 +2785,6 @@ static int alc269_resume(struct hda_codec *codec)
2715 if (spec->has_alc5505_dsp) 2785 if (spec->has_alc5505_dsp)
2716 alc5505_dsp_resume(codec); 2786 alc5505_dsp_resume(codec);
2717 2787
2718 /* clear the power-save mode for ALC283 */
2719 if (codec->vendor_id == 0x10ec0283) {
2720 alc_write_coef_idx(codec, 0x4, 0xaf01);
2721 alc_write_coef_idx(codec, 0x6, 0x2104);
2722 }
2723
2724 return 0; 2788 return 0;
2725} 2789}
2726#endif /* CONFIG_PM */ 2790#endif /* CONFIG_PM */
@@ -3815,30 +3879,6 @@ static void alc269_fill_coef(struct hda_codec *codec)
3815 alc_write_coef_idx(codec, 0x4, val | (1<<11)); 3879 alc_write_coef_idx(codec, 0x4, val | (1<<11));
3816} 3880}
3817 3881
3818/* don't clear mic pin; otherwise it results in noise in D3 */
3819static void alc283_headset_shutup(struct hda_codec *codec)
3820{
3821 int i;
3822
3823 if (codec->bus->shutdown)
3824 return;
3825
3826 for (i = 0; i < codec->init_pins.used; i++) {
3827 struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
3828 /* use read here for syncing after issuing each verb */
3829 if (pin->nid != 0x19)
3830 snd_hda_codec_read(codec, pin->nid, 0,
3831 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
3832 }
3833
3834 alc_write_coef_idx(codec, 0x4, 0x0f01); /* power save */
3835 alc_write_coef_idx(codec, 0x6, 0x2100); /* power save */
3836 snd_hda_codec_write(codec, 0x19, 0,
3837 AC_VERB_SET_PIN_WIDGET_CONTROL,
3838 PIN_VREFHIZ);
3839 codec->pins_shutup = 1;
3840}
3841
3842/* 3882/*
3843 */ 3883 */
3844static int patch_alc269(struct hda_codec *codec) 3884static int patch_alc269(struct hda_codec *codec)
@@ -3853,9 +3893,6 @@ static int patch_alc269(struct hda_codec *codec)
3853 spec = codec->spec; 3893 spec = codec->spec;
3854 spec->gen.shared_mic_vref_pin = 0x18; 3894 spec->gen.shared_mic_vref_pin = 0x18;
3855 3895
3856 if (codec->vendor_id == 0x10ec0283)
3857 spec->shutup = alc283_headset_shutup;
3858
3859 snd_hda_pick_fixup(codec, alc269_fixup_models, 3896 snd_hda_pick_fixup(codec, alc269_fixup_models,
3860 alc269_fixup_tbl, alc269_fixups); 3897 alc269_fixup_tbl, alc269_fixups);
3861 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 3898 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
@@ -3897,11 +3934,15 @@ static int patch_alc269(struct hda_codec *codec)
3897 case 0x10ec0290: 3934 case 0x10ec0290:
3898 spec->codec_variant = ALC269_TYPE_ALC280; 3935 spec->codec_variant = ALC269_TYPE_ALC280;
3899 break; 3936 break;
3900 case 0x10ec0233:
3901 case 0x10ec0282: 3937 case 0x10ec0282:
3902 case 0x10ec0283:
3903 spec->codec_variant = ALC269_TYPE_ALC282; 3938 spec->codec_variant = ALC269_TYPE_ALC282;
3904 break; 3939 break;
3940 case 0x10ec0233:
3941 case 0x10ec0283:
3942 spec->codec_variant = ALC269_TYPE_ALC283;
3943 spec->shutup = alc283_shutup;
3944 spec->init_hook = alc283_init;
3945 break;
3905 case 0x10ec0284: 3946 case 0x10ec0284:
3906 case 0x10ec0292: 3947 case 0x10ec0292:
3907 spec->codec_variant = ALC269_TYPE_ALC284; 3948 spec->codec_variant = ALC269_TYPE_ALC284;