Revert "Revert "hal: add support for multi-mic input and multi-channel output""

This reverts commit 93be0a55c20477c0857f92d0a8a8808536c8d93f.
diff --git a/hal/Android.mk b/hal/Android.mk
index 076faed..a51fac7 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -12,15 +12,19 @@
   AUDIO_PLATFORM = msm8974
 ifneq ($(filter msm8226,$(TARGET_BOARD_PLATFORM)),)
   LOCAL_CFLAGS := -DPLATFORM_MSM8x26
+  LOCAL_CFLAGS += -DMAX_TARGET_SPECIFIC_CHANNEL_CNT="2"
 endif
 ifneq ($(filter msm8084,$(TARGET_BOARD_PLATFORM)),)
   LOCAL_CFLAGS := -DPLATFORM_MSM8084
+  LOCAL_CFLAGS += -DMAX_TARGET_SPECIFIC_CHANNEL_CNT="2"
 endif
 ifneq ($(filter msm8992,$(TARGET_BOARD_PLATFORM)),)
   LOCAL_CFLAGS := -DPLATFORM_MSM8994
+  LOCAL_CFLAGS += -DMAX_TARGET_SPECIFIC_CHANNEL_CNT="4"
 endif
 ifneq ($(filter msm8994,$(TARGET_BOARD_PLATFORM)),)
   LOCAL_CFLAGS := -DPLATFORM_MSM8994
+  LOCAL_CFLAGS += -DMAX_TARGET_SPECIFIC_CHANNEL_CNT="4"
 endif
 endif
 
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 8fc7764..c66f7ec 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -62,6 +62,13 @@
 #define PROXY_OPEN_RETRY_COUNT           100
 #define PROXY_OPEN_WAIT_TIME             20
 
+#define MIN_CHANNEL_COUNT                1
+#define DEFAULT_CHANNEL_COUNT            2
+
+#define MAX_CHANNEL_COUNT atoi(XSTR(MAX_TARGET_SPECIFIC_CHANNEL_CNT))
+#define XSTR(x) STR(x)
+#define STR(x) #x
+
 static unsigned int configured_low_latency_capture_period_size =
         LOW_LATENCY_CAPTURE_PERIOD_SIZE;
 
@@ -71,7 +78,7 @@
 static const bool k_enable_extended_precision = false;
 
 struct pcm_config pcm_config_deep_buffer = {
-    .channels = 2,
+    .channels = DEFAULT_CHANNEL_COUNT,
     .rate = DEFAULT_OUTPUT_SAMPLING_RATE,
     .period_size = DEEP_BUFFER_OUTPUT_PERIOD_SIZE,
     .period_count = DEEP_BUFFER_OUTPUT_PERIOD_COUNT,
@@ -82,7 +89,7 @@
 };
 
 struct pcm_config pcm_config_low_latency = {
-    .channels = 2,
+    .channels = DEFAULT_CHANNEL_COUNT,
     .rate = DEFAULT_OUTPUT_SAMPLING_RATE,
     .period_size = LOW_LATENCY_OUTPUT_PERIOD_SIZE,
     .period_count = LOW_LATENCY_OUTPUT_PERIOD_COUNT,
@@ -104,7 +111,7 @@
 };
 
 struct pcm_config pcm_config_audio_capture = {
-    .channels = 2,
+    .channels = DEFAULT_CHANNEL_COUNT,
     .period_count = AUDIO_CAPTURE_PERIOD_COUNT,
     .format = PCM_FORMAT_S16_LE,
     .stop_threshold = INT_MAX,
@@ -1187,9 +1194,16 @@
                                   audio_format_t format,
                                   int channel_count)
 {
-    if (format != AUDIO_FORMAT_PCM_16_BIT) return -EINVAL;
+    if (format != AUDIO_FORMAT_PCM_16_BIT) {
+        ALOGE("%s: unsupported AUDIO FORMAT (%d) ", __func__, format);
+        return -EINVAL;
+    }
 
-    if ((channel_count < 1) || (channel_count > 2)) return -EINVAL;
+    if ((channel_count < MIN_CHANNEL_COUNT) || (channel_count > MAX_CHANNEL_COUNT)) {
+        ALOGE("%s: unsupported channel count (%d) passed  Min / Max (%d\%d)", __func__,
+               channel_count, MIN_CHANNEL_COUNT, MAX_CHANNEL_COUNT);
+        return -EINVAL;
+    }
 
     switch (sample_rate) {
     case 8000:
@@ -1203,6 +1217,7 @@
     case 48000:
         break;
     default:
+        ALOGE("%s: unsupported (%d) samplerate passed ", __func__, sample_rate);
         return -EINVAL;
     }
 
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 7b1fa75..572945f 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -13,7 +13,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 #define LOG_TAG "msm8974_platform"
 /*#define LOG_NDEBUG 0*/
 #define LOG_NDDEBUG 0
@@ -35,9 +34,6 @@
 #define AUDIO_DATA_BLOCK_MIXER_CTL "HDMI EDID"
 #define CVD_VERSION_MIXER_CTL "CVD Version"
 
-#define DUALMIC_CONFIG_NONE 0      /* Target does not contain 2 mics */
-#define DUALMIC_CONFIG_ENDFIRE 1
-#define DUALMIC_CONFIG_BROADSIDE 2
 
 /*
  * This file will have a maximum of 38 bytes:
@@ -113,7 +109,9 @@
     bool fluence_in_voice_call;
     bool fluence_in_voice_comm;
     bool fluence_in_voice_rec;
-    int  dualmic_config;
+    /* 0 = no fluence, 1 = fluence, 2 = fluence pro */
+    int  fluence_type;
+    int  source_mic_type;
     bool speaker_lr_swap;
 
     void *acdb_handle;
@@ -127,6 +125,7 @@
 
     char *snd_card_name;
     int max_vol_index;
+    int max_mic_count;
 };
 
 static int pcm_device_table[AUDIO_USECASE_MAX][2] = {
@@ -247,7 +246,11 @@
 
     [SND_DEVICE_IN_VOICE_RX] = "voice-rx",
 
+    [SND_DEVICE_IN_THREE_MIC] = "three-mic",
+    [SND_DEVICE_IN_QUAD_MIC] = "quad-mic",
     [SND_DEVICE_IN_CAPTURE_VI_FEEDBACK] = "vi-feedback",
+    [SND_DEVICE_IN_HANDSET_TMIC] = "three-mic",
+    [SND_DEVICE_IN_HANDSET_QMIC] = "quad-mic",
 };
 
 /* ACDB IDs (audio DSP path configuration IDs) for each sound device */
