Skip to content

ASoC/soundwire: add companion amp support - #6025

Open
bardliao wants to merge 8 commits into
thesofproject:topic/sof-devfrom
bardliao:companion_amp-machine_driver
Open

bardliao wants to merge 8 commits into
thesofproject:topic/sof-devfrom
bardliao:companion_amp-machine_driver

Conversation

@bardliao

@bardliao bardliao commented Nov 6, 2026

Copy link
Copy Markdown
Collaborator

Some platforms use a SoundWire companion amp, which gets its audio data
from another SoundWire peripheral (the main amp) instead of from the
host. The current machine drivers and SoundWire core assume that every
stream is exchanged with the host, so these amps cannot be described or
configured.

This series adds the common support needed for such configurations:
a way to mark companion amp endpoints in the mach table, machine driver
support for the peripheral to peripheral path, a SoundWire stream type
that fits it.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Critical defects can block card registration, permanently defer probing, overlap companion-stream payload slots, and omit codec prefixes required to avoid control-name collisions and resolve routes.

5 open issues
What changed in this PR

This PR adds shared ASoC and SoundWire support for companion amplifiers that receive audio from another peripheral rather than the host.

Changes:

  • Adds companion endpoint metadata, grouping, and RT712/RT1320 DAI entries.
  • Creates Intel codec-to-codec links and adapts AMD drivers to the updated endpoint helpers.
  • Introduces a companion stream type and adjusts peripheral port offsets.
File Description
sound/​soc/​sof/​intel/​hda.c Excludes companion endpoints from automatic discovery.
sound/​soc/​sdw_utils/​soc_sdw_utils.c Adds companion DAI entries and endpoint grouping.
sound/​soc/​intel/​boards/​sof_sdw.c Creates companion codec-to-codec links.
sound/​soc/​amd/​acp/​acp-sdw-sof-mach.c Adapts SOF endpoint parsing for companion groups.
sound/​soc/​amd/​acp/​acp-sdw-legacy-mach.c Adapts legacy endpoint parsing for companion groups.
include/​sound/​soc-acpi.h Adds the companion endpoint flag.
include/​sound/​soc_sdw_utils.h Defines companion grouping structures and helper interfaces.
include/​linux/​soundwire/​sdw.h Adds the companion stream type.
drivers/​soundwire/​generic_bandwidth_allocation.c Resets port offsets for companion streams.

Review effort: Balanced

Comment thread sound/soc/intel/boards/sof_sdw.c Resolved
Comment thread sound/soc/intel/boards/sof_sdw.c Resolved
Comment thread sound/soc/sdw_utils/soc_sdw_utils.c Resolved

@plbossart plbossart left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Man you seem to start really big SoundWire changes. You should hire me haha...

Overall I didn't quite get how the new dailink is supposed to be handled, specifically how it's allocated, prepared and triggered. It's quite dependent on the host-peripheral dailink.

Comment thread include/sound/soc_sdw_utils.h Resolved
num_links = sdw_be_num + ssp_num + dmic_num + hdmi_num + bt_num + 1;
dai_links = devm_kcalloc(dev, num_links, sizeof(*dai_links), GFP_KERNEL);
num_links = sdw_be_num + ssp_num + dmic_num + hdmi_num + bt_num + num_comp_amps + 1;
dai_links = devm_kcalloc(dev, num_links + 1, sizeof(*dai_links), GFP_KERNEL);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you should explain why there's an additional dailink.

What's not clear specifically is how this dailink is handled, i.e. how it's allocated, prepared, triggered.

so far the device-to-device connections are not handled by the SoundWire core, so it's not clear how this might work?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is a codec to codec dai link to connect 2 peripherals. I will add some commits from @shumingfan to this PR to show how the link might work.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are test commits as follows:
5ad33ef
edffa25
6032198

Comment thread include/linux/soundwire/sdw.h Outdated
SDW_STREAM_PCM = 0,
SDW_STREAM_PDM = 1,
SDW_STREAM_BPT = 2,
SDW_STREAM_COMPANION = 3,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah but it could be PDM or PCM.

