hal: add DSDA support on APQ targets

-This change adds DSDA support for APQ based targets
 where external modem is used for voice calls.
-Add new CSD API to support local call hold.

Change-Id: I7743a1df43dc1abac4e325ff104ec1bb64c9e12b
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index d10566d..bd1b235 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -628,6 +628,8 @@
 {
     snd_device_t out_snd_device = SND_DEVICE_NONE;
     snd_device_t in_snd_device = SND_DEVICE_NONE;
+    snd_device_t prev_out_snd_device = SND_DEVICE_NONE;
+    snd_device_t prev_in_snd_device = SND_DEVICE_NONE;
     struct audio_usecase *usecase = NULL;
     struct audio_usecase *vc_usecase = NULL;
     struct audio_usecase *voip_usecase = NULL;
@@ -723,7 +725,9 @@
      * and enable both RX and TX devices though one of them is same as current
      * device.
      */
-    if (usecase->type == VOICE_CALL || usecase->type == VOIP_CALL) {
+    if ((usecase->type == VOICE_CALL) &&
+        (usecase->in_snd_device != SND_DEVICE_NONE) &&
+        (usecase->out_snd_device != SND_DEVICE_NONE)) {
         status = platform_switch_voice_call_device_pre(adev->platform);
     }
 
@@ -742,10 +746,13 @@
      * New device information should be sent to modem before enabling
      * the devices to reduce in-call device switch time.
      */
-    if (usecase->type == VOICE_CALL)
+    if ((usecase->type == VOICE_CALL) &&
+        (usecase->in_snd_device != SND_DEVICE_NONE) &&
+        (usecase->out_snd_device != SND_DEVICE_NONE)) {
         status = platform_switch_voice_call_enable_device_config(adev->platform,
                                                                  out_snd_device,
                                                                  in_snd_device);
+    }
 
     /* Enable new sound devices */
     if (out_snd_device != SND_DEVICE_NONE) {
@@ -764,6 +771,12 @@
                                                         out_snd_device,
                                                         in_snd_device);
 
+    /* Cache the current usecase devices. This is required to avoid
+     * sending device enable command to the external modem.
+     */
+    prev_in_snd_device = usecase->in_snd_device;
+    prev_out_snd_device = usecase->out_snd_device;
+
     usecase->in_snd_device = in_snd_device;
     usecase->out_snd_device = out_snd_device;
 
@@ -773,10 +786,13 @@
      * Enable device command should be sent to modem only after
      * enabling voice call mixer controls
      */
-    if (usecase->type == VOICE_CALL)
+    if ((usecase->type == VOICE_CALL) &&
+        (prev_in_snd_device != SND_DEVICE_NONE) &&
+        (prev_out_snd_device != SND_DEVICE_NONE)) {
         status = platform_switch_voice_call_usecase_route_post(adev->platform,
                                                                out_snd_device,
                                                                in_snd_device);
+    }
 
     ALOGD("%s: done",__func__);