audio: hal: Fix for DTSHD passthrough playback

-DTSHD passthrough is not working when drift correction is enabled.
-Drift correction enablement calls out_write(0) to start compress
 session. However DTSHD iec61937 transmission info parsing fails due
 to size zero write buffer.
-To fix this added
  -Changes to call dts parser when first valid buffer is enabled.
  -Changes to trigger select_device() to update backend configuration.
-Also added mixer path change to configure default HDMI backend
 configuration

Change-Id: I68b2c79ff008a7d081efa475c8b9782072f5ce03
diff --git a/configs/msm8998/mixer_paths_tasha.xml b/configs/msm8998/mixer_paths_tasha.xml
index a7dfbeb..93656e6 100644
--- a/configs/msm8998/mixer_paths_tasha.xml
+++ b/configs/msm8998/mixer_paths_tasha.xml
@@ -125,6 +125,10 @@
     <ctl name="MultiMedia1 Mixer SLIM_0_TX" value="0" />
     <ctl name="MultiMedia1 Mixer SLIM_4_TX" value="0" />
     <ctl name="MultiMedia1 Mixer SLIM_7_TX" value="0" />
+    <ctl name="HDMI RX Format" value="LPCM" />
+    <ctl name="HDMI_RX Bit Format" value="S16_LE" />
+    <ctl name="HDMI_RX SampleRate" value="KHZ_48" />
+    <ctl name="HDMI_RX Channels" value="Two" />
     <ctl name="HDMI Mixer MultiMedia1" value="0" />
     <ctl name="HDMI Mixer MultiMedia2" value="0" />
     <ctl name="HDMI Mixer MultiMedia3" value="0" />
@@ -139,6 +143,10 @@
     <ctl name="HDMI Mixer MultiMedia14" value="0" />
     <ctl name="HDMI Mixer MultiMedia15" value="0" />
     <ctl name="HDMI Mixer MultiMedia16" value="0" />
+    <ctl name="Display Port RX Format" value="LPCM" />
+    <ctl name="Display Port RX Bit Format" value="S16_LE" />
+    <ctl name="Display Port RX SampleRate" value="KHZ_48" />
+    <ctl name="Display Port RX Channels" value="Two" />
     <ctl name="DISPLAY_PORT Mixer MultiMedia1" value="0" />
     <ctl name="DISPLAY_PORT Mixer MultiMedia2" value="0" />
     <ctl name="DISPLAY_PORT Mixer MultiMedia3" value="0" />
diff --git a/configs/msm8998/mixer_paths_tavil.xml b/configs/msm8998/mixer_paths_tavil.xml
index def9580..ba37799 100644
--- a/configs/msm8998/mixer_paths_tavil.xml
+++ b/configs/msm8998/mixer_paths_tavil.xml
@@ -72,6 +72,10 @@
     <ctl name="MultiMedia8 Mixer SLIM_0_TX" value="0" />
     <ctl name="MultiMedia8 Mixer SLIM_4_TX" value="0" />
     <ctl name="MultiMedia8 Mixer SLIM_7_TX" value="0" />
+    <ctl name="HDMI RX Format" value="LPCM" />
+    <ctl name="HDMI_RX Bit Format" value="S16_LE" />
+    <ctl name="HDMI_RX SampleRate" value="KHZ_48" />
+    <ctl name="HDMI_RX Channels" value="Two" />
     <ctl name="HDMI Mixer MultiMedia1" value="0" />
     <ctl name="HDMI Mixer MultiMedia2" value="0" />
     <ctl name="HDMI Mixer MultiMedia3" value="0" />
@@ -86,6 +90,10 @@
     <ctl name="HDMI Mixer MultiMedia14" value="0" />
     <ctl name="HDMI Mixer MultiMedia15" value="0" />
     <ctl name="HDMI Mixer MultiMedia16" value="0" />
+    <ctl name="Display Port RX Format" value="LPCM" />
+    <ctl name="Display Port RX Bit Format" value="S16_LE" />
+    <ctl name="Display Port RX SampleRate" value="KHZ_48" />
+    <ctl name="Display Port RX Channels" value="Two" />
     <ctl name="DISPLAY_PORT Mixer MultiMedia1" value="0" />
     <ctl name="DISPLAY_PORT Mixer MultiMedia2" value="0" />
     <ctl name="DISPLAY_PORT Mixer MultiMedia3" value="0" />
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index 76874c0..1b3c5bb 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -516,6 +516,7 @@
 #define audio_extn_passthru_init(a) do {} while(0)
 #define audio_extn_passthru_should_standby(o) (1)
 #define audio_extn_passthru_get_channel_count(out) (0)
+#define audio_extn_passthru_update_dts_stream_configuration(out, buffer, bytes) (-ENOSYS)
 #else
 bool audio_extn_passthru_is_convert_supported(struct audio_device *adev,
                                                  struct stream_out *out);
