linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
To: broonie@kernel.org
Cc: vkoul@kernel.org, perex@perex.cz, tiwai@suse.com,
	alsa-devel@alsa-project.org, lgirdwood@gmail.com,
	linux-kernel@vger.kernel.org,
	Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Subject: [PATCH 8/8] ASoC: q6asm: allow to specify buffer offset in q6asm_write
Date: Thu, 11 Jun 2020 13:41:59 +0100	[thread overview]
Message-ID: <20200611124159.20742-9-srinivas.kandagatla@linaro.org> (raw)
In-Reply-To: <20200611124159.20742-1-srinivas.kandagatla@linaro.org>

In usecase like gapless, its possible that next stream/track
can start an offset where previous track ends, and this offset
may not be at period boundary.

So adding offset parameter to write function will provide ablity
to send buffers with an offset inside period boundary.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
---
 sound/soc/qcom/qdsp6/q6asm-dai.c | 15 +++++++++------
 sound/soc/qcom/qdsp6/q6asm.c     | 21 ++++++++++++++-------
 sound/soc/qcom/qdsp6/q6asm.h     |  3 ++-
 3 files changed, 25 insertions(+), 14 deletions(-)

diff --git a/sound/soc/qcom/qdsp6/q6asm-dai.c b/sound/soc/qcom/qdsp6/q6asm-dai.c
index 7aba3c07810b..113929e79407 100644
--- a/sound/soc/qcom/qdsp6/q6asm-dai.c
+++ b/sound/soc/qcom/qdsp6/q6asm-dai.c
@@ -187,7 +187,7 @@ static void event_handler(uint32_t opcode, uint32_t token,
 	case ASM_CLIENT_EVENT_CMD_RUN_DONE:
 		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 			q6asm_write_async(prtd->audio_client, prtd->stream_id,
-				   prtd->pcm_count, 0, 0, 0);
+				   0, prtd->pcm_count, 0, 0, 0);
 		break;
 	case ASM_CLIENT_EVENT_CMD_EOS_DONE:
 		prtd->state = Q6ASM_STREAM_STOPPED;
@@ -197,7 +197,7 @@ static void event_handler(uint32_t opcode, uint32_t token,
 		snd_pcm_period_elapsed(substream);
 		if (prtd->state == Q6ASM_STREAM_RUNNING)
 			q6asm_write_async(prtd->audio_client, prtd->stream_id,
-					   prtd->pcm_count, 0, 0, 0);
+					  0, prtd->pcm_count, 0, 0, 0);
 
 		break;
 		}
