Merge "configs: Add initial value for mixers of ADSP SVA"
diff --git a/configs/msm8909/msm8909.mk b/configs/msm8909/msm8909.mk
index 89a6d13..bc475c6 100644
--- a/configs/msm8909/msm8909.mk
+++ b/configs/msm8909/msm8909.mk
@@ -168,4 +168,10 @@
     android.hardware.audio@2.0-service \
     android.hardware.audio@2.0-impl \
     android.hardware.audio.effect@2.0-impl \
-    android.hardware.soundtrigger@2.0-impl
+    android.hardware.soundtrigger@2.0-impl \
+    android.hardware.audio@4.0 \
+    android.hardware.audio.common@4.0 \
+    android.hardware.audio.common@4.0-util \
+    android.hardware.audio@4.0-impl \
+    android.hardware.audio.effect@4.0 \
+    android.hardware.audio.effect@4.0-impl
diff --git a/configs/msmnile/audio_policy_configuration.xml b/configs/msmnile/audio_policy_configuration.xml
index 45598dc..a8ae093 100644
--- a/configs/msmnile/audio_policy_configuration.xml
+++ b/configs/msmnile/audio_policy_configuration.xml
@@ -370,7 +370,7 @@
                 <route type="mix" sink="USB Headset Out"
                        sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,hifi_playback"/>
                 <route type="mix" sink="Telephony Tx"
-                       sources="voice_tx"/>
+                       sources="voice_tx,incall_music_uplink"/>
                 <route type="mix" sink="voice_rx"
                        sources="Telephony Rx"/>
                 <route type="mix" sink="primary input"
diff --git a/configs/msmnile/mixer_paths_tavil.xml b/configs/msmnile/mixer_paths_tavil.xml
index a3cf0e1..b2c8be2 100644
--- a/configs/msmnile/mixer_paths_tavil.xml
+++ b/configs/msmnile/mixer_paths_tavil.xml
@@ -2992,76 +2992,79 @@
         <ctl name="MultiMedia2 Mixer USB_AUDIO_TX" value="1" />
     </path>
 
-    <path name="incall-music-uplink">
+    <path name="incall_music_uplink">
         <ctl name="Incall_Music Audio Mixer MultiMedia9" value="1" />
     </path>
 
-    <path name="incall-music-uplink speaker">
-        <path name="incall-music-uplink" />
+    <path name="incall_music_uplink speaker">
+        <path name="incall_music_uplink" />
     </path>
 
-    <path name="incall-music-uplink handset">
-        <path name="incall-music-uplink" />
+    <path name="incall_music_uplink handset">
+        <path name="incall_music_uplink" />
     </path>
 
-    <path name="incall-music-uplink handset-hac">
-        <path name="incall-music-uplink" />
+    <path name="incall_music_uplink handset-hac">
+        <path name="incall_music_uplink" />
     </path>
 
-    <path name="incall-music-uplink display-port">
-        <path name="incall-music-uplink" />
+    <path name="incall_music_uplink display-port">
+        <path name="incall_music_uplink" />
     </path>
 
-    <path name="incall-music-uplink bt-sco">
-        <path name="incall-music-uplink" />
+    <path name="incall_music_uplink bt-sco">
+        <path name="incall_music_uplink" />
     </path>
 
-    <path name="incall-music-uplink bt-sco-wb">
-        <path name="incall-music-uplink" />
+    <path name="incall_music_uplink bt-sco-wb">
+        <path name="incall_music_uplink" />
     </path>
 
-    <path name="incall-music-uplink speaker-and-display-port">
-        <path name="incall-music-uplink" />
+    <path name="incall_music_uplink speaker-and-display-port">
+        <path name="incall_music_uplink" />
     </path>
 
-    <path name="incall-music-uplink afe-proxy">
-        <path name="incall-music-uplink" />
+    <path name="incall_music_uplink afe-proxy">
+        <path name="incall_music_uplink" />
     </path>
 
-    <path name="incall-music-uplink usb-headphones">
-        <path name="incall-music-uplink" />
+    <path name="incall_music_uplink usb-headphones">
+        <path name="incall_music_uplink" />
     </path>
 
-    <path name="incall-music-uplink usb-headset">
-        <path name="incall-music-uplink" />
+    <path name="incall_music_uplink usb-headset">
+        <path name="incall_music_uplink" />
     </path>
 
