Merge "audio: Add support for CPE AFE MAD control" into av-userspace.lnx.2.0-dev
diff --git a/configs/msm8937/audio_policy.conf b/configs/msm8937/audio_policy.conf
index 3e59ba2..b7b858e 100644
--- a/configs/msm8937/audio_policy.conf
+++ b/configs/msm8937/audio_policy.conf
@@ -98,7 +98,7 @@
       }
       surround_sound {
         sampling_rates 8000|11025|12000|16000|22050|24000|32000|44100|48000
-        channel_masks AUDIO_CHANNEL_IN_MONO|AUDIO_CHANNEL_IN_STEREO|AUDIO_CHANNEL_IN_FRONT_BACK|AUDIO_CHANNEL_IN_5POINT1
+        channel_masks AUDIO_CHANNEL_IN_MONO|AUDIO_CHANNEL_IN_STEREO|AUDIO_CHANNEL_IN_FRONT_BACK|AUDIO_CHANNEL_INDEX_MASK_3|AUDIO_CHANNEL_INDEX_MASK_4|AUDIO_CHANNEL_IN_5POINT1
         formats AUDIO_FORMAT_PCM_16_BIT
         devices AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_BACK_MIC
       }
diff --git a/configs/msm8937/audio_policy_configuration.xml b/configs/msm8937/audio_policy_configuration.xml
index d0c4cdd..238c49e 100644
--- a/configs/msm8937/audio_policy_configuration.xml
+++ b/configs/msm8937/audio_policy_configuration.xml
@@ -150,7 +150,7 @@
                 <mixPort name="surround_sound" role="sink">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                              samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
-                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK,AUDIO_CHANNEL_IN_5POINT1"/>
+                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK,AUDIO_CHANNEL_INDEX_MASK_3,AUDIO_CHANNEL_INDEX_MASK_4,AUDIO_CHANNEL_IN_5POINT1"/>
                 </mixPort>
                 <mixPort name="voice_rx" role="sink">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
diff --git a/configs/msm8937/mixer_paths.xml b/configs/msm8937/mixer_paths.xml
index 520c72e..96f47d0 100644
--- a/configs/msm8937/mixer_paths.xml
+++ b/configs/msm8937/mixer_paths.xml
@@ -1100,6 +1100,14 @@
         <path name="adc1" />
     </path>
 
+    <path name="unprocessed-handset-mic">
+        <path name="handset-mic" />
+    </path>
+
+    <path name="unprocessed-mic">
+        <path name="unprocessed-handset-mic" />
+    </path>
+
     <path name="ADSP testfwk">
         <ctl name="MI2S_DL_HL Switch" value="1" />
     </path>
diff --git a/configs/msm8937/mixer_paths_mtp.xml b/configs/msm8937/mixer_paths_mtp.xml
index b5b3996..5bf3053 100644
--- a/configs/msm8937/mixer_paths_mtp.xml
+++ b/configs/msm8937/mixer_paths_mtp.xml
@@ -1235,6 +1235,14 @@
         <path name="adc1" />
     </path>
 
+    <path name="unprocessed-handset-mic">
+        <path name="handset-mic" />
+    </path>
+
+    <path name="unprocessed-mic">
+        <path name="unprocessed-handset-mic" />
+    </path>
+
     <path name="ADSP testfwk">
         <ctl name="MI2S_DL_HL Switch" value="1" />
     </path>
diff --git a/configs/msm8937/mixer_paths_wcd9335.xml b/configs/msm8937/mixer_paths_wcd9335.xml
index 2493f3f..e579d40 100644
--- a/configs/msm8937/mixer_paths_wcd9335.xml
+++ b/configs/msm8937/mixer_paths_wcd9335.xml
@@ -2404,6 +2404,14 @@
         <ctl name="MAD Input" value="DMIC0" />
     </path>
 
+    <path name="unprocessed-handset-mic">
+        <path name="handset-mic" />
+    </path>
+
+    <path name="unprocessed-mic">
+        <path name="unprocessed-handset-mic" />
+    </path>
+
     <!-- Added for ADSP testfwk -->
     <path name="ADSP testfwk">
         <ctl name="SLIMBUS_DL_HL Switch" value="1" />
diff --git a/configs/msm8953/audio_policy.conf b/configs/msm8953/audio_policy.conf
index 3e59ba2..b7b858e 100644
--- a/configs/msm8953/audio_policy.conf
+++ b/configs/msm8953/audio_policy.conf
@@ -98,7 +98,7 @@
       }
       surround_sound {
         sampling_rates 8000|11025|12000|16000|22050|24000|32000|44100|48000
-        channel_masks AUDIO_CHANNEL_IN_MONO|AUDIO_CHANNEL_IN_STEREO|AUDIO_CHANNEL_IN_FRONT_BACK|AUDIO_CHANNEL_IN_5POINT1
+        channel_masks AUDIO_CHANNEL_IN_MONO|AUDIO_CHANNEL_IN_STEREO|AUDIO_CHANNEL_IN_FRONT_BACK|AUDIO_CHANNEL_INDEX_MASK_3|AUDIO_CHANNEL_INDEX_MASK_4|AUDIO_CHANNEL_IN_5POINT1
         formats AUDIO_FORMAT_PCM_16_BIT
         devices AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_BACK_MIC
       }
diff --git a/configs/msm8953/audio_policy_configuration.xml b/configs/msm8953/audio_policy_configuration.xml
index d0c4cdd..238c49e 100644
--- a/configs/msm8953/audio_policy_configuration.xml
+++ b/configs/msm8953/audio_policy_configuration.xml
@@ -150,7 +150,7 @@
                 <mixPort name="surround_sound" role="sink">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                              samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
-                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK,AUDIO_CHANNEL_IN_5POINT1"/>
+                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK,AUDIO_CHANNEL_INDEX_MASK_3,AUDIO_CHANNEL_INDEX_MASK_4,AUDIO_CHANNEL_IN_5POINT1"/>
                 </mixPort>
                 <mixPort name="voice_rx" role="sink">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
diff --git a/configs/msm8953/mixer_paths.xml b/configs/msm8953/mixer_paths.xml
index 459e88d..91544a1 100644
--- a/configs/msm8953/mixer_paths.xml
+++ b/configs/msm8953/mixer_paths.xml
@@ -1104,6 +1104,14 @@
         <path name="adc1" />
     </path>
 
+    <path name="unprocessed-handset-mic">
+        <path name="handset-mic" />
+    </path>
+
+    <path name="unprocessed-mic">
+        <path name="unprocessed-handset-mic" />
+    </path>
+
     <path name="ADSP testfwk">
         <ctl name="MI2S_DL_HL Switch" value="1" />
     </path>
diff --git a/configs/msm8953/mixer_paths_mtp.xml b/configs/msm8953/mixer_paths_mtp.xml
index 4ac5ef7..42a9e68 100644
--- a/configs/msm8953/mixer_paths_mtp.xml
+++ b/configs/msm8953/mixer_paths_mtp.xml
@@ -1240,6 +1240,14 @@
         <path name="adc1" />
     </path>
 
