Skip to content

Commit 4e89c0d

Browse files
committed
ASoC: SOF: ipc4-topology: Improve playback dai copier in/out format selection
The dai copier configuration for playback and capture needs to be separated because it is not correct to configure the dai copier as part of the input format selection for both direction. The input format is the dai format for capture, but it is not for playback, for playback the dai format is on the output side. Currently we configure and adjust the params based on the DAI supported formats when configuring the input side of the copier but right after the format has been adjusted we reset it for playback and loose this information. When using a nocodec passthrough topology (which is a bug) we have SSP blobs supporting 32bit only, copier supporting 16/24/32 bit then on playback the dai and copier will be incorrectly configured: host.copier.in: S16_LE host.copier.out: S16_LE dai.copier.in: S16_LE SSP.blob: S32_LE (we only have S32_LE blobs) dai.copier.out: S16_LE (the dai constraint is ignored) To handle such case the handling of capture and playback streams must be changed: The input format (no changes to previous implementation): for playback it is the pipeline_params for capture it is the adjusted fe_params The output format (no change for capture direction): for playback it is the adjusted fe_params for capture it is the fe_params with this change path format configuration will be correct: host.copier.in: S16_LE host.copier.out: S16_LE dai.copier.in: S16_LE SSP.blob: S32_LE (we only have S32_LE blobs) dai.copier.out: S32_LE Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
1 parent fbab5b3 commit 4e89c0d

File tree

1 file changed

+47
-25
lines changed

1 file changed

+47
-25
lines changed

sound/soc/sof/ipc4-topology.c

Lines changed: 47 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2142,28 +2142,32 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
21422142
copier_data = &ipc4_copier->data;
21432143
available_fmt = &ipc4_copier->available_fmt;
21442144

2145-
/*
2146-
* Use the fe_params as a base for the copier configuration.
2147-
* The ref_params might get updated to reflect what format is
2148-
* supported by the copier on the DAI side.
2149-
*
2150-
* In case of capture the ref_params returned will be used to
2151-
* find the input configuration of the copier.
2152-
*/
2153-
ref_params = kmemdup(fe_params, sizeof(*ref_params), GFP_KERNEL);
2154-
if (!ref_params)
2155-
return -ENOMEM;
2156-
2157-
ret = sof_ipc4_prepare_dai_copier(sdev, dai, ref_params, dir);
2158-
if (ret < 0)
2159-
return ret;
2145+
if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
2146+
/*
2147+
* For playback the pipeline_params needs to be used to
2148+
* find the input configuration of the copier.
2149+
*/
2150+
ref_params = kmemdup(pipeline_params, sizeof(*ref_params),
2151+
GFP_KERNEL);
2152+
if (!ref_params)
2153+
return -ENOMEM;
2154+
} else {
2155+
/*
2156+
* For capture the adjusted fe_params needs to be used
2157+
* to find the input configuration of the copier.
2158+
*
2159+
* The params might be updated in
2160+
* sof_ipc4_prepare_dai_copier() to reflect the supported
2161+
* input formats by the copier/dai.
2162+
*/
2163+
ref_params = kmemdup(fe_params, sizeof(*ref_params), GFP_KERNEL);
2164+
if (!ref_params)
2165+
return -ENOMEM;
21602166

2161-
/*
2162-
* For playback the pipeline_params needs to be used to find the
2163-
* input configuration of the copier.
2164-
*/
2165-
if (dir == SNDRV_PCM_STREAM_PLAYBACK)
2166-
memcpy(ref_params, pipeline_params, sizeof(*ref_params));
2167+
ret = sof_ipc4_prepare_dai_copier(sdev, dai, ref_params, dir);
2168+
if (ret < 0)
2169+
return ret;
2170+
}
21672171

21682172
break;
21692173
}
@@ -2218,15 +2222,33 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
22182222
}
22192223
case snd_soc_dapm_aif_out:
22202224
case snd_soc_dapm_dai_in:
2221-
out_ref_rate = params_rate(fe_params);
2222-
out_ref_channels = params_channels(fe_params);
2223-
ret = sof_ipc4_get_sample_type(sdev, fe_params);
2225+
/*
2226+
* For capture the fe_params needs to be used to find the output
2227+
* configuration of the copier.
2228+
*
2229+
* For playback the adjusted fe_params needs to be used
2230+
* to find the output configuration of the copier.
2231+
*
2232+
* The params might be updated in
2233+
* sof_ipc4_prepare_dai_copier() to reflect the supported
2234+
* output formats by the copier/dai.
2235+
*/
2236+
memcpy(ref_params, fe_params, sizeof(*ref_params));
2237+
if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
2238+
ret = sof_ipc4_prepare_dai_copier(sdev, dai, ref_params, dir);
2239+
if (ret < 0)
2240+
return ret;
2241+
}
2242+
2243+
out_ref_rate = params_rate(ref_params);
2244+
out_ref_channels = params_channels(ref_params);
2245+
ret = sof_ipc4_get_sample_type(sdev, ref_params);
22242246
if (ret < 0)
22252247
return ret;
22262248
out_ref_type = (u32)ret;
22272249

22282250
if (!single_output_bitdepth) {
2229-
out_ref_valid_bits = sof_ipc4_get_valid_bits(sdev, fe_params);
2251+
out_ref_valid_bits = sof_ipc4_get_valid_bits(sdev, ref_params);
22302252
if (out_ref_valid_bits < 0)
22312253
return out_ref_valid_bits;
22322254
}

0 commit comments

Comments
 (0)