aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_intel.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2006-02-16 12:17:58 -0500
committerJaroslav Kysela <perex@suse.cz>2006-03-22 04:29:53 -0500
commit111d3af5f5fbf0e28570f1c01e83444d73c68a25 (patch)
tree4679b8c2336c475016cd19c81263df0347741684 /sound/pci/hda/hda_intel.c
parent353b9e667042d6faa15a41df022bf38c949a7b2f (diff)
[ALSA] hda-intel - Automatic correction to single_cmd mode
Modules: HDA Codec driver,HDA Intel driver Switch to single_cmd mode automatically as a fallback when CORB/RIRB communication doesn't work well. It may make the driver working on some devices with broken BIOS/ACPI support. 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.c60
1 files changed, 43 insertions, 17 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index dbed2644a192..016fbc263e55 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -446,8 +446,8 @@ static void azx_free_cmd_io(struct azx *chip)
446} 446}
447 447
448/* send a command */ 448/* send a command */
449static int azx_send_cmd(struct hda_codec *codec, hda_nid_t nid, int direct, 449static int azx_corb_send_cmd(struct hda_codec *codec, hda_nid_t nid, int direct,
450 unsigned int verb, unsigned int para) 450 unsigned int verb, unsigned int para)
451{ 451{
452 struct azx *chip = codec->bus->private_data; 452 struct azx *chip = codec->bus->private_data;
453 unsigned int wp; 453 unsigned int wp;
@@ -503,18 +503,21 @@ static void azx_update_rirb(struct azx *chip)
503} 503}
504 504
505/* receive a response */ 505/* receive a response */
506static unsigned int azx_get_response(struct hda_codec *codec) 506static unsigned int azx_rirb_get_response(struct hda_codec *codec)
507{ 507{
508 struct azx *chip = codec->bus->private_data; 508 struct azx *chip = codec->bus->private_data;
509 int timeout = 50; 509 int timeout = 50;
510 510
511 while (chip->rirb.cmds) { 511 while (chip->rirb.cmds) {
512 if (! --timeout) { 512 if (! --timeout) {
513 if (printk_ratelimit()) 513 snd_printk(KERN_ERR
514 snd_printk(KERN_ERR 514 "hda_intel: azx_get_response timeout, "
515 "azx_get_response timeout\n"); 515 "switching to single_cmd mode...\n");
516 chip->rirb.rp = azx_readb(chip, RIRBWP); 516 chip->rirb.rp = azx_readb(chip, RIRBWP);
517 chip->rirb.cmds = 0; 517 chip->rirb.cmds = 0;
518 /* switch to single_cmd mode */
519 chip->single_cmd = 1;
520 azx_free_cmd_io(chip);
518 return -1; 521 return -1;
519 } 522 }
520 msleep(1); 523 msleep(1);
@@ -578,6 +581,36 @@ static unsigned int azx_single_get_response(struct hda_codec *codec)
578 return (unsigned int)-1; 581 return (unsigned int)-1;
579} 582}
580 583
584/*
585 * The below are the main callbacks from hda_codec.
586 *
587 * They are just the skeleton to call sub-callbacks according to the
588 * current setting of chip->single_cmd.
589 */
590
591/* send a command */
592static int azx_send_cmd(struct hda_codec *codec, hda_nid_t nid,
593 int direct, unsigned int verb,
594 unsigned int para)
595{
596 struct azx *chip = codec->bus->private_data;
597 if (chip->single_cmd)
598 return azx_single_send_cmd(codec, nid, direct, verb, para);
599 else
600 return azx_corb_send_cmd(codec, nid, direct, verb, para);
601}
602
603/* get a response */
604static unsigned int azx_get_response(struct hda_codec *codec)
605{
606 struct azx *chip = codec->bus->private_data;
607 if (chip->single_cmd)
608 return azx_single_get_response(codec);
609 else
610 return azx_rirb_get_response(codec);
611}
612
613
581/* reset codec link */ 614/* reset codec link */
582static int azx_reset(struct azx *chip) 615static int azx_reset(struct azx *chip)
583{ 616{
@@ -900,13 +933,8 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model)
900 bus_temp.private_data = chip; 933 bus_temp.private_data = chip;
901 bus_temp.modelname = model; 934 bus_temp.modelname = model;
902 bus_temp.pci = chip->pci; 935 bus_temp.pci = chip->pci;
903 if (chip->single_cmd) { 936 bus_temp.ops.command = azx_send_cmd;
904 bus_temp.ops.command = azx_single_send_cmd; 937 bus_temp.ops.get_response = azx_get_response;
905 bus_temp.ops.get_response = azx_single_get_response;
906 } else {
907 bus_temp.ops.command = azx_send_cmd;
908 bus_temp.ops.get_response = azx_get_response;
909 }
910 938
911 if ((err = snd_hda_bus_new(chip->card, &bus_temp, &chip->bus)) < 0) 939 if ((err = snd_hda_bus_new(chip->card, &bus_temp, &chip->bus)) < 0)
912 return err; 940 return err;
@@ -1308,8 +1336,7 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state)
1308 for (i = 0; i < chip->pcm_devs; i++) 1336 for (i = 0; i < chip->pcm_devs; i++)
1309 snd_pcm_suspend_all(chip->pcm[i]); 1337 snd_pcm_suspend_all(chip->pcm[i]);
1310 snd_hda_suspend(chip->bus, state); 1338 snd_hda_suspend(chip->bus, state);
1311 if (! chip->single_cmd) 1339 azx_free_cmd_io(chip);
1312 azx_free_cmd_io(chip);
1313 pci_disable_device(pci); 1340 pci_disable_device(pci);
1314 pci_save_state(pci); 1341 pci_save_state(pci);
1315 return 0; 1342 return 0;
@@ -1347,8 +1374,7 @@ static int azx_free(struct azx *chip)
1347 azx_int_clear(chip); 1374 azx_int_clear(chip);
1348 1375
1349 /* disable CORB/RIRB */ 1376 /* disable CORB/RIRB */
1350 if (! chip->single_cmd) 1377 azx_free_cmd_io(chip);
1351 azx_free_cmd_io(chip);
1352 1378
1353 /* disable position buffer */ 1379 /* disable position buffer */
1354 azx_writel(chip, DPLBASE, 0); 1380 azx_writel(chip, DPLBASE, 0);