Skip to content

ASoC: SOF: ipc4-pcm: Add fixup for channels #5441

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: topic/sof-dev
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions sound/soc/sof/ipc4-pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,58 @@ static int sof_ipc4_pcm_dai_link_fixup_rate(struct snd_sof_dev *sdev,
return 0;
}

static int sof_ipc4_pcm_dai_link_fixup_channels(struct snd_sof_dev *sdev,
struct snd_pcm_hw_params *params,
struct sof_ipc4_copier *ipc4_copier)
{
struct sof_ipc4_pin_format *pin_fmts = ipc4_copier->available_fmt.input_pin_fmts;
struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
int num_input_formats = ipc4_copier->available_fmt.num_input_formats;
unsigned int fe_channels = params_channels(params);
bool fe_be_match = false;
bool single_be_channels = true;
unsigned int be_channels, val;
int i;

if (WARN_ON_ONCE(!num_input_formats))
return -EINVAL;

/*
* Copier does not change channels, so we
* need to only consider the input pin information.
*/
be_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(pin_fmts[0].audio_fmt.fmt_cfg);
for (i = 0; i < num_input_formats; i++) {
val = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(pin_fmts[i].audio_fmt.fmt_cfg);

if (val != be_channels)
single_be_channels = false;

if (val == fe_channels) {
fe_be_match = true;
break;
}
}

/*
* If channels is different than FE channels, topology must contain a
* module which can change the number of channels. But we do require
* topology to define a single channels in the DAI copier config in
* this case (FE channels may be variable).
*/
Copy link
Collaborator

Choose a reason for hiding this comment

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

What should we do if fe_be_match = true but single_be_channels = false? I.e. One of the pin formats matches the fe channels.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@bardliao, then we don't need to do anything, no fixup is needed, the FE channels are the same as the BE.

if (!fe_be_match) {
if (!single_be_channels) {
dev_err(sdev->dev, "Unable to select channels for DAI link\n");
return -EINVAL;
}

channels->min = be_channels;
channels->max = be_channels;
}

return 0;
}

static int sof_ipc4_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
Expand Down Expand Up @@ -790,6 +842,10 @@ static int sof_ipc4_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd,
if (ret)
return ret;

ret = sof_ipc4_pcm_dai_link_fixup_channels(sdev, params, ipc4_copier);
if (ret)
return ret;

if (single_bitdepth) {
snd_mask_none(fmt);
valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(ipc4_fmt->fmt_cfg);
Expand Down
Loading