aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_intel.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2008-11-06 11:11:10 -0500
committerTakashi Iwai <tiwai@suse.de>2008-11-06 11:29:48 -0500
commit6ce4a3bc1b93e8ca50b142b00dd73bfdb5c4a172 (patch)
treed6adcd686919c9107d638966aee06bb63ee8d5fd /sound/pci/hda/hda_intel.c
parent33fa35ed0d7e8996cc68cc2ffc21f12b38fa03c1 (diff)
ALSA: hda - Make codec-probing more robust
When an error occurs during the codec probing, typically accessing to an non-existing codec slot, the controller chip gets often screwed up and can no longer communicate with the codecs. This patch adds a preparation phase just to probe codec addresses before actually creating codec instances. If any error occurs during this probing phase, the driver resets the controller to recover. This will (hopefully) fix the famous "single_cmd" errors. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/hda_intel.c')
-rw-r--r--sound/pci/hda/hda_intel.c55
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 */
1190static 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
1178static int azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec, 1206static int azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
1179 struct hda_pcm *cpcm); 1207 struct hda_pcm *cpcm);
1208static 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;