aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_realtek.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r--sound/pci/hda/patch_realtek.c117
1 files changed, 117 insertions, 0 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 403010c9e82e..14ac9b0e740c 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -115,6 +115,7 @@ struct alc_spec {
115 115
116 int init_amp; 116 int init_amp;
117 int codec_variant; /* flag for other variants */ 117 int codec_variant; /* flag for other variants */
118 bool has_alc5505_dsp;
118 119
119 /* for PLL fix */ 120 /* for PLL fix */
120 hda_nid_t pll_nid; 121 hda_nid_t pll_nid;
@@ -2580,7 +2581,96 @@ static void alc269_shutup(struct hda_codec *codec)
2580 } 2581 }
2581} 2582}
2582 2583
2584static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg,
2585 unsigned int val)
2586{
2587 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
2588 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val & 0xffff); /* LSB */
2589 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val >> 16); /* MSB */
2590}
2591
2592static int alc5505_coef_get(struct hda_codec *codec, unsigned int index_reg)
2593{
2594 unsigned int val;
2595
2596 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
2597 val = snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
2598 & 0xffff;
2599 val |= snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
2600 << 16;
2601 return val;
2602}
2603
2604static void alc5505_dsp_halt(struct hda_codec *codec)
2605{
2606 unsigned int val;
2607
2608 alc5505_coef_set(codec, 0x3000, 0x000c); /* DSP CPU stop */
2609 alc5505_coef_set(codec, 0x880c, 0x0008); /* DDR enter self refresh */
2610 alc5505_coef_set(codec, 0x61c0, 0x11110080); /* Clock control for PLL and CPU */
2611 alc5505_coef_set(codec, 0x6230, 0xfc0d4011); /* Disable Input OP */
2612 alc5505_coef_set(codec, 0x61b4, 0x040a2b03); /* Stop PLL2 */
2613 alc5505_coef_set(codec, 0x61b0, 0x00005b17); /* Stop PLL1 */
2614 alc5505_coef_set(codec, 0x61b8, 0x04133303); /* Stop PLL3 */
2615 val = alc5505_coef_get(codec, 0x6220);
2616 alc5505_coef_set(codec, 0x6220, (val | 0x3000)); /* switch Ringbuffer clock to DBUS clock */
2617}
2618
2619static void alc5505_dsp_back_from_halt(struct hda_codec *codec)
2620{
2621 alc5505_coef_set(codec, 0x61b8, 0x04133302);
2622 alc5505_coef_set(codec, 0x61b0, 0x00005b16);
2623 alc5505_coef_set(codec, 0x61b4, 0x040a2b02);
2624 alc5505_coef_set(codec, 0x6230, 0xf80d4011);
2625 alc5505_coef_set(codec, 0x6220, 0x2002010f);
2626 alc5505_coef_set(codec, 0x880c, 0x00000004);
2627}
2628
2629static void alc5505_dsp_init(struct hda_codec *codec)
2630{
2631 unsigned int val;
2632
2633 alc5505_dsp_halt(codec);
2634 alc5505_dsp_back_from_halt(codec);
2635 alc5505_coef_set(codec, 0x61b0, 0x5b14); /* PLL1 control */
2636 alc5505_coef_set(codec, 0x61b0, 0x5b16);
2637 alc5505_coef_set(codec, 0x61b4, 0x04132b00); /* PLL2 control */
2638 alc5505_coef_set(codec, 0x61b4, 0x04132b02);
2639 alc5505_coef_set(codec, 0x61b8, 0x041f3300); /* PLL3 control*/
2640 alc5505_coef_set(codec, 0x61b8, 0x041f3302);
2641 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_CODEC_RESET, 0); /* Function reset */
2642 alc5505_coef_set(codec, 0x61b8, 0x041b3302);
2643 alc5505_coef_set(codec, 0x61b8, 0x04173302);
2644 alc5505_coef_set(codec, 0x61b8, 0x04163302);
2645 alc5505_coef_set(codec, 0x8800, 0x348b328b); /* DRAM control */
2646 alc5505_coef_set(codec, 0x8808, 0x00020022); /* DRAM control */
2647 alc5505_coef_set(codec, 0x8818, 0x00000400); /* DRAM control */
2648
2649 val = alc5505_coef_get(codec, 0x6200) >> 16; /* Read revision ID */
2650 if (val <= 3)
2651 alc5505_coef_set(codec, 0x6220, 0x2002010f); /* I/O PAD Configuration */
2652 else
2653 alc5505_coef_set(codec, 0x6220, 0x6002018f);
2654
2655 alc5505_coef_set(codec, 0x61ac, 0x055525f0); /**/
2656 alc5505_coef_set(codec, 0x61c0, 0x12230080); /* Clock control */
2657 alc5505_coef_set(codec, 0x61b4, 0x040e2b02); /* PLL2 control */
2658 alc5505_coef_set(codec, 0x61bc, 0x010234f8); /* OSC Control */
2659 alc5505_coef_set(codec, 0x880c, 0x00000004); /* DRAM Function control */
2660 alc5505_coef_set(codec, 0x880c, 0x00000003);
2661 alc5505_coef_set(codec, 0x880c, 0x00000010);
2662}
2663
2583#ifdef CONFIG_PM 2664#ifdef CONFIG_PM
2665static int alc269_suspend(struct hda_codec *codec)
2666{
2667 struct alc_spec *spec = codec->spec;
2668
2669 if (spec->has_alc5505_dsp)
2670 alc5505_dsp_halt(codec);
2671 return alc_suspend(codec);
2672}
2673
2584static int alc269_resume(struct hda_codec *codec) 2674static int alc269_resume(struct hda_codec *codec)
2585{ 2675{
2586 struct alc_spec *spec = codec->spec; 2676 struct alc_spec *spec = codec->spec;
@@ -2603,7 +2693,10 @@ static int alc269_resume(struct hda_codec *codec)
2603 2693
2604 snd_hda_codec_resume_amp(codec); 2694 snd_hda_codec_resume_amp(codec);
2605 snd_hda_codec_resume_cache(codec); 2695 snd_hda_codec_resume_cache(codec);
2696 alc_inv_dmic_sync(codec, true);
2606 hda_call_check_power_status(codec, 0x01); 2697 hda_call_check_power_status(codec, 0x01);
2698 if (spec->has_alc5505_dsp)
2699 alc5505_dsp_back_from_halt(codec);
2607 return 0; 2700 return 0;
2608} 2701}
2609#endif /* CONFIG_PM */ 2702#endif /* CONFIG_PM */
@@ -3225,6 +3318,7 @@ enum {
3225 ALC271_FIXUP_HP_GATE_MIC_JACK, 3318 ALC271_FIXUP_HP_GATE_MIC_JACK,
3226 ALC269_FIXUP_ACER_AC700, 3319 ALC269_FIXUP_ACER_AC700,
3227 ALC269_FIXUP_LIMIT_INT_MIC_BOOST, 3320 ALC269_FIXUP_LIMIT_INT_MIC_BOOST,
3321 ALC269VB_FIXUP_ORDISSIMO_EVE2,
3228}; 3322};
3229 3323
3230static const struct hda_fixup alc269_fixups[] = { 3324static const struct hda_fixup alc269_fixups[] = {
@@ -3467,6 +3561,15 @@ static const struct hda_fixup alc269_fixups[] = {
3467 .type = HDA_FIXUP_FUNC, 3561 .type = HDA_FIXUP_FUNC,
3468 .v.func = alc269_fixup_limit_int_mic_boost, 3562 .v.func = alc269_fixup_limit_int_mic_boost,
3469 }, 3563 },
3564 [ALC269VB_FIXUP_ORDISSIMO_EVE2] = {
3565 .type = HDA_FIXUP_PINS,
3566 .v.pins = (const struct hda_pintbl[]) {
3567 { 0x12, 0x99a3092f }, /* int-mic */
3568 { 0x18, 0x03a11d20 }, /* mic */
3569 { 0x19, 0x411111f0 }, /* Unused bogus pin */
3570 { }
3571 },
3572 },
3470}; 3573};
3471 3574
3472static const struct snd_pci_quirk alc269_fixup_tbl[] = { 3575static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -3482,6 +3585,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
3482 SND_PCI_QUIRK(0x1028, 0x05c9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 3585 SND_PCI_QUIRK(0x1028, 0x05c9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
3483 SND_PCI_QUIRK(0x1028, 0x05ca, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), 3586 SND_PCI_QUIRK(0x1028, 0x05ca, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
3484 SND_PCI_QUIRK(0x1028, 0x05cb, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), 3587 SND_PCI_QUIRK(0x1028, 0x05cb, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
3588 SND_PCI_QUIRK(0x1028, 0x05cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
3589 SND_PCI_QUIRK(0x1028, 0x05cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
3485 SND_PCI_QUIRK(0x1028, 0x05de, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), 3590 SND_PCI_QUIRK(0x1028, 0x05de, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
3486 SND_PCI_QUIRK(0x1028, 0x05e0, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), 3591 SND_PCI_QUIRK(0x1028, 0x05e0, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
3487 SND_PCI_QUIRK(0x1028, 0x05e9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 3592 SND_PCI_QUIRK(0x1028, 0x05e9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
@@ -3495,9 +3600,14 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
3495 SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 3600 SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
3496 SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 3601 SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
3497 SND_PCI_QUIRK(0x1028, 0x05f8, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 3602 SND_PCI_QUIRK(0x1028, 0x05f8, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
3603 SND_PCI_QUIRK(0x1028, 0x05f9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
3604 SND_PCI_QUIRK(0x1028, 0x05fb, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
3498 SND_PCI_QUIRK(0x1028, 0x0606, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 3605 SND_PCI_QUIRK(0x1028, 0x0606, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
3499 SND_PCI_QUIRK(0x1028, 0x0608, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 3606 SND_PCI_QUIRK(0x1028, 0x0608, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
3500 SND_PCI_QUIRK(0x1028, 0x0609, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 3607 SND_PCI_QUIRK(0x1028, 0x0609, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
3608 SND_PCI_QUIRK(0x1028, 0x0613, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
3609 SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
3610 SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
3501 SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), 3611 SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
3502 SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED), 3612 SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED),
3503 SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), 3613 SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1),
@@ -3539,6 +3649,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
3539 SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK), 3649 SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
3540 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K), 3650 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
3541 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), 3651 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
3652 SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
3542 3653
3543#if 0 3654#if 0
3544 /* Below is a quirk table taken from the old code. 3655 /* Below is a quirk table taken from the old code.
@@ -3718,6 +3829,11 @@ static int patch_alc269(struct hda_codec *codec)
3718 break; 3829 break;
3719 } 3830 }
3720 3831
3832 if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) {
3833 spec->has_alc5505_dsp = true;
3834 spec->init_hook = alc5505_dsp_init;
3835 }
3836
3721 /* automatic parse from the BIOS config */ 3837 /* automatic parse from the BIOS config */
3722 err = alc269_parse_auto_config(codec); 3838 err = alc269_parse_auto_config(codec);
3723 if (err < 0) 3839 if (err < 0)
@@ -3728,6 +3844,7 @@ static int patch_alc269(struct hda_codec *codec)
3728 3844
3729 codec->patch_ops = alc_patch_ops; 3845 codec->patch_ops = alc_patch_ops;
3730#ifdef CONFIG_PM 3846#ifdef CONFIG_PM
3847 codec->patch_ops.suspend = alc269_suspend;
3731 codec->patch_ops.resume = alc269_resume; 3848 codec->patch_ops.resume = alc269_resume;
3732#endif 3849#endif
3733 spec->shutup = alc269_shutup; 3850 spec->shutup = alc269_shutup;