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,
