aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSrinivas Kandagatla <srinivas.kandagatla@linaro.org>2018-02-28 13:54:15 +0000
committerSrinivas Kandagatla <srinivas.kandagatla@linaro.org>2018-02-28 13:58:22 +0000
commite4c51650e271e1f31a272c3458aec03dfc2fff8c (patch)
treea16bd858639ecbf01902399b7133def8c3f00300
parent1f81e3144a90bb83c6860d8b8f93a8a6150fe686 (diff)
ASoC: qcom: q6asm-dai: Add support to latency mode mixerv4.16-rc1-dsp-audio-v3
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-rw-r--r--sound/soc/qcom/qdsp6/q6asm-dai.c78
1 files changed, 76 insertions, 2 deletions
diff --git a/sound/soc/qcom/qdsp6/q6asm-dai.c b/sound/soc/qcom/qdsp6/q6asm-dai.c
index 55ac56d3bdbae..7606de036328d 100644
--- a/sound/soc/qcom/qdsp6/q6asm-dai.c
+++ b/sound/soc/qcom/qdsp6/q6asm-dai.c
@@ -51,6 +51,7 @@ struct q6asm_dai_rtd {
struct q6asm_dai_data {
long long int sid;
+ int latency_mode[MAX_SESSIONS];
};
static struct snd_pcm_hardware q6asm_dai_hardware_capture = {
@@ -97,6 +98,17 @@ static struct snd_pcm_hardware q6asm_dai_hardware_playback = {
.fifo_size = 0,
};
+static const char * const latency_modes_text[] = {
+ "NONE", /* Legacy PCM mode */
+ "LL", /* Low Latency */
+ "ULL", /* Ultra Low Latency */
+ "ULL_PP", /* Ultra Low Latency Post Processing */
+};
+
+static const struct soc_enum latency_modes_enum[] = {
+ SOC_ENUM_SINGLE_EXT(4, latency_modes_text),
+};
+
/* Conventional and unconventional sample rate supported */
static unsigned int supported_sample_rates[] = {
8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000,
@@ -109,6 +121,65 @@ static struct snd_pcm_hw_constraint_list constraints_sample_rates = {
.mask = 0,
};
+static int q6asm_dai_latency_mode_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+ struct q6asm_dai_data *pdata = q6asm_get_dai_data(component->dev);
+ int dai_id, ret;
+
+ ret = sscanf(kcontrol->id.name, "MultiMedia%d Latency Mode", &dai_id);
+ if (ret != 1)
+ return -EINVAL;
+
+ ucontrol->value.integer.value[0] = pdata->latency_mode[dai_id - 1];
+
+ return 0;
+}
+
+static int q6asm_dai_latency_mode_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+ struct q6asm_dai_data *pdata = q6asm_get_dai_data(component->dev);
+ int dai_id, ret;
+
+ ret = sscanf(kcontrol->id.name, "MultiMedia%d Latency Mode", &dai_id);
+ if (ret != 1)
+ return -EINVAL;
+
+ pdata->latency_mode[dai_id - 1] = ucontrol->value.integer.value[0];
+
+ return 0;
+}
+
+static const struct snd_kcontrol_new q6asm_dai_controls[] = {
+ SOC_ENUM_EXT("MultiMedia1 Latency Mode", latency_modes_enum[0],
+ q6asm_dai_latency_mode_get,
+ q6asm_dai_latency_mode_put),
+ SOC_ENUM_EXT("MultiMedia2 Latency Mode", latency_modes_enum[0],
+ q6asm_dai_latency_mode_get,
+ q6asm_dai_latency_mode_put),
+ SOC_ENUM_EXT("MultiMedia3 Latency Mode", latency_modes_enum[0],
+ q6asm_dai_latency_mode_get,
+ q6asm_dai_latency_mode_put),
+ SOC_ENUM_EXT("MultiMedia4 Latency Mode", latency_modes_enum[0],
+ q6asm_dai_latency_mode_get,
+ q6asm_dai_latency_mode_put),
+ SOC_ENUM_EXT("MultiMedia5 Latency Mode", latency_modes_enum[0],
+ q6asm_dai_latency_mode_get,
+ q6asm_dai_latency_mode_put),
+ SOC_ENUM_EXT("MultiMedia6 Latency Mode", latency_modes_enum[0],
+ q6asm_dai_latency_mode_get,
+ q6asm_dai_latency_mode_put),
+ SOC_ENUM_EXT("MultiMedia7 Latency Mode", latency_modes_enum[0],
+ q6asm_dai_latency_mode_get,
+ q6asm_dai_latency_mode_put),
+ SOC_ENUM_EXT("MultiMedia8 Latency Mode", latency_modes_enum[0],
+ q6asm_dai_latency_mode_get,
+ q6asm_dai_latency_mode_put),
+};
+
static void event_handler(uint32_t opcode, uint32_t token,
uint32_t *payload, void *priv)
{
@@ -202,7 +273,8 @@ static int q6asm_dai_prepare(struct snd_pcm_substream *substream)
}
prtd->session_id = q6asm_get_session_id(prtd->audio_client);
- ret = q6routing_stream_open(soc_prtd->dai_link->id, LEGACY_PCM_MODE,
+ ret = q6routing_stream_open(soc_prtd->dai_link->id,
+ pdata->latency_mode[soc_prtd->dai_link->id],
prtd->session_id, substream->stream);
if (ret) {
pr_err("%s: stream reg failed ret:%d\n", __func__, ret);
@@ -286,7 +358,7 @@ static int q6asm_dai_open(struct snd_pcm_substream *substream)
prtd->substream = substream;
prtd->audio_client = q6asm_audio_client_alloc(dev,
- (q6asm_cb)event_handler, prtd, stream_id);
+ (q6asm_cb)event_handler, prtd, stream_id, pdata->latency_mode[stream_id]);
if (!prtd->audio_client) {
pr_info("%s: Could not allocate memory\n", __func__);
kfree(prtd);
@@ -522,6 +594,8 @@ static int fe_dai_probe(struct snd_soc_dai *dai)
static const struct snd_soc_component_driver q6asm_fe_dai_component = {
.name = "q6asm-fe-dai",
+ .controls = q6asm_dai_controls,
+ .num_controls = ARRAY_SIZE(q6asm_dai_controls),
};
static struct snd_soc_dai_driver q6asm_fe_dais[] = {