static void audio_buffdone(struct s3c2410_dma_chan *channel, void *dev_id, int size, enum s3c2410_dma_buffresult result) { struct snd_pcm_substream *substream = dev_id; struct runtime_data *prtd; pr_debug("Entered %s\n", __func__); if (result == S3C2410_RES_ABORT || result == S3C2410_RES_ERR) return; prtd = substream->runtime->private_data; snd_pcm_period_elapsed(substream); spin_lock(&prtd->lock); if (prtd->state & ST_RUNNING && !s3c_dma_has_circular()) { prtd->dma_loaded--; if (!s3c_dma_has_infiniteloop()) dma_enqueue(substream); } spin_unlock(&prtd->lock); }
/* s3c_dma_enqueue * * place a dma buffer onto the queue for the dma system * to handle. */ static void s3c_dma_enqueue(struct snd_pcm_substream *substream) { struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; dma_addr_t pos = prtd->dma_pos; unsigned long len; unsigned int limit; int ret; pr_debug("Entered %s\n", __func__); if (s3c_dma_has_circular()) limit = (prtd->dma_end - prtd->dma_start) / prtd->dma_period; else limit = prtd->dma_limit; pr_debug("%s: loaded %d, limit %d\n", __func__, prtd->dma_loaded, limit); if (s3c_dma_has_infiniteloop()) { ret = s3c2410_dma_enqueue_ring(prtd->params->channel, substream, pos, prtd->dma_period, limit); if (ret == 0) { prtd->dma_loaded += limit; pos += prtd->dma_period; } } else { while (prtd->dma_loaded < limit) { len = prtd->dma_period; pr_debug("dma_loaded: %d\n", prtd->dma_loaded); if ((pos + len) > prtd->dma_end) { len = prtd->dma_end - pos; pr_debug("%s: corrected dma len %ld\n", __func__, len); } ret = s3c2410_dma_enqueue(prtd->params->channel, substream, pos, len); if (ret == 0) { prtd->dma_loaded++; pos += prtd->dma_period; if (pos >= prtd->dma_end) pos = prtd->dma_start; } else break; } } prtd->dma_pos = pos; }