-    <path name="incall-music-uplink speaker-and-usb-headphones">
-        <path name="incall-music-uplink" />
+    <path name="incall_music_uplink speaker-and-usb-headphones">
+        <path name="incall_music_uplink" />
     </path>
 
-    <path name="incall-music-uplink headphones">
-        <path name="incall-music-uplink" />
+    <path name="incall_music_uplink headphones">
+        <path name="incall_music_uplink" />
     </path>
 
-    <path name="incall-music-uplink speaker-and-headphones">
-        <path name="incall-music-uplink" />
+    <path name="incall_music_uplink speaker-and-headphones">
+        <path name="incall_music_uplink" />
     </path>
 
-    <path name="incall-music-uplink speaker-and-bt-sco">
-        <path name="incall-music-uplink" />
+    <path name="incall_music_uplink speaker-and-bt-sco">
+        <path name="incall_music_uplink" />
     </path>
 
-    <path name="incall-music-uplink voice-tty-hco-handset">
-        <path name="incall-music-uplink" />
+    <path name="incall_music_uplink voice-tty-hco-handset">
+        <path name="incall_music_uplink" />
     </path>
 
-    <path name="incall-music-uplink speaker-and-bt-a2dp">
-        <path name="incall-music-uplink" />
+    <path name="incall_music_uplink speaker-and-bt-a2dp">
+        <path name="incall_music_uplink" />
     </path>
 
-    <path name="incall-music-uplink bt-a2dp">
-        <path name="incall-music-uplink" />
+    <path name="incall_music_uplink bt-a2dp">
+        <path name="incall_music_uplink" />
     </path>
 
+    <path name="incall_music_uplink afe-proxy">
+        <path name="incall_music_uplink" />
+    </path>
 </mixer>
diff --git a/configs/msmsteppe/audio_platform_info_intcodec.xml b/configs/msmsteppe/audio_platform_info_intcodec.xml
index 27964f4..f838af8 100644
--- a/configs/msmsteppe/audio_platform_info_intcodec.xml
+++ b/configs/msmsteppe/audio_platform_info_intcodec.xml
@@ -102,6 +102,7 @@
     </acdb_ids>
     <backend_names>
         <device name="SND_DEVICE_OUT_HEADPHONES" backend="headphones" interface="RX_CDC_DMA_RX_0"/>
+        <device name="SND_DEVICE_OUT_HEADPHONES_44_1" backend="headphones-44.1" interface="RX_CDC_DMA_RX_0"/>
         <device name="SND_DEVICE_OUT_BT_SCO_WB" backend="bt-sco-wb" interface="SLIMBUS_7_RX"/>
         <device name="SND_DEVICE_OUT_BT_SCO" backend="bt-sco" interface="SLIMBUS_7_RX"/>
         <device name="SND_DEVICE_OUT_BT_A2DP" backend="bt-a2dp" interface="SLIMBUS_7_RX"/>
diff --git a/configs/msmsteppe/audio_platform_info_qrd.xml b/configs/msmsteppe/audio_platform_info_qrd.xml
index 99759a7..1aac2c5 100644
--- a/configs/msmsteppe/audio_platform_info_qrd.xml
+++ b/configs/msmsteppe/audio_platform_info_qrd.xml
@@ -102,6 +102,7 @@
     </acdb_ids>
     <backend_names>
         <device name="SND_DEVICE_OUT_HEADPHONES" backend="headphones" interface="RX_CDC_DMA_RX_0"/>
+        <device name="SND_DEVICE_OUT_HEADPHONES_44_1" backend="headphones-44.1" interface="RX_CDC_DMA_RX_0"/>
         <device name="SND_DEVICE_OUT_BT_SCO_WB" backend="bt-sco-wb" interface="SLIMBUS_7_RX"/>
         <device name="SND_DEVICE_OUT_BT_SCO" backend="bt-sco" interface="SLIMBUS_7_RX"/>
         <device name="SND_DEVICE_OUT_BT_A2DP" backend="bt-a2dp" interface="SLIMBUS_7_RX"/>
diff --git a/configs/msmsteppe/msmsteppe.mk b/configs/msmsteppe/msmsteppe.mk
index aea148f..dc4df7a 100644
--- a/configs/msmsteppe/msmsteppe.mk
+++ b/configs/msmsteppe/msmsteppe.mk
@@ -66,6 +66,7 @@
 AUDIO_FEATURE_ENABLED_RAS := true
 AUDIO_FEATURE_ENABLED_SND_MONITOR := true
 AUDIO_FEATURE_ENABLED_SVA_MULTI_STAGE := true
