audio: qdsp6v2: handle flush and eos in encoder driver
Updated encoder driver to handle the flush and eos.
CRs-fixed: 283541
Signed-off-by: Rajesha Kini <rkini@codeaurora.org>
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_utils.c b/arch/arm/mach-msm/qdsp6v2/audio_utils.c
index 2e31ba0..65a2c54 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_utils.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_utils.c
@@ -42,19 +42,26 @@
int rc;
pr_debug("%s:session id %d: flush\n", __func__, audio->ac->session);
- /* Implicitly issue a pause to the decoder before flushing */
- rc = audio_in_pause(audio);
- if (rc < 0) {
- pr_err("%s:session id %d: pause cmd failed rc=%d\n", __func__,
- audio->ac->session, rc);
- return rc;
- }
+ /* Flush if session running */
+ if (audio->enabled) {
+ /* Implicitly issue a pause to the encoder before flushing */
+ rc = audio_in_pause(audio);
+ if (rc < 0) {
+ pr_err("%s:session id %d: pause cmd failed rc=%d\n",
+ __func__, audio->ac->session, rc);
+ return rc;
+ }
- rc = q6asm_cmd(audio->ac, CMD_FLUSH);
- if (rc < 0) {
- pr_err("%s:session id %d: flush cmd failed rc=%d\n", __func__,
- audio->ac->session, rc);
- return rc;
+ rc = q6asm_cmd(audio->ac, CMD_FLUSH);
+ if (rc < 0) {
+ pr_err("%s:session id %d: flush cmd failed rc=%d\n",
+ __func__, audio->ac->session, rc);
+ return rc;
+ }
+ /* 2nd arg: 0 -> run immediately
+ 3rd arg: 0 -> msw_ts, 4th arg: 0 ->lsw_ts */
+ q6asm_run(audio->ac, 0x00, 0x00, 0x00);
+ pr_debug("Rerun the session\n");
}
audio->rflush = 1;
audio->wflush = 1;
@@ -75,6 +82,7 @@
audio->ac->session, atomic_read(&audio->in_samples));
atomic_set(&audio->in_bytes, 0);
atomic_set(&audio->in_samples, 0);
+ atomic_set(&audio->out_count, 0);
return 0;
}
@@ -239,6 +247,12 @@
if (rc < 0)
pr_err("%s:session id %d: Flush Fail rc=%d\n",
__func__, audio->ac->session, rc);
+ else { /* Register back the flushed read buffer with DSP */
+ int cnt = 0;
+ while (cnt++ < audio->str_cfg.buffer_count)
+ q6asm_read(audio->ac); /* Push buffer to DSP */
+ pr_debug("register the read buffer\n");
+ }
break;
}
case AUDIO_PAUSE: {
@@ -555,6 +569,27 @@
rc = -EBUSY;
break;
}
+ /* if no PCM data, might have only eos buffer
+ such case do not hold cpu buffer */
+ if ((buf == start) && (count == mfield_size)) {
+ char eos_buf[sizeof(struct meta_in)];
+ /* Processing begining of user buffer */
+ if (copy_from_user(eos_buf, buf, mfield_size)) {
+ rc = -EFAULT;
+ break;
+ }
+ /* Check if EOS flag is set and buffer has
+ * contains just meta field
+ */
+ extract_meta_info(eos_buf, &msw_ts, &lsw_ts,
+ &nflags);
+ buf += mfield_size;
+ /* send the EOS and return */
+ pr_debug("%s:session id %d: send EOS\
+ 0x%8x\n", __func__,
+ audio->ac->session, nflags);
+ break;
+ }
data = (unsigned char *)q6asm_is_cpu_buf_avail(IN, audio->ac,
&size, &idx);
if (!data) {
@@ -576,13 +611,6 @@
extract_meta_info(cpy_ptr, &msw_ts, &lsw_ts,
&nflags);
buf += mfield_size;
- if (count == mfield_size) {
- /* send the EOS and return */
- pr_debug("%s:session id %d: send EOS\
- 0x%8x\n", __func__,
- audio->ac->session, nflags);
- break;
- }
count -= mfield_size;
} else {
pr_debug("%s:session id %d: continuous\