diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 100 |
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 | ||
588 | static 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 | |||
587 | static void stac92xx_set_config_regs(struct hda_codec *codec) | 614 | static 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 | } |