Merge "hal: enable TERT TDM TX to SEC RX hostless"
diff --git a/configs/msmnile_au/mixer_paths_adp.xml b/configs/msmnile_au/mixer_paths_adp.xml
index bcea162..e5ce0ab 100644
--- a/configs/msmnile_au/mixer_paths_adp.xml
+++ b/configs/msmnile_au/mixer_paths_adp.xml
@@ -318,6 +318,10 @@
     <ctl name="SEC_TDM_RX_0 Audio Mixer MultiMedia9" value="0" />
     <ctl name="MultiMedia9 Mixer TERT_TDM_TX_0" value="0" />
 
+    <path name="dummy-hostless">
+        <ctl name="SEC_TDM_RX_7 Port Mixer TERT_TDM_TX_7" value="1" />
+    </path>
+
     <!-- Codec controls -->
     <!-- WSA controls -->
     <ctl name="SpkrLeft COMP Switch" value="0" />
diff --git a/hal/audio_extn/ext_hw_plugin.c b/hal/audio_extn/ext_hw_plugin.c
index 6e93ac4..3c9458a 100644
--- a/hal/audio_extn/ext_hw_plugin.c
+++ b/hal/audio_extn/ext_hw_plugin.c
@@ -62,6 +62,57 @@
 /* This can be defined in platform specific file or use compile flag */
 #define LIB_PLUGIN_DRIVER "libaudiohalplugin.so"
 
+/* Note: Due to ADP H/W design, SoC TERT/SEC TDM CLK and FSYNC lines are both connected
+ * with CODEC and a single master is needed to provide consistent CLK and FSYNC to slaves,
+ * hence configuring SoC TERT TDM as single master and bring up a dummy hostless from TERT
+ * to SEC to ensure both slave SoC SEC TDM and CODEC are driven upon system boot. */
+static void audio_extn_ext_hw_plugin_enable_adev_hostless(struct audio_device *adev)
+{
+    ALOGI("%s: Enable TERT -> SEC Hostless", __func__);
+
+    char mixer_path[MIXER_PATH_MAX_LENGTH];
+    strlcpy(mixer_path, "dummy-hostless", MIXER_PATH_MAX_LENGTH);
+    ALOGD("%s: apply mixer and update path: %s", __func__, mixer_path);
+    audio_route_apply_and_update_path(adev->audio_route, mixer_path);
+
+    /* TERT TDM TX 7 HOSTLESS to SEC TDM RX 7 HOSTLESS */
+    int pcm_dev_rx = 48, pcm_dev_tx = 49;
+    struct pcm_config pcm_config_lb = {
+        .channels = 1,
+        .rate = 48000,
+        .period_size = 240,
+        .period_count = 2,
+        .format = PCM_FORMAT_S16_LE,
+        .start_threshold = 0,
+        .stop_threshold = INT_MAX,
+        .avail_min = 0,
+    };
+
+    struct pcm *pcm_tx = pcm_open(adev->snd_card,
+                                   pcm_dev_tx,
+                                   PCM_IN, &pcm_config_lb);
+    if (pcm_tx && !pcm_is_ready(pcm_tx)) {
+        ALOGE("%s: %s", __func__, pcm_get_error(pcm_tx));
+        return;
+    }
+    struct pcm *pcm_rx = pcm_open(adev->snd_card,
+                                   pcm_dev_rx,
+                                   PCM_OUT, &pcm_config_lb);
+    if (pcm_rx && !pcm_is_ready(pcm_rx)) {
+        ALOGE("%s: %s", __func__, pcm_get_error(pcm_rx));
+        return;
+    }
+
+    if (pcm_start(pcm_tx) < 0) {
+        ALOGE("%s: pcm start for pcm tx failed", __func__);
+        return;
+    }
+    if (pcm_start(pcm_rx) < 0) {
+        ALOGE("%s: pcm start for pcm rx failed", __func__);
+        return;
+    }
+}
+
 void* audio_extn_ext_hw_plugin_init(struct audio_device *adev)
 {
     int32_t ret = 0;
@@ -114,6 +165,8 @@
         }
     }
 
+    audio_extn_ext_hw_plugin_enable_adev_hostless(adev);
+
     my_plugin->mic_mute = false;
     return my_plugin;