aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2014-08-15 11:35:00 -0400
committerTakashi Iwai <tiwai@suse.de>2014-08-16 03:10:26 -0400
commitf3ee07d8b6e061bf34a7167c3f564e8da4360a99 (patch)
treef8e6246f10a4e3d1b97eaf90ba98958f0401eb9b /sound
parent01d5500f35ad97887d786af03486d03e67965a6d (diff)
ALSA: hda/realtek - Avoid setting wrong COEF on ALC269 & co
ALC269 & co have many vendor-specific setups with COEF verbs. However, some verbs seem specific to some codec versions and they result in the codec stalling. Typically, such a case can be avoided by checking the return value from reading a COEF. If the return value is -1, it implies that the COEF is invalid, thus it shouldn't be written. This patch adds the invalid COEF checks in appropriate places accessing ALC269 and its variants. The patch actually fixes the resume problem on Acer AO725 laptop. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=52181 Tested-by: Francesco Muzio <muziofg@gmail.com> Cc: <stable@vger.kernel.org> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/hda/patch_realtek.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 6b38ec3c6e57..b32ce086d2e0 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -181,6 +181,8 @@ static void alc_fix_pll(struct hda_codec *codec)
181 spec->pll_coef_idx); 181 spec->pll_coef_idx);
182 val = snd_hda_codec_read(codec, spec->pll_nid, 0, 182 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
183 AC_VERB_GET_PROC_COEF, 0); 183 AC_VERB_GET_PROC_COEF, 0);
184 if (val == -1)
185 return;
184 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, 186 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
185 spec->pll_coef_idx); 187 spec->pll_coef_idx);
186 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF, 188 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
@@ -2806,6 +2808,8 @@ static void alc286_shutup(struct hda_codec *codec)
2806static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up) 2808static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up)
2807{ 2809{
2808 int val = alc_read_coef_idx(codec, 0x04); 2810 int val = alc_read_coef_idx(codec, 0x04);
2811 if (val == -1)
2812 return;
2809 if (power_up) 2813 if (power_up)
2810 val |= 1 << 11; 2814 val |= 1 << 11;
2811 else 2815 else
@@ -5311,27 +5315,30 @@ static void alc269_fill_coef(struct hda_codec *codec)
5311 if ((alc_get_coef0(codec) & 0x00ff) == 0x017) { 5315 if ((alc_get_coef0(codec) & 0x00ff) == 0x017) {
5312 val = alc_read_coef_idx(codec, 0x04); 5316 val = alc_read_coef_idx(codec, 0x04);
5313 /* Power up output pin */ 5317 /* Power up output pin */
5314 alc_write_coef_idx(codec, 0x04, val | (1<<11)); 5318 if (val != -1)
5319 alc_write_coef_idx(codec, 0x04, val | (1<<11));
5315 } 5320 }
5316 5321
5317 if ((alc_get_coef0(codec) & 0x00ff) == 0x018) { 5322 if ((alc_get_coef0(codec) & 0x00ff) == 0x018) {
5318 val = alc_read_coef_idx(codec, 0xd); 5323 val = alc_read_coef_idx(codec, 0xd);
5319 if ((val & 0x0c00) >> 10 != 0x1) { 5324 if (val != -1 && (val & 0x0c00) >> 10 != 0x1) {
5320 /* Capless ramp up clock control */ 5325 /* Capless ramp up clock control */
5321 alc_write_coef_idx(codec, 0xd, val | (1<<10)); 5326 alc_write_coef_idx(codec, 0xd, val | (1<<10));
5322 } 5327 }
5323 val = alc_read_coef_idx(codec, 0x17); 5328 val = alc_read_coef_idx(codec, 0x17);
5324 if ((val & 0x01c0) >> 6 != 0x4) { 5329 if (val != -1 && (val & 0x01c0) >> 6 != 0x4) {
5325 /* Class D power on reset */ 5330 /* Class D power on reset */
5326 alc_write_coef_idx(codec, 0x17, val | (1<<7)); 5331 alc_write_coef_idx(codec, 0x17, val | (1<<7));
5327 } 5332 }
5328 } 5333 }
5329 5334
5330 val = alc_read_coef_idx(codec, 0xd); /* Class D */ 5335 val = alc_read_coef_idx(codec, 0xd); /* Class D */
5331 alc_write_coef_idx(codec, 0xd, val | (1<<14)); 5336 if (val != -1)
5337 alc_write_coef_idx(codec, 0xd, val | (1<<14));
5332 5338
5333 val = alc_read_coef_idx(codec, 0x4); /* HP */ 5339 val = alc_read_coef_idx(codec, 0x4); /* HP */
5334 alc_write_coef_idx(codec, 0x4, val | (1<<11)); 5340 if (val != -1)
5341 alc_write_coef_idx(codec, 0x4, val | (1<<11));
5335} 5342}
5336 5343
5337/* 5344/*