It think you'd need to add a new transport type, such as MANAGER_PERIPHERAL or PERIPHERAL_PERIPHERAL.

There are other uses cases where device-to-device communication is needed, e.g. to share the amp feedback. Don't make this just for the companion case.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ack

slave_total_ch += ch;

if (m_rt->stream->type == SDW_STREAM_COMPANION)
port_bo = t_data->block_offset;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not following this one.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is trying to let all peripherals use the same frame slots. Like rt1320 and rt712 use the same frame slots.

Comment thread sound/soc/sof/intel/hda.c Outdated
* the mach table if it is present.
*/
if (!is_endpoint_present(sdw_device, codec_info_list[i].dais[j].dai_type) ||
(codec_info_list[i].dais[j].quirk & SOC_SDW_COMPANION_AMPS))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the commit message says the opposite of what's done in other patches where you create a new dailink.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trying to skip the companion dais here to avoid creating the dai links that connect the companion dai to the host. And the companion link will be created later by create_sdw_comp_dailinks().

bardliao and others added 8 commits November 10, 2026 17:48
Add asoc_sdw_companion_amp_endpoint struct to help machine driver to
create codec to codec dai links for SoundWire companion amps.

Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
The sdw_stream_config structures in the manager drivers are not
initialized and only some of the fields are set. Initialize them to zero
so that any field added to the structure later, and not explicitly set
by these drivers, gets its default value instead of stack garbage.

Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
The companion stream is from peripheral to peripheral and all
peripherals need to use the same SoundWire frame area to transfer the
stream data.

Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
The companion amp dai links should not be created by the default machine
driver. We will create a mach table for the config that companion amp is
used.

Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Signed-off-by: Shuming Fan <shumingf@realtek.com>
Signed-off-by: Shuming Fan <shumingf@realtek.com>
Signed-off-by: Shuming Fan <shumingf@realtek.com>
Add the componion amp dai info for rt712 and rt1320. This commit is only
for testing which is not a correct information.

Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Copilot AI balanced review requested due to automatic review settings November 10, 2026 09:55
@bardliao
bardliao force-pushed the companion_amp-machine_driver branch from e890ae0 to ced34fe Compare November 10, 2026 09:55

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

* the SoundWire bus instead of from the host, so a codec-to-codec dai link is created between
* the main amp and the companion amps.
*/
#define SOC_SDW_COMPANION_AMPS BIT(18)
Comment on lines +3515 to +3517
.probe = asoc_sdw_c_amp_probe,
.startup = asoc_sdw_c_amp_startup,
.prepare = asoc_sdw_c_amp_prepare,
return PTR_ERR(sdw_stream);
}

sdw_stream->type = SDW_STREAM_COMPANION;
{
struct sdw_slave *slave = dev_to_sdw_dev(dai->dev);
struct sdw_stream_runtime *sdw_stream = NULL;
struct sdw_stream_config sconfig;
Comment on lines +2113 to +2115
pconfig.num = 0; // no meaning for companion stream

retval = sdw_stream_add_master(slave->bus, &sconfig, &pconfig, 1, sdw_stream);
Comment on lines +2190 to +2200
ret = sdw_disable_stream(sdw_stream);
if (ret) {
dev_err(dai->dev, "%s trigger (disable stream) failed: %d\n", __func__, ret);
return ret;
}

ret = sdw_deprepare_stream(sdw_stream);
if (ret) {
dev_err(dai->dev, "%s deprepare failed: %d\n", __func__, ret);
return ret;
}
Comment on lines +3350 to +3351
retval = sdw_stream_add_slave(rt1320->sdw_slave, &stream_config,
&companion_config, 1, sdw_stream);
Comment on lines +2227 to +2228
snd_soc_dai_stream_dma_data_set_playback(dai, NULL);
snd_soc_dai_stream_dma_data_set_capture(dai, NULL);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants