예제 #1
0
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);
}
예제 #2
0
/* 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;
}