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); |