@@ -326,7 +329,11 @@
 
     [SND_DEVICE_IN_VOICE_RX] = 44,
 
+    [SND_DEVICE_IN_THREE_MIC] = 46,
+    [SND_DEVICE_IN_QUAD_MIC] = 46,
     [SND_DEVICE_IN_CAPTURE_VI_FEEDBACK] = 102,
+    [SND_DEVICE_IN_HANDSET_TMIC] = 125,
+    [SND_DEVICE_IN_HANDSET_QMIC] = 125,
 };
 
 struct name_to_index {
@@ -410,7 +417,11 @@
     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_DMIC_STEREO)},
     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE)},
 
+    {TO_NAME_INDEX(SND_DEVICE_IN_THREE_MIC)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_QUAD_MIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_CAPTURE_VI_FEEDBACK)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_TMIC)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_QMIC)},
 };
 
 static char * backend_tag_table[SND_DEVICE_MAX] = {0};
@@ -953,20 +964,23 @@
     property_get("ro.config.vc_call_vol_steps", value, TOSTRING(MAX_VOL_INDEX));
     my_data->max_vol_index = atoi(value);
 
-    my_data->dualmic_config = DUALMIC_CONFIG_NONE;
+    my_data->source_mic_type = SOURCE_DUAL_MIC;
+
     my_data->fluence_in_spkr_mode = false;
     my_data->fluence_in_voice_call = false;
     my_data->fluence_in_voice_comm = false;
     my_data->fluence_in_voice_rec = false;
 
