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;
}
Beispiel #2
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;
}
Beispiel #7
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;	
}
Beispiel #8
0
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;
}