[PATCH 0/3] ALSA: hda: SSID aliasing via model option
![](https://secure.gravatar.com/avatar/5b19e9d0e834ea10ef75803718ad564b.jpg?s=120&d=mm&r=g)
Hi,
this is a patch set for enhancement of HD-audio configuration. There are lots of cases where a quick is applied only with PCI or codec SSID matching but no corresponding model option entry is provided. In such a case, user had to modify and recompile the code, or using the early patching with patch option, both of which are cumbersome.
This option makes it easier to apply a quirk of another device. Now you can pass model option string in a form of 1234:abcd for specifying the SSID of the alias target.
Takashi
===
Takashi Iwai (3): ALSA: hda: Code refactoring snd_hda_pick_fixup() ALSA: hda: Allow model option to specify PCI SSID alias ALSA: hda: Update documentation for aliasing via the model option
Documentation/sound/alsa-configuration.rst | 6 ++ Documentation/sound/hd-audio/notes.rst | 11 +++ sound/pci/hda/hda_auto_parser.c | 84 +++++++++++++--------- 3 files changed, 66 insertions(+), 35 deletions(-)
![](https://secure.gravatar.com/avatar/5b19e9d0e834ea10ef75803718ad564b.jpg?s=120&d=mm&r=g)
This contains a slight code refactoring of snd_hda_pick_fixup(): - Unify the ID setup - Unify the debug print message - Use snd_pci_quirk_lookup_id() for the codec SSID matching
Mostly for simplifying the code flow but also it makes easier to add the codec alias handling in the upcoming patch.
Signed-off-by: Takashi Iwai tiwai@suse.de --- sound/pci/hda/hda_auto_parser.c | 75 +++++++++++++++++---------------- 1 file changed, 38 insertions(+), 37 deletions(-)
diff --git a/sound/pci/hda/hda_auto_parser.c b/sound/pci/hda/hda_auto_parser.c index 1a001ecf7f63..dd050be7aefa 100644 --- a/sound/pci/hda/hda_auto_parser.c +++ b/sound/pci/hda/hda_auto_parser.c @@ -982,65 +982,66 @@ void snd_hda_pick_fixup(struct hda_codec *codec, const struct snd_pci_quirk *q; int id = HDA_FIXUP_ID_NOT_SET; const char *name = NULL; + const char *type = NULL;
if (codec->fixup_id != HDA_FIXUP_ID_NOT_SET) return;
/* when model=nofixup is given, don't pick up any fixups */ if (codec->modelname && !strcmp(codec->modelname, "nofixup")) { - codec->fixup_list = NULL; - codec->fixup_name = NULL; - codec->fixup_id = HDA_FIXUP_ID_NO_FIXUP; + id = HDA_FIXUP_ID_NO_FIXUP; + fixlist = NULL; codec_dbg(codec, "%s: picked no fixup (nofixup specified)\n", codec->core.chip_name); - return; + goto found; }
+ /* match with the model name string */ if (codec->modelname && models) { while (models->name) { if (!strcmp(codec->modelname, models->name)) { - codec->fixup_id = models->id; - codec->fixup_name = models->name; - codec->fixup_list = fixlist; + id = models->id; + name = models->name; codec_dbg(codec, "%s: picked fixup %s (model specified)\n", codec->core.chip_name, codec->fixup_name); - return; + goto found; } models++; } } - if (quirk) { - q = snd_pci_quirk_lookup(codec->bus->pci, quirk); - if (q) { - id = q->value; -#ifdef CONFIG_SND_DEBUG_VERBOSE - name = q->name; - codec_dbg(codec, "%s: picked fixup %s (PCI SSID%s)\n", - codec->core.chip_name, name, q->subdevice_mask ? "" : " - vendor generic"); -#endif - } + + if (!quirk) + return; + + /* match with the PCI SSID */ + q = snd_pci_quirk_lookup(codec->bus->pci, quirk); + if (q) { + type = "PCI SSID"; + goto found_device; } - if (id < 0 && quirk) { - for (q = quirk; q->subvendor || q->subdevice; q++) { - unsigned int vendorid = - q->subdevice | (q->subvendor << 16); - unsigned int mask = 0xffff0000 | q->subdevice_mask; - if ((codec->core.subsystem_id & mask) == (vendorid & mask)) { - id = q->value; -#ifdef CONFIG_SND_DEBUG_VERBOSE - name = q->name; - codec_dbg(codec, "%s: picked fixup %s (codec SSID)\n", - codec->core.chip_name, name); -#endif - break; - } - } + + /* match with the codec SSID */ + q = snd_pci_quirk_lookup_id(codec->core.subsystem_id >> 16, + codec->core.subsystem_id & 0xffff, + quirk); + if (q) { + type = "codec SSID"; + goto found_device; }
+ return; /* no matching */ + + found_device: + id = q->value; +#ifdef CONFIG_SND_DEBUG_VERBOSE + name = q->name; +#endif + codec_dbg(codec, "%s: picked fixup %s for %s %04x:%04x\n", + codec->core.chip_name, name ? name : "", + type, q->subvendor, q->subdevice); + found: codec->fixup_id = id; - if (id >= 0) { - codec->fixup_list = fixlist; - codec->fixup_name = name; - } + codec->fixup_list = fixlist; + codec->fixup_name = name; } EXPORT_SYMBOL_GPL(snd_hda_pick_fixup);
![](https://secure.gravatar.com/avatar/5b19e9d0e834ea10ef75803718ad564b.jpg?s=120&d=mm&r=g)
There are tons of quirks for HD-audio and many of them are without model string, hence it's not trivial to apply the same quirk for a new device. This patch makes it easier: namely, the model string accepts a form as "XXXX:YYYY" (a pair of hex numbers of the subsystem-vendor and subsystem-device IDs), to specify the alias of PCI (or codec) SSID. e.g. passing model=1234:abcd would apply the quirk that matches with the given SSID 1234:abcd instead of the actual SSID.
Signed-off-by: Takashi Iwai tiwai@suse.de --- sound/pci/hda/hda_auto_parser.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/sound/pci/hda/hda_auto_parser.c b/sound/pci/hda/hda_auto_parser.c index dd050be7aefa..4a854475a0e6 100644 --- a/sound/pci/hda/hda_auto_parser.c +++ b/sound/pci/hda/hda_auto_parser.c @@ -971,6 +971,8 @@ EXPORT_SYMBOL_GPL(snd_hda_pick_pin_fixup); * When a special model string "nofixup" is given, also no fixup is applied. * * The function tries to find the matching model name at first, if given. + * If the model string contains the SSID alias, try to look up with the given + * alias ID. * If nothing matched, try to look up the PCI SSID. * If still nothing matched, try to look up the codec SSID. */ @@ -983,6 +985,7 @@ void snd_hda_pick_fixup(struct hda_codec *codec, int id = HDA_FIXUP_ID_NOT_SET; const char *name = NULL; const char *type = NULL; + int vendor, device;
if (codec->fixup_id != HDA_FIXUP_ID_NOT_SET) return; @@ -1013,6 +1016,16 @@ void snd_hda_pick_fixup(struct hda_codec *codec, if (!quirk) return;
+ /* match with the SSID alias given by the model string "XXXX:YYYY" */ + if (codec->modelname && + sscanf(codec->modelname, "%04x:%04x", &vendor, &device) == 2) { + q = snd_pci_quirk_lookup_id(vendor, device, quirk); + if (q) { + type = "alias SSID"; + goto found_device; + } + } + /* match with the PCI SSID */ q = snd_pci_quirk_lookup(codec->bus->pci, quirk); if (q) {
![](https://secure.gravatar.com/avatar/5b19e9d0e834ea10ef75803718ad564b.jpg?s=120&d=mm&r=g)
The previous patch allowed user to specify the aliasing of SSID via model option for applying a quirk. Update the documentation accordingly.
Signed-off-by: Takashi Iwai tiwai@suse.de --- Documentation/sound/alsa-configuration.rst | 6 ++++++ Documentation/sound/hd-audio/notes.rst | 11 +++++++++++ 2 files changed, 17 insertions(+)
diff --git a/Documentation/sound/alsa-configuration.rst b/Documentation/sound/alsa-configuration.rst index f148b58502c0..e61edd1295fc 100644 --- a/Documentation/sound/alsa-configuration.rst +++ b/Documentation/sound/alsa-configuration.rst @@ -1059,6 +1059,12 @@ The model name ``generic`` is treated as a special case. When this model is given, the driver uses the generic codec parser without "codec-patch". It's sometimes good for testing and debugging.
+The model option can be used also for aliasing to another PCI or codec +SSID. When it's passed in the form of ``model=XXXX:YYYY`` where XXXX +and YYYY are the sub-vendor and sub-device IDs in hex numbers, +respectively, the driver will refer to that SSID as a reference to the +quirk table. + If the default configuration doesn't work and one of the above matches with your device, report it together with alsa-info.sh output (with ``--no-upload`` option) to kernel bugzilla or alsa-devel diff --git a/Documentation/sound/hd-audio/notes.rst b/Documentation/sound/hd-audio/notes.rst index cf4d7158af78..d118b6fe269b 100644 --- a/Documentation/sound/hd-audio/notes.rst +++ b/Documentation/sound/hd-audio/notes.rst @@ -215,6 +215,17 @@ There are a few special model option values: * when ``generic`` is passed, the codec-specific parser is skipped and only the generic parser is used.
+A new style for the model option that was introduced since 5.15 kernel +is to pass the PCI or codec SSID in the form of ``model=XXXX:YYYY`` +where XXXX and YYYY are the sub-vendor and sub-device IDs in hex +numbers, respectively. This is a kind of aliasing to another device; +when this form is given, the driver will refer to that SSID as a +reference to the quirk table. It'd be useful especially when the +target quirk isn't listed in the model table. For example, passing +model=103c:8862 will apply the quirk for HP ProBook 445 G8 (which +isn't found in the model table as of writing) as long as the device is +handled equivalently by the same driver. +
Speaker and Headphone Output ----------------------------
participants (1)
-
Takashi Iwai