Merge "hal: check for initial calibration temperature threshold"
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index c0b6de1..2ed761e 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -221,6 +221,7 @@
 #define audio_extn_sound_trigger_set_parameters(adev, parms)           (0)
 #define audio_extn_sound_trigger_check_and_get_session(in)             (0)
 #define audio_extn_sound_trigger_stop_lab(in)                          (0)
+#define audio_extn_sound_trigger_read(in, buffer, bytes)               (0)
 #else
 
 enum st_event_type {
@@ -241,6 +242,8 @@
                                              struct str_parms *parms);
 void audio_extn_sound_trigger_check_and_get_session(struct stream_in *in);
 void audio_extn_sound_trigger_stop_lab(struct stream_in *in);
+int audio_extn_sound_trigger_read(struct stream_in *in, void *buffer,
+                                  size_t bytes);
 #endif
 
 #ifndef AUXPCM_BT_ENABLED
diff --git a/hal/audio_extn/fm.c b/hal/audio_extn/fm.c
index efc2307..0ef7c7e 100644
--- a/hal/audio_extn/fm.c
+++ b/hal/audio_extn/fm.c
@@ -251,7 +251,7 @@
                  * Currently, platform_get_wsa_mode will directly return
                  * 1 when wsa is in analog mode.
                  */
