Merge "hal: remove sending apply audio path for speaker swap"
diff --git a/configs/atoll/audio_platform_info_qrd.xml b/configs/atoll/audio_platform_info_qrd.xml
index 427647d..f272aee 100644
--- a/configs/atoll/audio_platform_info_qrd.xml
+++ b/configs/atoll/audio_platform_info_qrd.xml
@@ -70,8 +70,8 @@
     <config_params>
         <!-- In the below value string, the value indicates default mono -->
         <!-- speaker. It can be set to either left or right              -->
-        <param key="mono_speaker" value="right"/>
-        <param key="spkr_2_tz_name" value="wsatz.14"/>
+        <param key="mono_speaker" value="left"/>
+        <param key="spkr_2_tz_name" value="wsatz.13"/>
         <param key="true_32_bit" value="true"/>
         <param key="native_audio_mode" value="multiple_mix_dsp"/>
         <param key="hfp_pcm_dev_id" value="39"/>
diff --git a/configs/kona/audio_platform_info_intcodec.xml b/configs/kona/audio_platform_info_intcodec.xml
index 2d22400..4c0c9c3 100644
--- a/configs/kona/audio_platform_info_intcodec.xml
+++ b/configs/kona/audio_platform_info_intcodec.xml
@@ -154,7 +154,9 @@
         <device name="SND_DEVICE_OUT_VOICE_ANC_HEADSET" backend="headphones" interface="RX_CDC_DMA_RX_0"/>
         <device name="SND_DEVICE_OUT_VOICE_LINE" backend="headphones" interface="RX_CDC_DMA_RX_0"/>
         <device name="SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES" backend="headphones" interface="RX_CDC_DMA_RX_0"/>
+        <device name="SND_DEVICE_OUT_VOICE_TTY_FULL_HEADSET" backend="headset" interface="RX_CDC_DMA_RX_0"/>
         <device name="SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES" backend="headphones" interface="RX_CDC_DMA_RX_0"/>
+        <device name="SND_DEVICE_OUT_VOICE_TTY_VCO_HEADSET" backend="headset" interface="RX_CDC_DMA_RX_0"/>
         <device name="SND_DEVICE_OUT_HANDSET" interface="WSA_CDC_DMA_RX_0"/>
         <device name="SND_DEVICE_OUT_SPEAKER" interface="WSA_CDC_DMA_RX_0"/>
         <device name="SND_DEVICE_OUT_SPEAKER_EXTERNAL_1" interface="WSA_CDC_DMA_RX_0"/>
diff --git a/configs/kona/audio_platform_info_qrd.xml b/configs/kona/audio_platform_info_qrd.xml
index bcf63aa..bd5ebdc 100644
--- a/configs/kona/audio_platform_info_qrd.xml
+++ b/configs/kona/audio_platform_info_qrd.xml
@@ -165,7 +165,9 @@
         <device name="SND_DEVICE_OUT_VOICE_ANC_HEADSET" backend="headphones" interface="RX_CDC_DMA_RX_0"/>
         <device name="SND_DEVICE_OUT_VOICE_LINE" backend="headphones" interface="RX_CDC_DMA_RX_0"/>
         <device name="SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES" backend="headphones" interface="RX_CDC_DMA_RX_0"/>
+        <device name="SND_DEVICE_OUT_VOICE_TTY_FULL_HEADSET" backend="headset" interface="RX_CDC_DMA_RX_0"/>
         <device name="SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES" backend="headphones" interface="RX_CDC_DMA_RX_0"/>
+        <device name="SND_DEVICE_OUT_VOICE_TTY_VCO_HEADSET" backend="headset" interface="RX_CDC_DMA_RX_0"/>
         <device name="SND_DEVICE_OUT_HANDSET" backend="handset" interface="RX_CDC_DMA_RX_0"/>
         <device name="SND_DEVICE_OUT_SPEAKER" interface="WSA_CDC_DMA_RX_0"/>
         <device name="SND_DEVICE_OUT_SPEAKER_EXTERNAL_1" interface="WSA_CDC_DMA_RX_0"/>
diff --git a/configs/lito/sound_trigger_platform_info.xml b/configs/lito/sound_trigger_platform_info.xml
index 3353f86..3cbcd67 100644
--- a/configs/lito/sound_trigger_platform_info.xml
+++ b/configs/lito/sound_trigger_platform_info.xml
@@ -117,7 +117,7 @@
             <!-- fluence_type: "FLUENCE_MIC", "FLUENCE_DMIC", "FLUENCE_TMIC"   -->
             <!-- "FLUENCE_QMIC". Param value is valid when adm_cfg_profile -->
             <!-- is FFECNS -->
