summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sound/q6asm-v2.h4
-rw-r--r--sound/soc/msm/qdsp6v2/q6asm.c71
2 files changed, 75 insertions, 0 deletions
diff --git a/include/sound/q6asm-v2.h b/include/sound/q6asm-v2.h
index 42dd677610d9..8f488d9de06d 100644
--- a/include/sound/q6asm-v2.h
+++ b/include/sound/q6asm-v2.h
@@ -318,6 +318,10 @@ 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_transcode_loopback(struct audio_client *ac,
+ uint16_t bits_per_sample, uint32_t source_format,
+ uint32_t sink_format);
+
int q6asm_write(struct audio_client *ac, uint32_t len, uint32_t msw_ts,
uint32_t lsw_ts, uint32_t flags);
int q6asm_write_nolock(struct audio_client *ac, uint32_t len, uint32_t msw_ts,
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index 50bad5c2e48c..79ddef3ee6a5 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -3225,6 +3225,77 @@ fail_cmd:
return rc;
}
+
+int q6asm_open_transcode_loopback(struct audio_client *ac,
+ uint16_t bits_per_sample,
+ uint32_t source_format, uint32_t sink_format)
+{
+ int rc = 0x00;
+ struct asm_stream_cmd_open_transcode_loopback_t open;
+
+ if (ac == NULL) {
+ pr_err("%s: APR handle NULL\n", __func__);
+ return -EINVAL;
+ }
+ if (ac->apr == NULL) {
+ pr_err("%s: AC APR handle NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ pr_debug("%s: session[%d]\n", __func__, ac->session);
+
+ q6asm_add_hdr(ac, &open.hdr, sizeof(open), TRUE);
+ atomic_set(&ac->cmd_state, -1);
+ open.hdr.opcode = ASM_STREAM_CMD_OPEN_TRANSCODE_LOOPBACK;
+
+ open.mode_flags = 0;
+ open.src_endpoint_type = 0;
+ open.sink_endpoint_type = 0;
+ open.src_format_id = source_format;
+ open.sink_format_id = sink_format;
+ /* source endpoint : matrix */
+ open.audproc_topo_id = q6asm_get_asm_topology_cal();
+
+ ac->app_type = q6asm_get_asm_app_type_cal();
+ if (ac->perf_mode == LOW_LATENCY_PCM_MODE)
+ open.mode_flags |= ASM_LOW_LATENCY_STREAM_SESSION;
+ else
+ open.mode_flags |= ASM_LEGACY_STREAM_SESSION;
+ ac->topology = open.audproc_topo_id;
+ open.bits_per_sample = bits_per_sample;
+ open.reserved = 0;
+ pr_debug("%s: opening a transcode_loopback with mode_flags =[%d] session[%d]\n",
+ __func__, open.mode_flags, ac->session);
+
+ rc = apr_send_pkt(ac->apr, (uint32_t *) &open);
+ if (rc < 0) {
+ pr_err("%s: open failed op[0x%x]rc[%d]\n",
+ __func__, open.hdr.opcode, rc);
+ rc = -EINVAL;
+ goto fail_cmd;
+ }
+ rc = wait_event_timeout(ac->cmd_wait,
+ (atomic_read(&ac->cmd_state) >= 0), 5*HZ);
+ if (!rc) {
+ pr_err("%s: timeout. waited for open_transcode_loopback\n",
+ __func__);
+ rc = -ETIMEDOUT;
+ goto fail_cmd;
+ }
+ if (atomic_read(&ac->cmd_state) > 0) {
+ pr_err("%s: DSP returned error[%s]\n",
+ __func__, adsp_err_get_err_str(
+ atomic_read(&ac->cmd_state)));
+ rc = adsp_err_get_lnx_err_code(
+ atomic_read(&ac->cmd_state));
+ goto fail_cmd;
+ }
+
+ return 0;
+fail_cmd:
+ return rc;
+}
+
static
int q6asm_set_shared_circ_buff(struct audio_client *ac,
struct asm_stream_cmd_open_shared_io *open,