hal: support calibration for hfp with dual asm loopback

Add support TX and RX calibration for HFP call
on both uplink and downlink ASM loopback path.

Change-Id: I66dec9ec01e0645ba6f5c21a4e64aabd10e2b6a5
Signed-off-by: Derek Chen <chenche@codeaurora.org>
Signed-off-by: Guodong Hu <guodhu@codeaurora.org>
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index a29b6e5..b25fe3c 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -832,6 +832,25 @@
     return adev->vr_audio_mode_enabled;
 }
 
+static void audio_extn_btsco_get_sample_rate(int snd_device, int *sample_rate)
+{
+    switch (snd_device) {
+    case SND_DEVICE_OUT_BT_SCO:
+    case SND_DEVICE_IN_BT_SCO_MIC:
+    case SND_DEVICE_IN_BT_SCO_MIC_NREC:
+        *sample_rate = 8000;
+        break;
+    case SND_DEVICE_OUT_BT_SCO_WB:
+    case SND_DEVICE_IN_BT_SCO_MIC_WB:
+    case SND_DEVICE_IN_BT_SCO_MIC_WB_NREC:
+        *sample_rate = 16000;
+        break;
+    default:
+        ALOGD("%s:Not a BT SCO device, need not update sampling rate\n", __func__);
+        break;
+    }
+}
+
 void audio_extn_utils_update_stream_app_type_cfg_for_usecase(
                                     struct audio_device *adev,
                                     struct audio_usecase *usecase)
@@ -880,31 +899,46 @@
                                                 &usecase->stream.inout->out_app_type_cfg);
         ALOGV("%s Selected apptype: %d", __func__, usecase->stream.inout->out_app_type_cfg.app_type);
         break;
+    case PCM_HFP_CALL:
+        switch (usecase->id) {
+        case USECASE_AUDIO_HFP_SCO:
+        case USECASE_AUDIO_HFP_SCO_WB:
+            audio_extn_btsco_get_sample_rate(usecase->out_snd_device,
+                                             &usecase->out_app_type_cfg.sample_rate);
+            usecase->in_app_type_cfg.sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+            break;
+        case USECASE_AUDIO_HFP_SCO_DOWNLINK:
+        case USECASE_AUDIO_HFP_SCO_WB_DOWNLINK:
+            audio_extn_btsco_get_sample_rate(usecase->in_snd_device,
+                                             &usecase->in_app_type_cfg.sample_rate);
+            usecase->out_app_type_cfg.sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+            break;
+        default:
+            ALOGE("%s: usecase id (%d) not supported, use default sample rate",
+                __func__, usecase->id);
+            usecase->in_app_type_cfg.sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+            usecase->out_app_type_cfg.sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+            break;
+        }
+        /* update out_app_type_cfg */
+        usecase->out_app_type_cfg.bit_width =
+                                platform_get_snd_device_bit_width(usecase->out_snd_device);
+        usecase->out_app_type_cfg.app_type =
+                                platform_get_default_app_type_v2(adev->platform, PCM_PLAYBACK);
+        /* update in_app_type_cfg */
+        usecase->in_app_type_cfg.bit_width =
+                                platform_get_snd_device_bit_width(usecase->in_snd_device);
+        usecase->in_app_type_cfg.app_type =
+                                platform_get_default_app_type_v2(adev->platform, PCM_CAPTURE);
+        ALOGV("%s Selected apptype: playback %d capture %d",
+            __func__, usecase->out_app_type_cfg.app_type, usecase->in_app_type_cfg.app_type);
+        break;
     default:
         ALOGE("%s: app type cfg not supported for usecase type (%d)",
             __func__, usecase->type);
     }
 }
 
