return 0;
 }
 
+static int parse_link_formatted_string(struct snd_soc_component *comp, void *elem,
+                                      void *object, u32 offset)
+{
+       struct snd_soc_tplg_vendor_string_elem *tuple = elem;
+       struct snd_soc_acpi_mach *mach = dev_get_platdata(comp->card->dev);
+       char *val = (char *)((u8 *)object + offset);
+
+       /*
+        * Dynamic naming - string formats, e.g.: ssp%d - supported only for
+        * topologies describing single device e.g.: an I2S codec on SSP0.
+        */
+       if (hweight_long(mach->link_mask) != 1)
+               return avs_parse_string_token(comp, elem, object, offset);
+
+       snprintf(val, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, tuple->string,
+                __ffs(mach->link_mask));
+
+       return 0;
+}
+
 static int
 parse_dictionary_header(struct snd_soc_component *comp,
                        struct snd_soc_tplg_vendor_array *tuples,
                .token = AVS_TKN_BINDING_TARGET_TPLG_NAME_STRING,
                .type = SND_SOC_TPLG_TUPLE_TYPE_STRING,
                .offset = offsetof(struct avs_tplg_binding, target_tplg_name),
-               .parse = avs_parse_string_token,
+               .parse = parse_link_formatted_string,
        },
        {
                .token = AVS_TKN_BINDING_TARGET_PATH_TMPL_ID_U32,
        return template;
 }
 
+static int avs_route_load(struct snd_soc_component *comp, int index,
+                         struct snd_soc_dapm_route *route)
+{
+       struct snd_soc_acpi_mach *mach = dev_get_platdata(comp->card->dev);
+       size_t len = SNDRV_CTL_ELEM_ID_NAME_MAXLEN;
+       char buf[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
+       u32 port;
+
+       /* See parse_link_formatted_string() for dynamic naming when(s). */
+       if (hweight_long(mach->link_mask) == 1) {
+               port = __ffs(mach->link_mask);
+
+               snprintf(buf, len, route->source, port);
+               strncpy((char *)route->source, buf, len);
+               snprintf(buf, len, route->sink, port);
+               strncpy((char *)route->sink, buf, len);
+               if (route->control) {
+                       snprintf(buf, len, route->control, port);
+                       strncpy((char *)route->control, buf, len);
+               }
+       }
+
+       return 0;
+}
+
 static int avs_widget_load(struct snd_soc_component *comp, int index,
                           struct snd_soc_dapm_widget *w,
                           struct snd_soc_tplg_dapm_widget *dw)
        tplg = acomp->tplg;
        mach = dev_get_platdata(comp->card->dev);
 
+       /* See parse_link_formatted_string() for dynamic naming when(s). */
+       if (hweight_long(mach->link_mask) == 1) {
+               kfree(w->name);
+               /* w->name is freed later by soc_tplg_dapm_widget_create() */
+               w->name = kasprintf(GFP_KERNEL, dw->name, __ffs(mach->link_mask));
+               if (!w->name)
+                       return -ENOMEM;
+       }
+
        template = avs_tplg_path_template_create(comp, tplg, dw->priv.array,
                                                 le32_to_cpu(dw->priv.size));
        if (IS_ERR(template)) {
                .token = AVS_TKN_MANIFEST_NAME_STRING,
                .type = SND_SOC_TPLG_TUPLE_TYPE_STRING,
                .offset = offsetof(struct avs_tplg, name),
-               .parse = avs_parse_string_token,
+               .parse = parse_link_formatted_string,
        },
        {
                .token = AVS_TKN_MANIFEST_VERSION_U32,
 }
 
 static struct snd_soc_tplg_ops avs_tplg_ops = {
+       .dapm_route_load        = avs_route_load,
        .widget_load            = avs_widget_load,
        .dai_load               = avs_dai_load,
        .link_load              = avs_link_load,