Commit f3ee07d8 authored by Takashi Iwai's avatar Takashi Iwai

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=52181Tested-by: default avatarFrancesco Muzio <muziofg@gmail.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 01d5500f
...@@ -181,6 +181,8 @@ static void alc_fix_pll(struct hda_codec *codec) ...@@ -181,6 +181,8 @@ static void alc_fix_pll(struct hda_codec *codec)
spec->pll_coef_idx); spec->pll_coef_idx);
val = snd_hda_codec_read(codec, spec->pll_nid, 0, val = snd_hda_codec_read(codec, spec->pll_nid, 0,
AC_VERB_GET_PROC_COEF, 0); AC_VERB_GET_PROC_COEF, 0);
if (val == -1)
return;
snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
spec->pll_coef_idx); spec->pll_coef_idx);
snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF, 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) ...@@ -2806,6 +2808,8 @@ static void alc286_shutup(struct hda_codec *codec)
static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up) static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up)
{ {
int val = alc_read_coef_idx(codec, 0x04); int val = alc_read_coef_idx(codec, 0x04);
if (val == -1)
return;
if (power_up) if (power_up)
val |= 1 << 11; val |= 1 << 11;
else else
...@@ -5311,26 +5315,29 @@ static void alc269_fill_coef(struct hda_codec *codec) ...@@ -5311,26 +5315,29 @@ static void alc269_fill_coef(struct hda_codec *codec)
if ((alc_get_coef0(codec) & 0x00ff) == 0x017) { if ((alc_get_coef0(codec) & 0x00ff) == 0x017) {
val = alc_read_coef_idx(codec, 0x04); val = alc_read_coef_idx(codec, 0x04);
/* Power up output pin */ /* Power up output pin */
if (val != -1)
alc_write_coef_idx(codec, 0x04, val | (1<<11)); alc_write_coef_idx(codec, 0x04, val | (1<<11));
} }
if ((alc_get_coef0(codec) & 0x00ff) == 0x018) { if ((alc_get_coef0(codec) & 0x00ff) == 0x018) {
val = alc_read_coef_idx(codec, 0xd); val = alc_read_coef_idx(codec, 0xd);
if ((val & 0x0c00) >> 10 != 0x1) { if (val != -1 && (val & 0x0c00) >> 10 != 0x1) {
/* Capless ramp up clock control */ /* Capless ramp up clock control */
alc_write_coef_idx(codec, 0xd, val | (1<<10)); alc_write_coef_idx(codec, 0xd, val | (1<<10));
} }
val = alc_read_coef_idx(codec, 0x17); val = alc_read_coef_idx(codec, 0x17);
if ((val & 0x01c0) >> 6 != 0x4) { if (val != -1 && (val & 0x01c0) >> 6 != 0x4) {
/* Class D power on reset */ /* Class D power on reset */
alc_write_coef_idx(codec, 0x17, val | (1<<7)); alc_write_coef_idx(codec, 0x17, val | (1<<7));
} }
} }
val = alc_read_coef_idx(codec, 0xd); /* Class D */ val = alc_read_coef_idx(codec, 0xd); /* Class D */
if (val != -1)
alc_write_coef_idx(codec, 0xd, val | (1<<14)); alc_write_coef_idx(codec, 0xd, val | (1<<14));
val = alc_read_coef_idx(codec, 0x4); /* HP */ val = alc_read_coef_idx(codec, 0x4); /* HP */
if (val != -1)
alc_write_coef_idx(codec, 0x4, val | (1<<11)); alc_write_coef_idx(codec, 0x4, val | (1<<11));
} }
......
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