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