+AUDIO_FEATURE_ENABLED_BATTERY_LISTENER := true
 ##AUDIO_FEATURE_FLAGS
 
 #Audio Specific device overlays
diff --git a/configs/msmsteppe/sound_trigger_platform_info.xml b/configs/msmsteppe/sound_trigger_platform_info.xml
index 5f14bb8..ed9c08d 100644
--- a/configs/msmsteppe/sound_trigger_platform_info.xml
+++ b/configs/msmsteppe/sound_trigger_platform_info.xml
@@ -41,6 +41,7 @@
         <param support_device_switch="false" />
         <!-- Transition will only occur if execution_type="DYNAMIC" -->
         <param transit_to_adsp_on_playback="false" />
+        <param transit_to_adsp_on_battery_charging="false" />
         <!-- Below backend params must match with port used in mixer path file -->
         <!-- param used to configure backend sample rate, format and channels -->
         <param backend_port_name="SLIM_0_TX" />
@@ -153,6 +154,64 @@
         <param client_capture_read_delay="2000" />
     </sound_model_config>
 
+    <!-- QTI Music Detection !-->
+    <sound_model_config>
+        <param vendor_uuid="876c1b46-9d4d-40cc-a4fd-4d5ec7a80e47" />
+        <param execution_type="ADSP" /> <!-- value: "WDSP" "ADSP" "DYNAMIC" -->
+        <param library="libsmwrapper.so" />
+        <param max_cpe_phrases="1" />
+        <param max_cpe_users="1" />
+        <param max_ape_phrases="1" />
+        <param max_ape_users="1" />
+        <!-- Profile specific data which the algorithm can support -->
+        <param sample_rate="16000" />
+        <param bit_width="16" />
+        <param out_channels="1"/> <!-- Module output channels -->
+        <!-- adm_cfg_profile should match with the one defined under adm_config -->
+        <!-- Set it to NONE if LSM directly connects to AFE -->
+        <param adm_cfg_profile="NONE" />
+        <!-- fluence_type: "FLUENCE", "FLUENCE_DMIC", "FLUENCE_TMIC"   -->
+        <!-- "FLUENCE_QMIC". Param value is valid when adm_cfg_profile -->
+        <!-- is one of FLUENCE, FLUENCE_STEREO, FFECNS values          -->
+        <param fluence_type="FLUENCE_DMIC" />
+        <!-- wdsp_fluence_type: fluence disabled: "NONE" -->
+        <!-- fluence enabled: "FLUENCE_DMIC", "FLUENCE_TMIC", "FLUENCE_QMIC" -->
+        <param wdsp_fluence_type="NONE" />
+        <gcs_usecase>
+            <param uid="0x5" />
+            <param acdb_devices="DEVICE_HANDSET_MIC_CPE, DEVICE_HANDSET_TMIC_CPE, DEVICE_HEADSET_MIC_CPE" />
+            <!-- module_id, instance_id, param_id -->
+            <param load_sound_model_ids="0x00012C2E, 0x6, 0x00012C14" />
+            <param confidence_levels_ids="0x00012C2E, 0x6, 0x00012C28" />
+            <param detection_event_ids="0x00012C2E, 0x6, 0x00012B05" />
+            <param read_cmd_ids="0x00020013, 0x6, 0x00020015" />
+            <param read_rsp_ids="0x00020013, 0x6, 0x00020016" />
+            <param custom_config_ids="0x00012C2E, 0x6, 0x00012C2D" />
+            <param det_event_type_ids="0x00012C2E, 0x6, 0x00012C2C" />
+        </gcs_usecase>
+        <!-- Module and param ids with which the algorithm is integrated
+            in non-graphite firmware (note these must come after gcs params)
+            Extends flexibility to have different ids based on execution type.
+            valid execution_type values: only "ADSP" -->
+        <lsm_usecase>
+            <param execution_mode="ADSP" />
+            <param app_type="4" /> <!-- app type for MD used in ACDB -->
+            <param in_channels="1"/> <!-- Module input channels -->
+            <param load_sound_model_ids="0x00012C22, 0x00012C14" />
+            <param unload_sound_model_ids="0x00012C22, 0x00012C15" />
+            <param confidence_levels_ids="0x00012C22, 0x00012C07" />
+            <param det_event_type_ids="0x00012C22, 0x00012C2C" />
+            <param custom_config_ids="0x00012C22, 0x00012C30" />
+        </lsm_usecase>
+
+        <!-- format: "ADPCM_packet" or "PCM_packet" !-->
+        <!-- transfer_mode: "FTRT" or "RT" -->
+        <!--  kw_duration is in milli seconds. It is valid only for FTRT
+            transfer mode -->
+        <param capture_keyword="PCM_packet, FTRT, 1500" />
+        <param client_capture_read_delay="2000" />
+    </sound_model_config>
+
 <!-- Sound model config for Hotword !-->
     <sound_model_config>
         <param vendor_uuid="7038ddc8-30f2-11e6-b0ac-40a8f03d3f15" />
