Merge "hal: msm8916: Update the mixer path for the tomtom codec"
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 4d8925d..05ad4f6 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -1808,6 +1808,8 @@
         }
 
         ret = compress_write(out->compr, buffer, bytes);
+        if (ret < 0)
+            ret = -errno;
         ALOGVV("%s: writing buffer (%d bytes) to compress device returned %d", __func__, bytes, ret);
         if (ret >= 0 && ret < (ssize_t)bytes) {
             ALOGD("No space available in compress driver, post msg to cb thread");
@@ -1832,7 +1834,9 @@
                 memset((void *)buffer, 0, bytes);
             ALOGVV("%s: writing buffer (%d bytes) to pcm device", __func__, bytes);
             ret = pcm_write(out->pcm, (void *)buffer, bytes);
-            if (ret == 0)
+            if (ret < 0)
+                ret = -errno;
+            else if (ret == 0)
                 out->written += bytes / (out->config.channels * sizeof(short));
         }
     }
@@ -1874,6 +1878,8 @@
         if (out->compr != NULL) {
             ret = compress_get_tstamp(out->compr, (unsigned long *)dsp_frames,
                     &out->sample_rate);
+            if (ret < 0)
+                ret = -errno;
             ALOGVV("%s rendered frames %d sample_rate %d",
                    __func__, *dsp_frames, out->sample_rate);
         }
@@ -2248,6 +2254,8 @@
             ret = audio_extn_compr_cap_read(in, buffer, bytes);
         else
             ret = pcm_read(in->pcm, buffer, bytes);
+        if (ret < 0)
+            ret = -errno;
     }
 
     /*
@@ -2680,9 +2688,7 @@
 
     err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_NREC, value, sizeof(value));
     if (err >= 0) {
-        /* When set to false, HAL should disable EC and NS
-         * But it is currently not supported.
-         */
+        /* When set to false, HAL should disable EC and NS */
         if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
             adev->bluetooth_nrec = true;
         else
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index f1ceedc..e9f7af7 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -61,7 +61,7 @@
  * Each usecase is mapped to a specific PCM device.
  * Refer to pcm_device_table[].
  */
-typedef enum {
+enum {
     USECASE_INVALID = -1,
     /* Playback usecases */
     USECASE_AUDIO_PLAYBACK_DEEP_BUFFER = 0,
@@ -115,7 +115,9 @@
     USECASE_AUDIO_SPKR_CALIB_RX,
     USECASE_AUDIO_SPKR_CALIB_TX,
     AUDIO_USECASE_MAX
-} audio_usecase_t;
+};
+
+const char * const use_case_table[AUDIO_USECASE_MAX];
 
 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
 
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 0444b97..ae7b18a 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -232,7 +232,9 @@
     [SND_DEVICE_IN_VOICE_HEADSET_MIC] = "voice-headset-mic",
     [SND_DEVICE_IN_HDMI_MIC] = "hdmi-mic",
     [SND_DEVICE_IN_BT_SCO_MIC] = "bt-sco-mic",
+    [SND_DEVICE_IN_BT_SCO_MIC_NREC] = "bt-sco-mic",
     [SND_DEVICE_IN_BT_SCO_MIC_WB] = "bt-sco-mic-wb",
+    [SND_DEVICE_IN_BT_SCO_MIC_WB_NREC] = "bt-sco-mic-wb",
     [SND_DEVICE_IN_CAMCORDER_MIC] = "camcorder-mic",
     [SND_DEVICE_IN_VOICE_DMIC] = "voice-dmic-ef",
     [SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = "voice-speaker-dmic-ef",
@@ -310,7 +312,9 @@
     [SND_DEVICE_IN_VOICE_HEADSET_MIC] = 8,
     [SND_DEVICE_IN_HDMI_MIC] = 4,
     [SND_DEVICE_IN_BT_SCO_MIC] = 21,
+    [SND_DEVICE_IN_BT_SCO_MIC_NREC] = 122,
     [SND_DEVICE_IN_BT_SCO_MIC_WB] = 38,
+    [SND_DEVICE_IN_BT_SCO_MIC_WB_NREC] = 123,
     [SND_DEVICE_IN_CAMCORDER_MIC] = 4,
     [SND_DEVICE_IN_VOICE_DMIC] = 41,
     [SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = 43,
@@ -393,7 +397,9 @@
     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_HEADSET_MIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_HDMI_MIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_NREC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_WB)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_WB_NREC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_MIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_DMIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_DMIC)},
