Merge 9c4ba54b3ecb1ee854763970b3057220994dad8a on remote branch

Change-Id: I5a80c57243eda5a4fdd98a233766cd622b4ef9a3
diff --git a/audiod/AudioDaemon.cpp b/audiod/AudioDaemon.cpp
index 6f38218..2c9b5d0 100644
--- a/audiod/AudioDaemon.cpp
+++ b/audiod/AudioDaemon.cpp
@@ -1,5 +1,5 @@
 /* AudioDaemon.cpp
-Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
+Copyright (c) 2012-2015, 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
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index d8e5263..5231e93 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -384,6 +384,7 @@
 #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_OUTPUT_FLAG_COMPRESS_PASSTHROUGH  0x4000
 #else
 int audio_extn_dolby_update_passt_formats(struct audio_device *adev,
                                           struct stream_out *out);
@@ -445,6 +446,7 @@
                                   audio_format_t format,
                                   uint32_t sample_rate,
                                   uint32_t bit_width,
+                                  audio_channel_mask_t channel_mask,
                                   struct stream_app_type_cfg *app_type_cfg);
 int audio_extn_utils_send_app_type_cfg(struct audio_device *adev,
                                        struct audio_usecase *usecase);
diff --git a/hal/audio_extn/dolby.c b/hal/audio_extn/dolby.c
old mode 100755
new mode 100644
index a26063a..92ef4ac
--- a/hal/audio_extn/dolby.c
+++ b/hal/audio_extn/dolby.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
  * Not a Contribution.
  *
  * Copyright (C) 2010 The Android Open Source Project
@@ -609,6 +609,8 @@
     property_get("audio.ds1.metainfo.key",value,"0");
 #ifdef DOLBY_ACDB_LICENSE
     key = atoi(value);
+#else
+    key = 0;
 #endif
     ALOGV("%s Setting DS1 License, key:0x%x",__func__, key);
     ret = mixer_ctl_set_value(ctl, 0, key);
diff --git a/hal/audio_extn/spkr_protection.c b/hal/audio_extn/spkr_protection.c
index 1f9681d..efa885e 100644
--- a/hal/audio_extn/spkr_protection.c
+++ b/hal/audio_extn/spkr_protection.c
@@ -197,8 +197,6 @@
         ALOGE("Unable to open %s\n", THERMAL_SYSFS);
         return found;
     }
-    if (!sensor_name)
-        return found;
 
     while ((tdirent = readdir(tdir))) {
         char buf[50];
@@ -212,12 +210,11 @@
             if (strcmp(tzdirent->d_name, "type"))
                 continue;
             snprintf(name, MAX_PATH, TZ_TYPE, tzn);
-            ALOGV("Opening %s\n", name);
+            ALOGD("Opening %s\n", name);
             read_line_from_file(name, buf, sizeof(buf));
             if (strlen(buf) > 0)
                 buf[strlen(buf) - 1] = '\0';
             if (!strcmp(buf, sensor_name)) {
-                ALOGD(" spkr tz name found, %s\n", name);
                 found = 1;
                 break;
             }
@@ -1070,17 +1067,21 @@
 
     switch(snd_device) {
     case SND_DEVICE_OUT_SPEAKER:
+    case SND_DEVICE_OUT_SPEAKER_WSA:
         acdb_id = platform_get_snd_device_acdb_id(SND_DEVICE_OUT_SPEAKER_PROTECTED);
         break;
-    case SND_DEVICE_OUT_VOICE_SPEAKER:
-        acdb_id = platform_get_snd_device_acdb_id(SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED);
-        break;
     case SND_DEVICE_OUT_SPEAKER_VBAT:
         acdb_id = platform_get_snd_device_acdb_id(SND_DEVICE_OUT_SPEAKER_PROTECTED_VBAT);
         break;
     case SND_DEVICE_OUT_VOICE_SPEAKER_VBAT:
         acdb_id = platform_get_snd_device_acdb_id(SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED_VBAT);
         break;
+    case SND_DEVICE_OUT_VOICE_SPEAKER:
+
+    case SND_DEVICE_OUT_VOICE_SPEAKER_WSA:
+
+        acdb_id = platform_get_snd_device_acdb_id(SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED);
+        break;
     default:
         acdb_id = -EINVAL;
         break;
@@ -1095,13 +1096,15 @@
 
     switch(snd_device) {
     case SND_DEVICE_OUT_SPEAKER:
+    case SND_DEVICE_OUT_SPEAKER_WSA:
         return SND_DEVICE_OUT_SPEAKER_PROTECTED;
-    case SND_DEVICE_OUT_VOICE_SPEAKER:
-        return SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED;
     case SND_DEVICE_OUT_SPEAKER_VBAT:
         return SND_DEVICE_OUT_SPEAKER_PROTECTED_VBAT;
     case SND_DEVICE_OUT_VOICE_SPEAKER_VBAT:
         return SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED_VBAT;
+    case SND_DEVICE_OUT_VOICE_SPEAKER:
+    case SND_DEVICE_OUT_VOICE_SPEAKER_WSA:
+        return SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED;
     default:
         return snd_device;
     }
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index 1f2100b..9ec4243 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -158,14 +158,15 @@
 static audio_output_flags_t parse_flag_names(char *name)
 {
     uint32_t flag = 0;
-    char *flag_name = strtok(name, "|");
+    char *last_r;
+    char *flag_name = strtok_r(name, "|", &last_r);
     while (flag_name != NULL) {
         if (strlen(flag_name) != 0) {
             flag |= string_to_enum(s_flag_name_to_enum_table,
                                ARRAY_SIZE(s_flag_name_to_enum_table),
                                flag_name);
         }
-        flag_name = strtok(NULL, "|");
+        flag_name = strtok_r(NULL, "|", &last_r);
     }
 
     ALOGV("parse_flag_names: flag - %d", flag);
@@ -175,7 +176,8 @@
 static void parse_format_names(char *name, struct streams_output_cfg *so_info)
 {
     struct stream_format *sf_info = NULL;
-    char *str = strtok(name, "|");
+    char *last_r;
+    char *str = strtok_r(name, "|", &last_r);
 
     if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0)
         return;
@@ -193,7 +195,7 @@
             sf_info->format = format;
             list_add_tail(&so_info->format_list, &sf_info->list);
         }
-        str = strtok(NULL, "|");
+        str = strtok_r(NULL, "|", &last_r);
     }
 }
 
@@ -201,7 +203,8 @@
 {
     struct stream_sample_rate *ss_info = NULL;
     uint32_t sample_rate = 48000;
-    char *str = strtok(name, "|");
+    char *last_r;
+    char *str = strtok_r(name, "|", &last_r);
 
     if (str != NULL && 0 == strcmp(str, DYNAMIC_VALUE_TAG))
         return;
@@ -212,20 +215,22 @@
         ALOGV("%s: sample_rate - %d", __func__, sample_rate);
         if (0 != sample_rate) {
             ss_info = (struct stream_sample_rate *)calloc(1, sizeof(struct stream_sample_rate));
-            if (ss_info == NULL)
-                break; /* return whatever was parsed */
-
+            if (!ss_info) {
+                ALOGE("%s: memory allocation failure", __func__);
+                return;
+            }
             ss_info->sample_rate = sample_rate;
             list_add_tail(&so_info->sample_rate_list, &ss_info->list);
         }
-        str = strtok(NULL, "|");
+        str = strtok_r(NULL, "|", &last_r);
     }
 }
 
 static int parse_bit_width_names(char *name)
 {
     int bit_width = 16;
-    char *str = strtok(name, "|");
+    char *last_r;
+    char *str = strtok_r(name, "|", &last_r);
 
     if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG))
         bit_width = (int)strtol(str, (char **)NULL, 10);
@@ -237,7 +242,8 @@
 static int parse_app_type_names(void *platform, char *name)
 {
     int app_type = platform_get_default_app_type(platform);
-    char *str = strtok(name, "|");
+    char *last_r;
+    char *str = strtok_r(name, "|", &last_r);
 
     if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG))
         app_type = (int)strtol(str, (char **)NULL, 10);
@@ -477,12 +483,14 @@
                                   audio_format_t format,
                                   uint32_t sample_rate,
                                   uint32_t bit_width,
