[ALSA] hda - Fix PLL gating control on Realtek codecs

On some Realtek codecs, the analog PLL gating control bit must be set
off while the default value is 1.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Takashi Iwai 2008-06-04 12:39:38 +02:00
parent 17bba1b72d
commit 2c3bf9abb1
1 changed files with 46 additions and 0 deletions

View File

@ -285,6 +285,10 @@ struct alc_spec {
#ifdef CONFIG_SND_HDA_POWER_SAVE
struct hda_loopback_check loopback;
#endif
/* for PLL fix */
hda_nid_t pll_nid;
unsigned int pll_coef_idx, pll_coef_bit;
};
/*
@ -752,6 +756,38 @@ static struct hda_verb alc_gpio3_init_verbs[] = {
{ }
};
/*
* Fix hardware PLL issue
* On some codecs, the analog PLL gating control must be off while
* the default value is 1.
*/
static void alc_fix_pll(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
unsigned int val;
if (!spec->pll_nid)
return;
snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
spec->pll_coef_idx);
val = snd_hda_codec_read(codec, spec->pll_nid, 0,
AC_VERB_GET_PROC_COEF, 0);
snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
spec->pll_coef_idx);
snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
val & ~(1 << spec->pll_coef_bit));
}
static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
unsigned int coef_idx, unsigned int coef_bit)
{
struct alc_spec *spec = codec->spec;
spec->pll_nid = nid;
spec->pll_coef_idx = coef_idx;
spec->pll_coef_bit = coef_bit;
alc_fix_pll(codec);
}
static void alc_sku_automute(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
@ -2400,6 +2436,8 @@ static int alc_init(struct hda_codec *codec)
struct alc_spec *spec = codec->spec;
unsigned int i;
alc_fix_pll(codec);
for (i = 0; i < spec->num_init_verbs; i++)
snd_hda_sequence_write(codec, spec->init_verbs[i]);
@ -8286,6 +8324,8 @@ static int patch_alc883(struct hda_codec *codec)
codec->spec = spec;
alc_fix_pll_init(codec, 0x20, 0x0a, 10);
board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
alc883_models,
alc883_cfg_tbl);
@ -9886,6 +9926,8 @@ static int patch_alc262(struct hda_codec *codec)
}
#endif
alc_fix_pll_init(codec, 0x20, 0x0a, 10);
board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
alc262_models,
alc262_cfg_tbl);
@ -11196,6 +11238,8 @@ static int patch_alc269(struct hda_codec *codec)
codec->spec = spec;
alc_fix_pll_init(codec, 0x20, 0x04, 15);
board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
alc269_models,
alc269_cfg_tbl);
@ -14531,6 +14575,8 @@ static int patch_alc662(struct hda_codec *codec)
codec->spec = spec;
alc_fix_pll_init(codec, 0x20, 0x04, 15);
board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
alc662_models,
alc662_cfg_tbl);