pd->device_prep_slave_sg = pl330_prep_slave_sg;
pd->device_control = pl330_control;
pd->device_issue_pending = pl330_issue_pending;
+#ifdef drivers/dma/pl330.c
+ pd->dma_getposition = pl330_dma_getposition;
+#endif
ret = dma_async_device_register(pd);
if (ret) {
enum dma_status (*device_tx_status)(struct dma_chan *chan,
dma_cookie_t cookie,
struct dma_tx_state *txstate);
+#ifdef CONFIG_ARCH_ROCKCHIP
+ int (*dma_getposition)(struct dma_chan *chan,
+ dma_addr_t *src, dma_addr_t *dst);
+#endif
void (*device_issue_pending)(struct dma_chan *chan);
};
flags |= DMA_PREP_INTERRUPT;
prtd->pos = 0;
-#if CONFIG_ARCH_ROCKCHIP
+#ifdef CONFIG_ARCH_ROCKCHIP
//printk("soc dma buffersize = %d , periodsize=%d, periods=%d\n",
// snd_pcm_lib_buffer_bytes(substream),
// snd_pcm_lib_period_bytes(substream),
snd_pcm_uframes_t snd_dmaengine_pcm_pointer_no_residue(struct snd_pcm_substream *substream)
{
struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
+#ifdef CONFIG_ARCH_ROCKCHIP
+ dma_addr_t src, dst;
+
+ prtd->dma_chan->device->dma_getposition(prtd->dma_chan, &src, &dst);
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+ prtd->pos = dst - substream->runtime->dma_addr;
+ else
+ prtd->pos = src - substream->runtime->dma_addr;
+#endif
return bytes_to_frames(substream->runtime, prtd->pos);
}
EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_pointer_no_residue);