Merge "hal: fix incompatible APIs"
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 60ddb99..565891b 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -91,6 +91,7 @@
 
 #define AUDIO_PARAMETER_KEY_FLUENCE_TYPE  "fluence"
 #define AUDIO_PARAMETER_KEY_SLOWTALK      "st_enable"
+#define AUDIO_PARAMETER_KEY_HD_VOICE      "hd_voice"
 #define AUDIO_PARAMETER_KEY_VOLUME_BOOST  "volume_boost"
 
 enum {
@@ -122,6 +123,7 @@
     char fluence_cap[PROPERTY_VALUE_MAX];
     int  fluence_mode;
     bool slowtalk;
+    bool hd_voice;
     /* Audio calibration related functions */
     void                       *acdb_handle;
     int                        voice_feature_set;
@@ -719,6 +721,8 @@
     my_data->fluence_in_audio_rec = false;
     my_data->fluence_type = FLUENCE_NONE;
     my_data->fluence_mode = FLUENCE_ENDFIRE;
+    my_data->slowtalk = false;
+    my_data->hd_voice = false;
 
     property_get("ro.qc.sdk.audio.fluencetype", my_data->fluence_cap, "");
     if (!strncmp("fluencepro", my_data->fluence_cap, sizeof("fluencepro"))) {
@@ -1820,6 +1824,30 @@
     return ret;
 }
 
+static int set_hd_voice(struct platform_data *my_data, bool state)
+{
+    struct audio_device *adev = my_data->adev;
+    struct mixer_ctl *ctl;
+    const char *mixer_ctl_name = "HD Voice Enable";
+    int ret = 0;
+    uint32_t set_values[ ] = {0,
+                              ALL_SESSION_VSID};
+
+    set_values[0] = state;
+    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);
+        ret = -EINVAL;
+    } else {
+        ALOGV("Setting HD Voice state: %d", state);
+        ret = mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
+        my_data->hd_voice = state;
+    }
+
+    return ret;
+}
+
 int platform_set_parameters(void *platform, struct str_parms *parms)
 {
     struct platform_data *my_data = (struct platform_data *)platform;
@@ -1827,8 +1855,11 @@
     char value[256] = {0};
     int val;
     int ret = 0, err;
+    char *kv_pairs = NULL;
 
-    ALOGV("%s: enter: %s", __func__, str_parms_to_str(parms));
+    kv_pairs = str_parms_to_str(parms);
+    ALOGV("%s: enter: - %s", __func__, kv_pairs);
+    free(kv_pairs);
 
     err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_SLOWTALK, value, sizeof(value));
     if (err >= 0) {
@@ -1843,6 +1874,23 @@
             ALOGE("%s: Failed to set slow talk err: %d", __func__, ret);
     }
 
+    err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_HD_VOICE, value, sizeof(value));
+    if (err >= 0) {
+        bool state = false;
+        if (!strncmp("true", value, sizeof("true"))) {
+            state = true;
+        }
+
+        str_parms_del(parms, AUDIO_PARAMETER_KEY_HD_VOICE);
+        if (my_data->hd_voice != state) {
+            ret = set_hd_voice(my_data, state);
+            if (ret)
+                ALOGE("%s: Failed to set HD voice err: %d", __func__, ret);
+        } else {
+            ALOGV("%s: HD Voice already set to %d", __func__, state);
+        }
+    }
+
     err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_VOLUME_BOOST,
                             value, sizeof(value));
     if (err >= 0) {
@@ -1973,6 +2021,7 @@
     char *str = NULL;
     char value[256] = {0};
     int ret;
+    char *kv_pairs = NULL;
 
     ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_SLOWTALK,
                             value, sizeof(value));
@@ -1981,6 +2030,13 @@
                           my_data->slowtalk?"true":"false");
     }
 
+    ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_HD_VOICE,
+                            value, sizeof(value));
+    if (ret >= 0) {
+        str_parms_add_str(reply, AUDIO_PARAMETER_KEY_HD_VOICE,
+                          my_data->hd_voice?"true":"false");
+    }
+
     ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_VOLUME_BOOST,
                             value, sizeof(value));
     if (ret >= 0) {
@@ -1993,7 +2049,9 @@
         str_parms_add_str(reply, AUDIO_PARAMETER_KEY_VOLUME_BOOST, value);
     }
 