+                                  audio_channel_mask_t channel_mask,
                                   struct stream_app_type_cfg *app_type_cfg)
 {
     struct listnode *node_i, *node_j, *node_k;
     struct streams_output_cfg *so_info;
     struct stream_format *sf_info;
     struct stream_sample_rate *ss_info;
+    char value[PROPERTY_VALUE_MAX] = {0};
 
     if ((24 == bit_width) &&
         (devices & AUDIO_DEVICE_OUT_SPEAKER)) {
@@ -493,6 +501,16 @@
         ALOGI("%s Allowing 24-bit playback on speaker ONLY at default sampling rate", __func__);
     }
 
+    property_get("audio.playback.mch.downsample",value,"");
+    if (!strncmp("true", value, sizeof("true"))) {
+        if ((popcount(channel_mask) > 2) &&
+                (sample_rate > CODEC_BACKEND_DEFAULT_SAMPLE_RATE) &&
+                !(flags & AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH))  {
+                    sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+                    ALOGD("%s: MCH session defaulting sample rate to %d",
+                               __func__, sample_rate);
+        }
+    }
     ALOGV("%s: flags: %x, format: %x sample_rate %d",
            __func__, flags, format, sample_rate);
     list_for_each(node_i, streams_output_cfg_list) {
@@ -533,6 +551,7 @@
     struct mixer_ctl *ctl;
     int pcm_device_id, acdb_dev_id, snd_device = usecase->out_snd_device;
     int32_t sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
+    char value[PROPERTY_VALUE_MAX] = {0};
 
     ALOGV("%s", __func__);
 
@@ -576,47 +595,32 @@
         rc = -EINVAL;
         goto exit_send_app_type_cfg;
     }
-
-    if ((usecase->type == PCM_PLAYBACK) && (usecase->stream.out == NULL)) {
-        sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
-        app_type_cfg[len++] = platform_get_default_app_type_v2(adev->platform, usecase->type);
-        app_type_cfg[len++] = acdb_dev_id;
-        app_type_cfg[len++] = sample_rate;
-        ALOGI("%s PLAYBACK app_type %d, acdb_dev_id %d, sample_rate %d",
-              __func__, platform_get_default_app_type_v2(adev->platform, usecase->type),
-              acdb_dev_id, sample_rate);
-    } else if (usecase->type == PCM_PLAYBACK) {
-        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;
-        } else if ((snd_device != SND_DEVICE_OUT_HEADPHONES_44_1 &&
-            usecase->stream.out->sample_rate == OUTPUT_SAMPLING_RATE_44100) ||
-            (usecase->stream.out->sample_rate < OUTPUT_SAMPLING_RATE_44100)) {
-            usecase->stream.out->app_type_cfg.sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
-        }
-        sample_rate = usecase->stream.out->app_type_cfg.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))
-#ifdef HDMI_PASSTHROUGH_ENABLED
-            && (out->flags  & AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH)
-#endif
-            )
-            app_type_cfg[len++] = sample_rate * 4;
-        else
-            app_type_cfg[len++] = sample_rate;
-        ALOGI("%s PLAYBACK app_type %d, acdb_dev_id %d, sample_rate %d",
-              __func__, usecase->stream.out->app_type_cfg.app_type, acdb_dev_id, sample_rate);
-    } else if (usecase->type == PCM_CAPTURE) {
-        app_type_cfg[len++] = platform_get_default_app_type_v2(adev->platform, usecase->type);
-        app_type_cfg[len++] = acdb_dev_id;
-        app_type_cfg[len++] = sample_rate;
-        ALOGI("%s CAPTURE app_type %d, acdb_dev_id %d, sample_rate %d",
-           __func__, platform_get_default_app_type_v2(adev->platform, usecase->type),
-           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;
+    } else if ((snd_device != SND_DEVICE_OUT_HEADPHONES_44_1 &&
+        usecase->stream.out->sample_rate == OUTPUT_SAMPLING_RATE_44100) ||
+        (usecase->stream.out->sample_rate < OUTPUT_SAMPLING_RATE_44100)) {
+        usecase->stream.out->app_type_cfg.sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
     }
+    sample_rate = usecase->stream.out->app_type_cfg.sample_rate;
+
+    property_get("audio.playback.mch.downsample",value,"");
+    if (!strncmp("true", value, sizeof("true"))) {
+        if ((popcount(usecase->stream.out->channel_mask) > 2) &&
+               (usecase->stream.out->app_type_cfg.sample_rate > CODEC_BACKEND_DEFAULT_SAMPLE_RATE) &&
+               !(usecase->stream.out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH))
+           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;
     mixer_ctl_set_array(ctl, app_type_cfg, len);
     rc = 0;
 exit_send_app_type_cfg:
@@ -656,7 +660,7 @@
                      audio_extn_get_spkr_prot_snd_device(snd_device) : snd_device;
         platform_send_audio_calibration(adev->platform, usecase,
                                         out->app_type_cfg.app_type,
-                                        out->app_type_cfg.sample_rate);
+                                        usecase->stream.out->app_type_cfg.sample_rate);
     }
     if ((type == PCM_HFP_CALL) || (type == PCM_CAPTURE)) {
         /* when app type is default. the sample rate is not used to send cal */
@@ -875,6 +879,7 @@
          case 16000:
          case 22050:
              channel_status[3] |= SR_NOTID;
+             break;
          case 24000:
              channel_status[3] |= SR_24000;
              break;
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 9447d7e..a0f9206 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -450,7 +450,7 @@
     audio_extn_listen_update_stream_status(usecase, LISTEN_EVENT_STREAM_BUSY);
     audio_extn_utils_send_app_type_cfg(adev, usecase);
     audio_extn_utils_send_audio_calibration(adev, usecase);
-    strcpy(mixer_path, use_case_table[usecase->id]);
+    strlcpy(mixer_path, use_case_table[usecase->id], MIXER_PATH_MAX_LENGTH);
     platform_add_backend_name(mixer_path, snd_device, usecase);
     ALOGD("%s: apply mixer and update path: %s", __func__, mixer_path);
     audio_route_apply_and_update_path(adev->audio_route, mixer_path);
@@ -472,7 +472,7 @@
         snd_device = usecase->in_snd_device;
     else
         snd_device = usecase->out_snd_device;
-    strcpy(mixer_path, use_case_table[usecase->id]);
+    strlcpy(mixer_path, use_case_table[usecase->id], MIXER_PATH_MAX_LENGTH);
     platform_add_backend_name(mixer_path, snd_device, usecase);
     ALOGD("%s: reset and update mixer path: %s", __func__, mixer_path);
     audio_route_reset_and_update_path(adev->audio_route, mixer_path);
@@ -516,11 +516,10 @@
     if(SND_DEVICE_IN_USB_HEADSET_MIC == snd_device)
        audio_extn_usb_start_capture(adev);
 
-    if ((snd_device == SND_DEVICE_OUT_SPEAKER ||
-         snd_device == SND_DEVICE_OUT_SPEAKER_VBAT ||
-         snd_device == SND_DEVICE_OUT_VOICE_SPEAKER_VBAT ||
-         snd_device == SND_DEVICE_OUT_VOICE_SPEAKER) &&
-         audio_extn_spkr_prot_is_enabled()) {
+	   if ((snd_device == SND_DEVICE_OUT_SPEAKER || snd_device == SND_DEVICE_OUT_SPEAKER_WSA ||
+        snd_device == SND_DEVICE_OUT_SPEAKER_VBAT || snd_device == SND_DEVICE_OUT_VOICE_SPEAKER_VBAT ||
+        snd_device == SND_DEVICE_OUT_VOICE_SPEAKER) &&
+        audio_extn_spkr_prot_is_enabled()) {
        if (audio_extn_spkr_prot_get_acdb_id(snd_device) < 0) {
            adev->snd_dev_ref_cnt[snd_device]--;
            return -EINVAL;
@@ -585,12 +584,10 @@
         /* exit usb capture thread */
         if(SND_DEVICE_IN_USB_HEADSET_MIC == snd_device)
             audio_extn_usb_stop_capture();
-
-        if ((snd_device == SND_DEVICE_OUT_SPEAKER ||
-             snd_device == SND_DEVICE_OUT_SPEAKER_VBAT ||
-             snd_device == SND_DEVICE_OUT_VOICE_SPEAKER_VBAT ||
-             snd_device == SND_DEVICE_OUT_VOICE_SPEAKER) &&
-             audio_extn_spkr_prot_is_enabled()) {
+        if ((snd_device == SND_DEVICE_OUT_SPEAKER || snd_device == SND_DEVICE_OUT_SPEAKER_WSA ||
+            snd_device == SND_DEVICE_OUT_SPEAKER_VBAT || snd_device == SND_DEVICE_OUT_VOICE_SPEAKER_VBAT ||
+            snd_device == SND_DEVICE_OUT_VOICE_SPEAKER) &&
+            audio_extn_spkr_prot_is_enabled()) {
             audio_extn_spkr_prot_stop_processing(snd_device);
         } else {
             audio_route_reset_and_update_path(adev->audio_route, device_name);
@@ -1014,6 +1011,7 @@
                                                 usecase->stream.out->format,
                                                 usecase->stream.out->sample_rate,
                                                 usecase->stream.out->bit_width,
+                                                usecase->stream.out->channel_mask,
                                                 &usecase->stream.out->app_type_cfg);
         ALOGI("%s Selected apptype: %d", __func__, usecase->stream.out->app_type_cfg.app_type);
     }
@@ -2079,9 +2077,9 @@
             for (j = 0; j < ARRAY_SIZE(out_channels_name_to_enum_table); j++) {
                 if (out_channels_name_to_enum_table[j].value == out->supported_channel_masks[i]) {
                     if (!first) {
-                        strcat(value, "|");
+                        strlcat(value, "|", sizeof(value));
                     }
-                    strcat(value, out_channels_name_to_enum_table[j].name);
+                    strlcat(value, out_channels_name_to_enum_table[j].name, sizeof(value));
                     first = false;
                     break;
                 }
@@ -2123,7 +2121,7 @@
             for (j = 0; j < ARRAY_SIZE(out_formats_name_to_enum_table); j++) {
                 if (out_formats_name_to_enum_table[j].value == out->supported_formats[i]) {
                     if (!first) {
-                        strcat(value, "|");
+                        strlcat(value, "|", sizeof(value));
                     }
                     strlcat(value, out_formats_name_to_enum_table[j].name, sizeof(value));
                     first = false;
@@ -3171,7 +3169,8 @@
     audio_extn_utils_update_stream_app_type_cfg(adev->platform,
                                                 &adev->streams_output_cfg_list,
                                                 devices, flags, format, out->sample_rate,
-                                                out->bit_width, &out->app_type_cfg);
+                                                out->bit_width, out->channel_mask,
+                                                &out->app_type_cfg);
     if ((out->usecase == USECASE_AUDIO_PLAYBACK_PRIMARY) ||
         (flags & AUDIO_OUTPUT_FLAG_PRIMARY)) {
         /* Ensure the default output is not selected twice */
diff --git a/hal/edid.c b/hal/edid.c
index 9b05950..06e1e05 100644
--- a/hal/edid.c
+++ b/hal/edid.c
@@ -662,12 +662,12 @@
         ALOGV("AUDIO DESC BLOCK # %d\n",i);
 
         info->audio_blocks_array[i].channels = channels[i];
-        ALOGV("info->audio_blocks_array[i].channels %d\n",
+        ALOGD("info->audio_blocks_array[i].channels %d\n",
               info->audio_blocks_array[i].channels);
 
         ALOGV("Format Byte %d\n", formats[i]);
         info->audio_blocks_array[i].format_id = (edid_audio_format_id)formats[i];
-        ALOGV("info->audio_blocks_array[i].format_id %s",
+        ALOGD("info->audio_blocks_array[i].format_id %s",
               edid_format_to_str(formats[i]));
 
         ALOGV("Frequency Byte %d\n", frequency[i]);
diff --git a/hal/msm8916/hw_info.c b/hal/msm8916/hw_info.c
old mode 100755
new mode 100644
index 547e6e8..d04c69c
--- a/hal/msm8916/hw_info.c
+++ b/hal/msm8916/hw_info.c
@@ -137,6 +137,11 @@
         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, "msm8x16-snd-card-sbc")) {
+        strlcpy(hw_info->type, "sbc", sizeof(hw_info->type));
+        strlcpy(hw_info->name, "msm8x16", sizeof(hw_info->name));
+        hw_info->snd_devices = NULL;
+        hw_info->num_snd_devices = 0;
     } else if (!strcmp(snd_card_name, "msm8x16-skuh-snd-card")) {
         strlcpy(hw_info->type, "skuh", sizeof(hw_info->type));
         strlcpy(hw_info->name, "msm8x16", sizeof(hw_info->name));
@@ -264,6 +269,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, "msm8976-tasha-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 if (!strcmp(snd_card_name, "msm8976-tashalite-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__);
     }
@@ -280,7 +297,8 @@
     }
 
     if (strstr(snd_card_name, "msm8x16") || strstr(snd_card_name, "msm8939") ||
-        strstr(snd_card_name, "msm8909") || strstr(snd_card_name, "msm8952")) {
+        strstr(snd_card_name, "msm8909") || strstr(snd_card_name, "msm8952") ||
+        strstr(snd_card_name, "msm8976")) {
         ALOGV("8x16 - variant soundcard");
         update_hardware_info_8x16(hw_info, snd_card_name);
     } else {
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 2e48a71..463dc77 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -38,10 +38,10 @@
 #include "sound/msmcal-hwdep.h"
 #include <dirent.h>
 #define SOUND_TRIGGER_DEVICE_HANDSET_MONO_LOW_POWER_ACDB_ID (100)
-
 #define MAX_MIXER_XML_PATH  100
 #define MIXER_XML_PATH "/system/etc/mixer_paths.xml"
 #define MIXER_XML_PATH_MTP "/system/etc/mixer_paths_mtp.xml"
+#define MIXER_XML_PATH_SBC "/system/etc/mixer_paths_sbc.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"
@@ -54,6 +54,7 @@
 #define MIXER_XML_PATH_SKUM "/system/etc/mixer_paths_qrd_skum.xml"
 #define MIXER_XML_PATH_SKU1 "/system/etc/mixer_paths_qrd_sku1.xml"
 #define MIXER_XML_PATH_SKU2 "/system/etc/mixer_paths_qrd_sku2.xml"
+#define MIXER_XML_PATH_SKUN_CAJON "/system/etc/mixer_paths_qrd_skun_cajon.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_I2S "/system/etc/mixer_paths_i2s.xml"
@@ -61,6 +62,7 @@
 #define MIXER_XML_PATH_WCD9330 "/system/etc/mixer_paths_wcd9330.xml"
 #define MIXER_XML_PATH_WCD9335 "/system/etc/mixer_paths_wcd9335.xml"
 #define MIXER_XML_PATH_WCD9326 "/system/etc/mixer_paths_wcd9326.xml"
+#define MIXER_XML_PATH_SKUN "/system/etc/mixer_paths_qrd_skun.xml"
 #define PLATFORM_INFO_XML_PATH      "/system/etc/audio_platform_info.xml"
 #define PLATFORM_INFO_XML_PATH_EXTCODEC  "/system/etc/audio_platform_info_extcodec.xml"
 
@@ -143,7 +145,7 @@
 
 #define AUDIO_PARAMETER_KEY_REC_PLAY_CONC "rec_play_conc_on"
 
-#define  AUDIO_PARAMETER_IS_HW_DECODER_SESSION_ALLOWED  "is_hw_dec_session_allowed"
+#define  AUDIO_PARAMETER_IS_HW_DECODER_SESSION_AVAILABLE  "is_hw_dec_session_available"
 
 char * dsp_only_decoders_mime[] = {
     "audio/x-ms-wma" /* wma*/ ,
@@ -285,6 +287,7 @@
     [USECASE_AUDIO_PLAYBACK_OFFLOAD7] = {-1, -1},
     [USECASE_AUDIO_PLAYBACK_OFFLOAD8] = {-1, -1},
     [USECASE_AUDIO_PLAYBACK_OFFLOAD9] = {-1, -1},
+    [USECASE_AUDIO_PLAYBACK_ULL] = {MULTIMEDIA3_PCM_DEVICE, MULTIMEDIA3_PCM_DEVICE},
     [USECASE_AUDIO_RECORD] = {AUDIO_RECORD_PCM_DEVICE, AUDIO_RECORD_PCM_DEVICE},
     [USECASE_AUDIO_RECORD_COMPRESS] = {COMPRESS_CAPTURE_DEVICE, COMPRESS_CAPTURE_DEVICE},
     [USECASE_AUDIO_RECORD_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
@@ -336,19 +339,22 @@
     [SND_DEVICE_OUT_SPEAKER] = "speaker",
     [SND_DEVICE_OUT_SPEAKER_EXTERNAL_1] = "speaker-ext-1",
     [SND_DEVICE_OUT_SPEAKER_EXTERNAL_2] = "speaker-ext-2",
-    [SND_DEVICE_OUT_SPEAKER_WSA] = "speaker-wsa",
-    [SND_DEVICE_OUT_SPEAKER_VBAT] = "speaker-vbat",
+    [SND_DEVICE_OUT_SPEAKER_WSA] = "wsa-speaker",
+    [SND_DEVICE_OUT_SPEAKER_VBAT] = "vbat-speaker",
     [SND_DEVICE_OUT_SPEAKER_REVERSE] = "speaker-reverse",
     [SND_DEVICE_OUT_HEADPHONES] = "headphones",
     [SND_DEVICE_OUT_HEADPHONES_44_1] = "headphones-44.1",
+    [SND_DEVICE_OUT_LINE] = "line",
     [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = "speaker-and-headphones",
+    [SND_DEVICE_OUT_SPEAKER_AND_LINE] = "speaker-and-line",
     [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1] = "speaker-and-headphones-ext-1",
     [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2] = "speaker-and-headphones-ext-2",
     [SND_DEVICE_OUT_VOICE_HANDSET] = "voice-handset",
     [SND_DEVICE_OUT_VOICE_SPEAKER] = "voice-speaker",
-    [SND_DEVICE_OUT_VOICE_SPEAKER_WSA] = "voice-speaker-wsa",
-    [SND_DEVICE_OUT_VOICE_SPEAKER_VBAT] = "voice-speaker-vbat",
+    [SND_DEVICE_OUT_VOICE_SPEAKER_WSA] = "wsa-voice-speaker",
+    [SND_DEVICE_OUT_VOICE_SPEAKER_VBAT] = "vbat-voice-speaker",
     [SND_DEVICE_OUT_VOICE_HEADPHONES] = "voice-headphones",
+    [SND_DEVICE_OUT_VOICE_LINE] = "voice-line",
     [SND_DEVICE_OUT_HDMI] = "hdmi",
     [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = "speaker-and-hdmi",
     [SND_DEVICE_OUT_BT_SCO] = "bt-sco-headset",
@@ -448,12 +454,15 @@
     [SND_DEVICE_OUT_SPEAKER_WSA] = 135,
     [SND_DEVICE_OUT_SPEAKER_VBAT] = 135,
     [SND_DEVICE_OUT_SPEAKER_REVERSE] = 14,
+    [SND_DEVICE_OUT_LINE] = 10,
     [SND_DEVICE_OUT_HEADPHONES] = 10,
     [SND_DEVICE_OUT_HEADPHONES_44_1] = 10,
     [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = 10,
+    [SND_DEVICE_OUT_SPEAKER_AND_LINE] = 10,
     [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1] = 10,
     [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2] = 10,
     [SND_DEVICE_OUT_VOICE_HANDSET] = 7,
+    [SND_DEVICE_OUT_VOICE_LINE] = 10,
     [SND_DEVICE_OUT_VOICE_SPEAKER] = 14,
     [SND_DEVICE_OUT_VOICE_SPEAKER_WSA] = 135,
     [SND_DEVICE_OUT_VOICE_SPEAKER_VBAT] = 135,
@@ -536,7 +545,7 @@
     [SND_DEVICE_IN_SPEAKER_DMIC_AEC_BROADSIDE] = 119,
     [SND_DEVICE_IN_SPEAKER_DMIC_NS_BROADSIDE] = 121,
     [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE] = 120,
-    [SND_DEVICE_IN_VOICE_FLUENCE_DMIC_AANC] = 135,
+    [SND_DEVICE_IN_VOICE_FLUENCE_DMIC_AANC] = 105,
     [SND_DEVICE_IN_HANDSET_QMIC] = 125,
     [SND_DEVICE_IN_SPEAKER_QMIC_AEC] = 126,
     [SND_DEVICE_IN_SPEAKER_QMIC_NS] = 127,
@@ -561,7 +570,9 @@
     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_REVERSE)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES_44_1)},
+    {TO_NAME_INDEX(SND_DEVICE_OUT_LINE)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES)},
+    {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_LINE)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HANDSET)},
@@ -569,6 +580,7 @@
     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER_WSA)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER_VBAT)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HEADPHONES)},
+    {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_LINE)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_HDMI)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HDMI)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO)},
@@ -668,6 +680,7 @@
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD7)},
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD8)},
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD9)},
+    {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_ULL)},
     {TO_NAME_INDEX(USECASE_AUDIO_RECORD)},
     {TO_NAME_INDEX(USECASE_AUDIO_RECORD_LOW_LATENCY)},
     {TO_NAME_INDEX(USECASE_VOICE_CALL)},
