diff options
author | Kailang Yang <kailang@realtek.com> | 2010-09-15 04:02:29 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2010-09-16 01:32:30 -0400 |
commit | 977ddd6b2e63716cfefe669bbdb30ec0bcea1fe4 (patch) | |
tree | b82f3eb46002e981a84e6f12221025b923cbb2d4 /sound/pci | |
parent | 9ad0e496519d99eb2c34f01e41500a775122c744 (diff) |
ALSA: hda - Set up COEFs for ALC269 to avoid click noises at power-saving
For avoiding the click noises at power-saving, set some COEF values
for ALC269* codecs.
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.c | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 3b040870365d..ab2947d87232 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -1673,6 +1673,15 @@ static int alc_read_coef_idx(struct hda_codec *codec, | |||
1673 | return val; | 1673 | return val; |
1674 | } | 1674 | } |
1675 | 1675 | ||
1676 | static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx, | ||
1677 | unsigned int coef_val) | ||
1678 | { | ||
1679 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, | ||
1680 | coef_idx); | ||
1681 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, | ||
1682 | coef_val); | ||
1683 | } | ||
1684 | |||
1676 | /* set right pin controls for digital I/O */ | 1685 | /* set right pin controls for digital I/O */ |
1677 | static void alc_auto_init_digital(struct hda_codec *codec) | 1686 | static void alc_auto_init_digital(struct hda_codec *codec) |
1678 | { | 1687 | { |
@@ -14598,6 +14607,68 @@ static void alc269_auto_init(struct hda_codec *codec) | |||
14598 | alc_inithook(codec); | 14607 | alc_inithook(codec); |
14599 | } | 14608 | } |
14600 | 14609 | ||
14610 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
14611 | static int alc269_suspend(struct hda_codec *codec, pm_message_t state) | ||
14612 | { | ||
14613 | struct alc_spec *spec = codec->spec; | ||
14614 | int val; | ||
14615 | |||
14616 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) { | ||
14617 | val = alc_read_coef_idx(codec, 0x04); | ||
14618 | /* Power down output pin */ | ||
14619 | alc_write_coef_idx(codec, 0x04, val & ~(1<<11)); | ||
14620 | } | ||
14621 | |||
14622 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { | ||
14623 | val = alc_read_coef_idx(codec, 0x04); | ||
14624 | /* Power down output pin */ | ||
14625 | alc_write_coef_idx(codec, 0x04, val & ~(1<<11)); | ||
14626 | msleep(150); | ||
14627 | } | ||
14628 | |||
14629 | alc_shutup(codec); | ||
14630 | if (spec && spec->power_hook) | ||
14631 | spec->power_hook(codec); | ||
14632 | return 0; | ||
14633 | } | ||
14634 | #endif | ||
14635 | #ifdef SND_HDA_NEEDS_RESUME | ||
14636 | static int alc269_resume(struct hda_codec *codec) | ||
14637 | { | ||
14638 | int val; | ||
14639 | |||
14640 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { | ||
14641 | val = alc_read_coef_idx(codec, 0x04); | ||
14642 | /* Power down output pin */ | ||
14643 | alc_write_coef_idx(codec, 0x04, val & ~(1<<11)); | ||
14644 | msleep(150); | ||
14645 | } | ||
14646 | |||
14647 | codec->patch_ops.init(codec); | ||
14648 | |||
14649 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) { | ||
14650 | val = alc_read_coef_idx(codec, 0x04); | ||
14651 | /* Power up output pin */ | ||
14652 | alc_write_coef_idx(codec, 0x04, val | (1<<11)); | ||
14653 | msleep(200); | ||
14654 | } | ||
14655 | |||
14656 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { | ||
14657 | val = alc_read_coef_idx(codec, 0x04); | ||
14658 | /* Power up output pin */ | ||
14659 | alc_write_coef_idx(codec, 0x04, val | (1<<11)); | ||
14660 | } | ||
14661 | |||
14662 | snd_hda_codec_resume_amp(codec); | ||
14663 | snd_hda_codec_resume_cache(codec); | ||
14664 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
14665 | if (codec->patch_ops.check_power_status) | ||
14666 | codec->patch_ops.check_power_status(codec, 0x01); | ||
14667 | #endif | ||
14668 | return 0; | ||
14669 | } | ||
14670 | #endif | ||
14671 | |||
14601 | enum { | 14672 | enum { |
14602 | ALC269_FIXUP_SONY_VAIO, | 14673 | ALC269_FIXUP_SONY_VAIO, |
14603 | }; | 14674 | }; |
@@ -14814,6 +14885,41 @@ static struct alc_config_preset alc269_presets[] = { | |||
14814 | }, | 14885 | }, |
14815 | }; | 14886 | }; |
14816 | 14887 | ||
14888 | static int alc269_fill_coef(struct hda_codec *codec) | ||
14889 | { | ||
14890 | int val; | ||
14891 | |||
14892 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) { | ||
14893 | alc_write_coef_idx(codec, 0xf, 0x960b); | ||
14894 | alc_write_coef_idx(codec, 0xe, 0x8817); | ||
14895 | } | ||
14896 | |||
14897 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) { | ||
14898 | alc_write_coef_idx(codec, 0xf, 0x960b); | ||
14899 | alc_write_coef_idx(codec, 0xe, 0x8814); | ||
14900 | } | ||
14901 | |||
14902 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) { | ||
14903 | val = alc_read_coef_idx(codec, 0x04); | ||
14904 | /* Power up output pin */ | ||
14905 | alc_write_coef_idx(codec, 0x04, val | (1<<11)); | ||
14906 | } | ||
14907 | |||
14908 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { | ||
14909 | val = alc_read_coef_idx(codec, 0xd); | ||
14910 | if ((val & 0x0c00) >> 10 != 0x1) { | ||
14911 | /* Capless ramp up clock control */ | ||
14912 | alc_write_coef_idx(codec, 0xd, val | 1<<10); | ||
14913 | } | ||
14914 | val = alc_read_coef_idx(codec, 0x17); | ||
14915 | if ((val & 0x01c0) >> 6 != 0x4) { | ||
14916 | /* Class D power on reset */ | ||
14917 | alc_write_coef_idx(codec, 0x17, val | 1<<7); | ||
14918 | } | ||
14919 | } | ||
14920 | return 0; | ||
14921 | } | ||
14922 | |||
14817 | static int patch_alc269(struct hda_codec *codec) | 14923 | static int patch_alc269(struct hda_codec *codec) |
14818 | { | 14924 | { |
14819 | struct alc_spec *spec; | 14925 | struct alc_spec *spec; |
@@ -14839,6 +14945,8 @@ static int patch_alc269(struct hda_codec *codec) | |||
14839 | } else | 14945 | } else |
14840 | alc_fix_pll_init(codec, 0x20, 0x04, 15); | 14946 | alc_fix_pll_init(codec, 0x20, 0x04, 15); |
14841 | 14947 | ||
14948 | alc269_fill_coef(codec); | ||
14949 | |||
14842 | board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, | 14950 | board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, |
14843 | alc269_models, | 14951 | alc269_models, |
14844 | alc269_cfg_tbl); | 14952 | alc269_cfg_tbl); |
@@ -14917,6 +15025,12 @@ static int patch_alc269(struct hda_codec *codec) | |||
14917 | spec->vmaster_nid = 0x02; | 15025 | spec->vmaster_nid = 0x02; |
14918 | 15026 | ||
14919 | codec->patch_ops = alc_patch_ops; | 15027 | codec->patch_ops = alc_patch_ops; |
15028 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
15029 | codec->patch_ops.suspend = alc269_suspend; | ||
15030 | #endif | ||
15031 | #ifdef SND_HDA_NEEDS_RESUME | ||
15032 | codec->patch_ops.resume = alc269_resume; | ||
15033 | #endif | ||
14920 | if (board_config == ALC269_AUTO) | 15034 | if (board_config == ALC269_AUTO) |
14921 | spec->init_hook = alc269_auto_init; | 15035 | spec->init_hook = alc269_auto_init; |
14922 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 15036 | #ifdef CONFIG_SND_HDA_POWER_SAVE |