From b9caa7f4263e1f2327db4c0809653c798e7848fb Mon Sep 17 00:00:00 2001 From: Surendar Karka Date: Mon, 20 Aug 2018 18:06:16 +0530 Subject: [PATCH] asoc: qdsp6v2: latency mode support for transcode loopback Add metadata to configure latency mode for DSP transcode loopback to set legacy or low latency path. Userspace API introduced to configure the same. Change-Id: I914c68a9e9d8647530b72c42548e571b7508c423 Signed-off-by: Siddartha Shaik Signed-off-by: Surendar Karka --- asoc/msm-transcode-loopback-q6-v2.c | 55 +++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/asoc/msm-transcode-loopback-q6-v2.c b/asoc/msm-transcode-loopback-q6-v2.c index 14b7ac87a3a2..fb70f6cb7aa6 100644 --- a/asoc/msm-transcode-loopback-q6-v2.c +++ b/asoc/msm-transcode-loopback-q6-v2.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "msm-pcm-routing-v2.h" #include "msm-qti-pp-config.h" @@ -52,6 +53,7 @@ static DEFINE_MUTEX(transcode_loopback_session_lock); struct trans_loopback_pdata { struct snd_compr_stream *cstream[MSM_FRONTEND_DAI_MAX]; uint32_t master_gain; + int perf_mode; }; struct loopback_stream { @@ -344,6 +346,8 @@ static int msm_transcode_loopback_set_params(struct snd_compr_stream *cstream, struct msm_transcode_loopback *trans = runtime->private_data; struct snd_soc_pcm_runtime *soc_pcm_rx; struct snd_soc_pcm_runtime *soc_pcm_tx; + struct snd_soc_pcm_runtime *rtd; + struct trans_loopback_pdata *pdata; uint32_t bit_width = 16; int ret = 0; @@ -354,6 +358,9 @@ static int msm_transcode_loopback_set_params(struct snd_compr_stream *cstream, mutex_lock(&trans->lock); + rtd = snd_pcm_substream_chip(cstream); + pdata = snd_soc_platform_get_drvdata(rtd->platform); + if (cstream->direction == SND_COMPRESS_PLAYBACK) { if (codec_param->codec.id == SND_AUDIOCODEC_PCM) { trans->sink.codec_format = @@ -435,7 +442,7 @@ static int msm_transcode_loopback_set_params(struct snd_compr_stream *cstream, pr_debug("%s: ASM client allocated, callback %pK\n", __func__, loopback_event_handler); trans->session_id = trans->audio_client->session; - trans->audio_client->perf_mode = false; + trans->audio_client->perf_mode = pdata->perf_mode; ret = q6asm_open_transcode_loopback(trans->audio_client, bit_width, trans->source.codec_format, @@ -454,7 +461,7 @@ static int msm_transcode_loopback_set_params(struct snd_compr_stream *cstream, if (trans->source.codec_format != FORMAT_LINEAR_PCM) msm_pcm_routing_reg_phy_compr_stream( soc_pcm_tx->dai_link->id, - trans->audio_client->perf_mode, + LEGACY_PCM_MODE, trans->session_id, SNDRV_PCM_STREAM_CAPTURE, COMPRESSED_PASSTHROUGH_GEN); @@ -467,7 +474,7 @@ static int msm_transcode_loopback_set_params(struct snd_compr_stream *cstream, /* Opening Rx ADM in LOW_LATENCY mode by default */ msm_pcm_routing_reg_phy_stream( soc_pcm_rx->dai_link->id, - true, + trans->audio_client->perf_mode, trans->session_id, SNDRV_PCM_STREAM_PLAYBACK); pr_debug("%s: Successfully opened ADM sessions\n", __func__); @@ -500,6 +507,46 @@ static int msm_transcode_loopback_get_caps(struct snd_compr_stream *cstream, return 0; } +static int msm_transcode_loopback_set_metadata(struct snd_compr_stream *cstream, + struct snd_compr_metadata *metadata) +{ + struct snd_soc_pcm_runtime *rtd; + struct trans_loopback_pdata *pdata; + + if (!metadata || !cstream) { + pr_err("%s: Invalid arguments\n", __func__); + return -EINVAL; + } + + rtd = snd_pcm_substream_chip(cstream); + pdata = snd_soc_platform_get_drvdata(rtd->platform); + + switch (metadata->key) { + case SNDRV_COMPRESS_LATENCY_MODE: + { + switch (metadata->value[0]) { + case SNDRV_COMPRESS_LEGACY_LATENCY_MODE: + pdata->perf_mode = LEGACY_PCM_MODE; + break; + case SNDRV_COMPRESS_LOW_LATENCY_MODE: + pdata->perf_mode = LOW_LATENCY_PCM_MODE; + break; + default: + pr_debug("%s: Unsupported latency mode %d, default to Legacy\n", + __func__, metadata->value[0]); + pdata->perf_mode = LEGACY_PCM_MODE; + break; + } + } + break; + default: + pr_debug("%s: Unsupported metadata %d\n", + __func__, metadata->key); + break; + } + return 0; +} + static int msm_transcode_stream_cmd_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -1138,6 +1185,7 @@ static struct snd_compr_ops msm_transcode_loopback_ops = { .trigger = msm_transcode_loopback_trigger, .set_params = msm_transcode_loopback_set_params, .get_caps = msm_transcode_loopback_get_caps, + .set_metadata = msm_transcode_loopback_set_metadata, }; @@ -1152,6 +1200,7 @@ static int msm_transcode_loopback_probe(struct snd_soc_platform *platform) if (!pdata) return -ENOMEM; + pdata->perf_mode = LOW_LATENCY_PCM_MODE; snd_soc_platform_set_drvdata(platform, pdata); return 0; }