diff --git a/configs/sdm710/audio_platform_info_intcodec.xml b/configs/sdm710/audio_platform_info_intcodec.xml
index 8495686..d106ec0 100644
--- a/configs/sdm710/audio_platform_info_intcodec.xml
+++ b/configs/sdm710/audio_platform_info_intcodec.xml
@@ -107,6 +107,7 @@
     </acdb_ids>
     <backend_names>
         <device name="SND_DEVICE_OUT_HEADPHONES" backend="headphones" interface="INT0_MI2S_RX"/>
+        <device name="SND_DEVICE_OUT_HEADPHONES_44_1" backend="headphones-44.1" interface="INT0_MI2S_RX"/>
         <device name="SND_DEVICE_OUT_BT_SCO_WB" backend="bt-sco-wb" interface="SLIMBUS_7_RX"/>
         <device name="SND_DEVICE_OUT_BT_SCO" backend="bt-sco" interface="SLIMBUS_7_RX"/>
         <device name="SND_DEVICE_OUT_BT_A2DP" backend="bt-a2dp" interface="SLIMBUS_7_RX"/>
diff --git a/configs/sdm710/audio_platform_info_skuw.xml b/configs/sdm710/audio_platform_info_skuw.xml
index fccc18d..b7839d5 100644
--- a/configs/sdm710/audio_platform_info_skuw.xml
+++ b/configs/sdm710/audio_platform_info_skuw.xml
@@ -100,6 +100,7 @@
     </acdb_ids>
     <backend_names>
         <device name="SND_DEVICE_OUT_HEADPHONES" backend="headphones" interface="INT0_MI2S_RX"/>
+        <device name="SND_DEVICE_OUT_HEADPHONES_44_1" backend="headphones-44.1" interface="INT0_MI2S_RX"/>
         <device name="SND_DEVICE_OUT_BT_SCO_WB" backend="bt-sco-wb" interface="SLIMBUS_7_RX"/>
         <device name="SND_DEVICE_OUT_BT_SCO" backend="bt-sco" interface="SLIMBUS_7_RX"/>
         <device name="SND_DEVICE_OUT_BT_A2DP" backend="bt-a2dp" interface="SLIMBUS_7_RX"/>
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index 7231955..365b03e 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -217,7 +217,8 @@
 #define audio_extn_usb_deinit()                                        (0)
 #define audio_extn_usb_add_device(device, card)                        (0)
 #define audio_extn_usb_remove_device(device, card)                     (0)
-#define audio_extn_usb_is_config_supported(bit_width, sample_rate, ch, pb) (0)
+#define audio_extn_usb_is_config_supported(bit_width, sample_rate, ch, pb) \
+                        (*bit_width=0, *sample_rate=0, *ch=0, 0)
 #define audio_extn_usb_enable_sidetone(device, enable)                 (0)
 #define audio_extn_usb_set_sidetone_gain(parms, value, len)            (0)
 #define audio_extn_usb_is_capture_supported()                          (0)
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index d83002a..225a03e 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -2912,6 +2912,9 @@
             adev->offload_effects_stop_output(out->handle, out->pcm_device_id);
     }
 
+    if (out->usecase == USECASE_INCALL_MUSIC_UPLINK)
+        voice_set_device_mute_flag(adev, false);
+
     /* 1. Get and set stream specific mixer controls */
     disable_audio_route(adev, uc_info);
 
@@ -3071,6 +3074,9 @@
          select_devices(adev, out->usecase);
     }
 
+    if (out->usecase == USECASE_INCALL_MUSIC_UPLINK)
+        voice_set_device_mute_flag(adev, true);
+
     ALOGV("%s: Opening PCM device card_id(%d) device_id(%d) format(%#x)",
           __func__, adev->snd_card, out->pcm_device_id, out->config.format);
 
