plugins: test: AGM test app enhancement.

- Remove hardcoding of all gkvs, add support to take stream kv,
  device kv, device pp kv, instance kv from cmdline.
- Add support of passing device pp kv and instance kv as 0 for
  graph which doesn't have device pp kv or instance kv.
- SSMD playback support.
- Remove array of backends from agmhostless and add support of
  taking intf configuration from backend_conf.xml
- Support of loopback through application processor.

Change-Id: Ie5bef45f4670b5c99fa37bfcd8dab3ab54001866
diff --git a/plugins/tinyalsa/test/Android.mk b/plugins/tinyalsa/test/Android.mk
index 7990745..abca51c 100644
--- a/plugins/tinyalsa/test/Android.mk
+++ b/plugins/tinyalsa/test/Android.mk
@@ -88,6 +88,35 @@
 
 include $(CLEAR_VARS)
 
+LOCAL_MODULE        := agmhostless
+LOCAL_MODULE_OWNER  := qti
+LOCAL_MODULE_TAGS   := optional
+LOCAL_VENDOR_MODULE := true
+
+LOCAL_CFLAGS        += -Wno-unused-parameter -Wno-unused-result
+LOCAL_CFLAGS        += -DBACKEND_CONF_FILE=\"/vendor/etc/backend_conf.xml\"
+LOCAL_SRC_FILES     := agmhostless.c
+
+LOCAL_HEADER_LIBRARIES := \
+    libagm_headers \
+    libacdb_headers
+
+#if android version is R, refer to qtitinyxx otherwise use upstream ones
+#This assumes we would be using AR code only for Android R and subsequent versions.
+ifneq ($(filter 11 R, $(PLATFORM_VERSION)),)
+LOCAL_C_INCLUDES += $(TOP)/vendor/qcom/opensource/tinyalsa/include
+LOCAL_SHARED_LIBRARIES += libqti-tinyalsa
+else
+LOCAL_SHARED_LIBRARIES += libtinyalsa
+endif
+
+LOCAL_SHARED_LIBRARIES += \
+    libagmmixer
+
+include $(BUILD_EXECUTABLE)
+
+include $(CLEAR_VARS)
+
 LOCAL_MODULE        := agmcompressplay
 LOCAL_MODULE_OWNER  := qti
 LOCAL_MODULE_TAGS   := optional
@@ -125,6 +154,43 @@
 
 include $(CLEAR_VARS)
 
+LOCAL_MODULE        := agmcompresscap
+LOCAL_MODULE_OWNER  := qti
+LOCAL_MODULE_TAGS   := optional
+LOCAL_VENDOR_MODULE := true
+
+LOCAL_CFLAGS        += -Wno-unused-parameter -Wno-unused-result
+LOCAL_CFLAGS        += -DBACKEND_CONF_FILE=\"/vendor/etc/backend_conf.xml\"
+
+LOCAL_C_INCLUDES    += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
+LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
+
+LOCAL_SRC_FILES     := agmcompresscap.c
+
+LOCAL_HEADER_LIBRARIES := \
+    libagm_headers \
+    libacdb_headers
+
+#if android version is R, refer to qtitinyxx otherwise use upstream ones
+#This assumes we would be using AR code only for Android R and subsequent versions.
+ifneq ($(filter 11 R, $(PLATFORM_VERSION)),)
+LOCAL_C_INCLUDES += $(TOP)/vendor/qcom/opensource/tinyalsa/include
+LOCAL_C_INCLUDES += $(TOP)/vendor/qcom/opensource/tinycompress/include
+LOCAL_SHARED_LIBRARIES += libqti-tinyalsa\
+                          libqti-tinycompress
+else
+LOCAL_C_INCLUDES += $(TOP)/external/tinycompress/include
+LOCAL_SHARED_LIBRARIES += libtinyalsa\
+                          libtinycompress
+endif
+
+LOCAL_SHARED_LIBRARIES += \
+    libagmmixer
+
+include $(BUILD_EXECUTABLE)
+
+include $(CLEAR_VARS)
+
 LOCAL_MODULE        := agmvoiceui
 LOCAL_MODULE_OWNER  := qti
 LOCAL_MODULE_TAGS   := optional
diff --git a/plugins/tinyalsa/test/agm_voiceui.c b/plugins/tinyalsa/test/agm_voiceui.c
index 552c876..f039be8 100644
--- a/plugins/tinyalsa/test/agm_voiceui.c
+++ b/plugins/tinyalsa/test/agm_voiceui.c
@@ -236,11 +236,12 @@
         buf += size[i];
     }
     *sum = total_size;
-	/* TODO : free memory */
+    /* TODO : free memory */
     return payload;
 }
 
-void voice_ui_test(unsigned int card, unsigned int device, unsigned int audio_intf, unsigned int cap_time, int ec_aif)
+void voice_ui_test(unsigned int card, unsigned int device, unsigned int audio_intf, unsigned int cap_time, int ec_aif,
+                    unsigned int device_kv, unsigned int stream_kv, unsigned int instance_kv, unsigned int devicepp_kv)
 {
     struct mixer *mixer;
     char *intf_name = audio_interface_name[audio_intf];
@@ -261,6 +262,7 @@
     config.start_threshold = 0;
     config.stop_threshold = 0;
     config.silence_threshold = 0;
+    stream_kv = stream_kv ? stream_kv : VOICE_UI;
 
     mixer = mixer_open(card);
     if (!mixer) {
@@ -276,20 +278,25 @@
     }
 
     /* set audio interface metadata mixer control */
-    if (set_agm_audio_intf_metadata(mixer, intf_name, 0, CAPTURE, config.rate, pcm_format_to_bits(format), VOICE_UI)) {
+    if (set_agm_audio_intf_metadata(mixer, intf_name, 0, CAPTURE, config.rate,
+                                    pcm_format_to_bits(format), stream_kv)) {
         printf("Failed to set device metadata\n");
         goto err_close_mixer;
     }
 
     /* set stream metadata mixer control */
-    if (set_agm_stream_metadata(mixer, device, VOICE_UI, CAPTURE, STREAM_PCM, NULL)) {
+    if (set_agm_stream_metadata(mixer, device, stream_kv, CAPTURE, STREAM_PCM,
+                                instance_kv)) {
         printf("Failed to set pcm metadata\n");
         goto err_close_mixer;
     }
 
-    if (set_agm_stream_metadata(mixer, device, VOICE_UI, CAPTURE, STREAM_PCM, intf_name)) {
-        printf("Failed to set pcm metadata\n");
-        goto err_close_mixer;
+    if (devicepp_kv != 0) {
+        if (set_agm_streamdevice_metadata(mixer, device, stream_kv, CAPTURE, STREAM_PCM,
+                                intf_name, devicepp_kv)) {
+            printf("Failed to set pcm metadata\n");
+            goto err_close_mixer;
+        }
     }
     /* connect pcm stream to audio intf */
     if (connect_agm_audio_intf_to_stream(mixer, device, intf_name, STREAM_PCM, true)) {
@@ -385,6 +392,10 @@
     unsigned int audio_intf = 0;
     int ec_aif = -1;
     unsigned int cap_time = 5;
+    unsigned int device_kv = 0;
+    unsigned int devicepp_kv = DEVICEPP_TX_FLUENCE_FFECNS;
+    unsigned int stream_kv = 0;
+    unsigned int instance_kv = INSTANCE_1;
 
     argv += 1;
     while (*argv) {
@@ -420,12 +431,29 @@
             argv++;
             if (*argv)
                 cap_time = atoi(*argv);
+        } else if (strcmp(*argv, "-dkv") == 0) {
+            argv++;
+            if (*argv)
+                device_kv = convert_char_to_hex(*argv);
+        } else if (strcmp(*argv, "-skv") == 0) {
+            argv++;
+            if (*argv)
+                stream_kv = convert_char_to_hex(*argv);
+        } else if (strcmp(*argv, "-ikv") == 0) {
+            argv++;
+            if (*argv)
+                instance_kv = atoi(*argv);
+        } else if (strcmp(*argv, "-dppkv") == 0) {
+            argv++;
+            if (*argv)
+                devicepp_kv = convert_char_to_hex(*argv);
         }
 
         if (*argv)
             argv++;
     }
 
-    voice_ui_test(card, device, audio_intf, cap_time, ec_aif);
+    voice_ui_test(card, device, audio_intf, cap_time, ec_aif, device_kv, stream_kv,
+                  instance_kv, devicepp_kv);
     return 0;
 }
diff --git a/plugins/tinyalsa/test/agmcap.c b/plugins/tinyalsa/test/agmcap.c
index d0257e4..07a247d 100644
--- a/plugins/tinyalsa/test/agmcap.c
+++ b/plugins/tinyalsa/test/agmcap.c
@@ -64,16 +64,28 @@
 int capturing = 1;
 
 static unsigned int capture_sample(FILE *file, unsigned int card, unsigned int device,
-                            unsigned int dkv, unsigned int channels, unsigned int rate,
+                            unsigned int channels, unsigned int rate,
                             enum pcm_format format, unsigned int period_size,
                             unsigned int period_count, unsigned int cap_time,
-                            struct device_config *dev_config);
+                            struct device_config *dev_config, unsigned int stream_kv,
+                            unsigned int device_kv, unsigned int instance_kv,
+                            unsigned int devicepp_kv);
 
 static void sigint_handler(int sig)
 {
     capturing = 0;
 }
 
+static void usage(void)
+{
+    printf(" Usage: %s file.wav [-help print usage] [-D card] [-d device]\n"
+           " [-c channels] [-r rate] [-b bits] [-p period_size]\n"
+           " [-n n_periods] [-T capture time] [-i intf_name] [-dkv device_kv]\n"
+           " [-dppkv deviceppkv] : Assign 0 if no device pp in the graph\n"
+           " [-ikv instance_kv] :  Assign 0 if no instance kv in the graph\n"
+           " [-skv stream_kv]\n");
+}
+
 int main(int argc, char **argv)
 {
     FILE *file;
@@ -92,11 +104,13 @@
     struct device_config config;
     enum pcm_format format;
     int ret = 0;
+    unsigned int devicepp_kv = DEVICEPP_TX_AUDIO_FLUENCE_SMECNS;
+    unsigned int stream_kv = 0;
+    unsigned int instance_kv = INSTANCE_1;
+
 
     if (argc < 2) {
-        printf("Usage: %s file.wav [-D card] [-d device]"
-                " [-c channels] [-r rate] [-b bits] [-p period_size]"
-                " [-n n_periods] [-T capture time] [-i intf_name] [-dkv device_kv]\n", argv[0]);
+        usage();
         return 1;
     }
 
@@ -149,8 +163,21 @@
             argv++;
             if (*argv)
                 device_kv = convert_char_to_hex(*argv);
+        } else if (strcmp(*argv, "-skv") == 0) {
+            argv++;
+            if (*argv)
+                stream_kv = convert_char_to_hex(*argv);
+        } else if (strcmp(*argv, "-ikv") == 0) {
+            argv++;
+            if (*argv)
+                instance_kv = atoi(*argv);
+        } else if (strcmp(*argv, "-dppkv") == 0) {
+            argv++;
+            if (*argv)
+                devicepp_kv = convert_char_to_hex(*argv);
+        } else if (strcmp(*argv, "-help") == 0) {
+            usage();
         }
-
         if (*argv)
             argv++;
     }
@@ -202,9 +229,10 @@
     signal(SIGINT, sigint_handler);
     signal(SIGHUP, sigint_handler);
     signal(SIGTERM, sigint_handler);
-    frames = capture_sample(file, card, device, device_kv, header.num_channels,
+    frames = capture_sample(file, card, device, header.num_channels,
                             header.sample_rate, format,
-                            period_size, period_count, cap_time, &config);
+                            period_size, period_count, cap_time, &config,
+                            stream_kv, device_kv, instance_kv, devicepp_kv);
     printf("Captured %u frames\n", frames);
 
     /* write header now all information is known */
@@ -219,10 +247,11 @@
 }
 
 unsigned int capture_sample(FILE *file, unsigned int card, unsigned int device,
-                            unsigned int dkv, unsigned int channels, unsigned int rate,
+                            unsigned int channels, unsigned int rate,
                             enum pcm_format format, unsigned int period_size,
                             unsigned int period_count, unsigned int cap_time,
-                            struct device_config *dev_config)
+                            struct device_config *dev_config, unsigned int stream_kv,
+                            unsigned int device_kv, unsigned int instance_kv, unsigned int devicepp_kv)
 {
     struct pcm_config config;
     struct pcm *pcm;
@@ -234,6 +263,9 @@
     unsigned int frames = 0;
     struct timespec end;
     struct timespec now;
+    uint32_t miid = 0;
+    int ret = 0;
+    stream_kv = stream_kv ? stream_kv : PCM_RECORD;
 
     memset(&config, 0, sizeof(config));
     config.channels = channels;
@@ -259,21 +291,36 @@
     }
 
     /* set audio interface metadata mixer control */
