release-request-fbba21d1-17b5-4752-9864-95770e5db190-for-git_oc-mr1-release-4144771 snap-temp-L10300000078657232

Change-Id: I6164dca620dcbf92d03cedf4ed217eae19a11a4a
diff --git a/hal/Android.mk b/hal/Android.mk
index 2de6c16..0d2b6b9 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -80,6 +80,10 @@
     LOCAL_SRC_FILES += audio_extn/usb.c
 endif
 
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_USB_SIDETONE_VOLUME)),true)
+    LOCAL_CFLAGS += -DUSB_SIDETONE_VOLUME
+endif
+
 LOCAL_SHARED_LIBRARIES := \
 	libaudioutils \
 	liblog \
diff --git a/hal/audio_extn/soundtrigger.c b/hal/audio_extn/soundtrigger.c
index 32b7b85..112bd1e 100644
--- a/hal/audio_extn/soundtrigger.c
+++ b/hal/audio_extn/soundtrigger.c
@@ -68,6 +68,15 @@
     return NULL;
 }
 
+static void stdev_snd_mon_cb(void * stream __unused, struct str_parms * parms)
+{
+    if (!parms)
+        return;
+
+    audio_extn_sound_trigger_set_parameters(NULL, parms);
+    return;
+}
+
 int audio_hw_call_back(sound_trigger_event_type_t event,
                        sound_trigger_event_info_t* config)
 {
@@ -333,6 +342,7 @@
 
     st_dev->adev = adev;
     list_init(&st_dev->st_ses_list);
+    audio_extn_snd_mon_register_listener(st_dev, stdev_snd_mon_cb);
 
     return 0;
 
@@ -349,6 +359,7 @@
 {
     ALOGV("%s: Enter", __func__);
     if (st_dev && (st_dev->adev == adev) && st_dev->lib_handle) {
+        audio_extn_snd_mon_unregister_listener(st_dev);
         dlclose(st_dev->lib_handle);
         free(st_dev);
         st_dev = NULL;
diff --git a/hal/audio_extn/usb.c b/hal/audio_extn/usb.c
index 4e4c70d..6b3ee7b 100644
--- a/hal/audio_extn/usb.c
+++ b/hal/audio_extn/usb.c
@@ -505,9 +505,12 @@
             usb_card_info->usb_sidetone_index[USB_SIDETONE_ENABLE_INDEX] = index;
             /* Disable device sidetone by default */
             mixer_ctl_set_value(ctl, 0, false);
+            ALOGV("%s:: sidetone mixer Control found(%s) ... disabling by default",
+                   __func__, usb_sidetone_enable_str[index]);
             break;
         }
     }
+#ifdef USB_SIDETONE_VOLUME
     for (index = 0;
          index < sizeof(usb_sidetone_volume_str)/sizeof(usb_sidetone_volume_str[0]);
          index++) {
@@ -520,7 +523,7 @@
             break;
         }
     }
-
+#endif // USB_SIDETONE_VOLUME
     if ((usb_card_info->usb_snd_mixer != NULL) && (usb_audio_debug_enable))
         usb_soundcard_list_controls(usb_card_info->usb_snd_mixer);
 
@@ -848,6 +851,7 @@
                 else
                     break;
 
+#ifdef USB_SIDETONE_VOLUME
                 if ((i = card_info->usb_sidetone_index[USB_SIDETONE_VOLUME_INDEX]) != -1) {
                     ctl = mixer_get_ctl_by_name(
                                 card_info->usb_snd_mixer,
@@ -859,6 +863,7 @@
                         mixer_ctl_set_value(ctl, 0,
                                             usb_get_sidetone_gain(card_info));
                 }
+#endif // USB_SIDETONE_VOLUME
                 ret = 0;
                 break;
             }
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 767798c..d4adbcc 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -4483,19 +4483,17 @@
     if (!adev)
         return 0;
 