@@ -4358,6 +4364,8 @@
     struct audio_device *adev = out->dev;
     ssize_t ret = 0;
     int channels = 0;
+    const size_t frame_size = audio_stream_out_frame_size(stream);
+    const size_t frames = (frame_size != 0) ? bytes / frame_size : bytes;
 
     ATRACE_BEGIN("out_write");
     lock_output_stream(out);
@@ -4563,8 +4571,35 @@
         return ret;
     } else {
         if (out->pcm) {
+            size_t bytes_to_write = bytes;
             if (out->muted)
                 memset((void *)buffer, 0, bytes);
+            ALOGV("%s: frames=%zu, frame_size=%zu, bytes_to_write=%zu",
+                     __func__, frames, frame_size, bytes_to_write);
+
+            if (out->usecase == USECASE_INCALL_MUSIC_UPLINK) {
+                size_t channel_count = audio_channel_count_from_out_mask(out->channel_mask);
+                int16_t *src = (int16_t *)buffer;
+                int16_t *dst = (int16_t *)buffer;
+
+                LOG_ALWAYS_FATAL_IF(out->config.channels != 1 || channel_count != 2 ||
+                                    out->format != AUDIO_FORMAT_PCM_16_BIT,
+                                    "out_write called for incall music use case with wrong properties");
+
+                /*
+                 * FIXME: this can be removed once audio flinger mixer supports
+                 * mono output
+                 */
+
+                /*
+                 * Code below goes over each frame in the buffer and adds both
+                 * L and R samples and then divides by 2 to convert to mono
+                 */
+                for (size_t i = 0; i < frames ; i++, dst++, src += 2) {
+                    *dst = (int16_t)(((int32_t)src[0] + (int32_t)src[1]) >> 1);
+                }
+                bytes_to_write /= 2;
+            }
 
             ALOGVV("%s: writing buffer (%zu bytes) to pcm device", __func__, bytes);
 
@@ -4574,12 +4609,11 @@
                 ns = pcm_bytes_to_frames(out->pcm, bytes)*1000000000LL/
                                                      out->config.rate;
 
+            request_out_focus(out, ns);
             bool use_mmap = is_mmap_usecase(out->usecase) || out->realtime;
 
-            request_out_focus(out, ns);
-
             if (use_mmap)
-                ret = pcm_mmap_write(out->pcm, (void *)buffer, bytes);
+                ret = pcm_mmap_write(out->pcm, (void *)buffer, bytes_to_write);
             else if (out->hal_op_format != out->hal_ip_format &&
                        out->convert_buffer != NULL) {
 
@@ -4613,7 +4647,7 @@
                            out_get_sample_rate(&out->stream.common));
                     ret = 0;
                 } else
-                    ret = pcm_write(out->pcm, (void *)buffer, bytes);
+                    ret = pcm_write(out->pcm, (void *)buffer, bytes_to_write);
             }
 
             release_out_focus(out);
@@ -6119,13 +6153,55 @@
         create_offload_callback_thread(out);
 
     } else if (out->flags & AUDIO_OUTPUT_FLAG_INCALL_MUSIC) {
+          switch (config->sample_rate) {
+            case 0:
+                out->sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
+                break;
+            case 8000:
+            case 16000:
+            case 48000:
+                out->sample_rate = config->sample_rate;
+                break;
+            default:
+                ALOGE("%s: Unsupported sampling rate %d for Incall Music", __func__,
+                      config->sample_rate);
+                config->sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
+                ret = -EINVAL;
+                goto error_open;
+        }
+        //FIXME: add support for MONO stream configuration when audioflinger mixer supports it
+        switch (config->channel_mask) {
+            case AUDIO_CHANNEL_NONE:
+            case AUDIO_CHANNEL_OUT_STEREO:
+                out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+                break;
+            default:
+                ALOGE("%s: Unsupported channel mask %#x for Incall Music", __func__,
+                      config->channel_mask);
+                config->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+                ret = -EINVAL;
+                goto error_open;
+        }
+        switch (config->format) {
+            case AUDIO_FORMAT_DEFAULT:
+            case AUDIO_FORMAT_PCM_16_BIT:
+                out->format = AUDIO_FORMAT_PCM_16_BIT;
+                break;
+            default:
+                ALOGE("%s: Unsupported format %#x for Incall Music", __func__,
+                      config->format);
+                config->format = AUDIO_FORMAT_PCM_16_BIT;
+                ret = -EINVAL;
+                goto error_open;
+        }
+
         ret = voice_extn_check_and_set_incall_music_usecase(adev, out);
         if (ret != 0) {
             ALOGE("%s: Incall music delivery usecase cannot be set error:%d",
-                  __func__, ret);
+                __func__, ret);
             goto error_open;
         }