+    <path name="unprocessed-handset-mic">
+        <path name="handset-mic" />
+    </path>
+
+    <path name="unprocessed-mic">
+        <path name="unprocessed-handset-mic" />
+    </path>
+
     <path name="ADSP testfwk">
         <ctl name="MI2S_DL_HL Switch" value="1" />
     </path>
diff --git a/configs/msm8953/mixer_paths_wcd9335.xml b/configs/msm8953/mixer_paths_wcd9335.xml
index 3afe808..657198f 100644
--- a/configs/msm8953/mixer_paths_wcd9335.xml
+++ b/configs/msm8953/mixer_paths_wcd9335.xml
@@ -2415,6 +2415,14 @@
         <ctl name="MAD Input" value="DMIC0" />
     </path>
 
+    <path name="unprocessed-handset-mic">
+        <path name="handset-mic" />
+    </path>
+
+    <path name="unprocessed-mic">
+        <path name="unprocessed-handset-mic" />
+    </path>
+
     <!-- Added for ADSP testfwk -->
     <path name="ADSP testfwk">
         <ctl name="SLIMBUS_DL_HL Switch" value="1" />
diff --git a/configs/msm8996/audio_policy.conf b/configs/msm8996/audio_policy.conf
index 8a3bd30..641ec55 100644
--- a/configs/msm8996/audio_policy.conf
+++ b/configs/msm8996/audio_policy.conf
@@ -101,13 +101,13 @@
       }
       surround_sound {
         sampling_rates 8000|11025|12000|16000|22050|24000|32000|44100|48000
-        channel_masks AUDIO_CHANNEL_IN_5POINT1|AUDIO_CHANNEL_IN_MONO|AUDIO_CHANNEL_IN_STEREO|AUDIO_CHANNEL_IN_FRONT_BACK
+        channel_masks AUDIO_CHANNEL_IN_5POINT1|AUDIO_CHANNEL_IN_MONO|AUDIO_CHANNEL_IN_STEREO|AUDIO_CHANNEL_IN_FRONT_BACK|AUDIO_CHANNEL_INDEX_MASK_3|AUDIO_CHANNEL_INDEX_MASK_4
         formats AUDIO_FORMAT_PCM_16_BIT
         devices AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_BACK_MIC
       }
       record_24 {
         sampling_rates 8000|11025|12000|16000|22050|24000|32000|44100|48000|96000|192000
-        channel_masks AUDIO_CHANNEL_IN_MONO|AUDIO_CHANNEL_IN_STEREO|AUDIO_CHANNEL_IN_FRONT_BACK
+        channel_masks AUDIO_CHANNEL_IN_MONO|AUDIO_CHANNEL_IN_STEREO|AUDIO_CHANNEL_IN_FRONT_BACK|AUDIO_CHANNEL_INDEX_MASK_3|AUDIO_CHANNEL_INDEX_MASK_4
         formats AUDIO_FORMAT_PCM_24_BIT_PACKED|AUDIO_FORMAT_PCM_8_24_BIT|AUDIO_FORMAT_PCM_FLOAT
         devices AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_BACK_MIC|AUDIO_DEVICE_IN_WIRED_HEADSET
       }
diff --git a/configs/msm8996/audio_policy_configuration.xml b/configs/msm8996/audio_policy_configuration.xml
index 3f30e32..56848ad 100644
--- a/configs/msm8996/audio_policy_configuration.xml
+++ b/configs/msm8996/audio_policy_configuration.xml
@@ -150,18 +150,18 @@
                 <mixPort name="surround_sound" role="sink">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                              samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
-                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK,AUDIO_CHANNEL_IN_5POINT1"/>
+                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK,AUDIO_CHANNEL_INDEX_MASK_3,AUDIO_CHANNEL_INDEX_MASK_4,AUDIO_CHANNEL_IN_5POINT1"/>
                 </mixPort>
                 <mixPort name="record_24" role="sink">
                     <profile name="" format="AUDIO_FORMAT_PCM_24_BIT_PACKED"
                              samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,96000,192000"
-                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK,AUDIO_CHANNEL_INDEX_MASK_3,AUDIO_CHANNEL_INDEX_MASK_4"/>
                     <profile name="" format="AUDIO_FORMAT_PCM_8_24_BIT"
                              samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,96000,192000"
-                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK,AUDIO_CHANNEL_INDEX_MASK_3,AUDIO_CHANNEL_INDEX_MASK_4"/>
                     <profile name="" format="AUDIO_FORMAT_PCM_FLOAT"
                              samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,96000,192000"
-                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK,AUDIO_CHANNEL_INDEX_MASK_3,AUDIO_CHANNEL_INDEX_MASK_4"/>
                 </mixPort>
                 <mixPort name="voice_rx" role="sink">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
diff --git a/configs/msm8996/mixer_paths.xml b/configs/msm8996/mixer_paths.xml
index 7562b3d..1a895fe 100644
--- a/configs/msm8996/mixer_paths.xml
+++ b/configs/msm8996/mixer_paths.xml
@@ -2194,6 +2194,14 @@
         <ctl name="MAD Input" value="DMIC1" />
     </path>
 
+    <path name="unprocessed-handset-mic">
+        <path name="handset-mic" />
+    </path>
+
+    <path name="unprocessed-mic">
+        <path name="unprocessed-handset-mic" />
+    </path>
+
     <!-- Added for ADSP testfwk -->
     <path name="ADSP testfwk">
         <ctl name="SLIMBUS_DL_HL Switch" value="1" />
diff --git a/configs/msm8996/mixer_paths_tasha.xml b/configs/msm8996/mixer_paths_tasha.xml
index 9a97964..360e80b 100644
--- a/configs/msm8996/mixer_paths_tasha.xml
+++ b/configs/msm8996/mixer_paths_tasha.xml
@@ -2492,6 +2492,14 @@
         <ctl name="MAD Input" value="DMIC0" />
     </path>
 
+    <path name="unprocessed-handset-mic">
+        <path name="handset-mic" />
+    </path>
+
+    <path name="unprocessed-mic">
+        <path name="unprocessed-handset-mic" />
+    </path>
+
     <!-- Added for ADSP testfwk -->
     <path name="ADSP testfwk">
         <ctl name="SLIMBUS_DL_HL Switch" value="1" />
