Skip to content

Commit b65456b

Browse files
ujfalusibroonie
authored andcommitted
ASoC: SOF: ipc4-topology: Adjust the params based on DAI formats
Currently we only check the bit depth value among to DAI formats, but other parameters might be constant, like number of channels and/or rate. In capture we use the fe params as a reference to find the format and blob which should be used, but in the path we can have components which can handle expanding/narrowing number of channels or do a resample. In these cases the topology is expected to have 'fixed' parameter for channels/rates/bit depth and the conversion to the fe format is going to be done within the path. In practice this patch fixes issues like: All DMIC formats are fixed four channels We have a component which converts the four channel to stereo FE is opened with 2 channel Even if we have the correct bit depth format and blob (for four channel) we will still be looking for stereo configurations, which will fail. Note: the adjustment of params have switched order with the checking of single bit depth (needed for the NHLT blob fallback support). This change is non function, just that if the sof_ipc4_narrow_params_to_format() would fail, there is no point of checking the single bit depth. Signed-off-by: Peter Ujfalusi <[email protected]> Reviewed-by: Pierre-Louis Bossart <[email protected]> Reviewed-by: Bard Liao <[email protected]> Reviewed-by: Seppo Ingalsuo <[email protected]> Reviewed-by: Ranjani Sridharan <[email protected]> Link: https://msgid.link/r/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent 2fcad03 commit b65456b

File tree

1 file changed

+57
-14
lines changed

1 file changed

+57
-14
lines changed

sound/soc/sof/ipc4-topology.c

Lines changed: 57 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1583,6 +1583,55 @@ bool sof_ipc4_copier_is_single_bitdepth(struct snd_sof_dev *sdev,
15831583
return true;
15841584
}
15851585

1586+
static int
1587+
sof_ipc4_adjust_params_to_dai_format(struct snd_sof_dev *sdev,
1588+
struct snd_pcm_hw_params *params,
1589+
struct sof_ipc4_pin_format *pin_fmts,
1590+
u32 pin_fmts_size)
1591+
{
1592+
u32 params_mask = BIT(SNDRV_PCM_HW_PARAM_RATE) |
1593+
BIT(SNDRV_PCM_HW_PARAM_CHANNELS) |
1594+
BIT(SNDRV_PCM_HW_PARAM_FORMAT);
1595+
struct sof_ipc4_audio_format *fmt;
1596+
u32 rate, channels, valid_bits;
1597+
int i;
1598+
1599+
fmt = &pin_fmts[0].audio_fmt;
1600+
rate = fmt->sampling_frequency;
1601+
channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg);
1602+
valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg);
1603+
1604+
/* check if parameters in topology defined formats are the same */
1605+
for (i = 1; i < pin_fmts_size; i++) {
1606+
u32 val;
1607+
1608+
fmt = &pin_fmts[i].audio_fmt;
1609+
1610+
if (params_mask & BIT(SNDRV_PCM_HW_PARAM_RATE)) {
1611+
val = fmt->sampling_frequency;
1612+
if (val != rate)
1613+
params_mask &= ~BIT(SNDRV_PCM_HW_PARAM_RATE);
1614+
}
1615+
if (params_mask & BIT(SNDRV_PCM_HW_PARAM_CHANNELS)) {
1616+
val = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg);
1617+
if (val != channels)
1618+
params_mask &= ~BIT(SNDRV_PCM_HW_PARAM_CHANNELS);
1619+
}
1620+
if (params_mask & BIT(SNDRV_PCM_HW_PARAM_FORMAT)) {
1621+
val = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg);
1622+
if (val != valid_bits)
1623+
params_mask &= ~BIT(SNDRV_PCM_HW_PARAM_FORMAT);
1624+
}
1625+
}
1626+
1627+
if (params_mask)
1628+
return sof_ipc4_update_hw_params(sdev, params,
1629+
&pin_fmts[0].audio_fmt,
1630+
params_mask);
1631+
1632+
return 0;
1633+
}
1634+
15861635
static int
15871636
sof_ipc4_prepare_dai_copier(struct snd_sof_dev *sdev, struct snd_sof_dai *dai,
15881637
struct snd_pcm_hw_params *params, int dir)
@@ -1601,10 +1650,9 @@ sof_ipc4_prepare_dai_copier(struct snd_sof_dev *sdev, struct snd_sof_dai *dai,
16011650
available_fmt = &ipc4_copier->available_fmt;
16021651

16031652
/*
1604-
* If the copier on the DAI side supports only single bit depth then
1605-
* this depth (format) should be used to look for the NHLT blob (if
1606-
* needed) and in case of capture this should be used for the input
1607-
* format lookup
1653+
* Fixup the params based on the format parameters of the DAI. If any
1654+
* of the RATE, CHANNELS, bit depth is static among the formats then
1655+
* narrow the params to only allow that specific parameter value.
16081656
*/
16091657
if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
16101658
pin_fmts = available_fmt->output_pin_fmts;
@@ -1614,18 +1662,13 @@ sof_ipc4_prepare_dai_copier(struct snd_sof_dev *sdev, struct snd_sof_dai *dai,
16141662
num_pin_fmts = available_fmt->num_input_formats;
16151663
}
16161664

1665+
ret = sof_ipc4_adjust_params_to_dai_format(sdev, &dai_params, pin_fmts,
1666+
num_pin_fmts);
1667+
if (ret)
1668+
return ret;
1669+
16171670
single_bitdepth = sof_ipc4_copier_is_single_bitdepth(sdev, pin_fmts,
16181671
num_pin_fmts);
1619-
1620-
/* Update the dai_params with the only supported format */
1621-
if (single_bitdepth) {
1622-
ret = sof_ipc4_update_hw_params(sdev, &dai_params,
1623-
&pin_fmts[0].audio_fmt,
1624-
BIT(SNDRV_PCM_HW_PARAM_FORMAT));
1625-
if (ret)
1626-
return ret;
1627-
}
1628-
16291672
ret = snd_sof_get_nhlt_endpoint_data(sdev, dai, single_bitdepth,
16301673
&dai_params,
16311674
ipc4_copier->dai_index,

0 commit comments

Comments
 (0)