@@ -681,6 +694,7 @@
     {TO_NAME_INDEX(USECASE_INCALL_REC_DOWNLINK)},
     {TO_NAME_INDEX(USECASE_INCALL_REC_UPLINK_AND_DOWNLINK)},
     {TO_NAME_INDEX(USECASE_AUDIO_HFP_SCO)},
+    {TO_NAME_INDEX(USECASE_AUDIO_SPKR_CALIB_TX)},
 };
 
 #define NO_COLS 2
@@ -773,7 +787,13 @@
          !strncmp(snd_card_name, "msm8952-tashalite-snd-card",
                   sizeof("msm8952-tashalite-snd-card")) ||
          !strncmp(snd_card_name, "msm8952-tasha-skun-snd-card",
-                  sizeof("msm8952-tasha-skun-snd-card")))
+                  sizeof("msm8952-tasha-skun-snd-card")) ||
+         !strncmp(snd_card_name, "msm8976-tasha-snd-card",
+                  sizeof("msm8976-tasha-snd-card")) ||
+         !strncmp(snd_card_name, "msm8976-tashalite-snd-card",
+                  sizeof("msm8976-tashalite-snd-card")) ||
+         !strncmp(snd_card_name, "msm8976-tasha-skun-snd-card",
+                  sizeof("msm8976-tasha-skun-snd-card")))
      {
          ALOGI("%s: snd_card_name: %s",__func__,snd_card_name);
          is_external_codec = true;
@@ -791,6 +811,15 @@
         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, "msm8x16-snd-card-sbc",
+                 sizeof("msm8x16-snd-card-sbc"))) {
+        strlcpy(mixer_xml_path, MIXER_XML_PATH_SBC,
+                sizeof(mixer_xml_path));
+
+        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, "msm8x16-skuh-snd-card",
                  sizeof("msm8x16-skuh-snd-card"))) {
         strlcpy(mixer_xml_path, MIXER_XML_PATH_QRD_SKUH,
@@ -860,6 +889,30 @@
         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, "msm8976-tasha-snd-card",
+                 sizeof("msm8976-tasha-snd-card"))) {
+        strlcpy(mixer_xml_path, MIXER_XML_PATH_WCD9335,
+                sizeof(MIXER_XML_PATH_WCD9335));
+        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]);
+
+    } else if (!strncmp(snd_card_name, "msm8976-tashalite-snd-card",
+                 sizeof("msm8976-tashalite-snd-card"))) {
+        strlcpy(mixer_xml_path, MIXER_XML_PATH_WCD9326,
+               MAX_MIXER_XML_PATH);
+        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]);
+
+    } else if (!strncmp(snd_card_name, "msm8976-tasha-skun-snd-card",
+                sizeof("msm8976-tasha-skun-snd-card"))) {
+        strlcpy(mixer_xml_path, MIXER_XML_PATH_SKUN,
+                sizeof(MIXER_XML_PATH_SKUN));
+        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]);
+
     } else if (!strncmp(snd_card_name, "msm8909-skua-snd-card",
                  sizeof("msm8909-skua-snd-card"))) {
         strlcpy(mixer_xml_path, MIXER_XML_PATH_SKUA,
@@ -950,6 +1003,13 @@
         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]);
