/* * 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; }