ALSA 驱动中dma的配置

ALSA 驱动中dma的配置:

/*    * prepare DMA for pcm    */   int i2s_dma_prepare(struct snd_pcm_substream *substream)   {       struct snd_pcm_runtime *runtime = substream->runtime;       struct sep0611_runtime_data *prtd = runtime->private_data;       struct dma_info *p_dma_info;       unsigned long i2s_fifo_width = 1;   /* 16 bits in default */       int ret;              /* we need call the i2s_dma_prepare after set hw_params, such as in pcm_prepare */       if(runtime->format == 0){           printk("ERR:please ensure the hw_params has been set correctly\n");           return -EINVAL;       }              p_dma_info = kmalloc(sizeof(struct dma_info), GFP_KERNEL);       if(!p_dma_info){           return -ENOMEM;       }              if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK){           p_dma_info->trans_type = MEM_TO_DEV;           p_dma_info->src_addr = prtd->dma_buffer;           p_dma_info->dst_addr = I2S_BASE + I2S_TXDMA;                      /*             * match with tx data of (S16_LE | S20_3LE | S24_3LE | S32_LE)            */           if(runtime->format != SNDRV_PCM_FORMAT_S16_LE)               i2s_fifo_width = 2;                      /* CTLx and CFGx */           p_dma_info->ctrl_hi = DMAC_DONE (0) | DMAC_BLK_TRAN_SZ(prtd->period_len/8);                      p_dma_info->ctrl_lo = DMAC_SRC_LLP_EN    (1) | DMAC_DST_LLP_EN       (0) | DMAC_SRC_MASTER_SEL(0)\               | DMAC_DST_MASTER_SEL(1)| DMAC_TRAN_TYPE_FLOW_CTL(1)| DMAC_DST_SCAT_EN  (0) \               | DMAC_SRC_GATH_EN   (0)| DMAC_SRC_BST_SZ        (2)| DMAC_DST_BST_SZ   (3) \               | DMAC_SRC_INCR      (0)| DMAC_DST_INCR          (3)| DMAC_SRC_TRAN_WIDTH(3)\               | DMAC_DST_TRAN_WIDTH(i2s_fifo_width) | DMAC_INT_EN(1);                      p_dma_info->cfg_hi = DMAC_DST_PER    (7) | DMAC_SRC_PER  (6) | DMAC_SRC_STAT_UPD_EN(0) \               | DMAC_DST_STAT_UPD_EN(0) | DMAC_PROT_CTL (1) | DMAC_FIFO_MODE(0) \               | DMAC_FLOW_CTL_MODE  (0);                       p_dma_info->cfg_lo = DMAC_AUTO_RELOAD_DST(0) | DMAC_AUTO_RELOAD_SRC(0) | DMAC_MAX_AMBA_BST_LEN(0) \               | DMAC_SRC_HS_POL     (0) | DMAC_DST_HS_POL   (0) | DMAC_BUS_LOCK       (0) \               | DMAC_CH_LOCK        (0) | DMAC_BUS_LOCK_LEVEL(1)| DMAC_HW_SW_SEL_SRC  (1) \               | DMAC_HW_SW_SEL_DST  (0) | DMAC_CH_SUSP      (0) | DMAC_CH_PRIOR       (0);       }       else{           p_dma_info->trans_type = DEV_TO_MEM;           p_dma_info->src_addr = I2S_BASE + I2S_RXDMA;           p_dma_info->dst_addr = prtd->dma_buffer;                  /* CTLx and CFGx */           p_dma_info->ctrl_hi = DMAC_DONE(0) | DMAC_BLK_TRAN_SZ(prtd->period_len/2);                       p_dma_info->ctrl_lo = DMAC_SRC_LLP_EN (0)| DMAC_DST_LLP_EN (1) | DMAC_SRC_MASTER_SEL   (1) \               | DMAC_DST_MASTER_SEL(0) | DMAC_TRAN_TYPE_FLOW_CTL(2) | DMAC_DST_SCAT_EN    (0) \               | DMAC_SRC_GATH_EN   (0) | DMAC_SRC_BST_SZ        (2) | DMAC_DST_BST_SZ     (3) \               | DMAC_SRC_INCR      (3) | DMAC_DST_INCR          (0) | DMAC_SRC_TRAN_WIDTH (i2s_fifo_width) \               | DMAC_DST_TRAN_WIDTH(2) | DMAC_INT_EN(1);                      p_dma_info->cfg_hi = DMAC_DST_PER(7) | DMAC_SRC_PER(6) | DMAC_SRC_STAT_UPD_EN(0) \               | DMAC_DST_STAT_UPD_EN(0) | DMAC_PROT_CTL (1) | DMAC_FIFO_MODE      (0) \               | DMAC_FLOW_CTL_MODE  (0);                                     p_dma_info->cfg_lo = DMAC_AUTO_RELOAD_DST(0) | DMAC_AUTO_RELOAD_SRC(0) | DMAC_MAX_AMBA_BST_LEN(0) \               | DMAC_SRC_HS_POL     (0) | DMAC_DST_HS_POL     (0) | DMAC_BUS_LOCK        (0) \               | DMAC_CH_LOCK        (0) | DMAC_BUS_LOCK_LEVEL (1) | DMAC_HW_SW_SEL_SRC   (0) \               | DMAC_HW_SW_SEL_DST  (1) | DMAC_CH_SUSP        (0) | DMAC_CH_PRIOR        (0);       }              /* store p_dma_info in prtd */       prtd->dma_info = p_dma_info;              ret = <SPAN style="BACKGROUND-COLOR: rgb(255,255,255)">set_dma_cll</SPAN>(p_dma_info, prtd->buffer_len, prtd->period_len);       if(ret < 0){           return -ENOMEM;       }              load_first_llp(prtd->dma_info, prtd->dma_params->channel);              return 0;   }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/pxzzw.html