static int sun4i_pcm_trigger(struct snd_pcm_substream *substream, int cmd) { struct sun4i_runtime_data *prtd = substream->runtime->private_data; int ret ; spin_lock(&prtd->lock); switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: printk("[IIS] dma trigger start\n"); printk("[IIS] 0x01c22400+0x24 = %#x, line= %d\n", readl(0xf1c22400+0x24), __LINE__); sw_dma_ctrl(prtd->params->channel, SW_DMAOP_START); break; case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: printk("[IIS] dma trigger stop\n"); sw_dma_ctrl(prtd->params->channel, SW_DMAOP_STOP); break; default: ret = -EINVAL; break; } spin_unlock(&prtd->lock); return 0; }
static int sun4i_pcm_trigger(struct snd_pcm_substream *substream, int cmd) { struct sun4i_runtime_data *prtd = substream->runtime->private_data; int ret ; spin_lock(&prtd->lock); switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: // spin_lock(&prtd->lock); // prtd->dma_loaded--; // sun4i_pcm_enqueue(substream); // spin_unlock(&prtd->lock); printk("[HDMI-AUDIO] PCM trigger start...\n"); sw_dma_ctrl(prtd->params->channel, SW_DMAOP_START); break; case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: printk("[HDMI-AUDIO] PCM trigger stop...\n"); sw_dma_ctrl(prtd->params->channel, SW_DMAOP_STOP); break; default: ret = -EINVAL; break; } spin_unlock(&prtd->lock); return 0; }
static int sun5i_pcm_trigger(struct snd_pcm_substream *substream, int cmd) { struct sun5i_runtime_data *prtd = substream->runtime->private_data; int ret ; spin_lock(&prtd->lock); switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: printk("[SPDIF] dma trigger start\n"); sw_dma_ctrl(prtd->params->channel, SW_DMAOP_START); break; case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: sw_dma_ctrl(prtd->params->channel, SW_DMAOP_STOP); break; default: ret = -EINVAL; break; } spin_unlock(&prtd->lock); return 0; }
static int sun4i_pcm_prepare(struct snd_pcm_substream *substream) { struct sun4i_runtime_data *prtd = substream->runtime->private_data; struct dma_hw_conf codec_dma_conf; int ret = 0; if (!prtd->params) return 0; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){ codec_dma_conf.drqsrc_type = DRQ_TYPE_SDRAM; codec_dma_conf.drqdst_type = DRQ_TYPE_IIS; codec_dma_conf.xfer_type = DMAXFER_D_BHALF_S_BHALF; codec_dma_conf.address_type = DMAADDRT_D_FIX_S_INC; codec_dma_conf.dir = SW_DMA_WDEV; codec_dma_conf.reload = 0; codec_dma_conf.hf_irq = SW_DMA_IRQ_FULL; codec_dma_conf.from = prtd->dma_start; codec_dma_conf.to = prtd->params->dma_addr; ret = sw_dma_config(prtd->params->channel, &codec_dma_conf); } /* flush the DMA channel */ sw_dma_ctrl(prtd->params->channel, SW_DMAOP_FLUSH); prtd->dma_loaded = 0; prtd->dma_pos = prtd->dma_start; /* enqueue dma buffers */ sun4i_pcm_enqueue(substream); return ret; }
static int sun5i_spdif_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { int ret = 0; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct sun5i_dma_params *dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { sun5i_snd_rxctrl(1); } else { sun5i_snd_txctrl(substream, 1); } sw_dma_ctrl(dma_data->channel, SW_DMAOP_STARTED); break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { sun5i_snd_rxctrl(0); } else { sun5i_snd_txctrl(substream, 0); } break; default: ret = -EINVAL; break; } return ret; }
static int sun4i_pcm_hw_free(struct snd_pcm_substream *substream) { struct sun4i_runtime_data *prtd = substream->runtime->private_data; /* TODO - do we need to ensure DMA flushed */ if(prtd->params) sw_dma_ctrl(prtd->params->channel, SW_DMAOP_FLUSH); snd_pcm_set_runtime_buffer(substream, NULL); if (prtd->params) { sw_dma_free(prtd->params->channel, prtd->params->client); prtd->params = NULL; } return 0; }
static int sun4i_pcm_prepare(struct snd_pcm_substream *substream) { struct sun4i_runtime_data *prtd = substream->runtime->private_data; struct dma_hw_conf codec_dma_conf; int ret = 0; // codec_dma_conf = kmalloc(sizeof(struct dma_hw_conf), GFP_KERNEL); // if (!codec_dma_conf) // { // ret = - ENOMEM; // return ret; // } if (!prtd->params) return 0; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){ codec_dma_conf.drqsrc_type = DRQ_TYPE_SDRAM; codec_dma_conf.drqdst_type = DRQ_TYPE_HDMIAUDIO; codec_dma_conf.xfer_type = DMAXFER_D_BWORD_S_BWORD; codec_dma_conf.address_type = DMAADDRT_D_IO_S_LN; codec_dma_conf.dir = SW_DMA_WDEV; codec_dma_conf.reload = 0; codec_dma_conf.hf_irq = SW_DMA_IRQ_FULL; codec_dma_conf.from = prtd->dma_start; codec_dma_conf.to = prtd->params->dma_addr; codec_dma_conf.cmbk = 0x1F071F07; ret = sw_dma_config(prtd->params->channel, &codec_dma_conf); } /* flush the DMA channel */ sw_dma_ctrl(prtd->params->channel, SW_DMAOP_FLUSH); prtd->dma_loaded = 0; prtd->dma_pos = prtd->dma_start; /* enqueue dma buffers */ sun4i_pcm_enqueue(substream); return ret; }
int wemac_dma_config_start(__u8 rw, void * buff_addr, __u32 len) { int ret; if(rw == 0){ struct dma_hw_conf emac_hwconf = { .xfer_type = DMAXFER_D_SWORD_S_SWORD, .hf_irq = SW_DMA_IRQ_FULL, .cmbk = 0x03030303, .dir = SW_DMA_RDEV, .from = 0x01C0B04C, .address_type = DMAADDRT_D_LN_S_IO, .drqsrc_type = DRQ_TYPE_EMAC }; ret = sw_dma_setflags(ch_rx, SW_DMAF_AUTOSTART); if(ret!=0) return ret; ret = sw_dma_config(ch_rx, &emac_hwconf); if(ret!=0) return ret; ret = emacrx_DMAEqueueBuf(ch_rx, buff_addr, len); if(ret!=0) return ret; ret = sw_dma_ctrl(ch_rx, SW_DMAOP_START); } else { struct dma_hw_conf emac_hwconf = { .xfer_type = DMAXFER_D_SWORD_S_SWORD, .hf_irq = SW_DMA_IRQ_FULL, .cmbk = 0x03030303, .dir = SW_DMA_WDEV, .to = 0x01C0B024, .address_type = DMAADDRT_D_IO_S_LN, .drqdst_type = DRQ_TYPE_EMAC }; ret = sw_dma_setflags(ch_tx, SW_DMAF_AUTOSTART); if(ret!=0) return ret; ret = sw_dma_config(ch_tx, &emac_hwconf); if(ret!=0) return ret; ret = emactx_DMAEqueueBuf(ch_tx, buff_addr, len); if(ret!=0) return ret; ret = sw_dma_ctrl(ch_tx, SW_DMAOP_START); } return 0; } __s32 emacrx_WaitDmaFinish(void) { unsigned long flags; int i; while(1){ local_irq_save(flags); if (emacrx_dma_completed_flag){ local_irq_restore(flags); break; } for(i=0;i<1000;i++); local_irq_restore(flags); } return 0; }