Commit 977ddd6b authored by Kailang Yang's avatar Kailang Yang Committed by Takashi Iwai

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: default avatarKailang Yang <kailang@realtek.com>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 9ad0e496
...@@ -1673,6 +1673,15 @@ static int alc_read_coef_idx(struct hda_codec *codec, ...@@ -1673,6 +1673,15 @@ static int alc_read_coef_idx(struct hda_codec *codec,
return val; return val;
} }
static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
unsigned int coef_val)
{
snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
coef_idx);
snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF,
coef_val);
}
/* set right pin controls for digital I/O */ /* set right pin controls for digital I/O */
static void alc_auto_init_digital(struct hda_codec *codec) static void alc_auto_init_digital(struct hda_codec *codec)
{ {
...@@ -14598,6 +14607,68 @@ static void alc269_auto_init(struct hda_codec *codec) ...@@ -14598,6 +14607,68 @@ static void alc269_auto_init(struct hda_codec *codec)
alc_inithook(codec); alc_inithook(codec);
} }
#ifdef CONFIG_SND_HDA_POWER_SAVE
static int alc269_suspend(struct hda_codec *codec, pm_message_t state)
{
struct alc_spec *spec = codec->spec;
int val;
if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
val = alc_read_coef_idx(codec, 0x04);
/* Power down output pin */
alc_write_coef_idx(codec, 0x04, val & ~(1<<11));
}
if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
val = alc_read_coef_idx(codec, 0x04);
/* Power down output pin */
alc_write_coef_idx(codec, 0x04, val & ~(1<<11));
msleep(150);
}
alc_shutup(codec);
if (spec && spec->power_hook)
spec->power_hook(codec);
return 0;
}
#endif
#ifdef SND_HDA_NEEDS_RESUME
static int alc269_resume(struct hda_codec *codec)
{
int val;
if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
val = alc_read_coef_idx(codec, 0x04);
/* Power down output pin */
alc_write_coef_idx(codec, 0x04, val & ~(1<<11));
msleep(150);
}
codec->patch_ops.init(codec);
if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
val = alc_read_coef_idx(codec, 0x04);
/* Power up output pin */
alc_write_coef_idx(codec, 0x04, val | (1<<11));
msleep(200);
}
if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
val = alc_read_coef_idx(codec, 0x04);
/* Power up output pin */
alc_write_coef_idx(codec, 0x04, val | (1<<11));
}
snd_hda_codec_resume_amp(codec);
snd_hda_codec_resume_cache(codec);
#ifdef CONFIG_SND_HDA_POWER_SAVE
if (codec->patch_ops.check_power_status)
codec->patch_ops.check_power_status(codec, 0x01);
#endif
return 0;
}
#endif
enum { enum {
ALC269_FIXUP_SONY_VAIO, ALC269_FIXUP_SONY_VAIO,
}; };
...@@ -14814,6 +14885,41 @@ static struct alc_config_preset alc269_presets[] = { ...@@ -14814,6 +14885,41 @@ static struct alc_config_preset alc269_presets[] = {
}, },
}; };
static int alc269_fill_coef(struct hda_codec *codec)
{
int val;
if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) {
alc_write_coef_idx(codec, 0xf, 0x960b);
alc_write_coef_idx(codec, 0xe, 0x8817);
}
if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) {
alc_write_coef_idx(codec, 0xf, 0x960b);
alc_write_coef_idx(codec, 0xe, 0x8814);
}
if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
val = alc_read_coef_idx(codec, 0x04);
/* Power up output pin */
alc_write_coef_idx(codec, 0x04, val | (1<<11));
}
if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
val = alc_read_coef_idx(codec, 0xd);
if ((val & 0x0c00) >> 10 != 0x1) {
/* Capless ramp up clock control */
alc_write_coef_idx(codec, 0xd, val | 1<<10);
}
val = alc_read_coef_idx(codec, 0x17);
if ((val & 0x01c0) >> 6 != 0x4) {
/* Class D power on reset */
alc_write_coef_idx(codec, 0x17, val | 1<<7);
}
}
return 0;
}
static int patch_alc269(struct hda_codec *codec) static int patch_alc269(struct hda_codec *codec)
{ {
struct alc_spec *spec; struct alc_spec *spec;
...@@ -14839,6 +14945,8 @@ static int patch_alc269(struct hda_codec *codec) ...@@ -14839,6 +14945,8 @@ static int patch_alc269(struct hda_codec *codec)
} else } else
alc_fix_pll_init(codec, 0x20, 0x04, 15); alc_fix_pll_init(codec, 0x20, 0x04, 15);
alc269_fill_coef(codec);
board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
alc269_models, alc269_models,
alc269_cfg_tbl); alc269_cfg_tbl);
...@@ -14917,6 +15025,12 @@ static int patch_alc269(struct hda_codec *codec) ...@@ -14917,6 +15025,12 @@ static int patch_alc269(struct hda_codec *codec)
spec->vmaster_nid = 0x02; spec->vmaster_nid = 0x02;
codec->patch_ops = alc_patch_ops; codec->patch_ops = alc_patch_ops;
#ifdef CONFIG_SND_HDA_POWER_SAVE
codec->patch_ops.suspend = alc269_suspend;
#endif
#ifdef SND_HDA_NEEDS_RESUME
codec->patch_ops.resume = alc269_resume;
#endif
if (board_config == ALC269_AUTO) if (board_config == ALC269_AUTO)
spec->init_hook = alc269_auto_init; spec->init_hook = alc269_auto_init;
#ifdef CONFIG_SND_HDA_POWER_SAVE #ifdef CONFIG_SND_HDA_POWER_SAVE
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment