ASoC: SOF: topology: Extend the optionality of IPC ops to IPC as well
authorPeter Ujfalusi <peter.ujfalusi@linux.intel.com>
Wed, 21 Dec 2022 10:23:24 +0000 (12:23 +0200)
committerMark Brown <broonie@kernel.org>
Sun, 25 Dec 2022 23:32:35 +0000 (23:32 +0000)
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->[tplg] == NULL
sdev->ipc->ops->[tplg]->ops == NULL (treated optional currently)

At the same time standardize the naming of the ops pointer to tplg_ops

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

index c668bd9..560771b 100644 (file)
@@ -54,11 +54,16 @@ int sof_update_ipc_object(struct snd_soc_component *scomp, void *object, enum so
                          size_t object_size, int token_instance_num)
 {
        struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
-       const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg;
-       const struct sof_token_info *token_list = ipc_tplg_ops->token_list;
+       const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
+       const struct sof_token_info *token_list;
        const struct sof_topology_token *tokens;
        int i, j;
 
+       token_list = tplg_ops ? tplg_ops->token_list : NULL;
+       /* nothing to do if token_list is NULL */
+       if (!token_list)
+               return 0;
+
        if (token_list[token_id].count < 0) {
                dev_err(scomp->dev, "Invalid token count for token ID: %d\n", token_id);
                return -EINVAL;
@@ -263,9 +268,9 @@ static int set_up_volume_table(struct snd_sof_control *scontrol,
 {
        struct snd_soc_component *scomp = scontrol->scomp;
        struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
-       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);
 
-       if (tplg_ops->control->set_up_volume_table)
+       if (tplg_ops && tplg_ops->control && tplg_ops->control->set_up_volume_table)
                return tplg_ops->control->set_up_volume_table(scontrol, tlv, size);
 
        dev_err(scomp->dev, "Mandatory op %s not set\n", __func__);
@@ -490,13 +495,14 @@ static int sof_copy_tuples(struct snd_sof_dev *sdev, struct snd_soc_tplg_vendor_
                           int array_size, u32 token_id, int token_instance_num,
                           struct snd_sof_tuple *tuples, int tuples_size, int *num_copied_tuples)
 {
-       const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg;
-       const struct sof_token_info *token_list = ipc_tplg_ops->token_list;
+       const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
+       const struct sof_token_info *token_list;
        const struct sof_topology_token *tokens;
        int found = 0;
        int num_tokens, asize;
        int i, j;
 
+       token_list = tplg_ops ? tplg_ops->token_list : NULL;
        /* nothing to do if token_list is NULL */
        if (!token_list)
                return 0;
@@ -1015,14 +1021,14 @@ static int sof_control_unload(struct snd_soc_component *scomp,
                              struct snd_soc_dobj *dobj)
 {
        struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
-       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_control *scontrol = dobj->private;
        int ret = 0;
 
        dev_dbg(scomp->dev, "tplg: unload control name : %s\n", scontrol->name);
 
-       if (ipc_tplg_ops->control_free) {
-               ret = ipc_tplg_ops->control_free(sdev, scontrol);
+       if (tplg_ops && tplg_ops->control_free) {
+               ret = tplg_ops->control_free(sdev, scontrol);
                if (ret < 0)
                        dev_err(scomp->dev, "failed to free control: %s\n", scontrol->name);
        }
@@ -1201,12 +1207,17 @@ static int sof_widget_parse_tokens(struct snd_soc_component *scomp, struct snd_s
                                   enum sof_tokens *object_token_list, int count)
 {
        struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
-       const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg;
-       const struct sof_token_info *token_list = ipc_tplg_ops->token_list;
+       const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
        struct snd_soc_tplg_private *private = &tw->priv;
+       const struct sof_token_info *token_list;
        int num_tuples = 0;
        int ret, i;
 
+       token_list = tplg_ops ? tplg_ops->token_list : NULL;
+       /* nothing to do if token_list is NULL */
+       if (!token_list)
+               return 0;
+
        if (count > 0 && !object_token_list) {
                dev_err(scomp->dev, "No token list for widget %s\n", swidget->widget->name);
                return -EINVAL;
@@ -1375,13 +1386,13 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index,
                            struct snd_soc_tplg_dapm_widget *tw)
 {
        struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
-       const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg;
-       const struct sof_ipc_tplg_widget_ops *widget_ops = ipc_tplg_ops->widget;
+       const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
+       const struct sof_ipc_tplg_widget_ops *widget_ops;
        struct snd_soc_tplg_private *priv = &tw->priv;
+       enum sof_tokens *token_list = NULL;
        struct snd_sof_widget *swidget;
        struct snd_sof_dai *dai;
-       enum sof_tokens *token_list;
-       int token_list_size;
+       int token_list_size = 0;
        int ret = 0;
 
        swidget = kzalloc(sizeof(*swidget), GFP_KERNEL);
@@ -1440,8 +1451,11 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index,
                swidget->num_sink_pins, swidget->num_source_pins,
                strnlen(w->sname, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) > 0 ? w->sname : "none");
 
-       token_list = widget_ops[w->id].token_list;
-       token_list_size = widget_ops[w->id].token_list_size;
+       widget_ops = tplg_ops ? tplg_ops->widget : NULL;
+       if (widget_ops) {
+               token_list = widget_ops[w->id].token_list;
+               token_list_size = widget_ops[w->id].token_list_size;
+       }
 
        /* handle any special case widgets */
        switch (w->id) {
@@ -1525,7 +1539,7 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index,
 
        /* bind widget to external event */
        if (tw->event_type) {
-               if (widget_ops[w->id].bind_event) {
+               if (widget_ops && widget_ops[w->id].bind_event) {
                        ret = widget_ops[w->id].bind_event(scomp, swidget,
                                                           le16_to_cpu(tw->event_type));
                        if (ret) {
@@ -1565,8 +1579,8 @@ static int sof_widget_unload(struct snd_soc_component *scomp,
                             struct snd_soc_dobj *dobj)
 {
        struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
-       const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg;
-       const struct sof_ipc_tplg_widget_ops *widget_ops = ipc_tplg_ops->widget;
+       const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
+       const struct sof_ipc_tplg_widget_ops *widget_ops;
        const struct snd_kcontrol_new *kc;
        struct snd_soc_dapm_widget *widget;
        struct snd_sof_control *scontrol;
@@ -1626,7 +1640,8 @@ static int sof_widget_unload(struct snd_soc_component *scomp,
 
 out:
        /* free IPC related data */
-       if (widget_ops[swidget->id].ipc_free)
+       widget_ops = tplg_ops ? tplg_ops->widget : NULL;
+       if (widget_ops && widget_ops[swidget->id].ipc_free)
                widget_ops[swidget->id].ipc_free(swidget);
 
        ida_destroy(&swidget->src_queue_ida);
@@ -1784,9 +1799,9 @@ static int sof_link_load(struct snd_soc_component *scomp, int index, struct snd_
                         struct snd_soc_tplg_link_config *cfg)
 {
        struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
-       const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg;
-       const struct sof_token_info *token_list = ipc_tplg_ops->token_list;
+       const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
        struct snd_soc_tplg_private *private = &cfg->priv;
+       const struct sof_token_info *token_list;
        struct snd_sof_dai_link *slink;
        u32 token_id = 0;
        int num_tuples = 0;
@@ -1856,6 +1871,7 @@ static int sof_link_load(struct snd_soc_component *scomp, int index, struct snd_
                return ret;
        }
 
+       token_list = tplg_ops ? tplg_ops->token_list : NULL;
        if (!token_list)
                goto out;
 
@@ -2100,16 +2116,18 @@ static int sof_set_pipe_widget(struct snd_sof_dev *sdev, struct snd_sof_widget *
 static int sof_complete(struct snd_soc_component *scomp)
 {
        struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
+       const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
        struct snd_sof_widget *swidget, *comp_swidget;
-       const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg;
-       const struct sof_ipc_tplg_widget_ops *widget_ops = ipc_tplg_ops->widget;
+       const struct sof_ipc_tplg_widget_ops *widget_ops;
        struct snd_sof_control *scontrol;
        int ret;
 
+       widget_ops = tplg_ops ? tplg_ops->widget : NULL;
+
        /* first update all control IPC structures based on the IPC version */
-       if (ipc_tplg_ops->control_setup)
+       if (tplg_ops && tplg_ops->control_setup)
                list_for_each_entry(scontrol, &sdev->kcontrol_list, list) {
-                       ret = ipc_tplg_ops->control_setup(sdev, scontrol);
+                       ret = tplg_ops->control_setup(sdev, scontrol);
                        if (ret < 0) {
                                dev_err(sdev->dev, "failed updating IPC struct for control %s\n",
                                        scontrol->name);
@@ -2123,7 +2141,7 @@ static int sof_complete(struct snd_soc_component *scomp)
         * associated memories.
         */
        list_for_each_entry(swidget, &sdev->widget_list, list) {
-               if (widget_ops[swidget->id].ipc_setup) {
+               if (widget_ops && widget_ops[swidget->id].ipc_setup) {
                        ret = widget_ops[swidget->id].ipc_setup(swidget);
                        if (ret < 0) {
                                dev_err(sdev->dev, "failed updating IPC struct for %s\n",
@@ -2155,15 +2173,16 @@ static int sof_complete(struct snd_soc_component *scomp)
 
        /* verify topology components loading including dynamic pipelines */
        if (sof_debug_check_flag(SOF_DBG_VERIFY_TPLG)) {
-               if (ipc_tplg_ops->set_up_all_pipelines && ipc_tplg_ops->tear_down_all_pipelines) {
-                       ret = ipc_tplg_ops->set_up_all_pipelines(sdev, true);
+               if (tplg_ops && tplg_ops->set_up_all_pipelines &&
+                   tplg_ops->tear_down_all_pipelines) {
+                       ret = tplg_ops->set_up_all_pipelines(sdev, true);
                        if (ret < 0) {
                                dev_err(sdev->dev, "Failed to set up all topology pipelines: %d\n",
                                        ret);
                                return ret;
                        }
 
-                       ret = ipc_tplg_ops->tear_down_all_pipelines(sdev, true);
+                       ret = tplg_ops->tear_down_all_pipelines(sdev, true);
                        if (ret < 0) {
                                dev_err(sdev->dev, "Failed to tear down topology pipelines: %d\n",
                                        ret);
@@ -2173,8 +2192,8 @@ static int sof_complete(struct snd_soc_component *scomp)
        }
 
        /* set up static pipelines */
-       if (ipc_tplg_ops->set_up_all_pipelines)
-               return ipc_tplg_ops->set_up_all_pipelines(sdev, false);
+       if (tplg_ops && tplg_ops->set_up_all_pipelines)
+               return tplg_ops->set_up_all_pipelines(sdev, false);
 
        return 0;
 }
@@ -2184,10 +2203,10 @@ static int sof_manifest(struct snd_soc_component *scomp, int index,
                        struct snd_soc_tplg_manifest *man)
 {
        struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
-       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);
 
-       if (ipc_tplg_ops->parse_manifest)
-               return ipc_tplg_ops->parse_manifest(scomp, index, man);
+       if (tplg_ops && tplg_ops->parse_manifest)
+               return tplg_ops->parse_manifest(scomp, index, man);
 
        return 0;
 }