unsigned int use_pmdown_time:1; /* care pmdown_time at stop */
        unsigned int endianness:1;
        unsigned int non_legacy_dai_naming:1;
+
+       /* this component uses topology and ignore machine driver FEs */
+       const char *ignore_machine;
+       const char *topology_name_prefix;
+       int (*be_hw_params_fixup)(struct snd_soc_pcm_runtime *rtd,
+                                 struct snd_pcm_hw_params *params);
+       bool use_dai_pcm_id;    /* use the DAI link PCM ID as PCM device number */
+       int be_pcm_base;        /* base device ID for all BE PCMs */
 };
 
 struct snd_soc_component {
        /* pmdown_time is ignored at stop */
        unsigned int ignore_pmdown_time:1;
 
+       /* Do not create a PCM for this DAI link (Backend link) */
+       unsigned int ignore:1;
+
        struct list_head list; /* DAI link list of the soc card */
        struct snd_soc_dobj dobj; /* For topology */
 };
        const char *long_name;
        const char *driver_name;
        char dmi_longname[80];
+       char topology_shortname[32];
 
        struct device *dev;
        struct snd_card *snd_card;
        struct mutex dapm_mutex;
 
        bool instantiated;
+       bool topology_shortname_created;
 
        int (*probe)(struct snd_soc_card *card);
        int (*late_probe)(struct snd_soc_card *card);
 
        const char *platform_name;
        int i;
 
+       if (dai_link->ignore)
+               return 0;
+
        dev_dbg(card->dev, "ASoC: binding %s\n", dai_link->name);
 
        if (soc_is_dai_link_bound(card, dai_link)) {
 {
        struct snd_soc_dai_link *dai_link = rtd->dai_link;
        struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
-       int i, ret;
+       struct snd_soc_rtdcom_list *rtdcom;
+       struct snd_soc_component *component;
+       int i, ret, num;
 
        dev_dbg(card->dev, "ASoC: probe %s dai link %d late %d\n",
                        card->name, rtd->num, order);
                soc_dpcm_debugfs_add(rtd);
 #endif
 
+       num = rtd->num;
+
+       /*
+        * most drivers will register their PCMs using DAI link ordering but
+        * topology based drivers can use the DAI link id field to set PCM
+        * device number and then use rtd + a base offset of the BEs.
+        */
+       for_each_rtdcom(rtd, rtdcom) {
+               component = rtdcom->component;
+
+               if (!component->driver->use_dai_pcm_id)
+                       continue;
+
+               if (rtd->dai_link->no_pcm)
+                       num += component->driver->be_pcm_base;
+               else
+                       num = rtd->dai_link->id;
+       }
+
        if (cpu_dai->driver->compress_new) {
                /*create compress_device"*/
-               ret = cpu_dai->driver->compress_new(rtd, rtd->num);
+               ret = cpu_dai->driver->compress_new(rtd, num);
                if (ret < 0) {
                        dev_err(card->dev, "ASoC: can't create compress %s\n",
                                         dai_link->stream_name);
 
                if (!dai_link->params) {
                        /* create the pcm */
-                       ret = soc_new_pcm(rtd, rtd->num);
+                       ret = soc_new_pcm(rtd, num);
                        if (ret < 0) {
                                dev_err(card->dev, "ASoC: can't create pcm %s :%d\n",
                                       dai_link->stream_name, ret);
 EXPORT_SYMBOL_GPL(snd_soc_set_dmi_name);
 #endif /* CONFIG_DMI */
 
+static void soc_check_tplg_fes(struct snd_soc_card *card)
+{
+       struct snd_soc_component *component;
+       const struct snd_soc_component_driver *comp_drv;
+       struct snd_soc_dai_link *dai_link;
+       int i;
+
+       list_for_each_entry(component, &component_list, list) {
+
+               /* does this component override FEs ? */
+               if (!component->driver->ignore_machine)
+                       continue;
+
+               /* for this machine ? */
+               if (strcmp(component->driver->ignore_machine,
+                          card->dev->driver->name))
+                       continue;
+
+               /* machine matches, so override the rtd data */
+               for (i = 0; i < card->num_links; i++) {
+
+                       dai_link = &card->dai_link[i];
+
+                       /* ignore this FE */
+                       if (dai_link->dynamic) {
+                               dai_link->ignore = true;
+                               continue;
+                       }
+
+                       dev_info(card->dev, "info: override FE DAI link %s\n",
+                                card->dai_link[i].name);
+
+                       /* override platform component */
+                       dai_link->platform_name = component->name;
+
+                       /* convert non BE into BE */
+                       dai_link->no_pcm = 1;
+
+                       /* override any BE fixups */
+                       dai_link->be_hw_params_fixup =
+                               component->driver->be_hw_params_fixup;
+
+                       /* most BE links don't set stream name, so set it to
+                        * dai link name if it's NULL to help bind widgets.
+                        */
+                       if (!dai_link->stream_name)
+                               dai_link->stream_name = dai_link->name;
+               }
+
+               /* Inform userspace we are using alternate topology */
+               if (component->driver->topology_name_prefix) {
+
+                       /* topology shortname created ? */
+                       if (!card->topology_shortname_created) {
+                               comp_drv = component->driver;
+
+                               snprintf(card->topology_shortname, 32, "%s-%s",
+                                        comp_drv->topology_name_prefix,
+                                        card->name);
+                               card->topology_shortname_created = true;
+                       }
+
+                       /* use topology shortname */
+                       card->name = card->topology_shortname;
+               }
+       }
+}
+
 static int snd_soc_instantiate_card(struct snd_soc_card *card)
 {
        struct snd_soc_pcm_runtime *rtd;
        mutex_lock(&client_mutex);
        mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_INIT);
 
+       /* check whether any platform is ignore machine FE and using topology */
+       soc_check_tplg_fes(card);
+
        /* bind DAIs */
        for (i = 0; i < card->num_links; i++) {
                ret = soc_bind_dai_link(card, &card->dai_link[i]);