ASoC: SOF: sof-audio: Fix broken early bclk feature for SSP

With the removal of widget setup during BE hw_params, the DAI config IPC
is never sent with the SOF_DAI_CONFIG_FLAGS_HW_PARAMS. This means that
the early bit clock feature required for certain codecs will be broken.

Fix this by saving the config flags sent during BE DAI hw_params and
reusing it when the DAI_CONFIG IPC is sent after the DAI widget is set
up. Also, free the DAI config before the widget is freed.

The DAI_CONFIG IPC sent during the sof_widget_free() does not have the
DAI index information. So, save the dai_index in the config during
hw_params and reuse it during hw_free.

For IPC4, do not clear the node ID during hw_free. It will be needed for
freeing the group_ida during unprepare.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Link: https://lore.kernel.org/r/20230307114639.4553-1-peter.ujfalusi@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Ranjani Sridharan
2023-03-07 13:46:39 +02:00
committed by Mark Brown
parent ca09e2a351
commit b66bfc3a98
3 changed files with 68 additions and 7 deletions
+25 -3
View File
@@ -50,9 +50,27 @@ static int sof_widget_free_unlocked(struct snd_sof_dev *sdev,
/* reset route setup status for all routes that contain this widget */
sof_reset_route_setup_status(sdev, swidget);
/* free DAI config and continue to free widget even if it fails */
if (WIDGET_IS_DAI(swidget->id)) {
struct snd_sof_dai_config_data data;
unsigned int flags = SOF_DAI_CONFIG_FLAGS_HW_FREE;
data.dai_data = DMA_CHAN_INVALID;
if (tplg_ops && tplg_ops->dai_config) {
err = tplg_ops->dai_config(sdev, swidget, flags, &data);
if (err < 0)
dev_err(sdev->dev, "failed to free config for widget %s\n",
swidget->widget->name);
}
}
/* continue to disable core even if IPC fails */
if (tplg_ops && tplg_ops->widget_free)
err = tplg_ops->widget_free(sdev, swidget);
if (tplg_ops && tplg_ops->widget_free) {
ret = tplg_ops->widget_free(sdev, swidget);
if (ret < 0 && !err)
err = ret;
}
/*
* disable widget core. continue to route setup status and complete flag
@@ -151,8 +169,12 @@ static int sof_widget_setup_unlocked(struct snd_sof_dev *sdev,
/* send config for DAI components */
if (WIDGET_IS_DAI(swidget->id)) {
unsigned int flags = SOF_DAI_CONFIG_FLAGS_NONE;
unsigned int flags = SOF_DAI_CONFIG_FLAGS_HW_PARAMS;
/*
* The config flags saved during BE DAI hw_params will be used for IPC3. IPC4 does
* not use the flags argument.
*/
if (tplg_ops && tplg_ops->dai_config) {
ret = tplg_ops->dai_config(sdev, swidget, flags, NULL);
if (ret < 0)