+    } else if (!strncmp(snd_card_name, "msm8976-skun-snd-card",
+                 sizeof("msm8976-skun-snd-card"))) {
+        strlcpy(mixer_xml_path, MIXER_XML_PATH_SKUN_CAJON,
+                sizeof(MIXER_XML_PATH_SKUN_CAJON));
+        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));
@@ -961,6 +1021,41 @@
     }
 }
 
+void platform_set_echo_reference(struct audio_device *adev, bool enable,
+    audio_devices_t out_device)
+{
+    struct platform_data *my_data = (struct platform_data *)adev->platform;
+    snd_device_t snd_device = SND_DEVICE_NONE;
+    struct stream_out out;
+
+    out.devices = out_device;
+
+    if (strcmp(my_data->ec_ref_mixer_path, "")) {
+        ALOGV("%s: disabling %s", __func__, my_data->ec_ref_mixer_path);
+        audio_route_reset_and_update_path(adev->audio_route,
+            my_data->ec_ref_mixer_path);
+    }
+
+    if (enable) {
+        snd_device = platform_get_output_snd_device(adev->platform, &out);
+
+        if (adev->snd_dev_ref_cnt[SND_DEVICE_OUT_HEADPHONES_44_1] > 0)
+            strlcpy(my_data->ec_ref_mixer_path, "echo-reference headphones-44.1",
+                sizeof(my_data->ec_ref_mixer_path));
+        else if ((snd_device == SND_DEVICE_OUT_SPEAKER_VBAT) ||
+                 (snd_device == SND_DEVICE_OUT_SPEAKER_PROTECTED_VBAT))
+            strlcpy(my_data->ec_ref_mixer_path, "vbat-speaker echo-reference",
+                sizeof(my_data->ec_ref_mixer_path));
+        else
+            strlcpy(my_data->ec_ref_mixer_path, "echo-reference",
+                sizeof(my_data->ec_ref_mixer_path));
+
+
+        ALOGD("%s: enabling %s", __func__, my_data->ec_ref_mixer_path);
+        audio_route_apply_and_update_path(adev->audio_route,
+            my_data->ec_ref_mixer_path);
+    }
+}
 void platform_set_gsm_mode(void *platform, bool enable)
 {
     struct platform_data *my_data = (struct platform_data *)platform;
@@ -979,42 +1074,7 @@
     }
 }
 
