#define SOF_IPC4_GAIN_PARAM_ID  0
 #define SOF_IPC4_TPLG_ABI_SIZE 6
 
+static DEFINE_IDA(alh_group_ida);
+
 static const struct sof_topology_token ipc4_sched_tokens[] = {
        {SOF_TKN_SCHED_LP_MODE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
                offsetof(struct sof_ipc4_pipeline, lp_mode)}
        switch (ipc4_copier->dai_type) {
        case SOF_DAI_INTEL_ALH:
        {
+               struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
                struct sof_ipc4_alh_configuration_blob *blob;
+               struct snd_sof_widget *w;
 
                blob = kzalloc(sizeof(*blob), GFP_KERNEL);
                if (!blob) {
                        goto err;
                }
 
+               list_for_each_entry(w, &sdev->widget_list, list) {
+                       if (w->widget->sname &&
+                           strcmp(w->widget->sname, swidget->widget->sname))
+                               continue;
+
+                       blob->alh_cfg.count++;
+               }
+
                ipc4_copier->copier_config = (uint32_t *)blob;
                ipc4_copier->data.gtw_cfg.config_length = sizeof(*blob) >> 2;
                break;
                struct snd_sof_dai *dai = swidget->private;
 
                ipc4_copier = dai->private;
+               if (ipc4_copier->dai_type == SOF_DAI_INTEL_ALH) {
+                       struct sof_ipc4_alh_configuration_blob *blob;
+                       unsigned int group_id;
+
+                       blob = (struct sof_ipc4_alh_configuration_blob *)ipc4_copier->copier_config;
+                       if (blob->alh_cfg.count > 1) {
+                               group_id = SOF_IPC4_NODE_INDEX(ipc4_copier->data.gtw_cfg.node_id) -
+                                          ALH_MULTI_GTW_BASE;
+                               ida_free(&alh_group_ida, group_id);
+                       }
+               }
        }
 
        if (ipc4_copier) {
        struct sof_ipc4_copier_data *copier_data;
        struct snd_pcm_hw_params *ref_params;
        struct sof_ipc4_copier *ipc4_copier;
+       struct snd_sof_dai *dai;
        struct snd_mask *fmt;
        int out_sample_valid_bits;
        size_t ref_audio_fmt_size;
        case snd_soc_dapm_dai_in:
        case snd_soc_dapm_dai_out:
        {
-               struct snd_sof_dai *dai = swidget->private;
+               dai = swidget->private;
 
                ipc4_copier = (struct sof_ipc4_copier *)dai->private;
                copier_data = &ipc4_copier->data;
                 */
                if (ipc4_copier->dai_type == SOF_DAI_INTEL_ALH) {
                        struct sof_ipc4_alh_configuration_blob *blob;
+                       struct sof_ipc4_copier_data *alh_data;
+                       struct sof_ipc4_copier *alh_copier;
+                       struct snd_sof_widget *w;
+                       u32 ch_mask = 0;
                        u32 ch_map;
                        int i;
 
                        blob = (struct sof_ipc4_alh_configuration_blob *)ipc4_copier->copier_config;
-                       /* TODO: add aggregation mode support */
-                       blob->alh_cfg.count = 1;
-                       blob->alh_cfg.mapping[0].alh_id = copier_data->gtw_cfg.node_id;
+
                        blob->gw_attr.lp_buffer_alloc = 0;
 
                        /* Get channel_mask from ch_map */
                        ch_map = copier_data->base_config.audio_fmt.ch_map;
                        for (i = 0; ch_map; i++) {
                                if ((ch_map & 0xf) != 0xf)
-                                       blob->alh_cfg.mapping[0].channel_mask |= BIT(i);
+                                       ch_mask |= BIT(i);
                                ch_map >>= 4;
                        }
+
+                       /*
+                        * Set each gtw_cfg.node_id to blob->alh_cfg.mapping[]
+                        * for all widgets with the same stream name
+                        */
+                       i = 0;
+                       list_for_each_entry(w, &sdev->widget_list, list) {
+                               if (w->widget->sname &&
+                                   strcmp(w->widget->sname, swidget->widget->sname))
+                                       continue;
+
+                               dai = w->private;
+                               alh_copier = (struct sof_ipc4_copier *)dai->private;
+                               alh_data = &alh_copier->data;
+                               blob->alh_cfg.mapping[i].alh_id = alh_data->gtw_cfg.node_id;
+                               blob->alh_cfg.mapping[i].channel_mask = ch_mask;
+                               i++;
+                       }
+                       if (blob->alh_cfg.count > 1) {
+                               int group_id;
+
+                               group_id = ida_alloc_max(&alh_group_ida, ALH_MULTI_GTW_COUNT,
+                                                        GFP_KERNEL);
+
+                               if (group_id < 0)
+                                       return group_id;
+
+                               /* add multi-gateway base */
+                               group_id += ALH_MULTI_GTW_BASE;
+                               copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK;
+                               copier_data->gtw_cfg.node_id |= SOF_IPC4_NODE_INDEX(group_id);
+                       }
                }
        }
        }