-            <param fluence_type="FLUENCE_TMIC" />
+            <param fluence_type="FLUENCE_DMIC" />
             <param execution_mode="ADSP" />
             <param app_type="2" /> <!-- app type used in ACDB -->
             <param in_channels="5"/> <!-- Module input channels -->
diff --git a/configs/msm8998/msm8998.mk b/configs/msm8998/msm8998.mk
index 9e3c63b..fad7f5a 100644
--- a/configs/msm8998/msm8998.mk
+++ b/configs/msm8998/msm8998.mk
@@ -257,6 +257,10 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 persist.vendor.bt.aac_frm_ctl.enabled=true
 
+#Set speaker protection cal tx path sampling rate to 48k
+PRODUCT_PROPERTY_OVERRIDES += \
+vendor.audio.spkr_prot.tx.sampling_rate=48000
+
 #add dynamic feature flags here
 PRODUCT_PROPERTY_OVERRIDES += \
 vendor.audio.feature.a2dp_offload.enable=true \
diff --git a/configs/sdm660/sdm660.mk b/configs/sdm660/sdm660.mk
index b3cb143..601819e 100644
--- a/configs/sdm660/sdm660.mk
+++ b/configs/sdm660/sdm660.mk
@@ -268,6 +268,10 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 persist.vendor.bt.aac_frm_ctl.enabled=true
 
+#Set speaker protection cal tx path sampling rate to 48k
+PRODUCT_PROPERTY_OVERRIDES += \
+vendor.audio.spkr_prot.tx.sampling_rate=48000
+
 #add dynamic feature flags here
 PRODUCT_PROPERTY_OVERRIDES += \
 vendor.audio.feature.a2dp_offload.enable=true \
diff --git a/hal/audio_extn/auto_hal.c b/hal/audio_extn/auto_hal.c
index 0269e81..b09a9d0 100644
--- a/hal/audio_extn/auto_hal.c
+++ b/hal/audio_extn/auto_hal.c
@@ -158,11 +158,11 @@
                                                 sources->ext.device.address);
         } else {
             address = (char *)calloc(1, 1);
-            if (address == NULL) {
-                ALOGE("%s: failed to get address",__func__);
-                ret = -EFAULT;
-                goto error;
-            }
+        }
+        if (address == NULL) {
+            ALOGE("%s: failed to get address",__func__);
+            ret = -EFAULT;
+            goto exit;
         }
         parms = str_parms_create_str(address);
         if (!parms) {
@@ -197,11 +197,11 @@
                                                 sinks->ext.device.address);
         } else {
             address = (char *)calloc(1, 1);
-            if (address == NULL) {
-                ALOGE("%s: failed to get address",__func__);
-                ret = -EFAULT;
-                goto error;
-            }
+        }
+        if (address == NULL) {
+            ALOGE("%s: failed to get address",__func__);
+            ret = -EFAULT;
+            goto exit;
         }
         parms = str_parms_create_str(address);
         if (!parms) {
diff --git a/hal/audio_extn/usb.c b/hal/audio_extn/usb.c
index c1ee008..a2d559d 100644
--- a/hal/audio_extn/usb.c
+++ b/hal/audio_extn/usb.c
@@ -1138,10 +1138,11 @@
     uint32_t tries = _MIN(sample_rate_size, (uint32_t)__builtin_popcount(bm));
 
     int i = 0;
-    while (tries--) {
+    while (tries) {
         int idx = __builtin_ffs(bm) - 1;
         sample_rates[i++] = supported_sample_rates[idx];
         bm &= ~(1<<idx);
+        tries--;
     }
 
     return i;
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index 5bdc881..a788996 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -1173,7 +1173,10 @@
             }
             sample_rate = usecase->stream.in->app_type_cfg.sample_rate;
         } else if (usecase->id == USECASE_AUDIO_SPKR_CALIB_TX) {
-            sample_rate = SAMPLE_RATE_8000;
+            if ((property_get("vendor.audio.spkr_prot.tx.sampling_rate", value, NULL) > 0))
+                sample_rate = atoi(value);
+            else
+                sample_rate = SAMPLE_RATE_8000;
         }
     } else if (usecase->type == TRANSCODE_LOOPBACK_RX) {
         sample_rate = usecase->stream.inout->out_config.sample_rate;
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 0580353..8366f24 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -5680,7 +5680,7 @@
                 int16_t *src = (int16_t *)buffer;
                 int16_t *dst = (int16_t *)buffer;
 
-                LOG_ALWAYS_FATAL_IF(out->config.channels != 1 || channel_count != 2 ||
+                LOG_ALWAYS_FATAL_IF(channel_count > 2 ||
                                     out->format != AUDIO_FORMAT_PCM_16_BIT,
                                     "out_write called for %s use case with wrong properties",
                                     use_case_table[out->usecase]);
@@ -5694,12 +5694,13 @@
                  * 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);
+                if (channel_count == 2) {
+                    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;
                 }
-                bytes_to_write /= 2;
             }
