How to add 2 different SND_PCI_QUIRKs for 2 models with the same PCI subsys vend + prod ids?
Hans de Goede
hdegoede at redhat.com
Mon Jun 13 22:53:54 CEST 2022
Hi,
On 6/13/22 11:13, Takashi Iwai wrote:
> On Mon, 13 Jun 2022 10:46:28 +0200,
> Hans de Goede wrote:
>>
>> Hi,
>>
>> On 6/13/22 10:28, Takashi Iwai wrote:
>>> On Mon, 13 Jun 2022 09:54:47 +0200,
>>> Hans de Goede wrote:
>>>>
>>>> Hi All,
>>>>
>>>> There is a problem with the sound on the Lenovo Yoga Duet 7 13IML05, which
>>>> requires a SND_PCI_QUIRK to fix. But there already is an existing quirk
>>>> for another Lenovo laptop using the same PCI subsys vend + prod ids.
>>>>
>>>> For more details see:
>>>> https://wiki.archlinux.org/title/Lenovo_Yoga_Duet_7_13IML05#Audio
>>>>
>>>> So I guess this means that we need to add a way to also include a DMI match
>>>> for SND_PCI_QUIRKs ?
>>>>
>>>> Maybe add a:
>>>>
>>>> const struct dmi_systemid *dmi_ids;
>>>>
>>>> member to struct snd_pci_quirk and a new
>>>> SND_PCI_QUIRK_DMI macro to set this?
>>>
>>> Do both machines have the very same codec? I couldn't find
>>> alsa-info.sh output for Duet 7, but at least, C940 seems with ALC298
>>> (0x10ec0298), judging from
>>> https://bugzilla.kernel.org/show_bug.cgi?id=205755
>>> If Duet 7 has a different codec (e.g. ALC287 0x10ec0287), we can
>>> distinguish from that.
>>
>> I've just asked the reporter of this for alsa-info.sh output.
>>
>> So assuming the codec is indeed different how would I go about
>> fixing this ?
>
> It'll be something like below.
Thanks.
The alsa-info.sh output for the Yoga Duet 7 is here:
http://alsa-project.org/db/?f=5500aa1b489d2ef4ee6ac3ee613f11f3ed8ecfa8
This confirms that the codec is different, so I've asked
@nikitashvets to test the below patch you suggested and
he has confirmed that this fixes things (thank you @nikitashvets).
Takashi, if you can turn this into a proper patch (-series?)
and merge it that would be great!
Regards,
Hans
>
>
> Takashi
>
> -- 8< --
> diff --git a/sound/pci/hda/hda_auto_parser.c b/sound/pci/hda/hda_auto_parser.c
> index cd1db943b7e0..7c6b1fe8dfcc 100644
> --- a/sound/pci/hda/hda_auto_parser.c
> +++ b/sound/pci/hda/hda_auto_parser.c
> @@ -819,7 +819,7 @@ static void set_pin_targets(struct hda_codec *codec,
> snd_hda_set_pin_ctl_cache(codec, cfg->nid, cfg->val);
> }
>
> -static void apply_fixup(struct hda_codec *codec, int id, int action, int depth)
> +void __snd_hda_apply_fixup(struct hda_codec *codec, int id, int action, int depth)
> {
> const char *modelname = codec->fixup_name;
>
> @@ -829,7 +829,7 @@ static void apply_fixup(struct hda_codec *codec, int id, int action, int depth)
> if (++depth > 10)
> break;
> if (fix->chained_before)
> - apply_fixup(codec, fix->chain_id, action, depth + 1);
> + __snd_hda_apply_fixup(codec, fix->chain_id, action, depth + 1);
>
> switch (fix->type) {
> case HDA_FIXUP_PINS:
> @@ -870,6 +870,7 @@ static void apply_fixup(struct hda_codec *codec, int id, int action, int depth)
> id = fix->chain_id;
> }
> }
> +EXPORT_SYMBOL_GPL(__snd_hda_apply_fixup);
>
> /**
> * snd_hda_apply_fixup - Apply the fixup chain with the given action
> @@ -879,7 +880,7 @@ static void apply_fixup(struct hda_codec *codec, int id, int action, int depth)
> void snd_hda_apply_fixup(struct hda_codec *codec, int action)
> {
> if (codec->fixup_list)
> - apply_fixup(codec, codec->fixup_id, action, 0);
> + __snd_hda_apply_fixup(codec, codec->fixup_id, action, 0);
> }
> EXPORT_SYMBOL_GPL(snd_hda_apply_fixup);
>
> diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
> index aca592651870..682dca2057db 100644
> --- a/sound/pci/hda/hda_local.h
> +++ b/sound/pci/hda/hda_local.h
> @@ -348,6 +348,7 @@ void snd_hda_apply_verbs(struct hda_codec *codec);
> void snd_hda_apply_pincfgs(struct hda_codec *codec,
> const struct hda_pintbl *cfg);
> void snd_hda_apply_fixup(struct hda_codec *codec, int action);
> +void __snd_hda_apply_fixup(struct hda_codec *codec, int id, int action, int depth);
> void snd_hda_pick_fixup(struct hda_codec *codec,
> const struct hda_model_fixup *models,
> const struct snd_pci_quirk *quirk,
> diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
> index a1a7842e7b5f..f2b0de3aa756 100644
> --- a/sound/pci/hda/patch_realtek.c
> +++ b/sound/pci/hda/patch_realtek.c
> @@ -7004,6 +7004,7 @@ enum {
> ALC287_FIXUP_LEGION_15IMHG05_SPEAKERS,
> ALC287_FIXUP_LEGION_15IMHG05_AUTOMUTE,
> ALC287_FIXUP_YOGA7_14ITL_SPEAKERS,
> + ALC298_FIXUP_LENOVO_C940_DUET7,
> ALC287_FIXUP_13S_GEN2_SPEAKERS,
> ALC256_FIXUP_SET_COEF_DEFAULTS,
> ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE,
> @@ -7022,6 +7023,23 @@ enum {
> ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE,
> };
>
> +/* A special fixup for Lenovo C940 and Yoga Duet 7;
> + * both have the very same PCI SSID, and we need to apply different fixups
> + * depending on the codec ID
> + */
> +static void alc298_fixup_lenovo_c940_duet7(struct hda_codec *codec,
> + const struct hda_fixup *fix,
> + int action)
> +{
> + int id;
> +
> + if (codec->core.vendor_id == 0x10ec0298)
> + id = ALC298_FIXUP_LENOVO_SPK_VOLUME; /* C940 */
> + else
> + id = ALC287_FIXUP_YOGA7_14ITL_SPEAKERS; /* Duet 7 */
> + __snd_hda_apply_fixup(codec, id, action, 0);
> +}
> +
> static const struct hda_fixup alc269_fixups[] = {
> [ALC269_FIXUP_GPIO2] = {
> .type = HDA_FIXUP_FUNC,
> @@ -8721,6 +8739,10 @@ static const struct hda_fixup alc269_fixups[] = {
> .chained = true,
> .chain_id = ALC269_FIXUP_HEADSET_MODE,
> },
> + [ALC298_FIXUP_LENOVO_C940_DUET7] = {
> + .type = HDA_FIXUP_FUNC,
> + .v.func = alc298_fixup_lenovo_c940_duet7,
> + },
> [ALC287_FIXUP_13S_GEN2_SPEAKERS] = {
> .type = HDA_FIXUP_VERBS,
> .v.verbs = (const struct hda_verb[]) {
> @@ -9274,7 +9296,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
> SND_PCI_QUIRK(0x17aa, 0x31af, "ThinkCentre Station", ALC623_FIXUP_LENOVO_THINKSTATION_P340),
> SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo Yoga DuetITL 2021", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS),
> SND_PCI_QUIRK(0x17aa, 0x3813, "Legion 7i 15IMHG05", ALC287_FIXUP_LEGION_15IMHG05_SPEAKERS),
> - SND_PCI_QUIRK(0x17aa, 0x3818, "Lenovo C940", ALC298_FIXUP_LENOVO_SPK_VOLUME),
> + SND_PCI_QUIRK(0x17aa, 0x3818, "Lenovo C940 / Yoga Duet 7", ALC298_FIXUP_LENOVO_C940_DUET7),
> SND_PCI_QUIRK(0x17aa, 0x3819, "Lenovo 13s Gen2 ITL", ALC287_FIXUP_13S_GEN2_SPEAKERS),
> SND_PCI_QUIRK(0x17aa, 0x3820, "Yoga Duet 7 13ITL6", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS),
> SND_PCI_QUIRK(0x17aa, 0x3824, "Legion Y9000X 2020", ALC285_FIXUP_LEGION_Y9000X_SPEAKERS),
>
More information about the Alsa-devel
mailing list