diff --git a/configs/msmcobalt/audio_policy.conf b/configs/msmcobalt/audio_policy.conf
index a9f4644..efd1ef3 100644
--- a/configs/msmcobalt/audio_policy.conf
+++ b/configs/msmcobalt/audio_policy.conf
@@ -94,13 +94,13 @@
       }
       surround_sound {
         sampling_rates 8000|11025|12000|16000|22050|24000|32000|44100|48000
-        channel_masks AUDIO_CHANNEL_IN_5POINT1|AUDIO_CHANNEL_IN_MONO|AUDIO_CHANNEL_IN_STEREO|AUDIO_CHANNEL_IN_FRONT_BACK
+        channel_masks AUDIO_CHANNEL_IN_5POINT1|AUDIO_CHANNEL_IN_MONO|AUDIO_CHANNEL_IN_STEREO|AUDIO_CHANNEL_IN_FRONT_BACK|AUDIO_CHANNEL_INDEX_MASK_3|AUDIO_CHANNEL_INDEX_MASK_4
         formats AUDIO_FORMAT_PCM_16_BIT
         devices AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_BACK_MIC
       }
       record_24 {
         sampling_rates 8000|11025|12000|16000|22050|24000|32000|44100|48000|96000|192000
-        channel_masks AUDIO_CHANNEL_IN_MONO|AUDIO_CHANNEL_IN_STEREO|AUDIO_CHANNEL_IN_FRONT_BACK
+        channel_masks AUDIO_CHANNEL_IN_MONO|AUDIO_CHANNEL_IN_STEREO|AUDIO_CHANNEL_IN_FRONT_BACK|AUDIO_CHANNEL_INDEX_MASK_3|AUDIO_CHANNEL_INDEX_MASK_4
         formats AUDIO_FORMAT_PCM_24_BIT_PACKED|AUDIO_FORMAT_PCM_8_24_BIT
         devices AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_BACK_MIC|AUDIO_DEVICE_IN_WIRED_HEADSET
       }
diff --git a/configs/msmcobalt/audio_policy_configuration.xml b/configs/msmcobalt/audio_policy_configuration.xml
index 3f30e32..56848ad 100644
--- a/configs/msmcobalt/audio_policy_configuration.xml
+++ b/configs/msmcobalt/audio_policy_configuration.xml
@@ -150,18 +150,18 @@
                 <mixPort name="surround_sound" role="sink">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                              samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
-                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK,AUDIO_CHANNEL_IN_5POINT1"/>
+                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK,AUDIO_CHANNEL_INDEX_MASK_3,AUDIO_CHANNEL_INDEX_MASK_4,AUDIO_CHANNEL_IN_5POINT1"/>
                 </mixPort>
                 <mixPort name="record_24" role="sink">
                     <profile name="" format="AUDIO_FORMAT_PCM_24_BIT_PACKED"
                              samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,96000,192000"
-                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK,AUDIO_CHANNEL_INDEX_MASK_3,AUDIO_CHANNEL_INDEX_MASK_4"/>
                     <profile name="" format="AUDIO_FORMAT_PCM_8_24_BIT"
                              samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,96000,192000"
-                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK,AUDIO_CHANNEL_INDEX_MASK_3,AUDIO_CHANNEL_INDEX_MASK_4"/>
                     <profile name="" format="AUDIO_FORMAT_PCM_FLOAT"
                              samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,96000,192000"
-                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK,AUDIO_CHANNEL_INDEX_MASK_3,AUDIO_CHANNEL_INDEX_MASK_4"/>
                 </mixPort>
                 <mixPort name="voice_rx" role="sink">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
diff --git a/configs/msmcobalt/mixer_paths.xml b/configs/msmcobalt/mixer_paths.xml
index 7562b3d..1a895fe 100644
--- a/configs/msmcobalt/mixer_paths.xml
+++ b/configs/msmcobalt/mixer_paths.xml
@@ -2194,6 +2194,14 @@
         <ctl name="MAD Input" value="DMIC1" />
     </path>
 
+    <path name="unprocessed-handset-mic">
+        <path name="handset-mic" />
+    </path>
+
+    <path name="unprocessed-mic">
+        <path name="unprocessed-handset-mic" />
+    </path>
+
     <!-- Added for ADSP testfwk -->
     <path name="ADSP testfwk">
         <ctl name="SLIMBUS_DL_HL Switch" value="1" />
diff --git a/configs/msmcobalt/mixer_paths_tasha.xml b/configs/msmcobalt/mixer_paths_tasha.xml
index 93d671d..14bba4e 100644
--- a/configs/msmcobalt/mixer_paths_tasha.xml
+++ b/configs/msmcobalt/mixer_paths_tasha.xml
@@ -2489,6 +2489,14 @@
         <ctl name="MAD Input" value="DMIC0" />
     </path>
 
+    <path name="unprocessed-handset-mic">
+        <path name="handset-mic" />
+    </path>
+
+    <path name="unprocessed-mic">
+        <path name="unprocessed-handset-mic" />
+    </path>
+
     <!-- Added for ADSP testfwk -->
     <path name="ADSP testfwk">
         <ctl name="SLIMBUS_DL_HL Switch" value="1" />
diff --git a/hal/audio_extn/source_track.c b/hal/audio_extn/source_track.c
index c672ffd..0a0b970 100644
--- a/hal/audio_extn/source_track.c
+++ b/hal/audio_extn/source_track.c
@@ -448,8 +448,8 @@
             if ((i >=4) && (sound_focus_data.start_angle[i] == 0xFFFF))
                 continue;
             if (i)
-                snprintf(value + strlen(value) - 1, MAX_STR_SIZE, ",");
-            snprintf(value + strlen(value) - 1, MAX_STR_SIZE, "%d", sound_focus_data.start_angle[i]);
+                snprintf(value + strlen(value), MAX_STR_SIZE - strlen(value) - 1, ",");
+            snprintf(value + strlen(value), MAX_STR_SIZE - strlen(value) - 1, "%d", sound_focus_data.start_angle[i]);
         }
         str_parms_add_str(reply, AUDIO_PARAMETER_KEY_SOUND_FOCUS_START_ANGLES, value);
     }
@@ -460,8 +460,8 @@
             if ((i >=4) && (sound_focus_data.enable[i] == 0xFF))
                 continue;
             if (i)
-                snprintf(value + strlen(value), MAX_STR_SIZE, ",");
-            snprintf(value + strlen(value), MAX_STR_SIZE, "%d", sound_focus_data.enable[i]);
+                snprintf(value + strlen(value), MAX_STR_SIZE - strlen(value) - 1, ",");
+            snprintf(value + strlen(value), MAX_STR_SIZE - strlen(value) - 1, "%d", sound_focus_data.enable[i]);
         }
         str_parms_add_str(reply, AUDIO_PARAMETER_KEY_SOUND_FOCUS_ENABLE_SECTORS, value);
     }
@@ -475,8 +475,8 @@
             if ((i >=4) && (source_tracking_data.vad[i] == 0xFF))
                 continue;
             if (i)
-                snprintf(value + strlen(value) - 1, MAX_STR_SIZE, ",");
-            snprintf(value + strlen(value) - 1, MAX_STR_SIZE, "%d", source_tracking_data.vad[i]);
+                snprintf(value + strlen(value), MAX_STR_SIZE - strlen(value) - 1, ",");
+            snprintf(value + strlen(value), MAX_STR_SIZE - strlen(value) - 1, "%d", source_tracking_data.vad[i]);
         }
         str_parms_add_str(reply, AUDIO_PARAMETER_KEY_SOURCE_TRACK_VAD, value);
     }
@@ -495,8 +495,8 @@
     if (bitmask & BITMASK_AUDIO_PARAMETER_KEY_SOURCE_TRACK_POLAR_ACTIVITY) {
         for (i = 0; i < 360; i++) {
             if (i)
-                snprintf(value + strlen(value) - 1, MAX_STR_SIZE, ",");
-            snprintf(value + strlen(value) - 1, MAX_STR_SIZE, "%d", source_tracking_data.polar_activity[i]);
+                snprintf(value + strlen(value), MAX_STR_SIZE - strlen(value) - 1, ",");
+            snprintf(value + strlen(value), MAX_STR_SIZE - strlen(value) - 1, "%d", source_tracking_data.polar_activity[i]);
         }
         str_parms_add_str(reply, AUDIO_PARAMETER_KEY_SOURCE_TRACK_POLAR_ACTIVITY, value);
     }
