diff options
author | Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | 2020-06-10 14:12:07 +0100 |
---|---|---|
committer | Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | 2020-06-10 14:56:00 +0100 |
commit | f3c53b3d6225167203a672b21e6e68d68a0c0469 (patch) | |
tree | 957e9258ec2990a9f8708cbd238d734882d637e3 | |
parent | f627eeccd9f58fb04664808b973b45a8d516c1f1 (diff) |
ASoC: q6asm: allow to specify buffer offset in q6asm_writegapless/v1
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-rw-r--r-- | sound/soc/qcom/qdsp6/q6asm-dai.c | 41 | ||||
-rw-r--r-- | sound/soc/qcom/qdsp6/q6asm.c | 18 | ||||
-rw-r--r-- | sound/soc/qcom/qdsp6/q6asm.h | 3 |
3 files changed, 39 insertions, 23 deletions
diff --git a/sound/soc/qcom/qdsp6/q6asm-dai.c b/sound/soc/qcom/qdsp6/q6asm-dai.c index 703b54a946f10..20e54663d1bc6 100644 --- a/sound/soc/qcom/qdsp6/q6asm-dai.c +++ b/sound/soc/qcom/qdsp6/q6asm-dai.c @@ -193,7 +193,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; @@ -203,7 +203,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; } @@ -510,7 +510,7 @@ static void compress_event_handler(uint32_t opcode, uint32_t token, struct snd_compr_stream *substream = prtd->cstream; unsigned long flags = 0; uint64_t avail; - uint32_t bytes_written; + uint32_t bytes_written, offset, bytes_to_write; switch (opcode) { case ASM_CLIENT_EVENT_CMD_RUN_DONE: @@ -522,7 +522,7 @@ static void compress_event_handler(uint32_t opcode, uint32_t token, avail = prtd->bytes_received - 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; } @@ -555,7 +555,19 @@ static void compress_event_handler(uint32_t opcode, uint32_t token, bytes_written = (token >> 16); prtd->copied_total += bytes_written; - snd_compr_fragment_elapsed(substream); + offset = prtd->copied_total % prtd->pcm_count; + + if (bytes_written && + ((bytes_written == prtd->pcm_count) || (!offset))) { + //FIXME + snd_compr_fragment_elapsed(substream); + bytes_to_write = prtd->pcm_count; + } else { + bytes_to_write = prtd->pcm_count - offset; + } + + pr_err("DEBUG: %s:%d offset and bytes to write (%d, %d)\n", + __func__, __LINE__, offset, bytes_to_write); avail = prtd->bytes_received - prtd->bytes_sent; if (prtd->state != Q6ASM_STREAM_RUNNING || avail <= 0) { @@ -563,8 +575,8 @@ static void compress_event_handler(uint32_t opcode, uint32_t token, break; } - if (avail >= prtd->pcm_count) { - if (prtd->partial_drain && avail == prtd->pcm_count) { + if (avail >= bytes_to_write) { + if (prtd->partial_drain && avail == bytes_to_write) { flags |= ASM_LAST_BUFFER_FLAG; q6asm_stream_remove_trailing_silence(prtd->audio_client, prtd->stream_id, @@ -573,19 +585,18 @@ static void compress_event_handler(uint32_t opcode, uint32_t token, q6asm_write_async(prtd->audio_client, prtd->stream_id, - prtd->pcm_count, 0, 0, flags); + offset, bytes_to_write, 0, 0, flags); - if (prtd->notify_on_drain && avail == prtd->pcm_count) + if (prtd->notify_on_drain && avail == bytes_to_write) q6asm_cmd_nowait(prtd->audio_client, prtd->stream_id, CMD_EOS); - prtd->bytes_sent += prtd->pcm_count; + prtd->bytes_sent += bytes_to_write; } else if (avail > 0 && (prtd->partial_drain || prtd->notify_on_drain)) { - uint32_t flags = 0; /* Check if partial drain is active and mark last buffer*/ - if (prtd->partial_drain && avail <= prtd->pcm_count) { + if (prtd->partial_drain && avail <= bytes_to_write) { flags |= ASM_LAST_BUFFER_FLAG; q6asm_stream_remove_trailing_silence(prtd->audio_client, prtd->stream_id, @@ -593,9 +604,9 @@ static void compress_event_handler(uint32_t opcode, uint32_t token, } q6asm_write_async(prtd->audio_client, prtd->stream_id, - avail /*prtd->pcm_count*/, 0, 0, flags); + offset, avail /*prtd->pcm_count*/, 0, 0, flags); - if (prtd->notify_on_drain && avail <= prtd->pcm_count) + if (prtd->notify_on_drain && avail <= bytes_to_write) q6asm_cmd_nowait(prtd->audio_client, prtd->stream_id, CMD_EOS); @@ -1096,7 +1107,7 @@ static int q6asm_dai_compr_ack(struct snd_compr_stream *stream, /* Kick off the data to dsp if dsp was starving */ if (prtd->gapless_in_progress && !avail) q6asm_write_async(prtd->audio_client, prtd->stream_id, - 0, 0, 0, 0); + 0, 0, 0, 0, 0); return count; } diff --git a/sound/soc/qcom/qdsp6/q6asm.c b/sound/soc/qcom/qdsp6/q6asm.c index 939f990de6ab6..7266d241fa38e 100644 --- a/sound/soc/qcom/qdsp6/q6asm.c +++ b/sound/soc/qcom/qdsp6/q6asm.c @@ -675,6 +675,7 @@ static int32_t q6asm_stream_callback(struct apr_device *adev, phys_addr_t phys; unsigned long flags; int token = hdr->token & 0xFFFF; + struct audio_buffer *ab; spin_lock_irqsave(&ac->lock, flags); @@ -686,12 +687,14 @@ static int32_t q6asm_stream_callback(struct apr_device *adev, goto done; } - phys = port->buf[token].phys; + ab = &port->buf[token]; + phys = ab->phys; - if (lower_32_bits(phys) != result->opcode || + if (lower_32_bits(phys) != + (result->opcode & ~(ab->size - 1)) || upper_32_bits(phys) != result->status) { dev_err(ac->dev, "Expected addr %pa\n", - &port->buf[token].phys); + &ab->phys); spin_unlock_irqrestore(&ac->lock, flags); ret = -EINVAL; goto done; @@ -1563,8 +1566,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; @@ -1590,7 +1594,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 << 16); 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; @@ -1601,7 +1605,7 @@ int q6asm_write_async(struct audio_client *ac, uint32_t stream_id, uint32_t len, write->flags = wflags; - if (len) + if ((offset + len) == ab->size) port->dsp_buf++; if (port->dsp_buf >= port->num_periods) diff --git a/sound/soc/qcom/qdsp6/q6asm.h b/sound/soc/qcom/qdsp6/q6asm.h index c586b3c980b98..da68c9146adbd 100644 --- a/sound/soc/qcom/qdsp6/q6asm.h +++ b/sound/soc/qcom/qdsp6/q6asm.h @@ -93,7 +93,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, uint16_t bits_per_sample, |