aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorRichard Fish <bigfish@asmallpond.org>2006-08-23 12:31:34 -0400
committerJaroslav Kysela <perex@suse.cz>2006-09-23 04:43:51 -0400
commit11b44bbde52b6c50ed8c9ba579d7ee9ff5b48cd8 (patch)
tree0e216886680a33d2ca2f29b5551c1484e1da0d48 /sound
parent6d8590650eb81d2c869c7adf4b469071cec11eee (diff)
[ALSA] hda-codec - restore HDA sigmatel pin configs on resume
This patch restores the Intel HDA Sigmatel codec pin configuration on resume. Most of it is dedicated to saving the BIOS pin configuration if necessary, so that even unrecognized chips can be resumed correctly. Signed-off-by: Richard Fish <bigfish@asmallpond.org> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/hda/patch_sigmatel.c100
1 files changed, 79 insertions, 21 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 139d73e18a3c..239ae3fad054 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -73,6 +73,7 @@ struct sigmatel_spec {
73 hda_nid_t *pin_nids; 73 hda_nid_t *pin_nids;
74 unsigned int num_pins; 74 unsigned int num_pins;
75 unsigned int *pin_configs; 75 unsigned int *pin_configs;
76 unsigned int *bios_pin_configs;
76 77
77 /* codec specific stuff */ 78 /* codec specific stuff */
78 struct hda_verb *init; 79 struct hda_verb *init;
@@ -584,13 +585,42 @@ static struct hda_board_config stac9205_cfg_tbl[] = {
584 {} /* terminator */ 585 {} /* terminator */
585}; 586};
586 587
588static int stac92xx_save_bios_config_regs(struct hda_codec *codec)
589{
590 int i;
591 struct sigmatel_spec *spec = codec->spec;
592
593 if (! spec->bios_pin_configs) {
594 spec->bios_pin_configs = kcalloc(spec->num_pins,
595 sizeof(*spec->bios_pin_configs), GFP_KERNEL);
596 if (! spec->bios_pin_configs)
597 return -ENOMEM;
598 }
599
600 for (i = 0; i < spec->num_pins; i++) {
601 hda_nid_t nid = spec->pin_nids[i];
602 unsigned int pin_cfg;
603
604 pin_cfg = snd_hda_codec_read(codec, nid, 0,
605 AC_VERB_GET_CONFIG_DEFAULT, 0x00);
606 snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x bios pin config %8.8x\n",
607 nid, pin_cfg);
608 spec->bios_pin_configs[i] = pin_cfg;
609 }
610
611 return 0;
612}
613
587static void stac92xx_set_config_regs(struct hda_codec *codec) 614static void stac92xx_set_config_regs(struct hda_codec *codec)
588{ 615{
589 int i; 616 int i;
590 struct sigmatel_spec *spec = codec->spec; 617 struct sigmatel_spec *spec = codec->spec;
591 unsigned int pin_cfg; 618 unsigned int pin_cfg;
592 619
593 for (i=0; i < spec->num_pins; i++) { 620 if (! spec->pin_nids || ! spec->pin_configs)
621 return;
622
623 for (i = 0; i < spec->num_pins; i++) {
594 snd_hda_codec_write(codec, spec->pin_nids[i], 0, 624 snd_hda_codec_write(codec, spec->pin_nids[i], 0,
595 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0, 625 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0,
596 spec->pin_configs[i] & 0x000000ff); 626 spec->pin_configs[i] & 0x000000ff);
@@ -1302,6 +1332,9 @@ static void stac92xx_free(struct hda_codec *codec)
1302 kfree(spec->kctl_alloc); 1332 kfree(spec->kctl_alloc);
1303 } 1333 }
1304 1334
1335 if (spec->bios_pin_configs)
1336 kfree(spec->bios_pin_configs);
1337
1305 kfree(spec); 1338 kfree(spec);
1306} 1339}
1307 1340
@@ -1359,6 +1392,7 @@ static int stac92xx_resume(struct hda_codec *codec)
1359 int i; 1392 int i;
1360 1393
1361 stac92xx_init(codec); 1394 stac92xx_init(codec);
1395 stac92xx_set_config_regs(codec);
1362 for (i = 0; i < spec->num_mixers; i++) 1396 for (i = 0; i < spec->num_mixers; i++)
1363 snd_hda_resume_ctls(codec, spec->mixers[i]); 1397 snd_hda_resume_ctls(codec, spec->mixers[i]);
1364 if (spec->multiout.dig_out_nid) 1398 if (spec->multiout.dig_out_nid)
@@ -1391,12 +1425,18 @@ static int patch_stac9200(struct hda_codec *codec)
1391 return -ENOMEM; 1425 return -ENOMEM;
1392 1426
1393 codec->spec = spec; 1427 codec->spec = spec;
1428 spec->num_pins = 8;
1429 spec->pin_nids = stac9200_pin_nids;
1394 spec->board_config = snd_hda_check_board_config(codec, stac9200_cfg_tbl); 1430 spec->board_config = snd_hda_check_board_config(codec, stac9200_cfg_tbl);
1395 if (spec->board_config < 0) 1431 if (spec->board_config < 0) {
1396 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9200, using BIOS defaults\n"); 1432 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9200, using BIOS defaults\n");
1397 else { 1433 err = stac92xx_save_bios_config_regs(codec);
1398 spec->num_pins = 8; 1434 if (err < 0) {
1399 spec->pin_nids = stac9200_pin_nids; 1435 stac92xx_free(codec);
1436 return err;
1437 }
1438 spec->pin_configs = spec->bios_pin_configs;
1439 } else {
1400 spec->pin_configs = stac9200_brd_tbl[spec->board_config]; 1440 spec->pin_configs = stac9200_brd_tbl[spec->board_config];
1401 stac92xx_set_config_regs(codec); 1441 stac92xx_set_config_regs(codec);
1402 } 1442 }
@@ -1432,13 +1472,19 @@ static int patch_stac922x(struct hda_codec *codec)
1432 return -ENOMEM; 1472 return -ENOMEM;
1433 1473
1434 codec->spec = spec; 1474 codec->spec = spec;
1475 spec->num_pins = 10;
1476 spec->pin_nids = stac922x_pin_nids;
1435 spec->board_config = snd_hda_check_board_config(codec, stac922x_cfg_tbl); 1477 spec->board_config = snd_hda_check_board_config(codec, stac922x_cfg_tbl);
1436 if (spec->board_config < 0) 1478 if (spec->board_config < 0) {
1437 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, " 1479 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, "
1438 "using BIOS defaults\n"); 1480 "using BIOS defaults\n");
1439 else if (stac922x_brd_tbl[spec->board_config] != NULL) { 1481 err = stac92xx_save_bios_config_regs(codec);
1440 spec->num_pins = 10; 1482 if (err < 0) {
1441 spec->pin_nids = stac922x_pin_nids; 1483 stac92xx_free(codec);
1484 return err;
1485 }
1486 spec->pin_configs = spec->bios_pin_configs;
1487 } else if (stac922x_brd_tbl[spec->board_config] != NULL) {
1442 spec->pin_configs = stac922x_brd_tbl[spec->board_config]; 1488 spec->pin_configs = stac922x_brd_tbl[spec->board_config];
1443 stac92xx_set_config_regs(codec); 1489 stac92xx_set_config_regs(codec);
1444 } 1490 }
@@ -1476,12 +1522,18 @@ static int patch_stac927x(struct hda_codec *codec)
1476 return -ENOMEM; 1522 return -ENOMEM;
1477 1523
1478 codec->spec = spec; 1524 codec->spec = spec;
1525 spec->num_pins = 14;
1526 spec->pin_nids = stac927x_pin_nids;
1479 spec->board_config = snd_hda_check_board_config(codec, stac927x_cfg_tbl); 1527 spec->board_config = snd_hda_check_board_config(codec, stac927x_cfg_tbl);
1480 if (spec->board_config < 0) 1528 if (spec->board_config < 0) {
1481 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC927x, using BIOS defaults\n"); 1529 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC927x, using BIOS defaults\n");
1482 else if (stac927x_brd_tbl[spec->board_config] != NULL) { 1530 err = stac92xx_save_bios_config_regs(codec);
1483 spec->num_pins = 14; 1531 if (err < 0) {
1484 spec->pin_nids = stac927x_pin_nids; 1532 stac92xx_free(codec);
1533 return err;
1534 }
1535 spec->pin_configs = spec->bios_pin_configs;
1536 } else if (stac927x_brd_tbl[spec->board_config] != NULL) {
1485 spec->pin_configs = stac927x_brd_tbl[spec->board_config]; 1537 spec->pin_configs = stac927x_brd_tbl[spec->board_config];
1486 stac92xx_set_config_regs(codec); 1538 stac92xx_set_config_regs(codec);
1487 } 1539 }
@@ -1532,12 +1584,18 @@ static int patch_stac9205(struct hda_codec *codec)
1532 return -ENOMEM; 1584 return -ENOMEM;
1533 1585
1534 codec->spec = spec; 1586 codec->spec = spec;
1587 spec->num_pins = 14;
1588 spec->pin_nids = stac9205_pin_nids;
1535 spec->board_config = snd_hda_check_board_config(codec, stac9205_cfg_tbl); 1589 spec->board_config = snd_hda_check_board_config(codec, stac9205_cfg_tbl);
1536 if (spec->board_config < 0) 1590 if (spec->board_config < 0) {
1537 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9205, using BIOS defaults\n"); 1591 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9205, using BIOS defaults\n");
1538 else { 1592 err = stac92xx_save_bios_config_regs(codec);
1539 spec->num_pins = 14; 1593 if (err < 0) {
1540 spec->pin_nids = stac9205_pin_nids; 1594 stac92xx_free(codec);
1595 return err;
1596 }
1597 spec->pin_configs = spec->bios_pin_configs;
1598 } else {
1541 spec->pin_configs = stac9205_brd_tbl[spec->board_config]; 1599 spec->pin_configs = stac9205_brd_tbl[spec->board_config];
1542 stac92xx_set_config_regs(codec); 1600 stac92xx_set_config_regs(codec);
1543 } 1601 }