diff options
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index c41ac30ffc7f..7b24a2d72936 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -301,6 +301,7 @@ struct alc_customize_define { | |||
301 | unsigned int platform_type:1; | 301 | unsigned int platform_type:1; |
302 | unsigned int swap:1; | 302 | unsigned int swap:1; |
303 | unsigned int override:1; | 303 | unsigned int override:1; |
304 | unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */ | ||
304 | }; | 305 | }; |
305 | 306 | ||
306 | struct alc_spec { | 307 | struct alc_spec { |
@@ -1464,6 +1465,11 @@ static void alc_init_auto_mic(struct hda_codec *codec) | |||
1464 | spec->unsol_event = alc_sku_unsol_event; | 1465 | spec->unsol_event = alc_sku_unsol_event; |
1465 | } | 1466 | } |
1466 | 1467 | ||
1468 | /* Could be any non-zero and even value. When used as fixup, tells | ||
1469 | * the driver to ignore any present sku defines. | ||
1470 | */ | ||
1471 | #define ALC_FIXUP_SKU_IGNORE (2) | ||
1472 | |||
1467 | static int alc_auto_parse_customize_define(struct hda_codec *codec) | 1473 | static int alc_auto_parse_customize_define(struct hda_codec *codec) |
1468 | { | 1474 | { |
1469 | unsigned int ass, tmp, i; | 1475 | unsigned int ass, tmp, i; |
@@ -1472,6 +1478,13 @@ static int alc_auto_parse_customize_define(struct hda_codec *codec) | |||
1472 | 1478 | ||
1473 | spec->cdefine.enable_pcbeep = 1; /* assume always enabled */ | 1479 | spec->cdefine.enable_pcbeep = 1; /* assume always enabled */ |
1474 | 1480 | ||
1481 | if (spec->cdefine.fixup) { | ||
1482 | ass = spec->cdefine.sku_cfg; | ||
1483 | if (ass == ALC_FIXUP_SKU_IGNORE) | ||
1484 | return -1; | ||
1485 | goto do_sku; | ||
1486 | } | ||
1487 | |||
1475 | ass = codec->subsystem_id & 0xffff; | 1488 | ass = codec->subsystem_id & 0xffff; |
1476 | if (ass != codec->bus->pci->subsystem_device && (ass & 1)) | 1489 | if (ass != codec->bus->pci->subsystem_device && (ass & 1)) |
1477 | goto do_sku; | 1490 | goto do_sku; |
@@ -1539,6 +1552,13 @@ static int alc_subsystem_id(struct hda_codec *codec, | |||
1539 | unsigned nid; | 1552 | unsigned nid; |
1540 | struct alc_spec *spec = codec->spec; | 1553 | struct alc_spec *spec = codec->spec; |
1541 | 1554 | ||
1555 | if (spec->cdefine.fixup) { | ||
1556 | ass = spec->cdefine.sku_cfg; | ||
1557 | if (ass == ALC_FIXUP_SKU_IGNORE) | ||
1558 | return 0; | ||
1559 | goto do_sku; | ||
1560 | } | ||
1561 | |||
1542 | ass = codec->subsystem_id & 0xffff; | 1562 | ass = codec->subsystem_id & 0xffff; |
1543 | if ((ass != codec->bus->pci->subsystem_device) && (ass & 1)) | 1563 | if ((ass != codec->bus->pci->subsystem_device) && (ass & 1)) |
1544 | goto do_sku; | 1564 | goto do_sku; |
@@ -1658,6 +1678,7 @@ struct alc_pincfg { | |||
1658 | }; | 1678 | }; |
1659 | 1679 | ||
1660 | struct alc_fixup { | 1680 | struct alc_fixup { |
1681 | unsigned int sku; | ||
1661 | const struct alc_pincfg *pins; | 1682 | const struct alc_pincfg *pins; |
1662 | const struct hda_verb *verbs; | 1683 | const struct hda_verb *verbs; |
1663 | }; | 1684 | }; |
@@ -1668,12 +1689,22 @@ static void alc_pick_fixup(struct hda_codec *codec, | |||
1668 | int pre_init) | 1689 | int pre_init) |
1669 | { | 1690 | { |
1670 | const struct alc_pincfg *cfg; | 1691 | const struct alc_pincfg *cfg; |
1692 | struct alc_spec *spec; | ||
1671 | 1693 | ||
1672 | quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); | 1694 | quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); |
1673 | if (!quirk) | 1695 | if (!quirk) |
1674 | return; | 1696 | return; |
1675 | fix += quirk->value; | 1697 | fix += quirk->value; |
1676 | cfg = fix->pins; | 1698 | cfg = fix->pins; |
1699 | if (pre_init && fix->sku) { | ||
1700 | #ifdef CONFIG_SND_DEBUG_VERBOSE | ||
1701 | snd_printdd(KERN_INFO "hda_codec: %s: Apply sku override for %s\n", | ||
1702 | codec->chip_name, quirk->name); | ||
1703 | #endif | ||
1704 | spec = codec->spec; | ||
1705 | spec->cdefine.sku_cfg = fix->sku; | ||
1706 | spec->cdefine.fixup = 1; | ||
1707 | } | ||
1677 | if (pre_init && cfg) { | 1708 | if (pre_init && cfg) { |
1678 | #ifdef CONFIG_SND_DEBUG_VERBOSE | 1709 | #ifdef CONFIG_SND_DEBUG_VERBOSE |
1679 | snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n", | 1710 | snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n", |
@@ -10861,8 +10892,6 @@ static int patch_alc882(struct hda_codec *codec) | |||
10861 | 10892 | ||
10862 | codec->spec = spec; | 10893 | codec->spec = spec; |
10863 | 10894 | ||
10864 | alc_auto_parse_customize_define(codec); | ||
10865 | |||
10866 | switch (codec->vendor_id) { | 10895 | switch (codec->vendor_id) { |
10867 | case 0x10ec0882: | 10896 | case 0x10ec0882: |
10868 | case 0x10ec0885: | 10897 | case 0x10ec0885: |
@@ -10890,6 +10919,8 @@ static int patch_alc882(struct hda_codec *codec) | |||
10890 | if (board_config == ALC882_AUTO) | 10919 | if (board_config == ALC882_AUTO) |
10891 | alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 1); | 10920 | alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 1); |
10892 | 10921 | ||
10922 | alc_auto_parse_customize_define(codec); | ||
10923 | |||
10893 | if (board_config == ALC882_AUTO) { | 10924 | if (board_config == ALC882_AUTO) { |
10894 | /* automatic parse from the BIOS config */ | 10925 | /* automatic parse from the BIOS config */ |
10895 | err = alc882_parse_auto_config(codec); | 10926 | err = alc882_parse_auto_config(codec); |