aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorDavid Henningsson <david.henningsson@canonical.com>2010-10-14 08:50:18 -0400
committerTakashi Iwai <tiwai@suse.de>2010-10-17 04:20:27 -0400
commit906229174c20e3d5cbda8da070af8f30196316c3 (patch)
treea3db9c5eef95a74108b5961852b498c198af1903 /sound
parent2df03514de41f3bbb5623f2e7f2bf594e49cb2ec (diff)
ALSA: HDA: Enable SKU quirks for Realtek
Realtek have ways of specifying external amps and more via a special nid or via the Codec's subsystem ID, this is called "SKU". The computer manufacturer sometimes gets this wrong, so we need to be able to override or ignore the SKU customization value. Signed-off-by: David Henningsson <david.henningsson@canonical.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/hda/patch_realtek.c35
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
306struct alc_spec { 307struct 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
1467static int alc_auto_parse_customize_define(struct hda_codec *codec) 1473static 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
1660struct alc_fixup { 1680struct 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);