diff options
author | Todd Broch <tbroch@chromium.org> | 2010-12-06 14:19:51 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2010-12-09 01:23:01 -0500 |
commit | e1eb5f10069b7c393174b3a272ad647537969862 (patch) | |
tree | e8276e32ca6bce5ccb7ed698121b6842b3e28f3d /sound/pci | |
parent | 116dcde638065a6b94344ca570e1e79c8e857826 (diff) |
ALSA: hda: Add modelname lookup and fixup for realtek codecs
Facilitate fixup for realtek codecs via modelname lookup of fixup
data. Fallback to quirk based lookup in absence of model definition.
Signed-off-by: Todd Broch <tbroch@chromium.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 61 |
1 files changed, 49 insertions, 12 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 0badedab1335..9ba4279c690d 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -1677,6 +1677,11 @@ struct alc_pincfg { | |||
1677 | u32 val; | 1677 | u32 val; |
1678 | }; | 1678 | }; |
1679 | 1679 | ||
1680 | struct alc_model_fixup { | ||
1681 | const int id; | ||
1682 | const char *name; | ||
1683 | }; | ||
1684 | |||
1680 | struct alc_fixup { | 1685 | struct alc_fixup { |
1681 | unsigned int sku; | 1686 | unsigned int sku; |
1682 | const struct alc_pincfg *pins; | 1687 | const struct alc_pincfg *pins; |
@@ -1685,23 +1690,19 @@ struct alc_fixup { | |||
1685 | int pre_init); | 1690 | int pre_init); |
1686 | }; | 1691 | }; |
1687 | 1692 | ||
1688 | static void alc_pick_fixup(struct hda_codec *codec, | 1693 | static void __alc_pick_fixup(struct hda_codec *codec, |
1689 | const struct snd_pci_quirk *quirk, | 1694 | const struct alc_fixup *fix, |
1690 | const struct alc_fixup *fix, | 1695 | const char *modelname, |
1691 | int pre_init) | 1696 | int pre_init) |
1692 | { | 1697 | { |
1693 | const struct alc_pincfg *cfg; | 1698 | const struct alc_pincfg *cfg; |
1694 | struct alc_spec *spec; | 1699 | struct alc_spec *spec; |
1695 | 1700 | ||
1696 | quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); | ||
1697 | if (!quirk) | ||
1698 | return; | ||
1699 | fix += quirk->value; | ||
1700 | cfg = fix->pins; | 1701 | cfg = fix->pins; |
1701 | if (pre_init && fix->sku) { | 1702 | if (pre_init && fix->sku) { |
1702 | #ifdef CONFIG_SND_DEBUG_VERBOSE | 1703 | #ifdef CONFIG_SND_DEBUG_VERBOSE |
1703 | snd_printdd(KERN_INFO "hda_codec: %s: Apply sku override for %s\n", | 1704 | snd_printdd(KERN_INFO "hda_codec: %s: Apply sku override for %s\n", |
1704 | codec->chip_name, quirk->name); | 1705 | codec->chip_name, modelname); |
1705 | #endif | 1706 | #endif |
1706 | spec = codec->spec; | 1707 | spec = codec->spec; |
1707 | spec->cdefine.sku_cfg = fix->sku; | 1708 | spec->cdefine.sku_cfg = fix->sku; |
@@ -1710,7 +1711,7 @@ static void alc_pick_fixup(struct hda_codec *codec, | |||
1710 | if (pre_init && cfg) { | 1711 | if (pre_init && cfg) { |
1711 | #ifdef CONFIG_SND_DEBUG_VERBOSE | 1712 | #ifdef CONFIG_SND_DEBUG_VERBOSE |
1712 | snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n", | 1713 | snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n", |
1713 | codec->chip_name, quirk->name); | 1714 | codec->chip_name, modelname); |
1714 | #endif | 1715 | #endif |
1715 | for (; cfg->nid; cfg++) | 1716 | for (; cfg->nid; cfg++) |
1716 | snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val); | 1717 | snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val); |
@@ -1718,19 +1719,55 @@ static void alc_pick_fixup(struct hda_codec *codec, | |||
1718 | if (!pre_init && fix->verbs) { | 1719 | if (!pre_init && fix->verbs) { |
1719 | #ifdef CONFIG_SND_DEBUG_VERBOSE | 1720 | #ifdef CONFIG_SND_DEBUG_VERBOSE |
1720 | snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n", | 1721 | snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n", |
1721 | codec->chip_name, quirk->name); | 1722 | codec->chip_name, modelname); |
1722 | #endif | 1723 | #endif |
1723 | add_verb(codec->spec, fix->verbs); | 1724 | add_verb(codec->spec, fix->verbs); |
1724 | } | 1725 | } |
1725 | if (fix->func) { | 1726 | if (fix->func) { |
1726 | #ifdef CONFIG_SND_DEBUG_VERBOSE | 1727 | #ifdef CONFIG_SND_DEBUG_VERBOSE |
1727 | snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-func for %s\n", | 1728 | snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-func for %s\n", |
1728 | codec->chip_name, quirk->name); | 1729 | codec->chip_name, modelname); |
1729 | #endif | 1730 | #endif |
1730 | fix->func(codec, fix, pre_init); | 1731 | fix->func(codec, fix, pre_init); |
1731 | } | 1732 | } |
1732 | } | 1733 | } |
1733 | 1734 | ||
1735 | static void alc_pick_fixup(struct hda_codec *codec, | ||
1736 | const struct snd_pci_quirk *quirk, | ||
1737 | const struct alc_fixup *fix, | ||
1738 | int pre_init) | ||
1739 | { | ||
1740 | quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); | ||
1741 | if (quirk) { | ||
1742 | fix += quirk->value; | ||
1743 | #ifdef CONFIG_SND_DEBUG_VERBOSE | ||
1744 | __alc_pick_fixup(codec, fix, quirk->name, pre_init); | ||
1745 | #else | ||
1746 | __alc_pick_fixup(codec, fix, NULL, pre_init); | ||
1747 | #endif | ||
1748 | } | ||
1749 | } | ||
1750 | |||
1751 | static void alc_pick_fixup_model(struct hda_codec *codec, | ||
1752 | const struct alc_model_fixup *models, | ||
1753 | const struct snd_pci_quirk *quirk, | ||
1754 | const struct alc_fixup *fix, | ||
1755 | int pre_init) | ||
1756 | { | ||
1757 | if (codec->modelname && models) { | ||
1758 | while (models->name) { | ||
1759 | if (!strcmp(codec->modelname, models->name)) { | ||
1760 | fix += models->id; | ||
1761 | break; | ||
1762 | } | ||
1763 | models++; | ||
1764 | } | ||
1765 | __alc_pick_fixup(codec, fix, codec->modelname, pre_init); | ||
1766 | } else { | ||
1767 | alc_pick_fixup(codec, quirk, fix, pre_init); | ||
1768 | } | ||
1769 | } | ||
1770 | |||
1734 | static int alc_read_coef_idx(struct hda_codec *codec, | 1771 | static int alc_read_coef_idx(struct hda_codec *codec, |
1735 | unsigned int coef_idx) | 1772 | unsigned int coef_idx) |
1736 | { | 1773 | { |