audio: hal: support for audio clock recovery modes

-Hal changes to configure clock recovery mode based on output device
-In STC Master mode on HDMI device mode is set to none and
 for other devices mode is set to auto clock recover mode.

Change-Id: I17aed22d885df2f8236f739ab61e258bd3f760bf
CRs-Fixed: 2009985
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index a6510e5..ab4ce47 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -834,4 +834,5 @@
                 struct audio_avt_device_drift_param *drift_param);
 int audio_extn_utils_compress_get_dsp_latency(struct stream_out *out);
 int audio_extn_utils_compress_set_render_mode(struct stream_out *out);
+int audio_extn_utils_compress_set_clk_rec_mode(struct audio_usecase *usecase);
 #endif /* AUDIO_EXTN_H */
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index 050dcd6..5ba85c5 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -1741,3 +1741,71 @@
     return 0;
 }
 #endif
+
+#ifdef SNDRV_COMPRESS_CLK_REC_MODE
+int audio_extn_utils_compress_set_clk_rec_mode(
+            struct audio_usecase *usecase)
+{
+    struct snd_compr_metadata metadata;
+    struct stream_out *out = NULL;
+    int ret = -EINVAL;
+
+    if (usecase != NULL && usecase->type != PCM_PLAYBACK) {
+        ALOGE("%s:: Invalid use case", __func__);
+        goto exit;
+    }
+
+    out = usecase->stream.out;
+    if (!out) {
+        ALOGE("%s:: invalid stream", __func__);
+        goto exit;
+    }
+
+    if (!is_offload_usecase(out->usecase)) {
+        ALOGE("%s:: not supported for non offload session", __func__);
+        goto exit;
+    }
+
+    if (out->render_mode != RENDER_MODE_AUDIO_STC_MASTER) {
+        ALOGD("%s:: clk recovery is only supported in STC render mode",
+                __func__);
+        ret = 0;
+        goto exit;
+    }
+
+    if (!out->compr) {
+        ALOGD("%s:: Invalid compress handle",
+                __func__);
+        goto exit;
+    }
+    metadata.key = SNDRV_COMPRESS_CLK_REC_MODE;
+    switch(usecase->out_snd_device) {
+        case SND_DEVICE_OUT_HDMI:
+        case SND_DEVICE_OUT_SPEAKER_AND_HDMI:
+        case SND_DEVICE_OUT_DISPLAY_PORT:
+        case SND_DEVICE_OUT_SPEAKER_AND_DISPLAY_PORT:
+            metadata.value[0] = SNDRV_COMPRESS_CLK_REC_MODE_NONE;
+            break;
+        default:
+            metadata.value[0] = SNDRV_COMPRESS_CLK_REC_MODE_AUTO;
+            break;
+    }
+
+    ALOGD("%s:: clk recovery mode %d",__func__, metadata.value[0]);
+
+    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_set_clk_rec_mode(
+            struct audio_usecase *usecase __unused)
+{
+    ALOGD("%s:: configuring render mode not supported", __func__);
+    return 0;
+}
+#endif
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index df52b4c..cb759f7 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -710,6 +710,7 @@
 {
     snd_device_t snd_device;
     char mixer_path[MIXER_PATH_MAX_LENGTH];
+    struct stream_out *out = NULL;
 
     if (usecase == NULL)
         return -EINVAL;
@@ -730,6 +731,12 @@
     audio_extn_listen_update_stream_status(usecase, LISTEN_EVENT_STREAM_BUSY);
     audio_extn_utils_send_app_type_cfg(adev, usecase);
     audio_extn_utils_send_audio_calibration(adev, usecase);
+    if ((usecase->type == PCM_PLAYBACK) && is_offload_usecase(usecase->id)) {
+        out = usecase->stream.out;
+        if (out && out->compr)
+            audio_extn_utils_compress_set_clk_rec_mode(usecase);
+    }
+
     strlcpy(mixer_path, use_case_table[usecase->id], MIXER_PATH_MAX_LENGTH);
     platform_add_backend_name(mixer_path, snd_device, usecase);
     ALOGD("%s: apply mixer and update path: %s", __func__, mixer_path);
@@ -2364,6 +2371,7 @@
         }
 
         audio_extn_utils_compress_set_render_mode(out);
+        audio_extn_utils_compress_set_clk_rec_mode(uc_info);
 
         audio_extn_dts_create_state_notifier_node(out->usecase);
         audio_extn_dts_notify_playback_state(out->usecase, 0, out->sample_rate,