diff --git a/hal/audio_extn/spkr_protection.c b/hal/audio_extn/spkr_protection.c
index 8e52402..1f88c71 100644
--- a/hal/audio_extn/spkr_protection.c
+++ b/hal/audio_extn/spkr_protection.c
@@ -96,6 +96,7 @@
 #define WSA_ANALOG_MODE_CHANNELS 2
 
 #define MAX_PATH             (256)
+#define MAX_STR_SIZE         (1024)
 #define THERMAL_SYSFS "/sys/class/thermal"
 #define TZ_TYPE "/sys/class/thermal/thermal_zone%d/type"
 #define TZ_WSA "/sys/class/thermal/thermal_zone%d/temp"
@@ -965,7 +966,8 @@
         ALOGE("%s: failed to open cal file\n", __func__);
         status = -EINVAL;
     }
-    sprintf(param, "SpkrCalStatus: %d; R0: %lf, %lf; T0: %lf, %lf",
+    snprintf(param, MAX_STR_SIZE - strlen(param) - 1,
+            "SpkrCalStatus: %d; R0: %lf, %lf; T0: %lf, %lf",
             status, dr0[SP_V2_SPKR_1], dr0[SP_V2_SPKR_2],
             dt0[SP_V2_SPKR_1], dt0[SP_V2_SPKR_2]);
     ALOGD("%s:: param = %s\n", __func__, param);
@@ -1089,7 +1091,8 @@
             ftm_status[i] = -EINVAL;
         }
     }
-    sprintf(param, "SpkrParamStatus: %d, %d; Rdc: %lf, %lf; Temp: %lf, %lf;"
+    snprintf(param, MAX_STR_SIZE - strlen(param) - 1,
+            "SpkrParamStatus: %d, %d; Rdc: %lf, %lf; Temp: %lf, %lf;"
             " Freq: %lf, %lf; Rect: %lf, %lf; Qmct: %lf, %lf",
             ftm_status[SP_V2_SPKR_1], ftm_status[SP_V2_SPKR_2],
             rdc[SP_V2_SPKR_1], rdc[SP_V2_SPKR_2], temp[SP_V2_SPKR_1],
@@ -1219,7 +1222,7 @@
                                    struct str_parms *reply)
 {
     int err = 0;
-    char value[1024] = {0};
+    char value[MAX_STR_SIZE] = {0};
 
     if (!handle.spkr_prot_enable) {
         ALOGD("%s: Speaker protection disabled", __func__);
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index ad565de..2a7895c 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -2009,6 +2009,8 @@
     switch (channel_count) {
     case 1:
     case 2:
+    case 3:
+    case 4:
     case 6:
         break;
     default:
@@ -3985,8 +3987,10 @@
     bool is_low_latency = false;
 
     *stream_in = NULL;
-    if (check_input_parameters(config->sample_rate, config->format, channel_count) != 0)
+    if (check_input_parameters(config->sample_rate, config->format, channel_count) != 0) {
+        ALOGE("%s: invalid input parameters", __func__);
         return -EINVAL;
+    }
 
     in = (struct stream_in *)calloc(1, sizeof(struct stream_in));
 
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 46611fc..b39b668 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -259,6 +259,8 @@
     char cvd_version[MAX_CVD_VERSION_STRING_SIZE];
     char snd_card_name[MAX_SND_CARD_STRING_SIZE];
     int metainfo_key;
+    int source_mic_type;
+    int max_mic_count;
 };
 
 static bool is_external_codec = false;
@@ -441,6 +443,12 @@
     [SND_DEVICE_IN_SPEAKER_QMIC_NS] = "quad-mic",
     [SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = "quad-mic",
     [SND_DEVICE_IN_THREE_MIC] = "three-mic",
+    [SND_DEVICE_IN_HANDSET_TMIC] = "three-mic",
+    [SND_DEVICE_IN_UNPROCESSED_MIC] = "unprocessed-mic",
+    [SND_DEVICE_IN_UNPROCESSED_STEREO_MIC] = "voice-rec-dmic-ef",
+    [SND_DEVICE_IN_UNPROCESSED_THREE_MIC] = "three-mic",
+    [SND_DEVICE_IN_UNPROCESSED_QUAD_MIC] = "quad-mic",
+    [SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC] = "headset-mic",
 };
 
 // Platform specific backend bit width table
@@ -552,7 +560,13 @@
     [SND_DEVICE_IN_SPEAKER_QMIC_AEC] = 126,
     [SND_DEVICE_IN_SPEAKER_QMIC_NS] = 127,
     [SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = 129,
-    [SND_DEVICE_IN_THREE_MIC] = 46,
+    [SND_DEVICE_IN_THREE_MIC] = 46, /* for APSS Surround Sound Recording */
+    [SND_DEVICE_IN_HANDSET_TMIC] = 125, /* for 3mic recording with fluence */
+    [SND_DEVICE_IN_UNPROCESSED_MIC] = 143,
+    [SND_DEVICE_IN_UNPROCESSED_STEREO_MIC] = 144,
+    [SND_DEVICE_IN_UNPROCESSED_THREE_MIC] = 145,
+    [SND_DEVICE_IN_UNPROCESSED_QUAD_MIC] = 146,
+    [SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC] = 147,
 };
 
 struct name_to_index {
@@ -666,6 +680,13 @@
     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_NS)},
     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_THREE_MIC)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_TMIC)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_MIC)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_STEREO_MIC)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_THREE_MIC)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_QUAD_MIC)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC)},
 };
 
 static char * backend_tag_table[SND_DEVICE_MAX] = {0};
@@ -1143,7 +1164,7 @@
 }
 
 