@@ -824,9 +830,11 @@
 
 void platform_add_backend_name(char *mixer_path, snd_device_t snd_device)
 {
-    if (snd_device == SND_DEVICE_IN_BT_SCO_MIC)
+    if ((snd_device == SND_DEVICE_IN_BT_SCO_MIC) ||
+         (snd_device == SND_DEVICE_IN_BT_SCO_MIC_NREC))
         strlcat(mixer_path, " bt-sco", MIXER_PATH_MAX_LENGTH);
-    else if (snd_device == SND_DEVICE_IN_BT_SCO_MIC_WB)
+    else if ((snd_device == SND_DEVICE_IN_BT_SCO_MIC_WB) ||
+              (snd_device == SND_DEVICE_IN_BT_SCO_MIC_WB_NREC))
         strlcat(mixer_path, " bt-sco-wb", MIXER_PATH_MAX_LENGTH);
     else if(snd_device == SND_DEVICE_OUT_BT_SCO)
         strlcat(mixer_path, " bt-sco", MIXER_PATH_MAX_LENGTH);
@@ -1433,10 +1441,17 @@
             snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC;
             set_echo_reference(adev->mixer, EC_REF_RX);
         } else if (out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
-            if (adev->bt_wb_speech_enabled)
-                snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
-            else
-                snd_device = SND_DEVICE_IN_BT_SCO_MIC;
+            if (adev->bt_wb_speech_enabled) {
+                if (adev->bluetooth_nrec)
+                    snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB_NREC;
+                else
+                    snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
+            } else {
+                if (adev->bluetooth_nrec)
+                    snd_device = SND_DEVICE_IN_BT_SCO_MIC_NREC;
+                else
+                    snd_device = SND_DEVICE_IN_BT_SCO_MIC;
+            }
         } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
             if (my_data->fluence_type != FLUENCE_NONE &&
                 my_data->fluence_in_voice_call &&
@@ -1585,10 +1600,17 @@
         } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
             snd_device = SND_DEVICE_IN_HEADSET_MIC;
         } else if (in_device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
-            if (adev->bt_wb_speech_enabled)
-                snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
-            else
-                snd_device = SND_DEVICE_IN_BT_SCO_MIC;
+            if (adev->bt_wb_speech_enabled) {
+                if (adev->bluetooth_nrec)
+                    snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB_NREC;
+                else
+                    snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
+            } else {
+                if (adev->bluetooth_nrec)
+                    snd_device = SND_DEVICE_IN_BT_SCO_MIC_NREC;
+                else
+                    snd_device = SND_DEVICE_IN_BT_SCO_MIC;
+            }
         } else if (in_device & AUDIO_DEVICE_IN_AUX_DIGITAL) {
             snd_device = SND_DEVICE_IN_HDMI_MIC;
         } else if (in_device & AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET ||
@@ -1614,10 +1636,17 @@
         } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
             snd_device = SND_DEVICE_IN_HANDSET_MIC;
         } else if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