-    audio_extn_snd_mon_unregister_listener(adev);
-    audio_extn_snd_mon_deinit();
-
-    audio_extn_tfa_98xx_deinit();
-
     pthread_mutex_lock(&adev_init_lock);
 
     if ((--audio_device_ref_count) == 0) {
+        audio_extn_snd_mon_unregister_listener(adev);
+        audio_extn_tfa_98xx_deinit();
         audio_route_free(adev->audio_route);
         free(adev->snd_dev_ref_cnt);
         platform_deinit(adev->platform);
         audio_extn_extspk_deinit(adev->extspk);
         audio_extn_sound_trigger_deinit(adev);
+        audio_extn_snd_mon_deinit();
         for (i = 0; i < ARRAY_SIZE(adev->use_case_table); ++i) {
             pcm_params_free(adev->use_case_table[i]);
         }
@@ -4621,7 +4619,6 @@
         return -EINVAL;
     }
     adev->extspk = audio_extn_extspk_init(adev);
-    audio_extn_sound_trigger_init(adev);
 
     adev->visualizer_lib = dlopen(VISUALIZER_LIBRARY_PATH, RTLD_NOW);
     if (adev->visualizer_lib == NULL) {
@@ -4733,6 +4730,7 @@
     audio_extn_snd_mon_register_listener(NULL, adev_snd_mon_cb);
     adev->card_status = CARD_STATUS_ONLINE;
     pthread_mutex_unlock(&adev->lock);
+    audio_extn_sound_trigger_init(adev);/* dependent on snd_mon_init() */
 
     ALOGD("%s: exit", __func__);
     return 0;
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 6d92d93..628d1d6 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -2335,3 +2335,25 @@
     return -ENOSYS;
 }
 
+int platform_set_sidetone(struct audio_device *adev,
+                          snd_device_t out_snd_device,
+                          bool enable, char *str)
+{
+    int ret;
+    if (out_snd_device == SND_DEVICE_OUT_USB_HEADSET ||
+        out_snd_device == SND_DEVICE_OUT_VOICE_USB_HEADSET) {
+            ret = audio_extn_usb_enable_sidetone(out_snd_device, enable);
+            if (ret)
+                ALOGI("%s: usb device %d does not support device sidetone\n",
+                  __func__, out_snd_device);
+    } else {
+        ALOGV("%s: sidetone out device(%d) mixer cmd = %s\n",
+              __func__, out_snd_device, str);
+
+        if (enable)
+            audio_route_apply_and_update_path(adev->audio_route, str);
+        else
+            audio_route_reset_and_update_path(adev->audio_route, str);
+    }
+    return 0;
+}
diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c
index cd7305d..c30ccda 100644
--- a/hal/msm8960/platform.c
+++ b/hal/msm8960/platform.c
@@ -1169,3 +1169,25 @@
 int platform_get_snd_device_backend_index(snd_device_t snd_device) {
     return -ENOSYS;
 }
+
+int platform_set_sidetone(struct audio_device *adev,
+                          snd_device_t out_snd_device,
+                          bool enable, char *str)
+{
+    int ret;
+    if (out_snd_device == SND_DEVICE_OUT_USB_HEADSET ||
+        out_snd_device == SND_DEVICE_OUT_VOICE_USB_HEADSET) {
+            ret = audio_extn_usb_enable_sidetone(out_snd_device, enable);
+            if (ret)
+                ALOGI("%s: usb device %d does not support device sidetone\n",
+                  __func__, out_snd_device);
+    } else {
+        ALOGV("%s: sidetone out device(%d) mixer cmd = %s\n",
+              __func__, out_snd_device, str);
+        if (enable)
+            audio_route_apply_and_update_path(adev->audio_route, str);
+        else
+            audio_route_reset_and_update_path(adev->audio_route, str);
+    }
+    return 0;
+}
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 7944540..1b0bc20 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -1073,7 +1073,20 @@
     hw_interface_table[SND_DEVICE_IN_HEADSET_MIC] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_UNPROCESSED_MIC] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_CAMCORDER_MIC] = strdup("SLIMBUS_0_TX");