-void audio_extn_btsco_get_sample_rate(int snd_device, int *sample_rate)
-{
-    switch (snd_device) {
-    case SND_DEVICE_OUT_BT_SCO:
-    case SND_DEVICE_IN_BT_SCO_MIC:
-    case SND_DEVICE_IN_BT_SCO_MIC_NREC:
-        *sample_rate = 8000;
-        break;
-    case SND_DEVICE_OUT_BT_SCO_WB:
-    case SND_DEVICE_IN_BT_SCO_MIC_WB:
-    case SND_DEVICE_IN_BT_SCO_MIC_WB_NREC:
-        *sample_rate = 16000;
-        break;
-    default:
-        ALOGD("%s:Not a BT SCO device, need not update sampling rate\n", __func__);
-        break;
-    }
-}
-
 static int set_stream_app_type_mixer_ctrl(struct audio_device *adev,
                                           int pcm_device_id, int app_type,
                                           int acdb_dev_id, int sample_rate,
@@ -955,21 +989,27 @@
     int pcm_device_id, acdb_dev_id = 0, snd_device = usecase->out_snd_device;
     int32_t sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
     int app_type = 0, rc = 0;
+    bool is_bus_dev_usecase = false;
 
     ALOGV("%s", __func__);
 
     if (usecase->type != PCM_HFP_CALL) {
-        ALOGV("%s: not a playback or HFP path, no need to cfg app type", __func__);
+        ALOGV("%s: not a HFP path, no need to cfg app type", __func__);
         rc = 0;
         goto exit_send_app_type_cfg;
     }
     if ((usecase->id != USECASE_AUDIO_HFP_SCO) &&
-        (usecase->id != USECASE_AUDIO_HFP_SCO_WB)) {
-        ALOGV("%s: a playback path where app type cfg is not required", __func__);
+        (usecase->id != USECASE_AUDIO_HFP_SCO_WB) &&
+        (usecase->id != USECASE_AUDIO_HFP_SCO_DOWNLINK) &&
+        (usecase->id != USECASE_AUDIO_HFP_SCO_WB_DOWNLINK)) {
+        ALOGV("%s: a usecase where app type cfg is not required", __func__);
         rc = 0;
         goto exit_send_app_type_cfg;
     }
 
+    if (usecase->devices & AUDIO_DEVICE_OUT_BUS)
+        is_bus_dev_usecase = true;
+
     snd_device = usecase->out_snd_device;
     pcm_device_id = platform_get_pcm_device_id(usecase->id, PCM_PLAYBACK);
 
@@ -983,24 +1023,47 @@
     if (usecase->type == PCM_HFP_CALL) {
 
         /* config HFP session:1 playback path */
-        app_type = platform_get_default_app_type_v2(adev->platform, PCM_PLAYBACK);
-        sample_rate= CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+        if (is_bus_dev_usecase) {
+            app_type = usecase->out_app_type_cfg.app_type;
+            sample_rate= usecase->out_app_type_cfg.sample_rate;
+        } else {
+            snd_device = SND_DEVICE_NONE; // use legacy behavior
+            app_type = platform_get_default_app_type_v2(adev->platform, PCM_PLAYBACK);
+            sample_rate= CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+        }
         rc = set_stream_app_type_mixer_ctrl(adev, pcm_device_id, app_type,
                                             acdb_dev_id, sample_rate,
                                             PCM_PLAYBACK,
-                                            SND_DEVICE_NONE); // use legacy behavior
+                                            snd_device);
         if (rc < 0)
             goto exit_send_app_type_cfg;
 
         /* config HFP session:1 capture path */
-        app_type = platform_get_default_app_type_v2(adev->platform, PCM_CAPTURE);
+        if (is_bus_dev_usecase) {
+            snd_device = usecase->in_snd_device;
+            pcm_device_id = platform_get_pcm_device_id(usecase->id, PCM_CAPTURE);
+            acdb_dev_id = platform_get_snd_device_acdb_id(snd_device);
+            if (acdb_dev_id < 0) {
+                ALOGE("%s: Couldn't get the acdb dev id", __func__);
+                rc = -EINVAL;
+                goto exit_send_app_type_cfg;
+            }
+            app_type = usecase->in_app_type_cfg.app_type;
+            sample_rate= usecase->in_app_type_cfg.sample_rate;
+        } else {
+            snd_device = SND_DEVICE_NONE; // use legacy behavior
+            app_type = platform_get_default_app_type_v2(adev->platform, PCM_CAPTURE);
+        }
         rc = set_stream_app_type_mixer_ctrl(adev, pcm_device_id, app_type,
                                             acdb_dev_id, sample_rate,
                                             PCM_CAPTURE,
-                                            SND_DEVICE_NONE);
+                                            snd_device);
         if (rc < 0)
             goto exit_send_app_type_cfg;
 
+        if (is_bus_dev_usecase)
+            goto exit_send_app_type_cfg;
+
         /* config HFP session:2 capture path */
         pcm_device_id = HFP_ASM_RX_TX;
         snd_device = usecase->in_snd_device;