static snd_pcm_uframes_t s3c_dma_pointer(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct s3c24xx_runtime_data *prtd = runtime->private_data; unsigned long res; dma_addr_t src, dst; pr_debug("Entered %s\n", __func__); spin_lock(&prtd->lock); s3c2410_dma_getposition(prtd->params->channel, &src, &dst); if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) res = dst - prtd->dma_start; else res = src - prtd->dma_start; spin_unlock(&prtd->lock); pr_debug("Pointer %x %x\n", src, dst); /* we seem to be getting the odd error from the pcm library due * to out-of-bounds pointers. this is maybe due to the dma engine * not having loaded the new values for the channel before being * callled... (todo - fix ) */ if (res >= snd_pcm_lib_buffer_bytes(substream)) { if (res == snd_pcm_lib_buffer_bytes(substream)) res = 0; } return bytes_to_frames(substream->runtime, res); }
static u_int audio_get_dma_pos(audio_stream_t *s) { int dma_srcpos,dma_dstpos; audio_buf_t *b = &s->buffers[s->dma_tail]; u_int offset; if (b->dma_ref) { s3c2410_dma_getposition(s->dma, &dma_srcpos,&dma_dstpos); offset = dma_srcpos - b->dma_addr; if (offset >= s->fragsize) offset = s->fragsize - 4; } else if (s->pending_frags) { offset = b->offset; } else { offset = 0; } return offset; }