-
+    hw_interface_table[SND_DEVICE_IN_VOICE_REC_MIC] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_VOICE_REC_MIC_NS] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_SPEAKER_MIC] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_SPEAKER_MIC_AEC] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_SPEAKER_MIC_NS] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_SPEAKER_MIC_AEC_NS] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_SPEAKER_DMIC] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_SPEAKER_DMIC_AEC] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_SPEAKER_DMIC_NS] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_VOICE_SPEAKER_MIC] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_VOICE_HEADSET_MIC] = strdup("SLIMBUS_0_TX");
     my_data->max_mic_count = PLATFORM_DEFAULT_MIC_COUNT;
 }
 
@@ -3015,6 +3028,8 @@
         ALOGV("%s: max_mic_count %s/%d", __func__, value, my_data->max_mic_count);
     }
 
+    // to-do: disable setting sidetone gain, will revist this later
+    // audio_extn_usb_set_sidetone_gain(parms, value, len);
 done:
     ALOGV("%s: exit with code(%d)", __func__, ret);
     if (kv_pairs != NULL)
@@ -4000,3 +4015,25 @@
     }
     return 0;
 }
+
+int platform_set_sidetone(struct audio_device *adev,
+                          snd_device_t out_snd_device,
+                          bool enable, char *str)
+{
+    int ret;
+    if (out_snd_device == SND_DEVICE_OUT_USB_HEADSET ||
+        out_snd_device == SND_DEVICE_OUT_VOICE_USB_HEADSET) {
+            ret = audio_extn_usb_enable_sidetone(out_snd_device, enable);
+            if (ret)
+                ALOGI("%s: usb device %d does not support device sidetone\n",
+                  __func__, out_snd_device);
+    } else {
+        ALOGV("%s: sidetone out device(%d) mixer cmd = %s\n",
+              __func__, out_snd_device, str);
+        if (enable)
+            audio_route_apply_and_update_path(adev->audio_route, str);
+        else
+            audio_route_reset_and_update_path(adev->audio_route, str);
+    }
+    return 0;
+}
diff --git a/hal/platform_api.h b/hal/platform_api.h
index e500da5..2e30608 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -142,4 +142,7 @@
                            const char *mode,
                            int bw, int app_type, int max_sr);
 int platform_get_snd_device_backend_index(snd_device_t snd_device);
+int platform_set_sidetone(struct audio_device *adev,
+                          snd_device_t out_snd_device,
+                          bool enable, char * str);
 #endif // AUDIO_PLATFORM_API_H
diff --git a/hal/voice.c b/hal/voice.c
index 611d875..6f16137 100644
--- a/hal/voice.c
+++ b/hal/voice.c
@@ -68,7 +68,13 @@
     case SND_DEVICE_OUT_VOICE_HEADPHONES:
         strlcpy(mixer_path, "sidetone-headphones", MIXER_PATH_MAX_LENGTH);
         break;
+    case SND_DEVICE_OUT_VOICE_USB_HEADSET:
+    case SND_DEVICE_OUT_USB_HEADSET:
+        // USB does not use a QC mixer.
+        mixer_path[0] = '\0';
+        break;
     default:
+        ALOGW("%s: %d is not a sidetone device", __func__, out_device);
         is_sidetone_dev = false;
         break;
     }
@@ -86,21 +92,8 @@
           __func__, (enable ? "enable" : "disable"),
           out_snd_device);
 
-    is_sidetone_dev = voice_is_sidetone_device(out_snd_device, mixer_path);
-
-    if (!is_sidetone_dev) {
-        ALOGD("%s: device %d does not support sidetone\n",
-              __func__, out_snd_device);
-        return;
-    }
-
-    ALOGD("%s: sidetone out device = %s\n",
-          __func__, mixer_path);
-
-    if (enable)
-        audio_route_apply_and_update_path(adev->audio_route, mixer_path);
-    else
-        audio_route_reset_and_update_path(adev->audio_route, mixer_path);
+    if (voice_is_sidetone_device(out_snd_device, mixer_path))
+        platform_set_sidetone(adev, out_snd_device, enable, mixer_path);
 
     return;
 }