-static void set_platform_defaults()
+static void set_platform_defaults(struct platform_data * my_data)
 {
     int32_t dev, count = 0;
     const char *MEDIA_MIMETYPE_AUDIO_ALAC = "audio/alac";
@@ -1182,6 +1203,7 @@
     hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = strdup("SLIMBUS_0_RX-and-HDMI_RX");
     hw_interface_table[SND_DEVICE_OUT_VOICE_TX] = strdup("AFE_PCM_RX");
 
+    my_data->max_mic_count = PLATFORM_DEFAULT_MIC_COUNT;
     /*remove ALAC & APE from DSP decoder list based on software decoder availability*/
     for (count = 0; count < (int32_t) (sizeof(dsp_only_decoders_mime)/sizeof(dsp_only_decoders_mime[0]));
             count++) {
@@ -1521,6 +1543,27 @@
     return found;
 }
 
+static void get_source_mic_type(struct platform_data * my_data)
+{
+    // 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;
+    }
+}
+
 void *platform_init(struct audio_device *adev)
 {
     char value[PROPERTY_VALUE_MAX];
@@ -1776,7 +1819,7 @@
 
 acdb_init_fail:
 
-    set_platform_defaults();
+    set_platform_defaults(my_data);
 
     /* Initialize ACDB and PCM ID's */
     if (is_external_codec)
@@ -1784,6 +1827,14 @@
     else
         platform_info_init(PLATFORM_INFO_XML_PATH, my_data);
 
+    /* obtain source mic type from max mic count*/
+    get_source_mic_type(my_data);
+    ALOGD("%s: Fluence_Type(%d) max_mic_count(%d) mic_type(0x%x) fluence_in_voice_call(%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_rec,
+          my_data->fluence_in_spkr_mode);
+
     /* init usb */
     audio_extn_usb_init(adev);
     /* update sound cards appropriately */
@@ -2000,7 +2051,7 @@
     const char * be_itf2 = hw_interface_table[snd_device2];
 
     if (NULL != be_itf1 && NULL != be_itf2) {
-        if (0 != strcmp(be_itf1, be_itf2))
+        if ((NULL == strstr(be_itf2, be_itf1)) && (NULL == strstr(be_itf1, be_itf2)))
             result = false;
     } else if (NULL == be_itf1 && NULL != be_itf2) {
             result = false;
@@ -2957,8 +3008,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 (my_data->external_mic) {
         if ((out_device != AUDIO_DEVICE_NONE) && ((mode == AUDIO_MODE_IN_CALL) ||
             voice_extn_compress_voip_is_active(adev) || audio_extn_hfp_is_active(adev))) {
@@ -3004,7 +3055,8 @@
             out_device & AUDIO_DEVICE_OUT_LINE) {
             if (out_device & AUDIO_DEVICE_OUT_EARPIECE &&
                 audio_extn_should_use_handset_anc(channel_count) &&
-                my_data->fluence_type != FLUENCE_NONE) {
+                my_data->fluence_type != FLUENCE_NONE &&
+                my_data->source_mic_type & SOURCE_DUAL_MIC) {
                 snd_device = SND_DEVICE_IN_VOICE_FLUENCE_DMIC_AANC;
                 adev->acdb_settings |= DMIC_FLAG;
                 ALOGD("Selecting AANC, Fluence combo device");
@@ -3041,7 +3093,8 @@
             if (my_data->fluence_type != FLUENCE_NONE &&
                 my_data->fluence_in_voice_call &&
                 my_data->fluence_in_spkr_mode) {
-                if(my_data->fluence_type & FLUENCE_QUAD_MIC) {
+                if((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+                   (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
                     adev->acdb_settings |= QMIC_FLAG;
                     snd_device = SND_DEVICE_IN_VOICE_SPEAKER_QMIC;
                 } else {
@@ -3061,26 +3114,62 @@
     } else if (source == AUDIO_SOURCE_CAMCORDER) {
         if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
             in_device & AUDIO_DEVICE_IN_BACK_MIC) {
-            if (my_data->fluence_type & FLUENCE_DUAL_MIC &&
-                channel_count == 2)
+            if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+                (my_data->source_mic_type & SOURCE_DUAL_MIC) &&
+                (channel_count == 2))
                 snd_device = SND_DEVICE_IN_HANDSET_STEREO_DMIC;
             else
                 snd_device = SND_DEVICE_IN_CAMCORDER_MIC;
         }
     } else if (source == AUDIO_SOURCE_VOICE_RECOGNITION) {
         if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
-            if (channel_count == 2) {
+            if (my_data->fluence_in_voice_rec && channel_count == 1) {
+                if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+                    (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
+                     snd_device = SND_DEVICE_IN_HANDSET_QMIC;
+                } else if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+                    (my_data->source_mic_type & SOURCE_THREE_MIC)) {
+                    snd_device = SND_DEVICE_IN_HANDSET_TMIC;
+                } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+                    (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) ||
+                       (channel_mask == AUDIO_CHANNEL_IN_STEREO)) &&
+                       (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
                 snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_STEREO;
-                adev->acdb_settings |= DMIC_FLAG;
-            } else if (adev->active_input->enable_ns)
-                snd_device = SND_DEVICE_IN_VOICE_REC_MIC_NS;
-            else if (my_data->fluence_type != FLUENCE_NONE &&
-                     my_data->fluence_in_voice_rec) {
-                snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE;
-                adev->acdb_settings |= DMIC_FLAG;
-            } else {
-                snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
+            } 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;
+                else
+                    snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
+            }
+      }
+    } else if (source == AUDIO_SOURCE_UNPROCESSED) {
+        if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
+            if (((channel_mask == AUDIO_CHANNEL_IN_FRONT_BACK) ||
+                (channel_mask == AUDIO_CHANNEL_IN_STEREO)) &&
+                (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+                snd_device = SND_DEVICE_IN_UNPROCESSED_STEREO_MIC;
+            } else if (((int)channel_mask == AUDIO_CHANNEL_INDEX_MASK_3) &&
+                (my_data->source_mic_type & SOURCE_THREE_MIC)) {
+                snd_device = SND_DEVICE_IN_UNPROCESSED_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_UNPROCESSED_QUAD_MIC;
+            } else {
+                snd_device = SND_DEVICE_IN_UNPROCESSED_MIC;
+            }
+        } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
+            snd_device = SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC;
         }
     } else if ((source == AUDIO_SOURCE_VOICE_COMMUNICATION) ||
               (mode == AUDIO_MODE_IN_COMMUNICATION)) {
@@ -3092,9 +3181,11 @@
                 adev->active_input->enable_ns) {
                 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
                     if (my_data->fluence_in_spkr_mode) {
-                        if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
+                        if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+                             (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
                             snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS;
-                        } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+                        } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+                             (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
                             if (my_data->fluence_mode == FLUENCE_BROADSIDE)
                                 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE;
                             else
@@ -3104,7 +3195,8 @@
                     } else
                         snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC_NS;
                 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
-                    if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+                    if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+                        (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
                         snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC_NS;
                         adev->acdb_settings |= DMIC_FLAG;
                     } else
@@ -3117,9 +3209,11 @@
                        adev->active_input->enable_aec) {
                 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
                     if (my_data->fluence_in_spkr_mode) {
-                        if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
+                        if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+                            (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
                             snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC;
-                        } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+                        } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+                            (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
                             if (my_data->fluence_mode == FLUENCE_BROADSIDE)
                                 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_BROADSIDE;
                             else
@@ -3129,7 +3223,8 @@
                     } else
                         snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
                 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
-                    if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+                    if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+                        (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
                         snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC;
                         adev->acdb_settings |= DMIC_FLAG;
                     } else
@@ -3142,9 +3237,11 @@
                        adev->active_input->enable_ns) {
                 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
                     if (my_data->fluence_in_spkr_mode) {
-                        if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
+                        if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+                            (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
                             snd_device = SND_DEVICE_IN_SPEAKER_QMIC_NS;
-                        } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+                        } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+                            (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
                             if (my_data->fluence_mode == FLUENCE_BROADSIDE)
                                 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS_BROADSIDE;
                             else
@@ -3154,7 +3251,8 @@
                     } else
                         snd_device = SND_DEVICE_IN_SPEAKER_MIC_NS;
                 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
-                    if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+                    if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+                        (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
                         snd_device = SND_DEVICE_IN_HANDSET_DMIC_NS;
                         adev->acdb_settings |= DMIC_FLAG;
                     } else
@@ -3170,10 +3268,15 @@
         if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC &&
                 channel_count == 1 ) {
             if(my_data->fluence_in_audio_rec) {
-                if(my_data->fluence_type & FLUENCE_QUAD_MIC) {
+                if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+                    (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
                     snd_device = SND_DEVICE_IN_HANDSET_QMIC;
                     platform_set_echo_reference(adev, true, out_device);
-                } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+                } else if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+                    (my_data->source_mic_type & SOURCE_THREE_MIC)) {
+                    snd_device = SND_DEVICE_IN_HANDSET_TMIC;
+                } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+                    (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
                     snd_device = SND_DEVICE_IN_HANDSET_DMIC;
                     platform_set_echo_reference(adev, true, out_device);
                 }
@@ -3198,8 +3301,8 @@
         if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
             if (adev->active_input && (audio_extn_ssr_get_stream() == adev->active_input))
                 snd_device = SND_DEVICE_IN_QUAD_MIC;
-            else if (my_data->fluence_type & (FLUENCE_DUAL_MIC | FLUENCE_QUAD_MIC) &&
-                    channel_count == 2)
+            else if ((my_data->fluence_type & (FLUENCE_DUAL_MIC | FLUENCE_QUAD_MIC)) &&
+                    (channel_count == 2) && (my_data->source_mic_type & SOURCE_DUAL_MIC))
                 snd_device = SND_DEVICE_IN_HANDSET_STEREO_DMIC;
             else
                 snd_device = SND_DEVICE_IN_HANDSET_MIC;
@@ -3237,7 +3340,7 @@
         } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
             snd_device = SND_DEVICE_IN_HEADSET_MIC;
         } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
-            if (channel_count > 1)
+            if ((channel_count > 1) && (my_data->source_mic_type & SOURCE_DUAL_MIC))
                 snd_device = SND_DEVICE_IN_SPEAKER_STEREO_DMIC;
             else
                 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
@@ -3471,6 +3574,15 @@
         }
     }
 #endif
+
+   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 %d", __func__, my_data->max_mic_count);
+    }
+
     native_audio_set_params(platform, parms, value, sizeof(value));
     audio_extn_spkr_prot_set_parameters(parms, value, len);
     ALOGV("%s: exit with code(%d)", __func__, ret);