-    property_get("persist.audio.dualmic.config",value,"");
-    if (!strcmp("broadside", value)) {
-        ALOGE("%s: Unsupported dualmic configuration", __func__);
-    } else if (!strcmp("endfire", value)) {
-        my_data->dualmic_config = DUALMIC_CONFIG_ENDFIRE;
+    property_get("ro.qc.sdk.audio.fluencetype", value, "");
+    if (!strcmp("fluencepro", value)) {
+        my_data->fluence_type = FLUENCE_PRO_ENABLE;
+    } else if (!strcmp("fluence", value)) {
+        my_data->fluence_type = FLUENCE_ENABLE;
+    } else if (!strcmp("none", value)) {
+        my_data->fluence_type = FLUENCE_DISABLE;
     }
 
-    if (my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
+    if (my_data->fluence_type != FLUENCE_DISABLE) {
         property_get("persist.audio.fluence.voicecall",value,"");
         if (!strcmp("true", value)) {
             my_data->fluence_in_voice_call = true;
@@ -988,6 +1002,30 @@
         }
     }
 
+    // support max to mono, example if max count is 3, usecase supports Three, dual and mono mic
+    switch (my_data->max_mic_count) {
+        case 4:
+            my_data->source_mic_type |= SOURCE_QUAD_MIC;
+        case 3:
+            my_data->source_mic_type |= SOURCE_THREE_MIC;
+        case 2:
+            my_data->source_mic_type |= SOURCE_DUAL_MIC;
+        case 1:
+            my_data->source_mic_type |= SOURCE_MONO_MIC;
+            break;
+        default:
+            ALOGE("%s: max_mic_count (%d), is not supported, setting to default",
+                   __func__, my_data->max_mic_count);
+            my_data->source_mic_type = SOURCE_MONO_MIC|SOURCE_DUAL_MIC;
+            break;
+        }
+
+    ALOGV("%s: Fluence_Type(%d) max_mic_count(%d) mic_type(0x%x) fluence_in_voice_call(%d)"
+          " fluence_in_voice_comm(%d) fluence_in_voice_rec(%d) fluence_in_spkr_mode(%d) ",
+          __func__, my_data->fluence_type, my_data->max_mic_count, my_data->source_mic_type,
+          my_data->fluence_in_voice_call, my_data->fluence_in_voice_comm,
+          my_data->fluence_in_voice_rec, my_data->fluence_in_spkr_mode);
+
     my_data->acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
     if (my_data->acdb_handle == NULL) {
         ALOGE("%s: DLOPEN failed for %s", __func__, LIB_ACDB_LOADER);
@@ -1753,8 +1791,8 @@
     snd_device_t snd_device = SND_DEVICE_NONE;
     int channel_count = popcount(channel_mask);
 
-    ALOGV("%s: enter: out_device(%#x) in_device(%#x)",
-          __func__, out_device, in_device);
+    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);
     if ((out_device != AUDIO_DEVICE_NONE) && voice_is_in_call(adev)) {
         if (adev->voice.tty_mode != TTY_MODE_OFF) {
             if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
@@ -1800,17 +1838,19 @@
                     snd_device = SND_DEVICE_IN_BT_SCO_MIC;
             }
         } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER ||
-            out_device & AUDIO_DEVICE_OUT_SPEAKER_SAFE ||
-            out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
-            out_device & AUDIO_DEVICE_OUT_LINE) {
-            if (my_data->fluence_in_voice_call && my_data->fluence_in_spkr_mode &&
-                    my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
-                snd_device = SND_DEVICE_IN_VOICE_SPEAKER_DMIC;
-            } else {
-                snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
+                   out_device & AUDIO_DEVICE_OUT_SPEAKER_SAFE ||
+                   out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
+                   out_device & AUDIO_DEVICE_OUT_LINE) {
+            if (my_data->fluence_in_voice_call && my_data->fluence_in_spkr_mode) {
+                if (my_data->source_mic_type & SOURCE_DUAL_MIC) {
+                    snd_device = SND_DEVICE_IN_VOICE_SPEAKER_DMIC;
+                } else {
+                    snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
+                }
             }
-        } else if (out_device & AUDIO_DEVICE_OUT_TELEPHONY_TX)
+        } else if (out_device & AUDIO_DEVICE_OUT_TELEPHONY_TX) {
             snd_device = SND_DEVICE_IN_VOICE_RX;
+        }
     } else if (source == AUDIO_SOURCE_CAMCORDER) {
         if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
             in_device & AUDIO_DEVICE_IN_BACK_MIC) {
@@ -1818,14 +1858,29 @@
         }
     } else if (source == AUDIO_SOURCE_VOICE_RECOGNITION) {
         if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
-            if (my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
-                if (channel_mask == AUDIO_CHANNEL_IN_FRONT_BACK)
-                    snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_STEREO;
-                else if (my_data->fluence_in_voice_rec &&
-                         adev->active_input->enable_ns)
+            if (my_data->fluence_in_voice_rec && channel_count == 1) {
+                if ((my_data->fluence_type == FLUENCE_PRO_ENABLE) &&
+                    (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
+                    snd_device = SND_DEVICE_IN_HANDSET_QMIC;
+                } else if ((my_data->fluence_type == FLUENCE_PRO_ENABLE) &&
+                    (my_data->source_mic_type & SOURCE_THREE_MIC)) {
+                    snd_device = SND_DEVICE_IN_HANDSET_TMIC;
+                } else if (((my_data->fluence_type == FLUENCE_PRO_ENABLE) ||
+                    (my_data->fluence_type == FLUENCE_ENABLE)) &&
+                    (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
                     snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE;
+                }
+                platform_set_echo_reference(adev, true, out_device);
+            } else if ((channel_mask == AUDIO_CHANNEL_IN_FRONT_BACK) &&
+                       (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+                snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_STEREO;
+            } else if (((int)channel_mask == AUDIO_CHANNEL_INDEX_MASK_3) &&
+                       (my_data->source_mic_type & SOURCE_THREE_MIC)) {
+                snd_device = SND_DEVICE_IN_THREE_MIC;
+            } else if (((int)channel_mask == AUDIO_CHANNEL_INDEX_MASK_4) &&
+                       (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
+                snd_device = SND_DEVICE_IN_QUAD_MIC;
             }
-
             if (snd_device == SND_DEVICE_NONE) {
                 if (adev->active_input->enable_ns)
                     snd_device = SND_DEVICE_IN_VOICE_REC_MIC_NS;
@@ -1842,16 +1897,18 @@
                 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
                     if (my_data->fluence_in_spkr_mode &&
                             my_data->fluence_in_voice_comm &&
-                            my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
+                            (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
                         snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS;
-                    } else
+                    } else {
                         snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC_NS;
+                    }
                 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
                     if (my_data->fluence_in_voice_comm &&
-                            my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
+                            (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
                         snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC_NS;
-                    } else
+                    } else {
                         snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC_NS;
+                    }
                 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
                     snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
                 }
@@ -1860,16 +1917,18 @@
                 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
                     if (my_data->fluence_in_spkr_mode &&
                             my_data->fluence_in_voice_comm &&
-                            my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
+                            (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
                         snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC;
-                    } else
+                    } else {
                         snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
+                    }
                 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
                     if (my_data->fluence_in_voice_comm &&
-                            my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
+                            (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
                         snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC;
-                    } else
+                    } else {
                         snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC;
+                    }
                } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
                    snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
                }
@@ -1878,16 +1937,18 @@
                 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
                     if (my_data->fluence_in_spkr_mode &&
                             my_data->fluence_in_voice_comm &&
-                            my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
+                            (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
                         snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS;
-                    } else
+                    } else {
                         snd_device = SND_DEVICE_IN_SPEAKER_MIC_NS;
+                    }
                 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
                     if (my_data->fluence_in_voice_comm &&
-                            my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
+                            (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
                         snd_device = SND_DEVICE_IN_HANDSET_DMIC_NS;
-                    } else
+                    } else {
                         snd_device = SND_DEVICE_IN_HANDSET_MIC_NS;
+                    }
                 }
             }
         }
@@ -1904,17 +1965,37 @@
             !(in_device & AUDIO_DEVICE_IN_VOICE_CALL) &&
             !(in_device & AUDIO_DEVICE_IN_COMMUNICATION)) {
         if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
-            if (my_data->dualmic_config != DUALMIC_CONFIG_NONE &&
-                    channel_count == 2)
+            if ((my_data->source_mic_type & SOURCE_QUAD_MIC) &&
+                (int)channel_mask == AUDIO_CHANNEL_INDEX_MASK_4) {
+                snd_device = SND_DEVICE_IN_QUAD_MIC;
+            } else if ((my_data->source_mic_type & SOURCE_THREE_MIC) &&
+                       (int)channel_mask == AUDIO_CHANNEL_INDEX_MASK_3) {
+                snd_device = SND_DEVICE_IN_THREE_MIC;
+            } else if ((my_data->source_mic_type & SOURCE_DUAL_MIC) &&
+                       channel_count == 2) {
                 snd_device = SND_DEVICE_IN_HANDSET_DMIC_STEREO;
-            else
+            } else if ((my_data->source_mic_type & SOURCE_MONO_MIC) &&
+                       channel_count == 1) {
                 snd_device = SND_DEVICE_IN_HANDSET_MIC;
+            } else {
+                ALOGE("%s: something wrong (1): source type (%d) channel_count (%d) .."
+                      " channel mask (0x%x) no combination found .. setting to mono", __func__,
+                       my_data->source_mic_type, channel_count, channel_mask);
+                snd_device = SND_DEVICE_IN_HANDSET_MIC;
+            }
         } else if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
