Commit 9e507abd authored by Takashi Iwai's avatar Takashi Iwai Committed by Jaroslav Kysela

[ALSA] hda-codec - Fix Oops with probing sigmatel codec chips

When a device is unkown, the driver tries to set up the codec based on
the BIOS information.  Then it may result in Oops if BIOS is broken.
The patch fixes the issue, falling back to a reference model in such a
case.
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Signed-off-by: default avatarJaroslav Kysela <perex@suse.cz>
parent ac98695d
...@@ -1800,6 +1800,7 @@ static int patch_stac925x(struct hda_codec *codec) ...@@ -1800,6 +1800,7 @@ static int patch_stac925x(struct hda_codec *codec)
spec->board_config = snd_hda_check_board_config(codec, STAC_925x_MODELS, spec->board_config = snd_hda_check_board_config(codec, STAC_925x_MODELS,
stac925x_models, stac925x_models,
stac925x_cfg_tbl); stac925x_cfg_tbl);
again:
if (spec->board_config < 0) { if (spec->board_config < 0) {
snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x, using BIOS defaults\n"); snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x, using BIOS defaults\n");
err = stac92xx_save_bios_config_regs(codec); err = stac92xx_save_bios_config_regs(codec);
...@@ -1825,6 +1826,15 @@ static int patch_stac925x(struct hda_codec *codec) ...@@ -1825,6 +1826,15 @@ static int patch_stac925x(struct hda_codec *codec)
spec->mixer = stac925x_mixer; spec->mixer = stac925x_mixer;
err = stac92xx_parse_auto_config(codec, 0x8, 0x7); err = stac92xx_parse_auto_config(codec, 0x8, 0x7);
if (!err) {
if (spec->board_config < 0) {
printk(KERN_WARNING "hda_codec: No auto-config is "
"available, default to model=ref\n");
spec->board_config = STAC_925x_REF;
goto again;
}
err = -EINVAL;
}
if (err < 0) { if (err < 0) {
stac92xx_free(codec); stac92xx_free(codec);
return err; return err;
...@@ -1850,6 +1860,7 @@ static int patch_stac922x(struct hda_codec *codec) ...@@ -1850,6 +1860,7 @@ static int patch_stac922x(struct hda_codec *codec)
spec->board_config = snd_hda_check_board_config(codec, STAC_922X_MODELS, spec->board_config = snd_hda_check_board_config(codec, STAC_922X_MODELS,
stac922x_models, stac922x_models,
stac922x_cfg_tbl); stac922x_cfg_tbl);
again:
if (spec->board_config < 0) { if (spec->board_config < 0) {
snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, " snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, "
"using BIOS defaults\n"); "using BIOS defaults\n");
...@@ -1875,6 +1886,15 @@ static int patch_stac922x(struct hda_codec *codec) ...@@ -1875,6 +1886,15 @@ static int patch_stac922x(struct hda_codec *codec)
spec->multiout.dac_nids = spec->dac_nids; spec->multiout.dac_nids = spec->dac_nids;
err = stac92xx_parse_auto_config(codec, 0x08, 0x09); err = stac92xx_parse_auto_config(codec, 0x08, 0x09);
if (!err) {
if (spec->board_config < 0) {
printk(KERN_WARNING "hda_codec: No auto-config is "
"available, default to model=ref\n");
spec->board_config = STAC_D945_REF;
goto again;
}
err = -EINVAL;
}
if (err < 0) { if (err < 0) {
stac92xx_free(codec); stac92xx_free(codec);
return err; return err;
...@@ -1903,6 +1923,7 @@ static int patch_stac927x(struct hda_codec *codec) ...@@ -1903,6 +1923,7 @@ static int patch_stac927x(struct hda_codec *codec)
spec->board_config = snd_hda_check_board_config(codec, STAC_927X_MODELS, spec->board_config = snd_hda_check_board_config(codec, STAC_927X_MODELS,
stac927x_models, stac927x_models,
stac927x_cfg_tbl); stac927x_cfg_tbl);
again:
if (spec->board_config < 0) { if (spec->board_config < 0) {
snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC927x, using BIOS defaults\n"); snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC927x, using BIOS defaults\n");
err = stac92xx_save_bios_config_regs(codec); err = stac92xx_save_bios_config_regs(codec);
...@@ -1945,6 +1966,15 @@ static int patch_stac927x(struct hda_codec *codec) ...@@ -1945,6 +1966,15 @@ static int patch_stac927x(struct hda_codec *codec)
spec->multiout.dac_nids = spec->dac_nids; spec->multiout.dac_nids = spec->dac_nids;
err = stac92xx_parse_auto_config(codec, 0x1e, 0x20); err = stac92xx_parse_auto_config(codec, 0x1e, 0x20);
if (!err) {
if (spec->board_config < 0) {
printk(KERN_WARNING "hda_codec: No auto-config is "
"available, default to model=ref\n");
spec->board_config = STAC_D965_REF;
goto again;
}
err = -EINVAL;
}
if (err < 0) { if (err < 0) {
stac92xx_free(codec); stac92xx_free(codec);
return err; return err;
...@@ -1970,6 +2000,7 @@ static int patch_stac9205(struct hda_codec *codec) ...@@ -1970,6 +2000,7 @@ static int patch_stac9205(struct hda_codec *codec)
spec->board_config = snd_hda_check_board_config(codec, STAC_9205_MODELS, spec->board_config = snd_hda_check_board_config(codec, STAC_9205_MODELS,
stac9205_models, stac9205_models,
stac9205_cfg_tbl); stac9205_cfg_tbl);
again:
if (spec->board_config < 0) { if (spec->board_config < 0) {
snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9205, using BIOS defaults\n"); snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9205, using BIOS defaults\n");
err = stac92xx_save_bios_config_regs(codec); err = stac92xx_save_bios_config_regs(codec);
...@@ -2008,6 +2039,15 @@ static int patch_stac9205(struct hda_codec *codec) ...@@ -2008,6 +2039,15 @@ static int patch_stac9205(struct hda_codec *codec)
AC_VERB_SET_GPIO_MASK, 0x00000001); AC_VERB_SET_GPIO_MASK, 0x00000001);
err = stac92xx_parse_auto_config(codec, 0x1f, 0x20); err = stac92xx_parse_auto_config(codec, 0x1f, 0x20);
if (!err) {
if (spec->board_config < 0) {
printk(KERN_WARNING "hda_codec: No auto-config is "
"available, default to model=ref\n");
spec->board_config = STAC_9205_REF;
goto again;
}
err = -EINVAL;
}
if (err < 0) { if (err < 0) {
stac92xx_free(codec); stac92xx_free(codec);
return err; return err;
......
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