aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/pci/hda/hda_intel.c45
1 files changed, 21 insertions, 24 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index c78ff901a572..92bc8b3fa2a0 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -341,6 +341,9 @@ struct azx {
341 unsigned int single_cmd :1; 341 unsigned int single_cmd :1;
342 unsigned int polling_mode :1; 342 unsigned int polling_mode :1;
343 unsigned int msi :1; 343 unsigned int msi :1;
344
345 /* for debugging */
346 unsigned int last_cmd; /* last issued command (to sync) */
344}; 347};
345 348
346/* driver types */ 349/* driver types */
@@ -466,18 +469,10 @@ static void azx_free_cmd_io(struct azx *chip)
466} 469}
467 470
468/* send a command */ 471/* send a command */
469static int azx_corb_send_cmd(struct hda_codec *codec, hda_nid_t nid, int direct, 472static int azx_corb_send_cmd(struct hda_codec *codec, u32 val)
470 unsigned int verb, unsigned int para)
471{ 473{
472 struct azx *chip = codec->bus->private_data; 474 struct azx *chip = codec->bus->private_data;
473 unsigned int wp; 475 unsigned int wp;
474 u32 val;
475
476 val = (u32)(codec->addr & 0x0f) << 28;
477 val |= (u32)direct << 27;
478 val |= (u32)nid << 20;
479 val |= verb << 8;
480 val |= para;
481 476
482 /* add command to corb */ 477 /* add command to corb */
483 wp = azx_readb(chip, CORBWP); 478 wp = azx_readb(chip, CORBWP);
@@ -543,7 +538,7 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec)
543 538
544 if (chip->msi) { 539 if (chip->msi) {
545 snd_printk(KERN_WARNING "hda_intel: No response from codec, " 540 snd_printk(KERN_WARNING "hda_intel: No response from codec, "
546 "disabling MSI...\n"); 541 "disabling MSI: last cmd=0x%08x\n", chip->last_cmd);
547 free_irq(chip->irq, chip); 542 free_irq(chip->irq, chip);
548 chip->irq = -1; 543 chip->irq = -1;
549 pci_disable_msi(chip->pci); 544 pci_disable_msi(chip->pci);
@@ -555,13 +550,15 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec)
555 550
556 if (!chip->polling_mode) { 551 if (!chip->polling_mode) {
557 snd_printk(KERN_WARNING "hda_intel: azx_get_response timeout, " 552 snd_printk(KERN_WARNING "hda_intel: azx_get_response timeout, "
558 "switching to polling mode...\n"); 553 "switching to polling mode: last cmd=0x%08x\n",
554 chip->last_cmd);
559 chip->polling_mode = 1; 555 chip->polling_mode = 1;
560 goto again; 556 goto again;
561 } 557 }
562 558
563 snd_printk(KERN_ERR "hda_intel: azx_get_response timeout, " 559 snd_printk(KERN_ERR "hda_intel: azx_get_response timeout, "
564 "switching to single_cmd mode...\n"); 560 "switching to single_cmd mode: last cmd=0x%08x\n",
561 chip->last_cmd);
565 chip->rirb.rp = azx_readb(chip, RIRBWP); 562 chip->rirb.rp = azx_readb(chip, RIRBWP);
566 chip->rirb.cmds = 0; 563 chip->rirb.cmds = 0;
567 /* switch to single_cmd mode */ 564 /* switch to single_cmd mode */
@@ -581,20 +578,11 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec)
581 */ 578 */
582 579
583/* send a command */ 580/* send a command */
584static int azx_single_send_cmd(struct hda_codec *codec, hda_nid_t nid, 581static int azx_single_send_cmd(struct hda_codec *codec, u32 val)
585 int direct, unsigned int verb,
586 unsigned int para)
587{ 582{
588 struct azx *chip = codec->bus->private_data; 583 struct azx *chip = codec->bus->private_data;
589 u32 val;
590 int timeout = 50; 584 int timeout = 50;
591 585
592 val = (u32)(codec->addr & 0x0f) << 28;
593 val |= (u32)direct << 27;
594 val |= (u32)nid << 20;
595 val |= verb << 8;
596 val |= para;
597
598 while (timeout--) { 586 while (timeout--) {
599 /* check ICB busy bit */ 587 /* check ICB busy bit */
600 if (! (azx_readw(chip, IRS) & ICH6_IRS_BUSY)) { 588 if (! (azx_readw(chip, IRS) & ICH6_IRS_BUSY)) {
@@ -639,10 +627,19 @@ static int azx_send_cmd(struct hda_codec *codec, hda_nid_t nid,
639 unsigned int para) 627 unsigned int para)
640{ 628{
641 struct azx *chip = codec->bus->private_data; 629 struct azx *chip = codec->bus->private_data;
630 u32 val;
631
632 val = (u32)(codec->addr & 0x0f) << 28;
633 val |= (u32)direct << 27;
634 val |= (u32)nid << 20;
635 val |= verb << 8;
636 val |= para;
637 chip->last_cmd = val;
638
642 if (chip->single_cmd) 639 if (chip->single_cmd)
643 return azx_single_send_cmd(codec, nid, direct, verb, para); 640 return azx_single_send_cmd(codec, val);
644 else 641 else
645 return azx_corb_send_cmd(codec, nid, direct, verb, para); 642 return azx_corb_send_cmd(codec, val);
646} 643}
647 644
648/* get a response */ 645/* get a response */