-            if (my_data->dualmic_config != DUALMIC_CONFIG_NONE &&
-                    channel_count == 2)
+            if ((my_data->source_mic_type & SOURCE_DUAL_MIC) &&
+                    channel_count == 2) {
                 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_STEREO;
-            else
+            } else if ((my_data->source_mic_type & SOURCE_MONO_MIC) &&
+                    channel_count == 1) {
                 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
+            } else {
+                ALOGE("%s: something wrong (2): source type (%d) channel_count (%d) .."
+                      " no combination found .. setting to mono", __func__,
+                       my_data->source_mic_type, channel_count);
+                snd_device = SND_DEVICE_IN_SPEAKER_MIC;
+            }
         } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
             snd_device = SND_DEVICE_IN_HEADSET_MIC;
         } else if (in_device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
@@ -1945,10 +2026,18 @@
                    out_device & AUDIO_DEVICE_OUT_SPEAKER_SAFE ||
                    out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
                    out_device & AUDIO_DEVICE_OUT_LINE) {
-            if (channel_count == 2)
+            if ((my_data->source_mic_type & SOURCE_DUAL_MIC) &&
+                    channel_count == 2) {
                 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_STEREO;
-            else
+            } else if ((my_data->source_mic_type & SOURCE_MONO_MIC) &&
+                          channel_count == 1) {
                 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
+            } else {
+                ALOGE("%s: something wrong (3): source type (%d) channel_count (%d) .."
+                      " no combination found .. setting to mono", __func__,
+                       my_data->source_mic_type, channel_count);
+                snd_device = SND_DEVICE_IN_SPEAKER_MIC;
+            }
         } else if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
             if (adev->bt_wb_speech_enabled) {
                 if (adev->bluetooth_nrec)
@@ -2188,6 +2277,19 @@
         list_add_tail(&operator_info_list, &info->list);
         ALOGD("%s: add operator[%s] mccmnc[%s]", __func__, info->name, info->mccmnc);
     }