-    if (set_agm_audio_intf_metadata(mixer, intf_name, dkv, CAPTURE, dev_config->rate, dev_config->bits, PCM_RECORD)) {
+    if (set_agm_audio_intf_metadata(mixer, intf_name, device_kv, CAPTURE,
+                                    dev_config->rate, dev_config->bits, stream_kv)) {
         printf("Failed to set device metadata\n");
         goto err_close_mixer;
     }
 
     /* set stream metadata mixer control */
-    if (set_agm_capture_stream_metadata(mixer, device, PCM_RECORD, CAPTURE, STREAM_PCM, dev_config->ch)) {
+    if (set_agm_capture_stream_metadata(mixer, device, stream_kv, CAPTURE, STREAM_PCM,
+                                        instance_kv)) {
         printf("Failed to set pcm metadata\n");
         goto err_close_mixer;
     }
 
-    if (configure_mfc(mixer, device, intf_name, TAG_STREAM_MFC,
-                     STREAM_PCM, rate, channels, pcm_format_to_bits(format))) {
-        printf("Failed to configure pspd mfc\n");
-        goto err_close_mixer;
+    if (devicepp_kv != 0) {
+        if (set_agm_streamdevice_metadata(mixer, device, stream_kv, CAPTURE, STREAM_PCM,
+                                intf_name, devicepp_kv)) {
+            printf("Failed to set pcm metadata\n");
+            goto err_close_mixer;
+        }
+    }
+
+    ret = agm_mixer_get_miid (mixer, device, intf_name, STREAM_PCM, TAG_STREAM_MFC, &miid);
+    if (ret) {
+        printf("MFC not present for this graph\n");
+    } else {
+        if (configure_mfc(mixer, device, intf_name, TAG_STREAM_MFC,
+                     STREAM_PCM, rate, channels, pcm_format_to_bits(format), miid)) {
+            printf("Failed to configure stream mfc\n");
+            goto err_close_mixer;
+        }
     }
 
     /* connect pcm stream to audio intf */
diff --git a/plugins/tinyalsa/test/agmcompresscap.c b/plugins/tinyalsa/test/agmcompresscap.c
index 7f20323..d5e1794 100644
--- a/plugins/tinyalsa/test/agmcompresscap.c
+++ b/plugins/tinyalsa/test/agmcompresscap.c
@@ -88,459 +88,503 @@
 static const unsigned int DEFAULT_FORMAT = SNDRV_PCM_FORMAT_S16_LE;
 
 struct riff_chunk {
-	char desc[4];
-	uint32_t size;
+    char desc[4];
+    uint32_t size;
 } __attribute__((__packed__));
 
 struct wave_header {
-	struct {
-		struct riff_chunk chunk;
-		char format[4];
-	} __attribute__((__packed__)) riff;
+    struct {
+        struct riff_chunk chunk;
+        char format[4];
+    } __attribute__((__packed__)) riff;
 
-	struct {
-		struct riff_chunk chunk;
-		uint16_t type;
-		uint16_t channels;
-		uint32_t rate;
-		uint32_t byterate;
-		uint16_t blockalign;
-		uint16_t samplebits;
-	} __attribute__((__packed__)) fmt;
+    struct {
+        struct riff_chunk chunk;
+        uint16_t type;
+        uint16_t channels;
+        uint32_t rate;
+        uint32_t byterate;
+        uint16_t blockalign;
+        uint16_t samplebits;
+    } __attribute__((__packed__)) fmt;
 
-	struct {
-		struct riff_chunk chunk;
-	} __attribute__((__packed__)) data;
+    struct {
+        struct riff_chunk chunk;
+    } __attribute__((__packed__)) data;
 } __attribute__((__packed__));
 
 static const struct wave_header blank_wave_header = {
-	.riff = {
-		.chunk = {
-			.desc = "RIFF",
-		},
-		.format = "WAVE",
-	},
-	.fmt = {
-		.chunk = {
-			.desc = "fmt ", /* Note the space is important here */
-			.size = sizeof(blank_wave_header.fmt) -
-				sizeof(blank_wave_header.fmt.chunk),
-		},
-		.type = 0x01,   /* PCM */
-	},
-	.data = {
-		.chunk = {
-			.desc = "data",
-		},
-	},
-};
-
-char *audio_interface_name[] = {
-    "CODEC_DMA-LPAIF_VA-TX-0",
-    "CODEC_DMA-LPAIF_VA-TX-1",
-    "MI2S-LPAIF_AXI-TX-PRIMARY",
-    "TDM-LPAIF_AXI-TX-PRIMARY",
-    "AUXPCM-LPAIF_AXI-TX-PRIMARY",
-    "SLIM-DEV1-TX-0",
-    "USB_AUDIO-TX",
+    .riff = {
+        .chunk = {
+            .desc = "RIFF",
+        },
+        .format = "WAVE",
+    },
+    .fmt = {
+        .chunk = {
+            .desc = "fmt ", /* Note the space is important here */
+            .size = sizeof(blank_wave_header.fmt) -
+                sizeof(blank_wave_header.fmt.chunk),
+        },
+        .type = 0x01,   /* PCM */
+    },
+    .data = {
+        .chunk = {
+            .desc = "data",
+        },
+    },
 };
 
 static void init_wave_header(struct wave_header *header, uint16_t channels,
-			     uint32_t rate, uint16_t samplebits)
+                 uint32_t rate, uint16_t samplebits)
 {
-	memcpy(header, &blank_wave_header, sizeof(blank_wave_header));
+    memcpy(header, &blank_wave_header, sizeof(blank_wave_header));
 
-	header->fmt.channels = channels;
-	header->fmt.rate = rate;
-	header->fmt.byterate = channels * rate * (samplebits / 8);
-	header->fmt.blockalign = channels * (samplebits / 8);
-	header->fmt.samplebits = samplebits;
+    header->fmt.channels = channels;
+    header->fmt.rate = rate;
+    header->fmt.byterate = channels * rate * (samplebits / 8);
+    header->fmt.blockalign = channels * (samplebits / 8);
+    header->fmt.samplebits = samplebits;
 }
 
 static void size_wave_header(struct wave_header *header, uint32_t size)
 {
-	header->riff.chunk.size = sizeof(*header) -
-				  sizeof(header->riff.chunk) + size;
-	header->data.chunk.size = size;
+    header->riff.chunk.size = sizeof(*header) -
+                  sizeof(header->riff.chunk) + size;
+    header->data.chunk.size = size;
 }
 
 static void usage(void)
 {
-	fprintf(stderr, "usage: crec [OPTIONS] [filename]\n"
-		"-c\tcard number\n"
-		"-d\tdevice node\n"
-		"-b\tbuffer size\n"
-		"-f\tfragments\n"
-		"-v\tverbose mode\n"
-		"-l\tlength of record in seconds\n"
-		"-h\tPrints this help list\n\n"
-		"-C\tSpecify the number of channels (default %u)\n"
-		"-R\tSpecify the sample rate (default %u)\n"
-		"-F\tSpecify the format: S16_LE, S32_LE (default S16_LE)\n\n"
-		"If filename is not given the output is\n"
-		"written to stdout\n\n"
-		"Example:\n"
-		"\tcrec -c 1 -d 2 test.wav\n"
-		"\tcrec -f 5 test.wav\n",
-		DEFAULT_CHANNELS, DEFAULT_RATE);
+    fprintf(stderr, "usage: crec [OPTIONS] [filename]\n"
+        "-D\tcard number\n"
+        "-d\tdevice node\n"
+        "-buf\tbuffer size\n"
+        "-f\tfragments\n"
+        "-v\tverbose mode\n"
+        "-l\tlength of record in seconds\n"
+        " [-help print usage]\n"
+        " [-c channels] [-r rate] [-b bits]\n"
+        " [-n n_periods] [-i intf_name] [-dkv device_kv]\n"
+        " [-dppkv deviceppkv] : Assign 0 if no device pp in the graph\n"
+        " [-ikv instance_kv] :  Assign 0 if no instance kv in the graph\n"
+        " [-skv stream_kv]");
 
-	exit(EXIT_FAILURE);
+    exit(EXIT_FAILURE);
 }
 
 static int print_time(struct compress *compress)
 {
-	unsigned int avail;
-	struct timespec tstamp;
+    unsigned int avail;
+    struct timespec tstamp;
 
-	if (compress_get_hpointer(compress, &avail, &tstamp) != 0) {
-		fprintf(stderr, "Error querying timestamp\n");
-		fprintf(stderr, "ERR: %s\n", compress_get_error(compress));
-		return -1;
-	} else {
-		fprintf(finfo, "DSP recorded %jd.%jd\n",
-		       (intmax_t)tstamp.tv_sec, (intmax_t)tstamp.tv_nsec*1000);
-	}
-	return 0;
+    if (compress_get_hpointer(compress, &avail, &tstamp) != 0) {
+        fprintf(stderr, "Error querying timestamp\n");
+        fprintf(stderr, "ERR: %s\n", compress_get_error(compress));
+        return -1;
+    } else {
+        fprintf(finfo, "DSP recorded %jd.%jd\n",
+               (intmax_t)tstamp.tv_sec, (intmax_t)tstamp.tv_nsec*1000);
+    }
+    return 0;
 }
 
 static int finish_record(void)
 {
-	struct wave_header header;
-	int ret;
-	size_t nread, written;
+    struct wave_header header;
+    int ret;
+    size_t nread, written;
 
-	if (!file)
-		return -ENOENT;
+    if (!file)
+        return -ENOENT;
 
-	/* can't rewind if streaming to stdout */
-	if (streamed)
-		return 0;
+    /* can't rewind if streaming to stdout */
+    if (streamed)
+        return 0;
 
-	/* Get amount of data written to file */
-	ret = lseek(file, 0, SEEK_END);
-	if (ret < 0)
-		return -errno;
+    /* Get amount of data written to file */
+    ret = lseek(file, 0, SEEK_END);
+    if (ret < 0)
+        return -errno;
 
-	written = ret;
-	if (written < sizeof(header))
-		return -ENOENT;
-	written -= sizeof(header);
+    written = ret;
+    if (written < sizeof(header))
+        return -ENOENT;
+    written -= sizeof(header);
 
-	/* Sync file header from file */
-	ret = lseek(file, 0, SEEK_SET);
-	if (ret < 0)
-		return -errno;
+    /* Sync file header from file */
+    ret = lseek(file, 0, SEEK_SET);
+    if (ret < 0)
+        return -errno;
 
-	nread = read(file, &header, sizeof(header));
-	if (nread != sizeof(header))
-		return -errno;
+    nread = read(file, &header, sizeof(header));
+    if (nread != sizeof(header))
+        return -errno;
 
-	/* Update file header */
-	ret = lseek(file, 0, SEEK_SET);
-	if (ret < 0)
-		return -errno;
+    /* Update file header */
+    ret = lseek(file, 0, SEEK_SET);
+    if (ret < 0)
+        return -errno;
 
-	size_wave_header(&header, written);
+    size_wave_header(&header, written);
 
-	written = write(file, &header, sizeof(header));
-	if (written != sizeof(header))
-		return -errno;
+    written = write(file, &header, sizeof(header));
+    if (written != sizeof(header))
+        return -errno;
 
-	return 0;
+    return 0;
 }
 
 static void capture_samples(char *name, unsigned int card, unsigned int device,
-		     unsigned long buffer_size, unsigned int frag,
-		     unsigned int length, unsigned int rate,
-		     unsigned int channels, unsigned int format, unsigned int intf)
+             unsigned long buffer_size, unsigned int frag,
+             unsigned int length, unsigned int rate,
+             unsigned int channels, unsigned int format, struct device_config *dev_config, unsigned int stream_kv,
+             unsigned int device_kv, unsigned int instance_kv, unsigned int devicepp_kv)
 {
-	struct compr_config config;
-	struct snd_codec codec;
-	struct compress *compress;
-	struct mixer *mixer;
-	struct wave_header header;
-	char *buffer;
-	size_t written;
-	int read, ret;
-	unsigned int size, total_read = 0;
-	unsigned int samplebits;
-	char *intf_name = audio_interface_name[intf];
+    struct compr_config config;
+    struct snd_codec codec;
+    struct compress *compress;
+    struct mixer *mixer;
+    struct wave_header header;
+    char *buffer;
+    size_t written;
+    int read, ret;
+    unsigned int size, total_read = 0;
+    unsigned int samplebits;
+    uint32_t miid = 0;
+    char *intf_name = dev_config->name;
+    //TODO: Change default stream_kv to COMPRESS_RECORD later.
+    stream_kv = stream_kv ? stream_kv : PCM_RECORD;
 
-	switch (format) {
-	case SNDRV_PCM_FORMAT_S32_LE:
-		samplebits = 32;
-		break;
-	default:
-		samplebits = 16;
-		break;
-	}
+    switch (format) {
+    case SNDRV_PCM_FORMAT_S32_LE:
+        samplebits = 32;
+        break;
+    default:
+        samplebits = 16;
+        break;
+    }
 
-	/* Convert length from seconds to bytes */
-	length = length * rate * (samplebits / 8) * channels;
+    /* Convert length from seconds to bytes */
+    length = length * rate * (samplebits / 8) * channels;
 
-	if (verbose)
-		fprintf(finfo, "%s: entry, reading %u bytes\n", __func__, length);
+    if (verbose)
+        fprintf(finfo, "%s: entry, reading %u bytes\n", __func__, length);
         if (!name) {
                 file = STDOUT_FILENO;
         } else {
-	        file = open(name, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
-	        if (file == -1) {
-		       fprintf(stderr, "Unable to open file '%s'\n", name);
-		       exit(EXIT_FAILURE);
-	        }
+            file = open(name, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
+            if (file == -1) {
+               fprintf(stderr, "Unable to open file '%s'\n", name);
+               exit(EXIT_FAILURE);
+            }
         }
 
-	/* Write a header, will update with size once record is complete */
-        if (!streamed) {
-	    init_wave_header(&header, channels, rate, samplebits);
-	    written = write(file, &header, sizeof(header));
-	    if (written != sizeof(header)) {
-		fprintf(stderr, "Error writing output file header: %s\n",
-			strerror(errno));
-		goto file_exit;
-	    }
+    /* Write a header, will update with size once record is complete */
+    if (!streamed) {
+        init_wave_header(&header, channels, rate, samplebits);
+        written = write(file, &header, sizeof(header));
+        if (written != sizeof(header)) {
+            fprintf(stderr, "Error writing output file header: %s\n",
+                    strerror(errno));
+            goto file_exit;
         }
+    }
 
-	memset(&codec, 0, sizeof(codec));
-	memset(&config, 0, sizeof(config));
-	codec.id = SND_AUDIOCODEC_PCM;
-	codec.ch_in = channels;
-	codec.ch_out = channels;
-	codec.sample_rate = rate;
-	if (!codec.sample_rate) {
-		fprintf(stderr, "invalid sample rate %d\n", rate);
-		goto file_exit;
-	}
-	codec.format = format;
-	if ((buffer_size != 0) && (frag != 0)) {
-		config.fragment_size = buffer_size/frag;
-		config.fragments = frag;
-	}
-	config.codec = &codec;
+    memset(&codec, 0, sizeof(codec));
+    memset(&config, 0, sizeof(config));
+    codec.id = SND_AUDIOCODEC_PCM;
+    codec.ch_in = channels;
+    codec.ch_out = channels;
+    codec.sample_rate = rate;
+    if (!codec.sample_rate) {
+        fprintf(stderr, "invalid sample rate %d\n", rate);
+        goto file_exit;
+    }
+    codec.format = format;
+    if ((buffer_size != 0) && (frag != 0)) {
+        config.fragment_size = buffer_size/frag;
+        config.fragments = frag;
+    }
+    config.codec = &codec;
 
-	mixer = mixer_open(card);
-	if (!mixer) {
-		printf("Failed to open mixer\n");
-		goto file_exit;
-	}
+    mixer = mixer_open(card);
+    if (!mixer) {
+        printf("Failed to open mixer\n");
+        goto file_exit;
+    }
 
-	/* set device/audio_intf media config mixer control */
-	if (set_agm_device_media_config(mixer, channels, rate, samplebits, intf_name)) {
-		printf("Failed to set device media config\n");
-		goto mixer_exit;
-	}
+    /* set device/audio_intf media config mixer control */
+    if (set_agm_device_media_config(mixer, dev_config->ch, dev_config->rate,
+                                    dev_config->bits, intf_name)) {
+        printf("Failed to set device media config\n");
+        goto mixer_exit;
+    }
 
-	/* set audio interface metadata mixer control */
-	if (set_agm_audio_intf_metadata(mixer, intf_name, 0, CAPTURE, rate, samplebits, PCM_RECORD)) {
-		printf("Failed to set device metadata\n");
-		goto mixer_exit;
-	}
+    /* set audio interface metadata mixer control */
+    if (set_agm_audio_intf_metadata(mixer, intf_name, device_kv, CAPTURE,
+                                    dev_config->rate, dev_config->bits, stream_kv)) {
+        printf("Failed to set device metadata\n");
+        goto mixer_exit;
+    }
 
-	/* set audio interface metadata mixer control */
+    /* set audio interface metadata mixer control */
         /* Change pcm_record to compress_record */
-	if (set_agm_stream_metadata(mixer, device, PCM_RECORD, CAPTURE, STREAM_COMPRESS, NULL)) {
-		printf("Failed to set stream metadata\n");
-		goto mixer_exit;
-	}
+    if (set_agm_capture_stream_metadata(mixer, device, stream_kv, CAPTURE, STREAM_COMPRESS,
+                                        instance_kv)) {
+        printf("Failed to set pcm metadata\n");
+        goto mixer_exit;
+    }
 
-	/* Note:  No common metadata as of now*/
+    if (devicepp_kv != 0) {
+        if (set_agm_streamdevice_metadata(mixer, device, stream_kv, CAPTURE, STREAM_COMPRESS,
+                                intf_name, devicepp_kv)) {
+            printf("Failed to set pcm metadata\n");
+            goto mixer_exit;
+        }
+    }
 
-	/* connect stream to audio intf */
-	if (connect_agm_audio_intf_to_stream(mixer, device, intf_name, STREAM_COMPRESS, true)) {
-		printf("Failed to connect stream to audio interface\n");
-		goto mixer_exit;
-	}
+    ret = agm_mixer_get_miid (mixer, device, intf_name, STREAM_COMPRESS, TAG_STREAM_MFC, &miid);
+    if (ret) {
+        printf("MFC not present for this graph");
+    } else {
+        if (configure_mfc(mixer, device, intf_name, TAG_STREAM_MFC,
+                     STREAM_COMPRESS, rate, channels, pcm_format_to_bits(format), miid)) {
+            printf("Failed to configure pspd mfc\n");
+            goto mixer_exit;
+        }
+    }
 
-	compress = compress_open(card, device, COMPRESS_OUT, &config);
-	if (!compress || !is_compress_ready(compress)) {
-		fprintf(stderr, "Unable to open Compress device %d:%d\n",
-			card, device);
-		fprintf(stderr, "ERR: %s\n", compress_get_error(compress));
-		goto mixer_exit;
-	};
+    /* Note:  No common metadata as of now*/
 
-	if (verbose)
-		fprintf(finfo, "%s: Opened compress device\n", __func__);
+    /* connect stream to audio intf */
+    if (connect_agm_audio_intf_to_stream(mixer, device, intf_name, STREAM_COMPRESS, true)) {
+        printf("Failed to connect stream to audio interface\n");
+        goto mixer_exit;
+    }
 
-	size = config.fragment_size;
-	buffer = malloc(size * config.fragments);
-	if (!buffer) {
-		fprintf(stderr, "Unable to allocate %d bytes\n", size);
-		goto comp_exit;
-	}
+    compress = compress_open(card, device, COMPRESS_OUT, &config);
+    if (!compress || !is_compress_ready(compress)) {
+        fprintf(stderr, "Unable to open Compress device %d:%d\n",
+            card, device);
+        fprintf(stderr, "ERR: %s\n", compress_get_error(compress));
+        goto mixer_exit;
+    };
 
-	fprintf(finfo, "Recording file %s On Card %u device %u, with buffer of %lu bytes\n",
-	       name, card, device, buffer_size);
-	fprintf(finfo, "Codec %u Format %u Channels %u, %u Hz\n",
-	       codec.id, codec.format, codec.ch_out, rate);
+    if (verbose)
+        fprintf(finfo, "%s: Opened compress device\n", __func__);
 
-	compress_start(compress);
+    size = config.fragment_size;
+    buffer = malloc(size * config.fragments);
+    if (!buffer) {
+        fprintf(stderr, "Unable to allocate %d bytes\n", size);
+        goto comp_exit;
+    }
 
-	if (verbose)
-		fprintf(finfo, "%s: Capturing audio NOW!!!\n", __func__);
+    fprintf(finfo, "Recording file %s On Card %u device %u, with buffer of %lu bytes\n",
+           name, card, device, buffer_size);
+    fprintf(finfo, "Codec %u Format %u Channels %u, %u Hz\n",
+           codec.id, codec.format, codec.ch_out, rate);
 
-	do {
-		read = compress_read(compress, buffer, size);
-		if (read < 0) {
-			fprintf(stderr, "Error reading sample\n");
-			fprintf(stderr, "ERR: %s\n", compress_get_error(compress));
-			goto buf_exit;
-		}
-		if ((unsigned int)read != size) {
-			fprintf(stderr, "We read %d, DSP sent %d\n",
-				size, read);
-		}
+    compress_start(compress);
 
-		if (read > 0) {
-			total_read += read;
+    if (verbose)
+        fprintf(finfo, "%s: Capturing audio NOW!!!\n", __func__);
 
-			written = write(file, buffer, read);
-			if (written != (size_t)read) {
-				fprintf(stderr, "Error writing output file: %s\n",
-					strerror(errno));
-				goto buf_exit;
-			}
-			if (verbose) {
-				print_time(compress);
-				fprintf(finfo, "%s: read %d\n", __func__, read);
-			}
-		}
-	} while (!length || total_read < length);
+    do {
+        read = compress_read(compress, buffer, size);
+        if (read < 0) {
+            fprintf(stderr, "Error reading sample\n");
+            fprintf(stderr, "ERR: %s\n", compress_get_error(compress));
+            goto buf_exit;
+        }
+        if ((unsigned int)read != size) {
+            fprintf(stderr, "We read %d, DSP sent %d\n",
+                size, read);
+        }
 
-	ret = compress_stop(compress);
-	if (ret < 0) {
-		fprintf(stderr, "Error closing stream\n");
-		fprintf(stderr, "ERR: %s\n", compress_get_error(compress));
-	}
+        if (read > 0) {
+            total_read += read;
 
-	ret = finish_record();
-	if (ret < 0) {
-		fprintf(stderr, "Failed to finish header: %s\n", strerror(ret));
-		goto buf_exit;
-	}
+            written = write(file, buffer, read);
+            if (written != (size_t)read) {
+                fprintf(stderr, "Error writing output file: %s\n",
+                    strerror(errno));
+                goto buf_exit;
+            }
+            if (verbose) {
+                print_time(compress);
+                fprintf(finfo, "%s: read %d\n", __func__, read);
+            }
+        }
+    } while (!length || total_read < length);
 
-	if (verbose)
-		fprintf(finfo, "%s: exit success\n", __func__);
+    ret = compress_stop(compress);
+    if (ret < 0) {
+        fprintf(stderr, "Error closing stream\n");
+        fprintf(stderr, "ERR: %s\n", compress_get_error(compress));
+    }
 
-	free(buffer);
-	close(file);
-	file = 0;
+    ret = finish_record();
+    if (ret < 0) {
+        fprintf(stderr, "Failed to finish header: %s\n", strerror(ret));
+        goto buf_exit;
+    }
 
-	compress_close(compress);
+    if (verbose)
+        fprintf(finfo, "%s: exit success\n", __func__);
 
-	return;
+    free(buffer);
+    close(file);
+    file = 0;
+
+    compress_close(compress);
+
+    return;
 buf_exit:
-	free(buffer);
+    free(buffer);
 comp_exit:
-	compress_close(compress);
-	connect_agm_audio_intf_to_stream(mixer, device, intf_name, STREAM_COMPRESS, false);
+    compress_close(compress);
+    connect_agm_audio_intf_to_stream(mixer, device, intf_name, STREAM_COMPRESS, false);
 mixer_exit:
-	mixer_close(mixer);
+    mixer_close(mixer);
 file_exit:
-	close(file);
+    close(file);
 
-	if (verbose)
-		fprintf(finfo, "%s: exit failure\n", __func__);
+    if (verbose)
+        fprintf(finfo, "%s: exit failure\n", __func__);
 
-	exit(EXIT_FAILURE);
+    exit(EXIT_FAILURE);
 }
 
 static void sig_handler(int signum __attribute__ ((unused)))
 {
-	finish_record();
+    finish_record();
 
-	if (file)
-		close(file);
+    if (file)
+        close(file);
 
-	_exit(EXIT_FAILURE);
+    _exit(EXIT_FAILURE);
 }
 
 int main(int argc, char **argv)
 {
-	char *file;
-	unsigned long buffer_size = 0;
-	int c;
-	unsigned int card = 0, device = 0, frag = 0, length = 0;
-	unsigned int rate = DEFAULT_RATE, channels = DEFAULT_CHANNELS;
-	unsigned int format = DEFAULT_FORMAT;
-	unsigned int audio_intf;
+    char *file = NULL;
+    unsigned long buffer_size = 0;
+    unsigned int card = 0, device = 0, frag = 0, length = 0;
+    unsigned int rate = DEFAULT_RATE, channels = DEFAULT_CHANNELS;
+    unsigned int bits = 16;
+    unsigned int format = DEFAULT_FORMAT;
+    char* intf_name;
+    int ret = 0;
+    unsigned int devicepp_kv = DEVICEPP_TX_AUDIO_FLUENCE_SMECNS;
+    unsigned int stream_kv = 0;
+    unsigned int instance_kv = INSTANCE_1;
+    struct device_config config;
+    unsigned int device_kv = 0;
 
-	if (signal(SIGINT, sig_handler) == SIG_ERR) {
-		fprintf(stderr, "Error registering signal handler\n");
-		exit(EXIT_FAILURE);
-	}
+    if (signal(SIGINT, sig_handler) == SIG_ERR) {
+        fprintf(stderr, "Error registering signal handler\n");
+        exit(EXIT_FAILURE);
+    }
 
-	if (argc < 1)
-		usage();
+    if (argc < 3)
+        usage();
 
-	verbose = 0;
-	while ((c = getopt(argc, argv, "hvl:R:C:F:b:f:c:d:i:")) != -1) {
-		switch (c) {
-		case 'h':
-			usage();
-			break;
-		case 'b':
-			buffer_size = strtol(optarg, NULL, 0);
-			break;
-		case 'f':
-			frag = strtol(optarg, NULL, 10);
-			break;
-		case 'c':
-			card = strtol(optarg, NULL, 10);
-			break;
-		case 'd':
-			device = strtol(optarg, NULL, 10);
-			break;
-		case 'v':
-			verbose = 1;
-			break;
-		case 'l':
-			length = strtol(optarg, NULL, 10);
-			break;
-		case 'R':
-			rate = strtol(optarg, NULL, 10);
-			break;
-		case 'C':
-			channels = strtol(optarg, NULL, 10);
-			break;
-		case 'F':
-			if (strcmp(optarg, "S16_LE") == 0) {
-				format = SNDRV_PCM_FORMAT_S16_LE;
-			} else if (strcmp(optarg, "S32_LE") == 0) {
-				format = SNDRV_PCM_FORMAT_S32_LE;
-			} else {
-				fprintf(stderr, "Unrecognised format: %s\n",
-					optarg);
-				usage();
-			}
-			break;
-                case 'i':
-                        audio_intf = strtol(optarg, NULL, 10);
-			break;
-		default:
-			exit(EXIT_FAILURE);
-		}
-	}
-	if (optind >= argc) {
-		file = NULL;
-		finfo = fopen("/dev/null", "w");
-		streamed = true;
-	} else {
-		file = argv[optind];
-		finfo = stdout;
-		streamed = false;
-	}
+    verbose = 0;
 
-        if (audio_intf >= sizeof(audio_interface_name)/sizeof(char *)) {
-                printf("Invalid audio interface index denoted by -i\n");
-		exit(EXIT_FAILURE);
+    /* parse command line arguments */
+    argv += 2;
+    while (*argv) {
+        if (strcmp(*argv, "-d") == 0) {
+            argv++;
+            if (*argv)
+                device = atoi(*argv);
+        } else if (strcmp(*argv, "-c") == 0) {
+            argv++;
+            if (*argv)
+                channels = atoi(*argv);
+        } else if (strcmp(*argv, "-r") == 0) {
+            argv++;
+            if (*argv)
+                rate = atoi(*argv);
+        } else if (strcmp(*argv, "-b") == 0) {
+            argv++;
+            if (*argv)
+                bits = atoi(*argv);
+        } else if (strcmp(*argv, "-D") == 0) {
+            argv++;
+            if (*argv)
+                card = atoi(*argv);
+        } else if (strcmp(*argv, "-l") == 0) {
+            argv++;
+            if (*argv)
+                length = atoi(*argv);
+        } else if (strcmp(*argv, "-i") == 0) {
+            argv++;
+            if (*argv)
+                intf_name = *argv;
+        } else if (strcmp(*argv, "-dkv") == 0) {
+            argv++;
+            if (*argv)
+                device_kv = convert_char_to_hex(*argv);
+        } else if (strcmp(*argv, "-skv") == 0) {
+            argv++;
+            if (*argv)
+                stream_kv = convert_char_to_hex(*argv);
+        } else if (strcmp(*argv, "-ikv") == 0) {
+            argv++;
+            if (*argv)
+                instance_kv = atoi(*argv);
+        } else if (strcmp(*argv, "-dppkv") == 0) {
+            argv++;
+            if (*argv)
+                devicepp_kv = convert_char_to_hex(*argv);
+        } else if (strcmp(*argv, "-buf") == 0) {
+            argv++;
+            if (*argv)
+                 buffer_size = atoi(*argv);
+        } else if (strcmp(*argv, "-f") == 0) {
+            argv++;
+            if (*argv)
+                frag = atoi(*argv);
+        } else if (strcmp(*argv, "-v") == 0) {
+            argv++;
+            if (*argv)
+                verbose = atoi(*argv);
+        } else if (strcmp(*argv, "-help") == 0) {
+            usage();
         }
+        if (*argv)
+            argv++;
+    }
 
-	capture_samples(file, card, device, buffer_size, frag, length,
-			rate, channels, format, audio_intf);
+    if (intf_name == NULL) {
+        printf("Invalid audio interface index denoted by -i\n");
+        exit(EXIT_FAILURE);
+    }
 
-	fprintf(finfo, "Finish capturing... Close Normally\n");
+    ret = get_device_media_config(BACKEND_CONF_FILE, intf_name, &config);
+    if (ret) {
+        printf("Invalid input, entry not found for %s\n", intf_name);
+        fclose(file);
+        return ret;
+    }
 
-	exit(EXIT_SUCCESS);
+    switch (bits) {
+    case 32:
+        format = SNDRV_PCM_FORMAT_S32_LE;
+        break;
+    default:
+        format = SNDRV_PCM_FORMAT_S16_LE;
+        break;
+    }
+    capture_samples(file, card, device, buffer_size, frag, length,
+            rate, channels, format, &config, stream_kv, device_kv, instance_kv,
+             devicepp_kv);
+
+    fprintf(finfo, "Finish capturing... Close Normally\n");
+
+    exit(EXIT_SUCCESS);
 }
 
diff --git a/plugins/tinyalsa/test/agmcompressplay.c b/plugins/tinyalsa/test/agmcompressplay.c
index 646645b..0e5018a 100644
--- a/plugins/tinyalsa/test/agmcompressplay.c
+++ b/plugins/tinyalsa/test/agmcompressplay.c
@@ -77,76 +77,79 @@
 #define MP3_SYNC 0xe0ff
 
 const int mp3_sample_rates[3][3] = {
-	{44100, 48000, 32000},        /* MPEG-1 */
-	{22050, 24000, 16000},        /* MPEG-2 */
-	{11025, 12000,  8000},        /* MPEG-2.5 */
+    {44100, 48000, 32000},        /* MPEG-1 */
+    {22050, 24000, 16000},        /* MPEG-2 */
+    {11025, 12000,  8000},        /* MPEG-2.5 */
 };
 
 const int mp3_bit_rates[3][3][15] = {
-	{
-		/* MPEG-1 */
-		{  0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448}, /* Layer 1 */
-		{  0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384}, /* Layer 2 */
-		{  0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320}, /* Layer 3 */
-	},
-	{
-		/* MPEG-2 */
-		{  0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256}, /* Layer 1 */
-		{  0,  8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}, /* Layer 2 */
-		{  0,  8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}, /* Layer 3 */
-	},
-	{
-		/* MPEG-2.5 */
-		{  0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256}, /* Layer 1 */
-		{  0,  8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}, /* Layer 2 */
-		{  0,  8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}, /* Layer 3 */
-	},
+    {
+        /* MPEG-1 */
+        {  0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448}, /* Layer 1 */
+        {  0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384}, /* Layer 2 */
+        {  0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320}, /* Layer 3 */
+    },
+    {
+        /* MPEG-2 */
+        {  0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256}, /* Layer 1 */
+        {  0,  8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}, /* Layer 2 */
+        {  0,  8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}, /* Layer 3 */
+    },
+    {
+        /* MPEG-2.5 */
+        {  0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256}, /* Layer 1 */
+        {  0,  8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}, /* Layer 2 */
+        {  0,  8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}, /* Layer 3 */
+    },
 };
 
 enum mpeg_version {
-	MPEG1  = 0,
-	MPEG2  = 1,
-	MPEG25 = 2
+    MPEG1  = 0,
+    MPEG2  = 1,
+    MPEG25 = 2
 };
 
 enum mp3_stereo_mode {
-	STEREO = 0x00,
-	JOINT = 0x01,
-	DUAL = 0x02,
-	MONO = 0x03
+    STEREO = 0x00,
+    JOINT = 0x01,
+    DUAL = 0x02,
+    MONO = 0x03
 };
 
 static int verbose;
 
 static void usage(void)
 {
-	fprintf(stderr, "usage: cplay [OPTIONS] filename\n"
-		"-c\tcard number\n"
-		"-d\tdevice node\n"
-		"-b\tbuffer size\n"
-		"-f\tfragments\n\n"
-                "-i\taudio_intf_id\n"
-		"-v\tverbose mode\n"
-		"-h\tPrints this help list\n\n"
-		"-t\tcodec type\n\n"
-			"1 : mp3"
-			"2 : aac"
-		"-p\tpause/resume with 2 secs sleep\n\n"
-		"Example:\n"
-		"\tagmcompressplay -c 1 -d 2 test.mp3\n"
-		"\tagmcompressplay -f 5 test.mp3\n");
+    fprintf(stderr, "usage: cplay [OPTIONS] filename\n"
+        "-D\tcard number\n"
+        "-d\tdevice node\n"
+        "-b\tbuffer size\n"
+        "-f\tfragments\n\n"
+        "-v\tverbose mode\n"
+        "-help\tPrints this help list\n\n"
+        "-t\tcodec type\n\n"
+            "1 : mp3"
+            "2 : aac"
+        "-p\tpause/resume with 2 secs sleep\n\n"
+        " [-num_intf num of interfaces followed by interface name]\n"
+        " [-i intf_name] : Can be multiple if num_intf is more than 1\n"
+        " [-dkv device_kv] : Can be multiple if num_intf is more than 1\n"
+        " [-dppkv deviceppkv] : Assign 0 if no device pp in the graph\n"
+        " [-ikv instance_kv] :  Assign 0 if no instance kv in the graph\n"
+        " [-skv stream_kv]");
 
-	exit(EXIT_FAILURE);
+    exit(EXIT_FAILURE);
 }
 
-void play_samples(char *name, unsigned int card, unsigned int device,
-		unsigned long buffer_size, unsigned int frag, unsigned int audio_format,
-        int pause, struct device_config *dev_config);
+void play_samples(char *name, unsigned int card, unsigned int device, unsigned int *device_kv,
+                  unsigned int stream_kv, unsigned int instance_kv, unsigned int *devicepp_kv,
+                  unsigned long buffer_size, unsigned int frag, unsigned int format,
+                  int pause, char **intf_name, int intf_num);
 
 struct mp3_header {
-	uint16_t sync;
-	uint8_t format1;
-	uint8_t format2;
+    uint16_t sync;
+    uint8_t format1;
+    uint8_t format2;
 };
 
 #define ADTS_SYNC 0xF0FF
@@ -154,356 +157,471 @@
 #define AAC_ADTS_FORMAT 2
 
 struct adts_header {
-	uint32_t sync;
-	uint8_t format1;
-	uint8_t format2;
-	uint8_t format3;
+    uint32_t sync;
+    uint8_t format1;
+    uint8_t format2;
+    uint8_t format3;
 };
 
 uint aac_sample_rates[] = {96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350, 48000, 48000, 48000};
 
 int parse_aac_header(struct adts_header *header, unsigned int *num_channels,
-		unsigned int *sample_rate, unsigned int *protection_absent)
+        unsigned int *sample_rate, unsigned int *protection_absent)
 {
-	int profile, sample_rate_idx;
+    int profile, sample_rate_idx;
 
-	/* check sync bits */
-	if ((header->sync & 0xF0FF) != ADTS_SYNC) {
-		fprintf(stderr, "Error: Can't find sync word: 0x%X\n", header->sync);
-		return -1;
-	}
-	*protection_absent = (header->sync >> 8) & 0x01;
-	profile = ((header->sync >> 22) & 0x03) - 1;
-	sample_rate_idx = ((header->sync >> 18) & 0x0F);
-//	channel_idx = ((header->format1 >> 7) & 0x07);
-//	frame_length  = ((header->format1 >> 14) & 0x1FFF);
+    /* check sync bits */
+    if ((header->sync & 0xF0FF) != ADTS_SYNC) {
+        fprintf(stderr, "Error: Can't find sync word: 0x%X\n", header->sync);
+        return -1;
+    }
+    *protection_absent = (header->sync >> 8) & 0x01;
+    profile = ((header->sync >> 22) & 0x03) - 1;
+    sample_rate_idx = ((header->sync >> 18) & 0x0F);
+//  channel_idx = ((header->format1 >> 7) & 0x07);
+//  frame_length  = ((header->format1 >> 14) & 0x1FFF);
 
-	*num_channels = 2;
-	*sample_rate = aac_sample_rates[sample_rate_idx];
-//	 *size = frame_length - ((protection_absent == 1)? 7: 9));
+    *num_channels = 2;
+    *sample_rate = aac_sample_rates[sample_rate_idx];
+//   *size = frame_length - ((protection_absent == 1)? 7: 9));
 
-	if (verbose)
-		printf("%s: exit sr %d\n", __func__, *sample_rate);
-	return 0;
+    if (verbose)
+        printf("%s: exit sr %d\n", __func__, *sample_rate);
+    return 0;
 }
 
 int parse_mp3_header(struct mp3_header *header, unsigned int *num_channels,
-		unsigned int *sample_rate, unsigned int *bit_rate)
+        unsigned int *sample_rate, unsigned int *bit_rate)
 {
-	int ver_idx, mp3_version, layer, bit_rate_idx, sample_rate_idx, channel_idx;
+    int ver_idx, mp3_version, layer, bit_rate_idx, sample_rate_idx, channel_idx;
 
-	/* check sync bits */
-	if ((header->sync & MP3_SYNC) != MP3_SYNC) {
-		fprintf(stderr, "Error: Can't find sync word\n");
-		return -1;
-	}
-	ver_idx = (header->sync >> 11) & 0x03;
-	mp3_version = ver_idx == 0 ? MPEG25 : ((ver_idx & 0x1) ? MPEG1 : MPEG2);
-	layer = 4 - ((header->sync >> 9) & 0x03);
-	bit_rate_idx = ((header->format1 >> 4) & 0x0f);
-	sample_rate_idx = ((header->format1 >> 2) & 0x03);
-	channel_idx = ((header->format2 >> 6) & 0x03);
+    /* check sync bits */
+    if ((header->sync & MP3_SYNC) != MP3_SYNC) {
+        fprintf(stderr, "Error: Can't find sync word\n");
+        return -1;
+    }
+    ver_idx = (header->sync >> 11) & 0x03;
+    mp3_version = ver_idx == 0 ? MPEG25 : ((ver_idx & 0x1) ? MPEG1 : MPEG2);
+    layer = 4 - ((header->sync >> 9) & 0x03);
+    bit_rate_idx = ((header->format1 >> 4) & 0x0f);
+    sample_rate_idx = ((header->format1 >> 2) & 0x03);
+    channel_idx = ((header->format2 >> 6) & 0x03);
 
-	if (sample_rate_idx == 3 || layer == 4 || bit_rate_idx == 15) {
-		fprintf(stderr, "Error: Can't find valid header\n");
-		return -1;
-	}
-	*num_channels = (channel_idx == MONO ? 1 : 2);
-	*sample_rate = mp3_sample_rates[mp3_version][sample_rate_idx];
-	*bit_rate = (mp3_bit_rates[mp3_version][layer - 1][bit_rate_idx]) * 1000;
-	if (verbose)
-		printf("%s: exit\n", __func__);
-	return 0;
+    if (sample_rate_idx == 3 || layer == 4 || bit_rate_idx == 15) {
+        fprintf(stderr, "Error: Can't find valid header\n");
+        return -1;
+    }
+    *num_channels = (channel_idx == MONO ? 1 : 2);
+    *sample_rate = mp3_sample_rates[mp3_version][sample_rate_idx];
+    *bit_rate = (mp3_bit_rates[mp3_version][layer - 1][bit_rate_idx]) * 1000;
+    if (verbose)
+        printf("%s: exit\n", __func__);
+    return 0;
 }
 
 int check_codec_format_supported(unsigned int card, unsigned int device, struct snd_codec *codec)
 {
-	if (is_codec_supported(card, device, COMPRESS_IN, codec) == false) {
-		fprintf(stderr, "Error: This codec or format is not supported by DSP\n");
-		return -1;
-	}
-	return 0;
+    if (is_codec_supported(card, device, COMPRESS_IN, codec) == false) {
+        fprintf(stderr, "Error: This codec or format is not supported by DSP\n");
+        return -1;
+    }
+    return 0;
 }
 
 static int print_time(struct compress *compress)
 {
-	unsigned int avail;
-	struct timespec tstamp;
+    unsigned int avail;
+    struct timespec tstamp;
 
-	if (compress_get_hpointer(compress, &avail, &tstamp) != 0) {
-		fprintf(stderr, "Error querying timestamp\n");
-		fprintf(stderr, "ERR: %s\n", compress_get_error(compress));
-		return -1;
-	} else
-		fprintf(stderr, "DSP played %ld.%ld\n", tstamp.tv_sec, tstamp.tv_nsec*1000);
-	return 0;
+    if (compress_get_hpointer(compress, &avail, &tstamp) != 0) {
+        fprintf(stderr, "Error querying timestamp\n");
+        fprintf(stderr, "ERR: %s\n", compress_get_error(compress));
+        return -1;
+    } else
+        fprintf(stderr, "DSP played %ld.%ld\n", tstamp.tv_sec, tstamp.tv_nsec*1000);
+    return 0;
 }
 
 int main(int argc, char **argv)
 {
-	char *file;
-	unsigned long buffer_size = 0;
-	char *intf_name = NULL;
-	struct device_config config;
-	int ret = 0;
-	unsigned int card = 0, device = 0, frag = 0, audio_format = 0, pause = 0;
+    char *file;
+    unsigned long buffer_size = 0;
+    char **intf_name = NULL;
+    int ret = 0, i = 0;
+    unsigned int card = 0, device = 0, frag = 0, audio_format = 0, pause = 0;
+    int intf_num = 1;
+    unsigned int *device_kv = 0;
+    unsigned int stream_kv = 0;
+    unsigned int instance_kv = INSTANCE_1;
+    unsigned int *devicepp_kv = NULL;
 
+    if (argc < 3) {
+        usage();
+        return 1;
+    }
 
-	if (argc < 2)
-		usage();
+    file = argv[1];
+    /* parse command line arguments */
+    argv += 2;
+    while (*argv) {
+        if (strcmp(*argv, "-d") == 0) {
+            argv++;
+            if (*argv)
+                device = atoi(*argv);
+        } else if (strcmp(*argv, "-t") == 0) {
+            argv++;
+            if (*argv)
+                audio_format = atoi(*argv);
+        } else if (strcmp(*argv, "-D") == 0) {
+            argv++;
+            if (*argv)
+                card = atoi(*argv);
+        } else if (strcmp(*argv, "-p") == 0) {
+            argv++;
+            if (*argv)
+                pause = atoi(*argv);
+        } else if (strcmp(*argv, "-f") == 0) {
+            argv++;
+            if (*argv)
+                frag = atoi(*argv);
+        } else if (strcmp(*argv, "-v") == 0) {
+            argv++;
+            if (*argv)
+                verbose = atoi(*argv);
+        } else if (strcmp(*argv, "-num_intf") == 0) {
+                      argv++;
+            if (*argv)
+                intf_num = atoi(*argv);
+        } else if (strcmp(*argv, "-i") == 0) {
+            intf_name = (char**) malloc(intf_num * sizeof(char*));
+            if (!intf_name) {
+                printf("invalid memory\n");
+            }
+            for (i = 0; i < intf_num ; i++){
+                argv++;
+                if (*argv)
+                    intf_name[i] = *argv;
+            }
+        } else if (strcmp(*argv, "-dkv") == 0) {
+            device_kv = (unsigned int *) malloc(intf_num * sizeof(unsigned int));
+            if (!device_kv) {
+                printf(" insufficient memory\n");
+            }
+            for (i = 0; i < intf_num ; i++) {
+                argv++;
+                if (*argv) {
+                    device_kv[i] = convert_char_to_hex(*argv);
+                }
+            }
+        } else if (strcmp(*argv, "-skv") == 0) {
+            argv++;
+            if (*argv)
+                stream_kv = convert_char_to_hex(*argv);
+        } else if (strcmp(*argv, "-ikv") == 0) {
+            argv++;
+            if (*argv) {
+                instance_kv = atoi(*argv);
+            }
+        } else if (strcmp(*argv, "-dppkv") == 0) {
+            devicepp_kv = (unsigned int *) malloc(intf_num * sizeof(unsigned int));
+            if (!devicepp_kv) {
+                printf(" insufficient memory\n");
+            }
+            for (i = 0; i < intf_num ; i++) {
+                devicepp_kv[i] = DEVICEPP_RX_AUDIO_MBDRC;
+            }
+            for (i = 0; i < intf_num ; i++)
+            {
+                argv++;
+                if(*argv) {
+                    devicepp_kv[i] = convert_char_to_hex(*argv);
+                }
+            }
+        } else if (strcmp(*argv, "-help") == 0) {
+            usage();
+        }
 
-	file = argv[1];
-	/* parse command line arguments */
-        argv += 2;
-	while (*argv) {
-		if (strcmp(*argv, "-d") == 0) {
-			argv++;
-			if (*argv)
-				device = atoi(*argv);
-		} else if (strcmp(*argv, "-t") == 0) {
-			argv++;
-			if (*argv)
-				audio_format = atoi(*argv);
-		} else if (strcmp(*argv, "-c") == 0) {
-			argv++;
-			if (*argv)
-				card = atoi(*argv);
-		} else if (strcmp(*argv, "-p") == 0) {
-			argv++;
-			if (*argv)
-				pause = atoi(*argv);
-		} else if (strcmp(*argv, "-i") == 0) {
-			argv++;
-			if (*argv)
-				intf_name = *argv;
-		}
-		if (*argv)
-			argv++;
-	}
+        if (*argv)
+            argv++;
+    }
 
-	if (intf_name == NULL)
-		return 1;
+    if (intf_name == NULL)
+        return 1;
 
-	ret = get_device_media_config(BACKEND_CONF_FILE, intf_name, &config);
-	if (ret) {
-		printf("Invalid input, entry not found for : %s\n", intf_name);
-		return ret;
-	}
+    play_samples(file, card, device, device_kv, stream_kv, instance_kv, devicepp_kv,
+                 buffer_size, frag, audio_format, pause, 
+                 intf_name, intf_num);
 
-	play_samples(file, card, device, buffer_size, frag, audio_format, pause, &config);
-
-	fprintf(stderr, "Finish Playing.... Close Normally\n");
-	exit(EXIT_SUCCESS);
+    fprintf(stderr, "Finish Playing.... Close Normally\n");
+    if (device_kv)
+        free(device_kv);
+    if (devicepp_kv)
+        free(devicepp_kv);
+    if (intf_name)
+        free(intf_name);
+    exit(EXIT_SUCCESS);
 }
 
-void play_samples(char *name, unsigned int card, unsigned int device,
-		unsigned long buffer_size, unsigned int frag, unsigned int format,
-        int pause, struct device_config *dev_config)
+void play_samples(char *name, unsigned int card, unsigned int device, unsigned int *device_kv,
+                  unsigned int stream_kv, unsigned int instance_kv, unsigned int *devicepp_kv,
+                  unsigned long buffer_size, unsigned int frag, unsigned int format,
+                  int pause, char **intf_name, int intf_num)
 {
-	struct compr_config config;
-	struct snd_codec codec;
-	struct compress *compress;
-	struct mp3_header header;
-	struct adts_header adts_header;
-	struct mixer *mixer;
-	FILE *file;
-	char *buffer;
-	int size, num_read, wrote;
-	unsigned int channels = 0, rate = 0, bits = 0;
-	char *intf_name = dev_config->name;
+    struct compr_config config;
+    struct snd_codec codec;
+    struct compress *compress;
+    struct mp3_header header;
+    struct adts_header adts_header;
+    struct mixer *mixer;
+    FILE *file;
+    char *buffer;
+    int num_read, wrote;
+    unsigned int channels = 0, rate = 0, bits = 0;
+    struct device_config *dev_config = (struct device_config *)malloc(intf_num*sizeof(struct device_config *));
+    struct group_config *grp_config = (struct group_config *)malloc(intf_num*sizeof(struct group_config *));
+    int size, index, ret = 0;
+    uint32_t miid = 0;
 
-	if (verbose)
-		printf("%s: entry\n", __func__);
-	file = fopen(name, "rb");
-	if (!file) {
-		fprintf(stderr, "Unable to open file '%s'\n", name);
-		exit(EXIT_FAILURE);
-	}
+    stream_kv = stream_kv ? stream_kv : COMPRESSED_OFFLOAD_PLAYBACK;
 
-	if (format == MP3_FORMAT) {
-		fread(&header, sizeof(header), 1, file);
+    if (verbose)
+        printf("%s: entry\n", __func__);
+    file = fopen(name, "rb");
+    if (!file) {
+        fprintf(stderr, "Unable to open file '%s'\n", name);
+        exit(EXIT_FAILURE);
+    }
 
-		if (parse_mp3_header(&header, &channels, &rate, &bits) == -1) {
-			fclose(file);
-			exit(EXIT_FAILURE);
-		}
+    if (format == MP3_FORMAT) {
+        fread(&header, sizeof(header), 1, file);
 
-		codec.id = SND_AUDIOCODEC_MP3;
+        if (parse_mp3_header(&header, &channels, &rate, &bits) == -1) {
+            fclose(file);
+            exit(EXIT_FAILURE);
+        }
+
+        codec.id = SND_AUDIOCODEC_MP3;
 #ifdef SND_COMPRESS_DEC_HDR
-	} else if (format == AAC_ADTS_FORMAT) {
-		uint16_t protection_absent, crc;
-		fread(&adts_header, sizeof(adts_header), 1, file);
-		if (parse_aac_header(&adts_header, &channels, &rate, (unsigned int*)&protection_absent) == -1) {
-			fclose(file);
-			exit(EXIT_FAILURE);
-		}
-		if (!protection_absent) {
-			fread(&crc, 2, 1, file);
-		}
-		codec.id = SND_AUDIOCODEC_AAC;
-		codec.format = SND_AUDIOSTREAMFORMAT_MP4ADTS;
-		bits = 16;
-		codec.options.aac_dec.audio_obj_type = 29;
-		codec.options.aac_dec.pce_bits_size = 0;
+    } else if (format == AAC_ADTS_FORMAT) {
+        uint16_t protection_absent, crc;
+        fread(&adts_header, sizeof(adts_header), 1, file);
+        if (parse_aac_header(&adts_header, &channels, &rate, (unsigned int*)&protection_absent) == -1) {
+            fclose(file);
+            exit(EXIT_FAILURE);
+        }
+        if (!protection_absent) {
+            fread(&crc, 2, 1, file);
+        }
+        codec.id = SND_AUDIOCODEC_AAC;
+        codec.format = SND_AUDIOSTREAMFORMAT_MP4ADTS;
+        bits = 16;
+        codec.options.aac_dec.audio_obj_type = 29;
+        codec.options.aac_dec.pce_bits_size = 0;
 #endif
-	} else {
-		printf("unknown format");
-	}
-	codec.ch_in = channels;
-	codec.ch_out = channels;
-	codec.sample_rate = rate;
-	if (!codec.sample_rate) {
-		fprintf(stderr, "invalid sample rate %d\n", rate);
-		fclose(file);
-		exit(EXIT_FAILURE);
-	}
-	codec.bit_rate = bits;
-	codec.rate_control = 0;
-	codec.profile = 0;
-	codec.level = 0;
-	codec.ch_mode = 0;
-	codec.format = 0;
-	if ((buffer_size != 0) && (frag != 0)) {
-		config.fragment_size = buffer_size/frag;
-		config.fragments = frag;
-	} else {
-		/* use driver defaults */
-		config.fragment_size = 0;
-		config.fragments = 0;
-	}
-	config.codec = &codec;
+    } else {
+        printf("unknown format");
+    }
+    codec.ch_in = channels;
+    codec.ch_out = channels;
+    codec.sample_rate = rate;
+    if (!codec.sample_rate) {
+        fprintf(stderr, "invalid sample rate %d\n", rate);
+        fclose(file);
+        exit(EXIT_FAILURE);
+    }
+    codec.bit_rate = bits;
+    codec.rate_control = 0;
+    codec.profile = 0;
+    codec.level = 0;
+    codec.ch_mode = 0;
+    codec.format = 0;
+    if ((buffer_size != 0) && (frag != 0)) {
+        config.fragment_size = buffer_size/frag;
+        config.fragments = frag;
+    } else {
+        /* use driver defaults */
+        config.fragment_size = 0;
+        config.fragments = 0;
+    }
+    config.codec = &codec;
 
-	mixer = mixer_open(card);
-	if (!mixer) {
-		printf("Failed to open mixer\n");
-		goto FILE_EXIT;
-	}
+    mixer = mixer_open(card);
+    if (!mixer) {
+        printf("Failed to open mixer\n");
+        goto FILE_EXIT;
+    }
+    for (index = 0; index < intf_num; index++) {
+        ret = get_device_media_config(BACKEND_CONF_FILE, intf_name[index], &dev_config[index]);
+        if (ret) {
+            printf("Invalid input, entry not found for : %s\n", intf_name[index]);
+            fclose(file);
+        }
+        printf("Backend %s rate ch bit : %d, %d, %d\n", intf_name[index],
+            dev_config[index].rate, dev_config[index].ch, dev_config[index].bits);
 
-	/* set device/audio_intf media config mixer control */
-	if (set_agm_device_media_config(mixer, dev_config->ch, dev_config->rate,
-                                    dev_config->bits, intf_name)) {
-		printf("Failed to set device media config\n");
-		goto MIXER_EXIT;
-	}
+        /* set device/audio_intf media config mixer control */
+        if (set_agm_device_media_config(mixer, dev_config[index].ch, dev_config[index].rate,
+                                    dev_config[index].bits, intf_name[index])) {
+            printf("Failed to set device media config\n");
+            goto MIXER_EXIT;
+        }
 
-	/* set audio interface metadata mixer control */
-	if (set_agm_audio_intf_metadata(mixer, intf_name, 0, PLAYBACK,
-                                    dev_config->rate, dev_config->bits, COMPRESSED_OFFLOAD_PLAYBACK)) {
-		printf("Failed to set device metadata\n");
-		goto MIXER_EXIT;
-	}
+        /* set audio interface metadata mixer control */
+        if (set_agm_audio_intf_metadata(mixer, intf_name[index], device_kv[index], PLAYBACK,
+                                    dev_config[index].rate, dev_config[index].bits, stream_kv)) {
+            printf("Failed to set device metadata\n");
+            goto MIXER_EXIT;
+        }
+    }
 
-	/* set audio interface metadata mixer control */
-	if (set_agm_stream_metadata(mixer, device, COMPRESSED_OFFLOAD_PLAYBACK, PLAYBACK, STREAM_COMPRESS, NULL)) {
-		printf("Failed to set stream metadata\n");
-		goto MIXER_EXIT;
-	}
+    /* set audio interface metadata mixer control */
+    if (set_agm_stream_metadata(mixer, device, stream_kv, PLAYBACK, STREAM_COMPRESS,
+                                instance_kv)) {
+        printf("Failed to set stream metadata\n");
+        goto MIXER_EXIT;
+    }
 
-	/* Note:  No common metadata as of now*/
+    /* Note:  No common metadata as of now*/
+    for (index = 0; index < intf_num; index++) {
+         if (devicepp_kv[index] != 0) {
+             if (set_agm_streamdevice_metadata(mixer, device, stream_kv, PLAYBACK, STREAM_COMPRESS, intf_name[index],
+                                               devicepp_kv[index])) {
+                 printf("Failed to set pcm metadata\n");
+                 goto MIXER_EXIT;
+             }
+         }
 
-	/* connect stream to audio intf */
-	if (connect_agm_audio_intf_to_stream(mixer, device, intf_name, STREAM_COMPRESS, true)) {
-		printf("Failed to connect stream to audio interface\n");
-		goto MIXER_EXIT;
-	}
+        /* connect stream to audio intf */
+        if (connect_agm_audio_intf_to_stream(mixer, device, intf_name[index], STREAM_COMPRESS, true)) {
+            printf("Failed to connect pcm to audio interface\n");
+            goto MIXER_EXIT;
+        }
 
-	if (configure_mfc(mixer, device, intf_name, PER_STREAM_PER_DEVICE_MFC,
-			STREAM_COMPRESS, dev_config->rate, dev_config->ch,
-			dev_config->bits)) {
-		printf("Failed to configure pspd mfc\n");
-		goto MIXER_EXIT;
-	}
+        ret = agm_mixer_get_miid (mixer, device, intf_name[index], STREAM_PCM, PER_STREAM_PER_DEVICE_MFC, &miid);
+        if (ret) {
+            printf("MFC not present for this graph\n");
+        } else {
+            if (configure_mfc(mixer, device, intf_name[index], PER_STREAM_PER_DEVICE_MFC,
+                           STREAM_COMPRESS, dev_config[index].rate, dev_config[index].ch,
+                           dev_config[index].bits, miid)) {
+                printf("Failed to configure pspd mfc\n");
+                goto MIXER_EXIT;
+            }
+        }
 
-	compress = compress_open(card, device, COMPRESS_IN, &config);
-	if (!compress || !is_compress_ready(compress)) {
-		fprintf(stderr, "Unable to open Compress device %d:%d\n",
-				card, device);
-		fprintf(stderr, "ERR: %s\n", compress_get_error(compress));
-		goto MIXER_EXIT;
-	};
-	if (verbose)
-		printf("%s: Opened compress device\n", __func__);
-	size = config.fragment_size;
-	buffer = malloc(size * config.fragments);
-	if (!buffer) {
-		fprintf(stderr, "Unable to allocate %d bytes\n", size);
-		goto COMP_EXIT;
-	}
+        if (strstr(intf_name[index], "VIRT-")) {
+            if (get_group_device_info(BACKEND_CONF_FILE, intf_name[index], &grp_config[index]))
+                goto MIXER_EXIT;
 
-	/* we will write frag fragment_size and then start */
-	num_read = fread(buffer, 1, size * config.fragments, file);
-	if (num_read > 0) {
-		if (verbose)
-			printf("%s: Doing first buffer write of %d\n", __func__, num_read);
-		wrote = compress_write(compress, buffer, num_read);
-		if (wrote < 0) {
-			fprintf(stderr, "Error %d playing sample\n", wrote);
-			fprintf(stderr, "ERR: %s\n", compress_get_error(compress));
-			goto BUF_EXIT;
-		}
-		if (wrote != num_read) {
-			/* TODO: Buufer pointer needs to be set here */
-			fprintf(stderr, "We wrote %d, DSP accepted %d\n", num_read, wrote);
-		}
-	}
-	printf("Playing file %s On Card %u device %u, with buffer of %lu bytes\n",
-			name, card, device, buffer_size);
-	printf("Format %u Channels %u, %u Hz, Bit Rate %d\n",
-			SND_AUDIOCODEC_MP3, channels, rate, bits);
+            if (set_agm_group_device_config(mixer, intf_name[index], &grp_config[index])) {
+                printf("Failed to set grp device config\n");
+                goto MIXER_EXIT;
+            }
+        }
+    }
 
-	compress_start(compress);
-	if (verbose)
-		printf("%s: You should hear audio NOW!!!\n", __func__);
 
-	do {
-		num_read = fread(buffer, 1, size, file);
-		if (num_read > 0) {
-			wrote = compress_write(compress, buffer, num_read);
-			if (wrote < 0) {
-				fprintf(stderr, "Error playing sample\n");
-				fprintf(stderr, "ERR: %s\n", compress_get_error(compress));
-				goto BUF_EXIT;
-			}
-			if (wrote != num_read) {
-				/* TODO: Buffer pointer needs to be set here */
-				fprintf(stderr, "We wrote %d, DSP accepted %d\n", num_read, wrote);
-			}
-			if (verbose) {
-				print_time(compress);
-				printf("%s: wrote %d\n", __func__, wrote);
-			}
-			if (pause) {
-				printf("%s: pause \n", __func__);
-				compress_pause(compress);
-				sleep(2);
-				printf("%s: resume \n", __func__);
-				compress_resume(compress);
-			}
-		}
-	} while (num_read > 0);
+    compress = compress_open(card, device, COMPRESS_IN, &config);
+    if (!compress || !is_compress_ready(compress)) {
+        fprintf(stderr, "Unable to open Compress device %d:%d\n",
+                card, device);
+        fprintf(stderr, "ERR: %s\n", compress_get_error(compress));
+        goto MIXER_EXIT;
+    };
+    if (verbose)
+        printf("%s: Opened compress device\n", __func__);
 
-	if (verbose)
-		printf("%s: exit success\n", __func__);
-	/* issue drain if it supports */
-	compress_drain(compress);
-	/* disconnect stream to audio intf */
-	connect_agm_audio_intf_to_stream(mixer, device, intf_name, STREAM_COMPRESS, false);
-	free(buffer);
-	fclose(file);
-	compress_close(compress);
-	return;
+    for (index = 0; index < intf_num; index++) {
+        if (strstr(intf_name[index], "VIRT-") || (device_kv[index] == SPEAKER) || (device_kv[index] == HANDSET)) {
+            if (set_agm_group_mux_config(mixer, device, &grp_config[index], intf_name[index], dev_config[index].ch)) {
+                printf("Failed to set grp device config\n");
+            }
+        }
+    }
+    size = config.fragment_size;
+    buffer = malloc(size * config.fragments);
+    if (!buffer) {
+        fprintf(stderr, "Unable to allocate %d bytes\n", size);
+        goto COMP_EXIT;
+    }
+
+    /* we will write frag fragment_size and then start */
+    num_read = fread(buffer, 1, size * config.fragments, file);
+    if (num_read > 0) {
+        if (verbose)
+            printf("%s: Doing first buffer write of %d\n", __func__, num_read);
+        wrote = compress_write(compress, buffer, num_read);
+        if (wrote < 0) {
+            fprintf(stderr, "Error %d playing sample\n", wrote);
+            fprintf(stderr, "ERR: %s\n", compress_get_error(compress));
+            goto BUF_EXIT;
+        }
+        if (wrote != num_read) {
+            /* TODO: Buufer pointer needs to be set here */
+            fprintf(stderr, "We wrote %d, DSP accepted %d\n", num_read, wrote);
+        }
+    }
+    printf("Playing file %s On Card %u device %u, with buffer of %lu bytes\n",
+            name, card, device, buffer_size);
+    printf("Format %u Channels %u, %u Hz, Bit Rate %d\n",
+            SND_AUDIOCODEC_MP3, channels, rate, bits);
+
+    compress_start(compress);
+    if (verbose)
+        printf("%s: You should hear audio NOW!!!\n", __func__);
+
+    do {
+        num_read = fread(buffer, 1, size, file);
+        if (num_read > 0) {
+            wrote = compress_write(compress, buffer, num_read);
+            if (wrote < 0) {
+                fprintf(stderr, "Error playing sample\n");
+                fprintf(stderr, "ERR: %s\n", compress_get_error(compress));
+                goto BUF_EXIT;
+            }
+            if (wrote != num_read) {
+                /* TODO: Buffer pointer needs to be set here */
+                fprintf(stderr, "We wrote %d, DSP accepted %d\n", num_read, wrote);
+            }
+            if (verbose) {
+                print_time(compress);
+                printf("%s: wrote %d\n", __func__, wrote);
+            }
+            if (pause) {
+                printf("%s: pause \n", __func__);
+                compress_pause(compress);
+                sleep(2);
+                printf("%s: resume \n", __func__);
+                compress_resume(compress);
+            }
+        }
+    } while (num_read > 0);
+
+    if (verbose)
+        printf("%s: exit success\n", __func__);
+    /* issue drain if it supports */
+    compress_drain(compress);
+    /* disconnect stream to audio intf */
+    for(index = 0; index < intf_num; index++) {
+        connect_agm_audio_intf_to_stream(mixer, device, intf_name[index], STREAM_COMPRESS, false);
+    }
+    free(buffer);
+    fclose(file);
+    compress_close(compress);
+    return;
 BUF_EXIT:
-	free(buffer);
+    free(buffer);
 COMP_EXIT:
-	/* disconnect stream to audio intf */
-	connect_agm_audio_intf_to_stream(mixer, device, intf_name, STREAM_COMPRESS, false);
-	compress_close(compress);
+    compress_close(compress);
 MIXER_EXIT:
-	mixer_close(mixer);
+    if (dev_config)
+        free(dev_config);
+    if (grp_config)
+        free(grp_config);
+    mixer_close(mixer);
 FILE_EXIT:
-	fclose(file);
-	if (verbose)
-		printf("%s: exit failure\n", __func__);
-	exit(EXIT_FAILURE);
+    fclose(file);
+    if (verbose)
+        printf("%s: exit failure\n", __func__);
+    exit(EXIT_FAILURE);
 }
-
diff --git a/plugins/tinyalsa/test/agmhostless.c b/plugins/tinyalsa/test/agmhostless.c
index d262f0a..9ff4952 100644
--- a/plugins/tinyalsa/test/agmhostless.c
+++ b/plugins/tinyalsa/test/agmhostless.c
@@ -46,25 +46,23 @@
     close_f = 1;
 }
 
-char *capture_audio_interface_name[] = {
-    "CODEC_DMA-LPAIF_VA-TX-0",
-    "CODEC_DMA-LPAIF_VA-TX-1",
-    "MI2S-LPAIF_AXI-TX-PRIMARY",
-    "TDM-LPAIF_AXI-TX-PRIMARY",
-    "AUXPCM-LPAIF_AXI-TX-PRIMARY",
-};
+void play_loopback(unsigned int card, unsigned int p_device, unsigned int c_device, unsigned int channels,
+                  unsigned int rate, enum pcm_format format, struct device_config *cap_config,
+                  struct device_config *p_config, unsigned int period_size,
+                  unsigned int period_count, unsigned int play_cap_time, char* capture_intf,
+                  char* play_intf, unsigned int pdkv, unsigned int cdkv, unsigned int stream_kv,
+                  unsigned int do_loopback);
 
-char *playback_audio_interface_name[] = {
-    "CODEC_DMA-LPAIF_WSA-RX-0",
-    "CODEC_DMA-LPAIF_WSA-RX-1",
-    "MI2S-LPAIF_AXI-RX-PRIMARY",
-    "TDM-LPAIF_AXI-RX-PRIMARY",
-    "AUXPCM-LPAIF_AXI-RX-PRIMARY",
-};
-
-static void play_loopback(unsigned int card, unsigned int p_device, unsigned int c_device, unsigned int channels,
-                 unsigned int rate, enum pcm_format format, unsigned int period_size,
-                 unsigned int period_count, unsigned int play_cap_time, unsigned int capture_intf, unsigned int play_intf);
+void usage()
+{
+    printf(" Usage: %s [-D card] [-P Hostless Playback device] [-C Hostless Capture device] [-p period_size]\n"
+           " [-n n_periods]  [-c channels] [-r rate] [-b bits] [-T playback/capture time ]\n"
+           " [-i capture intf] [-o playback intf]\n"
+           " [-cdkv capture_device_kv] [-pdkv playback_device_kv] [-skv stream_kv]\n"
+           " Used to enable 'hostless' mode for audio devices with a DSP back-end.\n"
+           " Alternatively, specify '-l' for loopback mode: this program will read\n"
+           " from the capture device and write to the playback device.\n");
+}
 
 int main(int argc, char **argv)
 {
@@ -77,34 +75,19 @@
     unsigned int num_channels = 2;
     unsigned int sample_rate = 48000;
     unsigned int play_cap_time = 10;
-    unsigned int c_audio_intf = 0;
-    unsigned int p_audio_intf = 0;
+    char* c_intf_name = NULL;
+    char* p_intf_name = NULL;
+    unsigned int do_loopback = 0;
     enum pcm_format format;
+    struct device_config capture_config;
+    struct device_config play_config;
+    unsigned int c_device_kv = 0;
+    unsigned int p_device_kv = 0;
+    unsigned int stream_kv = 0;
+    unsigned int ret = 0;
 
     if (argc < 2) {
-        printf("Usage: %s [-D card] [-P Hostless Playback device] [-C Hostless Capture device] [-p period_size]"
-                " [-n n_periods]  [-c num_channels]  [-r sample_rate]   [-T playback/capture time ]  [-i capture intf id] [-o playback intf id]\n"
-               " valid playback_intf_id :\n"
-                "0 : WSA_CDC_DMA_RX_0\n"
-                "1 : RX_CDC_DMA_RX_0\n"
-                "2 : SLIM_0_RX\n"
-                "3 : DISPLAY_PORT_RX\n"
-                "4 : PRI_TDM_RX_0\n"
-                "5 : SEC_TDM_RX_0\n"
-                "6 : AUXPCM_RX\n"
-                "7 : SEC_AUXPCM_RX\n"
-                "8 : PRI_MI2S_RX\n"
-                "9 : SEC_MI2S_RX\n"
-                " valid capture_intf_id :\n"
-                "0 : TX_CDC_DMA_TX_0\n"
-                "1 : SLIM_0_TX\n"
-                "2 : PRI_TDM_TX_0\n"
-                "3 : SEC_TDM_TX_0\n"
-                "4 : AUXPCM_TX\n"
-                "5 : SEC_AUXPCM_TX\n"
-                "6 : PRI_MI2S_TX\n"
-                "7 : SEC_MI2S_TX\n",
-                 argv[0]);
+        usage();
         return 1;
     }
 
@@ -115,67 +98,84 @@
             argv++;
             if (*argv)
                 p_device = atoi(*argv);
-        }
-	 if (strcmp(*argv, "-C") == 0) {
+        } else if (strcmp(*argv, "-C") == 0) {
             argv++;
             if (*argv)
                 c_device = atoi(*argv);
-        }
-        if (strcmp(*argv, "-p") == 0) {
+        } else if (strcmp(*argv, "-p") == 0) {
             argv++;
             if (*argv)
                 period_size = atoi(*argv);
-        }
-        if (strcmp(*argv, "-n") == 0) {
+        } else if (strcmp(*argv, "-n") == 0) {
             argv++;
             if (*argv)
                 period_count = atoi(*argv);
-        }
-	if (strcmp(*argv, "-c") == 0) {
+        }  else if (strcmp(*argv, "-c") == 0) {
             argv++;
             if (*argv)
                 num_channels = atoi(*argv);
-        }
-	if (strcmp(*argv, "-r") == 0) {
+        } else if (strcmp(*argv, "-r") == 0) {
             argv++;
             if (*argv)
                 sample_rate = atoi(*argv);
-        }
-
-	if (strcmp(*argv, "-T") == 0) {
+        } else if (strcmp(*argv, "-b") == 0) {
+            argv++;
+            if (*argv)
+                bits = atoi(*argv);
+        } else if (strcmp(*argv, "-T") == 0) {
             argv++;
             if (*argv)
                 play_cap_time = atoi(*argv);
-        }
-
-        if (strcmp(*argv, "-D") == 0) {
+        } else if (strcmp(*argv, "-D") == 0) {
             argv++;
             if (*argv)
                 card = atoi(*argv);
-        }
-        if (strcmp(*argv, "-i") == 0) {
+        } else if (strcmp(*argv, "-i") == 0) {
             argv++;
             if (*argv)
-                c_audio_intf = atoi(*argv);
-            if (c_audio_intf >= sizeof(capture_audio_interface_name)/sizeof(char *)) {
-                printf("Invalid audio interface index denoted by -i\n");
-                return 1;
-            }
-        }
-        if (strcmp(*argv, "-o") == 0) {
+                c_intf_name = *argv;
+        } else if (strcmp(*argv, "-o") == 0) {
             argv++;
             if (*argv)
-                p_audio_intf = atoi(*argv);
-            if (p_audio_intf >= sizeof(playback_audio_interface_name)/sizeof(char *)) {
-                printf("Invalid audio interface index denoted by -i\n");
-                return 1;
-            }
+                p_intf_name = *argv;
+        } else if (strcmp(*argv, "-l") == 0) {
+            do_loopback = 1;
+        } else if (strcmp(*argv, "-skv") == 0) {
+            argv++;
+            if (*argv)
+                stream_kv = convert_char_to_hex(*argv);
+        } else if (strcmp(*argv, "-cdkv") == 0) {
+            argv++;
+            if (*argv)
+                c_device_kv = convert_char_to_hex(*argv);
+        } else if (strcmp(*argv, "-pdkv") == 0) {
+            argv++;
+            if (*argv)
+                p_device_kv = convert_char_to_hex(*argv);
+        } else if (strcmp(*argv, "-help") == 0) {
+            usage();
         }
 
         if (*argv)
             argv++;
     }
 
+    ret = get_device_media_config(BACKEND_CONF_FILE, c_intf_name, &capture_config);
+    if (ret) {
+        printf("Invalid input, assigning default values for : %s\n", c_intf_name);
+        capture_config.rate = sample_rate;
+        capture_config.bits = bits;
+        capture_config.ch = num_channels;
+    }
+
+    ret = get_device_media_config(BACKEND_CONF_FILE, p_intf_name, &play_config);
+    if (ret) {
+        printf("Invalid input, assigning default values for : %s\n", p_intf_name);
+        play_config.rate = sample_rate;
+        play_config.bits = bits;
+        play_config.ch = num_channels;
+    }
+
     switch (bits) {
     case 32:
         format = PCM_FORMAT_S32_LE;
@@ -190,33 +190,33 @@
         printf("%u bits is not supported.\n", bits);
         return 1;
     }
-
-    signal(SIGINT, sigint_handler);
-    signal(SIGHUP, sigint_handler);
-    signal(SIGTERM, sigint_handler);
-
-    play_loopback(card, p_device, c_device, num_channels, sample_rate,
-                  format, period_size, period_count, play_cap_time,
-                  c_audio_intf, p_audio_intf);
+    play_loopback(card, p_device, c_device, num_channels, sample_rate, format, &capture_config, &play_config, period_size,
+                  period_count, play_cap_time, c_intf_name, p_intf_name, p_device_kv,
+                  c_device_kv, stream_kv, do_loopback);
 
     return 0;
 }
 
 void play_loopback(unsigned int card, unsigned int p_device, unsigned int c_device, unsigned int channels,
-                 unsigned int rate, enum pcm_format format, unsigned int period_size,
-                 unsigned int period_count, unsigned int play_cap_time, unsigned int capture_intf, unsigned int play_intf)
+                  unsigned int rate, enum pcm_format format, struct device_config *cap_config,
+                  struct device_config *p_config, unsigned int period_size,
+                  unsigned int period_count, unsigned int play_cap_time, char* capture_intf,
+                  char* play_intf, unsigned int pdkv, unsigned int cdkv, unsigned int stream_kv,
+                  unsigned int do_loopback)
 {
     struct pcm_config config;
     struct pcm *p_pcm, *c_pcm;
     struct mixer *mixer;
-    char *buffer;
-    char *p_intf_name = playback_audio_interface_name[play_intf];
-    char *c_intf_name = capture_audio_interface_name[capture_intf];
+    char *buffer = NULL;
+    char *p_intf_name = play_intf;
+    char *c_intf_name = capture_intf;
     unsigned int size;
     unsigned int bytes_read = 0;
-    unsigned int frames = 0;
+    unsigned int frames = 0, ret = 0, miid = 0;
     struct timespec end;
     struct timespec now;
+    struct group_config grp_config;
+    stream_kv = stream_kv ? stream_kv : PCM_RX_LOOPBACK;
 
     memset(&config, 0, sizeof(config));
     config.channels = channels;
@@ -235,30 +235,31 @@
     }
 
     /* set device/audio_intf media config mixer control */