-            if (adev->bt_wb_speech_enabled)
-                snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
-            else
-                snd_device = SND_DEVICE_IN_BT_SCO_MIC;
+            if (adev->bt_wb_speech_enabled) {
+                if (adev->bluetooth_nrec)
+                    snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB_NREC;
+                else
+                    snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
+            } else {
+                if (adev->bluetooth_nrec)
+                    snd_device = SND_DEVICE_IN_BT_SCO_MIC_NREC;
+                else
+                    snd_device = SND_DEVICE_IN_BT_SCO_MIC;
+            }
         } else if (out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
             snd_device = SND_DEVICE_IN_HDMI_MIC;
         } else if (out_device & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET ||
diff --git a/hal/msm8916/platform.h b/hal/msm8916/platform.h
index 3fc8fbf..dec9eda 100644
--- a/hal/msm8916/platform.h
+++ b/hal/msm8916/platform.h
@@ -107,7 +107,9 @@
     SND_DEVICE_IN_VOICE_HEADSET_MIC,
     SND_DEVICE_IN_HDMI_MIC,
     SND_DEVICE_IN_BT_SCO_MIC,
+    SND_DEVICE_IN_BT_SCO_MIC_NREC,
     SND_DEVICE_IN_BT_SCO_MIC_WB,
+    SND_DEVICE_IN_BT_SCO_MIC_WB_NREC,
     SND_DEVICE_IN_CAMCORDER_MIC,
     SND_DEVICE_IN_VOICE_DMIC,
     SND_DEVICE_IN_VOICE_SPEAKER_DMIC,
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 88a09b8..949753d 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -266,7 +266,9 @@
     [SND_DEVICE_IN_VOICE_HEADSET_MIC] = "voice-headset-mic",
     [SND_DEVICE_IN_HDMI_MIC] = "hdmi-mic",
     [SND_DEVICE_IN_BT_SCO_MIC] = "bt-sco-mic",
+    [SND_DEVICE_IN_BT_SCO_MIC_NREC] = "bt-sco-mic",
     [SND_DEVICE_IN_BT_SCO_MIC_WB] = "bt-sco-mic-wb",
+    [SND_DEVICE_IN_BT_SCO_MIC_WB_NREC] = "bt-sco-mic-wb",
     [SND_DEVICE_IN_CAMCORDER_MIC] = "camcorder-mic",
     [SND_DEVICE_IN_VOICE_DMIC] = "voice-dmic-ef",
     [SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = "voice-speaker-dmic-ef",
@@ -349,7 +351,9 @@
     [SND_DEVICE_IN_VOICE_HEADSET_MIC] = 8,
     [SND_DEVICE_IN_HDMI_MIC] = 4,
     [SND_DEVICE_IN_BT_SCO_MIC] = 21,
+    [SND_DEVICE_IN_BT_SCO_MIC_NREC] = 122,
     [SND_DEVICE_IN_BT_SCO_MIC_WB] = 38,
+    [SND_DEVICE_IN_BT_SCO_MIC_WB_NREC] = 123,
     [SND_DEVICE_IN_CAMCORDER_MIC] = 4,
     [SND_DEVICE_IN_VOICE_DMIC] = 41,
     [SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = 43,
@@ -437,7 +441,9 @@
     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_HEADSET_MIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_HDMI_MIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_NREC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_WB)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_WB_NREC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_MIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_DMIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_DMIC)},
@@ -676,6 +682,8 @@
     // will help in avoiding strdups here
     backend_table[SND_DEVICE_IN_BT_SCO_MIC] = strdup("bt-sco");
     backend_table[SND_DEVICE_IN_BT_SCO_MIC_WB] = strdup("bt-sco-wb");
+    backend_table[SND_DEVICE_IN_BT_SCO_MIC_NREC] = strdup("bt-sco");
+    backend_table[SND_DEVICE_IN_BT_SCO_MIC_WB_NREC] = strdup("bt-sco-wb");
     backend_table[SND_DEVICE_OUT_BT_SCO] = strdup("bt-sco");
     backend_table[SND_DEVICE_OUT_BT_SCO_WB] = strdup("bt-sco-wb");
     backend_table[SND_DEVICE_OUT_HDMI] = strdup("hdmi");
