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;
 {
        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__);
                           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;
                              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);
        }
                                   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;
                            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);
                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) {
 
        /* 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) {
                             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;
 
 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);
                         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;
                return ret;
        }
 
+       token_list = tplg_ops ? tplg_ops->token_list : NULL;
        if (!token_list)
                goto out;
 
 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);
         * 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",
 
        /* 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);
        }
 
        /* 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;
 }
                        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;
 }