-
             ALOGVV("%s: writing buffer (%zu bytes) to pcm device", __func__, bytes);
 
             long ns = 0;
@@ -8207,7 +8208,6 @@
     int status = 0;
     bool a2dp_reconfig = false;
     struct listnode *node;
-    struct audio_usecase *usecase = NULL;
     int controller = -1, stream = -1;
 
     ALOGD("%s: enter: %s", __func__, kvpairs);
@@ -8240,17 +8240,26 @@
         if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0){
             adev->bt_sco_on = true;
         } else {
-            ALOGD("sco is off, reset sco and route device to handset mic");
             adev->bt_sco_on = false;
             audio_extn_sco_reset_configuration();
+        }
+    }
+
+    ret = str_parms_get_str(parms, "A2dpSuspended", value, sizeof(value));
+    if (ret>=0) {
+        if (!strncmp(value, "false", 5) &&
+            audio_extn_a2dp_source_is_suspended()) {
+            struct audio_usecase *usecase;
+            struct listnode *node;
             list_for_each(node, &adev->usecase_list) {
                 usecase = node_to_item(node, struct audio_usecase, list);
-                if ((usecase->type == PCM_CAPTURE) && usecase->stream.in &&
-                    (usecase->stream.in->device & AUDIO_DEVICE_IN_ALL_SCO))
+                if (usecase->stream.in && (usecase->type == PCM_CAPTURE) &&
+                    ((usecase->stream.in->device & ~AUDIO_DEVICE_BIT_IN) &
+                        AUDIO_DEVICE_IN_ALL_SCO)) {
+                    ALOGD("a2dp resumed, switch bt sco mic to handset mic");
                     usecase->stream.in->device = AUDIO_DEVICE_IN_BUILTIN_MIC;
-                else
-                    continue;
-                select_devices(adev, usecase->id);
+                    select_devices(adev, usecase->id);
+                }
             }
         }
     }
@@ -9589,11 +9598,10 @@
             pthread_mutex_unlock(&out->compr_mute_lock);
         }
     } else {
-        // mute compress stream if suspended
-        pthread_mutex_lock(&out->compr_mute_lock);
-        if ((out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) &&
-            (!out->a2dp_compress_mute)) {
-            if (!out->standby) {
+        if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
+            // mute compress stream if suspended
+            pthread_mutex_lock(&out->compr_mute_lock);
+            if (!out->a2dp_compress_mute && !out->standby) {
                 ALOGD("%s: selecting speaker and muting stream", __func__);
                 devices = out->devices;
                 out->devices = AUDIO_DEVICE_OUT_SPEAKER;
@@ -9610,8 +9618,12 @@
                 out->volume_l = left_p;
                 out->volume_r = right_p;
             }
+            pthread_mutex_unlock(&out->compr_mute_lock);
+        } else {
+            // tear down a2dp path for non offloaded streams
+            if (audio_extn_a2dp_source_is_suspended())
+                out_standby_l(&out->stream.common);
         }
-        pthread_mutex_unlock(&out->compr_mute_lock);
     }
     ALOGV("%s: exit", __func__);
     return 0;
diff --git a/hal/voice_extn/voice_extn.c b/hal/voice_extn/voice_extn.c
index 0a1a574..7e78fa6 100644
--- a/hal/voice_extn/voice_extn.c
+++ b/hal/voice_extn/voice_extn.c
@@ -747,8 +747,8 @@
 
         out->config = pcm_config_incall_music;
         //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->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_MONO;
+        out->supported_channel_masks[1] = AUDIO_CHANNEL_OUT_STEREO;
         out->config.rate = out->sample_rate;
 
         ALOGV("%s: mode=%d, usecase id=%d", __func__, adev->mode, out->usecase);