@@ -1649,10 +1657,17 @@
             snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC;
             set_echo_reference(adev, true);
         } else if (out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
-            if (adev->bt_wb_speech_enabled)
-                snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
-            else
-                snd_device = SND_DEVICE_IN_BT_SCO_MIC;
+            if (adev->bt_wb_speech_enabled) {
+                if (adev->bluetooth_nrec)
+                    snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB_NREC;
+                else
+                    snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
+            } else {
+                if (adev->bluetooth_nrec)
+                    snd_device = SND_DEVICE_IN_BT_SCO_MIC_NREC;
+                else
+                    snd_device = SND_DEVICE_IN_BT_SCO_MIC;
+            }
         } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
             if (my_data->fluence_type != FLUENCE_NONE &&
                 my_data->fluence_in_voice_call &&
@@ -1800,10 +1815,17 @@
         } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
             snd_device = SND_DEVICE_IN_HEADSET_MIC;
         } else if (in_device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
-            if (adev->bt_wb_speech_enabled)
-                snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
-            else
-                snd_device = SND_DEVICE_IN_BT_SCO_MIC;
+            if (adev->bt_wb_speech_enabled) {
+                if (adev->bluetooth_nrec)
+                    snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB_NREC;
+                else
+                    snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
+            } else {
+                if (adev->bluetooth_nrec)
+                    snd_device = SND_DEVICE_IN_BT_SCO_MIC_NREC;
+                else
+                    snd_device = SND_DEVICE_IN_BT_SCO_MIC;
+            }
         } else if (in_device & AUDIO_DEVICE_IN_AUX_DIGITAL) {
             snd_device = SND_DEVICE_IN_HDMI_MIC;
         } else if (in_device & AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET ||
@@ -1829,10 +1851,17 @@
         } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
             snd_device = SND_DEVICE_IN_HANDSET_MIC;
         } else if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
-            if (adev->bt_wb_speech_enabled)
-                snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
-            else
-                snd_device = SND_DEVICE_IN_BT_SCO_MIC;
+            if (adev->bt_wb_speech_enabled) {
+                if (adev->bluetooth_nrec)
+                    snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB_NREC;
+                else
+                    snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
+            } else {
+                if (adev->bluetooth_nrec)
+                    snd_device = SND_DEVICE_IN_BT_SCO_MIC_NREC;
+                else
+                    snd_device = SND_DEVICE_IN_BT_SCO_MIC;
+            }
         } else if (out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
             snd_device = SND_DEVICE_IN_HDMI_MIC;
         } else if (out_device & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET ||
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index 19f37c7..6f430cc 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -112,7 +112,9 @@
     SND_DEVICE_IN_VOICE_HEADSET_MIC,
     SND_DEVICE_IN_HDMI_MIC,
     SND_DEVICE_IN_BT_SCO_MIC,
+    SND_DEVICE_IN_BT_SCO_MIC_NREC,
     SND_DEVICE_IN_BT_SCO_MIC_WB,
+    SND_DEVICE_IN_BT_SCO_MIC_WB_NREC,
     SND_DEVICE_IN_CAMCORDER_MIC,
     SND_DEVICE_IN_VOICE_DMIC,
     SND_DEVICE_IN_VOICE_SPEAKER_DMIC,
diff --git a/hal/voice.c b/hal/voice.c
index a5826e6..71fee64 100644
--- a/hal/voice.c
+++ b/hal/voice.c
@@ -41,8 +41,6 @@
     .format = PCM_FORMAT_S16_LE,
 };
 
-extern const char * const use_case_table[AUDIO_USECASE_MAX];
-
 static struct voice_session *voice_get_session_from_use_case(struct audio_device *adev,
                               audio_usecase_t usecase_id)
 {
@@ -57,7 +55,7 @@
     return session;
 }
 
-int stop_call(struct audio_device *adev, audio_usecase_t usecase_id)
+int voice_stop_usecase(struct audio_device *adev, audio_usecase_t usecase_id)
 {
     int i, ret = 0;
     struct audio_usecase *uc_info;
@@ -108,7 +106,7 @@
     return ret;
 }
 
