aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSrinivas Kandagatla <srinivas.kandagatla@linaro.org>2020-06-10 14:12:07 +0100
committerSrinivas Kandagatla <srinivas.kandagatla@linaro.org>2020-06-10 14:56:00 +0100
commitf3c53b3d6225167203a672b21e6e68d68a0c0469 (patch)
tree957e9258ec2990a9f8708cbd238d734882d637e3
parentf627eeccd9f58fb04664808b973b45a8d516c1f1 (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.c41
-rw-r--r--sound/soc/qcom/qdsp6/q6asm.c18
-rw-r--r--sound/soc/qcom/qdsp6/q6asm.h3
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,