OSDN Git Service

ASoC: SOF: Add a new dai_get_clk topology IPC op
authorRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Thu, 17 Mar 2022 17:50:44 +0000 (10:50 -0700)
committerMark Brown <broonie@kernel.org>
Fri, 18 Mar 2022 16:04:53 +0000 (16:04 +0000)
This will help make the code for getting the mclk and bclk IPC specific.
Add the implementation for IPC3 as well.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Link: https://lore.kernel.org/r/20220317175044.1752400-20-ranjani.sridharan@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/sof/ipc3-topology.c
sound/soc/sof/sof-audio.c
sound/soc/sof/sof-audio.h

index 3ac65da..2f8450a 100644 (file)
@@ -2252,6 +2252,34 @@ static int sof_ipc3_tear_down_all_pipelines(struct snd_sof_dev *sdev, bool verif
        return 0;
 }
 
+static int sof_ipc3_dai_get_clk(struct snd_sof_dev *sdev, struct snd_sof_dai *dai, int clk_type)
+{
+       struct sof_dai_private_data *private = dai->private;
+
+       if (!private || !private->dai_config)
+               return 0;
+
+       switch (private->dai_config->type) {
+       case SOF_DAI_INTEL_SSP:
+               switch (clk_type) {
+               case SOF_DAI_CLK_INTEL_SSP_MCLK:
+                       return private->dai_config->ssp.mclk_rate;
+               case SOF_DAI_CLK_INTEL_SSP_BCLK:
+                       return private->dai_config->ssp.bclk_rate;
+               default:
+                       break;
+               }
+               dev_err(sdev->dev, "fail to get SSP clk %d rate\n", clk_type);
+               break;
+       default:
+               /* not yet implemented for platforms other than the above */
+               dev_err(sdev->dev, "DAI type %d not supported yet!\n", private->dai_config->type);
+               break;
+       }
+
+       return -EINVAL;
+}
+
 /* token list for each topology object */
 static enum sof_tokens host_token_list[] = {
        SOF_CORE_TOKENS,
@@ -2359,6 +2387,7 @@ const struct sof_ipc_tplg_ops ipc3_tplg_ops = {
        .widget_free = sof_ipc3_widget_free,
        .widget_setup = sof_ipc3_widget_setup,
        .dai_config = sof_ipc3_dai_config,
+       .dai_get_clk = sof_ipc3_dai_get_clk,
        .set_up_all_pipelines = sof_ipc3_set_up_all_pipelines,
        .tear_down_all_pipelines = sof_ipc3_tear_down_all_pipelines,
 };
index b4ee65c..b2f009a 100644 (file)
@@ -628,40 +628,23 @@ struct snd_sof_dai *snd_sof_find_dai(struct snd_soc_component *scomp,
        return NULL;
 }
 
-#define SOF_DAI_CLK_INTEL_SSP_MCLK     0
-#define SOF_DAI_CLK_INTEL_SSP_BCLK     1
-
 static int sof_dai_get_clk(struct snd_soc_pcm_runtime *rtd, int clk_type)
 {
        struct snd_soc_component *component =
                snd_soc_rtdcom_lookup(rtd, SOF_AUDIO_PCM_DRV_NAME);
        struct snd_sof_dai *dai =
                snd_sof_find_dai(component, (char *)rtd->dai_link->name);
-       struct sof_dai_private_data *private = dai->private;
+       struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
+       const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg;
 
        /* use the tplg configured mclk if existed */
-       if (!dai || !private || !private->dai_config)
+       if (!dai)
                return 0;
 
-       switch (private->dai_config->type) {
-       case SOF_DAI_INTEL_SSP:
-               switch (clk_type) {
-               case SOF_DAI_CLK_INTEL_SSP_MCLK:
-                       return private->dai_config->ssp.mclk_rate;
-               case SOF_DAI_CLK_INTEL_SSP_BCLK:
-                       return private->dai_config->ssp.bclk_rate;
-               default:
-                       dev_err(rtd->dev, "fail to get SSP clk %d rate\n",
-                               clk_type);
-                       return -EINVAL;
-               }
-               break;
-       default:
-               /* not yet implemented for platforms other than the above */
-               dev_err(rtd->dev, "DAI type %d not supported yet!\n",
-                       private->dai_config->type);
-               return -EINVAL;
-       }
+       if (tplg_ops->dai_get_clk)
+               return tplg_ops->dai_get_clk(sdev, dai, clk_type);
+
+       return 0;
 }
 
 /*
index b9a9956..7f15b3b 100644 (file)
@@ -30,6 +30,9 @@
 
 #define WIDGET_IS_DAI(id) ((id) == snd_soc_dapm_dai_in || (id) == snd_soc_dapm_dai_out)
 
+#define SOF_DAI_CLK_INTEL_SSP_MCLK     0
+#define SOF_DAI_CLK_INTEL_SSP_BCLK     1
+
 /*
  * Volume fractional word length define to 16 sets
  * the volume linear gain value to use Qx.16 format
@@ -39,6 +42,7 @@
 struct snd_sof_widget;
 struct snd_sof_route;
 struct snd_sof_control;
+struct snd_sof_dai;
 
 struct snd_sof_dai_config_data {
        int dai_index;
@@ -117,6 +121,7 @@ struct sof_ipc_tplg_widget_ops {
  * @widget_setup: Function pointer for setting up setup in the DSP
  * @widget_free: Function pointer for freeing widget in the DSP
  * @dai_config: Function pointer for sending DAI config IPC to the DSP
+ * @dai_get_clk: Function pointer for getting the DAI clock setting
  * @set_up_all_pipelines: Function pointer for setting up all topology pipelines
  * @tear_down_all_pipelines: Function pointer for tearing down all topology pipelines
  */
@@ -132,6 +137,7 @@ struct sof_ipc_tplg_ops {
        int (*widget_free)(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget);
        int (*dai_config)(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget,
                          unsigned int flags, struct snd_sof_dai_config_data *data);
+       int (*dai_get_clk)(struct snd_sof_dev *sdev, struct snd_sof_dai *dai, int clk_type);
        int (*set_up_all_pipelines)(struct snd_sof_dev *sdev, bool verify);
        int (*tear_down_all_pipelines)(struct snd_sof_dev *sdev, bool verify);
 };