-void platform_set_echo_reference(struct audio_device *adev, bool enable, audio_devices_t out_device)
-{
-    struct platform_data *my_data = (struct platform_data *)adev->platform;
-    snd_device_t snd_device = SND_DEVICE_NONE;
-    struct stream_out out;
 
-    out.devices = out_device;
-
-    if (strcmp(my_data->ec_ref_mixer_path, "")) {
-        ALOGV("%s: disabling %s", __func__, my_data->ec_ref_mixer_path);
-        audio_route_reset_and_update_path(adev->audio_route,
-                                          my_data->ec_ref_mixer_path);
-    }
-
-    if (enable) {
-        snd_device = platform_get_output_snd_device(adev->platform, &out);
-
-        /*
-         * If native audio device reference count > 0, then apply codec EC otherwise
-         * fallback to Speakers with VBat if enabled or default
-         */
-        if (adev->snd_dev_ref_cnt[SND_DEVICE_OUT_HEADPHONES_44_1] > 0)
-            strlcpy(my_data->ec_ref_mixer_path, "echo-reference headphones-44.1",
-                    sizeof(my_data->ec_ref_mixer_path));
-        else if ((snd_device == SND_DEVICE_OUT_SPEAKER_VBAT) ||
-                 (snd_device == SND_DEVICE_OUT_SPEAKER_PROTECTED_VBAT))
-            strlcpy(my_data->ec_ref_mixer_path, "vbat-speaker echo-reference",
-                    sizeof(my_data->ec_ref_mixer_path));
-        else
-            strlcpy(my_data->ec_ref_mixer_path, "echo-reference",
-                    sizeof(my_data->ec_ref_mixer_path));
-
-        ALOGD("%s: enabling %s", __func__, my_data->ec_ref_mixer_path);
-        audio_route_apply_and_update_path(adev->audio_route, my_data->ec_ref_mixer_path);
-    }
-}
 
 static struct csd_data *open_csd_client()
 {
@@ -1191,7 +1251,7 @@
     backend_table[SND_DEVICE_IN_CAPTURE_FM] = strdup("capture-fm");
     backend_table[SND_DEVICE_OUT_TRANSMISSION_FM] = strdup("transmission-fm");
     backend_table[SND_DEVICE_OUT_HEADPHONES_44_1] = strdup("headphones-44.1");
-    backend_table[SND_DEVICE_OUT_VOICE_SPEAKER_VBAT] = strdup("voice-speaker-vbat");
+    backend_table[SND_DEVICE_OUT_VOICE_SPEAKER_VBAT] = strdup("vbat-voice-speaker");
 }
 
 void get_cvd_version(char *cvd_version, struct audio_device *adev)
@@ -1474,8 +1534,10 @@
     struct platform_data *my_data = NULL;
     int retry_num = 0, snd_card_num = 0, key = 0;
     const char *snd_card_name;
-    char mixer_xml_path[100],ffspEnable[PROPERTY_VALUE_MAX];
+    char mixer_xml_path[MAX_MIXER_XML_PATH],ffspEnable[PROPERTY_VALUE_MAX];
     char *cvd_version = NULL;
+    const char *mixer_ctl_name = "Set HPX ActiveBe";
+    struct mixer_ctl *ctl = NULL;
     int idx;
     int wsaCount =0;
 
@@ -1689,22 +1751,11 @@
     }
     audio_extn_pm_vote();
 
-    // Check if WSA speaker is supported in codec
-    char CodecPeek[1024] = "/sys/kernel/debug/asoc/";
-    DIR *dir;
-    struct dirent *dirent;
-    char file_name[10] = "wsa";
-    strcat(CodecPeek, snd_card_name);
-
-    dir = opendir(CodecPeek);
-    if (dir != NULL) {
-        while (NULL != (dirent = readdir(dir))) {
-            if (strstr (dirent->d_name,file_name)) {
-                my_data->is_wsa_speaker = true;
-                break;
-            }
-        }
-        closedir(dir);
+    /* Configure active back end for HPX*/
+    ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+    if (ctl) {
+        ALOGE(" sending HPX Active BE information ");
+        mixer_ctl_set_value(ctl, 0, is_external_codec);
     }
 
 acdb_init_fail:
@@ -1772,8 +1823,6 @@
         (platform_get_native_support() ? "enabled" : "disabled"),
         snd_card_name);
 
-
-
     my_data->edid_info = NULL;
     return my_data;
 }
@@ -2514,6 +2563,9 @@
                 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2;
             else
                 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
