Merge remote-tracking branch 'quic/LA.BR.1' into HEAD

* quic/LA.BR.1: (37 commits)
  hal: Performance mode during recording usecase
  audio: Support for compress offload recovery
  audio: Fix for clip skip issue during SSR
  hal: add checks for calibration buffer allocation failures
  mm-audio: aenc-aac: fix integer overflow for encoded buffer timestamp calculation
  hal: Add support for 8909 QRD skue
  hal: Fix for FM mute issue on start of FM record
  hal: Fix array length computation for backend id array.
  hal : set Non SA+ app type for PCM Capture
  hal : Fix for SA+ app type selection for PCM Capture usecase
  hal : Fix for SA+ app type selection for PCM Capture usecase
  hal: use 0 as default return value for out_get_render_position
  audio: hal: Add support for pm8916 on msm8909
  hal: Define a new combo device for AANC and Fluence
  hal: Define a new combo device for AANC and Fluence
  hal: use 0 as default return value for out_get_render_position
  hal: Update DS2 implementation to support ACDB based license mechanism
  hal : Overwrite the APP type for PCM RX and TX path
  audio: HAL to support for peripheral manager
  hal : Set the input device for VOIP calls using audio path
  ...
Conflicts:
	hal/Android.mk
	hal/audio_extn/audio_extn.c
	hal/audio_extn/audio_extn.h
	hal/audio_extn/dolby.c
	hal/audio_extn/utils.c
	hal/audio_hw.c
	hal/msm8916/hw_info.c
	hal/msm8916/platform.c
	hal/msm8974/platform.c
	hal/platform_api.h
Change-Id: Ibfa171e8f3af713dbb2cffbaf2ca2b0df3e8ae73
diff --git a/hal/Android.mk b/hal/Android.mk
index c27ac4b..9d78ddc 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -222,6 +222,13 @@
     LOCAL_CFLAGS += -DAUXPCM_BT_ENABLED
 endif
 
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_PM_SUPPORT)),true)
+    LOCAL_CFLAGS += -DPM_SUPPORT_ENABLED
+    LOCAL_SRC_FILES += audio_extn/pm.c
+    LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/libperipheralclient/inc
+    LOCAL_SHARED_LIBRARIES += libperipheral_client
+endif
+
 LOCAL_COPY_HEADERS_TO   := mm-audio
 LOCAL_COPY_HEADERS      := audio_extn/audio_defs.h
 
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index 62ab6d5..ff485e5 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -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
@@ -534,6 +534,7 @@
    audio_extn_ds2_set_parameters(adev, parms);
    audio_extn_customstereo_set_parameters(adev, parms);
    audio_extn_hpx_set_parameters(adev, parms);
