aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2010-01-27 18:01:53 -0500
committerTakashi Iwai <tiwai@suse.de>2010-01-27 18:04:21 -0500
commitb09f3e78ee7bb69171411b75bd9e771fc7f24749 (patch)
treeed4d4f357a805425e19de53b6b3710150482df06 /sound/pci
parentccc5df058da70d1c26c72cd1c24072a89998d735 (diff)
ALSA: hda - Allow override more fields via patch loader
Allow the override of vendor-id, subsystem-id, revision-id and chip name via patch loading. Updated the document, too. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/hda_hwdep.c53
1 files changed, 38 insertions, 15 deletions
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c
index b36919c0d363..a1fc83753cc6 100644
--- a/sound/pci/hda/hda_hwdep.c
+++ b/sound/pci/hda/hda_hwdep.c
@@ -625,6 +625,10 @@ enum {
625 LINE_MODE_PINCFG, 625 LINE_MODE_PINCFG,
626 LINE_MODE_VERB, 626 LINE_MODE_VERB,
627 LINE_MODE_HINT, 627 LINE_MODE_HINT,
628 LINE_MODE_VENDOR_ID,
629 LINE_MODE_SUBSYSTEM_ID,
630 LINE_MODE_REVISION_ID,
631 LINE_MODE_CHIP_NAME,
628 NUM_LINE_MODES, 632 NUM_LINE_MODES,
629}; 633};
630 634
@@ -654,53 +658,71 @@ static void parse_codec_mode(char *buf, struct hda_bus *bus,
654} 658}
655 659
656/* parse the contents after the other command tags, [pincfg], [verb], 660/* parse the contents after the other command tags, [pincfg], [verb],
657 * [hint] and [model] 661 * [vendor_id], [subsystem_id], [revision_id], [chip_name], [hint] and [model]
658 * just pass to the sysfs helper (only when any codec was specified) 662 * just pass to the sysfs helper (only when any codec was specified)
659 */ 663 */
660static void parse_pincfg_mode(char *buf, struct hda_bus *bus, 664static void parse_pincfg_mode(char *buf, struct hda_bus *bus,
661 struct hda_codec **codecp) 665 struct hda_codec **codecp)
662{ 666{
663 if (!*codecp)
664 return;
665 parse_user_pin_configs(*codecp, buf); 667 parse_user_pin_configs(*codecp, buf);
666} 668}
667 669
668static void parse_verb_mode(char *buf, struct hda_bus *bus, 670static void parse_verb_mode(char *buf, struct hda_bus *bus,
669 struct hda_codec **codecp) 671 struct hda_codec **codecp)
670{ 672{
671 if (!*codecp)
672 return;
673 parse_init_verbs(*codecp, buf); 673 parse_init_verbs(*codecp, buf);
674} 674}
675 675
676static void parse_hint_mode(char *buf, struct hda_bus *bus, 676static void parse_hint_mode(char *buf, struct hda_bus *bus,
677 struct hda_codec **codecp) 677 struct hda_codec **codecp)
678{ 678{
679 if (!*codecp)
680 return;
681 parse_hints(*codecp, buf); 679 parse_hints(*codecp, buf);
682} 680}
683 681
684static void parse_model_mode(char *buf, struct hda_bus *bus, 682static void parse_model_mode(char *buf, struct hda_bus *bus,
685 struct hda_codec **codecp) 683 struct hda_codec **codecp)
686{ 684{
687 if (!*codecp)
688 return;
689 kfree((*codecp)->modelname); 685 kfree((*codecp)->modelname);
690 (*codecp)->modelname = kstrdup(buf, GFP_KERNEL); 686 (*codecp)->modelname = kstrdup(buf, GFP_KERNEL);
691} 687}
692 688
689static void parse_chip_name_mode(char *buf, struct hda_bus *bus,
690 struct hda_codec **codecp)
691{
692 kfree((*codecp)->chip_name);
693 (*codecp)->chip_name = kstrdup(buf, GFP_KERNEL);
694}
695
696#define DEFINE_PARSE_ID_MODE(name) \
697static void parse_##name##_mode(char *buf, struct hda_bus *bus, \
698 struct hda_codec **codecp) \
699{ \
700 unsigned long val; \
701 if (!strict_strtoul(buf, 0, &val)) \
702 (*codecp)->name = val; \
703}
704
705DEFINE_PARSE_ID_MODE(vendor_id);
706DEFINE_PARSE_ID_MODE(subsystem_id);
707DEFINE_PARSE_ID_MODE(revision_id);
708
709
693struct hda_patch_item { 710struct hda_patch_item {
694 const char *tag; 711 const char *tag;
695 void (*parser)(char *buf, struct hda_bus *bus, struct hda_codec **retc); 712 void (*parser)(char *buf, struct hda_bus *bus, struct hda_codec **retc);
713 int need_codec;
696}; 714};
697 715
698static struct hda_patch_item patch_items[NUM_LINE_MODES] = { 716static struct hda_patch_item patch_items[NUM_LINE_MODES] = {
699 [LINE_MODE_CODEC] = { "[codec]", parse_codec_mode }, 717 [LINE_MODE_CODEC] = { "[codec]", parse_codec_mode, 0 },
700 [LINE_MODE_MODEL] = { "[model]", parse_model_mode }, 718 [LINE_MODE_MODEL] = { "[model]", parse_model_mode, 1 },
701 [LINE_MODE_VERB] = { "[verb]", parse_verb_mode }, 719 [LINE_MODE_VERB] = { "[verb]", parse_verb_mode, 1 },
702 [LINE_MODE_PINCFG] = { "[pincfg]", parse_pincfg_mode }, 720 [LINE_MODE_PINCFG] = { "[pincfg]", parse_pincfg_mode, 1 },
703 [LINE_MODE_HINT] = { "[hint]", parse_hint_mode }, 721 [LINE_MODE_HINT] = { "[hint]", parse_hint_mode, 1 },
722 [LINE_MODE_VENDOR_ID] = { "[vendor_id]", parse_vendor_id_mode, 1 },
723 [LINE_MODE_SUBSYSTEM_ID] = { "[subsystem_id]", parse_subsystem_id_mode, 1 },
724 [LINE_MODE_REVISION_ID] = { "[revision_id]", parse_revision_id_mode, 1 },
725 [LINE_MODE_CHIP_NAME] = { "[chip_name]", parse_chip_name_mode, 1 },
704}; 726};
705 727
706/* check the line starting with '[' -- change the parser mode accodingly */ 728/* check the line starting with '[' -- change the parser mode accodingly */
@@ -783,7 +805,8 @@ int snd_hda_load_patch(struct hda_bus *bus, const char *patch)
783 continue; 805 continue;
784 if (*buf == '[') 806 if (*buf == '[')
785 line_mode = parse_line_mode(buf, bus); 807 line_mode = parse_line_mode(buf, bus);
786 else if (patch_items[line_mode].parser) 808 else if (patch_items[line_mode].parser &&
809 (codec || !patch_items[line_mode].need_codec))
787 patch_items[line_mode].parser(buf, bus, &codec); 810 patch_items[line_mode].parser(buf, bus, &codec);
788 } 811 }
789 release_firmware(fw); 812 release_firmware(fw);