-    if (set_agm_device_media_config(mixer, channels, rate,
-                                    pcm_format_to_bits(format), p_intf_name)) {
+    if (set_agm_device_media_config(mixer, p_config->ch, p_config->rate,
+                                    p_config->bits, p_intf_name)) {
         printf("Failed to set playback device media config\n");
         goto err_close_mixer;
     }
 
-    if (set_agm_device_media_config(mixer, channels, rate,
-                                    pcm_format_to_bits(format), c_intf_name)) {
+    if (set_agm_device_media_config(mixer, cap_config->ch, cap_config->rate,
+                                    cap_config->bits, c_intf_name)) {
         printf("Failed to set capture device media config\n");
         goto err_close_mixer;
     }
 
     /* set audio interface metadata mixer control */
-    if (set_agm_audio_intf_metadata(mixer, c_intf_name, 0, CAPTURE, rate, pcm_format_to_bits(format), PCM_RX_LOOPBACK)) {
+    if (set_agm_audio_intf_metadata(mixer, c_intf_name, cdkv, CAPTURE, rate, cap_config->bits, stream_kv)) {
         printf("Failed to set capture device metadata\n");
         goto err_close_mixer;
     }
 
-    if (set_agm_audio_intf_metadata(mixer, p_intf_name, 0, PLAYBACK, rate, pcm_format_to_bits(format), PCM_RX_LOOPBACK)) {
+    if (set_agm_audio_intf_metadata(mixer, p_intf_name, pdkv, PLAYBACK, rate, p_config->bits, stream_kv)) {
         printf("Failed to set playback device metadata\n");
         goto err_close_mixer;
     }
 
-    if (set_agm_stream_metadata(mixer, c_device, PCM_RX_LOOPBACK, LOOPBACK, STREAM_PCM, NULL)) {
+    if (set_agm_stream_metadata(mixer, c_device, stream_kv, LOOPBACK, STREAM_PCM,
+                                0)) {
         printf("Failed to capture stream metadata\n");
         goto err_close_mixer;
     }
@@ -282,11 +283,38 @@
         goto err_disconnect;
     }
 
+    if (strstr(p_intf_name, "VIRT-")) {
+        if (get_group_device_info(BACKEND_CONF_FILE, p_intf_name, &grp_config))
+            goto err_disconnect;
+
+        if (set_agm_group_device_config(mixer, p_intf_name, &grp_config)) {
+            printf("Failed to set grp device config\n");
+            goto err_disconnect;
+        }
+    }
+    ret = agm_mixer_get_miid (mixer, p_device, p_intf_name, STREAM_PCM, PER_STREAM_PER_DEVICE_MFC, &miid);
+    if (ret) {
+        printf("MFC not present for this graph\n");
+    } else {
+        if (configure_mfc(mixer, p_device, p_intf_name, PER_STREAM_PER_DEVICE_MFC,
+                           STREAM_PCM, p_config->rate, p_config->ch,
+                           p_config->bits, miid)) {
+            printf("Failed to configure pspd mfc\n");
+            goto err_disconnect;
+        }
+    }
+
     p_pcm = pcm_open(card, p_device, PCM_OUT, &config);
     if (!p_pcm || !pcm_is_ready(p_pcm)) {
         printf("Unable to open playback PCM device (%s)\n",
                 pcm_get_error(p_pcm));
-        goto err_close_c_pcm;
+        goto err_disconnect;
+    }
+    if (strstr(p_intf_name, "VIRT-") || (pdkv == SPEAKER) || (pdkv == HANDSET)) {
+        if (set_agm_group_mux_config(mixer, p_device, &grp_config, p_intf_name, p_config->ch)) {
+            printf("Failed to set mux config\n");
+            goto err_close_p_pcm;
+        }
     }
 
     if (pcm_start(p_pcm) < 0) {
@@ -298,7 +326,7 @@
     if (!c_pcm || !pcm_is_ready(c_pcm)) {
         printf("Unable to open playback PCM device (%s)\n",
                 pcm_get_error(c_pcm));
-        goto err_disconnect;
+        goto err_close_p_pcm;
     }
 
     if (pcm_start(c_pcm) < 0) {
@@ -306,11 +334,34 @@
         goto err_close_c_pcm;
     }
 
+    if (do_loopback) {
+        size = pcm_frames_to_bytes(c_pcm, pcm_get_buffer_size(c_pcm));
+        buffer = malloc(size);
+        if (!buffer) {
+            printf("Unable to allocate %d bytes\n", size);
+            goto err_close_c_pcm;
+        }
+    }
+
     clock_gettime(CLOCK_MONOTONIC, &end);
     end.tv_sec += play_cap_time;
     while (1) {
         if (close_f)
             break;
+        if (do_loopback) {
+            if (pcm_read(c_pcm, buffer, size)) {
+                printf("Unable to read from PCM capture device %u (%s)\n",
+                        c_device, pcm_get_error(c_pcm));
+                break;
+            }
+            if (pcm_write(p_pcm, buffer, size)) {
+                printf("Unable to write to PCM playback device %u (%s)\n",
+                        p_device, pcm_get_error(p_pcm));
+                break;
+            }
+        } else {
+            usleep(100000);
+        }
 
         if (play_cap_time) {
             clock_gettime(CLOCK_MONOTONIC, &now);
@@ -320,10 +371,12 @@
         }
     }
     connect_play_pcm_to_cap_pcm(mixer, -1, c_device);
-err_close_p_pcm:
-    pcm_close(p_pcm);
 err_close_c_pcm:
     pcm_close(c_pcm);
+err_close_p_pcm:
+    if (buffer)
+        free(buffer);
+    pcm_close(p_pcm);
 err_disconnect:
     connect_agm_audio_intf_to_stream(mixer, p_device, p_intf_name, STREAM_PCM, false);
     connect_agm_audio_intf_to_stream(mixer, c_device, c_intf_name, STREAM_PCM, false);
diff --git a/plugins/tinyalsa/test/agmmixer.c b/plugins/tinyalsa/test/agmmixer.c
index 40714be..b7ef20c 100644
--- a/plugins/tinyalsa/test/agmmixer.c
+++ b/plugins/tinyalsa/test/agmmixer.c
@@ -88,25 +88,28 @@
 
 
 struct gsl_module_id_info_entry {
-	uint32_t module_id; /**< module id */
-	uint32_t module_iid; /**< globally unique module instance id */
+    uint32_t module_id; /**< module id */
+    uint32_t module_iid; /**< globally unique module instance id */
 };
 
 /**
  * Structure mapping the tag_id to module info (mid and miid)
  */
 struct gsl_tag_module_info_entry {
-	uint32_t tag_id; /**< tag id of the module */
-	uint32_t num_modules; /**< number of modules matching the tag_id */
-	struct gsl_module_id_info_entry module_entry[0]; /**< module list */
+    uint32_t tag_id; /**< tag id of the module */
+    uint32_t num_modules; /**< number of modules matching the tag_id */
+    struct gsl_module_id_info_entry module_entry[0]; /**< module list */
 };
 
 struct gsl_tag_module_info {
-	uint32_t num_tags; /**< number of tags */
-	struct gsl_tag_module_info_entry tag_module_entry[0];
-	/**< variable payload of type struct gsl_tag_module_info_entry */
+    uint32_t num_tags; /**< number of tags */
+    struct gsl_tag_module_info_entry tag_module_entry[0];
+    /**< variable payload of type struct gsl_tag_module_info_entry */
 };
 
+unsigned int slot_mask_map[5] = { 0, SLOT_MASK1, SLOT_MASK3, SLOT_MASK7, SLOT_MASK15};
+
+
 #define PADDING_8BYTE_ALIGN(x)  ((((x) + 7) & 7) ^ 7)
 
 static unsigned int  bits_to_alsa_format(unsigned int bits)
@@ -367,7 +370,7 @@
     return ret;
 }
 
-int set_agm_group_mux_config(struct mixer *mixer, unsigned int device, struct group_config *config, char *intf_name)
+int set_agm_group_mux_config(struct mixer *mixer, unsigned int device, struct group_config *config, char *intf_name, unsigned int channels)
 {
     char *stream = "PCM";
     char *control = "setParamTag";
@@ -376,6 +379,7 @@
     int ctl_len = 0, val_len;
     int ret = 0;
     struct agm_tag_config* tag_config = NULL;
+    uint32_t miid = 0;
 
     ret = set_agm_stream_metadata_type(mixer, device, intf_name, STREAM_PCM);
     if (ret)
@@ -403,7 +407,11 @@
     tag_config->tag = TAG_DEVICE_MUX;
     tag_config->num_tkvs = 1;
     tag_config->kv[0].key = TAG_KEY_SLOT_MASK;
-    tag_config->kv[0].value = config->slot_mask;
+    ret = agm_mixer_get_miid(mixer, device, intf_name, STREAM_PCM, TAG_DEVICE_MUX, &miid);
+    if (ret)
+        tag_config->kv[0].value = config->slot_mask;
+    else
+        tag_config->kv[0].value = slot_mask_map[channels];
 
     mixer_ctl_set_array(ctl, tag_config, val_len);
 done:
@@ -607,7 +615,7 @@
         gkv[0].value = HAPTICS_DEVICE;
     } else if (val == VOICE_UI) {
         gkv[0].key = DEVICETX;
-        gkv[0].value = HANDSETMIC_VA;
+        gkv[0].value = dkv ? dkv : HANDSETMIC_VA;
     } else {
         gkv[0].key = DEVICETX;
         gkv[0].value = dkv ? dkv : HANDSETMIC;
@@ -743,22 +751,15 @@
 
 int configure_mfc(struct mixer *mixer, int device, char *intf_name, int tag,
                   enum stream_type stype, unsigned int rate,
-                  unsigned int channels, unsigned int bits)
+                  unsigned int channels, unsigned int bits, uint32_t miid)
 {
     int ret = 0;
-    uint32_t miid = 0;
     struct apm_module_param_data_t* header = NULL;
     struct param_id_mfc_output_media_fmt_t *mfcConf;
     uint16_t* pcmChannel = NULL;
     uint8_t* payloadInfo = NULL;
     size_t payloadSize = 0, padBytes = 0, size;
 
-    ret = agm_mixer_get_miid(mixer, device, intf_name, stype, tag, &miid);
-    if (ret) {
-        printf("%s Get MIID from tag data failed\n", __func__);
-        return ret;
-    }
-
     payloadSize = sizeof(struct apm_module_param_data_t) +
                   sizeof(struct param_id_mfc_output_media_fmt_t) +
                   sizeof(uint16_t)*channels;
@@ -792,7 +793,7 @@
 }
 
 int set_agm_capture_stream_metadata(struct mixer *mixer, int device, uint32_t val, enum usecase_type usecase,
-     enum stream_type stype, unsigned int dev_channels)
+                                    enum stream_type stype, unsigned int instance_kv)
 {
     char *stream = "PCM";
     char *control = "metadata";
@@ -801,11 +802,18 @@
     uint8_t *metadata = NULL;
     struct agm_key_value *gkv = NULL, *ckv = NULL;
     struct prop_data *prop = NULL;
-    uint32_t num_gkv = 2, num_ckv = 1, num_props = 0;
+    uint32_t num_gkv = 1, num_ckv = 1, num_props = 0;
     uint32_t gkv_size, ckv_size, prop_size, index = 0;
     int ctl_len = 0, ret = 0, offset = 0;
     char *type = "ZERO";
 
+    ret = set_agm_stream_metadata_type(mixer, device, type, stype);
+    if (ret)
+        return ret;
+
+    if (instance_kv != 0)
+       num_gkv += 1;
+
     gkv_size = num_gkv * sizeof(struct agm_key_value);
     ckv_size = num_ckv * sizeof(struct agm_key_value);
     prop_size = sizeof(struct prop_data) + (num_props * sizeof(uint32_t));
@@ -830,9 +838,11 @@
     gkv[index].value = val;
     index++;
 
-    gkv[index].key = INSTANCE;
-    gkv[index].value = INSTANCE_1;
-    index++;
+    if (instance_kv != 0) {
+        gkv[index].key = INSTANCE;
+        gkv[index].value = instance_kv;
+        index++;
+    }
 
     index = 0;
     ckv[index].key = VOLUME;
@@ -878,22 +888,20 @@
     return ret;
 }
 
-int set_agm_stream_metadata(struct mixer *mixer, int device, uint32_t val, enum usecase_type usecase, enum stream_type stype, char *intf_name)
+int set_agm_streamdevice_metadata(struct mixer *mixer, int device, uint32_t val, enum usecase_type usecase,
+                                  enum stream_type stype, char *intf_name,
+                                  unsigned int devicepp_kv)
 {
     char *stream = "PCM";
     char *control = "metadata";
     char *mixer_str;
     struct mixer_ctl *ctl;
     uint8_t *metadata = NULL;
-    struct agm_key_value *gkv = NULL, *ckv = NULL;
-    struct prop_data *prop = NULL;
-    uint32_t num_gkv = 2, num_ckv = 1, num_props = 0;
-    uint32_t gkv_size, ckv_size, prop_size, index = 0;
+    struct agm_key_value *gkv = NULL;
+    uint32_t num_gkv = 2;
+    uint32_t gkv_size, index = 0;
     int ctl_len = 0, ret = 0, offset = 0;
-    char *type = "ZERO";
-
-    if (intf_name)
-        type = intf_name;
+    char *type = intf_name;
 
     ret = set_agm_stream_metadata_type(mixer, device, type, stype);
     if (ret)
@@ -902,17 +910,100 @@
     if (stype == STREAM_COMPRESS)
         stream = "COMPRESS";
 
-    if (val == PCM_LL_PLAYBACK || val == COMPRESSED_OFFLOAD_PLAYBACK || val == PCM_RECORD)
-        num_gkv += 1;
+    gkv_size = num_gkv * sizeof(struct agm_key_value);
 
-    if (val == HAPTICS_PLAYBACK)
-        num_gkv = 1;
+    metadata = calloc(1, sizeof(num_gkv) +  gkv_size);
+    if (!metadata)
+        return -ENOMEM;
+
+    gkv = calloc(num_gkv, sizeof(struct agm_key_value));
+    if (!gkv) {
+        free(metadata);
+        return -ENOMEM;
+    }
+    if (val == VOICE_UI) {
+        gkv[index].key = STREAMTX;
+        gkv[index].value = val;
+        index++;
+    } else if (usecase == PLAYBACK) {
+        gkv[index].key = STREAMRX;
+        gkv[index].value = val;
+        index++;
+    } else if (usecase == CAPTURE) {
+        gkv[index].key = STREAMRX;
+        gkv[index].value = val;
+        index++;
+    }
+    if (val == VOICE_UI) {
+        gkv[index].key = DEVICEPP_TX;
+        gkv[index].value = devicepp_kv;
+        index++;
+    } else if (usecase == PLAYBACK) {
+        gkv[index].key = DEVICEPP_RX;
+        gkv[index].value = devicepp_kv;
+        index++;
+    } else if (usecase == CAPTURE) {
+        gkv[index].key = DEVICEPP_TX;
+        gkv[index].value = devicepp_kv;
+        index++;
+    }
+
+    memcpy(metadata, &num_gkv, sizeof(num_gkv));
+    offset += sizeof(num_gkv);
+    memcpy(metadata + offset, gkv, gkv_size);
+    offset += gkv_size;
+
+    ctl_len = strlen(stream) + 4 + strlen(control) + 1;
+    mixer_str = calloc(1, ctl_len);
+    if (!mixer_str) {
+        free(metadata);
+        return -ENOMEM;
+    }
+    snprintf(mixer_str, ctl_len, "%s%d %s", stream, device, control);
+    ctl = mixer_get_ctl_by_name(mixer, mixer_str);
+    if (!ctl) {
+        printf("Invalid mixer control: %s\n", mixer_str);
+        free(gkv);
+        free(metadata);
+        free(mixer_str);
+        return ENOENT;
+    }
+
+    ret = mixer_ctl_set_array(ctl, metadata, sizeof(num_gkv) + gkv_size);
+
+    free(gkv);
+    free(metadata);
+    free(mixer_str);
+    return ret;
+}
+
+int set_agm_stream_metadata(struct mixer *mixer, int device, uint32_t val, enum usecase_type usecase,
+                            enum stream_type stype, unsigned int instance_kv)
+{
+    char *stream = "PCM";
+    char *control = "metadata";
+    char *mixer_str;
+    struct mixer_ctl *ctl;
+    uint8_t *metadata = NULL;
+    struct agm_key_value *gkv = NULL, *ckv = NULL;
+    struct prop_data *prop = NULL;
+    uint32_t num_gkv = 1, num_ckv = 1, num_props = 0;
+    uint32_t gkv_size, ckv_size, prop_size, index = 0;
+    int ctl_len = 0, ret = 0, offset = 0;
+    char *type = "ZERO";
+
+    ret = set_agm_stream_metadata_type(mixer, device, type, stype);
+    if (ret)
+        return ret;
+
+    if (stype == STREAM_COMPRESS)
+        stream = "COMPRESS";
+
+    if (instance_kv != 0)
+       num_gkv += 1;
 
     if (val == VOICE_UI) {
-        if (intf_name)
-            num_gkv = 2;
-        else
-            num_gkv = 3;
+        num_gkv = 3;
     }
 
     gkv_size = num_gkv * sizeof(struct agm_key_value);
@@ -936,48 +1027,31 @@
     }
 
     if (val == VOICE_UI) {
-        if (intf_name) {
-            gkv[index].key = DEVICEPP_TX;
-            gkv[index].value = DEVICEPP_TX_FLUENCE_FFECNS;
-            index++;
-            gkv[index].key = DEVICETX;
-            gkv[index].value = HANDSETMIC;
-            index++;
-        } else {
-            gkv[index].key = STREAMTX;
-            gkv[index].value = val;
-            index++;
+        gkv[index].key = STREAMTX;
+        gkv[index].value = val;
+        index++;
+        if (instance_kv != 0){
             gkv[index].key = INSTANCE;
-            gkv[index].value = INSTANCE_1;
-            index++;
-            gkv[index].key = STREAM_CONFIG;
-            gkv[index].value = STREAM_CFG_VUI_SVA;
+            gkv[index].value = instance_kv;
             index++;
         }
-    } else {
-        if (usecase == PLAYBACK)
-            gkv[index].key = STREAMRX;
-        else
-            gkv[index].key = STREAMTX;
-
+        gkv[index].key = STREAM_CONFIG;
+        gkv[index].value = STREAM_CFG_VUI_SVA;
+        index++;
+    } else if (usecase == PLAYBACK) {
+        gkv[index].key = STREAMRX;
         gkv[index].value = val;
 
         index++;
-        if (val == PCM_LL_PLAYBACK || val == COMPRESSED_OFFLOAD_PLAYBACK ||
-            val == PCM_RECORD) {
+        if (instance_kv != 0) {
             printf("Instance key is added\n");
             gkv[index].key = INSTANCE;
-            gkv[index].value = INSTANCE_1;
+            gkv[index].value = instance_kv;
             index++;
         }
-
-        if (usecase == PLAYBACK  && val != HAPTICS_PLAYBACK) {
-            gkv[index].key = DEVICEPP_RX;
-            gkv[index].value = DEVICEPP_RX_AUDIO_MBDRC;
-        } else if (val != HAPTICS_PLAYBACK) {
-            gkv[index].key = DEVICEPP_TX;
-            gkv[index].value = DEVICEPP_TX_AUDIO_FLUENCE_SMECNS;
-        }
+    } else if (usecase == LOOPBACK) {
+        gkv[index].key = STREAMRX;
+        gkv[index].value = val;
     }
 
     index = 0;
diff --git a/plugins/tinyalsa/test/agmmixer.h b/plugins/tinyalsa/test/agmmixer.h
index ee293f2..15e0402 100644
--- a/plugins/tinyalsa/test/agmmixer.h
+++ b/plugins/tinyalsa/test/agmmixer.h
@@ -60,16 +60,27 @@
     unsigned int slot_mask;
 };
 
+typedef enum {
+   SLOT_MASK1  = 1,
+   SLOT_MASK3  = 3,
+   SLOT_MASK7  = 7,
+   SLOT_MASK15 = 15,
+}slot_mask_t;
+
 int convert_char_to_hex(char *char_num);
 int set_agm_device_media_config(struct mixer *mixer, unsigned int channels,
                                 unsigned int rate, unsigned int bits, char *intf_name);
 int set_agm_group_device_config(struct mixer *mixer, char *intf_name, struct group_config *config);
-int set_agm_group_mux_config(struct mixer *mixer, unsigned int device, struct group_config *config, char *intf_name);
+int set_agm_group_mux_config(struct mixer *mixer, unsigned int device, struct group_config *config, char *intf_name, unsigned int channels);
 int connect_play_pcm_to_cap_pcm(struct mixer *mixer, unsigned int p_device, unsigned int c_device);
 int set_agm_audio_intf_metadata(struct mixer *mixer, char *intf_name, unsigned int dkv, enum usecase_type, int rate, int bitwidth, uint32_t val);
 int set_agm_stream_metadata_type(struct mixer *mixer, int device, char *val, enum stream_type stype);
-int set_agm_stream_metadata(struct mixer *mixer, int device, uint32_t val, enum usecase_type utype, enum stream_type stype, char *intf_name);
-int set_agm_capture_stream_metadata(struct mixer *mixer, int device, uint32_t val, enum usecase_type utype, enum stream_type stype, unsigned int dev_channels);
+int set_agm_streamdevice_metadata(struct mixer *mixer, int device, uint32_t val, enum usecase_type usecase, enum stream_type stype,
+                                  char *intf_name, unsigned int devicepp_kv);
+int set_agm_stream_metadata(struct mixer *mixer, int device, uint32_t val, enum usecase_type utype, enum stream_type stype,
+                            unsigned int instance_kv);
+int set_agm_capture_stream_metadata(struct mixer *mixer, int device, uint32_t val, enum usecase_type utype, enum stream_type stype,
+                            unsigned int instance_kv);
 int connect_agm_audio_intf_to_stream(struct mixer *mixer, unsigned int device,
                                   char *intf_name, enum stream_type, bool connect);
 int agm_mixer_register_event(struct mixer *mixer, int device, enum stream_type stype, uint32_t miid, uint8_t is_register);
@@ -84,5 +95,5 @@
 int get_device_media_config(char* filename, char *intf_name, struct device_config *config);
 int get_group_device_info(char* filename, char *intf_name, struct group_config *config);
 int configure_mfc(struct mixer *mixer, int device, char *intf_name, int tag, enum stream_type stype, unsigned int rate,
-                       unsigned int channels, unsigned int bits);
+                       unsigned int channels, unsigned int bits, uint32_t miid);
 #endif
diff --git a/plugins/tinyalsa/test/agmplay.c b/plugins/tinyalsa/test/agmplay.c
index 43258b3..3b3386e 100644
--- a/plugins/tinyalsa/test/agmplay.c
+++ b/plugins/tinyalsa/test/agmplay.c
@@ -66,8 +66,9 @@
 
 static int close = 0;
 
-void play_sample(FILE *file, unsigned int card, unsigned int device, unsigned int device_kv,
-                 struct chunk_fmt fmt, struct device_config *dev_config, bool haptics);
+void play_sample(FILE *file, unsigned int card, unsigned int device, unsigned int *device_kv,
+                 unsigned int stream_kv, unsigned int instance_kv, unsigned int *devicepp_kv,
+                 struct chunk_fmt fmt, bool haptics, char **intf_name, int intf_num);
 
 void stream_close(int sig)
 {
@@ -76,24 +77,37 @@
     close = 1;
 }
 
+static void usage(void)
+{
+    printf(" Usage: %s file.wav [-help print usage] [-D card] [-d device]\n"
+           " [-num_intf num of interfaces followed by interface name]\n"
+           " [-i intf_name] : Can be multiple if num_intf is more than 1\n"
+           " [-dkv device_kv] : Can be multiple if num_intf is more than 1\n"
+           " [-dppkv deviceppkv] : Assign 0 if no device pp in the graph\n"
+           " [-ikv instance_kv] :  Assign 0 if no instance kv in the graph\n"
+           " [-skv stream_kv] [-h haptics usecase]\n");
+}
+
 int main(int argc, char **argv)
 {
     FILE *file;
     struct riff_wave_header riff_wave_header;
     struct chunk_header chunk_header;
     struct chunk_fmt chunk_fmt;
-    unsigned int card = 100, device = 100;
-    unsigned int device_kv = 0;
+    unsigned int card = 100, device = 100, i=0;
+    int intf_num = 1;
+    unsigned int *device_kv = 0;
+    unsigned int stream_kv = 0;
+    unsigned int instance_kv = INSTANCE_1;
+    unsigned int *devicepp_kv = NULL;
     bool haptics = false;
-    char *intf_name = NULL;
+    char **intf_name = NULL;
     struct device_config config;
     char *filename;
     int more_chunks = 1, ret = 0;
 
     if (argc < 3) {
-        printf("Usage: %s file.wav [-D card] [-d device] [-i device_id] [-h haptics]",
-               " [-dkv device_kv]\n",
-                argv[0]);
+        usage();
         return 1;
     }
 
@@ -143,51 +157,97 @@
             argv++;
             if (*argv)
                 card = atoi(*argv);
-        } else if (strcmp(*argv, "-i") == 0) {
+        } else if (strcmp(*argv, "-num_intf") == 0) {
             argv++;
             if (*argv)
-                intf_name = *argv;
+                intf_num = atoi(*argv);
+        } else if (strcmp(*argv, "-i") == 0) {
+            intf_name = (char**) malloc(intf_num * sizeof(char*));
+            if (!intf_name) {
+                printf("invalid memory\n");
+            }
+            for (i = 0; i < intf_num ; i++){
+                argv++;
+                if (*argv)
+                    intf_name[i] = *argv;
+            }
         } else if (strcmp(*argv, "-h") == 0) {
             argv++;
             if (*argv)
                 haptics = *argv;
         } else if (strcmp(*argv, "-dkv") == 0) {
+            device_kv = (unsigned int *) malloc(intf_num * sizeof(unsigned int));
+            if (!device_kv) {
+                printf(" insufficient memory\n");
+            }
+            for (i = 0; i < intf_num ; i++) {
+                argv++;
+                if (*argv) {
+                    device_kv[i] = convert_char_to_hex(*argv);
+                }
+            }
+        } else if (strcmp(*argv, "-skv") == 0) {
             argv++;
             if (*argv)
-                device_kv = convert_char_to_hex(*argv);
+                stream_kv = convert_char_to_hex(*argv);
+        } else if (strcmp(*argv, "-ikv") == 0) {
+            argv++;
+            if (*argv) {
+                instance_kv = atoi(*argv);
+            }
+        } else if (strcmp(*argv, "-dppkv") == 0) {
+            devicepp_kv = (unsigned int *) malloc(intf_num * sizeof(unsigned int));
+            if (!devicepp_kv) {
+                printf(" insufficient memory\n");
+            }
+            for (i = 0; i < intf_num ; i++) {
+                devicepp_kv[i] = DEVICEPP_RX_AUDIO_MBDRC;
+            }
+            for (i = 0; i < intf_num ; i++)
+            {
+                argv++;
+                if (*argv) {
+                    devicepp_kv[i] = convert_char_to_hex(*argv);
+                }
+            }
+        } else if (strcmp(*argv, "-help") == 0) {
+            usage();
         }
         if (*argv)
             argv++;
     }
 
-    if (intf_name == NULL)
+    if (*intf_name == NULL)
         return 1;
 
-    ret = get_device_media_config(BACKEND_CONF_FILE, intf_name, &config);
-    if (ret) {
-        printf("Invalid input, entry not found for : %s\n", intf_name);
-        fclose(file);
-        return ret;
-    }
-    play_sample(file, card, device, device_kv, chunk_fmt, &config, haptics);
+    play_sample(file, card, device, device_kv, stream_kv, instance_kv, devicepp_kv,
+                 chunk_fmt, haptics, intf_name, intf_num);
 
     fclose(file);
+    if (device_kv)
+        free(device_kv);
+    if (devicepp_kv)
+        free(devicepp_kv);
+    if (intf_name)
+        free(intf_name);
 
     return 0;
 }
 
-void play_sample(FILE *file, unsigned int card, unsigned int device, unsigned int device_kv,
-                 struct chunk_fmt fmt, struct device_config *dev_config, bool haptics)
+void play_sample(FILE *file, unsigned int card, unsigned int device, unsigned int *device_kv,
+                 unsigned int stream_kv, unsigned int instance_kv, unsigned int *devicepp_kv,
+                 struct chunk_fmt fmt, bool haptics, char **intf_name, int intf_num)
 {
     struct pcm_config config;
     struct pcm *pcm;
     struct mixer *mixer;
     char *buffer;
     int playback_path, playback_value;
-    int size;
+    int size, index, ret = 0;
     int num_read;
-    char *name = dev_config->name;
-    struct group_config grp_config;
+    struct group_config *grp_config = (struct group_config *)malloc(intf_num*sizeof(struct group_config *));
+    struct device_config *dev_config = (struct device_config *)malloc(intf_num*sizeof(struct device_config *));
+    uint32_t miid = 0;
 
     memset(&config, 0, sizeof(config));
     config.channels = fmt.num_channels;
@@ -204,62 +264,87 @@
     config.stop_threshold = 0;
     config.silence_threshold = 0;
 
-    printf("Backend %s rate ch bit : %d, %d, %d\n", name,
-            dev_config->rate, dev_config->ch, dev_config->bits);
     mixer = mixer_open(card);
     if (!mixer) {
         printf("Failed to open mixer\n");
         return;
     }
 
-    /* set device/audio_intf media config mixer control */
-    if (set_agm_device_media_config(mixer, dev_config->ch, dev_config->rate,
-                                    dev_config->bits, name)) {
-        printf("Failed to set device media config\n");
-        goto err_close_mixer;
-    }
-
     if (haptics) {
         playback_path = HAPTICS;
-        playback_value = HAPTICS_PLAYBACK;
+        stream_kv = stream_kv ? stream_kv : HAPTICS_PLAYBACK;
     } else {
         playback_path = PLAYBACK;
-        playback_value = PCM_LL_PLAYBACK;
+        stream_kv = stream_kv ? stream_kv : PCM_LL_PLAYBACK;
     }
-     /* set audio interface metadata mixer control */
-    if (set_agm_audio_intf_metadata(mixer, name, device_kv, playback_path,
-                                    dev_config->rate, dev_config->bits, PCM_LL_PLAYBACK)) {
-        printf("Failed to set device metadata\n");
-        goto err_close_mixer;
+
+    for (index = 0; index < intf_num; index++) {
+        ret = get_device_media_config(BACKEND_CONF_FILE, intf_name[index], &dev_config[index]);
+        if (ret) {
+            printf("Invalid input, entry not found for : %s\n", intf_name[index]);
+            fclose(file);
+        }
+        printf("Backend %s rate ch bit : %d, %d, %d\n", intf_name[index],
+            dev_config[index].rate, dev_config[index].ch, dev_config[index].bits);
+
+        /* set device/audio_intf media config mixer control */
+        if (set_agm_device_media_config(mixer, dev_config[index].ch, dev_config[index].rate,
+                                    dev_config[index].bits, intf_name[index])) {
+            printf("Failed to set device media config\n");
+            goto err_close_mixer;
+        }
+
+        /* set audio interface metadata mixer control */
+        if (set_agm_audio_intf_metadata(mixer, intf_name[index], device_kv[index], playback_path,
+                                    dev_config[index].rate, dev_config[index].bits, stream_kv)) {
+            printf("Failed to set device metadata\n");
+            goto err_close_mixer;
+        }
     }
+
     /* set audio interface metadata mixer control */
-    if (set_agm_stream_metadata(mixer, device, playback_value, PLAYBACK, STREAM_PCM, NULL)) {
+    if (set_agm_stream_metadata(mixer, device, stream_kv, PLAYBACK, STREAM_PCM,
+                                instance_kv)) {
         printf("Failed to set pcm metadata\n");
         goto err_close_mixer;
     }
 
-    /* Note:  No common metadata as of now*/
+     /* Note:  No common metadata as of now*/
+    for (index = 0; index < intf_num; index++) {
+         if (devicepp_kv[index] != 0) {
+             if (set_agm_streamdevice_metadata(mixer, device, stream_kv, PLAYBACK, STREAM_PCM, intf_name[index],
+                                               devicepp_kv[index])) {
+                 printf("Failed to set pcm metadata\n");
+                 goto err_close_mixer;
+             }
+         }
 
-    /* connect pcm stream to audio intf */
-    if (connect_agm_audio_intf_to_stream(mixer, device, name, STREAM_PCM, true)) {
-        printf("Failed to connect pcm to audio interface\n");
-        goto err_close_mixer;
-    }
-
-    if (configure_mfc(mixer, device, name, PER_STREAM_PER_DEVICE_MFC,
-                           STREAM_PCM, dev_config->rate, dev_config->ch,
-                           dev_config->bits)) {
-        printf("Failed to configure pspd mfc\n");
-        goto err_close_mixer;
-    }
-
-    if (strstr(name, "VIRT-")) {
-        if (get_group_device_info(BACKEND_CONF_FILE, name, &grp_config))
+        /* connect pcm stream to audio intf */
+        if (connect_agm_audio_intf_to_stream(mixer, device, intf_name[index], STREAM_PCM, true)) {
+            printf("Failed to connect pcm to audio interface\n");
             goto err_close_mixer;
+        }
 
-        if (set_agm_group_device_config(mixer, name, &grp_config)) {
-            printf("Failed to set grp device config\n");
-            goto err_close_mixer;
+        ret = agm_mixer_get_miid (mixer, device, intf_name[index], STREAM_PCM, PER_STREAM_PER_DEVICE_MFC, &miid);
+        if (ret) {
+            printf("MFC not present for this graph\n");
+        } else {
+            if (configure_mfc(mixer, device, intf_name[index], PER_STREAM_PER_DEVICE_MFC,
+                           STREAM_PCM, dev_config[index].rate, dev_config[index].ch,
+                           dev_config[index].bits, miid)) {
+                printf("Failed to configure pspd mfc\n");
+                goto err_close_mixer;
+            }
+        }
+
+        if (strstr(intf_name[index], "VIRT-")) {
+            if (get_group_device_info(BACKEND_CONF_FILE, intf_name[index], &grp_config[index]))
+                goto err_close_mixer;
+
+            if (set_agm_group_device_config(mixer, intf_name[index], &grp_config[index])) {
+                printf("Failed to set grp device config\n");
+                goto err_close_mixer;
+            }
         }
     }
 
@@ -270,10 +355,11 @@
         goto err_close_mixer;
     }
 
-    if (strstr(name, "VIRT-")) {
-        if (set_agm_group_mux_config(mixer, device, &grp_config, name)) {
-            printf("Failed to set grp device config\n");
-            goto err_close_pcm;
+    for (index = 0; index < intf_num; index++) {
+        if (strstr(intf_name[index], "VIRT-") || (device_kv[index] == SPEAKER) || (device_kv[index] == HANDSET)) {
+            if (set_agm_group_mux_config(mixer, device, &grp_config[index], intf_name[index], dev_config[index].ch)) {
+                printf("Failed to set grp device config\n");
+            }
         }
     }
 
@@ -306,13 +392,18 @@
     } while (!close && num_read > 0);
 
     pcm_stop(pcm);
-    /* connect pcm stream to audio intf */
-    connect_agm_audio_intf_to_stream(mixer, device, name, STREAM_PCM, false);
+    /* disconnect pcm stream to audio intf */
+    for (index = 0; index < intf_num; index++) {
+        connect_agm_audio_intf_to_stream(mixer, device, intf_name[index], STREAM_PCM, false);
+    }
 
     free(buffer);
 err_close_pcm:
     pcm_close(pcm);
 err_close_mixer:
+    if (dev_config)
+        free(dev_config);
+    if (grp_config)
+        free(grp_config);
     mixer_close(mixer);
 }
-
diff --git a/plugins/tinyalsa/test/backend_conf.xml b/plugins/tinyalsa/test/backend_conf.xml
index 1e342d3..883a08f 100644
--- a/plugins/tinyalsa/test/backend_conf.xml
+++ b/plugins/tinyalsa/test/backend_conf.xml
@@ -66,5 +66,9 @@
     <device name="TDM-LPAIF_VA-TX-PRIMARY" rate="48000" ch="1" bits="16" />
     <device name="TDM-LPAIF_WSA-RX-PRIMARY" rate="48000" ch="1" bits="16" />
     <device name="TDM-LPAIF_WSA-TX-PRIMARY" rate="48000" ch="1" bits="16" />
+    <device name="TDM-LPAIF_AXI-TX-PRIMARY" rate="48000" ch="2" bits="16" />
+    <device name="AUXPCM-LPAIF_AXI-TX-PRIMARY" rate="48000" ch="2" bits="16" />
+    <device name="MI2S-LPAIF_AXI-RX-PRIMARY" rate="48000" ch="2" bits="16" />
+    <device name="AUXPCM-LPAIF_AXI-RX-PRIMARY" rate="48000" ch="2" bits="16" />
 </config>