RE: [PATCH 3/3] ASoC: SOF: Intel: hda: duplicate _ADR entries share one amp index

"Liao, Bard" <[email protected]>
Newsgroups org.kernel.vger.linux-kernel,org.kernel.vger.linux-sound
Message-ID <SJ2PR11MB842442415FD961269F0D43DBFFD32@SJ2PR11MB8424.namprd11.prod.outlook.com>

> -----Original Message-----
> From: Sergey Lebedev <[email protected]>
> Sent: Wednesday, August 5, 2026 7:00 AM
> To: Mark Brown <[email protected]>; Liam Girdwood
> <[email protected]>; Jaroslav Kysela <[email protected]>; Takashi Iwai
> <[email protected]>; Oder Chiou <[email protected]>; Bard Liao <yung-
> [email protected]>; Peter Ujfalusi <[email protected]>;
> Kai Vehmanen <[email protected]>; Ranjani Sridharan
> <[email protected]>; Pierre-Louis Bossart <pierre-
> [email protected]>; Daniel Baluta <[email protected]>; Vijendar
> Mukunda <[email protected]>
> Cc: [email protected]; [email protected];
> [email protected]
> Subject: [PATCH 3/3] ASoC: SOF: Intel: hda: duplicate _ADR entries share one
> amp index
> 
> find_acpi_adr_device() assigns each amplifier a name prefix carrying an
> index ("rt1320-1", "rt1320-2", or Left/Right) and advances that index
> once per _ADR entry. Firmware that describes one physical part with two
> _ADR entries therefore consumes two indices for one device.
> 
> The Microsoft Surface Pro 11 (Intel) does exactly that. Link 0 carries:
> 
>   SWRA  _ADR 0x000030025D132000   SDCA class 0
>   SWRB  _ADR 0x000030025D132001   SDCA class 1
> 
> identical but for the class id: same link, same manufacturer, part and
> version, same unique id 0. The part reports class 1, so SWRB is the one
> that enumerates and SWRA never attaches on any boot or firmware version
> tested.
> 
> Both still reach this function, so SWRA takes index 1 and the real
> amplifier is named "rt1320-2". Its controls appear as "rt1320-2 OT23 L/R
> Switch". The stock sof-soundwire UCM profile expects the first
> amplifier, so it enables switches on a device that is not present, and
> the speakers stay silent while everything else reports success.
> 
> Compare entries that differ only in class id and give the later one the
> earlier one's name prefix, jumping past the amplifier-index increment so
> a repeated description consumes one index rather than several.
> 
> Testing the peripheral's attach status instead does not work here, and
> was tried: at machine-select time neither entry has attached yet, so a
> status test finds both unattached, no amplifier is matched at all, and
> the card falls back to the HDMI-only HDA machine driver. Comparing
> addresses needs no runtime state.
> 
> Signed-off-by: Sergey Lebedev <[email protected]>
> ---
>  sound/soc/sof/intel/hda.c | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
> 
> diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c
> index 4dbba9186..1d60a8caa 100644
> --- a/sound/soc/sof/intel/hda.c
> +++ b/sound/soc/sof/intel/hda.c
> @@ -1245,6 +1245,22 @@ static struct snd_soc_acpi_adr_device
> *find_acpi_adr_device(struct device *dev,
>  			((u64)(sdw_device->id.sdw_version & 0xF) << 44) |
>  			((u64)(sdw_device->bus->link_id & 0xF) << 48);
> 
> +	/*
> +	 * Firmware may describe a single physical part with more than one
> _ADR
> +	 * entry, differing only in SDCA class id. Those entries are the same
> +	 * device: they must share a name prefix, and only the first of them
> may
> +	 * consume an amp index. Otherwise the part that actually
> enumerates is
> +	 * named as though it were the second amplifier, and UCM profiles
> +	 * written for the first one address a device that is not there.
> +	 */

Not sure if it is true. AFAIK, Realtek has a few codecs with the same
part ID and different class ID and they are different codecs.
In other words, IIUC, rt1320 class 0 and 1 are 2 different codecs.

> +	for (j = 0; j < index; j++) {
> +		if ((adr_dev[j].adr & ~SDW_CLASS_ID_MASK) ==
> +		    (adr_dev[index].adr & ~SDW_CLASS_ID_MASK)) {
> +			adr_dev[index].name_prefix =
> adr_dev[j].name_prefix;
> +			goto done_name_prefix;
> +		}
> +	}
> +
>  	if (!codec_info_list[i].is_amp) {
>  		/* For non-amp codecs, get name_prefix from
> codec_info_list[] */
>  		adr_dev[index].name_prefix = devm_kasprintf(dev,
> GFP_KERNEL, "%s", name_prefix);
> --
> 2.50.1 (Apple Git-155)
> 
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.