diff options
author | Takashi Iwai <tiwai@suse.de> | 2006-01-12 12:28:44 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2006-03-22 04:22:51 -0500 |
commit | 27346166a9b3b9eee586bce212502cddf9685a07 (patch) | |
tree | 97a1feb7937b0ca82538e049e7e332f4797b2eb9 | |
parent | 84a43bd523a63f1b53fd734c3798d71b7b53f123 (diff) |
[ALSA] hda-intel - Add single_cmd option for debugging
Modules: Documentation,HDA Intel driver
Added single_cmd module option for debugging in the case CORB/RIRB
doesn't work well (e.g. due to wrong irq routings).
Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r-- | Documentation/sound/alsa/ALSA-Configuration.txt | 13 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 57 |
2 files changed, 39 insertions, 31 deletions
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index 36b511c7cade..cc8a70187199 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt | |||
@@ -671,6 +671,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
671 | 671 | ||
672 | model - force the model name | 672 | model - force the model name |
673 | position_fix - Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size) | 673 | position_fix - Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size) |
674 | single_cmd - Use single immediate commands to communicate with | ||
675 | codecs (for debugging only) | ||
674 | 676 | ||
675 | This module supports one card and autoprobe. | 677 | This module supports one card and autoprobe. |
676 | 678 | ||
@@ -723,6 +725,17 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
723 | (Usually SD_LPLIB register is more accurate than the | 725 | (Usually SD_LPLIB register is more accurate than the |
724 | position buffer.) | 726 | position buffer.) |
725 | 727 | ||
728 | NB: If you get many "azx_get_response timeout" messages at | ||
729 | loading, it's likely a problem of interrupts (e.g. ACPI irq | ||
730 | routing). Try to boot with options like "pci=noacpi". Also, you | ||
731 | can try "single_cmd=1" module option. This will switch the | ||
732 | communication method between HDA controller and codecs to the | ||
733 | single immediate commands instead of CORB/RIRB. Basically, the | ||
734 | single command mode is provided only for BIOS, and you won't get | ||
735 | unsolicited events, too. But, at least, this works independently | ||
736 | from the irq. Remember this is a last resort, and should be | ||
737 | avoided as much as possible... | ||
738 | |||
726 | The power-management is supported. | 739 | The power-management is supported. |
727 | 740 | ||
728 | Module snd-hdsp | 741 | Module snd-hdsp |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index fd12b6991fe4..b3f37e7b33c0 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -53,6 +53,7 @@ static char *id = SNDRV_DEFAULT_STR1; | |||
53 | static char *model; | 53 | static char *model; |
54 | static int position_fix; | 54 | static int position_fix; |
55 | static int probe_mask = -1; | 55 | static int probe_mask = -1; |
56 | static int single_cmd; | ||
56 | 57 | ||
57 | module_param(index, int, 0444); | 58 | module_param(index, int, 0444); |
58 | MODULE_PARM_DESC(index, "Index value for Intel HD audio interface."); | 59 | MODULE_PARM_DESC(index, "Index value for Intel HD audio interface."); |
@@ -64,6 +65,8 @@ module_param(position_fix, int, 0444); | |||
64 | MODULE_PARM_DESC(position_fix, "Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)."); | 65 | MODULE_PARM_DESC(position_fix, "Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)."); |
65 | module_param(probe_mask, int, 0444); | 66 | module_param(probe_mask, int, 0444); |
66 | MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1)."); | 67 | MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1)."); |
68 | module_param(single_cmd, bool, 0444); | ||
69 | MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs (for debugging only)."); | ||
67 | 70 | ||
68 | 71 | ||
69 | /* just for backward compatibility */ | 72 | /* just for backward compatibility */ |
@@ -235,12 +238,6 @@ enum { | |||
235 | #define NVIDIA_HDA_ENABLE_COHBITS 0x0f | 238 | #define NVIDIA_HDA_ENABLE_COHBITS 0x0f |
236 | 239 | ||
237 | /* | 240 | /* |
238 | * Use CORB/RIRB for communication from/to codecs. | ||
239 | * This is the way recommended by Intel (see below). | ||
240 | */ | ||
241 | #define USE_CORB_RIRB | ||
242 | |||
243 | /* | ||
244 | */ | 241 | */ |
245 | 242 | ||
246 | struct azx_dev { | 243 | struct azx_dev { |
@@ -325,6 +322,7 @@ struct azx { | |||
325 | /* flags */ | 322 | /* flags */ |
326 | int position_fix; | 323 | int position_fix; |
327 | unsigned int initialized: 1; | 324 | unsigned int initialized: 1; |
325 | unsigned int single_cmd: 1; | ||
328 | }; | 326 | }; |
329 | 327 | ||
330 | /* driver types */ | 328 | /* driver types */ |
@@ -388,7 +386,6 @@ static char *driver_short_names[] __devinitdata = { | |||
388 | * Interface for HD codec | 386 | * Interface for HD codec |
389 | */ | 387 | */ |
390 | 388 | ||
391 | #ifdef USE_CORB_RIRB | ||
392 | /* | 389 | /* |
393 | * CORB / RIRB interface | 390 | * CORB / RIRB interface |
394 | */ | 391 | */ |
@@ -436,11 +433,7 @@ static void azx_init_cmd_io(struct azx *chip) | |||
436 | /* set N=1, get RIRB response interrupt for new entry */ | 433 | /* set N=1, get RIRB response interrupt for new entry */ |
437 | azx_writew(chip, RINTCNT, 1); | 434 | azx_writew(chip, RINTCNT, 1); |
438 | /* enable rirb dma and response irq */ | 435 | /* enable rirb dma and response irq */ |
439 | #ifdef USE_CORB_RIRB | ||
440 | azx_writeb(chip, RIRBCTL, ICH6_RBCTL_DMA_EN | ICH6_RBCTL_IRQ_EN); | 436 | azx_writeb(chip, RIRBCTL, ICH6_RBCTL_DMA_EN | ICH6_RBCTL_IRQ_EN); |
441 | #else | ||
442 | azx_writeb(chip, RIRBCTL, ICH6_RBCTL_DMA_EN); | ||
443 | #endif | ||
444 | chip->rirb.rp = chip->rirb.cmds = 0; | 437 | chip->rirb.rp = chip->rirb.cmds = 0; |
445 | } | 438 | } |
446 | 439 | ||
@@ -528,7 +521,6 @@ static unsigned int azx_get_response(struct hda_codec *codec) | |||
528 | return chip->rirb.res; /* the last value */ | 521 | return chip->rirb.res; /* the last value */ |
529 | } | 522 | } |
530 | 523 | ||
531 | #else | ||
532 | /* | 524 | /* |
533 | * Use the single immediate command instead of CORB/RIRB for simplicity | 525 | * Use the single immediate command instead of CORB/RIRB for simplicity |
534 | * | 526 | * |
@@ -539,13 +531,10 @@ static unsigned int azx_get_response(struct hda_codec *codec) | |||
539 | * I left the codes, however, for debugging/testing purposes. | 531 | * I left the codes, however, for debugging/testing purposes. |
540 | */ | 532 | */ |
541 | 533 | ||
542 | #define azx_alloc_cmd_io(chip) 0 | ||
543 | #define azx_init_cmd_io(chip) | ||
544 | #define azx_free_cmd_io(chip) | ||
545 | |||
546 | /* send a command */ | 534 | /* send a command */ |
547 | static int azx_send_cmd(struct hda_codec *codec, hda_nid_t nid, int direct, | 535 | static int azx_single_send_cmd(struct hda_codec *codec, hda_nid_t nid, |
548 | unsigned int verb, unsigned int para) | 536 | int direct, unsigned int verb, |
537 | unsigned int para) | ||
549 | { | 538 | { |
550 | struct azx *chip = codec->bus->private_data; | 539 | struct azx *chip = codec->bus->private_data; |
551 | u32 val; | 540 | u32 val; |
@@ -573,7 +562,7 @@ static int azx_send_cmd(struct hda_codec *codec, hda_nid_t nid, int direct, | |||
573 | } | 562 | } |
574 | 563 | ||
575 | /* receive a response */ | 564 | /* receive a response */ |
576 | static unsigned int azx_get_response(struct hda_codec *codec) | 565 | static unsigned int azx_single_get_response(struct hda_codec *codec) |
577 | { | 566 | { |
578 | struct azx *chip = codec->bus->private_data; | 567 | struct azx *chip = codec->bus->private_data; |
579 | int timeout = 50; | 568 | int timeout = 50; |
@@ -588,10 +577,6 @@ static unsigned int azx_get_response(struct hda_codec *codec) | |||
588 | return (unsigned int)-1; | 577 | return (unsigned int)-1; |
589 | } | 578 | } |
590 | 579 | ||
591 | #define azx_update_rirb(chip) | ||
592 | |||
593 | #endif /* USE_CORB_RIRB */ | ||
594 | |||
595 | /* reset codec link */ | 580 | /* reset codec link */ |
596 | static int azx_reset(struct azx *chip) | 581 | static int azx_reset(struct azx *chip) |
597 | { | 582 | { |
@@ -737,7 +722,8 @@ static void azx_init_chip(struct azx *chip) | |||
737 | azx_int_enable(chip); | 722 | azx_int_enable(chip); |
738 | 723 | ||
739 | /* initialize the codec command I/O */ | 724 | /* initialize the codec command I/O */ |
740 | azx_init_cmd_io(chip); | 725 | if (! chip->single_cmd) |
726 | azx_init_cmd_io(chip); | ||
741 | 727 | ||
742 | /* program the position buffer */ | 728 | /* program the position buffer */ |
743 | azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr); | 729 | azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr); |
@@ -796,7 +782,7 @@ static irqreturn_t azx_interrupt(int irq, void* dev_id, struct pt_regs *regs) | |||
796 | /* clear rirb int */ | 782 | /* clear rirb int */ |
797 | status = azx_readb(chip, RIRBSTS); | 783 | status = azx_readb(chip, RIRBSTS); |
798 | if (status & RIRB_INT_MASK) { | 784 | if (status & RIRB_INT_MASK) { |
799 | if (status & RIRB_INT_RESPONSE) | 785 | if (! chip->single_cmd && (status & RIRB_INT_RESPONSE)) |
800 | azx_update_rirb(chip); | 786 | azx_update_rirb(chip); |
801 | azx_writeb(chip, RIRBSTS, RIRB_INT_MASK); | 787 | azx_writeb(chip, RIRBSTS, RIRB_INT_MASK); |
802 | } | 788 | } |
@@ -913,8 +899,13 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model) | |||
913 | bus_temp.private_data = chip; | 899 | bus_temp.private_data = chip; |
914 | bus_temp.modelname = model; | 900 | bus_temp.modelname = model; |
915 | bus_temp.pci = chip->pci; | 901 | bus_temp.pci = chip->pci; |
916 | bus_temp.ops.command = azx_send_cmd; | 902 | if (chip->single_cmd) { |
917 | bus_temp.ops.get_response = azx_get_response; | 903 | bus_temp.ops.command = azx_single_send_cmd; |
904 | bus_temp.ops.get_response = azx_single_get_response; | ||
905 | } else { | ||
906 | bus_temp.ops.command = azx_send_cmd; | ||
907 | bus_temp.ops.get_response = azx_get_response; | ||
908 | } | ||
918 | 909 | ||
919 | if ((err = snd_hda_bus_new(chip->card, &bus_temp, &chip->bus)) < 0) | 910 | if ((err = snd_hda_bus_new(chip->card, &bus_temp, &chip->bus)) < 0) |
920 | return err; | 911 | return err; |
@@ -1316,7 +1307,8 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state) | |||
1316 | for (i = 0; i < chip->pcm_devs; i++) | 1307 | for (i = 0; i < chip->pcm_devs; i++) |
1317 | snd_pcm_suspend_all(chip->pcm[i]); | 1308 | snd_pcm_suspend_all(chip->pcm[i]); |
1318 | snd_hda_suspend(chip->bus, state); | 1309 | snd_hda_suspend(chip->bus, state); |
1319 | azx_free_cmd_io(chip); | 1310 | if (! chip->single_cmd) |
1311 | azx_free_cmd_io(chip); | ||
1320 | pci_disable_device(pci); | 1312 | pci_disable_device(pci); |
1321 | pci_save_state(pci); | 1313 | pci_save_state(pci); |
1322 | return 0; | 1314 | return 0; |
@@ -1354,7 +1346,8 @@ static int azx_free(struct azx *chip) | |||
1354 | azx_int_clear(chip); | 1346 | azx_int_clear(chip); |
1355 | 1347 | ||
1356 | /* disable CORB/RIRB */ | 1348 | /* disable CORB/RIRB */ |
1357 | azx_free_cmd_io(chip); | 1349 | if (! chip->single_cmd) |
1350 | azx_free_cmd_io(chip); | ||
1358 | 1351 | ||
1359 | /* disable position buffer */ | 1352 | /* disable position buffer */ |
1360 | azx_writel(chip, DPLBASE, 0); | 1353 | azx_writel(chip, DPLBASE, 0); |
@@ -1422,6 +1415,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
1422 | chip->driver_type = driver_type; | 1415 | chip->driver_type = driver_type; |
1423 | 1416 | ||
1424 | chip->position_fix = position_fix ? position_fix : POS_FIX_POSBUF; | 1417 | chip->position_fix = position_fix ? position_fix : POS_FIX_POSBUF; |
1418 | chip->single_cmd = single_cmd; | ||
1425 | 1419 | ||
1426 | #if BITS_PER_LONG != 64 | 1420 | #if BITS_PER_LONG != 64 |
1427 | /* Fix up base address on ULI M5461 */ | 1421 | /* Fix up base address on ULI M5461 */ |
@@ -1492,8 +1486,9 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
1492 | goto errout; | 1486 | goto errout; |
1493 | } | 1487 | } |
1494 | /* allocate CORB/RIRB */ | 1488 | /* allocate CORB/RIRB */ |
1495 | if ((err = azx_alloc_cmd_io(chip)) < 0) | 1489 | if (! chip->single_cmd) |
1496 | goto errout; | 1490 | if ((err = azx_alloc_cmd_io(chip)) < 0) |
1491 | goto errout; | ||
1497 | 1492 | ||
1498 | /* initialize streams */ | 1493 | /* initialize streams */ |
1499 | azx_init_stream(chip); | 1494 | azx_init_stream(chip); |