RE: [PATCH 3/3] ASoC: SOF: Intel: hda: duplicate _ADR entries share one amp index
"Liao, Bard" <[email protected]> Wed, 5 Aug 2026 01:21:57 +0000
| Newsgroups | org.kernel.vger.linux-sound,org.kernel.vger.linux-kernel |
|---|---|
| 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) > >