-    } else  if (out->devices == AUDIO_DEVICE_OUT_TELEPHONY_TX) {
+    } else if (out->devices == AUDIO_DEVICE_OUT_TELEPHONY_TX) {
         if (config->sample_rate == 0)
             config->sample_rate = AFE_PROXY_SAMPLING_RATE;
         if (config->sample_rate != 48000 && config->sample_rate != 16000 &&
@@ -7650,6 +7726,8 @@
         }
     }
 
+    adev->mic_break_enabled = property_get_bool("vendor.audio.mic_break", false);
+
     if (property_get("vendor.audio_hal.period_multiplier", value, NULL) > 0) {
         af_period_multiplier = atoi(value);
         if (af_period_multiplier < 0)
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index c29f7b8..202e09a 100755
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -487,6 +487,7 @@
     bool bt_wb_speech_enabled;
     bool allow_afe_proxy_usage;
     bool is_charging; // from battery listener
+    bool mic_break_enabled;
 
     int snd_card;
     card_status_t card_status;
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index e5cb9b4..c6d1a74 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -3647,6 +3647,11 @@
     return ret;
 }
 
+int platform_set_mic_break_det(void *platform __unused, bool enable __unused)
+{
+    return 0;
+}
+
 int platform_stop_voice_call(void *platform, uint32_t vsid)
 {
     struct platform_data *my_data = (struct platform_data *)platform;
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index fab7034..e8da091 100755
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -2471,6 +2471,10 @@
                 strdup("RX_CDC_DMA_RX_0 Format");
             my_data->current_backend_cfg[HEADPHONE_BACKEND].samplerate_mixer_ctl =
                 strdup("RX_CDC_DMA_RX_0 SampleRate");
+            my_data->current_backend_cfg[HEADPHONE_44_1_BACKEND].bitwidth_mixer_ctl =
+                strdup("RX_CDC_DMA_RX_0 Format");
+            my_data->current_backend_cfg[HEADPHONE_44_1_BACKEND].samplerate_mixer_ctl =
+                strdup("RX_CDC_DMA_RX_0 SampleRate");
 
             if (default_rx_backend)
                 free(default_rx_backend);
@@ -2491,6 +2495,10 @@
                 strdup("INT0_MI2S_RX Format");
             my_data->current_backend_cfg[HEADPHONE_BACKEND].samplerate_mixer_ctl =
                 strdup("INT0_MI2S_RX SampleRate");
+            my_data->current_backend_cfg[HEADPHONE_44_1_BACKEND].bitwidth_mixer_ctl =
+                strdup("INT0_MI2S_RX Format");
+            my_data->current_backend_cfg[HEADPHONE_44_1_BACKEND].samplerate_mixer_ctl =
+                strdup("INT0_MI2S_RX SampleRate");
 
             if (default_rx_backend)
                 free(default_rx_backend);
@@ -3510,6 +3518,26 @@
     return ret;
 }
 
