Example #1
0
/*
 * Get DMA channel and allocate DMA descriptors memory.
 * Prepare DMA descriptors link lists
 */
static int lpc32xx_nand_dma_setup(struct lpc32xx_nand_host *host,
	int num_entries)
{
	int ret = 0;

	host->dmach = DMA_CH_SLCNAND;
	host->dmacfg.ch = DMA_CH_SLCNAND;

	/*
	 * All the DMA configuration parameters will
	 * be overwritten in lpc32xx_nand_dma_configure().
	 */
	host->dmacfg.tc_inten = 1;
	host->dmacfg.err_inten = 1;
	host->dmacfg.src_size = 4;
	host->dmacfg.src_inc = 1;
	host->dmacfg.src_ahb1 = 1;
	host->dmacfg.src_bsize = DMAC_CHAN_SRC_BURST_4;
	host->dmacfg.src_prph = 0;
	host->dmacfg.dst_size = 4;
	host->dmacfg.dst_inc = 0;
	host->dmacfg.dst_bsize = DMAC_CHAN_DEST_BURST_4;
	host->dmacfg.dst_ahb1 = 0;
	host->dmacfg.dst_prph = DMAC_DEST_PERIP(DMA_PERID_NAND1);
	host->dmacfg.flowctrl = DMAC_CHAN_FLOW_D_M2P;
	if (lpc32xx_dma_ch_get(&host->dmacfg, LPC32XX_MODNAME,
		&lpc3xxx_nand_dma_irq, host) < 0) {
		dev_err(host->mtd.dev.parent, "Error setting up SLC NAND "
			"DMA channel\n");
		ret = -ENODEV;
		goto dma_ch_err;
	}

	/*
	 * Allocate Linked list of DMA Descriptors
	 */
	host->llptr = lpc32xx_dma_alloc_llist(host->dmach, num_entries);
	if (host->llptr == 0) {
		lpc32xx_dma_ch_put(host->dmach);
		host->dmach = -1;
		dev_err(host->mtd.dev.parent,
			"Error allocating list buffer for SLC NAND\n");
		ret = -ENOMEM;
		goto dma_alloc_err;
	}

	return ret;
dma_alloc_err:
	lpc32xx_dma_ch_put(host->dmach);
dma_ch_err:
	return ret;
}
static int lpc3xxx_pcm_prepare(struct snd_pcm_substream *substream)
{
	struct lpc3xxx_dma_data *prtd = substream->runtime->private_data;

	/* Setup DMA channel */
	if (prtd->dmach == -1) {
		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
			prtd->dmach = DMA_CH_I2S_TX;
			prtd->dmacfg.ch = DMA_CH_I2S_TX;
			prtd->dmacfg.tc_inten = 1;
			prtd->dmacfg.err_inten = 1;
			prtd->dmacfg.src_size = 4;
			prtd->dmacfg.src_inc = 1;
#ifdef CONFIG_ARM_LPC32XX
			prtd->dmacfg.src_ahb1 = 1;
#endif
			prtd->dmacfg.src_bsize = DMAC_CHAN_SRC_BURST_4;
			prtd->dmacfg.src_prph = 0;
			prtd->dmacfg.dst_size = 4;
			prtd->dmacfg.dst_inc = 0;
			prtd->dmacfg.dst_bsize = DMAC_CHAN_DEST_BURST_4;
#ifdef CONFIG_ARM_LPC32XX
			prtd->dmacfg.dst_ahb1 = 0;
#endif

#if defined(CONFIG_SND_LPC32XX_USEI2S1)
			prtd->dmacfg.dst_prph = DMAC_DEST_PERIP(DMA_PERID_I2S1_DMA1);
#else
			prtd->dmacfg.dst_prph = DMAC_DEST_PERIP(DMA_PERID_I2S0_DMA1);
#endif
			prtd->dmacfg.flowctrl = DMAC_CHAN_FLOW_D_M2P;
			if (lpc32xx_dma_ch_get(&prtd->dmacfg, "dma_i2s_tx",
				&lpc3xxx_pcm_dma_irq, substream) < 0) {
				pr_debug(KERN_ERR "Error setting up I2S TX DMA channel\n");
				return -ENODEV;
			}

			/* Allocate a linked list for audio buffers */
			prtd->llptr = lpc32xx_dma_alloc_llist(prtd->dmach, NUMLINKS);
			if (prtd->llptr == 0) {
				lpc32xx_dma_ch_put(prtd->dmach);
				prtd->dmach = -1;
				pr_debug(KERN_ERR "Error allocating list buffer (I2S TX)\n");
				return -ENOMEM;
			}
		}
		else {
			prtd->dmach = DMA_CH_I2S_RX;
			prtd->dmacfg.ch = DMA_CH_I2S_RX;
			prtd->dmacfg.tc_inten = 1;
			prtd->dmacfg.err_inten = 1;
			prtd->dmacfg.src_size = 4;
			prtd->dmacfg.src_inc = 0;
#ifdef CONFIG_ARM_LPC32XX
			prtd->dmacfg.src_ahb1 = 1;
#endif
			prtd->dmacfg.src_bsize = DMAC_CHAN_SRC_BURST_4;
#if defined(CONFIG_SND_LPC32XX_USEI2S1)
			prtd->dmacfg.src_prph = DMAC_SRC_PERIP(DMA_PERID_I2S1_DMA0);
#else
			prtd->dmacfg.src_prph = DMAC_SRC_PERIP(DMA_PERID_I2S0_DMA0);
#endif
			prtd->dmacfg.dst_size = 4;
			prtd->dmacfg.dst_inc = 1;
#ifdef CONFIG_ARM_LPC32XX
			prtd->dmacfg.dst_ahb1 = 0;
#endif
			prtd->dmacfg.dst_bsize = DMAC_CHAN_DEST_BURST_4;
			prtd->dmacfg.dst_prph = 0;
			prtd->dmacfg.flowctrl = DMAC_CHAN_FLOW_D_P2M;
			if (lpc32xx_dma_ch_get(&prtd->dmacfg, "dma_i2s_rx",
				&lpc3xxx_pcm_dma_irq, substream) < 0) {
				pr_debug(KERN_ERR "Error setting up I2S RX DMA channel\n");
				return -ENODEV;
			}

			/* Allocate a linked list for audio buffers */
			prtd->llptr = lpc32xx_dma_alloc_llist(prtd->dmach, NUMLINKS);
			if (prtd->llptr == 0) {
				lpc32xx_dma_ch_put(prtd->dmach);
				prtd->dmach = -1;
				pr_debug(KERN_ERR "Error allocating list buffer (I2S RX)\n");
				return -ENOMEM;
			}
		}
	}

	return 0;
}