diff options
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 117 |
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 | ||
2584 | static 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 | |||
2592 | static 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 | |||
2604 | static 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 | |||
2619 | static 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 | |||
2629 | static 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 |
2665 | static 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 | |||
2584 | static int alc269_resume(struct hda_codec *codec) | 2674 | static 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 | ||
3230 | static const struct hda_fixup alc269_fixups[] = { | 3324 | static 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 | ||
3472 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { | 3575 | static 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; |