+   audio_extn_pm_set_parameters(parms);
 }
 
 void audio_extn_get_parameters(const struct audio_device *adev,
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index 5aa9f2e..7bfa607 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.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
@@ -310,6 +310,7 @@
 void audio_extn_dolby_set_endpoint(struct audio_device *adev);
 #endif
 
+
 #if defined(DS1_DOLBY_DDP_ENABLED) || defined(DS2_DOLBY_DAP_ENABLED)
 bool audio_extn_is_dolby_format(audio_format_t format);
 int audio_extn_dolby_get_snd_codec_id(struct audio_device *adev,
@@ -377,6 +378,16 @@
 int audio_extn_dev_arbi_release(snd_device_t snd_device);
 #endif
 
+#ifndef PM_SUPPORT_ENABLED
+#define audio_extn_pm_set_parameters(params) (0)
+#define audio_extn_pm_vote(void) (0)
+#define audio_extn_pm_unvote(void) (0)
+#else
+void audio_extn_pm_set_parameters(struct str_parms *parms);
+int audio_extn_pm_vote (void);
+void audio_extn_pm_unvote(void);
+#endif
+
 void audio_extn_utils_update_streams_output_cfg_list(void *platform,
                                   struct mixer *mixer,
                                   struct listnode *streams_output_cfg_list);
diff --git a/hal/audio_extn/dolby.c b/hal/audio_extn/dolby.c
old mode 100644
new mode 100755
index cdfa2a1..0f53ad7
--- a/hal/audio_extn/dolby.c
+++ b/hal/audio_extn/dolby.c
@@ -20,7 +20,6 @@
 #define LOG_TAG "audio_hw_dolby"
 //#define LOG_NDEBUG 0
 //#define LOG_NDDEBUG 0
-
 #include <errno.h>
 #include <cutils/properties.h>
 #include <stdlib.h>
@@ -749,7 +748,7 @@
 
 void audio_extn_dolby_set_license(struct audio_device *adev)
 {
-    int i_key;
+    int i_key=0;
     char c_key[128] = {0};
     char c_dmid[128] = {0};
     int i_dmid, ret = -EINVAL;
diff --git a/hal/audio_extn/pm.c b/hal/audio_extn/pm.c
new file mode 100644
index 0000000..7b76f60
--- /dev/null
+++ b/hal/audio_extn/pm.c
@@ -0,0 +1,149 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#define LOG_TAG "audio_hw_pm"
+/*#define LOG_NDEBUG 0*/
+
+#include "pm.h"
+#include <cutils/log.h>
+
+static s_audio_subsys audio_ss;
+
+int audio_extn_pm_vote(void)
+{
+    int err, intfd, ret;
+    FILE *fd;
+    enum pm_event subsys_state;
+    char halPropVal[PROPERTY_VALUE_MAX];
+    bool prop_unload_image = false;
+    bool pm_reg = false;
+    bool pm_supp = false;
+
+    platform_get_subsys_image_name((char *)&audio_ss.img_name);
+    ALOGD("%s: register with peripheral manager for %s",__func__, audio_ss.img_name);
+    ret = pm_client_register(audio_extn_pm_event_notifier,
+                      &audio_ss,
+                      audio_ss.img_name,
+                      PM_CLIENT_NAME,
+                      &subsys_state,
+                      &audio_ss.pm_handle);
+    if (ret == PM_RET_SUCCESS) {
+        pm_reg = true;
+        pm_supp = true;
+        ALOGV("%s: registered with peripheral manager for %s",
+                  __func__, audio_ss.img_name);
+    } else if (ret == PM_RET_UNSUPPORTED) {
+        pm_reg = true;
+        pm_supp = false;
+        ALOGV("%s: peripheral mgr unsupported for %s",
+              __func__, audio_ss.img_name);
+        return ret;
+    } else {
+       return ret;
+    }
+    if (pm_supp == true &&
+       pm_reg == true) {
+       ALOGD("%s: Voting for subsystem power up", __func__);
+       pm_client_connect(audio_ss.pm_handle);
+
+       if (property_get("sys.audio.init", halPropVal, NULL)) {
+           prop_unload_image = !(strncmp("false", halPropVal, sizeof("false")));
+       }
+       /*
+        * adsp-loader loads modem/adsp image at boot up to play boot tone,
+        * before peripheral manager service is up. Once PM is up, vote to PM
+        * and unload the image to give control to PM to load/unload image
+        */
+       if (prop_unload_image) {
+           intfd = open(BOOT_IMG_SYSFS_PATH, O_WRONLY);
+           if (intfd == -1) {
+               ALOGE("failed to open fd in write mode, %d", errno);
+           } else {
+               ALOGD("%s: write to sysfs to unload image", __func__);
+               err = write(intfd, UNLOAD_IMAGE, 1);
+               close(intfd);
+               property_set("sys.audio.init", "true");
+          }
+       }
+    }
+    return 0;
+}
+
+void audio_extn_pm_unvote(void)
+{
+    ALOGD("%s", __func__);
+    if (audio_ss.pm_handle) {
+        pm_client_disconnect(audio_ss.pm_handle);
+        pm_client_unregister(audio_ss.pm_handle);
+    }
+}
+
+void audio_extn_pm_set_parameters(struct str_parms *parms)
+{
+    int ret;
+    char value[32];
+
+    ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_DEV_SHUTDOWN, value, sizeof(value));
+    if (ret >= 0) {
+        if (strstr(value, "true")) {
+            ALOGD("Device shutdown notification received, unregister with PM");
+            audio_extn_pm_unvote();
+        }
+    }
+}
+
+void audio_extn_pm_event_notifier(void *client_data, enum pm_event event)
+{
+    pm_client_event_acknowledge(audio_ss.pm_handle, event);
+
+    /* Closing and re-opening of session is done based on snd card status given
+     * by AudioDaemon during SS offline/online (legacy code). Just return for now.
+     */
+    switch (event) {
+    case EVENT_PERIPH_GOING_OFFLINE:
+        ALOGV("%s: %s is going offline", __func__, audio_ss.img_name);
+    break;
+
+    case EVENT_PERIPH_IS_OFFLINE:
+        ALOGV("%s: %s is offline", __func__, audio_ss.img_name);
+    break;
+
+    case EVENT_PERIPH_GOING_ONLINE:
+        ALOGV("%s: %s is going online", __func__, audio_ss.img_name);
+    break;
+
+    case EVENT_PERIPH_IS_ONLINE:
+        ALOGV("%s: %s is online", __func__, audio_ss.img_name);
+    break;
+
+    default:
+        ALOGV("%s: invalid event received from PM", __func__);
+    break;
+    }
+}
diff --git a/hal/audio_extn/pm.h b/hal/audio_extn/pm.h
new file mode 100644
index 0000000..daa376e
--- /dev/null
+++ b/hal/audio_extn/pm.h
@@ -0,0 +1,68 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef AUDIO_EXTN_PM_H
+#define AUDIO_EXTN_PM_H
+
+#include <errno.h>
+#include <math.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <pm-service.h>
+#include "audio_hw.h"
+#include <platform.h>
+#include <cutils/properties.h>
+#include <cutils/log.h>
+
+
+/* Client name to be registered with PM */
+#define PM_CLIENT_NAME "audio"
+/* Command to sysfs to unload image */
+#define UNLOAD_IMAGE "0"
+#define MAX_NAME_LEN 32
+#define BOOT_IMG_SYSFS_PATH "/sys/kernel/boot_adsp/boot"
+
+typedef struct {
+    //MAX_NAME_LEN defined in mdm_detect.h
+    char img_name[MAX_NAME_LEN];
+    //this handle is used by peripheral mgr
+    void *pm_handle;
+}s_audio_subsys;
+
+/* Vote to peripheral manager for required subsystem */
+int audio_extn_pm_vote (void);
+
+/* Unvote to peripheral manager */
+void audio_extn_pm_unvote (void);
+
+/* Get subsytem status notification from PM */
+void audio_extn_pm_event_notifier (void *client_data, enum pm_event event);
+
+#endif // AUDIO_EXTN_PM_H
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index 34e6089..96722cc 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -579,23 +579,15 @@
         int snd_device = usecase->out_snd_device;
         snd_device = (snd_device == SND_DEVICE_OUT_SPEAKER) ?
                      audio_extn_get_spkr_prot_snd_device(snd_device) : snd_device;
-        platform_send_audio_calibration(adev->platform, usecase->out_snd_device,
+        platform_send_audio_calibration(adev->platform, usecase,
                                         out->app_type_cfg.app_type,
                                         out->app_type_cfg.sample_rate);
     }
     if ((type == PCM_HFP_CALL) || (type == PCM_CAPTURE)) {
-        if ((type == PCM_CAPTURE) & voice_is_in_call_rec_stream(usecase->stream.in)) {
-            snd_device_t incall_record_snd_device =
-                        voice_get_incall_rec_snd_device(usecase->in_snd_device);
-            platform_send_audio_calibration(adev->platform, incall_record_snd_device,
-                                            platform_get_default_app_type(adev->platform),
-                                            48000);
-        } else {
-            /* when app type is default. the sample rate is not used to send cal */
-            platform_send_audio_calibration(adev->platform, usecase->in_snd_device,
-                                            platform_get_default_app_type(adev->platform),
-                                            48000);
-        }
+        /* when app type is default. the sample rate is not used to send cal */
+        platform_send_audio_calibration(adev->platform, usecase,
+                                        platform_get_default_app_type(adev->platform),
+                                        48000);
     }
 }
 
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 3750945..977f77e 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -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
@@ -1210,17 +1210,21 @@
             ret = compress_next_track(out->compr);
             if(ret == 0) {
                 ALOGD("copl(%p):calling compress_partial_drain", out);
-                compress_partial_drain(out->compr);
+                ret = compress_partial_drain(out->compr);
                 ALOGD("copl(%p):out of compress_partial_drain", out);
+                if (ret < 0)
+                    ret = -errno;
             }
-            else if(ret == -ETIMEDOUT)
+            else if (ret == -ETIMEDOUT)
                 compress_drain(out->compr);
             else
                 ALOGE("%s: Next track returned error %d",__func__, ret);
-            send_callback = true;
-            event = STREAM_CBK_EVENT_DRAIN_READY;
-            /* Resend the metadata for next iteration */
-            out->send_new_metadata = 1;
+            if (ret != -ENETRESET) {
+                send_callback = true;
+                event = STREAM_CBK_EVENT_DRAIN_READY;
+                ALOGV("copl(%p):send drain callback, ret %d", out, ret);
+            } else
+                ALOGE("%s: Block drain ready event during SSR", __func__);
             break;
         case OFFLOAD_CMD_DRAIN:
             ALOGD("copl(%p):calling compress_drain", out);
@@ -2164,6 +2168,7 @@
                                    uint32_t *dsp_frames)
 {
     struct stream_out *out = (struct stream_out *)stream;
+    struct audio_device *adev = out->dev;
     if (is_offload_usecase(out->usecase) && (dsp_frames != NULL)) {
         ssize_t ret = 0;
         *dsp_frames = 0;
@@ -2184,6 +2189,13 @@
         } else if(ret < 0) {
             ALOGE(" ERROR: Unable to get time stamp from compress driver");
             return -EINVAL;
+        } else if (get_snd_card_state(adev) == SND_CARD_STATE_OFFLINE){
+            /*
+             * Handle corner case where compress session is closed during SSR
+             * and timestamp is queried
+             */
+            ALOGE(" ERROR: sound card not active, return error");
+            return -EINVAL;
         } else {
             return 0;
         }
@@ -2220,12 +2232,20 @@
 
     if (is_offload_usecase(out->usecase)) {
         if (out->compr != NULL) {
-            compress_get_tstamp(out->compr, &dsp_frames,
+            ret = compress_get_tstamp(out->compr, &dsp_frames,
                     &out->sample_rate);
             ALOGVV("%s rendered frames %ld sample_rate %d",
                    __func__, dsp_frames, out->sample_rate);
             *frames = dsp_frames;
-            ret = 0;
+            if (ret < 0)
+                ret = -errno;
+            if (-ENETRESET == ret) {
+                ALOGE(" ERROR: sound card not active Unable to get time stamp from compress driver");
+                set_snd_card_state(adev,SND_CARD_STATE_OFFLINE);
+                ret = -EINVAL;
+            } else
+                ret = 0;
+
             /* this is the best we can do */
             clock_gettime(CLOCK_MONOTONIC, timestamp);
         }
diff --git a/hal/msm8916/hw_info.c b/hal/msm8916/hw_info.c
index 624850b..a7efe23 100644
--- a/hal/msm8916/hw_info.c
+++ b/hal/msm8916/hw_info.c
@@ -198,6 +198,18 @@
         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, "msm8909-pm8916-snd-card")) {
+        strlcpy(hw_info->type, "", sizeof(hw_info->type));
+        strlcpy(hw_info->name, "msm8909", 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 if (!strcmp(snd_card_name, "msm8909-skue-snd-card")) {
+        strlcpy(hw_info->type, "skue", sizeof(hw_info->type));
+        strlcpy(hw_info->name, "msm8909", 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 device", __func__);
     }
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
old mode 100644
new mode 100755
index 201a170..968ae39
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -38,12 +38,14 @@
 
 #define MIXER_XML_PATH "/system/etc/mixer_paths.xml"
 #define MIXER_XML_PATH_MTP "/system/etc/mixer_paths_mtp.xml"
+#define MIXER_XML_PATH_MSM8909_PM8916 "/system/etc/mixer_paths_msm8909_pm8916.xml"
 #define MIXER_XML_PATH_QRD_SKUH "/system/etc/mixer_paths_qrd_skuh.xml"
 #define MIXER_XML_PATH_QRD_SKUI "/system/etc/mixer_paths_qrd_skui.xml"
 #define MIXER_XML_PATH_QRD_SKUHF "/system/etc/mixer_paths_qrd_skuhf.xml"
 #define MIXER_XML_PATH_SKUK "/system/etc/mixer_paths_skuk.xml"
 #define MIXER_XML_PATH_SKUA "/system/etc/mixer_paths_skua.xml"
 #define MIXER_XML_PATH_SKUC "/system/etc/mixer_paths_skuc.xml"
+#define MIXER_XML_PATH_SKUE "/system/etc/mixer_paths_skue.xml"
 #define MIXER_XML_PATH_AUXPCM "/system/etc/mixer_paths_auxpcm.xml"
 #define MIXER_XML_PATH_AUXPCM "/system/etc/mixer_paths_auxpcm.xml"
 #define MIXER_XML_PATH_WCD9306 "/system/etc/mixer_paths_wcd9306.xml"
@@ -99,6 +101,8 @@
 #define AUDIO_PARAMETER_KEY_HD_VOICE      "hd_voice"
 #define AUDIO_PARAMETER_KEY_VOLUME_BOOST  "volume_boost"
 #define MAX_CAL_NAME 20
+#define APP_TYPE_SYSTEM_SOUNDS 0x00011131
+#define APP_TYPE_GENERAL_RECORDING 0x00011132
 
 char cal_name_info[WCD9XXX_MAX_CAL][MAX_CAL_NAME] = {
         [WCD9XXX_ANC_CAL] = "anc_cal",
@@ -599,7 +603,6 @@
                  sizeof("msm8939-tomtom9330-snd-card"))) {
         strlcpy(mixer_xml_path, MIXER_XML_PATH_WCD9330,
                 sizeof(MIXER_XML_PATH_WCD9330));
-
         msm_device_to_be_id = msm_device_to_be_id_external_codec;
         msm_be_id_array_len  =
             sizeof(msm_device_to_be_id_external_codec) / sizeof(msm_device_to_be_id_external_codec[0]);
@@ -608,18 +611,35 @@
                  sizeof("msm8909-skua-snd-card"))) {
         strlcpy(mixer_xml_path, MIXER_XML_PATH_SKUA,
                 sizeof(MIXER_XML_PATH_SKUA));
-
         msm_device_to_be_id = msm_device_to_be_id_internal_codec;
         msm_be_id_array_len  =
             sizeof(msm_device_to_be_id_internal_codec) / sizeof(msm_device_to_be_id_internal_codec[0]);
+
     } else if (!strncmp(snd_card_name, "msm8909-skuc-snd-card",
                  sizeof("msm8909-skuc-snd-card"))) {
         strlcpy(mixer_xml_path, MIXER_XML_PATH_SKUC,
                 sizeof(MIXER_XML_PATH_SKUC));
+        msm_device_to_be_id = msm_device_to_be_id_internal_codec;
+        msm_be_id_array_len  =
+            sizeof(msm_device_to_be_id_internal_codec) / sizeof(msm_device_to_be_id_internal_codec[0]);
+
+    } else if (!strncmp(snd_card_name, "msm8909-pm8916-snd-card",
+                 sizeof("msm8909-pm8916-snd-card"))) {
+        strlcpy(mixer_xml_path, MIXER_XML_PATH_MSM8909_PM8916,
+                sizeof(MIXER_XML_PATH_MSM8909_PM8916));
 
         msm_device_to_be_id = msm_device_to_be_id_internal_codec;
         msm_be_id_array_len  =
             sizeof(msm_device_to_be_id_internal_codec) / sizeof(msm_device_to_be_id_internal_codec[0]);
+
+    } else if (!strncmp(snd_card_name, "msm8909-skue-snd-card",
+                 sizeof("msm8909-skue-snd-card"))) {
+        strlcpy(mixer_xml_path, MIXER_XML_PATH_SKUE,
+                sizeof(MIXER_XML_PATH_SKUE));
+        msm_device_to_be_id = msm_device_to_be_id_internal_codec;
+        msm_be_id_array_len  =
+            sizeof(msm_device_to_be_id_internal_codec) / sizeof(msm_device_to_be_id_internal_codec[0]);
+
     } else {
         strlcpy(mixer_xml_path, MIXER_XML_PATH,
                 sizeof(MIXER_XML_PATH));
@@ -1078,11 +1098,11 @@
             ALOGE("Failed to allocate cvd version");
         else
             get_cvd_version(cvd_version, adev);
-
-        my_data->acdb_init((char *)snd_card_name, cvd_version);
+        my_data->acdb_init(snd_card_name, cvd_version, key);
         if (cvd_version)
             free(cvd_version);
     }
+    audio_extn_pm_vote();
 
 acdb_init_fail:
     /* Initialize ACDB ID's */
@@ -1299,7 +1319,6 @@
     }
     return acdb_device_table[snd_device];
 }