-int start_call(struct audio_device *adev, audio_usecase_t usecase_id)
+int voice_start_usecase(struct audio_device *adev, audio_usecase_t usecase_id)
 {
     int i, ret = 0;
     struct audio_usecase *uc_info;
@@ -195,7 +193,7 @@
     goto done;
 
 error_start_voice:
-    stop_call(adev, usecase_id);
+    voice_stop_usecase(adev, usecase_id);
 
 done:
     ALOGD("%s: exit: status(%d)", __func__, ret);
@@ -372,7 +370,7 @@
 
     ret = voice_extn_start_call(adev);
     if (ret == -ENOSYS) {
-        ret = start_call(adev, USECASE_VOICE_CALL);
+        ret = voice_start_usecase(adev, USECASE_VOICE_CALL);
     }
     adev->voice.in_call = true;
 
@@ -386,7 +384,7 @@
     adev->voice.in_call = false;
     ret = voice_extn_stop_call(adev);
     if (ret == -ENOSYS) {
-        ret = stop_call(adev, USECASE_VOICE_CALL);
+        ret = voice_stop_usecase(adev, USECASE_VOICE_CALL);
     }
 
     return ret;
diff --git a/hal/voice.h b/hal/voice.h
index 5d1ae40..95609b3 100644
--- a/hal/voice.h
+++ b/hal/voice.h
@@ -42,6 +42,7 @@
 struct str_parms;
 struct stream_in;
 struct stream_out;
+typedef int audio_usecase_t;
 
 struct call_state {
     int current;
@@ -71,6 +72,9 @@
     INCALL_REC_UPLINK_AND_DOWNLINK,
 };
 
+int voice_start_usecase(struct audio_device *adev, audio_usecase_t usecase_id);
+int voice_stop_usecase(struct audio_device *adev, audio_usecase_t usecase_id);
+
 int voice_start_call(struct audio_device *adev);
 int voice_stop_call(struct audio_device *adev);
 int voice_set_parameters(struct audio_device *adev, struct str_parms *parms);
diff --git a/hal/voice_extn/voice_extn.c b/hal/voice_extn/voice_extn.c
index 89abc3a..dcbe825 100644
--- a/hal/voice_extn/voice_extn.c
+++ b/hal/voice_extn/voice_extn.c
@@ -71,8 +71,6 @@
     .avail_min = LOW_LATENCY_OUTPUT_PERIOD_SIZE / 4,
 };
 
-extern int start_call(struct audio_device *adev, audio_usecase_t usecase_id);
-extern int stop_call(struct audio_device *adev, audio_usecase_t usecase_id);
 int voice_extn_is_call_state_active(struct audio_device *adev, bool *is_call_active);
 
 static bool is_valid_call_state(int call_state)
@@ -169,9 +167,9 @@
             {
             case CALL_INACTIVE:
                 ALOGD("%s: INACTIVE -> ACTIVE vsid:%x", __func__, session->vsid);
-                ret = start_call(adev, usecase_id);
+                ret = voice_start_usecase(adev, usecase_id);
                 if(ret < 0) {
-                    ALOGE("%s: voice_start_call() failed for usecase: %d\n",
+                    ALOGE("%s: voice_start_usecase() failed for usecase: %d\n",
                           __func__, usecase_id);
                 } else {
                     session->state.current = session->state.new;
@@ -207,9 +205,9 @@
             case CALL_HOLD:
             case CALL_LOCAL_HOLD:
                 ALOGD("%s: ACTIVE/HOLD/LOCAL_HOLD -> INACTIVE vsid:%x", __func__, session->vsid);
-                ret = stop_call(adev, usecase_id);
+                ret = voice_stop_usecase(adev, usecase_id);
                 if(ret < 0) {
-                    ALOGE("%s: voice_end_call() failed for usecase: %d\n",
+                    ALOGE("%s: voice_stop_usecase() failed for usecase: %d\n",
                           __func__, usecase_id);
                 } else {
                     session->state.current = session->state.new;