diff options
-rw-r--r-- | sound/pci/hda/hda_intel.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index bf8e6f94aebc..f3c447cf67f8 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -392,6 +392,7 @@ struct azx { | |||
392 | unsigned int msi :1; | 392 | unsigned int msi :1; |
393 | unsigned int irq_pending_warned :1; | 393 | unsigned int irq_pending_warned :1; |
394 | unsigned int via_dmapos_patch :1; /* enable DMA-position fix for VIA */ | 394 | unsigned int via_dmapos_patch :1; /* enable DMA-position fix for VIA */ |
395 | unsigned int probing :1; /* codec probing phase */ | ||
395 | 396 | ||
396 | /* for debugging */ | 397 | /* for debugging */ |
397 | unsigned int last_cmd; /* last issued command (to sync) */ | 398 | unsigned int last_cmd; /* last issued command (to sync) */ |
@@ -624,6 +625,14 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus) | |||
624 | goto again; | 625 | goto again; |
625 | } | 626 | } |
626 | 627 | ||
628 | if (chip->probing) { | ||
629 | /* If this critical timeout happens during the codec probing | ||
630 | * phase, this is likely an access to a non-existing codec | ||
631 | * slot. Better to return an error and reset the system. | ||
632 | */ | ||
633 | return -1; | ||
634 | } | ||
635 | |||
627 | snd_printk(KERN_ERR "hda_intel: azx_get_response timeout, " | 636 | snd_printk(KERN_ERR "hda_intel: azx_get_response timeout, " |
628 | "switching to single_cmd mode: last cmd=0x%08x\n", | 637 | "switching to single_cmd mode: last cmd=0x%08x\n", |
629 | chip->last_cmd); | 638 | chip->last_cmd); |
@@ -1175,8 +1184,28 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev) | |||
1175 | return 0; | 1184 | return 0; |
1176 | } | 1185 | } |
1177 | 1186 | ||
1187 | /* | ||
1188 | * Probe the given codec address | ||
1189 | */ | ||
1190 | static int probe_codec(struct azx *chip, int addr) | ||
1191 | { | ||
1192 | unsigned int cmd = (addr << 28) | (AC_NODE_ROOT << 20) | | ||
1193 | (AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID; | ||
1194 | unsigned int res; | ||
1195 | |||
1196 | chip->probing = 1; | ||
1197 | azx_send_cmd(chip->bus, cmd); | ||
1198 | res = azx_get_response(chip->bus); | ||
1199 | chip->probing = 0; | ||
1200 | if (res == -1) | ||
1201 | return -EIO; | ||
1202 | snd_printdd("hda_intel: codec #%d probed OK\n", addr); | ||
1203 | return 0; | ||
1204 | } | ||
1205 | |||
1178 | static int azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec, | 1206 | static int azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec, |
1179 | struct hda_pcm *cpcm); | 1207 | struct hda_pcm *cpcm); |
1208 | static void azx_stop_chip(struct azx *chip); | ||
1180 | 1209 | ||
1181 | /* | 1210 | /* |
1182 | * Codec initialization | 1211 | * Codec initialization |
@@ -1216,6 +1245,32 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model, | |||
1216 | max_slots = azx_max_codecs[chip->driver_type]; | 1245 | max_slots = azx_max_codecs[chip->driver_type]; |
1217 | if (!max_slots) | 1246 | if (!max_slots) |
1218 | max_slots = AZX_MAX_CODECS; | 1247 | max_slots = AZX_MAX_CODECS; |
1248 | |||
1249 | /* First try to probe all given codec slots */ | ||
1250 | for (c = 0; c < max_slots; c++) { | ||
1251 | if ((chip->codec_mask & (1 << c)) & codec_probe_mask) { | ||
1252 | if (probe_codec(chip, c) < 0) { | ||
1253 | /* Some BIOSen give you wrong codec addresses | ||
1254 | * that don't exist | ||
1255 | */ | ||
1256 | snd_printk(KERN_WARNING | ||
1257 | "hda_intel: Codec #%d probe error; " | ||
1258 | "disabling it...\n", c); | ||
1259 | chip->codec_mask &= ~(1 << c); | ||
1260 | /* More badly, accessing to a non-existing | ||
1261 | * codec often screws up the controller chip, | ||
1262 | * and distrubs the further communications. | ||
1263 | * Thus if an error occurs during probing, | ||
1264 | * better to reset the controller chip to | ||
1265 | * get back to the sanity state. | ||
1266 | */ | ||
1267 | azx_stop_chip(chip); | ||
1268 | azx_init_chip(chip); | ||
1269 | } | ||
1270 | } | ||
1271 | } | ||
1272 | |||
1273 | /* Then create codec instances */ | ||
1219 | for (c = 0; c < max_slots; c++) { | 1274 | for (c = 0; c < max_slots; c++) { |
1220 | if ((chip->codec_mask & (1 << c)) & codec_probe_mask) { | 1275 | if ((chip->codec_mask & (1 << c)) & codec_probe_mask) { |
1221 | struct hda_codec *codec; | 1276 | struct hda_codec *codec; |