+int platform_set_mic_break_det(void *platform, bool enable)
+{
+    int ret = 0;
+    struct platform_data *my_data = (struct platform_data *)platform;
+    struct audio_device *adev = my_data->adev;
+    const char *mixer_ctl_name = "Voice Mic Break Enable";
+    struct mixer_ctl *ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+    if (!ctl) {
+        ALOGE("%s: Could not get ctl for mixer cmd - %s",
+              __func__, mixer_ctl_name);
+        return -EINVAL;
+    }
+
+    ret = mixer_ctl_set_value(ctl, 0, enable);
+    if(ret)
+        ALOGE("%s: Failed to set mixer ctl: %s", __func__, mixer_ctl_name);
+
+    return ret;
+}
+
 int platform_get_sample_rate(void *platform, uint32_t *rate)
 {
     struct platform_data *my_data = (struct platform_data *)platform;
@@ -4025,6 +4053,9 @@
         } else if (NATIVE_AUDIO_MODE_SRC == na_mode &&
                    OUTPUT_SAMPLING_RATE_44100 == sample_rate) {
                 snd_device = SND_DEVICE_OUT_HEADPHONES_44_1;
+        } else if (NATIVE_AUDIO_MODE_TRUE_44_1 == na_mode &&
+                   OUTPUT_SAMPLING_RATE_44100 == sample_rate) {
+                snd_device = SND_DEVICE_OUT_HEADPHONES_44_1;
         } else if (NATIVE_AUDIO_MODE_MULTIPLE_44_1 == na_mode &&
                    (sample_rate % OUTPUT_SAMPLING_RATE_44100 == 0) &&
                    (out->format != AUDIO_FORMAT_DSD)) {
@@ -6361,6 +6392,13 @@
 
     backend_idx = platform_get_backend_index(snd_device);
 
+    //initialize backend config if current snd_device is SND_DEVICE_NONE
+    if (usecase->out_snd_device == SND_DEVICE_NONE) {
+        my_data->current_backend_cfg[backend_idx].sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+        my_data->current_backend_cfg[backend_idx].bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
+        my_data->current_backend_cfg[backend_idx].channels = CODEC_BACKEND_DEFAULT_CHANNELS;
+    }
+
     if (usecase->type == TRANSCODE_LOOPBACK) {
         backend_cfg.bit_width = usecase->stream.inout->out_config.bit_width;
         backend_cfg.sample_rate = usecase->stream.inout->out_config.sample_rate;
diff --git a/hal/platform_api.h b/hal/platform_api.h
index 226275e..6ba962d 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -150,6 +150,7 @@
                                                   snd_device_t in_snd_device);
 int platform_start_voice_call(void *platform, uint32_t vsid);
 int platform_stop_voice_call(void *platform, uint32_t vsid);
+int platform_set_mic_break_det(void *platform, bool enable);
 int platform_set_voice_volume(void *platform, int volume);
 int platform_set_mic_mute(void *platform, bool state);
 int platform_get_sample_rate(void *platform, uint32_t *rate);
diff --git a/hal/voice.c b/hal/voice.c
index f9e3562..425bb54 100644
--- a/hal/voice.c
+++ b/hal/voice.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
  * Not a contribution.
  *
  * Copyright (C) 2013 The Android Open Source Project
@@ -228,6 +228,7 @@
 
     uc_info->in_snd_device = SND_DEVICE_NONE;
     uc_info->out_snd_device = SND_DEVICE_NONE;
+    adev->voice.use_device_mute = false;
 
     if (audio_is_bluetooth_sco_device(uc_info->devices) && !adev->bt_sco_on) {
         ALOGE("start_call: couldn't find BT SCO, SCO is not ready");
@@ -281,6 +282,9 @@
         goto error_start_voice;
     }
 
+    if(adev->mic_break_enabled)
+        platform_set_mic_break_det(adev->platform, true);
+
     pcm_start(session->pcm_tx);
     pcm_start(session->pcm_rx);
 
@@ -338,10 +342,10 @@
        return in_call_rec;
     }
 
-    if(in->source == AUDIO_SOURCE_VOICE_DOWNLINK ||
-       in->source == AUDIO_SOURCE_VOICE_UPLINK ||
-       in->source == AUDIO_SOURCE_VOICE_CALL) {
-       in_call_rec = true;
+    if (in->source == AUDIO_SOURCE_VOICE_DOWNLINK ||
+        in->source == AUDIO_SOURCE_VOICE_UPLINK ||
+        in->source == AUDIO_SOURCE_VOICE_CALL) {
+            in_call_rec = true;
     }
 
     return in_call_rec;
@@ -476,13 +480,21 @@
     int err = 0;
 
     adev->voice.mic_mute = state;
+
     if (audio_extn_hfp_is_active(adev)) {
         err = hfp_set_mic_mute(adev, state);
     } else if (adev->mode == AUDIO_MODE_IN_CALL) {
-        err = platform_set_mic_mute(adev->platform, state);
+       /* Use device mute if incall music delivery usecase is in progress */
+        if (adev->voice.use_device_mute)
+            err = platform_set_device_mute(adev->platform, state, "tx");
+        else
+            err = platform_set_mic_mute(adev->platform, state);
+        ALOGV("%s: voice mute status=%d, use_device_mute flag=%d",
+            __func__, state, adev->voice.use_device_mute);
     } else if (adev->mode == AUDIO_MODE_IN_COMMUNICATION) {
         err = voice_extn_compress_voip_set_mic_mute(adev, state);
     }
+
     return err;
 }
 