-    ALOGV("%s: exit: returns - %s", __func__, str_parms_to_str(reply));
+    kv_pairs = str_parms_to_str(reply);
+    ALOGV("%s: exit: returns - %s", __func__, kv_pairs);
+    free(kv_pairs);
 }
 
 /* Delay in Us */
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index a28ddc3..0a7f879 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -90,6 +90,7 @@
 
 #define AUDIO_PARAMETER_KEY_FLUENCE_TYPE  "fluence"
 #define AUDIO_PARAMETER_KEY_SLOWTALK      "st_enable"
+#define AUDIO_PARAMETER_KEY_HD_VOICE      "hd_voice"
 #define AUDIO_PARAMETER_KEY_VOLUME_BOOST  "volume_boost"
 /* Query external audio device connection status */
 #define AUDIO_PARAMETER_KEY_EXT_AUDIO_DEVICE "ext_audio_device"
@@ -130,6 +131,7 @@
     int  fluence_mode;
     char fluence_cap[PROPERTY_VALUE_MAX];
     bool slowtalk;
+    bool hd_voice;
     bool is_i2s_ext_modem;
     /* Audio calibration related functions */
     void                       *acdb_handle;
@@ -805,6 +807,8 @@
     my_data->external_mic = false;
     my_data->fluence_type = FLUENCE_NONE;
     my_data->fluence_mode = FLUENCE_ENDFIRE;
+    my_data->slowtalk = false;
+    my_data->hd_voice = false;
 
     property_get("ro.qc.sdk.audio.fluencetype", my_data->fluence_cap, "");
     if (!strncmp("fluencepro", my_data->fluence_cap, sizeof("fluencepro"))) {
@@ -1998,6 +2002,29 @@
     return ret;
 }
 
+static int set_hd_voice(struct platform_data *my_data, bool state)
+{
+    struct audio_device *adev = my_data->adev;
+    struct mixer_ctl *ctl;
+    char *mixer_ctl_name = "HD Voice Enable";
+    int ret = 0;
+    uint32_t set_values[ ] = {0,
+                              ALL_SESSION_VSID};
+
+    set_values[0] = state;
+    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;
+    } else {
+        ALOGV("Setting HD Voice state: %d", state);
+        ret = mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
+        my_data->hd_voice = state;
+    }
+
+    return ret;
+}
 
 static int update_external_device_status(struct platform_data *my_data,
                                  char* event_name, bool status)
@@ -2051,6 +2078,23 @@
             ALOGE("%s: Failed to set slow talk err: %d", __func__, ret);
     }
 
+    err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_HD_VOICE, value, sizeof(value));
+    if (err >= 0) {
+        bool state = false;
+        if (!strncmp("true", value, sizeof("true"))) {
+            state = true;
+        }
+
+        str_parms_del(parms, AUDIO_PARAMETER_KEY_HD_VOICE);
+        if (my_data->hd_voice != state) {
+            ret = set_hd_voice(my_data, state);
+            if (ret)
+                ALOGE("%s: Failed to set HD voice err: %d", __func__, ret);
+        } else {
+            ALOGV("%s: HD Voice already set to %d", __func__, state);
+        }
+    }
+
     err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_VOLUME_BOOST,
                             value, sizeof(value));
     if (err >= 0) {
@@ -2208,6 +2252,13 @@
                           my_data->slowtalk?"true":"false");
     }
 
+    ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_HD_VOICE,
+                            value, sizeof(value));
+    if (ret >= 0) {
+        str_parms_add_str(reply, AUDIO_PARAMETER_KEY_HD_VOICE,
+                          my_data->hd_voice?"true":"false");
+    }
+
     ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_VOLUME_BOOST,
                             value, sizeof(value));
     if (ret >= 0) {
diff --git a/hal/voice_extn/compress_voip.c b/hal/voice_extn/compress_voip.c
index 46aab7d..224861e 100644
--- a/hal/voice_extn/compress_voip.c
+++ b/hal/voice_extn/compress_voip.c
@@ -612,6 +612,7 @@
     if (!voip_data.in_stream_count)
         ret = voice_extn_compress_voip_open_input_stream(in);
 
+    adev->active_input = in;
     ret = voip_start_call(adev, &in->config);
     in->pcm = voip_data.pcm_tx;
 
@@ -670,6 +671,7 @@
     ALOGD("%s: enter", __func__);
 
     if(voip_data.in_stream_count > 0) {
+       adev->active_input = NULL;
        voip_data.in_stream_count--;
        status = voip_stop_call(adev);
        in->pcm = NULL;