diff options
-rw-r--r-- | sound/pci/hda/hda_intel.c | 45 |
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 */ |
469 | static int azx_corb_send_cmd(struct hda_codec *codec, hda_nid_t nid, int direct, | 472 | static 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 */ |
584 | static int azx_single_send_cmd(struct hda_codec *codec, hda_nid_t nid, | 581 | static 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 */ |