+
+    memset(value, 0, sizeof(value));
+    err = str_parms_get_str(parms, PLATFORM_MAX_MIC_COUNT,
+                            value, sizeof(value));
+    if (err >= 0) {
+        str_parms_del(parms, PLATFORM_MAX_MIC_COUNT);
+        my_data->max_mic_count = atoi(value);
+        ALOGV("%s: max_mic_count %s/%d", __func__, value, my_data->max_mic_count);
+    } else {
+        ALOGE("%s: max_mic_count key value pair not found, reset to default", __func__);
+        my_data->max_mic_count = 2;
+    }
+
 done:
     ALOGV("%s: exit with code(%d)", __func__, ret);
     if (kv_pairs != NULL)
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index efc3bb1..456e61f 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -17,6 +17,19 @@
 #ifndef QCOM_AUDIO_PLATFORM_H
 #define QCOM_AUDIO_PLATFORM_H
 
+enum {
+    FLUENCE_DISABLE,                  /* Target dosent support fluence */
+    FLUENCE_ENABLE      = 0x1,        /* Target supports fluence */
+    FLUENCE_PRO_ENABLE  = 0x2,        /* Target supports fluence pro */
+};
+
+enum {
+    SOURCE_MONO_MIC  = 0x1,            /* Target contains 1 mic */
+    SOURCE_DUAL_MIC  = 0x2,            /* Target contains 2 mics */
+    SOURCE_THREE_MIC = 0x4,            /* Target contains 3 mics */
+    SOURCE_QUAD_MIC  = 0x8,            /* Target contains 4 mics */
+};
+
 /*
  * Below are the devices for which is back end is same, SLIMBUS_0_RX.
  * All these devices are handled by the internal HW codec. We can
@@ -118,8 +131,12 @@
 
     SND_DEVICE_IN_VOICE_RX,
 
+    SND_DEVICE_IN_THREE_MIC,
+    SND_DEVICE_IN_QUAD_MIC,
     SND_DEVICE_IN_CAPTURE_VI_FEEDBACK,
 
+    SND_DEVICE_IN_HANDSET_TMIC,
+    SND_DEVICE_IN_HANDSET_QMIC,
     SND_DEVICE_IN_END,
 
     SND_DEVICE_MAX = SND_DEVICE_IN_END,
@@ -225,6 +242,7 @@
 #define LIB_MDM_DETECT "libmdmdetect.so"
 
 #define PLATFORM_CONFIG_KEY_SOUNDCARD_NAME "snd_card_name"
+#define PLATFORM_MAX_MIC_COUNT "input_mic_max_count"
 
 /* CSD-CLIENT related functions */
 typedef int (*init_t)(bool);