+        } else if (devices == (AUDIO_DEVICE_OUT_LINE |
+                               AUDIO_DEVICE_OUT_SPEAKER)) {
+                snd_device = SND_DEVICE_OUT_SPEAKER_AND_LINE;
         } else if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADSET |
                                AUDIO_DEVICE_OUT_SPEAKER)) {
             if (audio_extn_get_anc_enabled())
@@ -2547,7 +2599,8 @@
     if ((mode == AUDIO_MODE_IN_CALL) ||
         voice_extn_compress_voip_is_active(adev)) {
         if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
-            devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
+            devices & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
+            devices & AUDIO_DEVICE_OUT_LINE) {
             if ((adev->voice.tty_mode != TTY_MODE_OFF) &&
                 !voice_extn_compress_voip_is_active(adev)) {
                 switch (adev->voice.tty_mode) {
@@ -2564,6 +2617,8 @@
                     ALOGE("%s: Invalid TTY mode (%#x)",
                           __func__, adev->voice.tty_mode);
                 }
+            } else if (devices & AUDIO_DEVICE_OUT_LINE) {
+                snd_device = SND_DEVICE_OUT_VOICE_LINE;
             } else if (audio_extn_get_anc_enabled()) {
                 if (audio_extn_should_use_fb_anc())
                     snd_device = SND_DEVICE_OUT_VOICE_ANC_FB_HEADSET;
@@ -2630,6 +2685,8 @@
 #endif
                 snd_device = SND_DEVICE_OUT_HEADPHONES;
         }
+    } else if (devices & AUDIO_DEVICE_OUT_LINE) {
+        snd_device = SND_DEVICE_OUT_LINE;
     } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
 #ifdef RECORD_PLAY_CONCURRENCY
         if (use_voip_out_devices) {
@@ -2722,7 +2779,8 @@
         if ((adev->voice.tty_mode != TTY_MODE_OFF) &&
             !voice_extn_compress_voip_is_active(adev)) {
             if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
-                out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
+                out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
+                out_device & AUDIO_DEVICE_OUT_LINE) {
                 switch (adev->voice.tty_mode) {
                 case TTY_MODE_FULL:
                     snd_device = SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC;
@@ -2741,7 +2799,8 @@
             }
         }
         if (out_device & AUDIO_DEVICE_OUT_EARPIECE ||
-            out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
+            out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
+            out_device & AUDIO_DEVICE_OUT_LINE) {
             if (out_device & AUDIO_DEVICE_OUT_EARPIECE &&
                 audio_extn_should_use_handset_anc(channel_count) &&
                 my_data->fluence_type != FLUENCE_NONE) {
@@ -2827,8 +2886,9 @@
         if (out_device & AUDIO_DEVICE_OUT_SPEAKER)
             in_device = AUDIO_DEVICE_IN_BACK_MIC;
         if (adev->active_input) {
-            if (adev->active_input->enable_aec &&
-                    adev->active_input->enable_ns) {
+            if (my_data->fluence_type != FLUENCE_NONE &&
+                adev->active_input->enable_aec &&
+                adev->active_input->enable_ns) {
                 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
                     if (my_data->fluence_in_spkr_mode) {
                         if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
@@ -2852,7 +2912,8 @@
                     snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
                 }
                 platform_set_echo_reference(adev, true, out_device);
-            } else if (adev->active_input->enable_aec) {
+            } else if (my_data->fluence_type != FLUENCE_NONE &&
+                       adev->active_input->enable_aec) {
                 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
                     if (my_data->fluence_in_spkr_mode) {
                         if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
@@ -2876,7 +2937,8 @@
                     snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
                 }
                 platform_set_echo_reference(adev, true, out_device);
-            } else if (adev->active_input->enable_ns) {
+            } else if (my_data->fluence_type != FLUENCE_NONE &&
+                       adev->active_input->enable_ns) {
                 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
                     if (my_data->fluence_in_spkr_mode) {
                         if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
@@ -2976,7 +3038,8 @@
                 snd_device = SND_DEVICE_IN_SPEAKER_STEREO_DMIC;
             else
                 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
-        } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
+        } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
+                       out_device & AUDIO_DEVICE_OUT_LINE) {
             snd_device = SND_DEVICE_IN_HANDSET_MIC;
         } else if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
             if (adev->bt_wb_speech_enabled) {
@@ -3590,7 +3653,7 @@
     }
     native_audio_get_params(query, reply, value, sizeof(value));
 
-    ret = str_parms_get_str(query, AUDIO_PARAMETER_IS_HW_DECODER_SESSION_ALLOWED,
+    ret = str_parms_get_str(query, AUDIO_PARAMETER_IS_HW_DECODER_SESSION_AVAILABLE,
                                     value, sizeof(value));
     if (ret >= 0) {
         int isallowed = 1; /*true*/
@@ -3617,7 +3680,7 @@
                 }
             }
         }
-        str_parms_add_int(reply, AUDIO_PARAMETER_IS_HW_DECODER_SESSION_ALLOWED, isallowed);
+        str_parms_add_int(reply, AUDIO_PARAMETER_IS_HW_DECODER_SESSION_AVAILABLE, isallowed);
     }
 
 
@@ -3862,7 +3925,15 @@
         !strncmp(snd_card_name, "msm8952-tasha-snd-card",
         sizeof("msm8952-tasha-snd-card")) ||
         !strncmp(snd_card_name, "msm8952-tashalite-snd-card",
-        sizeof("msm8952-tashalite-snd-card")))
+        sizeof("msm8952-tashalite-snd-card")) ||
+        !strncmp(snd_card_name, "msm8952-tasha-skun-snd-card",
+        sizeof("msm8952-tasha-skun-snd-card")) ||
+        !strncmp(snd_card_name, "msm8976-tasha-snd-card",
+        sizeof("msm8976-tasha-snd-card")) ||
+        !strncmp(snd_card_name, "msm8976-tashalite-snd-card",
+        sizeof("msm8976-tashalite-snd-card")) ||
+        !strncmp(snd_card_name, "msm8976-tasha-skun-snd-card",
+        sizeof("msm8976-tasha-skun-snd-card")))
     {
         /* external codec, for rest/old of the external codecs
            we dont support this funtionality(chaning AFE params)
@@ -4076,6 +4147,21 @@
     if (!is_external_codec)
         sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
 
+    //check if mulitchannel clip needs to be down sampled to 48k
+    property_get("audio.playback.mch.downsample",value,"");
+    if (!strncmp("true", value, sizeof("true"))) {
+        out = usecase->stream.out;
+        if ((popcount(out->channel_mask) > 2) &&
+                      (out->sample_rate > CODEC_BACKEND_DEFAULT_SAMPLE_RATE) &&
+                      !(out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH)) {
+           sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+          /* update out sample rate to reflect current backend sample rate  */
+           out->sample_rate = sample_rate;
+           ALOGD("%s: MCH session defaulting sample rate to %d",
+                        __func__, sample_rate);
+         }
+    }
+
 
     ALOGI("%s Codec selected backend: %d updated bit width: %d and sample rate: %d",
                __func__, backend_idx, bit_width, sample_rate);
@@ -4359,10 +4445,15 @@
         ALOGE("%s: Invalid channel mapping used", __func__);
         return -EINVAL;
     }
-    strlcpy(mixer_ctl_name, "Playback Channel Map", sizeof(mixer_ctl_name));
+
+    /*
+     * If snd_id is greater than 0, stream channel mapping
+     * If snd_id is below 0, typically -1, device channel mapping
+     */
     if (snd_id >= 0) {
-        snprintf(device_num, sizeof(device_num), "%d", snd_id);
-        strncat(mixer_ctl_name, device_num, 13);
+        snprintf(mixer_ctl_name, sizeof(mixer_ctl_name), "Playback Channel Map%d", snd_id);
+    } else {
+        strlcpy(mixer_ctl_name, "Playback Device Channel Map", sizeof(mixer_ctl_name));
     }
 
     ALOGD("%s mixer_ctl_name:%s", __func__, mixer_ctl_name);
@@ -4728,10 +4819,59 @@
     return ret;
 }
 
-bool platform_send_gain_dep_cal(void *platform __unused,
-                                int level __unused)
+ /*
+ * This is a lookup table to map names of speaker device with respective left and right TZ names.
+ * Also the tz names for a particular left or right speaker can be overriden by adding
+ * corresponding entry in audio_platform_info.xml file.
+ */
+struct speaker_device_to_tz_names speaker_device_tz_names = {
+    {SND_DEVICE_OUT_SPEAKER, "", ""},
+};
+
+const char *platform_get_spkr_1_tz_name(snd_device_t snd_device)
 {
-    return 0;
+    if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX)
+        return speaker_device_tz_names.spkr_1_tz_name;
+    else
+        return "";
+}
+
+const char *platform_get_spkr_2_tz_name(snd_device_t snd_device)
+{
+    if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX)
+        return speaker_device_tz_names.spkr_2_tz_name;
+    else
+        return "";
+}
+
+int platform_set_spkr_device_tz_names(snd_device_t index,
+                                      const char *spkr_1_tz_name, const char *spkr_2_tz_name)
+{
+    int ret = 0;
+    int i;
+
+    if (spkr_1_tz_name == NULL && spkr_2_tz_name == NULL) {
+        ALOGE("%s: Invalid input", __func__);
+        ret = -EINVAL;
+        goto done;
+    }
+    if (index != speaker_device_tz_names.snd_device) {
+        ALOGE("%s: not matching speaker device\n");
+        ret = -EINVAL;
+        goto done;
+    }
+    ALOGD("%s: Enter, spkr_1_tz_name :%s, spkr_2_tz_name:%s",
+            __func__, spkr_1_tz_name, spkr_2_tz_name);
+
+    if (spkr_1_tz_name != NULL)
+        strlcpy(speaker_device_tz_names.spkr_1_tz_name, spkr_1_tz_name,
+                sizeof(speaker_device_tz_names.spkr_1_tz_name));
+
+    if (spkr_2_tz_name != NULL)
+        strlcpy(speaker_device_tz_names.spkr_2_tz_name, spkr_2_tz_name,
+                sizeof(speaker_device_tz_names.spkr_2_tz_name));
+done:
+    return ret;
 }
 
 int platform_get_wsa_mode(void *adev)
