[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:
@@ -285,6 +285,10 @@ struct alc_spec {
|
|||||||
#ifdef CONFIG_SND_HDA_POWER_SAVE
|
#ifdef CONFIG_SND_HDA_POWER_SAVE
|
||||||
struct hda_loopback_check loopback;
|
struct hda_loopback_check loopback;
|
||||||
#endif
|
#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)
|
static void alc_sku_automute(struct hda_codec *codec)
|
||||||
{
|
{
|
||||||
struct alc_spec *spec = codec->spec;
|
struct alc_spec *spec = codec->spec;
|
||||||
@@ -2400,6 +2436,8 @@ static int alc_init(struct hda_codec *codec)
|
|||||||
struct alc_spec *spec = codec->spec;
|
struct alc_spec *spec = codec->spec;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
alc_fix_pll(codec);
|
||||||
|
|
||||||
for (i = 0; i < spec->num_init_verbs; i++)
|
for (i = 0; i < spec->num_init_verbs; i++)
|
||||||
snd_hda_sequence_write(codec, spec->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;
|
codec->spec = spec;
|
||||||
|
|
||||||
|
alc_fix_pll_init(codec, 0x20, 0x0a, 10);
|
||||||
|
|
||||||
board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
|
board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
|
||||||
alc883_models,
|
alc883_models,
|
||||||
alc883_cfg_tbl);
|
alc883_cfg_tbl);
|
||||||
@@ -9886,6 +9926,8 @@ static int patch_alc262(struct hda_codec *codec)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
alc_fix_pll_init(codec, 0x20, 0x0a, 10);
|
||||||
|
|
||||||
board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
|
board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
|
||||||
alc262_models,
|
alc262_models,
|
||||||
alc262_cfg_tbl);
|
alc262_cfg_tbl);
|
||||||
@@ -11196,6 +11238,8 @@ static int patch_alc269(struct hda_codec *codec)
|
|||||||
|
|
||||||
codec->spec = spec;
|
codec->spec = spec;
|
||||||
|
|
||||||
|
alc_fix_pll_init(codec, 0x20, 0x04, 15);
|
||||||
|
|
||||||
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);
|
||||||
@@ -14531,6 +14575,8 @@ static int patch_alc662(struct hda_codec *codec)
|
|||||||
|
|
||||||
codec->spec = spec;
|
codec->spec = spec;
|
||||||
|
|
||||||
|
alc_fix_pll_init(codec, 0x20, 0x04, 15);
|
||||||
|
|
||||||
board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
|
board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
|
||||||
alc662_models,
|
alc662_models,
|
||||||
alc662_cfg_tbl);
|
alc662_cfg_tbl);
|
||||||
|
Reference in New Issue
Block a user