diff options
-rw-r--r-- | include/sound/q6asm-v2.h | 6 | ||||
-rw-r--r-- | sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c | 8 | ||||
-rw-r--r-- | sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c | 8 | ||||
-rw-r--r-- | sound/soc/msm/qdsp6v2/q6asm.c | 68 |
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, |