diff --git a/hal/msm8916/platform.h b/hal/msm8916/platform.h
index 9380561..aef905d 100644
--- a/hal/msm8916/platform.h
+++ b/hal/msm8916/platform.h
@@ -32,6 +32,13 @@
     FLUENCE_BROADSIDE = 0x2,
 };
 
+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 */
+};
+
 #define PLATFORM_IMAGE_NAME "modem"
 
 /*
@@ -178,6 +185,12 @@
     SND_DEVICE_IN_SPEAKER_QMIC_NS,
     SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS,
     SND_DEVICE_IN_THREE_MIC,
+    SND_DEVICE_IN_HANDSET_TMIC,
+    SND_DEVICE_IN_UNPROCESSED_MIC,
+    SND_DEVICE_IN_UNPROCESSED_STEREO_MIC,
+    SND_DEVICE_IN_UNPROCESSED_THREE_MIC,
+    SND_DEVICE_IN_UNPROCESSED_QUAD_MIC,
+    SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC,
     SND_DEVICE_IN_END,
 
     SND_DEVICE_MAX = SND_DEVICE_IN_END,
@@ -278,6 +291,9 @@
 #define AFE_PROXY_PLAYBACK_PCM_DEVICE 7
 #define AFE_PROXY_RECORD_PCM_DEVICE 8
 
+#define PLATFORM_MAX_MIC_COUNT "input_mic_max_count"
+#define PLATFORM_DEFAULT_MIC_COUNT 2
+
 #define LIB_CSD_CLIENT "libcsd-client.so"
 /* CSD-CLIENT related functions */
 typedef int (*init_t)();
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index c0e4088..fe7e1c1 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -94,6 +94,7 @@
 #define SAD_BLOCK_SIZE      3
 
 #define MAX_CVD_VERSION_STRING_SIZE    100
+#define MAX_SND_CARD_STRING_SIZE    100
 
 /* EDID format ID for LPCM audio */
 #define EDID_FORMAT_LPCM    1
@@ -121,6 +122,9 @@
 
 #define AUDIO_PARAMETER_KEY_PERF_LOCK_OPTS "perf_lock_opts"
 
+/* Reload ACDB files from specified path */
+#define AUDIO_PARAMETER_KEY_RELOAD_ACDB "reload_acdb"
+
 /* Query external audio device connection status */
 #define AUDIO_PARAMETER_KEY_EXT_AUDIO_DEVICE "ext_audio_device"
 
@@ -191,6 +195,7 @@
 typedef int (*acdb_get_audio_cal_t) (void *, void *, uint32_t*);
 typedef int (*acdb_send_common_top_t) (void);
 typedef int (*acdb_set_codec_data_t) (void *, char *);
+typedef int (*acdb_reload_t) (char *, char *, char *, int);
 
 typedef struct codec_backend_cfg {
     uint32_t sample_rate;
@@ -235,7 +240,7 @@
     acdb_get_default_app_type_t acdb_get_default_app_type;
     acdb_send_common_top_t     acdb_send_common_top;
     acdb_set_codec_data_t      acdb_set_codec_data;
-
+    acdb_reload_t              acdb_reload;
     void *hw_info;
     acdb_send_gain_dep_cal_t   acdb_send_gain_dep_cal;
     struct csd_data *csd;
@@ -246,6 +251,11 @@
     codec_backend_cfg_t current_tx_backend_cfg[MAX_CODEC_TX_BACKENDS];
     char codec_version[CODEC_VERSION_MAX_LENGTH];
     int hw_dep_fd;
+    char cvd_version[MAX_CVD_VERSION_STRING_SIZE];
+    char snd_card_name[MAX_SND_CARD_STRING_SIZE];
+    int metainfo_key;
+    int source_mic_type;
+    int max_mic_count;
 };
 
 static int pcm_device_table[AUDIO_USECASE_MAX][2] = {
@@ -425,6 +435,12 @@
     [SND_DEVICE_IN_SPEAKER_QMIC_NS] = "quad-mic",
     [SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = "quad-mic",
     [SND_DEVICE_IN_THREE_MIC] = "three-mic",
+    [SND_DEVICE_IN_HANDSET_TMIC] = "three-mic",
+    [SND_DEVICE_IN_UNPROCESSED_MIC] = "unprocessed-mic",
+    [SND_DEVICE_IN_UNPROCESSED_STEREO_MIC] = "voice-rec-dmic-ef",
+    [SND_DEVICE_IN_UNPROCESSED_THREE_MIC] = "three-mic",
+    [SND_DEVICE_IN_UNPROCESSED_QUAD_MIC] = "quad-mic",
+    [SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC] = "headset-mic",
 };
 
 // Platform specific backend bit width table
@@ -530,7 +546,13 @@
     [SND_DEVICE_IN_SPEAKER_QMIC_AEC] = 126,
     [SND_DEVICE_IN_SPEAKER_QMIC_NS] = 127,
     [SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = 129,
-    [SND_DEVICE_IN_THREE_MIC] = 46,
+    [SND_DEVICE_IN_THREE_MIC] = 46, /* for APSS Surround Sound Recording */
+    [SND_DEVICE_IN_HANDSET_TMIC] = 125, /* for 3mic recording with fluence */
+    [SND_DEVICE_IN_UNPROCESSED_MIC] = 143,
+    [SND_DEVICE_IN_UNPROCESSED_STEREO_MIC] = 144,
+    [SND_DEVICE_IN_UNPROCESSED_THREE_MIC] = 145,
+    [SND_DEVICE_IN_UNPROCESSED_QUAD_MIC] = 146,
+    [SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC] = 147,
 };
 
 struct name_to_index {
@@ -635,6 +657,13 @@
     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_NS)},
     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_THREE_MIC)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_TMIC)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_MIC)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_STEREO_MIC)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_THREE_MIC)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_QUAD_MIC)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC)},
 };
 
 static char * backend_tag_table[SND_DEVICE_MAX] = {0};