@@ -540,6 +541,8 @@
 void audio_extn_passthru_init(struct audio_device *adev);
 bool audio_extn_passthru_should_standby(struct stream_out *out);
 int audio_extn_passthru_get_channel_count(struct stream_out *out);
+int audio_extn_passthru_update_dts_stream_configuration(struct stream_out *out,
+        const void *buffer, size_t bytes);
 #endif
 
 #ifndef HFP_ENABLED
diff --git a/hal/audio_extn/passthru.c b/hal/audio_extn/passthru.c
index f0cae69..e106ef9 100644
--- a/hal/audio_extn/passthru.c
+++ b/hal/audio_extn/passthru.c
@@ -90,7 +90,7 @@
 static volatile int32_t compress_passthru_active;
 
 #ifdef DTSHD_PARSER_ENABLED
-static void passthru_update_stream_configuration_from_dts_parser( struct stream_out *out,
+int audio_extn_passthru_update_dts_stream_configuration(struct stream_out *out,
         const void *buffer, size_t bytes)
 {
     struct audio_parser_codec_info codec_info;
@@ -100,6 +100,27 @@
     bool is_valid_transmission_rate = false;
     bool is_valid_transmission_channels = false;
 
+    if (!out) {
+        ALOGE("Invalid session");
+        return -EINVAL;
+    }
+
+    if ((out->format != AUDIO_FORMAT_DTS) &&
+        (out->format != AUDIO_FORMAT_DTS_HD)) {
+        ALOGE("Non DTS format %d", out->format);
+        return -EINVAL;
+    }
+
+    if (!buffer || bytes <= 0) {
+        ALOGD("Invalid buffer %p size %d skipping dts stream conf update",
+                buffer, bytes);
+        out->sample_rate = 48000;
+        out->compr_config.codec->sample_rate = out->sample_rate;
+        out->compr_config.codec->ch_in = 2;
+        out->channel_mask = audio_channel_out_mask_from_count(2);
+        return -EINVAL;
+    }
+
     /* codec format is AUDIO_PARSER_CODEC_DTSHD for both DTS and DTSHD as
      *  DTSHD parser can support both DTS and DTSHD
      */
@@ -147,14 +168,15 @@
         out->compr_config.codec->ch_in = 2;
         out->channel_mask = audio_channel_out_mask_from_count(2);
     }
+    return 0;
 }
 #else
-static void passthru_update_stream_configuration_from_dts_parser(
+int audio_extn_passthru_update_dts_stream_configuration(
                         struct stream_out *out __unused,
                         const void *buffer __unused,
                         size_t bytes __unused)
 {
-    return;
+    return -ENOSYS;
 }
 #endif
 
@@ -406,15 +428,6 @@
         ALOGV("%s:NO PASSTHROUGH", __func__);
         out->compr_config.codec->compr_passthr = LEGACY_PCM;
     }
-
-    /*
-     * for DTS passthrough, need to get sample rate from bitstream,
-     * based on this sample rate hdmi backend will be configured
-     */
-    if ((out->format == AUDIO_FORMAT_DTS) ||
-        (out->format == AUDIO_FORMAT_DTS_HD))
-        passthru_update_stream_configuration_from_dts_parser(out, buffer, bytes);
-
 }
 
 bool audio_extn_passthru_is_passthrough_stream(struct stream_out *out)
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index c5e0dbe..926a63f 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -1645,6 +1645,10 @@
          ret = true;
      }
 
+     if (usecase->stream.out->stream_config_changed) {
+         ALOGD("Force stream_config_changed to update iec61937 transmission config");
+         return true;
+     }
     return ret;
 }
 
@@ -3739,6 +3743,29 @@
             audio_extn_passthru_update_stream_configuration(adev, out,
                     buffer, bytes);
             out->is_iec61937_info_available = true;
+
+            if((out->format == AUDIO_FORMAT_DTS) ||
+               (out->format == AUDIO_FORMAT_DTS_HD)) {
+                ret = audio_extn_passthru_update_dts_stream_configuration(out,
+                                                                buffer, bytes);
+                if (ret) {
+                    if (ret != -ENOSYS) {
+                        out->is_iec61937_info_available = false;
+                        ALOGD("iec61937 transmission info not yet updated retry");
+                    }
+                } else {
+                    /* if stream has started and after that there is
+                     * stream config change (iec transmission config)
+                     * then trigger select_device to update backend configuration.
+                     */
+                    out->stream_config_changed = true;
+                    pthread_mutex_lock(&adev->lock);
+                    select_devices(adev, out->usecase);
+                    pthread_mutex_unlock(&adev->lock);
+                    out->stream_config_changed = false;
+                    out->is_iec61937_info_available = true;
+                }
+            }
         }
     }
 
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index ac8a801..f0b7077 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -323,6 +323,7 @@
 
     char pm_qos_mixer_path[MAX_MIXER_PATH_LEN];
     int dynamic_pm_qos_enabled;
+    bool stream_config_changed;
     mix_matrix_params_t pan_scale_params;
     mix_matrix_params_t downmix_params;
 };