@@ -491,6 +503,27 @@
     return adev->voice.mic_mute;
 }
 
+/*
+ * Following function is called when incall music uplink usecase is
+ * created or destroyed while mic is muted. If incall music uplink
+ * usecase is active, apply voice device mute to mute only voice Tx
+ * path and not the mixed voice Tx + inncall-music path. Revert to
+ * voice stream mute once incall music uplink usecase is inactive
+ */
+void voice_set_device_mute_flag(struct audio_device *adev, bool state)
+{
+    if (adev->voice.mic_mute) {
+        if (state) {
+            platform_set_device_mute(adev->platform, true, "tx");
+            platform_set_mic_mute(adev->platform, false);
+        } else {
+            platform_set_mic_mute(adev->platform, true);
+            platform_set_device_mute(adev->platform, false, "tx");
+        }
+    }
+    adev->voice.use_device_mute = state;
+}
+
 int voice_set_volume(struct audio_device *adev, float volume)
 {
     int vol, err = 0;
diff --git a/hal/voice.h b/hal/voice.h
index 3ae42a8..2ef790a 100644
--- a/hal/voice.h
+++ b/hal/voice.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
  * Not a contribution.
  *
  * Copyright (C) 2013 The Android Open Source Project
@@ -61,6 +61,7 @@
     struct voice_session session[MAX_VOICE_SESSIONS];
     int tty_mode;
     bool mic_mute;
+    bool use_device_mute;
     float volume;
     bool in_call;
 };
@@ -101,4 +102,6 @@
                                       snd_device_t out_snd_device,
                                       bool enable);
 bool voice_is_call_state_active(struct audio_device *adev);
+void voice_set_device_mute_flag (struct audio_device *adev, bool state);
+
 #endif //VOICE_H
diff --git a/hal/voice_extn/voice_extn.c b/hal/voice_extn/voice_extn.c
index 93653ca..ec85259 100644
--- a/hal/voice_extn/voice_extn.c
+++ b/hal/voice_extn/voice_extn.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
  * Not a contribution.
  *
  * Copyright (C) 2013 The Android Open Source Project
@@ -594,27 +594,16 @@
     voice_extn_compress_voip_in_get_parameters(in, query, reply);
 }
 
-#ifdef INCALL_MUSIC_ENABLED
 int voice_extn_check_and_set_incall_music_usecase(struct audio_device *adev,
                                                   struct stream_out *out)
 {
-    uint32_t session_id = 0;
-
-    session_id = get_session_id_with_state(adev, CALL_LOCAL_HOLD);
-    if (session_id == VOICE_VSID) {
-        out->usecase = USECASE_INCALL_MUSIC_UPLINK;
-    } else if (session_id == VOICE2_VSID) {
-        out->usecase = USECASE_INCALL_MUSIC_UPLINK2;
-    } else {
-        ALOGE("%s: Invalid session id %x", __func__, session_id);
-        return -EINVAL;
-    }
-
+    out->usecase = USECASE_INCALL_MUSIC_UPLINK;
     out->config = pcm_config_incall_music;
-    out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_MONO;
-    out->channel_mask = AUDIO_CHANNEL_OUT_MONO;
+    //FIXME: add support for MONO stream configuration when audioflinger mixer supports it
+    out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO;
+    out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+    out->config.rate = out->sample_rate;
 
+    ALOGV("%s: mode=%d, usecase id=%d", __func__, adev->mode, out->usecase);
     return 0;
 }
-#endif
-
diff --git a/hal/voice_extn/voice_extn.h b/hal/voice_extn/voice_extn.h
index f35344f..5d1cac3 100644
--- a/hal/voice_extn/voice_extn.h
+++ b/hal/voice_extn/voice_extn.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2014, 2016-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, 2016-2018, The Linux Foundation. All rights reserved.
  * Not a contribution.
  *
  * Copyright (C) 2013 The Android Open Source Project
@@ -101,13 +101,8 @@
 }
 #endif
 
-#ifdef INCALL_MUSIC_ENABLED
 int voice_extn_check_and_set_incall_music_usecase(struct audio_device *adev,
                                                   struct stream_out *out);
-#else
-#define voice_extn_check_and_set_incall_music_usecase(adev, out) -ENOSYS
-#endif
-
 #ifdef COMPRESS_VOIP_ENABLED
 int voice_extn_compress_voip_close_output_stream(struct audio_stream *stream);
 int voice_extn_compress_voip_open_output_stream(struct stream_out *out);