-
 int platform_set_snd_device_bit_width(snd_device_t snd_device __unused,
                                       unsigned int bit_width __unused)
 {
@@ -1313,11 +1332,24 @@
     return -ENOSYS;
 }
 
-int platform_send_audio_calibration(void *platform, snd_device_t snd_device,
+int platform_send_audio_calibration(void *platform, struct audio_usecase *usecase,
                                     int app_type, int sample_rate)
 {
     struct platform_data *my_data = (struct platform_data *)platform;
     int acdb_dev_id, acdb_dev_type;
+    struct audio_device *adev = my_data->adev;
+    int snd_device = SND_DEVICE_OUT_SPEAKER;
+
+    if (usecase->type == PCM_PLAYBACK) {
+        snd_device = platform_get_output_snd_device(adev->platform,
+                                            usecase->stream.out->devices);
+        if(usecase->id != USECASE_AUDIO_PLAYBACK_OFFLOAD)
+            app_type = APP_TYPE_SYSTEM_SOUNDS;
+    } else if ((usecase->type == PCM_HFP_CALL) || (usecase->type == PCM_CAPTURE)) {
+        snd_device = platform_get_input_snd_device(adev->platform,
+                                            adev->primary_output->devices);
+        app_type = APP_TYPE_GENERAL_RECORDING;
+    }
 
     acdb_dev_id = acdb_device_table[snd_device];
     if (acdb_dev_id < 0) {
@@ -2640,7 +2672,6 @@
 {
     return -ENOSYS;
 }
-
 int platform_get_edid_info(void *platform __unused)
 {
    return -ENOSYS;
@@ -2672,3 +2703,8 @@
 void platform_invalidate_edid(void * platform __unused)
 {
 }
+int platform_get_subsys_image_name(char *buf)
+{
+    strlcpy(buf, PLATFORM_IMAGE_NAME, sizeof(PLATFORM_IMAGE_NAME));
+    return 0;
+}
diff --git a/hal/msm8916/platform.h b/hal/msm8916/platform.h
index a0cf5dc..35b577e 100644
--- a/hal/msm8916/platform.h
+++ b/hal/msm8916/platform.h
@@ -32,6 +32,8 @@
     FLUENCE_BROADSIDE = 0x2,
 };
 
+#define PLATFORM_IMAGE_NAME "modem"
+
 /*
  * Below are the devices for which is back end is same, SLIMBUS_0_RX.
  * All these devices are handled by the internal HW codec. We can
@@ -251,4 +253,6 @@
     stop_record_t stop_record;
 };
 
+int platform_get_subsys_image_name (char *buf);
+
 #endif // QCOM_AUDIO_PLATFORM_H
diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c
index e73fb93..4c798b6 100644
--- a/hal/msm8960/platform.c
+++ b/hal/msm8960/platform.c
@@ -477,12 +477,20 @@
     return -ENOSYS;
 }
 
-int platform_send_audio_calibration(void *platform, snd_device_t snd_device,
+int platform_send_audio_calibration(void *platform, struct audio_usecase *usecase,
                                     int app_type __unused, int sample_rate __unused)
 {
     struct platform_data *my_data = (struct platform_data *)platform;
     int acdb_dev_id, acdb_dev_type;
+    struct audio_device *adev = my_data->adev;
+    int snd_device = SND_DEVICE_OUT_SPEAKER;
 
+    if (usecase->type == PCM_PLAYBACK)
+        snd_device = platform_get_output_snd_device(adev->platform,
+                                            usecase->stream.out->devices);
+    else if ((usecase->type == PCM_HFP_CALL) || (usecase->type == PCM_CAPTURE))
+        snd_device = platform_get_input_snd_device(adev->platform,
+                                            adev->primary_output->devices);
     acdb_dev_id = acdb_device_table[snd_device];
     if (acdb_dev_id < 0) {
         ALOGE("%s: Could not find acdb id for device(%d)",
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
old mode 100644
new mode 100755
index 1c19a61..e178712
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -1461,12 +1461,20 @@
     return backend_bit_width_table[snd_device];
 }
 
-int platform_send_audio_calibration(void *platform, snd_device_t snd_device,
+int platform_send_audio_calibration(void *platform, struct audio_usecase *usecase,
                                     int app_type, int sample_rate)
 {
     struct platform_data *my_data = (struct platform_data *)platform;
     int acdb_dev_id, acdb_dev_type;
+    struct audio_device *adev = my_data->adev;
+    int snd_device = SND_DEVICE_OUT_SPEAKER;
 
+    if (usecase->type == PCM_PLAYBACK)
+        snd_device = platform_get_output_snd_device(adev->platform,
+                                            usecase->stream.out->devices);
+    else if ((usecase->type == PCM_HFP_CALL) || (usecase->type == PCM_CAPTURE))
+        snd_device = platform_get_input_snd_device(adev->platform,
+                                            adev->primary_output->devices);
     acdb_dev_id = acdb_device_table[audio_extn_get_spkr_prot_snd_device(snd_device)];
     if (acdb_dev_id < 0) {
         ALOGE("%s: Could not find acdb id for device(%d)",
@@ -3150,7 +3158,6 @@
      *device_to_be_id = msm_device_to_be_id;
      *length = msm_be_id_array_len;
 }
-
 int platform_set_stream_channel_map(void *platform, audio_channel_mask_t channel_mask, int snd_id)
 {
     int ret = 0;
diff --git a/hal/platform_api.h b/hal/platform_api.h
index ab2cc9d..3e81d68 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -38,7 +38,7 @@
 int platform_get_snd_device_acdb_id(snd_device_t snd_device);
 int platform_set_snd_device_bit_width(snd_device_t snd_device, unsigned int bit_width);
 int platform_get_snd_device_bit_width(snd_device_t snd_device);
-int platform_send_audio_calibration(void *platform, snd_device_t snd_device,
+int platform_send_audio_calibration(void *platform, struct audio_usecase *usecase,
                                     int app_type, int sample_rate);
 int platform_get_default_app_type(void *platform);
 int platform_switch_voice_call_device_pre(void *platform);