hal: Add support to use compress path for ec ref loopback

Add support to use compress path for mic and ec reference data
capture in single stream.
Modify parsing logic of custom mtmx param tags to reflect changes
in platform xml.

Change-Id: Iebbd56de6ab95f35c695205cdd14bf928321eead
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index a2a52a8..03c07e3 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -474,7 +474,7 @@
     int num_devices = 0, pcm_device_id = -1, i = 0, ret = 0;
     snd_device_t new_snd_devices[SND_DEVICE_OUT_END] = {0};
     struct audio_backend_cfg backend_cfg = {0};
-    uint32_t feature_id = 0;
+    uint32_t feature_id = 0, idx = 0;
 
     switch(usecase->type) {
     case PCM_PLAYBACK:
@@ -519,7 +519,7 @@
      * if features like dual_mono is enabled and overrides the default(i.e. 0).
      */
     info.id = feature_id;
-    info.usecase_id = usecase->id;
+    info.usecase_id[0] = usecase->id;
     for (i = 0, ret = 0; i < num_devices; i++) {
         info.snd_device = new_snd_devices[i];
         platform_get_codec_backend_cfg(adev, info.snd_device, &backend_cfg);
@@ -532,7 +532,7 @@
             info.op_channels = audio_channel_count_from_in_mask(
                                    usecase->stream.in->channel_mask);
         }
-        params = platform_get_custom_mtmx_params(adev->platform, &info);
+        params = platform_get_custom_mtmx_params(adev->platform, &info, &idx);
         if (params) {
             if (enable)
                 ret = update_custom_mtmx_coefficients_v2(adev, params,
@@ -677,7 +677,8 @@
                                            struct audio_custom_mtmx_in_params *in_params,
                                            int pcm_device_id,
                                            usecase_type_t type,
-                                           bool enable)
+                                           bool enable,
+                                           uint32_t idx)
 {
     struct mixer_ctl *ctl = NULL;
     char mixer_ctl_name[128] = {0};
@@ -691,13 +692,13 @@
           __func__, pinfo->ip_channels, pinfo->op_channels, pcm_device_id,
           type, enable);
 
-    if (!strcmp(pinfo->fe_name, "")) {
+    if (pinfo->fe_id[idx] == 0) {
         ALOGE("%s: Error. no front end defined", __func__);
         return -EINVAL;
     }
 
-    strlcpy(mixer_name_prefix, pinfo->fe_name, sizeof(mixer_name_prefix));
-
+    snprintf(mixer_name_prefix, sizeof(mixer_name_prefix), "%s%d",
+             "MultiMedia", pinfo->fe_id[idx]);
     /*
      * Enable/Disable channel mixer.
      * If enable, use params and in_params to configure mixer.
@@ -839,7 +840,7 @@
     struct audio_custom_mtmx_in_params_info in_info = {0};
     struct audio_custom_mtmx_in_params *in_params = NULL;
     int pcm_device_id = -1, ret = 0;
-    uint32_t feature_id = 0;
+    uint32_t feature_id = 0, idx = 0;
 
     switch(usecase->type) {
     case PCM_CAPTURE:
@@ -861,26 +862,26 @@
 
     ALOGD("%s: snd device %d", __func__, info.snd_device);
     info.id = feature_id;
-    info.usecase_id = usecase->id;
+    info.usecase_id[0] = usecase->id;
     info.op_channels = audio_channel_count_from_in_mask(
                                 usecase->stream.in->channel_mask);
 
-    in_info.usecase_id = info.usecase_id;
+    in_info.usecase_id[0] = info.usecase_id[0];
     in_info.op_channels = info.op_channels;
     in_params = platform_get_custom_mtmx_in_params(adev->platform, &in_info);
     if (!in_params) {
         ALOGE("%s: Could not get in params for usecase %d, channels %d",
-               __func__, in_info.usecase_id, in_info.op_channels);
+               __func__, in_info.usecase_id[0], in_info.op_channels);
         return;
     }
 
     info.ip_channels = in_params->ip_channels;
     ALOGD("%s: ip channels %d, op channels %d", __func__, info.ip_channels, info.op_channels);
 
-    params = platform_get_custom_mtmx_params(adev->platform, &info);
+    params = platform_get_custom_mtmx_params(adev->platform, &info, &idx);
     if (params) {
         ret = update_custom_mtmx_coefficients_v1(adev, params, in_params,
-                             pcm_device_id, usecase->type, enable);
+                             pcm_device_id, usecase->type, enable, idx);
         if (ret < 0)
             ALOGE("%s: error updating mtmx coeffs err:%d", __func__, ret);
     }
@@ -899,12 +900,12 @@
         return snd_device;
     }
 
-    in_info.usecase_id = usecase->id;
+    in_info.usecase_id[0] = usecase->id;
     in_info.op_channels = channel_count;
     in_params = platform_get_custom_mtmx_in_params(adev->platform, &in_info);
     if (!in_params) {
         ALOGE("%s: Could not get in params for usecase %d, channels %d",
-               __func__, in_info.usecase_id, in_info.op_channels);
+               __func__, in_info.usecase_id[0], in_info.op_channels);
         return snd_device;
     }
 
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index e6989f6..98f587a 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -2778,11 +2778,18 @@
 
 struct audio_custom_mtmx_params *
     platform_get_custom_mtmx_params(void *platform,
-                                    struct audio_custom_mtmx_params_info *info)
+                                    struct audio_custom_mtmx_params_info *info,
+                                    uint32_t *idx)
 {
     struct platform_data *my_data = (struct platform_data *)platform;
     struct listnode *node = NULL;
     struct audio_custom_mtmx_params *params = NULL;
+    int i = 0;
+
+    if (!info || !idx) {
+        ALOGE("%s: Invalid params", __func__);
+        return NULL;
+    }
 
     list_for_each(node, &my_data->custom_mtmx_params_list) {
         params = node_to_item(node, struct audio_custom_mtmx_params, list);
@@ -2790,17 +2797,22 @@
             params->info.id == info->id &&
             params->info.ip_channels == info->ip_channels &&
             params->info.op_channels == info->op_channels &&
-            params->info.usecase_id == info->usecase_id &&
             params->info.snd_device == info->snd_device) {
-            ALOGV("%s: found params with ip_ch %d op_ch %d uc_id %d snd_dev %d",
-                  __func__, info->ip_channels, info->op_channels,
-                  info->usecase_id, info->snd_device);
-            return params;
+            while (params->info.usecase_id[i] != 0) {
+                if (params->info.usecase_id[i] == info->usecase_id[0]) {
+                    ALOGV("%s: found params with ip_ch %d op_ch %d uc_id %d snd_dev %d",
+                           __func__, info->ip_channels, info->op_channels,
+                           info->usecase_id[0], info->snd_device);
+                    *idx = i;
+                    return params;
+                }
+                i++;
+            }
         }
     }
     ALOGI("%s: no matching param with id %d ip_ch %d op_ch %d uc_id %d snd_dev %d",
           __func__, info->id, info->ip_channels, info->op_channels,
-          info->usecase_id, info->snd_device);
+          info->usecase_id[0], info->snd_device);
     return NULL;
 }
 
@@ -2810,6 +2822,12 @@
     struct platform_data *my_data = (struct platform_data *)platform;
     struct audio_custom_mtmx_params *params = NULL;
     uint32_t size = sizeof(*params);
+    int i = 0;
+
+    if (!info) {
+        ALOGE("%s: Invalid params", __func__);
+        return NULL;
+    }
 
     if (info->ip_channels > AUDIO_CHANNEL_COUNT_MAX ||
         info->op_channels > AUDIO_CHANNEL_COUNT_MAX) {
@@ -2825,9 +2843,14 @@
         return -ENOMEM;
     }
 
-    ALOGI("%s: adding mtmx params with id %d ip_ch %d op_ch %d uc_id %d snd_dev %d",
+    ALOGI("%s: adding mtmx params with id %d ip_ch %d op_ch %d snd_dev %d",
           __func__, info->id, info->ip_channels, info->op_channels,
-          info->usecase_id, info->snd_device);
+          info->snd_device);
+    while (info->usecase_id[i] != 0) {
+        ALOGI("%s: supported usecase ids for added mtmx params %d",
+              __func__, info->usecase_id[i]);
+        i++;
+    }
 
     params->info = *info;
     list_add_tail(&my_data->custom_mtmx_params_list, &params->list);
diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c
index 137e700..e3d1b7b 100644
--- a/hal/msm8960/platform.c
+++ b/hal/msm8960/platform.c
@@ -357,7 +357,8 @@
     platform_get_custom_mtmx_params
     (
         void *platform __unused,
-        struct audio_custom_mtmx_params_info *info __unused
+        struct audio_custom_mtmx_params_info *info __unused,
+        uint32_t *idx __unused
     )
 {
     ALOGW("%s: not implemented!", __func__);
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 676a30d..8ce1d58 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -3680,11 +3680,18 @@
 
 struct audio_custom_mtmx_params *
     platform_get_custom_mtmx_params(void *platform,
-                                    struct audio_custom_mtmx_params_info *info)
+                                    struct audio_custom_mtmx_params_info *info,
+                                    uint32_t *idx)
 {
     struct platform_data *my_data = (struct platform_data *)platform;
     struct listnode *node = NULL;
     struct audio_custom_mtmx_params *params = NULL;
+    int i = 0;
+
+    if (!info || !idx) {
+        ALOGE("%s: Invalid params", __func__);
+        return NULL;
+    }
 
     list_for_each(node, &my_data->custom_mtmx_params_list) {
         params = node_to_item(node, struct audio_custom_mtmx_params, list);
@@ -3692,17 +3699,22 @@
             params->info.id == info->id &&
             params->info.ip_channels == info->ip_channels &&
             params->info.op_channels == info->op_channels &&
-            params->info.usecase_id == info->usecase_id &&
             params->info.snd_device == info->snd_device) {
-            ALOGV("%s: found params with ip_ch %d op_ch %d uc_id %d snd_dev %d",
-                  __func__, info->ip_channels, info->op_channels,
-                  info->usecase_id, info->snd_device);
-            return params;
+            while (params->info.usecase_id[i] != 0) {
+                if (params->info.usecase_id[i] == info->usecase_id[0]) {
+                    ALOGV("%s: found params with ip_ch %d op_ch %d uc_id %d snd_dev %d",
+                           __func__, info->ip_channels, info->op_channels,
+                           info->usecase_id[0], info->snd_device);
+                    *idx = i;
+                    return params;
+                }
+                i++;
+            }
         }
     }
     ALOGI("%s: no matching param with id %d ip_ch %d op_ch %d uc_id %d snd_dev %d",
           __func__, info->id, info->ip_channels, info->op_channels,
-          info->usecase_id, info->snd_device);
+          info->usecase_id[0], info->snd_device);
     return NULL;
 }
 
@@ -3712,6 +3724,12 @@
     struct platform_data *my_data = (struct platform_data *)platform;
     struct audio_custom_mtmx_params *params = NULL;
     uint32_t size = sizeof(*params);
+    int i = 0;
+
+    if (!info) {
+        ALOGE("%s: Invalid params", __func__);
+        return -EINVAL;
+    }
 
     if (info->ip_channels > AUDIO_CHANNEL_COUNT_MAX ||
         info->op_channels > AUDIO_CHANNEL_COUNT_MAX) {
@@ -3727,9 +3745,14 @@
         return -ENOMEM;
     }
 
-    ALOGI("%s: adding mtmx params with id %d ip_ch %d op_ch %d uc_id %d snd_dev %d",
+    ALOGI("%s: adding mtmx params with id %d ip_ch %d op_ch %d snd_dev %d",
           __func__, info->id, info->ip_channels, info->op_channels,
-          info->usecase_id, info->snd_device);
+          info->snd_device);
+    while (info->usecase_id[i] != 0) {
+        ALOGI("%s: supported usecase ids for added mtmx params %d",
+              __func__, info->usecase_id[i]);
+        i++;
+    }
 
     params->info = *info;
     list_add_tail(&my_data->custom_mtmx_params_list, &params->list);
@@ -3753,20 +3776,30 @@
     struct platform_data *my_data = (struct platform_data *)platform;
     struct listnode *node = NULL;
     struct audio_custom_mtmx_in_params *params = NULL;
+    int i = 0;
+
+    if (!info) {
+        ALOGE("%s: Invalid params", __func__);
+        return NULL;
+    }
 
     list_for_each(node, &my_data->custom_mtmx_in_params_list) {
         params = node_to_item(node, struct audio_custom_mtmx_in_params, list);
         if (params &&
-            params->in_info.op_channels == info->op_channels &&
-            params->in_info.usecase_id == info->usecase_id) {
-            ALOGV("%s: found params with op_ch %d uc_id %d",
-                  __func__, info->op_channels, info->usecase_id);
-            return params;
+            params->in_info.op_channels == info->op_channels) {
+            while (params->in_info.usecase_id[i] != 0) {
+                if (params->in_info.usecase_id[i] == info->usecase_id[0]) {
+                    ALOGV("%s: found params with op_ch %d uc_id %d",
+                          __func__, info->op_channels, info->usecase_id[0]);
+                    return params;
+                }
+                i++;
+            }
         }
     }
 
     ALOGI("%s: no matching param with op_ch %d uc_id %d",
-           __func__, info->op_channels, info->usecase_id);
+           __func__, info->op_channels, info->usecase_id[0]);
     return NULL;
 }
 
@@ -3776,6 +3809,12 @@
     struct platform_data *my_data = (struct platform_data *)platform;
     struct audio_custom_mtmx_in_params *params = NULL;
     uint32_t size = sizeof(*params);
+    int i = 0;
+
+    if (!info) {
+        ALOGE("%s: Invalid params", __func__);
+        return -EINVAL;
+    }
 
     if (info->op_channels > AUDIO_CHANNEL_COUNT_MAX) {
         ALOGE("%s: unusupported channels in %d", __func__, info->op_channels);
@@ -3788,8 +3827,14 @@
         return -ENOMEM;
     }
 
-    ALOGI("%s: adding mtmx in params with op_ch %d uc_id %d",
-          __func__, info->op_channels, info->usecase_id);
+    ALOGI("%s: adding mtmx in params with op_ch %d",
+          __func__, info->op_channels);
+
+    while (info->usecase_id[i] != 0) {
+        ALOGI("%s: supported usecase ids for added mtmx in params %d",
+              __func__, info->usecase_id[i]);
+        i++;
+    }
 
     params->in_info = *info;
     list_add_tail(&my_data->custom_mtmx_in_params_list, &params->list);
@@ -6208,6 +6253,7 @@
     int str_bitwidth = (in == NULL) ? CODEC_BACKEND_DEFAULT_BIT_WIDTH : in->bit_width;
     int sample_rate = (in == NULL) ? 8000 : in->sample_rate;
     struct audio_usecase *usecase = NULL;
+    audio_usecase_t uc_id = (in == NULL) ? USECASE_AUDIO_RECORD : in->usecase;
 
     ALOGV("%s: enter: out_device(%#x) in_device(%#x) channel_count (%d) channel_mask (0x%x)",
           __func__, out_device, in_device, channel_count, channel_mask);
@@ -6613,7 +6659,7 @@
             }
         } else if (in_device & AUDIO_DEVICE_IN_LOOPBACK) {
             if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
-                usecase = get_usecase_from_list(adev, USECASE_AUDIO_RECORD);
+                usecase = get_usecase_from_list(adev, uc_id);
                 if (usecase == NULL) {
                     ALOGE("%s: Could not find the record usecase", __func__);
                     snd_device = SND_DEVICE_NONE;
diff --git a/hal/platform_api.h b/hal/platform_api.h
index 394310a..30a10c5 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -35,6 +35,7 @@
 #define PRODUCT_FFV      "ffv"
 #define PRODUCT_ALLPLAY  "allplay"
 #define MAX_IN_CHANNELS 32
+#define CUSTOM_MTRX_PARAMS_MAX_USECASE 8
 
 typedef enum {
     PLATFORM,
@@ -103,9 +104,9 @@
     uint32_t id;
     uint32_t ip_channels;
     uint32_t op_channels;
-    uint32_t usecase_id;
+    uint32_t usecase_id[CUSTOM_MTRX_PARAMS_MAX_USECASE];
     uint32_t snd_device;
-    char fe_name[128];
+    uint32_t fe_id[CUSTOM_MTRX_PARAMS_MAX_USECASE];
 };
 
 struct audio_custom_mtmx_params {
@@ -116,7 +117,7 @@
 
 struct audio_custom_mtmx_in_params_info {
     uint32_t op_channels;
-    uint32_t usecase_id;
+    uint32_t usecase_id[CUSTOM_MTRX_PARAMS_MAX_USECASE];
 };
 
 struct audio_custom_mtmx_params_in_ch_info {
@@ -377,7 +378,8 @@
 int platform_get_delay(void *platform, int pcm_device_id);
 struct audio_custom_mtmx_params *
     platform_get_custom_mtmx_params(void *platform,
-                                    struct audio_custom_mtmx_params_info *info);
+                                    struct audio_custom_mtmx_params_info *info,
+                                    uint32_t *idx);
 int platform_add_custom_mtmx_params(void *platform,
                                     struct audio_custom_mtmx_params_info *info);
 /* callback functions from platform to common audio HAL */
diff --git a/hal/platform_info.c b/hal/platform_info.c
index 8ee8b07..0f5f0f9 100644
--- a/hal/platform_info.c
+++ b/hal/platform_info.c
@@ -1068,13 +1068,19 @@
 
 static void process_custom_mtmx_in_params(const XML_Char **attr)
 {
-    int attr_idx = 0;
+    int attr_idx = 0, i = 0;
+    char *context = NULL, *value = NULL;
 
     if (strcmp(attr[attr_idx++], "usecase") != 0) {
         ALOGE("%s: 'usecase' not found", __func__);
         return;
     }
-    mtmx_in_params_info.usecase_id = platform_get_usecase_index((char *)attr[attr_idx++]);
+    /* Check if multi usecases are supported for this custom mtrx params */
+    value = strtok_r((char *)attr[attr_idx++], ",", &context);
+    while (value && (i < CUSTOM_MTRX_PARAMS_MAX_USECASE)) {
+        mtmx_in_params_info.usecase_id[i++] = platform_get_usecase_index(value);
+        value = strtok_r(NULL, ",", &context);
+    }
 
     if (strcmp(attr[attr_idx++], "out_channel_count") != 0) {
         ALOGE("%s: 'out_channel_count' not found", __func__);
@@ -1089,7 +1095,7 @@
 static void process_custom_mtmx_param_coeffs(const XML_Char **attr)
 {
     uint32_t attr_idx = 0, out_ch_idx = -1, ch_coeff_count = 0;
-    uint32_t ip_channels = 0, op_channels = 0;
+    uint32_t ip_channels = 0, op_channels = 0, idx = 0;
     char *context = NULL, *ch_coeff_value = NULL;
     struct audio_custom_mtmx_params *mtmx_params = NULL;
 
@@ -1109,7 +1115,7 @@
         return;
     }
     mtmx_params = platform_get_custom_mtmx_params((void *)my_data.platform,
-                                                  &mtmx_params_info);
+                                                  &mtmx_params_info, &idx);
     if (mtmx_params == NULL) {
         ALOGE("%s: mtmx params with given param info, not found", __func__);
         return;
@@ -1129,7 +1135,10 @@
 
 static void process_custom_mtmx_params(const XML_Char **attr)
 {
-    int attr_idx = 0;
+    int attr_idx = 0, i = 0;
+    char *context = NULL, *value = NULL;
+
+    memset(&mtmx_params_info, 0, sizeof(mtmx_params_info));
 
     if (strcmp(attr[attr_idx++], "param_id") != 0) {
         ALOGE("%s: 'param_id' not found", __func__);
@@ -1153,7 +1162,13 @@
         ALOGE("%s: 'usecase' not found", __func__);
         return;
     }
-    mtmx_params_info.usecase_id = platform_get_usecase_index((char *)attr[attr_idx++]);
+
+    /* check if multi usecases are supported for this custom mtrx params */
+    value = strtok_r((char *)attr[attr_idx++], ",", &context);
+    while (value && (i < CUSTOM_MTRX_PARAMS_MAX_USECASE)) {
+        mtmx_params_info.usecase_id[i++] = platform_get_usecase_index(value);
+        value = strtok_r(NULL, ",", &context);
+    }
 
     if (strcmp(attr[attr_idx++], "snd_device") != 0) {
         ALOGE("%s: 'snd_device' not found", __func__);
@@ -1161,12 +1176,15 @@
     }
     mtmx_params_info.snd_device = platform_get_snd_device_index((char *)attr[attr_idx++]);
 
-    if ((attr[attr_idx] != NULL) && (strcmp(attr[attr_idx++], "fe_name") == 0)) {
-        strlcpy(mtmx_params_info.fe_name, (char *)attr[attr_idx++],
-                sizeof(mtmx_params_info.fe_name));
-    } else {
-        ALOGD("%s: 'fe_name' not found", __func__);
-        mtmx_params_info.fe_name[0] = '\0';
+    if ((attr[attr_idx] != NULL) && (strcmp(attr[attr_idx++], "fe_id") == 0)) {
+        i = 0;
+        value = strtok_r((char *)attr[attr_idx++], ",", &context);
+        while (value && (i < CUSTOM_MTRX_PARAMS_MAX_USECASE)) {
+            mtmx_params_info.fe_id[i++] = atoi(value);
+            value = strtok_r(NULL, ",", &context);
+        }
+
+        attr_idx++;
     }
 
     platform_add_custom_mtmx_params((void *)my_data.platform, &mtmx_params_info);