audio : refactoring of compress passthrough changes.

Add DTS fomat support for compress passthrough.
Code clean-up and refactoring.
Keep Alive fixes.
Disable Compress Passthrough and DAP by default.

Change-Id: Id0b67630077e06284b8a396be69ebe0c72747c90
diff --git a/configs/msm8996/audio_output_policy.conf b/configs/msm8996/audio_output_policy.conf
index 93cd0c2..0563503 100644
--- a/configs/msm8996/audio_output_policy.conf
+++ b/configs/msm8996/audio_output_policy.conf
@@ -46,11 +46,18 @@
     bit_width 24
     app_type 69940
   }
-  compress_passthrough {
+  compress_passthrough_16 {
     flags AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|AUDIO_OUTPUT_FLAG_NON_BLOCKING|AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH
     formats AUDIO_FORMAT_AC3|AUDIO_FORMAT_E_AC3|AUDIO_FORMAT_E_AC3_JOC|AUDIO_FORMAT_DTS|AUDIO_FORMAT_DTS_HD
     sampling_rates 32000|44100|48000|88200|96000|176400|192000
-    bit_width 16|24
+    bit_width 16
+    app_type 69941
+  }
+  compress_passthrough_24 {
+    flags AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|AUDIO_OUTPUT_FLAG_NON_BLOCKING|AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH
+    formats AUDIO_FORMAT_AC3|AUDIO_FORMAT_E_AC3|AUDIO_FORMAT_E_AC3_JOC|AUDIO_FORMAT_DTS|AUDIO_FORMAT_DTS_HD
+    sampling_rates 32000|44100|48000|88200|96000|176400|192000
+    bit_width 24
     app_type 69941
   }
   compress_offload_16 {
diff --git a/configs/msm8996/mixer_paths_tasha.xml b/configs/msm8996/mixer_paths_tasha.xml
index 360e80b..596b016 100644
--- a/configs/msm8996/mixer_paths_tasha.xml
+++ b/configs/msm8996/mixer_paths_tasha.xml
@@ -120,6 +120,7 @@
     <ctl name="HDMI Mixer MultiMedia4" value="0" />
     <ctl name="HDMI Mixer MultiMedia5" value="0" />
     <ctl name="HDMI Mixer MultiMedia7" value="0" />
+    <ctl name="HDMI Mixer MultiMedia9" value="0" />
     <ctl name="HDMI Mixer MultiMedia10" value="0" />
     <ctl name="HDMI Mixer MultiMedia11" value="0" />
     <ctl name="HDMI Mixer MultiMedia12" value="0" />
@@ -755,6 +756,10 @@
         <ctl name="HDMI Mixer MultiMedia4" value="1" />
     </path>
 
+    <path name="silence-playback hdmi">
+        <ctl name="HDMI Mixer MultiMedia9" value="1" />
+    </path>
+
     <path name="compress-offload-playback bt-sco">
         <ctl name="AUX_PCM_RX Audio Mixer MultiMedia4" value="1" />
     </path>
diff --git a/configs/msm8996/msm8996.mk b/configs/msm8996/msm8996.mk
index 2b70a81..d0ddf24 100644
--- a/configs/msm8996/msm8996.mk
+++ b/configs/msm8996/msm8996.mk
@@ -19,7 +19,8 @@
 AUDIO_FEATURE_ENABLED_FLUENCE := true
 AUDIO_FEATURE_ENABLED_HDMI_SPK := true
 AUDIO_FEATURE_ENABLED_HDMI_EDID := true
-AUDIO_FEATURE_ENABLED_HDMI_PASSTHROUGH := true
+#AUDIO_FEATURE_ENABLED_HDMI_PASSTHROUGH := true
+#AUDIO_FEATURE_ENABLED_KEEP_ALIVE := true
 AUDIO_FEATURE_ENABLED_HFP := true
 AUDIO_FEATURE_ENABLED_INCALL_MUSIC := false
 AUDIO_FEATURE_ENABLED_MULTI_VOICE_SESSIONS := true
@@ -45,8 +46,8 @@
 MM_AUDIO_ENABLED_SAFX := true
 TARGET_USES_QCOM_MM_AUDIO := true
 AUDIO_FEATURE_ENABLED_HW_ACCELERATED_EFFECTS := false
-DOLBY_DDP := true
 #AUDIO_FEATURE_ENABLED_DS2_DOLBY_DAP := true
+#DOLBY_DDP := true
 AUDIO_FEATURE_ENABLED_SOURCE_TRACKING := true
 AUDIO_FEATURE_ENABLED_AUDIOSPHERE := true
 ##AUDIO_FEATURE_FLAGS
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index 0420105..090e6b0 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -354,7 +354,6 @@
                                     AUDIO_CHANNEL_OUT_FRONT_CENTER | AUDIO_CHANNEL_OUT_BACK_CENTER)
 #endif
 
-
 #if defined(DS1_DOLBY_DDP_ENABLED) || defined(DS1_DOLBY_DAP_ENABLED) || defined(DS2_DOLBY_DAP_ENABLED)
 void audio_extn_dolby_set_license(struct audio_device *adev);
 #else
@@ -389,13 +388,13 @@
 #endif
 
 #ifndef HDMI_PASSTHROUGH_ENABLED
-#define audio_extn_dolby_update_passt_stream_configuration(adev, out)      (0)
-#define audio_extn_dolby_is_passt_convert_supported(adev, out)             (0)
-#define audio_extn_dolby_is_passt_supported(adev, out)                     (0)
-#define audio_extn_dolby_is_passthrough_stream(out)                        (0)
-#define audio_extn_dolby_get_passt_buffer_size(info)                       (0)
-#define audio_extn_dolby_set_passt_volume(out, mute)                       (0)
-#define audio_extn_dolby_set_passt_latency(out, latency)                   (0)
+#define audio_extn_passthru_update_stream_configuration(adev, out)            (0)
+#define audio_extn_passthru_is_convert_supported(adev, out)                   (0)
+#define audio_extn_passthru_is_passt_supported(adev, out)                     (0)
+#define audio_extn_passthru_is_passthrough_stream(out)                        (0)
+#define audio_extn_passthru_get_buffer_size(info)                             (0)
+#define audio_extn_passthru_set_volume(out, mute)                             (0)
+#define audio_extn_passthru_set_latency(out, latency)                         (0)
 #define audio_extn_passthru_is_supported_format(f) (0)
 #define audio_extn_passthru_should_drop_data(o) (0)
 #define audio_extn_passthru_on_start(o) do {} while(0)
@@ -409,16 +408,16 @@
 
 #define AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH  0x1000
 #else
-bool audio_extn_dolby_is_passt_convert_supported(struct audio_device *adev,
+bool audio_extn_passthru_is_convert_supported(struct audio_device *adev,
                                                  struct stream_out *out);
-bool audio_extn_dolby_is_passt_supported(struct audio_device *adev,
+bool audio_extn_passthru_is_passt_supported(struct audio_device *adev,
                                          struct stream_out *out);
-void audio_extn_dolby_update_passt_stream_configuration(struct audio_device *adev,
+void audio_extn_passthru_update_stream_configuration(struct audio_device *adev,
                                                  struct stream_out *out);
-bool audio_extn_dolby_is_passthrough_stream(struct stream_out *out);
-int audio_extn_dolby_get_passt_buffer_size(audio_offload_info_t* info);
-int audio_extn_dolby_set_passt_volume(struct stream_out *out, int mute);
-int audio_extn_dolby_set_passt_latency(struct stream_out *out, int latency);
+bool audio_extn_passthru_is_passthrough_stream(struct stream_out *out);
+int audio_extn_passthru_get_buffer_size(audio_offload_info_t* info);
+int audio_extn_passthru_set_volume(struct stream_out *out, int mute);
+int audio_extn_passthru_set_latency(struct stream_out *out, int latency);
 bool audio_extn_passthru_is_supported_format(audio_format_t format);
 bool audio_extn_passthru_should_drop_data(struct stream_out * out);
 void audio_extn_passthru_on_start(struct stream_out *out);
@@ -430,7 +429,6 @@
 bool audio_extn_passthru_is_active();
 void audio_extn_passthru_init(struct audio_device *adev);
 bool audio_extn_passthru_should_standby(struct stream_out *out);
-
 #endif
 
 #ifndef HFP_ENABLED
diff --git a/hal/audio_extn/dolby.c b/hal/audio_extn/dolby.c
index ad8f8a4..f07c66a 100644
--- a/hal/audio_extn/dolby.c
+++ b/hal/audio_extn/dolby.c
@@ -357,45 +357,6 @@
 #endif /* DS1_DOLBY_DDP_ENABLED */
 
 #if defined(DS1_DOLBY_DDP_ENABLED) || defined(DS2_DOLBY_DAP_ENABLED)
-int audio_extn_dolby_get_snd_codec_id(struct audio_device *adev,
-                                      struct stream_out *out,
-                                      audio_format_t format)
-{
-    int id = 0;
-    /*
-     * Use wfd /hdmi sink channel cap for dolby params if device is wfd
-     * or hdmi. Otherwise use stereo configuration
-     */
-    int channel_cap = out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL ?
-                      adev->cur_hdmi_channels :
-                      out->devices & AUDIO_DEVICE_OUT_PROXY ?
-                      adev->cur_wfd_channels : 2;
-
-    switch (format) {
-    case AUDIO_FORMAT_AC3:
-        id = SND_AUDIOCODEC_AC3;
-#ifdef DS1_DOLBY_DDP_ENABLED
-        send_ddp_endp_params_stream(out, out->devices,
-                            channel_cap, true /* set_cache */);
-#endif
-        audio_extn_dolby_set_dmid(adev);
-        break;
-    case AUDIO_FORMAT_E_AC3:
-    case AUDIO_FORMAT_E_AC3_JOC:
-        id = SND_AUDIOCODEC_EAC3;
-#ifdef DS1_DOLBY_DDP_ENABLED
-        send_ddp_endp_params_stream(out, out->devices,
-                            channel_cap, true /* set_cache */);
-#endif
-        audio_extn_dolby_set_dmid(adev);
-        break;
-    default:
-        ALOGE("%s: Unsupported audio format :%x", __func__, format);
-    }
-
-    return id;
-}
-
 bool audio_extn_is_dolby_format(audio_format_t format)
 {
     if (format == AUDIO_FORMAT_AC3 ||
@@ -407,121 +368,6 @@
 }
 #endif /* DS1_DOLBY_DDP_ENABLED || DS2_DOLBY_DAP_ENABLED */
 
-#ifdef HDMI_PASSTHROUGH_ENABLED
-bool audio_extn_dolby_is_passt_convert_supported(struct audio_device *adev,
-                                                 struct stream_out *out) {
-
-    bool convert = false;
-    switch (out->format) {
-    case AUDIO_FORMAT_E_AC3:
-    case AUDIO_FORMAT_E_AC3_JOC:
-        if (!platform_is_edid_supported_format(adev->platform,
-            AUDIO_FORMAT_E_AC3)) {
-            ALOGV("%s:PASSTHROUGH_CONVERT supported", __func__);
-            convert = true;
-        }
-        break;
-    default:
-        ALOGE("%s: PASSTHROUGH_CONVERT not supported for format 0x%x",
-              __func__, out->format);
-        break;
-    }
-    ALOGE("%s: convert %d", __func__, convert);
-    return convert;
-}
-
-bool audio_extn_dolby_is_passt_supported(struct audio_device *adev,
-                                         struct stream_out *out) {
-    bool passt = false;
-    switch (out->format) {
-    case AUDIO_FORMAT_E_AC3:
-        if (platform_is_edid_supported_format(adev->platform, out->format)) {
-            ALOGV("%s:PASSTHROUGH supported for format %x",
-                   __func__, out->format);
-            passt = true;
-        }
-        break;
-    case AUDIO_FORMAT_AC3:
-        if (platform_is_edid_supported_format(adev->platform, AUDIO_FORMAT_AC3)
-            || platform_is_edid_supported_format(adev->platform,
-            AUDIO_FORMAT_E_AC3)) {
-            ALOGV("%s:PASSTHROUGH supported for format %x",
-                   __func__, out->format);
-            passt = true;
-        }
-        break;
-    case AUDIO_FORMAT_E_AC3_JOC:
-         /* Check for DDP capability in edid for JOC contents.*/
-         if (platform_is_edid_supported_format(adev->platform,
-             AUDIO_FORMAT_E_AC3)) {
-             ALOGV("%s:PASSTHROUGH supported for format %x",
-                   __func__, out->format);
-             passt = true;
-         }
-    default:
-        ALOGV("%s:Passthrough not supported", __func__);
-    }
-    return passt;
-}
-
-void audio_extn_dolby_update_passt_stream_configuration(
-        struct audio_device *adev, struct stream_out *out) {
-    if (audio_extn_dolby_is_passt_supported(adev, out)) {
-        ALOGV("%s:PASSTHROUGH", __func__);
-        out->compr_config.codec->compr_passthr = PASSTHROUGH;
-    } else if (audio_extn_dolby_is_passt_convert_supported(adev, out)){
-        ALOGV("%s:PASSTHROUGH CONVERT", __func__);
-        out->compr_config.codec->compr_passthr = PASSTHROUGH_CONVERT;
-    } else {
-        ALOGV("%s:NO PASSTHROUGH", __func__);
-        out->compr_config.codec->compr_passthr = LEGACY_PCM;
-    }
-}
-
-bool audio_extn_dolby_is_passthrough_stream(struct stream_out *out) {
-
-    //check passthrough system property
-    if (!property_get_bool("audio.offload.passthrough", false)) {
-        return false;
-    }
-
-    //check supported device, currently only on HDMI.
-    if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
-        //passthrough flag
-        if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH)
-            return true;
-        //direct flag, check supported formats.
-        if (out->flags & AUDIO_OUTPUT_FLAG_DIRECT) {
-            if (audio_extn_passthru_is_supported_format(out->format)) {
-                if (platform_is_edid_supported_format(out->dev->platform,
-                        out->format)) {
-                    return true;
-                } else if (audio_extn_is_dolby_format(out->format) &&
-                            platform_is_edid_supported_format(out->dev->platform,
-                                AUDIO_FORMAT_AC3)){
-                    //return true for EAC3/EAC3_JOC formats
-                    //if sink supports only AC3
-                    return true;
-                }
-            }
-        }
-    }
-
-    return false;
-}
-
-int audio_extn_dolby_get_passt_buffer_size(audio_offload_info_t* info) {
-    return platform_get_compress_passthrough_buffer_size(info);
-}
-
-int audio_extn_dolby_set_passt_volume(struct stream_out *out,  int mute) {
-    return platform_set_device_params(out, DEVICE_PARAM_MUTE_ID, mute);
-}
-
-int audio_extn_dolby_set_passt_latency(struct stream_out *out, int latency) {
-    return platform_set_device_params(out, DEVICE_PARAM_LATENCY_ID, latency);
-}
-#endif /* HDMI_PASSTHROUGH_ENABLED */
 
 #ifdef DS1_DOLBY_DAP_ENABLED
 void audio_extn_dolby_set_endpoint(struct audio_device *adev)
diff --git a/hal/audio_extn/keep_alive.c b/hal/audio_extn/keep_alive.c
index ab663ef..1a4f135 100644
--- a/hal/audio_extn/keep_alive.c
+++ b/hal/audio_extn/keep_alive.c
@@ -37,7 +37,7 @@
 #include <platform.h>
 
 #define SILENCE_MIXER_PATH "silence-playback hdmi"
-#define SILENCE_DEV_ID 5            /* index into machine driver */
+#define SILENCE_DEV_ID 32           /* index into machine driver */
 #define SILENCE_INTERVAL_US 2000000
 
 typedef enum {
@@ -147,22 +147,71 @@
 void audio_extn_keep_alive_start()
 {
     struct audio_device * adev = (struct audio_device *)ka.userdata;
-
-    if (ka.state == STATE_DEINIT)
-        return;
-
-    if (audio_extn_passthru_is_active())
-        return;
+    char mixer_ctl_name[MAX_LENGTH_MIXER_CONTROL_IN_INT];
+    int app_type_cfg[MAX_LENGTH_MIXER_CONTROL_IN_INT], len = 0, rc;
+    struct mixer_ctl *ctl;
+    int acdb_dev_id, snd_device;
+    int32_t sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
 
     pthread_mutex_lock(&ka.lock);
 
-    if (ka.state == STATE_ACTIVE)
+    if (ka.state == STATE_DEINIT) {
+        ALOGE(" %s : Invalid state ",__func__);
+        return;
+    }
+
+    if (audio_extn_passthru_is_active()) {
+        ALOGE(" %s : Pass through is already active", __func__);
+        return;
+    }
+
+    if (ka.state == STATE_ACTIVE) {
+        ALOGV(" %s : Keep alive state is already Active",__func__ );
         goto exit;
+    }
 
     ka.done = false;
-    //todo: platform_send_audio_calibration is replaced by audio_extn_utils_send_audio_calibration
-    //check why audio cal needs to be set
-    //platform_send_audio_calibration(adev->platform, SND_DEVICE_OUT_HDMI);
+
+    /*configure app type */
+    snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
+             "Audio Stream %d App Type Cfg",SILENCE_DEV_ID);
+
+    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);
+        rc = -EINVAL;
+        goto exit;
+    }
+
+    snd_device = SND_DEVICE_OUT_HDMI;
+    acdb_dev_id = platform_get_snd_device_acdb_id(snd_device);
+    if (acdb_dev_id < 0) {
+        ALOGE("%s: Couldn't get the acdb dev id", __func__);
+        rc = -EINVAL;
+        goto exit;
+    }
+
+    sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
+    app_type_cfg[len++] = platform_get_default_app_type(adev->platform);
+    app_type_cfg[len++] = acdb_dev_id;
+    app_type_cfg[len++] = sample_rate;
+
+    ALOGI("%s:%d PLAYBACK app_type %d, acdb_dev_id %d, sample_rate %d",
+          __func__, __LINE__,
+          platform_get_default_app_type(adev->platform),
+          acdb_dev_id, sample_rate);
+    mixer_ctl_set_array(ctl, app_type_cfg, len);
+
+    /*send calibration*/
+    struct audio_usecase *usecase = calloc(1, sizeof(struct audio_usecase));
+    usecase->type = PCM_PLAYBACK;
+    usecase->out_snd_device = SND_DEVICE_OUT_HDMI;
+
+    platform_send_audio_calibration(adev->platform, usecase,
+                platform_get_default_app_type(adev->platform), sample_rate);
+
+    /*apply audio route */
     audio_route_apply_and_update_path(adev->audio_route, SILENCE_MIXER_PATH);
 
     if (open_silence_stream() == 0) {
@@ -181,11 +230,11 @@
 {
     struct audio_device * adev = (struct audio_device *)ka.userdata;
 
+    pthread_mutex_lock(&ka.lock);
+
     if (ka.state == STATE_DEINIT)
         return;
 
-    pthread_mutex_lock(&ka.lock);
-
     if (ka.state == STATE_IDLE)
         goto exit;
 
@@ -211,7 +260,7 @@
     char value[32];
     int ret;
 
-    ret = str_parms_get_str(parms, "connect", value, sizeof(value));
+    ret = str_parms_get_str(parms, AUDIO_PARAMETER_DEVICE_CONNECT, value, sizeof(value));
     if (ret >= 0) {
         int val = atoi(value);
         if (val & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
@@ -237,12 +286,10 @@
 
 static void * keep_alive_loop(void * context __unused)
 {
-    struct audio_device *adev = (struct audio_device *)ka.userdata;
     struct keep_alive_cmd *cmd = NULL;
     struct listnode *item;
     uint8_t * silence = NULL;
-    int32_t bytes = 0, count = 0, i;
-    struct stream_out * p_out = NULL;
+    int32_t bytes = 0;
 
     while (true) {
         pthread_mutex_lock(&ka.lock);
diff --git a/hal/audio_extn/passthru.c b/hal/audio_extn/passthru.c
index d87303b..e6ac4dd 100644
--- a/hal/audio_extn/passthru.c
+++ b/hal/audio_extn/passthru.c
@@ -37,10 +37,14 @@
 #include "audio_extn.h"
 #include "platform_api.h"
 #include <platform.h>
+#include <cutils/properties.h>
+
+#include "sound/compress_params.h"
 
 static const audio_format_t audio_passthru_formats[] = {
     AUDIO_FORMAT_AC3,
     AUDIO_FORMAT_E_AC3,
+    AUDIO_FORMAT_E_AC3_JOC,
     AUDIO_FORMAT_DTS,
     AUDIO_FORMAT_DTS_HD
 };
@@ -63,9 +67,11 @@
 
     for (i = 0; i < num_passthru_formats; i++) {
         if (format == audio_passthru_formats[i]) {
+            ALOGD("%s : pass through format is true", __func__);
             return true;
         }
     }
+    ALOGD("%s : pass through format is false", __func__);
     return false;
 }
 
@@ -76,11 +82,6 @@
  */
 bool audio_extn_passthru_should_drop_data(struct stream_out * out)
 {
-    /* Make this product specific */
-    if (!(out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
-        ALOGI("drop data as end device 0x%x is unsupported", out->devices);
-        return true;
-    }
 
     if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
         if (android_atomic_acquire_load(&compress_passthru_active) > 0) {
@@ -158,8 +159,6 @@
 {
     if (android_atomic_acquire_load(&compress_passthru_active) == 0)
         return;
-
-    android_atomic_dec(&compress_passthru_active);
 }
 
 int audio_extn_passthru_set_parameters(struct audio_device *adev __unused,
@@ -183,3 +182,143 @@
 {
     return true;
 }
+
+bool audio_extn_passthru_is_convert_supported(struct audio_device *adev,
+                                                 struct stream_out *out)
+{
+
+    bool convert = false;
+    switch (out->format) {
+    case AUDIO_FORMAT_E_AC3:
+    case AUDIO_FORMAT_E_AC3_JOC:
+    case AUDIO_FORMAT_DTS_HD:
+        if (!platform_is_edid_supported_format(adev->platform,
+            out->format)) {
+            ALOGD("%s:PASSTHROUGH_CONVERT supported", __func__);
+            convert = true;
+        }
+        break;
+    default:
+        ALOGD("%s: PASSTHROUGH_CONVERT not supported for format 0x%x",
+              __func__, out->format);
+        break;
+    }
+    ALOGD("%s: convert %d", __func__, convert);
+    return convert;
+}
+
+bool audio_extn_passthru_is_passt_supported(struct audio_device *adev,
+                                         struct stream_out *out)
+{
+    bool passt = false;
+    switch (out->format) {
+    case AUDIO_FORMAT_E_AC3:
+        if (platform_is_edid_supported_format(adev->platform, out->format)) {
+            ALOGV("%s:PASSTHROUGH supported for format %x",
+                   __func__, out->format);
+            passt = true;
+        }
+        break;
+    case AUDIO_FORMAT_AC3:
+        if (platform_is_edid_supported_format(adev->platform, AUDIO_FORMAT_AC3)
+            || platform_is_edid_supported_format(adev->platform,
+            AUDIO_FORMAT_E_AC3)) {
+            ALOGV("%s:PASSTHROUGH supported for format %x",
+                   __func__, out->format);
+            passt = true;
+        }
+        break;
+    case AUDIO_FORMAT_E_AC3_JOC:
+         /* Check for DDP capability in edid for JOC contents.*/
+         if (platform_is_edid_supported_format(adev->platform,
+             AUDIO_FORMAT_E_AC3)) {
+             ALOGV("%s:PASSTHROUGH supported for format %x",
+                   __func__, out->format);
+             passt = true;
+         }
+         break;
+    case AUDIO_FORMAT_DTS:
+        if (platform_is_edid_supported_format(adev->platform, AUDIO_FORMAT_DTS)
+            || platform_is_edid_supported_format(adev->platform,
+            AUDIO_FORMAT_DTS_HD)) {
+            ALOGV("%s:PASSTHROUGH supported for format %x",
+                   __func__, out->format);
+            passt = true;
+        }
+        break;
+    case AUDIO_FORMAT_DTS_HD:
+        if (platform_is_edid_supported_format(adev->platform, out->format)) {
+            ALOGV("%s:PASSTHROUGH supported for format %x",
+                   __func__, out->format);
+            passt = true;
+        }
+        break;
+    default:
+        ALOGV("%s:Passthrough not supported", __func__);
+    }
+    return passt;
+}
+
+void audio_extn_passthru_update_stream_configuration(
+        struct audio_device *adev, struct stream_out *out)
+{
+    if (audio_extn_passthru_is_passt_supported(adev, out)) {
+        ALOGV("%s:PASSTHROUGH", __func__);
+        out->compr_config.codec->compr_passthr = PASSTHROUGH;
+    } else if (audio_extn_passthru_is_convert_supported(adev, out)){
+        ALOGV("%s:PASSTHROUGH CONVERT", __func__);
+        out->compr_config.codec->compr_passthr = PASSTHROUGH_CONVERT;
+    } else {
+        ALOGV("%s:NO PASSTHROUGH", __func__);
+        out->compr_config.codec->compr_passthr = LEGACY_PCM;
+    }
+}
+
+bool audio_extn_passthru_is_passthrough_stream(struct stream_out *out)
+{
+    //check passthrough system property
+    if (!property_get_bool("audio.offload.passthrough", false)) {
+        return false;
+    }
+
+    //check supported device, currently only on HDMI.
+    if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
+        //passthrough flag
+        if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH)
+            return true;
+        //direct flag, check supported formats.
+        if (out->flags & AUDIO_OUTPUT_FLAG_DIRECT) {
+            if (audio_extn_passthru_is_supported_format(out->format)) {
+                if (platform_is_edid_supported_format(out->dev->platform,
+                        out->format)) {
+                    ALOGV("%s : return true",__func__);
+                    return true;
+                } else if (audio_extn_is_dolby_format(out->format) &&
+                            platform_is_edid_supported_format(out->dev->platform,
+                                AUDIO_FORMAT_AC3)){
+                    //return true for EAC3/EAC3_JOC formats
+                    //if sink supports only AC3
+                    ALOGV("%s : return true",__func__);
+                    return true;
+                }
+            }
+        }
+    }
+    ALOGV("%s : return false",__func__);
+    return false;
+}
+
+int audio_extn_passthru_get_buffer_size(audio_offload_info_t* info)
+{
+    return platform_get_compress_passthrough_buffer_size(info);
+}
+
+int audio_extn_passthru_set_volume(struct stream_out *out,  int mute)
+{
+    return platform_set_device_params(out, DEVICE_PARAM_MUTE_ID, mute);
+}
+
+int audio_extn_passthru_set_latency(struct stream_out *out, int latency)
+{
+    return platform_set_device_params(out, DEVICE_PARAM_LATENCY_ID, latency);
+}
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index cd9ead7..cb646cf 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -107,8 +107,10 @@
     STRING_TO_ENUM(AUDIO_FORMAT_AMR_WB),
     STRING_TO_ENUM(AUDIO_FORMAT_AC3),
     STRING_TO_ENUM(AUDIO_FORMAT_E_AC3),
-#ifdef AUDIO_EXTN_FORMATS_ENABLED
     STRING_TO_ENUM(AUDIO_FORMAT_DTS),
+    STRING_TO_ENUM(AUDIO_FORMAT_DTS_HD),
+#ifdef AUDIO_EXTN_FORMATS_ENABLED
+    STRING_TO_ENUM(AUDIO_FORMAT_E_AC3_JOC),
     STRING_TO_ENUM(AUDIO_FORMAT_WMA),
     STRING_TO_ENUM(AUDIO_FORMAT_WMA_PRO),
     STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADIF),
@@ -639,20 +641,6 @@
                 sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
          }
 
-         app_type_cfg[len++] = usecase->stream.out->app_type_cfg.app_type;
-         app_type_cfg[len++] = acdb_dev_id;
-         if (((usecase->stream.out->format == AUDIO_FORMAT_E_AC3) ||
-             (usecase->stream.out->format == AUDIO_FORMAT_E_AC3_JOC)) &&
-             (usecase->stream.out->flags  & AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH))
-             app_type_cfg[len++] = sample_rate * 4;
-         else
-             app_type_cfg[len++] = sample_rate;
-
-         ALOGI("%s:%d PLAYBACK app_type %d, acdb_dev_id %d, sample_rate %d",
-               __func__, __LINE__,
-               platform_get_default_app_type(adev->platform),
-               acdb_dev_id, sample_rate);
-
         if ((24 == usecase->stream.out->bit_width) &&
             (usecase->stream.out->devices & AUDIO_DEVICE_OUT_SPEAKER)) {
             usecase->stream.out->app_type_cfg.sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
@@ -667,7 +655,7 @@
         app_type_cfg[len++] = acdb_dev_id;
         if (((usecase->stream.out->format == AUDIO_FORMAT_E_AC3) ||
             (usecase->stream.out->format == AUDIO_FORMAT_E_AC3_JOC))
-            && audio_extn_dolby_is_passthrough_stream(usecase->stream.out)) {
+            && audio_extn_passthru_is_passthrough_stream(usecase->stream.out)) {
             app_type_cfg[len++] = sample_rate * 4;
         } else {
             app_type_cfg[len++] = sample_rate;
@@ -1009,7 +997,7 @@
     if (audio_extn_is_dolby_format(out->format) &&
         /*TODO:Extend code to support DTS passthrough*/
         /*set compressed channel status bits*/
-        audio_extn_dolby_is_passthrough_stream(out)){
+        audio_extn_passthru_is_passthrough_stream(out)){
         get_compressed_channel_status(buffer, bytes, channel_status, AUDIO_PARSER_CODEC_AC3);
     } else
 #endif
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 17f71cc..e679c64 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -338,6 +338,10 @@
         format == AUDIO_FORMAT_PCM_24_BIT_PACKED ||
         format == AUDIO_FORMAT_PCM_8_24_BIT ||
         format == AUDIO_FORMAT_PCM_16_BIT ||
+        format == AUDIO_FORMAT_AC3 ||
+        format == AUDIO_FORMAT_E_AC3 ||
+        format == AUDIO_FORMAT_DTS ||
+        format == AUDIO_FORMAT_DTS_HD ||
         format == AUDIO_FORMAT_FLAC ||
         format == AUDIO_FORMAT_ALAC ||
         format == AUDIO_FORMAT_APE ||
@@ -384,6 +388,17 @@
     case AUDIO_FORMAT_WMA_PRO:
         id = SND_AUDIOCODEC_WMA_PRO;
         break;
+    case AUDIO_FORMAT_AC3:
+        id = SND_AUDIOCODEC_AC3;
+        break;
+    case AUDIO_FORMAT_E_AC3:
+    case AUDIO_FORMAT_E_AC3_JOC:
+        id = SND_AUDIOCODEC_EAC3;
+        break;
+    case AUDIO_FORMAT_DTS:
+    case AUDIO_FORMAT_DTS_HD:
+        id = SND_AUDIOCODEC_DTS;
+        break;
     default:
         ALOGE("%s: Unsupported audio format :%x", __func__, format);
     }
@@ -856,9 +871,6 @@
         out->supported_channel_masks[i++] = AUDIO_CHANNEL_OUT_QUAD;
         out->supported_channel_masks[i++] = AUDIO_CHANNEL_OUT_SURROUND;
         out->supported_channel_masks[i++] = AUDIO_CHANNEL_OUT_2POINT1;
-    case 2:
-        ALOGV("%s: HDMI supports 2 channels", __func__);
-        out->supported_channel_masks[i++] = AUDIO_CHANNEL_OUT_STEREO;
         break;
     default:
         ALOGE("invalid/nonstandard channal count[%d]",channels);
@@ -1739,8 +1751,9 @@
     ALOGV("%s usecase %s out->format:%x out->bit_width:%d", __func__, use_case_table[out->usecase],out->format,out->bit_width);
 
     if (is_offload_usecase(out->usecase) &&
-        audio_extn_dolby_is_passthrough_stream(out)) {
+        audio_extn_passthru_is_passthrough_stream(out)) {
         enable_passthru = true;
+        ALOGV("%s : enable_passthru is set to true", __func__);
     }
 
     /* Check if change in HDMI channel config is allowed */
@@ -1754,7 +1767,7 @@
 
         if (enable_passthru) {
             audio_extn_passthru_on_start(out);
-            audio_extn_dolby_update_passt_stream_configuration(adev, out);
+            audio_extn_passthru_update_stream_configuration(adev, out);
         }
 
         /* For pass through case, the backend should be configured as stereo */
@@ -1789,7 +1802,7 @@
     }
 
     if (is_offload_usecase(out->usecase) &&
-        !(audio_extn_dolby_is_passthrough_stream(out))) {
+        !(audio_extn_passthru_is_passthrough_stream(out))) {
         if (adev->visualizer_stop_output != NULL)
             adev->visualizer_stop_output(out->handle, out->pcm_device_id);
 
@@ -1809,21 +1822,21 @@
     free(uc_info);
 
     if (is_offload_usecase(out->usecase) &&
-        (audio_extn_dolby_is_passthrough_stream(out))) {
+        (audio_extn_passthru_is_passthrough_stream(out))) {
         ALOGV("Disable passthrough , reset mixer to pcm");
         /* NO_PASSTHROUGH */
         out->compr_config.codec->compr_passthr = 0;
 
-        /* Must be called after removing the usecase from list */
-        if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)
-                check_and_set_hdmi_config(adev, DEFAULT_HDMI_OUT_CHANNELS,
-                                          DEFAULT_HDMI_OUT_SAMPLE_RATE,
-                                          DEFAULT_HDMI_OUT_FORMAT,
-                                          false);
         audio_extn_passthru_on_stop(out);
         audio_extn_dolby_set_dap_bypass(adev, DAP_STATE_ON);
     }
 
+    /* Must be called after removing the usecase from list */
+    if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)
+        check_and_set_hdmi_config(adev, DEFAULT_HDMI_OUT_CHANNELS,
+                                  DEFAULT_HDMI_OUT_SAMPLE_RATE,
+                                  DEFAULT_HDMI_OUT_FORMAT,
+                                  false);
     ALOGV("%s: exit: status(%d)", __func__, ret);
     return ret;
 }
@@ -1964,7 +1977,7 @@
         if (audio_extn_is_dolby_format(out->format))
             audio_extn_dolby_send_ddp_endp_params(adev);
 #endif
-        if (!(audio_extn_dolby_is_passthrough_stream(out))) {
+        if (!(audio_extn_passthru_is_passthrough_stream(out))) {
             if (adev->visualizer_start_output != NULL)
                 adev->visualizer_start_output(out->handle, out->pcm_device_id);
             if (adev->offload_effects_start_output != NULL)
@@ -2248,7 +2261,7 @@
          */
         if ((out->devices == AUDIO_DEVICE_OUT_AUX_DIGITAL) &&
                 (val == AUDIO_DEVICE_NONE) &&
-                !audio_extn_dolby_is_passthrough_stream(out) &&
+                !audio_extn_passthru_is_passthrough_stream(out) &&
                 (platform_get_edid_info(adev->platform) != 0) /* HDMI disconnected */) {
             val = AUDIO_DEVICE_OUT_SPEAKER;
         }
@@ -2471,13 +2484,13 @@
         out->muted = (left == 0.0f);
         return 0;
     } else if (is_offload_usecase(out->usecase)) {
-        if (audio_extn_dolby_is_passthrough_stream(out)) {
+        if (audio_extn_passthru_is_passthrough_stream(out)) {
             /*
              * Set mute or umute on HDMI passthrough stream.
              * Only take left channel into account.
              * Mute is 0 and unmute 1
              */
-            audio_extn_dolby_set_passt_volume(out, (left == 0.0f));
+            audio_extn_passthru_set_volume(out, (left == 0.0f));
         } else {
             char mixer_ctl_name[128];
             struct audio_device *adev = out->dev;
@@ -2531,6 +2544,13 @@
         }
     }
 
+    if (audio_extn_passthru_should_drop_data(out)) {
+        ALOGD(" %s : Drop data as compress passthrough session is going on", __func__);
+        usleep((uint64_t)bytes * 1000000 / audio_stream_out_frame_size(stream) /
+                        out_get_sample_rate(&out->stream.common));
+        goto exit;
+    }
+
     if (out->standby) {
         out->standby = false;
         pthread_mutex_lock(&adev->lock);
@@ -3379,7 +3399,7 @@
         }
 
         if (!is_supported_format(config->offload_info.format) &&
-                !audio_extn_is_dolby_format(config->offload_info.format)) {
+                !audio_extn_passthru_is_supported_format(config->offload_info.format)) {
             ALOGE("%s: Unsupported audio format %x " , __func__, config->offload_info.format);
             ret = -EINVAL;
             goto error_open;
@@ -3433,21 +3453,19 @@
 
         out->bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
 
-        if (audio_extn_is_dolby_format(config->offload_info.format))
-            out->compr_config.codec->id =
-                audio_extn_dolby_get_snd_codec_id(adev, out,
-                                                  config->offload_info.format);
-        else
-            out->compr_config.codec->id =
-                get_snd_codec_id(config->offload_info.format);
+        out->compr_config.codec->id = get_snd_codec_id(config->offload_info.format);
+        if (audio_extn_is_dolby_format(config->offload_info.format)) {
+            audio_extn_dolby_send_ddp_endp_params(adev);
+            audio_extn_dolby_set_dmid(adev);
+        }
 
         if ((config->offload_info.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_PCM) {
             out->compr_config.fragment_size =
                platform_get_pcm_offload_buffer_size(&config->offload_info);
             out->compr_config.fragments = DIRECT_PCM_NUM_FRAGMENTS;
-        } else if (audio_extn_dolby_is_passthrough_stream(out)) {
+        } else if (audio_extn_passthru_is_passthrough_stream(out)) {
             out->compr_config.fragment_size =
-               audio_extn_dolby_get_passt_buffer_size(&config->offload_info);
+               audio_extn_passthru_get_buffer_size(&config->offload_info);
             out->compr_config.fragments = COMPRESS_OFFLOAD_NUM_FRAGMENTS;
         } else {
             out->compr_config.fragment_size =
@@ -3501,14 +3519,14 @@
          * AV playback
          * Direct PCM playback
          */
-        if (audio_extn_dolby_is_passthrough_stream(out) ||
+        if (audio_extn_passthru_is_passthrough_stream(out) ||
             config->offload_info.has_video ||
             out->flags & AUDIO_OUTPUT_FLAG_DIRECT_PCM) {
             check_and_set_gapless_mode(adev, false);
         } else
             check_and_set_gapless_mode(adev, true);
 
-        if (audio_extn_dolby_is_passthrough_stream(out)) {
+        if (audio_extn_passthru_is_passthrough_stream(out)) {
             out->flags |= AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH;
         }
     } else if (out->flags & AUDIO_OUTPUT_FLAG_INCALL_MUSIC) {
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index d60d67c..8922a4e 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -1642,6 +1642,9 @@
         platform_acdb_init(my_data);
     }
 
+    /* init keep-alive for compress passthru */
+    audio_extn_keep_alive_init(adev);
+
 acdb_init_fail:
 
     set_platform_defaults(my_data);