hal: add hostless disable upon deinit

Add adev hostless session disable upon
ext hw plugin driver deinitialization.

Change-Id: Icbaac82e951a7e2826bcad17b42bcc2c85ec3cce
diff --git a/hal/audio_extn/ext_hw_plugin.c b/hal/audio_extn/ext_hw_plugin.c
index 1336ae8..a24f5c6 100644
--- a/hal/audio_extn/ext_hw_plugin.c
+++ b/hal/audio_extn/ext_hw_plugin.c
@@ -47,6 +47,11 @@
 typedef int32_t (*audio_hal_plugin_send_msg_t)(audio_hal_plugin_msg_type_t,
                                            void *, uint32_t);
 
+struct hostless_module {
+    struct pcm *pcm_tx;
+    struct pcm *pcm_rx;
+};
+
 struct ext_hw_plugin_data {
     struct audio_device           *adev;
     void                          *plugin_handle;
@@ -57,23 +62,32 @@
     snd_device_t                   out_snd_dev[AUDIO_HAL_PLUGIN_USECASE_MAX];
     snd_device_t                   in_snd_dev[AUDIO_HAL_PLUGIN_USECASE_MAX];
     bool                           mic_mute;
+    struct hostless_module         adev_hostless;
 };
 
 /* 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)
+/* 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(void *plugin)
 {
+    struct ext_hw_plugin_data *my_plugin =
+        (struct ext_hw_plugin_data *)plugin;
+    char mixer_path[MIXER_PATH_MAX_LENGTH];
+
     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);
+    if (audio_route_apply_and_update_path(my_plugin->adev->audio_route,
+            mixer_path)) {
+        ALOGE("%s: %s not supported, continue", __func__, mixer_path);
+        return;
+    }
 
     /* TERT TDM TX 7 HOSTLESS to SEC TDM RX 7 HOSTLESS */
     int pcm_dev_rx = 48, pcm_dev_tx = 49;
@@ -88,31 +102,51 @@
         .avail_min = 0,
     };
 
-    struct pcm *pcm_tx = pcm_open(adev->snd_card,
+    my_plugin->adev_hostless.pcm_tx = pcm_open(my_plugin->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));
+    if (my_plugin->adev_hostless.pcm_tx &&
+        !pcm_is_ready(my_plugin->adev_hostless.pcm_tx)) {
+        ALOGE("%s: %s", __func__,
+            pcm_get_error(my_plugin->adev_hostless.pcm_tx));
         return;
     }
-    struct pcm *pcm_rx = pcm_open(adev->snd_card,
+    my_plugin->adev_hostless.pcm_rx = pcm_open(my_plugin->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));
+    if (my_plugin->adev_hostless.pcm_rx &&
+        !pcm_is_ready(my_plugin->adev_hostless.pcm_rx)) {
+        ALOGE("%s: %s", __func__,
+            pcm_get_error(my_plugin->adev_hostless.pcm_rx));
         return;
     }
 
-    if (pcm_start(pcm_tx) < 0) {
+    if (pcm_start(my_plugin->adev_hostless.pcm_tx) < 0) {
         ALOGE("%s: pcm start for pcm tx failed", __func__);
         return;
     }
-    if (pcm_start(pcm_rx) < 0) {
+    if (pcm_start(my_plugin->adev_hostless.pcm_rx) < 0) {
         ALOGE("%s: pcm start for pcm rx failed", __func__);
         return;
     }
 }
 
+static void audio_extn_ext_hw_plugin_disable_adev_hostless(void *plugin)
+{
+    struct ext_hw_plugin_data *my_plugin = (struct ext_hw_plugin_data *)plugin;
+
+    ALOGI("%s: Disable TERT -> SEC Hostless", __func__);
+
+    if (my_plugin->adev_hostless.pcm_tx) {
+        pcm_close(my_plugin->adev_hostless.pcm_tx);
+        my_plugin->adev_hostless.pcm_tx = NULL;
+    }
+    if (my_plugin->adev_hostless.pcm_rx) {
+        pcm_close(my_plugin->adev_hostless.pcm_rx);
+        my_plugin->adev_hostless.pcm_rx = NULL;
+    }
+}
+
 void* audio_extn_ext_hw_plugin_init(struct audio_device *adev)
 {
     int32_t ret = 0;
@@ -165,7 +199,7 @@
         }
     }
 
-    audio_extn_ext_hw_plugin_enable_adev_hostless(adev);
+    audio_extn_ext_hw_plugin_enable_adev_hostless(my_plugin);
 
     my_plugin->mic_mute = false;
     return my_plugin;
@@ -187,6 +221,8 @@
         return -EINVAL;
     }
 
+    audio_extn_ext_hw_plugin_disable_adev_hostless(my_plugin);
+
     if (my_plugin->audio_hal_plugin_deinit) {
         ret = my_plugin->audio_hal_plugin_deinit();
         if (ret) {