Commit cd6afb06 authored by Peter Ujfalusi's avatar Peter Ujfalusi Committed by Mark Brown

ASoC: SOF: sof-audio: Extend the optionality of IPC ops to IPC as well

The IPC ops are optional, but they require that the ops struct is to be
allocated with all callbacks set to NULL.

Update the code to extend the optionality to:
sdev->ipc == NULL
sdev->ipc->ops == NULL
sdev->ipc->ops->[ops_group] == NULL
sdev->ipc->ops->[pcmops_group]->ops == NULL (treated optional currently)
Signed-off-by: default avatarPeter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: default avatarRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: default avatarBard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: default avatarRander Wang <rander.wang@intel.com>
Link: https://lore.kernel.org/r/20221221102328.9635-7-peter.ujfalusi@linux.intel.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent cfa12c36
...@@ -16,12 +16,12 @@ ...@@ -16,12 +16,12 @@
static void sof_reset_route_setup_status(struct snd_sof_dev *sdev, struct snd_sof_widget *widget) static void sof_reset_route_setup_status(struct snd_sof_dev *sdev, struct snd_sof_widget *widget)
{ {
const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg; const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
struct snd_sof_route *sroute; struct snd_sof_route *sroute;
list_for_each_entry(sroute, &sdev->route_list, list) list_for_each_entry(sroute, &sdev->route_list, list)
if (sroute->src_widget == widget || sroute->sink_widget == widget) { if (sroute->src_widget == widget || sroute->sink_widget == widget) {
if (sroute->setup && tplg_ops->route_free) if (sroute->setup && tplg_ops && tplg_ops->route_free)
tplg_ops->route_free(sdev, sroute); tplg_ops->route_free(sdev, sroute);
sroute->setup = false; sroute->setup = false;
...@@ -30,7 +30,7 @@ static void sof_reset_route_setup_status(struct snd_sof_dev *sdev, struct snd_so ...@@ -30,7 +30,7 @@ static void sof_reset_route_setup_status(struct snd_sof_dev *sdev, struct snd_so
int sof_widget_free(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) int sof_widget_free(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget)
{ {
const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg; const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
int err = 0; int err = 0;
int ret; int ret;
...@@ -47,7 +47,7 @@ int sof_widget_free(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) ...@@ -47,7 +47,7 @@ int sof_widget_free(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget)
sof_reset_route_setup_status(sdev, swidget); sof_reset_route_setup_status(sdev, swidget);
/* continue to disable core even if IPC fails */ /* continue to disable core even if IPC fails */
if (tplg_ops->widget_free) if (tplg_ops && tplg_ops->widget_free)
err = tplg_ops->widget_free(sdev, swidget); err = tplg_ops->widget_free(sdev, swidget);
/* /*
...@@ -82,7 +82,7 @@ EXPORT_SYMBOL(sof_widget_free); ...@@ -82,7 +82,7 @@ EXPORT_SYMBOL(sof_widget_free);
int sof_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) int sof_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget)
{ {
const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg; const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
int ret; int ret;
/* skip if there is no private data */ /* skip if there is no private data */
...@@ -124,7 +124,7 @@ int sof_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) ...@@ -124,7 +124,7 @@ int sof_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget)
} }
/* setup widget in the DSP */ /* setup widget in the DSP */
if (tplg_ops->widget_setup) { if (tplg_ops && tplg_ops->widget_setup) {
ret = tplg_ops->widget_setup(sdev, swidget); ret = tplg_ops->widget_setup(sdev, swidget);
if (ret < 0) if (ret < 0)
goto core_put; goto core_put;
...@@ -134,7 +134,7 @@ int sof_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) ...@@ -134,7 +134,7 @@ int sof_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget)
if (WIDGET_IS_DAI(swidget->id)) { if (WIDGET_IS_DAI(swidget->id)) {
unsigned int flags = SOF_DAI_CONFIG_FLAGS_NONE; unsigned int flags = SOF_DAI_CONFIG_FLAGS_NONE;
if (tplg_ops->dai_config) { if (tplg_ops && tplg_ops->dai_config) {
ret = tplg_ops->dai_config(sdev, swidget, flags, NULL); ret = tplg_ops->dai_config(sdev, swidget, flags, NULL);
if (ret < 0) if (ret < 0)
goto widget_free; goto widget_free;
...@@ -142,7 +142,7 @@ int sof_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) ...@@ -142,7 +142,7 @@ int sof_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget)
} }
/* restore kcontrols for widget */ /* restore kcontrols for widget */
if (tplg_ops->control->widget_kcontrol_setup) { if (tplg_ops && tplg_ops->control && tplg_ops->control->widget_kcontrol_setup) {
ret = tplg_ops->control->widget_kcontrol_setup(sdev, swidget); ret = tplg_ops->control->widget_kcontrol_setup(sdev, swidget);
if (ret < 0) if (ret < 0)
goto widget_free; goto widget_free;
...@@ -169,7 +169,7 @@ EXPORT_SYMBOL(sof_widget_setup); ...@@ -169,7 +169,7 @@ EXPORT_SYMBOL(sof_widget_setup);
int sof_route_setup(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget *wsource, int sof_route_setup(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget *wsource,
struct snd_soc_dapm_widget *wsink) struct snd_soc_dapm_widget *wsink)
{ {
const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg; const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
struct snd_sof_widget *src_widget = wsource->dobj.private; struct snd_sof_widget *src_widget = wsource->dobj.private;
struct snd_sof_widget *sink_widget = wsink->dobj.private; struct snd_sof_widget *sink_widget = wsink->dobj.private;
struct snd_sof_route *sroute; struct snd_sof_route *sroute;
...@@ -211,8 +211,8 @@ int sof_route_setup(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget *wsourc ...@@ -211,8 +211,8 @@ int sof_route_setup(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget *wsourc
if (sroute->setup) if (sroute->setup)
return 0; return 0;
if (ipc_tplg_ops->route_setup) { if (tplg_ops && tplg_ops->route_setup) {
int ret = ipc_tplg_ops->route_setup(sdev, sroute); int ret = tplg_ops->route_setup(sdev, sroute);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -268,16 +268,17 @@ static int sof_setup_pipeline_connections(struct snd_sof_dev *sdev, ...@@ -268,16 +268,17 @@ static int sof_setup_pipeline_connections(struct snd_sof_dev *sdev,
static void static void
sof_unprepare_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget *widget) sof_unprepare_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget *widget)
{ {
const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg; const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
const struct sof_ipc_tplg_widget_ops *widget_ops = ipc_tplg_ops->widget;
struct snd_sof_widget *swidget = widget->dobj.private; struct snd_sof_widget *swidget = widget->dobj.private;
const struct sof_ipc_tplg_widget_ops *widget_ops;
struct snd_soc_dapm_path *p; struct snd_soc_dapm_path *p;
/* return if the widget is in use or if it is already unprepared */ /* return if the widget is in use or if it is already unprepared */
if (!swidget->prepared || swidget->use_count > 1) if (!swidget->prepared || swidget->use_count > 1)
return; return;
if (widget_ops[widget->id].ipc_unprepare) widget_ops = tplg_ops ? tplg_ops->widget : NULL;
if (widget_ops && widget_ops[widget->id].ipc_unprepare)
/* unprepare the source widget */ /* unprepare the source widget */
widget_ops[widget->id].ipc_unprepare(swidget); widget_ops[widget->id].ipc_unprepare(swidget);
...@@ -299,12 +300,16 @@ sof_prepare_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget ...@@ -299,12 +300,16 @@ sof_prepare_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget
struct snd_sof_platform_stream_params *platform_params, struct snd_sof_platform_stream_params *platform_params,
struct snd_pcm_hw_params *pipeline_params, int dir) struct snd_pcm_hw_params *pipeline_params, int dir)
{ {
const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg; const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
const struct sof_ipc_tplg_widget_ops *widget_ops = ipc_tplg_ops->widget;
struct snd_sof_widget *swidget = widget->dobj.private; struct snd_sof_widget *swidget = widget->dobj.private;
const struct sof_ipc_tplg_widget_ops *widget_ops;
struct snd_soc_dapm_path *p; struct snd_soc_dapm_path *p;
int ret; int ret;
widget_ops = tplg_ops ? tplg_ops->widget : NULL;
if (!widget_ops)
return 0;
if (!widget_ops[widget->id].ipc_prepare || swidget->prepared) if (!widget_ops[widget->id].ipc_prepare || swidget->prepared)
goto sink_prepare; goto sink_prepare;
...@@ -485,7 +490,7 @@ int sof_widget_list_setup(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm, ...@@ -485,7 +490,7 @@ int sof_widget_list_setup(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm,
struct snd_sof_platform_stream_params *platform_params, struct snd_sof_platform_stream_params *platform_params,
int dir) int dir)
{ {
const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg; const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
struct snd_soc_dapm_widget_list *list = spcm->stream[dir].list; struct snd_soc_dapm_widget_list *list = spcm->stream[dir].list;
struct snd_soc_dapm_widget *widget; struct snd_soc_dapm_widget *widget;
int i, ret; int i, ret;
...@@ -539,8 +544,8 @@ int sof_widget_list_setup(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm, ...@@ -539,8 +544,8 @@ int sof_widget_list_setup(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm,
if (pipe_widget->complete) if (pipe_widget->complete)
continue; continue;
if (ipc_tplg_ops->pipeline_complete) { if (tplg_ops && tplg_ops->pipeline_complete) {
pipe_widget->complete = ipc_tplg_ops->pipeline_complete(sdev, pipe_widget); pipe_widget->complete = tplg_ops->pipeline_complete(sdev, pipe_widget);
if (pipe_widget->complete < 0) { if (pipe_widget->complete < 0) {
ret = pipe_widget->complete; ret = pipe_widget->complete;
goto widget_free; goto widget_free;
...@@ -628,11 +633,11 @@ bool snd_sof_stream_suspend_ignored(struct snd_sof_dev *sdev) ...@@ -628,11 +633,11 @@ bool snd_sof_stream_suspend_ignored(struct snd_sof_dev *sdev)
int sof_pcm_stream_free(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream, int sof_pcm_stream_free(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream,
struct snd_sof_pcm *spcm, int dir, bool free_widget_list) struct snd_sof_pcm *spcm, int dir, bool free_widget_list)
{ {
const struct sof_ipc_pcm_ops *pcm_ops = sdev->ipc->ops->pcm; const struct sof_ipc_pcm_ops *pcm_ops = sof_ipc_get_ops(sdev, pcm);
int ret; int ret;
/* Send PCM_FREE IPC to reset pipeline */ /* Send PCM_FREE IPC to reset pipeline */
if (pcm_ops->hw_free && spcm->prepared[substream->stream]) { if (pcm_ops && pcm_ops->hw_free && spcm->prepared[substream->stream]) {
ret = pcm_ops->hw_free(sdev->component, substream); ret = pcm_ops->hw_free(sdev->component, substream);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -762,13 +767,13 @@ static int sof_dai_get_clk(struct snd_soc_pcm_runtime *rtd, int clk_type) ...@@ -762,13 +767,13 @@ static int sof_dai_get_clk(struct snd_soc_pcm_runtime *rtd, int clk_type)
struct snd_sof_dai *dai = struct snd_sof_dai *dai =
snd_sof_find_dai(component, (char *)rtd->dai_link->name); snd_sof_find_dai(component, (char *)rtd->dai_link->name);
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component); struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg; const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
/* use the tplg configured mclk if existed */ /* use the tplg configured mclk if existed */
if (!dai) if (!dai)
return 0; return 0;
if (tplg_ops->dai_get_clk) if (tplg_ops && tplg_ops->dai_get_clk)
return tplg_ops->dai_get_clk(sdev, dai, clk_type); return tplg_ops->dai_get_clk(sdev, dai, clk_type);
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment