From: Ranjani Sridharan <ranjani.sridharan@xxxxxxxxxxxxxxx> The BE DAI driver ops involve operations that are IPC-specific. For ex: for the HDA DAI, the trigger op involves sending the DAI_CONFIG IPC to the DSP to stop the DMA for the stop/pause commands. This sequence is different for IPC3 and IPC4. So, make the dai driver ops IPC-specific and set the IPC3-specific ops during the ops_init() callback. Reviewed-by: Rander Wang <rander.wang@xxxxxxxxx> Reviewed-by: Bard Liao <yung-chuan.liao@xxxxxxxxxxxxxxx> Reviewed-by: Péter Ujfalusi <peter.ujfalusi@xxxxxxxxxxxxxxx> Signed-off-by: Ranjani Sridharan <ranjani.sridharan@xxxxxxxxxxxxxxx> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@xxxxxxxxxxxxxxx> --- sound/soc/sof/intel/apl.c | 3 ++ sound/soc/sof/intel/cnl.c | 3 ++ sound/soc/sof/intel/hda-dai.c | 53 +++++++++++++++++++++-------------- sound/soc/sof/intel/hda.h | 2 ++ sound/soc/sof/intel/icl.c | 3 ++ sound/soc/sof/intel/tgl.c | 3 ++ 6 files changed, 46 insertions(+), 21 deletions(-) diff --git a/sound/soc/sof/intel/apl.c b/sound/soc/sof/intel/apl.c index cb499f3905cec..b7839fd04dfb7 100644 --- a/sound/soc/sof/intel/apl.c +++ b/sound/soc/sof/intel/apl.c @@ -43,6 +43,9 @@ int sof_apl_ops_init(struct snd_sof_dev *sdev) /* ipc */ sof_apl_ops.send_msg = hda_dsp_ipc_send_msg; + /* set DAI driver ops */ + hda_set_dai_drv_ops(sdev, &sof_apl_ops); + /* debug */ sof_apl_ops.debug_map = apl_dsp_debugfs; sof_apl_ops.debug_map_count = ARRAY_SIZE(apl_dsp_debugfs); diff --git a/sound/soc/sof/intel/cnl.c b/sound/soc/sof/intel/cnl.c index f5bac91c335ba..98c4e4f61e7c4 100644 --- a/sound/soc/sof/intel/cnl.c +++ b/sound/soc/sof/intel/cnl.c @@ -261,6 +261,9 @@ int sof_cnl_ops_init(struct snd_sof_dev *sdev) /* ipc */ sof_cnl_ops.send_msg = cnl_ipc_send_msg; + /* set DAI driver ops */ + hda_set_dai_drv_ops(sdev, &sof_cnl_ops); + /* debug */ sof_cnl_ops.debug_map = cnl_dsp_debugfs; sof_cnl_ops.debug_map_count = ARRAY_SIZE(cnl_dsp_debugfs); diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c index f9cb9f1f0237b..8891077d8d8c3 100644 --- a/sound/soc/sof/intel/hda-dai.c +++ b/sound/soc/sof/intel/hda-dai.c @@ -276,8 +276,8 @@ static int hda_link_dai_config_pause_push_ipc(struct snd_soc_dapm_widget *w) return ret; } -static int hda_link_pcm_trigger(struct snd_pcm_substream *substream, - int cmd, struct snd_soc_dai *dai) +static int ipc3_hda_link_pcm_trigger(struct snd_pcm_substream *substream, + int cmd, struct snd_soc_dai *dai) { struct hdac_ext_stream *hext_stream = snd_soc_dai_get_dma_data(dai, substream); @@ -395,10 +395,10 @@ static int hda_link_hw_free(struct snd_pcm_substream *substream, return 0; } -static const struct snd_soc_dai_ops hda_link_dai_ops = { +static const struct snd_soc_dai_ops ipc3_hda_link_dai_ops = { .hw_params = hda_link_hw_params, .hw_free = hda_link_hw_free, - .trigger = hda_link_pcm_trigger, + .trigger = ipc3_hda_link_pcm_trigger, .prepare = hda_link_pcm_prepare, }; @@ -478,8 +478,8 @@ static int ssp_dai_prepare(struct snd_pcm_substream *substream, return ssp_dai_setup(substream, dai, true); } -static int ssp_dai_trigger(struct snd_pcm_substream *substream, - int cmd, struct snd_soc_dai *dai) +static int ipc3_ssp_dai_trigger(struct snd_pcm_substream *substream, + int cmd, struct snd_soc_dai *dai) { if (cmd != SNDRV_PCM_TRIGGER_SUSPEND) return 0; @@ -507,15 +507,39 @@ static void ssp_dai_shutdown(struct snd_pcm_substream *substream, kfree(dma_data); } -static const struct snd_soc_dai_ops ssp_dai_ops = { +static const struct snd_soc_dai_ops ipc3_ssp_dai_ops = { .startup = ssp_dai_startup, .hw_params = ssp_dai_hw_params, .prepare = ssp_dai_prepare, - .trigger = ssp_dai_trigger, + .trigger = ipc3_ssp_dai_trigger, .hw_free = ssp_dai_hw_free, .shutdown = ssp_dai_shutdown, }; +void hda_set_dai_drv_ops(struct snd_sof_dev *sdev, struct snd_sof_dsp_ops *ops) +{ + int i; + + switch (sdev->pdata->ipc_type) { + case SOF_IPC: + for (i = 0; i < ops->num_drv; i++) { + if (strstr(ops->drv[i].name, "SSP")) { + ops->drv[i].ops = &ipc3_ssp_dai_ops; + continue; + } +#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) + if (strstr(ops->drv[i].name, "iDisp") || + strstr(ops->drv[i].name, "Analog") || + strstr(ops->drv[i].name, "Digital")) + ops->drv[i].ops = &ipc3_hda_link_dai_ops; +#endif + } + break; + default: + break; + } +} + /* * common dai driver for skl+ platforms. * some products who use this DAI array only physically have a subset of @@ -524,7 +548,6 @@ static const struct snd_soc_dai_ops ssp_dai_ops = { struct snd_soc_dai_driver skl_dai[] = { { .name = "SSP0 Pin", - .ops = &ssp_dai_ops, .playback = { .channels_min = 1, .channels_max = 8, @@ -536,7 +559,6 @@ struct snd_soc_dai_driver skl_dai[] = { }, { .name = "SSP1 Pin", - .ops = &ssp_dai_ops, .playback = { .channels_min = 1, .channels_max = 8, @@ -548,7 +570,6 @@ struct snd_soc_dai_driver skl_dai[] = { }, { .name = "SSP2 Pin", - .ops = &ssp_dai_ops, .playback = { .channels_min = 1, .channels_max = 8, @@ -560,7 +581,6 @@ struct snd_soc_dai_driver skl_dai[] = { }, { .name = "SSP3 Pin", - .ops = &ssp_dai_ops, .playback = { .channels_min = 1, .channels_max = 8, @@ -572,7 +592,6 @@ struct snd_soc_dai_driver skl_dai[] = { }, { .name = "SSP4 Pin", - .ops = &ssp_dai_ops, .playback = { .channels_min = 1, .channels_max = 8, @@ -584,7 +603,6 @@ struct snd_soc_dai_driver skl_dai[] = { }, { .name = "SSP5 Pin", - .ops = &ssp_dai_ops, .playback = { .channels_min = 1, .channels_max = 8, @@ -611,7 +629,6 @@ struct snd_soc_dai_driver skl_dai[] = { #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) { .name = "iDisp1 Pin", - .ops = &hda_link_dai_ops, .playback = { .channels_min = 1, .channels_max = 8, @@ -619,7 +636,6 @@ struct snd_soc_dai_driver skl_dai[] = { }, { .name = "iDisp2 Pin", - .ops = &hda_link_dai_ops, .playback = { .channels_min = 1, .channels_max = 8, @@ -627,7 +643,6 @@ struct snd_soc_dai_driver skl_dai[] = { }, { .name = "iDisp3 Pin", - .ops = &hda_link_dai_ops, .playback = { .channels_min = 1, .channels_max = 8, @@ -635,7 +650,6 @@ struct snd_soc_dai_driver skl_dai[] = { }, { .name = "iDisp4 Pin", - .ops = &hda_link_dai_ops, .playback = { .channels_min = 1, .channels_max = 8, @@ -643,7 +657,6 @@ struct snd_soc_dai_driver skl_dai[] = { }, { .name = "Analog CPU DAI", - .ops = &hda_link_dai_ops, .playback = { .channels_min = 1, .channels_max = 16, @@ -655,7 +668,6 @@ struct snd_soc_dai_driver skl_dai[] = { }, { .name = "Digital CPU DAI", - .ops = &hda_link_dai_ops, .playback = { .channels_min = 1, .channels_max = 16, @@ -667,7 +679,6 @@ struct snd_soc_dai_driver skl_dai[] = { }, { .name = "Alt Analog CPU DAI", - .ops = &hda_link_dai_ops, .playback = { .channels_min = 1, .channels_max = 16, diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index 6e05c77594809..f520d1cf70c90 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -761,4 +761,6 @@ int hda_ctrl_dai_widget_free(struct snd_soc_dapm_widget *w, unsigned int quirk_f extern int sof_hda_position_quirk; +void hda_set_dai_drv_ops(struct snd_sof_dev *sdev, struct snd_sof_dsp_ops *ops); + #endif diff --git a/sound/soc/sof/intel/icl.c b/sound/soc/sof/intel/icl.c index f845064c3589a..f19517dffd624 100644 --- a/sound/soc/sof/intel/icl.c +++ b/sound/soc/sof/intel/icl.c @@ -127,6 +127,9 @@ int sof_icl_ops_init(struct snd_sof_dev *sdev) /* dsp core get/put */ sof_icl_ops.core_get = hda_dsp_core_get; + /* set DAI driver ops */ + hda_set_dai_drv_ops(sdev, &sof_icl_ops); + return 0; }; EXPORT_SYMBOL_NS(sof_icl_ops_init, SND_SOC_SOF_INTEL_HDA_COMMON); diff --git a/sound/soc/sof/intel/tgl.c b/sound/soc/sof/intel/tgl.c index 816571305f247..ed76f736afb46 100644 --- a/sound/soc/sof/intel/tgl.c +++ b/sound/soc/sof/intel/tgl.c @@ -76,6 +76,9 @@ int sof_tgl_ops_init(struct snd_sof_dev *sdev) /* ipc */ sof_tgl_ops.send_msg = cnl_ipc_send_msg; + /* set DAI driver ops */ + hda_set_dai_drv_ops(sdev, &sof_tgl_ops); + /* debug */ sof_tgl_ops.debug_map = tgl_dsp_debugfs; sof_tgl_ops.debug_map_count = ARRAY_SIZE(tgl_dsp_debugfs); -- 2.30.2