hal: enable TERT TDM TX to SEC RX hostless
Enable TERT TDM TX to SEC TDM RX hostless
loopback upon ext hw plugin init to provide
TDM CLK and SYNC for external codec.
Change-Id: Ic9aff5000b3afe7593c4779b8bd18ae63464aee0
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;