int dma_prog_channel (unsigned int chn, dma_setup_t *dma_setup)
{
	if ((chn >= DMA_MAX_CHANNELS) || !dma_channels[chn].name ||
		dma_valid_config(dma_setup) )
		return -EINVAL;
	
	DMACH_SRC_ADDR(chn) = dma_setup->src_address;
	DMACH_DST_ADDR(chn) = dma_setup->dest_address;
	DMACH_LEN(chn) = dma_setup->trans_length;
	DMACH_CFG(chn) = dma_setup->cfg;

	return 0;
}
int dma_prog_sg_channel(int chn, u32 dma_sg_list)
{
	u32 dma_config;

	if (chn >= DMA_MAX_CHANNELS)
		return -EINVAL;

	dma_config = DMA_CFG_CMP_CH_EN | DMA_CFG_CMP_CH_NR(chn - 1);

	lpc313x_dma_lock();
	DMACH_SRC_ADDR(chn) = dma_sg_list;
	DMACH_DST_ADDR(chn) = DMACH_ALT_PHYS(chn - 1);
	DMACH_LEN(chn) = 0x4;
	DMACH_CFG(chn) = dma_config;
	lpc313x_dma_unlock();

	return 0;
}
Esempio n. 3
0
static void lpc313x_check_dmall(unsigned long data) {
	struct snd_pcm_substream *substream = (struct snd_pcm_substream *) data;
	struct snd_pcm_runtime *rtd = substream->runtime;
	struct lpc313x_dma_data *prtd = rtd->private_data;

	/* Determine buffer position from current DMA position. We don't need
	   the exact address, just the last finished period */
	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		mod_timer(&prtd->timer[0], jiffies + MINTICKINC);
		prtd->dma_cur = (dma_addr_t) DMACH_SRC_ADDR(prtd->dmach - 1);
	}
	else {
		mod_timer(&prtd->timer[1], jiffies + MINTICKINC);
		prtd->dma_cur = (dma_addr_t) DMACH_DST_ADDR(prtd->dmach - 1);
	}

	/* Tell audio system more buffer space is available */
	snd_pcm_period_elapsed(substream);
}
int dma_current_state (unsigned int   chn,
                        unsigned int * psrc,
                        unsigned int * pdst,
                        unsigned int * plen,
                        unsigned int * pcfg,
                        unsigned int * pena,
                        unsigned int * pcnt)
{
	if (chn >= DMA_MAX_CHANNELS || !dma_channels[chn].name) {
		return -EINVAL;
	}

	*psrc = DMACH_SRC_ADDR(chn);
	*pdst = DMACH_DST_ADDR(chn);
	*plen  = DMACH_LEN(chn);
	*pcfg = DMACH_CFG(chn);
	*pena = DMACH_EN(chn);
	*pcnt  = DMACH_TCNT(chn);
	return 0;
}