@@ -1034,7 +1063,7 @@
     return plat_data->is_i2s_ext_modem;
 }
 
-static void set_platform_defaults()
+static void set_platform_defaults(struct platform_data * my_data)
 {
     int32_t dev;
     unsigned int count = 0;
@@ -1075,6 +1104,7 @@
     hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = strdup("SLIMBUS_0_RX-and-HDMI_RX");
     hw_interface_table[SND_DEVICE_OUT_VOICE_TX] = strdup("AFE_PCM_RX");
 
+    my_data->max_mic_count = PLATFORM_DEFAULT_MIC_COUNT;
 
      /*remove ALAC & APE from DSP decoder list based on software decoder availability*/
      for (count = 0; count < (int32_t)(sizeof(dsp_only_decoders_mime)/sizeof(dsp_only_decoders_mime[0]));
@@ -1290,6 +1320,14 @@
     key = atoi(value);
     snd_card_name = mixer_get_name(my_data->adev->mixer);
     result = my_data->acdb_init(snd_card_name, cvd_version, key);
+
+    /* Save these variables in platform_data. These will be used
+       while reloading ACDB files during run time. */
+    strlcpy(my_data->cvd_version, cvd_version, MAX_CVD_VERSION_STRING_SIZE);
+    strlcpy(my_data->snd_card_name, snd_card_name,
+                                               MAX_SND_CARD_STRING_SIZE);
+    my_data->metainfo_key = key;
+
     if (cvd_version)
         free(cvd_version);
     if (!result) {
@@ -1303,6 +1341,27 @@
     return result;
 }
 
+static void get_source_mic_type(struct platform_data * my_data)
+{
+    // 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;
+    }
+}
+
 void *platform_init(struct audio_device *adev)
 {
     char platform[PROPERTY_VALUE_MAX];
@@ -1572,12 +1631,18 @@
             goto acdb_init_fail;
         }
 
+        my_data->acdb_reload = (acdb_reload_t)dlsym(my_data->acdb_handle,
+                                                    "acdb_loader_reload_acdb_files");
+        if (my_data->acdb_reload == NULL) {
+            ALOGE("%s: dlsym error %s for acdb_loader_reload_acdb_files", __func__, dlerror());
+            goto acdb_init_fail;
+        }
         platform_acdb_init(my_data);
     }
 
 acdb_init_fail:
 
-    set_platform_defaults();
+    set_platform_defaults(my_data);
 
     /* Initialize ACDB ID's */
     if (my_data->is_i2s_ext_modem)
@@ -1598,6 +1663,14 @@
          my_data->csd = NULL;
     }
 
+    /* obtain source mic type from max mic count*/
+    get_source_mic_type(my_data);
+    ALOGD("%s: Fluence_Type(%d) max_mic_count(%d) mic_type(0x%x) fluence_in_voice_call(%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_rec,
+          my_data->fluence_in_spkr_mode);
+
     /* init usb */
     audio_extn_usb_init(adev);
     /* update sound cards appropriately */
