ASoC: q6dsp: q6apm-dai: Add mmap and copy compress DAI callbacks
Add q6apm mmap and copy compress DAI callbacks to support compress offload playback. Co-developed-by: Mohammad Rafi Shaik <quic_mohs@quicinc.com> Signed-off-by: Mohammad Rafi Shaik <quic_mohs@quicinc.com> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> Link: https://lore.kernel.org/r/20230619101653.9750-12-srinivas.kandagatla@linaro.org Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
b3f736d126
commit
c317d148a2
@ -737,6 +737,85 @@ static int q6apm_dai_compr_set_metadata(struct snd_soc_component *component,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int q6apm_dai_compr_mmap(struct snd_soc_component *component,
|
||||
struct snd_compr_stream *stream,
|
||||
struct vm_area_struct *vma)
|
||||
{
|
||||
struct snd_compr_runtime *runtime = stream->runtime;
|
||||
struct q6apm_dai_rtd *prtd = runtime->private_data;
|
||||
struct device *dev = component->dev;
|
||||
|
||||
return dma_mmap_coherent(dev, vma, prtd->dma_buffer.area, prtd->dma_buffer.addr,
|
||||
prtd->dma_buffer.bytes);
|
||||
}
|
||||
|
||||
static int q6apm_compr_copy(struct snd_soc_component *component,
|
||||
struct snd_compr_stream *stream, char __user *buf,
|
||||
size_t count)
|
||||
{
|
||||
struct snd_compr_runtime *runtime = stream->runtime;
|
||||
struct q6apm_dai_rtd *prtd = runtime->private_data;
|
||||
void *dstn;
|
||||
unsigned long flags;
|
||||
size_t copy;
|
||||
u32 wflags = 0;
|
||||
u32 app_pointer;
|
||||
u32 bytes_received;
|
||||
uint32_t bytes_to_write;
|
||||
int avail, bytes_in_flight = 0;
|
||||
|
||||
bytes_received = prtd->bytes_received;
|
||||
|
||||
/**
|
||||
* Make sure that next track data pointer is aligned at 32 bit boundary
|
||||
* This is a Mandatory requirement from DSP data buffers alignment
|
||||
*/
|
||||
if (prtd->next_track)
|
||||
bytes_received = ALIGN(prtd->bytes_received, prtd->pcm_count);
|
||||
|
||||
app_pointer = bytes_received/prtd->pcm_size;
|
||||
app_pointer = bytes_received - (app_pointer * prtd->pcm_size);
|
||||
dstn = prtd->dma_buffer.area + app_pointer;
|
||||
|
||||
if (count < prtd->pcm_size - app_pointer) {
|
||||
if (copy_from_user(dstn, buf, count))
|
||||
return -EFAULT;
|
||||
} else {
|
||||
copy = prtd->pcm_size - app_pointer;
|
||||
if (copy_from_user(dstn, buf, copy))
|
||||
return -EFAULT;
|
||||
if (copy_from_user(prtd->dma_buffer.area, buf + copy, count - copy))
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&prtd->lock, flags);
|
||||
bytes_in_flight = prtd->bytes_received - prtd->copied_total;
|
||||
|
||||
if (prtd->next_track) {
|
||||
prtd->next_track = false;
|
||||
prtd->copied_total = ALIGN(prtd->copied_total, prtd->pcm_count);
|
||||
prtd->bytes_sent = ALIGN(prtd->bytes_sent, prtd->pcm_count);
|
||||
}
|
||||
|
||||
prtd->bytes_received = bytes_received + count;
|
||||
|
||||
/* Kick off the data to dsp if its starving!! */
|
||||
if (prtd->state == Q6APM_STREAM_RUNNING && (bytes_in_flight == 0)) {
|
||||
bytes_to_write = prtd->pcm_count;
|
||||
avail = prtd->bytes_received - prtd->bytes_sent;
|
||||
|
||||
if (avail < prtd->pcm_count)
|
||||
bytes_to_write = avail;
|
||||
|
||||
q6apm_write_async(prtd->graph, bytes_to_write, 0, 0, wflags);
|
||||
prtd->bytes_sent += bytes_to_write;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&prtd->lock, flags);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static const struct snd_compress_ops q6apm_dai_compress_ops = {
|
||||
.open = q6apm_dai_compr_open,
|
||||
.free = q6apm_dai_compr_free,
|
||||
@ -747,6 +826,8 @@ static const struct snd_compress_ops q6apm_dai_compress_ops = {
|
||||
.ack = q6apm_dai_compr_ack,
|
||||
.set_params = q6apm_dai_compr_set_params,
|
||||
.set_metadata = q6apm_dai_compr_set_metadata,
|
||||
.mmap = q6apm_dai_compr_mmap,
|
||||
.copy = q6apm_compr_copy,
|
||||
};
|
||||
|
||||
static const struct snd_soc_component_driver q6apm_fe_dai_component = {
|
||||
|
Loading…
x
Reference in New Issue
Block a user