Commit 111d3af5f5fbf0e28570f1c01e83444d73c68a25

Authored by Takashi Iwai
Committed by Jaroslav Kysela
1 parent 353b9e6670

[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>

Showing 2 changed files with 49 additions and 17 deletions Side-by-side Diff

sound/pci/hda/hda_codec.c
... ... @@ -531,6 +531,12 @@
531 531 bus->caddr_tbl[codec_addr] = codec;
532 532  
533 533 codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_VENDOR_ID);
  534 + if (codec->vendor_id == -1)
  535 + /* read again, hopefully the access method was corrected
  536 + * in the last read...
  537 + */
  538 + codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT,
  539 + AC_PAR_VENDOR_ID);
534 540 codec->subsystem_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_SUBSYSTEM_ID);
535 541 codec->revision_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_REV_ID);
536 542  
sound/pci/hda/hda_intel.c
... ... @@ -446,8 +446,8 @@
446 446 }
447 447  
448 448 /* send a command */
449   -static int azx_send_cmd(struct hda_codec *codec, hda_nid_t nid, int direct,
450   - unsigned int verb, unsigned int para)
  449 +static int azx_corb_send_cmd(struct hda_codec *codec, hda_nid_t nid, int direct,
  450 + unsigned int verb, unsigned int para)
451 451 {
452 452 struct azx *chip = codec->bus->private_data;
453 453 unsigned int wp;
454 454  
455 455  
... ... @@ -503,18 +503,21 @@
503 503 }
504 504  
505 505 /* receive a response */
506   -static unsigned int azx_get_response(struct hda_codec *codec)
  506 +static unsigned int azx_rirb_get_response(struct hda_codec *codec)
507 507 {
508 508 struct azx *chip = codec->bus->private_data;
509 509 int timeout = 50;
510 510  
511 511 while (chip->rirb.cmds) {
512 512 if (! --timeout) {
513   - if (printk_ratelimit())
514   - snd_printk(KERN_ERR
515   - "azx_get_response timeout\n");
  513 + snd_printk(KERN_ERR
  514 + "hda_intel: azx_get_response timeout, "
  515 + "switching to single_cmd mode...\n");
516 516 chip->rirb.rp = azx_readb(chip, RIRBWP);
517 517 chip->rirb.cmds = 0;
  518 + /* switch to single_cmd mode */
  519 + chip->single_cmd = 1;
  520 + azx_free_cmd_io(chip);
518 521 return -1;
519 522 }
520 523 msleep(1);
... ... @@ -578,6 +581,36 @@
578 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 */
  592 +static 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 */
  604 +static 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 614 /* reset codec link */
582 615 static int azx_reset(struct azx *chip)
583 616 {
... ... @@ -900,13 +933,8 @@
900 933 bus_temp.private_data = chip;
901 934 bus_temp.modelname = model;
902 935 bus_temp.pci = chip->pci;
903   - if (chip->single_cmd) {
904   - bus_temp.ops.command = azx_single_send_cmd;
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   - }
  936 + bus_temp.ops.command = azx_send_cmd;
  937 + bus_temp.ops.get_response = azx_get_response;
910 938  
911 939 if ((err = snd_hda_bus_new(chip->card, &bus_temp, &chip->bus)) < 0)
912 940 return err;
... ... @@ -1308,8 +1336,7 @@
1308 1336 for (i = 0; i < chip->pcm_devs; i++)
1309 1337 snd_pcm_suspend_all(chip->pcm[i]);
1310 1338 snd_hda_suspend(chip->bus, state);
1311   - if (! chip->single_cmd)
1312   - azx_free_cmd_io(chip);
  1339 + azx_free_cmd_io(chip);
1313 1340 pci_disable_device(pci);
1314 1341 pci_save_state(pci);
1315 1342 return 0;
... ... @@ -1347,8 +1374,7 @@
1347 1374 azx_int_clear(chip);
1348 1375  
1349 1376 /* disable CORB/RIRB */
1350   - if (! chip->single_cmd)
1351   - azx_free_cmd_io(chip);
  1377 + azx_free_cmd_io(chip);
1352 1378  
1353 1379 /* disable position buffer */
1354 1380 azx_writel(chip, DPLBASE, 0);