@@ -4748,3 +4888,9 @@
     else
         return 0;
 }
+
+bool platform_send_gain_dep_cal(void *platform __unused,
+                                int level __unused)
+{
+    return 0;
+}
diff --git a/hal/msm8916/platform.h b/hal/msm8916/platform.h
index a5b97ac..c4d0b59 100644
--- a/hal/msm8916/platform.h
+++ b/hal/msm8916/platform.h
@@ -45,7 +45,8 @@
  */
 #define AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND \
     (AUDIO_DEVICE_OUT_EARPIECE | AUDIO_DEVICE_OUT_SPEAKER | \
-     AUDIO_DEVICE_OUT_WIRED_HEADSET | AUDIO_DEVICE_OUT_WIRED_HEADPHONE)
+     AUDIO_DEVICE_OUT_WIRED_HEADSET | AUDIO_DEVICE_OUT_WIRED_HEADPHONE|\
+     AUDIO_DEVICE_OUT_LINE)
 
 /*
  * Below are the input devices for which back end is same, SLIMBUS_0_TX.
@@ -73,9 +74,11 @@
     SND_DEVICE_OUT_SPEAKER_REVERSE,
     SND_DEVICE_OUT_SPEAKER_WSA,
     SND_DEVICE_OUT_SPEAKER_VBAT,
+    SND_DEVICE_OUT_LINE,
     SND_DEVICE_OUT_HEADPHONES,
     SND_DEVICE_OUT_HEADPHONES_44_1,
     SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES,
+    SND_DEVICE_OUT_SPEAKER_AND_LINE,
     SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1,
     SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2,
     SND_DEVICE_OUT_VOICE_HANDSET,
@@ -83,6 +86,7 @@
     SND_DEVICE_OUT_VOICE_SPEAKER_WSA,
     SND_DEVICE_OUT_VOICE_SPEAKER_VBAT,
     SND_DEVICE_OUT_VOICE_HEADPHONES,
+    SND_DEVICE_OUT_VOICE_LINE,
     SND_DEVICE_OUT_HDMI,
     SND_DEVICE_OUT_SPEAKER_AND_HDMI,
     SND_DEVICE_OUT_BT_SCO,
@@ -236,6 +240,7 @@
 #define DEEP_BUFFER_PCM_DEVICE 0
 #define AUDIO_RECORD_PCM_DEVICE 0
 #define MULTIMEDIA2_PCM_DEVICE 1
+#define MULTIMEDIA3_PCM_DEVICE 4
 #define FM_PLAYBACK_PCM_DEVICE 5
 #define FM_CAPTURE_PCM_DEVICE  6
 #define HFP_PCM_RX 5
@@ -247,7 +252,7 @@
 #define SPKR_PROT_CALIB_RX_PCM_DEVICE 5
 #define SPKR_PROT_CALIB_TX_PCM_DEVICE 26
 #define PLAYBACK_OFFLOAD_DEVICE 9
-
+#define PLAYBACK_OFFLOAD_DEVICE2 24
 #define COMPRESS_VOIP_CALL_PCM_DEVICE 3
 
 /* Define macro for Internal FM volume mixer */
@@ -332,4 +337,10 @@
     char device_name[100];
     char interface_name[100];
 };
+
+struct speaker_device_to_tz_names {
+    snd_device_t snd_device;
+    char spkr_1_tz_name[100];
+    char spkr_2_tz_name[100];
+};
 #endif // QCOM_AUDIO_PLATFORM_H
diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c
index 5b4ebeb..23e3095 100644
--- a/hal/msm8960/platform.c
+++ b/hal/msm8960/platform.c
@@ -230,6 +230,8 @@
     char value[PROPERTY_VALUE_MAX];
     struct platform_data *my_data;
     const char *snd_card_name;
+    const char *mixer_ctl_name = "Set HPX ActiveBe";
+    struct mixer_ctl *ctl = NULL;
 
     adev->mixer = mixer_open(MIXER_CARD);
 
@@ -340,6 +342,13 @@
         }
     }
 
+    /* Configure active back end for HPX*/
+    ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+    if (ctl) {
+        ALOGI(" sending HPX Active BE information ");
+        mixer_ctl_set_value(ctl, 0, false);
+    }
+
     return my_data;
 }
 
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 2caefe0..d4cdf2e 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -3148,6 +3148,11 @@
         bool status = false;
         str_parms_del(parms, AUDIO_PARAMETER_KEY_EXT_AUDIO_DEVICE);
         event_name = strtok_r(value, ",", &status_str);
+        if (!event_name) {
+            ret = -EINVAL;
+            ALOGE("%s: event_name is NULL", __func__);
+            goto done;
+        }
         ALOGV("%s: recieved update of external audio device %s %s",
                          __func__,
                          event_name, status_str);
@@ -4027,7 +4032,7 @@
 int platform_set_channel_map(void *platform, int ch_count, char *ch_map, int snd_id)
 {
     struct mixer_ctl *ctl;
-    char mixer_ctl_name[44]; // max length of name is 44 as defined
+    char mixer_ctl_name[44] = {0}; // max length of name is 44 as defined
     int ret;
     unsigned int i;
     int set_values[8] = {0};
@@ -4393,3 +4398,5 @@
 done:
     return ret;
 }
+
+
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index a2c6304..c98d1af 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -105,6 +105,8 @@
     SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED,
     SND_DEVICE_OUT_SPEAKER_PROTECTED_VBAT,
     SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED_VBAT,
+    SND_DEVICE_OUT_SPEAKER_WSA,
+    SND_DEVICE_OUT_VOICE_SPEAKER_WSA,
     SND_DEVICE_OUT_END,
 
     /*
diff --git a/hal/platform_info.c b/hal/platform_info.c
index 4a788ab..6514cb3 100644
--- a/hal/platform_info.c
+++ b/hal/platform_info.c
@@ -50,6 +50,7 @@
     BACKEND_NAME,
     INTERFACE_NAME,
     CONFIG_PARAMS,
+    TZ_NAME,
 } section_t;
 
 typedef void (* section_process_fn)(const XML_Char **attr);
@@ -61,6 +62,7 @@
 static void process_backend_name(const XML_Char **attr);
 static void process_interface_name(const XML_Char **attr);
 static void process_config_params(const XML_Char **attr);
+static void process_tz_name(const XML_Char **attr);
 static void process_root(const XML_Char **attr);
 
 static section_process_fn section_table[] = {
@@ -72,6 +74,7 @@
     [BACKEND_NAME] = process_backend_name,
     [INTERFACE_NAME] = process_interface_name,
     [CONFIG_PARAMS] = process_config_params,
+    [TZ_NAME] = process_tz_name,
 };
 
 static section_t section;
@@ -111,6 +114,11 @@
  *      ...
  * </config_params>
  *
+ * <tz_names>
+ * <device name="???" spkr_1_tz_name="???" spkr_2_tz_name="???"/>
+ * ...
+ * ...
+ * </tz_names>
  * </audio_platform_info>
  */
 
@@ -316,8 +324,7 @@
     }
 
     if (platform_set_native_support(atoi((char *)attr[3])) < 0) {
-        ALOGE("%s: Device %s, ACDB ID %d was not set!",
-              __func__, attr[1], atoi((char *)attr[3]));
+        ALOGE("%s: NATIVE_AUDIO_44 was not set!", __func__);
         goto done;
     }
 
@@ -325,6 +332,43 @@
     return;
 }
 