@@ -1797,7 +1870,7 @@
     const char * be_itf2 = hw_interface_table[snd_device2];
 
     if (NULL != be_itf1 && NULL != be_itf2) {
-        if (0 != strcmp(be_itf1, be_itf2))
+        if ((NULL == strstr(be_itf2, be_itf1)) && (NULL == strstr(be_itf1, be_itf2)))
             result = false;
     } else if (NULL == be_itf1 && NULL != be_itf2) {
             result = false;
@@ -2694,8 +2767,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 (my_data->external_mic) {
         if ((out_device != AUDIO_DEVICE_NONE) && ((mode == AUDIO_MODE_IN_CALL) ||
             voice_extn_compress_voip_is_active(adev) || audio_extn_hfp_is_active(adev))) {
@@ -2740,7 +2813,8 @@
                 out_device & AUDIO_DEVICE_OUT_LINE) {
             if (out_device & AUDIO_DEVICE_OUT_EARPIECE &&
                 audio_extn_should_use_handset_anc(channel_count)) {
-                if(my_data->fluence_type != FLUENCE_NONE) {
+                if ((my_data->fluence_type != FLUENCE_NONE) &&
+                    (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
                     snd_device = SND_DEVICE_IN_VOICE_FLUENCE_DMIC_AANC;
                     adev->acdb_settings |= DMIC_FLAG;
                 } else {
@@ -2775,7 +2849,8 @@
             if (my_data->fluence_type != FLUENCE_NONE &&
                 my_data->fluence_in_voice_call &&
                 my_data->fluence_in_spkr_mode) {
-                if(my_data->fluence_type & FLUENCE_QUAD_MIC) {
+                if((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+                   (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
                     snd_device = SND_DEVICE_IN_VOICE_SPEAKER_QMIC;
                 } else {
                     if (my_data->fluence_mode == FLUENCE_BROADSIDE)
@@ -2797,22 +2872,54 @@
         }
     } else if (source == AUDIO_SOURCE_VOICE_RECOGNITION) {
         if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
-            if (channel_count == 2) {
-                snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_STEREO;
-            } else if (my_data->fluence_type != FLUENCE_NONE &&
-                     my_data->fluence_in_voice_rec) {
-                if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
-                    snd_device = SND_DEVICE_IN_HANDSET_QMIC;
-                } else {
+            if (my_data->fluence_in_voice_rec && channel_count == 1) {
+                if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+                    (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
+                     snd_device = SND_DEVICE_IN_HANDSET_QMIC;
+                } else if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+                    (my_data->source_mic_type & SOURCE_THREE_MIC)) {
+                    snd_device = SND_DEVICE_IN_HANDSET_TMIC;
+                } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+                    (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
                     snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE;
                 }
-                platform_set_echo_reference(adev->platform, true, out_device);
-            } else if (adev->active_input->enable_ns) {
-                snd_device = SND_DEVICE_IN_VOICE_REC_MIC_NS;
-            } else {
-                snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
+                platform_set_echo_reference(adev, true, out_device);
+            } else if (((channel_mask == AUDIO_CHANNEL_IN_FRONT_BACK) ||
+                       (channel_mask == AUDIO_CHANNEL_IN_STEREO)) &&
+                       (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;
+                else
+                    snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
             }
         }
+    } else if (source == AUDIO_SOURCE_UNPROCESSED) {
+         if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
+             if (((channel_mask == AUDIO_CHANNEL_IN_FRONT_BACK) ||
+                 (channel_mask == AUDIO_CHANNEL_IN_STEREO)) &&
+                 (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+                 snd_device = SND_DEVICE_IN_UNPROCESSED_STEREO_MIC;
+             } else if (((int)channel_mask == AUDIO_CHANNEL_INDEX_MASK_3) &&
+                 (my_data->source_mic_type & SOURCE_THREE_MIC)) {
+                 snd_device = SND_DEVICE_IN_UNPROCESSED_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_UNPROCESSED_QUAD_MIC;
+             } else {
+                 snd_device = SND_DEVICE_IN_UNPROCESSED_MIC;
+             }
+         } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
+             snd_device = SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC;
+         }
     } else if (source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
         if (out_device & AUDIO_DEVICE_OUT_SPEAKER)
             in_device = AUDIO_DEVICE_IN_BACK_MIC;
@@ -2821,9 +2928,11 @@
                     adev->active_input->enable_ns) {
                 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
                     if (my_data->fluence_in_spkr_mode) {
-                        if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
+                        if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+                            (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
                             snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS;
-                        } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+                        } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+                                   (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
                             if (my_data->fluence_mode == FLUENCE_BROADSIDE)
                                 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE;
                             else
@@ -2832,9 +2941,10 @@
                     } else
                         snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC_NS;
                 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
-                    if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+                    if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+                        (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_FLUENCE;
@@ -2843,9 +2953,11 @@
             } else if (adev->active_input->enable_aec) {
                 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
                     if (my_data->fluence_in_spkr_mode) {
-                        if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
+                        if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+                            (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
                             snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC;
-                        } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+                        } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+                                   (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
                             if (my_data->fluence_mode == FLUENCE_BROADSIDE)
                                 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_BROADSIDE;
                             else
@@ -2854,9 +2966,10 @@
                     } else
                         snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
                 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
-                    if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+                    if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+                        (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_FLUENCE;
@@ -2865,9 +2978,11 @@
             } else if (adev->active_input->enable_ns) {
                 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
                     if (my_data->fluence_in_spkr_mode) {
-                        if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
+                        if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+                            (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
                             snd_device = SND_DEVICE_IN_SPEAKER_QMIC_NS;
-                        } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+                        } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+                                   (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
                             if (my_data->fluence_mode == FLUENCE_BROADSIDE)
                                 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS_BROADSIDE;
                             else
@@ -2876,9 +2991,10 @@
                     } else
                         snd_device = SND_DEVICE_IN_SPEAKER_MIC_NS;
                 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
-                    if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+                    if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+                        (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;
                 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
                     snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
@@ -2891,10 +3007,15 @@
         if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC &&
                 channel_count == 1 ) {
             if(my_data->fluence_in_audio_rec) {
-                if(my_data->fluence_type & FLUENCE_QUAD_MIC) {
+                if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+                    (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
                     snd_device = SND_DEVICE_IN_HANDSET_QMIC;
                     platform_set_echo_reference(adev, true, out_device);
-                } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+                } else if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+                    (my_data->source_mic_type & SOURCE_THREE_MIC)) {
+                    snd_device = SND_DEVICE_IN_HANDSET_TMIC;
+                } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+                    (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
                     snd_device = SND_DEVICE_IN_HANDSET_DMIC;
                     platform_set_echo_reference(adev, true, out_device);
                 }
@@ -2919,8 +3040,8 @@
         if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
             if (adev->active_input && (audio_extn_ssr_get_stream() == adev->active_input))
                 snd_device = SND_DEVICE_IN_QUAD_MIC;
-            else if (my_data->fluence_type & (FLUENCE_DUAL_MIC | FLUENCE_QUAD_MIC) &&
-                    channel_count == 2)
+            else if ((my_data->fluence_type & (FLUENCE_DUAL_MIC | FLUENCE_QUAD_MIC)) &&
+                    (channel_count == 2) && (my_data->source_mic_type & SOURCE_DUAL_MIC))
                 snd_device = SND_DEVICE_IN_HANDSET_STEREO_DMIC;
             else
                 snd_device = SND_DEVICE_IN_HANDSET_MIC;
@@ -2958,10 +3079,18 @@
         } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
             snd_device = SND_DEVICE_IN_HEADSET_MIC;
         } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
-            if (channel_count == 2)
+            if ((my_data->source_mic_type & SOURCE_DUAL_MIC) &&
+                (channel_count == 2)) {
                 snd_device = SND_DEVICE_IN_SPEAKER_STEREO_DMIC;
-            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: 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_WIRED_HEADPHONE ||
                         out_device & AUDIO_DEVICE_OUT_LINE) {
             snd_device = SND_DEVICE_IN_HANDSET_MIC;
@@ -3372,6 +3501,16 @@
         }
     }
 
+    err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_RELOAD_ACDB,
+                            value, len);
+    if (err >= 0) {
+        str_parms_del(parms, AUDIO_PARAMETER_KEY_RELOAD_ACDB);
+
+        my_data->acdb_reload(value, my_data->snd_card_name,
+                              my_data->cvd_version, my_data->metainfo_key);
+
+    }
+
     err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_EXT_AUDIO_DEVICE,
                             value, len);
     if (err >= 0) {
@@ -3394,6 +3533,14 @@
         update_external_device_status(my_data, event_name, status);
     }
 
+    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 %d", __func__, my_data->max_mic_count);
+    }
+
     /* handle audio calibration parameters */
     set_audiocal(platform, parms, value, len);
     native_audio_set_params(platform, parms, value, len);
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index 7fe7271..52f0bac 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -32,6 +32,13 @@
     FLUENCE_BROADSIDE = 0x2,
 };
 
+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
@@ -171,6 +178,12 @@
     SND_DEVICE_IN_SPEAKER_QMIC_NS,
     SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS,
     SND_DEVICE_IN_THREE_MIC,
+    SND_DEVICE_IN_HANDSET_TMIC,
+    SND_DEVICE_IN_UNPROCESSED_MIC,
+    SND_DEVICE_IN_UNPROCESSED_STEREO_MIC,
+    SND_DEVICE_IN_UNPROCESSED_THREE_MIC,
+    SND_DEVICE_IN_UNPROCESSED_QUAD_MIC,
+    SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC,
     SND_DEVICE_IN_END,
 
     SND_DEVICE_MAX = SND_DEVICE_IN_END,
@@ -371,6 +384,9 @@
 #define FM_RX_VOLUME "Internal FM RX Volume"
 #endif
 
+#define PLATFORM_MAX_MIC_COUNT "input_mic_max_count"
+#define PLATFORM_DEFAULT_MIC_COUNT 2
+
 #define LIB_CSD_CLIENT "libcsd-client.so"
 /* CSD-CLIENT related functions */
 typedef int (*init_t)(bool);