summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sound/q6asm-v2.h6
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c8
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c8
-rw-r--r--sound/soc/msm/qdsp6v2/q6asm.c68
4 files changed, 80 insertions, 10 deletions
diff --git a/include/sound/q6asm-v2.h b/include/sound/q6asm-v2.h
index 3523fac586ce..8af49bb6a9fa 100644
--- a/include/sound/q6asm-v2.h
+++ b/include/sound/q6asm-v2.h
@@ -292,6 +292,9 @@ int q6asm_open_read_v4(struct audio_client *ac, uint32_t format,
int q6asm_open_read_v5(struct audio_client *ac, uint32_t format,
uint16_t bits_per_sample, bool ts_mode);
+int q6asm_open_read_with_retry(struct audio_client *ac, uint32_t format,
+ uint16_t bits_per_sample, bool ts_mode);
+
int q6asm_open_write(struct audio_client *ac, uint32_t format
/*, uint16_t bits_per_sample*/);
@@ -340,6 +343,9 @@ int q6asm_open_read_write_v2(struct audio_client *ac, uint32_t rd_format,
int q6asm_open_loopback_v2(struct audio_client *ac,
uint16_t bits_per_sample);
+int q6asm_open_loopback_with_retry(struct audio_client *ac,
+ uint16_t bits_per_sample);
+
int q6asm_open_transcode_loopback(struct audio_client *ac,
uint16_t bits_per_sample, uint32_t source_format,
uint32_t sink_format);
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c
index 9420534d3c5f..4f3f1d25b4a9 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c
@@ -289,10 +289,12 @@ static int msm_pcm_open(struct snd_pcm_substream *substream)
mutex_unlock(&pcm->lock);
return -ENOMEM;
}
- pcm->session_id = pcm->audio_client->session;
+
pcm->audio_client->perf_mode = pdata->perf_mode;
- ret = q6asm_open_loopback_v2(pcm->audio_client,
- bits_per_sample);
+ ret = q6asm_open_loopback_with_retry(pcm->audio_client,
+ bits_per_sample);
+ pcm->session_id = pcm->audio_client->session;
+
if (ret < 0) {
dev_err(rtd->platform->dev,
"%s: pcm out open failed\n", __func__);
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
index 1e69ddcc3464..6798b50e682f 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
@@ -498,13 +498,7 @@ static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream)
__func__, params_channels(params),
prtd->audio_client->perf_mode);
- if (q6asm_get_svc_version(APR_SVC_ASM) >=
- ADSP_ASM_API_VERSION_V2)
- ret = q6asm_open_read_v5(prtd->audio_client,
- FORMAT_LINEAR_PCM,
- bits_per_sample, false);
- else
- ret = q6asm_open_read_v4(prtd->audio_client,
+ ret = q6asm_open_read_with_retry(prtd->audio_client,
FORMAT_LINEAR_PCM,
bits_per_sample, false);
if (ret < 0) {
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index 0ad15e90bfc6..2f048fddcb08 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -2974,6 +2974,52 @@ int q6asm_open_read_v5(struct audio_client *ac, uint32_t format,
}
EXPORT_SYMBOL(q6asm_open_read_v5);
+static int q6asm_open_read_version_adaptor(struct audio_client *ac,
+ uint32_t format, uint16_t bits_per_sample, bool ts_mode)
+{
+ if (q6asm_get_svc_version(APR_SVC_ASM) >= ADSP_ASM_API_VERSION_V2)
+ return q6asm_open_read_v5(ac, FORMAT_LINEAR_PCM,
+ bits_per_sample, false);
+ else
+ return q6asm_open_read_v4(ac, FORMAT_LINEAR_PCM,
+ bits_per_sample, false);
+}
+
+/*
+ * q6asm_open_read_with_retry - Opens audio capture session, with retrying
+ * in case of session ID conflict
+ *
+ * @ac: Client session handle
+ * @format: encoder format
+ * @bits_per_sample: bit width of capture session
+ * @ts_mode: timestamp mode
+ */
+int q6asm_open_read_with_retry(struct audio_client *ac, uint32_t format,
+ uint16_t bits_per_sample, bool ts_mode)
+{
+ int i, rc;
+
+ mutex_lock(&session_lock);
+ for (i = 0; i < ASM_ACTIVE_STREAMS_ALLOWED; i++) {
+ rc = q6asm_open_read_version_adaptor(ac, format,
+ bits_per_sample, ts_mode);
+ if (rc != -EALREADY)
+ break;
+
+ pr_debug("%s: session %d is occupied, try next\n",
+ __func__, ac->session);
+ q6asm_session_set_ignore(ac->session);
+ rc = q6asm_session_try_next(ac);
+ if (rc < 0)
+ break;
+ }
+ q6asm_session_clean_ignore();
+ mutex_unlock(&session_lock);
+
+ return rc;
+}
+EXPORT_SYMBOL(q6asm_open_read_with_retry);
+
int q6asm_open_write_compressed(struct audio_client *ac, uint32_t format,
uint32_t passthrough_flag)
{
@@ -3667,7 +3713,29 @@ int q6asm_open_loopback_v2(struct audio_client *ac, uint16_t bits_per_sample)
fail_cmd:
return rc;
}
+int q6asm_open_loopback_with_retry(struct audio_client *ac,
+ uint16_t bits_per_sample)
+{
+ int i, rc;
+
+ mutex_lock(&session_lock);
+ for (i = 0; i < ASM_ACTIVE_STREAMS_ALLOWED; i++) {
+ rc = q6asm_open_loopback_v2(ac, bits_per_sample);
+ if (rc != -EALREADY)
+ break;
+ pr_debug("%s: session %d is occupied, try next\n",
+ __func__, ac->session);
+ q6asm_session_set_ignore(ac->session);
+ rc = q6asm_session_try_next(ac);
+ if (rc < 0)
+ break;
+ }
+ q6asm_session_clean_ignore();
+ mutex_unlock(&session_lock);
+ return rc;
+}
+EXPORT_SYMBOL(q6asm_open_loopback_with_retry);
int q6asm_open_transcode_loopback(struct audio_client *ac,
uint16_t bits_per_sample,