+static void process_tz_name(const XML_Char **attr)
+{
+    int ret, index;
+
+    if (strcmp(attr[0], "name") != 0) {
+        ALOGE("%s: 'name' not found, no Audio Interface set!", __func__);
+        goto done;
+    }
+
+    index = platform_get_snd_device_index((char *)attr[1]);
+    if (index < 0) {
+        ALOGE("%s: Device %s not found, no snd device set!",
+              __func__, attr[1]);
+        goto done;
+    }
+
+    if (strcmp(attr[2], "spkr_1_tz_name") != 0) {
+        ALOGE("%s: Device %s has no spkr_1_tz_name set!",
+              __func__, attr[1]);
+    }
+
+    if (strcmp(attr[4], "spkr_2_tz_name") != 0) {
+        ALOGE("%s: Device %s has no spkr_2_tz_name set!",
+              __func__, attr[1]);
+    }
+
+    /*  ret = platform_set_spkr_device_tz_names(index, (char *)attr[3], (char *)attr[5]);
+    if (ret < 0) {
+        ALOGE("%s: Audio Interface not set!", __func__);
+        goto done;
+    }
+    */
+
+done:
+    return;
+}
+
 static void process_config_params(const XML_Char **attr)
 {
     if (strcmp(attr[0], "key") != 0) {
@@ -361,12 +405,14 @@
         section = CONFIG_PARAMS;
     } else if (strcmp(tag_name, "interface_names") == 0) {
         section = INTERFACE_NAME;
+    } else if (strcmp(tag_name, "tz_names") == 0) {
+        section = TZ_NAME;
     } else if (strcmp(tag_name, "native_configs") == 0) {
         section = NATIVESUPPORT;
     } else if (strcmp(tag_name, "device") == 0) {
         if ((section != ACDB) && (section != BACKEND_NAME) && (section != BITWIDTH) &&
-            (section != INTERFACE_NAME)) {
-            ALOGE("device tag only supported for acdb/backend names/bitwitdh/interface names");
+            (section != INTERFACE_NAME) && (section != TZ_NAME)) {
+            ALOGE("device tag only supported for acdb/backend names/bitwitdh/interface/tz names");
             return;
         }
 
diff --git a/hal/voice.c b/hal/voice.c
index b1532f6..4824d35 100644
--- a/hal/voice.c
+++ b/hal/voice.c
@@ -22,6 +22,7 @@
 #define LOG_NDDEBUG 0
 
 #include <errno.h>
+#include <stdlib.h>
 #include <math.h>
 #include <cutils/log.h>
 #include <cutils/str_parms.h>
diff --git a/hal/voice_extn/compress_voip.c b/hal/voice_extn/compress_voip.c
index f7c99c5..1dcf865 100644
--- a/hal/voice_extn/compress_voip.c
+++ b/hal/voice_extn/compress_voip.c
@@ -703,10 +703,10 @@
 bool voice_extn_compress_voip_is_format_supported(audio_format_t format)
 {
     if (format == AUDIO_FORMAT_PCM_16_BIT &&
-	voice_extn_compress_voip_pcm_prop_check())
-	return true;
+       voice_extn_compress_voip_pcm_prop_check())
+       return true;
     else
-	return false;
+       return false;
 }
 
 bool voice_extn_compress_voip_is_config_supported(struct audio_config *config)
diff --git a/policy_hal/AudioPolicyManager.cpp b/policy_hal/AudioPolicyManager.cpp
index 4b471e8..e48de6d 100644
--- a/policy_hal/AudioPolicyManager.cpp
+++ b/policy_hal/AudioPolicyManager.cpp
@@ -2005,6 +2005,32 @@
     return status;
 }
 
+void AudioPolicyManagerCustom::closeAllInputs() {
+    bool patchRemoved = false;
+
+    for(size_t input_index = mInputs.size(); input_index > 0; input_index--) {
+        sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(input_index-1);
+        ssize_t patch_index = mAudioPatches.indexOfKey(inputDesc->mPatchHandle);
+        if (patch_index >= 0) {
+            sp<AudioPatch> patchDesc = mAudioPatches.valueAt(patch_index);
+            status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
+            mAudioPatches.removeItemsAt(patch_index);
+            patchRemoved = true;
+        }
+        if ((inputDesc->mIsSoundTrigger) && (mInputs.size() == 1)) {
+            ALOGD("Do not close sound trigger input handle");
+        } else {
+            mpClientInterface->closeInput(mInputs.keyAt(input_index-1));
+            mInputs.removeItem(mInputs.keyAt(input_index-1));
+        }
+    }
+    nextAudioPortGeneration();
+
+    if (patchRemoved) {
+        mpClientInterface->onAudioPatchListUpdate();
+    }
+}
+
 AudioPolicyManagerCustom::AudioPolicyManagerCustom(AudioPolicyClientInterface *clientInterface)
     : AudioPolicyManager(clientInterface),
       mHdmiAudioDisabled(false),
diff --git a/policy_hal/AudioPolicyManager.h b/policy_hal/AudioPolicyManager.h
index a7f88e4..55d59ac 100644
--- a/policy_hal/AudioPolicyManager.h
+++ b/policy_hal/AudioPolicyManager.h
@@ -75,6 +75,9 @@
         // indicates to the audio policy manager that the input stops being used.
         virtual status_t stopInput(audio_io_handle_t input,
                                    audio_session_t session);
+
+        virtual void closeAllInputs();
+
 protected:
 
          status_t checkAndSetVolume(audio_stream_type_t stream,
diff --git a/post_proc/bundle.c b/post_proc/bundle.c
index 1449eb4..2bc7fad 100644
--- a/post_proc/bundle.c
+++ b/post_proc/bundle.c
@@ -936,7 +936,6 @@
             add_effect_to_output(out_ctxt, context);
 
         } break;
-
 #ifdef HW_ACCELERATED_EFFECTS
     case EFFECT_CMD_HW_ACC: {
         ALOGV("EFFECT_CMD_HW_ACC cmdSize %d pCmdData %p, *replySize %d, pReplyData %p",
diff --git a/post_proc/bundle.h b/post_proc/bundle.h
index 06da991..efe69ee 100644
--- a/post_proc/bundle.h
+++ b/post_proc/bundle.h
@@ -27,7 +27,9 @@
 /* Retry for delay for mixer open */
 #define RETRY_NUMBER 10
 #define RETRY_US 500000
-
+#ifdef HW_ACCELERATED_EFFECTS
+#define EFFECT_CMD_HW_ACC 20
+#endif
 #define MIXER_CARD 0
 #define SOUND_CARD 0
 
diff --git a/post_proc/effect_api.c b/post_proc/effect_api.c
index 16c370b..ab8576f 100644
--- a/post_proc/effect_api.c
+++ b/post_proc/effect_api.c
@@ -61,7 +61,7 @@
 #include <sound/audio_effects.h>
 #include <sound/devdep_params.h>
 #include <linux/msm_audio.h>
-
+#include <errno.h>
 #include "effect_api.h"
 
 #ifdef DTS_EAGLE
@@ -111,11 +111,11 @@
     *mixer = mixer_open(card);
     if (!(*mixer)) {
         ALOGE("Failed to open mixer");
-        ctl = NULL;
+        *ctl = NULL;
         return -EINVAL;
     } else {
         *ctl = mixer_get_ctl_by_name(*mixer, mixer_string);
-        if (!(*ctl)) {
+        if (!*ctl) {
             ALOGE("mixer_get_ctl_by_name failed");
             mixer_close(*mixer);
             *mixer = NULL;
diff --git a/post_proc/effect_util.c b/post_proc/effect_util.c
index 52f623d..02911c1 100644
--- a/post_proc/effect_util.c
+++ b/post_proc/effect_util.c
@@ -18,6 +18,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include "effect_util.h"
+#include <string.h>
 
 #ifdef LOG_TAG
 #undef LOG_TAG
diff --git a/voice_processing/voice_processing.c b/voice_processing/voice_processing.c
index 72e4d84..1e1e123 100644
--- a/voice_processing/voice_processing.c
+++ b/voice_processing/voice_processing.c
@@ -18,6 +18,7 @@
 /*#define LOG_NDEBUG 0*/
 #include <stdlib.h>
 #include <dlfcn.h>
+#include <stdlib.h>
 #include <cutils/log.h>
 #include <cutils/list.h>
 #include <hardware/audio_effect.h>