@@ -509,14 +509,14 @@ static void compress_event_handler(uint32_t opcode, uint32_t token,
 	struct snd_compr_stream *substream = prtd->cstream;
 	unsigned long flags;
 	uint64_t avail;
-	uint32_t bytes_written;
+	uint32_t bytes_written, offset;
 
 	switch (opcode) {
 	case ASM_CLIENT_EVENT_CMD_RUN_DONE:
 		spin_lock_irqsave(&prtd->lock, flags);
 		if (!prtd->bytes_sent) {
 			q6asm_write_async(prtd->audio_client, prtd->stream_id,
-					  prtd->pcm_count, 0, 0, 0);
+					  0, prtd->pcm_count, 0, 0, 0);
 			prtd->bytes_sent += prtd->pcm_count;
 		}
 
@@ -532,7 +532,10 @@ static void compress_event_handler(uint32_t opcode, uint32_t token,
 
 		bytes_written = token >> ASM_WRITE_TOKEN_LEN_SHIFT;
 		prtd->copied_total += bytes_written;
-		snd_compr_fragment_elapsed(substream);
+		offset = prtd->copied_total % prtd->pcm_count;
+
+		if (bytes_written && !offset)
+			snd_compr_fragment_elapsed(substream);
 
 		avail = prtd->bytes_received - prtd->bytes_sent;
 		if (prtd->state != Q6ASM_STREAM_RUNNING || avail <= 0) {
@@ -542,7 +545,7 @@ static void compress_event_handler(uint32_t opcode, uint32_t token,
 
 		if (avail >= prtd->pcm_count) {
 			q6asm_write_async(prtd->audio_client, prtd->stream_id,
-					   prtd->pcm_count, 0, 0, 0);
+					  0, prtd->pcm_count, 0, 0, 0);
 			prtd->bytes_sent += prtd->pcm_count;
 		}
 
diff --git a/sound/soc/qcom/qdsp6/q6asm.c b/sound/soc/qcom/qdsp6/q6asm.c
index 205453d1c1fc..8e3746ce4fa4 100644
--- a/sound/soc/qcom/qdsp6/q6asm.c
+++ b/sound/soc/qcom/qdsp6/q6asm.c
@@ -238,6 +238,7 @@ struct asm_session_cmd_run_v2 {
 struct audio_buffer {
 	phys_addr_t phys;
 	uint32_t size;		/* size of buffer */
+	uint32_t offset;
 };
 
 struct audio_port_data {
@@ -671,6 +672,7 @@ static int32_t q6asm_stream_callback(struct apr_device *adev,
 			phys_addr_t phys;
 			unsigned long flags;
 			int token = hdr->token & ASM_WRITE_TOKEN_MASK;
+			struct audio_buffer *ab;
 
 			spin_lock_irqsave(&ac->lock, flags);
 
@@ -682,12 +684,13 @@ static int32_t q6asm_stream_callback(struct apr_device *adev,
 				goto done;
 			}
 
-			phys = port->buf[token].phys;
+			ab = &port->buf[token];
+			phys = ab->phys + ab->offset;
 
-			if (lower_32_bits(phys) != result->opcode ||
+			if (lower_32_bits(phys) != (result->opcode) ||
 			    upper_32_bits(phys) != result->status) {
 				dev_err(ac->dev, "Expected addr %pa\n",
-					&port->buf[token].phys);
+					&ab->phys + ab->offset);
 				spin_unlock_irqrestore(&ac->lock, flags);
 				ret = -EINVAL;
 				goto done;
@@ -1504,6 +1507,7 @@ EXPORT_SYMBOL_GPL(q6asm_open_read);
  *
  * @ac: audio client pointer
  * @stream_id: stream id
+ * @offset: offset in the period buffer
  * @len: length in bytes
  * @msw_ts: timestamp msw
  * @lsw_ts: timestamp lsw
@@ -1511,8 +1515,9 @@ EXPORT_SYMBOL_GPL(q6asm_open_read);
  *
  * Return: Will be an negative value on error or zero on success
  */
-int q6asm_write_async(struct audio_client *ac, uint32_t stream_id, uint32_t len,
-		      uint32_t msw_ts, uint32_t lsw_ts, uint32_t wflags)
+int q6asm_write_async(struct audio_client *ac, uint32_t stream_id,
+		      uint32_t offset, uint32_t len, uint32_t msw_ts,
+		      uint32_t lsw_ts, uint32_t wflags)
 {
 	struct asm_data_cmd_write_v2 *write;
 	struct audio_port_data *port;
@@ -1538,7 +1543,7 @@ int q6asm_write_async(struct audio_client *ac, uint32_t stream_id, uint32_t len,
 	ab = &port->buf[port->dsp_buf];
 	pkt->hdr.token = port->dsp_buf | (len << ASM_WRITE_TOKEN_LEN_SHIFT);
 	pkt->hdr.opcode = ASM_DATA_CMD_WRITE_V2;
-	write->buf_addr_lsw = lower_32_bits(ab->phys);
+	write->buf_addr_lsw = lower_32_bits(ab->phys + offset);
 	write->buf_addr_msw = upper_32_bits(ab->phys);
 	write->buf_size = len;
 	write->seq_id = port->dsp_buf;
@@ -1549,7 +1554,9 @@ int q6asm_write_async(struct audio_client *ac, uint32_t stream_id, uint32_t len,
 
 	write->flags = wflags;
 
-	port->dsp_buf++;
+	ab->offset = offset;
+	if ((offset + len) == ab->size)
+		port->dsp_buf++;
 
 	if (port->dsp_buf >= port->num_periods)
 		port->dsp_buf = 0;
diff --git a/sound/soc/qcom/qdsp6/q6asm.h b/sound/soc/qcom/qdsp6/q6asm.h
index 0379580f0742..ad7e2f6f122f 100644
--- a/sound/soc/qcom/qdsp6/q6asm.h
+++ b/sound/soc/qcom/qdsp6/q6asm.h
@@ -96,7 +96,8 @@ struct audio_client *q6asm_audio_client_alloc(struct device *dev,
 					      q6asm_cb cb, void *priv,
 					      int session_id, int perf_mode);
 void q6asm_audio_client_free(struct audio_client *ac);
-int q6asm_write_async(struct audio_client *ac, uint32_t stream_id, uint32_t len,
+int q6asm_write_async(struct audio_client *ac, uint32_t stream_id,
+		      uint32_t offset, uint32_t len,
 		      uint32_t msw_ts, uint32_t lsw_ts, uint32_t flags);
 int q6asm_open_write(struct audio_client *ac, uint32_t stream_id,
 		     uint32_t format, u32 codec_profile,
-- 
2.21.0


  parent reply	other threads:[~2020-06-11 12:42 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-11 12:41 [PATCH 0/8] ASoC: qcom: q6asm: few fixes and enhancements Srinivas Kandagatla
2020-06-11 12:41 ` [PATCH 1/8] ASoC: q6asm: add command opcode to timeout error report Srinivas Kandagatla
2020-06-11 12:41 ` [PATCH 2/8] ASoC: q6asm: handle EOS correctly Srinivas Kandagatla
2020-06-11 12:41 ` [PATCH 3/8] ASoC: q6asm: rename misleading session id variable Srinivas Kandagatla
2020-06-11 12:41 ` [PATCH 4/8] ASoC: q6asm: make commands specific to streams Srinivas Kandagatla
2020-06-11 12:41 ` [PATCH 5/8] ASoC: q6asm: use flags directly from asm-dai Srinivas Kandagatla
2020-06-11 12:41 ` [PATCH 6/8] ASoC: q6asm: add length to write command token Srinivas Kandagatla
2020-06-11 12:41 ` [PATCH 7/8] ASoC: q6asm-dai: check available buffer size before sending Srinivas Kandagatla
2020-06-11 12:41 ` Srinivas Kandagatla [this message]
2020-06-11 15:28 ` [PATCH 0/8] ASoC: qcom: q6asm: few fixes and enhancements Mark Brown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200611124159.20742-9-srinivas.kandagatla@linaro.org \
    --to=srinivas.kandagatla@linaro.org \
    --cc=alsa-devel@alsa-project.org \
    --cc=broonie@kernel.org \
    --cc=lgirdwood@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=perex@perex.cz \
    --cc=tiwai@suse.com \
    --cc=vkoul@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).