diff options
Diffstat (limited to 'sound/pci/hda')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 048cb84721fa..7997e13b59a6 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -285,6 +285,10 @@ struct alc_spec { | |||
285 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 285 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
286 | struct hda_loopback_check loopback; | 286 | struct hda_loopback_check loopback; |
287 | #endif | 287 | #endif |
288 | |||
289 | /* for PLL fix */ | ||
290 | hda_nid_t pll_nid; | ||
291 | unsigned int pll_coef_idx, pll_coef_bit; | ||
288 | }; | 292 | }; |
289 | 293 | ||
290 | /* | 294 | /* |
@@ -752,6 +756,38 @@ static struct hda_verb alc_gpio3_init_verbs[] = { | |||
752 | { } | 756 | { } |
753 | }; | 757 | }; |
754 | 758 | ||
759 | /* | ||
760 | * Fix hardware PLL issue | ||
761 | * On some codecs, the analog PLL gating control must be off while | ||
762 | * the default value is 1. | ||
763 | */ | ||
764 | static void alc_fix_pll(struct hda_codec *codec) | ||
765 | { | ||
766 | struct alc_spec *spec = codec->spec; | ||
767 | unsigned int val; | ||
768 | |||
769 | if (!spec->pll_nid) | ||
770 | return; | ||
771 | snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, | ||
772 | spec->pll_coef_idx); | ||
773 | val = snd_hda_codec_read(codec, spec->pll_nid, 0, | ||
774 | AC_VERB_GET_PROC_COEF, 0); | ||
775 | snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, | ||
776 | spec->pll_coef_idx); | ||
777 | snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF, | ||
778 | val & ~(1 << spec->pll_coef_bit)); | ||
779 | } | ||
780 | |||
781 | static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid, | ||
782 | unsigned int coef_idx, unsigned int coef_bit) | ||
783 | { | ||
784 | struct alc_spec *spec = codec->spec; | ||
785 | spec->pll_nid = nid; | ||
786 | spec->pll_coef_idx = coef_idx; | ||
787 | spec->pll_coef_bit = coef_bit; | ||
788 | alc_fix_pll(codec); | ||
789 | } | ||
790 | |||
755 | static void alc_sku_automute(struct hda_codec *codec) | 791 | static void alc_sku_automute(struct hda_codec *codec) |
756 | { | 792 | { |
757 | struct alc_spec *spec = codec->spec; | 793 | struct alc_spec *spec = codec->spec; |
@@ -2400,6 +2436,8 @@ static int alc_init(struct hda_codec *codec) | |||
2400 | struct alc_spec *spec = codec->spec; | 2436 | struct alc_spec *spec = codec->spec; |
2401 | unsigned int i; | 2437 | unsigned int i; |
2402 | 2438 | ||
2439 | alc_fix_pll(codec); | ||
2440 | |||
2403 | for (i = 0; i < spec->num_init_verbs; i++) | 2441 | for (i = 0; i < spec->num_init_verbs; i++) |
2404 | snd_hda_sequence_write(codec, spec->init_verbs[i]); | 2442 | snd_hda_sequence_write(codec, spec->init_verbs[i]); |
2405 | 2443 | ||
@@ -8286,6 +8324,8 @@ static int patch_alc883(struct hda_codec *codec) | |||
8286 | 8324 | ||
8287 | codec->spec = spec; | 8325 | codec->spec = spec; |
8288 | 8326 | ||
8327 | alc_fix_pll_init(codec, 0x20, 0x0a, 10); | ||
8328 | |||
8289 | board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST, | 8329 | board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST, |
8290 | alc883_models, | 8330 | alc883_models, |
8291 | alc883_cfg_tbl); | 8331 | alc883_cfg_tbl); |
@@ -9886,6 +9926,8 @@ static int patch_alc262(struct hda_codec *codec) | |||
9886 | } | 9926 | } |
9887 | #endif | 9927 | #endif |
9888 | 9928 | ||
9929 | alc_fix_pll_init(codec, 0x20, 0x0a, 10); | ||
9930 | |||
9889 | board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST, | 9931 | board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST, |
9890 | alc262_models, | 9932 | alc262_models, |
9891 | alc262_cfg_tbl); | 9933 | alc262_cfg_tbl); |
@@ -11196,6 +11238,8 @@ static int patch_alc269(struct hda_codec *codec) | |||
11196 | 11238 | ||
11197 | codec->spec = spec; | 11239 | codec->spec = spec; |
11198 | 11240 | ||
11241 | alc_fix_pll_init(codec, 0x20, 0x04, 15); | ||
11242 | |||
11199 | board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, | 11243 | board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, |
11200 | alc269_models, | 11244 | alc269_models, |
11201 | alc269_cfg_tbl); | 11245 | alc269_cfg_tbl); |
@@ -14531,6 +14575,8 @@ static int patch_alc662(struct hda_codec *codec) | |||
14531 | 14575 | ||
14532 | codec->spec = spec; | 14576 | codec->spec = spec; |
14533 | 14577 | ||
14578 | alc_fix_pll_init(codec, 0x20, 0x04, 15); | ||
14579 | |||
14534 | board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST, | 14580 | board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST, |
14535 | alc662_models, | 14581 | alc662_models, |
14536 | alc662_cfg_tbl); | 14582 | alc662_cfg_tbl); |