Loading Documentation/sound/alsa/HD-Audio.txt +27 −0 Original line number Diff line number Diff line Loading @@ -452,6 +452,33 @@ Similarly, the lines after `[verb]` are parsed as `init_verbs` sysfs entries, and the lines after `[hint]` are parsed as `hints` sysfs entries, respectively. Another example to override the codec vendor id from 0x12345678 to 0xdeadbeef is like below: ------------------------------------------------------------------------ [codec] 0x12345678 0xabcd1234 2 [vendor_id] 0xdeadbeef ------------------------------------------------------------------------ In the similar way, you can override the codec subsystem_id via `[subsystem_id]`, the revision id via `[revision_id]` line. Also, the codec chip name can be rewritten via `[chip_name]` line. ------------------------------------------------------------------------ [codec] 0x12345678 0xabcd1234 2 [subsystem_id] 0xffff1111 [revision_id] 0x10 [chip_name] My-own NEWS-0002 ------------------------------------------------------------------------ The hd-audio driver reads the file via request_firmware(). Thus, a patch file has to be located on the appropriate firmware path, typically, /lib/firmware. For example, when you pass the option Loading sound/pci/hda/hda_hwdep.c +38 −15 Original line number Diff line number Diff line Loading @@ -625,6 +625,10 @@ enum { LINE_MODE_PINCFG, LINE_MODE_VERB, LINE_MODE_HINT, LINE_MODE_VENDOR_ID, LINE_MODE_SUBSYSTEM_ID, LINE_MODE_REVISION_ID, LINE_MODE_CHIP_NAME, NUM_LINE_MODES, }; Loading Loading @@ -654,53 +658,71 @@ static void parse_codec_mode(char *buf, struct hda_bus *bus, } /* parse the contents after the other command tags, [pincfg], [verb], * [hint] and [model] * [vendor_id], [subsystem_id], [revision_id], [chip_name], [hint] and [model] * just pass to the sysfs helper (only when any codec was specified) */ static void parse_pincfg_mode(char *buf, struct hda_bus *bus, struct hda_codec **codecp) { if (!*codecp) return; parse_user_pin_configs(*codecp, buf); } static void parse_verb_mode(char *buf, struct hda_bus *bus, struct hda_codec **codecp) { if (!*codecp) return; parse_init_verbs(*codecp, buf); } static void parse_hint_mode(char *buf, struct hda_bus *bus, struct hda_codec **codecp) { if (!*codecp) return; parse_hints(*codecp, buf); } static void parse_model_mode(char *buf, struct hda_bus *bus, struct hda_codec **codecp) { if (!*codecp) return; kfree((*codecp)->modelname); (*codecp)->modelname = kstrdup(buf, GFP_KERNEL); } static void parse_chip_name_mode(char *buf, struct hda_bus *bus, struct hda_codec **codecp) { kfree((*codecp)->chip_name); (*codecp)->chip_name = kstrdup(buf, GFP_KERNEL); } #define DEFINE_PARSE_ID_MODE(name) \ static void parse_##name##_mode(char *buf, struct hda_bus *bus, \ struct hda_codec **codecp) \ { \ unsigned long val; \ if (!strict_strtoul(buf, 0, &val)) \ (*codecp)->name = val; \ } DEFINE_PARSE_ID_MODE(vendor_id); DEFINE_PARSE_ID_MODE(subsystem_id); DEFINE_PARSE_ID_MODE(revision_id); struct hda_patch_item { const char *tag; void (*parser)(char *buf, struct hda_bus *bus, struct hda_codec **retc); int need_codec; }; static struct hda_patch_item patch_items[NUM_LINE_MODES] = { [LINE_MODE_CODEC] = { "[codec]", parse_codec_mode }, [LINE_MODE_MODEL] = { "[model]", parse_model_mode }, [LINE_MODE_VERB] = { "[verb]", parse_verb_mode }, [LINE_MODE_PINCFG] = { "[pincfg]", parse_pincfg_mode }, [LINE_MODE_HINT] = { "[hint]", parse_hint_mode }, [LINE_MODE_CODEC] = { "[codec]", parse_codec_mode, 0 }, [LINE_MODE_MODEL] = { "[model]", parse_model_mode, 1 }, [LINE_MODE_VERB] = { "[verb]", parse_verb_mode, 1 }, [LINE_MODE_PINCFG] = { "[pincfg]", parse_pincfg_mode, 1 }, [LINE_MODE_HINT] = { "[hint]", parse_hint_mode, 1 }, [LINE_MODE_VENDOR_ID] = { "[vendor_id]", parse_vendor_id_mode, 1 }, [LINE_MODE_SUBSYSTEM_ID] = { "[subsystem_id]", parse_subsystem_id_mode, 1 }, [LINE_MODE_REVISION_ID] = { "[revision_id]", parse_revision_id_mode, 1 }, [LINE_MODE_CHIP_NAME] = { "[chip_name]", parse_chip_name_mode, 1 }, }; /* check the line starting with '[' -- change the parser mode accodingly */ Loading Loading @@ -783,7 +805,8 @@ int snd_hda_load_patch(struct hda_bus *bus, const char *patch) continue; if (*buf == '[') line_mode = parse_line_mode(buf, bus); else if (patch_items[line_mode].parser) else if (patch_items[line_mode].parser && (codec || !patch_items[line_mode].need_codec)) patch_items[line_mode].parser(buf, bus, &codec); } release_firmware(fw); Loading Loading
Documentation/sound/alsa/HD-Audio.txt +27 −0 Original line number Diff line number Diff line Loading @@ -452,6 +452,33 @@ Similarly, the lines after `[verb]` are parsed as `init_verbs` sysfs entries, and the lines after `[hint]` are parsed as `hints` sysfs entries, respectively. Another example to override the codec vendor id from 0x12345678 to 0xdeadbeef is like below: ------------------------------------------------------------------------ [codec] 0x12345678 0xabcd1234 2 [vendor_id] 0xdeadbeef ------------------------------------------------------------------------ In the similar way, you can override the codec subsystem_id via `[subsystem_id]`, the revision id via `[revision_id]` line. Also, the codec chip name can be rewritten via `[chip_name]` line. ------------------------------------------------------------------------ [codec] 0x12345678 0xabcd1234 2 [subsystem_id] 0xffff1111 [revision_id] 0x10 [chip_name] My-own NEWS-0002 ------------------------------------------------------------------------ The hd-audio driver reads the file via request_firmware(). Thus, a patch file has to be located on the appropriate firmware path, typically, /lib/firmware. For example, when you pass the option Loading
sound/pci/hda/hda_hwdep.c +38 −15 Original line number Diff line number Diff line Loading @@ -625,6 +625,10 @@ enum { LINE_MODE_PINCFG, LINE_MODE_VERB, LINE_MODE_HINT, LINE_MODE_VENDOR_ID, LINE_MODE_SUBSYSTEM_ID, LINE_MODE_REVISION_ID, LINE_MODE_CHIP_NAME, NUM_LINE_MODES, }; Loading Loading @@ -654,53 +658,71 @@ static void parse_codec_mode(char *buf, struct hda_bus *bus, } /* parse the contents after the other command tags, [pincfg], [verb], * [hint] and [model] * [vendor_id], [subsystem_id], [revision_id], [chip_name], [hint] and [model] * just pass to the sysfs helper (only when any codec was specified) */ static void parse_pincfg_mode(char *buf, struct hda_bus *bus, struct hda_codec **codecp) { if (!*codecp) return; parse_user_pin_configs(*codecp, buf); } static void parse_verb_mode(char *buf, struct hda_bus *bus, struct hda_codec **codecp) { if (!*codecp) return; parse_init_verbs(*codecp, buf); } static void parse_hint_mode(char *buf, struct hda_bus *bus, struct hda_codec **codecp) { if (!*codecp) return; parse_hints(*codecp, buf); } static void parse_model_mode(char *buf, struct hda_bus *bus, struct hda_codec **codecp) { if (!*codecp) return; kfree((*codecp)->modelname); (*codecp)->modelname = kstrdup(buf, GFP_KERNEL); } static void parse_chip_name_mode(char *buf, struct hda_bus *bus, struct hda_codec **codecp) { kfree((*codecp)->chip_name); (*codecp)->chip_name = kstrdup(buf, GFP_KERNEL); } #define DEFINE_PARSE_ID_MODE(name) \ static void parse_##name##_mode(char *buf, struct hda_bus *bus, \ struct hda_codec **codecp) \ { \ unsigned long val; \ if (!strict_strtoul(buf, 0, &val)) \ (*codecp)->name = val; \ } DEFINE_PARSE_ID_MODE(vendor_id); DEFINE_PARSE_ID_MODE(subsystem_id); DEFINE_PARSE_ID_MODE(revision_id); struct hda_patch_item { const char *tag; void (*parser)(char *buf, struct hda_bus *bus, struct hda_codec **retc); int need_codec; }; static struct hda_patch_item patch_items[NUM_LINE_MODES] = { [LINE_MODE_CODEC] = { "[codec]", parse_codec_mode }, [LINE_MODE_MODEL] = { "[model]", parse_model_mode }, [LINE_MODE_VERB] = { "[verb]", parse_verb_mode }, [LINE_MODE_PINCFG] = { "[pincfg]", parse_pincfg_mode }, [LINE_MODE_HINT] = { "[hint]", parse_hint_mode }, [LINE_MODE_CODEC] = { "[codec]", parse_codec_mode, 0 }, [LINE_MODE_MODEL] = { "[model]", parse_model_mode, 1 }, [LINE_MODE_VERB] = { "[verb]", parse_verb_mode, 1 }, [LINE_MODE_PINCFG] = { "[pincfg]", parse_pincfg_mode, 1 }, [LINE_MODE_HINT] = { "[hint]", parse_hint_mode, 1 }, [LINE_MODE_VENDOR_ID] = { "[vendor_id]", parse_vendor_id_mode, 1 }, [LINE_MODE_SUBSYSTEM_ID] = { "[subsystem_id]", parse_subsystem_id_mode, 1 }, [LINE_MODE_REVISION_ID] = { "[revision_id]", parse_revision_id_mode, 1 }, [LINE_MODE_CHIP_NAME] = { "[chip_name]", parse_chip_name_mode, 1 }, }; /* check the line starting with '[' -- change the parser mode accodingly */ Loading Loading @@ -783,7 +805,8 @@ int snd_hda_load_patch(struct hda_bus *bus, const char *patch) continue; if (*buf == '[') line_mode = parse_line_mode(buf, bus); else if (patch_items[line_mode].parser) else if (patch_items[line_mode].parser && (codec || !patch_items[line_mode].need_codec)) patch_items[line_mode].parser(buf, bus, &codec); } release_firmware(fw); Loading