예제 #1
0
static int rockchip_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{
	struct rockchip_runtime_data *prtd = substream->runtime->private_data;
	int ret = 0;
	/**************add by qiuen for volume*****/
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
	struct snd_soc_dai *pCodec_dai = rtd->codec_dai;
#else
	struct snd_soc_dai *pCodec_dai = rtd->dai->codec_dai;
#endif
	int vol = 0;
	int streamType = 0;
	
	DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
	
	if(cmd==SNDRV_PCM_TRIGGER_VOLUME){
		vol = substream->number % 100;
		streamType = (substream->number / 100) % 100;
		DBG("enter:vol=%d,streamType=%d\n",vol,streamType);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
		if(pCodec_dai->driver->ops->set_volume)
			pCodec_dai->driver->ops->set_volume(streamType, vol);
#else
		if(pCodec_dai->ops->set_volume)
			pCodec_dai->ops->set_volume(streamType, vol);
#endif
	}
	/****************************************************/
	spin_lock(&prtd->lock);

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
	        DBG(" START \n");
	    prtd->state |= ST_RUNNING;
	    rk29_dma_ctrl(prtd->params->channel, RK29_DMAOP_START);
		break;
	case SNDRV_PCM_TRIGGER_RESUME:
	    DBG(" RESUME \n");
	    break;
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		DBG(" RESTART \n");
		break;

	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_SUSPEND:
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
	    DBG(" STOPS \n");
		prtd->state &= ~ST_RUNNING;
		rk29_dma_ctrl(prtd->params->channel, RK29_DMAOP_STOP);
		break;
	default:
		ret = -EINVAL;
		break;
	}

	spin_unlock(&prtd->lock);
	return ret;
}
예제 #2
0
static int dma_stop(struct rk_mmc *host)
{	
	int res;
	u32 temp;
	
	/* Disable and reset the DMA interface */
	temp = mmc_readl(host, CTRL);
	temp &= ~MMC_CTRL_DMA_ENABLE;
	temp |= MMC_CTRL_DMA_RESET;
	mmc_writel(host, CTRL, temp);

	res = rk29_dma_ctrl(MMC_DMA_CHN, RK29_DMAOP_STOP);
	if(unlikely(res < 0))
		return res;

	rk29_dma_ctrl(MMC_DMA_CHN, RK29_DMAOP_FLUSH);

	return 0;
}
예제 #3
0
static ssize_t memcpy_dma_write(struct device *device, struct device_attribute *attr, const char *argv, size_t count)
{
    int rt;
    struct Dma_MemToMem  *DmaMemInfo = (struct Dma_MemToMem *)argv;
 
    rt = rk29_dma_devconfig(DMACH_DMAC0_MEMTOMEM, RK29_DMASRC_MEMTOMEM, DmaMemInfo->SrcAddr);
    rt = rk29_dma_enqueue(DMACH_DMAC0_MEMTOMEM, NULL, DmaMemInfo->DstAddr, DmaMemInfo->MenSize);
    rt = rk29_dma_ctrl(DMACH_DMAC0_MEMTOMEM, RK29_DMAOP_START);    
    wait_event_interruptible_timeout(wq, wq_condition, 200);
    wq_condition = 0;  
	//init_waitqueue_head(&dma_memcpy_wait);
	//interruptible_sleep_on(&dma_memcpy_wait);
    return 0;
}
예제 #4
0
static int rockchip_pcm_prepare(struct snd_pcm_substream *substream)
{
	struct rockchip_runtime_data *prtd = substream->runtime->private_data;
	int ret = 0;

	DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);

	/* return if this is a bufferless transfer e.g.
	 * codec <--> BT codec or GSM modem -- lg FIXME */
	if (!prtd->params)
		return 0;

        if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
                ret = rk29_dma_devconfig(prtd->params->channel, 
                               RK29_DMASRC_MEM, 
                               prtd->params->dma_addr);
        }else{
                ret = rk29_dma_devconfig(prtd->params->channel, 
                               RK29_DMASRC_HW, 
                               prtd->params->dma_addr);
        }
        DBG("Enter::%s, %d, ret=%d, Channel=%d, Addr=0x%X\n", __FUNCTION__, __LINE__, ret, prtd->params->channel, prtd->params->dma_addr);
        ret = rk29_dma_config(prtd->params->channel, 
                prtd->params->dma_size, 1);
		prtd->params->flag = 1;  

        DBG("Enter:%s, %d, ret = %d, Channel=%d, Size=%d\n", 
                __FUNCTION__, __LINE__, ret, prtd->params->channel, 
                prtd->params->dma_size);
                
        ret= rk29_dma_ctrl(prtd->params->channel, RK29_DMAOP_FLUSH);
        DBG("Enter:%s, %d, ret = %d, Channel=%d\n", 
                __FUNCTION__, __LINE__, ret, prtd->params->channel);
        
	prtd->dma_loaded = 0;
	prtd->dma_pos = prtd->dma_start;

	/* enqueue dma buffers */
	rockchip_pcm_enqueue(substream);
	return ret;
}
예제 #5
0
static int dma_start(struct rk_mmc *host)
{
	int i, res, direction, sg_len;
	enum rk29_dmasrc src;
	struct mmc_data *data = host->data;
	
	BUG_ON(!data);

	host->dma_xfer_size = 0;

	if (data->flags & MMC_DATA_READ){
		direction = DMA_FROM_DEVICE;
		src = RK29_DMASRC_HW;
	}else{
		direction = DMA_TO_DEVICE;
		src = RK29_DMASRC_MEM;
	}

	sg_len = rk_mmc_pre_dma_transfer(host, host->data, 0);
	if(sg_len < 0){
		host->ops->stop(host);
		return sg_len;
	}
	res = rk29_dma_devconfig(MMC_DMA_CHN, src, host->dma_addr);
	if(unlikely(res < 0))
		return res;

	for(i = 0; i < sg_len; i++){
		res = rk29_dma_enqueue(MMC_DMA_CHN, host, 
				sg_dma_address(&data->sg[i]),
				sg_dma_len(&data->sg[i]));
		if(unlikely(res < 0))
			return res;
	}
	res = rk29_dma_ctrl(MMC_DMA_CHN, RK29_DMAOP_START);
	if(unlikely(res < 0))
		return res;

	return res;
}