audio: hal: add DSP clock recovery support

-Changes to add DSP clock recovery support

Conflicts:
        qahw_api/test/qahw_playback_test.c
	    hal/audio_extn/utils.c

CRs-Fixed: 2036937
Change-Id: I32e18e415c4a7dfdc7ae13d0e50c1ca76d739cc0
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index a2dff9f..0331fc4 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -1609,36 +1609,39 @@
 {
     int ret = 0, count = 0;
     char avt_device_drift_mixer_ctl_name[MIXER_PATH_MAX_LENGTH] = {0};
+    const char *backend = NULL;
     struct mixer_ctl *ctl = NULL;
     struct audio_avt_device_drift_stats drift_stats;
     struct audio_device *adev = NULL;
 
     if (usecase != NULL && usecase->type == PCM_PLAYBACK) {
-        adev = usecase->stream.out->dev;
-        switch(usecase->out_snd_device) {
-            case SND_DEVICE_OUT_HDMI:
-                strlcpy(avt_device_drift_mixer_ctl_name,
-                        "HDMI RX Drift",
-                        MIXER_PATH_MAX_LENGTH);
-                break;
-            case SND_DEVICE_OUT_DISPLAY_PORT:
-                strlcpy(avt_device_drift_mixer_ctl_name,
-                        "DISPLAY Port RX Drift",
-                        MIXER_PATH_MAX_LENGTH);
-                break;
-            default :
-                ALOGE("%s: Unsupported device %d",__func__,
-                        usecase->stream.out->devices);
-                ret = -EINVAL;
+        backend = platform_get_snd_device_backend_interface(usecase->out_snd_device);
+        if (!backend) {
+            ALOGE("%s: Unsupported device %d", __func__,
+                   usecase->stream.out->devices);
+            ret = -EINVAL;
+            goto done;
+        }
+        strlcpy(avt_device_drift_mixer_ctl_name,
+                backend,
+                MIXER_PATH_MAX_LENGTH);
+
+        count = strlen(backend);
+        if (MIXER_PATH_MAX_LENGTH - count > 0) {
+            strlcat(&avt_device_drift_mixer_ctl_name[count],
+                    " DRIFT",
+                    MIXER_PATH_MAX_LENGTH - count);
+        } else {
+            ret = -EINVAL;
+            goto done;
         }
     } else {
         ALOGE("%s: Invalid usecase",__func__);
         ret = -EINVAL;
+        goto done;
     }
 
-    if(ret)
-        goto done;
-
+    adev = usecase->stream.out->dev;
     ctl = mixer_get_ctl_by_name(adev->mixer, avt_device_drift_mixer_ctl_name);
     if (!ctl) {
         ALOGE("%s: Could not get ctl for mixer cmd - %s",
@@ -1849,11 +1852,8 @@
         goto exit;
     }
 
-    if ((out->render_mode == RENDER_MODE_AUDIO_MASTER) ||
-        (out->render_mode == RENDER_MODE_AUDIO_STC_MASTER)) {
-        memcpy(&out->render_window, render_window,
-               sizeof(struct audio_out_render_window_param));
-    } else {
+    if ((out->render_mode != RENDER_MODE_AUDIO_MASTER) &&
+        (out->render_mode != RENDER_MODE_AUDIO_STC_MASTER)) {
         ALOGD("%s:: only supported in timestamp mode, current "
               "render mode mode %d", __func__, out->render_mode);
         goto exit;
@@ -1915,11 +1915,8 @@
         goto exit;
     }
 
-   if ((out->render_mode == RENDER_MODE_AUDIO_MASTER) ||
-       (out->render_mode == RENDER_MODE_AUDIO_STC_MASTER)) {
-        /* store it to reconfigure in start_output_stream() */
-        out->delay_param.start_delay = delay_param->start_delay;
-    } else {
+   if ((out->render_mode != RENDER_MODE_AUDIO_MASTER) &&
+       (out->render_mode != RENDER_MODE_AUDIO_STC_MASTER)) {
         ALOGD("%s:: only supported in timestamp mode, current "
               "render mode mode %d", __func__, out->render_mode);
         goto exit;
@@ -2016,3 +2013,104 @@
 
     return snd_card_num;
 }
+
+#ifdef SNDRV_COMPRESS_ENABLE_ADJUST_SESSION_CLOCK
+int audio_extn_utils_compress_enable_drift_correction(
+        struct stream_out *out,
+        struct audio_out_enable_drift_correction *drift)
+{
+    struct snd_compr_metadata metadata;
+    int ret = -EINVAL;
+
+    if(drift == NULL) {
+        ALOGE("%s:: Invalid param", __func__);
+        goto exit;
+    }
+
+    ALOGD("%s:: drift enable %d", __func__,drift->enable);
+
+    if (!is_offload_usecase(out->usecase)) {
+        ALOGE("%s:: not supported for non offload session", __func__);
+        goto exit;
+    }
+
+    if (!out->compr) {
+        ALOGW("%s:: offload session not yet opened,"
+                "start delay will be configure later", __func__);
+        goto exit;
+    }
+
+    metadata.key = SNDRV_COMPRESS_ENABLE_ADJUST_SESSION_CLOCK;
+    metadata.value[0] = drift->enable;
+    out->drift_correction_enabled = drift->enable;
+
+    ret = compress_set_metadata(out->compr, &metadata);
+    if(ret) {
+        ALOGE("%s::error %s", __func__, compress_get_error(out->compr));
+        out->drift_correction_enabled = false;
+    }
+
+exit:
+    return ret;
+}
+#else
+int audio_extn_utils_compress_enable_drift_correction(
+        struct stream_out *out __unused,
+        struct audio_out_enable_drift_correction *drift __unused)
+{
+    ALOGD("%s:: configuring drift enablement not supported", __func__);
+    return 0;
+}
+#endif
+
+#ifdef SNDRV_COMPRESS_ADJUST_SESSION_CLOCK
+int audio_extn_utils_compress_correct_drift(
+        struct stream_out *out,
+        struct audio_out_correct_drift *drift_param)
+{
+    struct snd_compr_metadata metadata;
+    int ret = -EINVAL;
+
+    if (drift_param == NULL) {
+        ALOGE("%s:: Invalid drift_param", __func__);
+        goto exit;
+    }
+
+    ALOGD("%s:: adjust time 0x%"PRIx64" ", __func__,
+            drift_param->adjust_time);
+
+    if (!is_offload_usecase(out->usecase)) {
+        ALOGE("%s:: not supported for non offload session", __func__);
+        goto exit;
+    }
+
+    if (!out->compr) {
+        ALOGW("%s:: offload session not yet opened", __func__);
+        goto exit;
+    }
+
+    if (!out->drift_correction_enabled) {
+        ALOGE("%s:: drift correction not enabled", __func__);
+        goto exit;
+    }
+
+    metadata.key = SNDRV_COMPRESS_ADJUST_SESSION_CLOCK;
+    metadata.value[0] = 0xFFFFFFFF & drift_param->adjust_time; /* lsb */
+    metadata.value[1] = \
+             (0xFFFFFFFF00000000 & drift_param->adjust_time) >> 32; /* msb*/
+
+    ret = compress_set_metadata(out->compr, &metadata);
+    if(ret)
+        ALOGE("%s::error %s", __func__, compress_get_error(out->compr));
+exit:
+    return ret;
+}
+#else
+int audio_extn_utils_compress_correct_drift(
+        struct stream_out *out __unused,
+        struct audio_out_correct_drift *drift_param __unused)
+{
+    ALOGD("%s:: setting adjust clock not supported", __func__);
+    return 0;
+}
+#endif