-                if (platform_get_wsa_mode(adev->platform) == 1) {
+                if (platform_get_wsa_mode(adev) == 1) {
                     fm_stop(adev);
                     fm_start(adev);
                 } else {
diff --git a/hal/audio_extn/soundtrigger.c b/hal/audio_extn/soundtrigger.c
index 9051334..3c16c88 100644
--- a/hal/audio_extn/soundtrigger.c
+++ b/hal/audio_extn/soundtrigger.c
@@ -30,6 +30,7 @@
 /* #define LOG_NDEBUG 0 */
 #define LOG_NDDEBUG 0
 
+#include <errno.h>
 #include <stdbool.h>
 #include <stdlib.h>
 #include <dlfcn.h>
@@ -64,7 +65,7 @@
 {
     struct sound_trigger_info  *st_ses_info = NULL;
     struct listnode *node;
-    ALOGD("%s: list %d capture_handle %d", __func__,
+    ALOGV("%s: list empty %d capture_handle %d", __func__,
            list_empty(&st_dev->st_ses_list), capture_handle);
     list_for_each(node, &st_dev->st_ses_list) {
         st_ses_info = node_to_item(node, struct sound_trigger_info , list);
@@ -128,6 +129,45 @@
     return status;
 }
 
+int audio_extn_sound_trigger_read(struct stream_in *in, void *buffer,
+                       size_t bytes)
+{
+    int ret = -1;
+    struct sound_trigger_info  *st_info = NULL;
+    audio_event_info_t event;
+
+    if (!st_dev)
+       return ret;
+
+    if (!in->is_st_session_active) {
+        ALOGE(" %s: Sound trigger is not active", __func__);
+        goto exit;
+    }
+    if(in->standby)
+        in->standby = false;
+
+    pthread_mutex_lock(&st_dev->lock);
+    st_info = get_sound_trigger_info(in->capture_handle);
+    pthread_mutex_unlock(&st_dev->lock);
+    if (st_info) {
+        event.u.aud_info.ses_info = &st_info->st_ses;
+        event.u.aud_info.buf = buffer;
+        event.u.aud_info.num_bytes = bytes;
+        ret = st_dev->st_callback(AUDIO_EVENT_READ_SAMPLES, &event);
+    }
+
+exit:
+    if (ret) {
+        if (-ENETRESET == ret)
+            in->is_st_session_active = false;
+        memset(buffer, 0, bytes);
+        ALOGV("%s: read failed status %d - sleep", __func__, ret);
+        usleep((bytes * 1000000) / (audio_stream_in_frame_size((struct audio_stream_in *)in) *
+                                   in->config.rate));
+    }
+    return ret;
+}
+
 void audio_extn_sound_trigger_stop_lab(struct stream_in *in)
 {
     int status = 0;
diff --git a/hal/audio_extn/spkr_protection.c b/hal/audio_extn/spkr_protection.c
index 2d6d414..b7217d6 100644
--- a/hal/audio_extn/spkr_protection.c
+++ b/hal/audio_extn/spkr_protection.c
@@ -949,6 +949,12 @@
     handle.spkr_prot_t0 = -1;
 
     if (is_wsa_present()) {
+        if (platform_get_wsa_mode(adev) == 1) {
+            ALOGD("%s: WSA analog mode", __func__);
+            platform_set_snd_device_acdb_id(SND_DEVICE_OUT_SPEAKER_PROTECTED, 136);
+            platform_set_snd_device_acdb_id(SND_DEVICE_IN_CAPTURE_VI_FEEDBACK, 137);
+            pcm_config_skr_prot.channels = 2;
+        }
         pthread_cond_init(&handle.spkr_calib_cancel, NULL);
         pthread_cond_init(&handle.spkr_calibcancel_ack, NULL);
         pthread_mutex_init(&handle.mutex_spkr_prot, NULL);
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index fc655ef..887b03e 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -486,7 +486,7 @@
     if(SND_DEVICE_IN_USB_HEADSET_MIC == snd_device)
        audio_extn_usb_start_capture(adev);
 
-    if ((snd_device == SND_DEVICE_OUT_SPEAKER ||
+    if ((snd_device == SND_DEVICE_OUT_SPEAKER || snd_device == SND_DEVICE_OUT_SPEAKER_WSA ||
         snd_device == SND_DEVICE_OUT_VOICE_SPEAKER) &&
         audio_extn_spkr_prot_is_enabled()) {
        if (audio_extn_spkr_prot_get_acdb_id(snd_device) < 0) {
@@ -556,7 +556,7 @@
         if(SND_DEVICE_IN_USB_HEADSET_MIC == snd_device)
             audio_extn_usb_stop_capture();
 
-        if ((snd_device == SND_DEVICE_OUT_SPEAKER ||
+        if ((snd_device == SND_DEVICE_OUT_SPEAKER || snd_device == SND_DEVICE_OUT_SPEAKER_WSA ||
             snd_device == SND_DEVICE_OUT_VOICE_SPEAKER) &&
             audio_extn_spkr_prot_is_enabled()) {
             audio_extn_spkr_prot_stop_processing(snd_device);
@@ -695,7 +695,8 @@
         if (usecase->type != PCM_PLAYBACK &&
                 usecase != uc_info &&
                 usecase->in_snd_device != snd_device &&
-                (usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) &&
+                ((uc_info->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) &&
+                ((usecase->devices & ~AUDIO_DEVICE_BIT_IN) & AUDIO_DEVICE_IN_ALL_CODEC_BACKEND)) &&
                 (usecase->id != USECASE_AUDIO_SPKR_CALIB_TX)) {
             ALOGV("%s: Usecase (%s) is active on (%s) - disabling ..",
                   __func__, use_case_table[usecase->id],
@@ -2602,31 +2603,29 @@
 
     pthread_mutex_lock(&in->lock);
 
-    if (in->pcm) {
-        if(SND_CARD_STATE_OFFLINE == snd_scard_state) {
-            ALOGD(" %s: sound card is not active/SSR state", __func__);
-            ret= -EIO;;
-            goto exit;
-        } else {
-            if (in->is_st_session &&  !in->is_st_session_active) {
-                ALOGD(" %s: Sound trigger is not active/SSR", __func__);
-                ret= -EIO;;
-                goto exit;
-            }
-        }
+    if (in->is_st_session) {
+        ALOGVV(" %s: reading on st session bytes=%zu", __func__, bytes);
+        /* Read from sound trigger HAL */
+        audio_extn_sound_trigger_read(in, buffer, bytes);
+        pthread_mutex_unlock(&in->lock);
+        return bytes;
+    }
+
+    if (in->pcm && (SND_CARD_STATE_OFFLINE == snd_scard_state)) {
+        ALOGD(" %s: sound card is not active/SSR state", __func__);
+        ret= -EIO;;
+        goto exit;
     }
 
     if (in->standby) {
-        if (!in->is_st_session) {
-            pthread_mutex_lock(&adev->lock);
-            if (in->usecase == USECASE_COMPRESS_VOIP_CALL)
-                ret = voice_extn_compress_voip_start_input_stream(in);
-            else
-                ret = start_input_stream(in);
-            pthread_mutex_unlock(&adev->lock);
-            if (ret != 0) {
-                goto exit;
-            }
+        pthread_mutex_lock(&adev->lock);
+        if (in->usecase == USECASE_COMPRESS_VOIP_CALL)
+            ret = voice_extn_compress_voip_start_input_stream(in);
+        else
+            ret = start_input_stream(in);
+        pthread_mutex_unlock(&adev->lock);
+        if (ret != 0) {
+            goto exit;
         }
         in->standby = 0;
     }
@@ -2656,17 +2655,9 @@
 exit:
     /* ToDo: There may be a corner case when SSR happens back to back during
        start/stop. Need to post different error to handle that. */
-    if (-ENETRESET == ret) {
-        /* CPE SSR results in kernel returning ENETRESET for sound trigger
-          session reading on LAB data. In this case do not set sound card state
-          offline, instead mark this sound trigger session inactive to avoid
-          further reading of LAB data from CPE driver. Marking the session
-          inactive handles both CPE and ADSP SSR for sound trigger session */
-        if (!in->is_st_session)
-            set_snd_card_state(adev,SND_CARD_STATE_OFFLINE);
-        else
-            in->is_st_session_active = false;
-    }
+    if (-ENETRESET == ret)
+        set_snd_card_state(adev,SND_CARD_STATE_OFFLINE);
+
     pthread_mutex_unlock(&in->lock);
 
     if (ret != 0) {
@@ -2788,7 +2779,8 @@
     out->use_small_bufs = false;
 
     /* Init use case and pcm_config */
-    if ((out->flags == AUDIO_OUTPUT_FLAG_DIRECT) &&
+    if ((out->flags & AUDIO_OUTPUT_FLAG_DIRECT) &&
+        !(out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) &&
         (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL ||
         out->devices & AUDIO_DEVICE_OUT_PROXY)) {
 
@@ -2893,7 +2885,7 @@
         }
         out->compr_config.fragments = COMPRESS_OFFLOAD_NUM_FRAGMENTS;
         out->compr_config.codec->sample_rate =
-                    compress_get_alsa_rate(config->offload_info.sample_rate);
+                    config->offload_info.sample_rate;
         out->compr_config.codec->bit_rate =
                     config->offload_info.bit_rate;
         out->compr_config.codec->ch_in =
@@ -3385,7 +3377,7 @@
 }
 
 static int adev_open_input_stream(struct audio_hw_device *dev,
-                                  audio_io_handle_t handle __unused,
+                                  audio_io_handle_t handle,
                                   audio_devices_t devices,
                                   struct audio_config *config,
                                   struct audio_stream_in **stream_in,
diff --git a/hal/msm8916/hw_info.c b/hal/msm8916/hw_info.c
index fb36a95..613c1a7 100644
--- a/hal/msm8916/hw_info.c
+++ b/hal/msm8916/hw_info.c
@@ -257,6 +257,12 @@
         hw_info->snd_devices = NULL;
         hw_info->num_snd_devices = 0;
         strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn));
+    }  else if (!strcmp(snd_card_name, "msm8976-skun-snd-card")) {
+        strlcpy(hw_info->type, "", sizeof(hw_info->type));
+        strlcpy(hw_info->name, "msm8976", sizeof(hw_info->name));
+        hw_info->snd_devices = NULL;
+        hw_info->num_snd_devices = 0;
+        strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn));
     } else {
         ALOGW("%s: Not an  8x16/8939/8909/8952 device", __func__);
     }
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index e2a9648..03476e4 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -924,7 +924,9 @@
         msm_be_id_array_len  =
             sizeof(msm_device_to_be_id_external_codec) / sizeof(msm_device_to_be_id_external_codec[0]);
     } else if (!strncmp(snd_card_name, "msm8952-skum-snd-card",
-                 sizeof("msm8952-skum-snd-card"))) {
+                 sizeof("msm8952-skum-snd-card")) ||
+               !strncmp(snd_card_name, "msm8976-skun-snd-card",
+                 sizeof("msm8976-skun-snd-card"))) {
         strlcpy(mixer_xml_path, MIXER_XML_PATH_SKUM,
                 sizeof(MIXER_XML_PATH_SKUM));
         msm_device_to_be_id = msm_device_to_be_id_internal_codec;
@@ -4504,13 +4506,14 @@
     return ret;
 }
 
-int platform_get_wsa_mode(void *platform)
+int platform_get_wsa_mode(void *adev)
 {
-    struct platform_data *my_data = (struct platform_data *)platform;
+    struct audio_device *adev_h = adev;
     char *snd_card_name;
 
-    snd_card_name = mixer_get_name(my_data->adev->mixer);
+    snd_card_name = mixer_get_name(adev_h->mixer);
     if ((!strcmp(snd_card_name, "msm8952-skum-snd-card")) ||
+        (!strcmp(snd_card_name, "msm8952-snd-card")) ||
         (!strcmp(snd_card_name, "msm8952-snd-card-mtp")))
         return 1;
     else
diff --git a/hal/msm8916/platform.h b/hal/msm8916/platform.h
index 9f0015a..82c01db 100644
--- a/hal/msm8916/platform.h
+++ b/hal/msm8916/platform.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
  * Not a Contribution.
  *
  * Copyright (C) 2013 The Android Open Source Project
@@ -47,6 +47,15 @@
     (AUDIO_DEVICE_OUT_EARPIECE | AUDIO_DEVICE_OUT_SPEAKER | \
      AUDIO_DEVICE_OUT_WIRED_HEADSET | AUDIO_DEVICE_OUT_WIRED_HEADPHONE)
 
+/*
+ * Below are the input devices for which back end is same, SLIMBUS_0_TX.
+ * All these devices are handled by the internal HW codec. We can
+ * enable any one of these devices at any time
+ */
+#define AUDIO_DEVICE_IN_ALL_CODEC_BACKEND \
+    (AUDIO_DEVICE_IN_BUILTIN_MIC | AUDIO_DEVICE_IN_BACK_MIC | \
+     AUDIO_DEVICE_IN_WIRED_HEADSET | AUDIO_DEVICE_IN_VOICE_CALL) & ~AUDIO_DEVICE_BIT_IN
+
 /* Sound devices specific to the platform
  * The DEVICE_OUT_* and DEVICE_IN_* should be mapped to these sound
  * devices to enable corresponding mixer paths
diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c
index 6212f23..7be3011 100644
--- a/hal/msm8960/platform.c
+++ b/hal/msm8960/platform.c
@@ -1176,7 +1176,7 @@
     return -ENOSYS;
 }
 
-int platform_get_wsa_mode(void *platform)
+int platform_get_wsa_mode(void *adev)
 {
     return 0;
 }
diff --git a/hal/msm8960/platform.h b/hal/msm8960/platform.h
index 4b4d14e..aab5436 100644
--- a/hal/msm8960/platform.h
+++ b/hal/msm8960/platform.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013, 2015 The Linux Foundation. All rights reserved.
  * Not a contribution.
  *
  * Copyright (C) 2013 The Android Open Source Project
@@ -35,6 +35,15 @@
     (AUDIO_DEVICE_OUT_EARPIECE | AUDIO_DEVICE_OUT_SPEAKER | \
      AUDIO_DEVICE_OUT_WIRED_HEADSET | AUDIO_DEVICE_OUT_WIRED_HEADPHONE)
 
+/*
+ * Below are the input devices for which back end is same, SLIMBUS_0_TX.
+ * All these devices are handled by the internal HW codec. We can
+ * enable any one of these devices at any time
+ */
+#define AUDIO_DEVICE_IN_ALL_CODEC_BACKEND \
+    (AUDIO_DEVICE_IN_BUILTIN_MIC | AUDIO_DEVICE_IN_BACK_MIC | \
+     AUDIO_DEVICE_IN_WIRED_HEADSET | AUDIO_DEVICE_IN_VOICE_CALL) & ~AUDIO_DEVICE_BIT_IN
+
 /* Sound devices specific to the platform
  * The DEVICE_OUT_* and DEVICE_IN_* should be mapped to these sound
  * devices to enable corresponding mixer paths
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 019a889..5b1cebc 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -4093,7 +4093,7 @@
     return ret;
 }
 
-int platform_get_wsa_mode (void *platform)
+int platform_get_wsa_mode (void *adev)
 {
     return 0;
 }
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index 4b90f8b..79e0816 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -45,6 +45,15 @@
     (AUDIO_DEVICE_OUT_EARPIECE | AUDIO_DEVICE_OUT_SPEAKER | \
      AUDIO_DEVICE_OUT_WIRED_HEADSET | AUDIO_DEVICE_OUT_WIRED_HEADPHONE)
 
+/*
+ * Below are the input devices for which back end is same, SLIMBUS_0_TX.
+ * All these devices are handled by the internal HW codec. We can
+ * enable any one of these devices at any time
+ */
+#define AUDIO_DEVICE_IN_ALL_CODEC_BACKEND \
+    (AUDIO_DEVICE_IN_BUILTIN_MIC | AUDIO_DEVICE_IN_BACK_MIC | \
+     AUDIO_DEVICE_IN_WIRED_HEADSET | AUDIO_DEVICE_IN_VOICE_CALL) & ~AUDIO_DEVICE_BIT_IN
+
 /* Sound devices specific to the platform
  * The DEVICE_OUT_* and DEVICE_IN_* should be mapped to these sound
  * devices to enable corresponding mixer paths
diff --git a/hal/platform_api.h b/hal/platform_api.h
index d8fa8fa..0b59d78 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -121,5 +121,5 @@
                                        const char *spkr_1_tz_name, const char *spkr_2_tz_name);
 const char *platform_get_spkr_1_tz_name(snd_device_t snd_device);
 const char *platform_get_spkr_2_tz_name(snd_device_t snd_device);
-int platform_get_wsa_mode(void *platform);
+int platform_get_wsa_mode(void *adev);
 #endif // AUDIO_PLATFORM_API_H