hal: Add support for In-Car Communication usecase

* Add ICC library functionality in icc.c
* Add support in audio_extn to open and initialize icc library
* Add platform changes for device selection in ICC usecase
* Add support for sending ICC audio calibration/app type cfg

Suggested-by: Tahir Dawson <dawson@qti.qualcomm.com>
Change-Id: I26937da282fcdd31d59a54b180dca5d7740fbfb0
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index 66d7441..366fc85 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -981,6 +981,20 @@
         ALOGV("%s Selected apptype: playback %d capture %d",
             __func__, usecase->out_app_type_cfg.app_type, usecase->in_app_type_cfg.app_type);
         break;
+    case ICC_CALL:
+        /* ICC usecase: Loopback from TERT_TDM_TX to TERT_TDM_RX */
+        /* update out_app_type_cfg */
+        usecase->out_app_type_cfg.sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+        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.sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+        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);
@@ -1142,6 +1156,64 @@
     return rc;
 }
 
+int audio_extn_utils_send_app_type_cfg_icc(struct audio_device *adev,
+                                       struct audio_usecase *usecase)
+{
+    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;
+
+    ALOGV("%s", __func__);
+
+    if (usecase->type != ICC_CALL) {
+        ALOGV("%s: not an ICC path, no need to cfg app type", __func__);
+        rc = 0;
+        goto exit_send_app_type_cfg;
+    }
+    if (usecase->id != USECASE_ICC_CALL) {
+        ALOGV("%s: a usecase where app type cfg is not required", __func__);
+        rc = 0;
+        goto exit_send_app_type_cfg;
+    }
+
+    snd_device = usecase->out_snd_device;
+    pcm_device_id = platform_get_pcm_device_id(usecase->id, PCM_PLAYBACK);
+    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;
+    }
+    /* config ICC session: playback path */
+    app_type = usecase->out_app_type_cfg.app_type;
+    sample_rate= usecase->out_app_type_cfg.sample_rate;
+
+    rc = set_stream_app_type_mixer_ctrl(adev, pcm_device_id, app_type,
+                                        acdb_dev_id, sample_rate,
+                                        PCM_PLAYBACK,
+                                        snd_device);
+    if (rc < 0)
+        goto exit_send_app_type_cfg;
+
+    /* config ICC session: capture path */
+    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;
+    rc = set_stream_app_type_mixer_ctrl(adev, pcm_device_id, app_type,
+                                        acdb_dev_id, sample_rate,
+                                        PCM_CAPTURE,
+                                        snd_device);
+exit_send_app_type_cfg:
+    return rc;
+}
+
 int audio_extn_utils_get_app_sample_rate_for_device(
                               struct audio_device *adev,
                               struct audio_usecase *usecase, int snd_device)
@@ -1487,6 +1559,8 @@
 
     if (usecase->type == PCM_HFP_CALL) {
         return audio_extn_utils_send_app_type_cfg_hfp(adev, usecase);
+    } else if (usecase->type == ICC_CALL) {
+        return audio_extn_utils_send_app_type_cfg_icc(adev, usecase);
     }
 
     switch (usecase->type) {
@@ -1888,7 +1962,8 @@
         platform_send_audio_calibration(adev->platform, usecase,
                          usecase->stream.in->app_type_cfg.app_type);
     } else if ((type == PCM_HFP_CALL) || (type == PCM_CAPTURE) ||
-               (type == TRANSCODE_LOOPBACK_RX && usecase->stream.inout != NULL)) {
+               (type == TRANSCODE_LOOPBACK_RX && usecase->stream.inout != NULL) ||
+               (type == ICC_CALL)) {
         platform_send_audio_calibration(adev->platform, usecase,
                          platform_get_default_app_type_v2(adev->platform, usecase->type));
     } else {