From 8971e7babe429452199c62fbb84817dc17dd214e Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E9=82=B1=E5=BB=BA=E6=96=8C?= Date: Thu, 7 Jun 2012 16:53:04 +0800 Subject: [PATCH] rk30: support sound capture DMA buffer in internal SRAM --- arch/arm/plat-rk/Kconfig | 2 +- sound/soc/rk29/rk29_pcm.c | 105 ++++++++++++++++++-------------------- 2 files changed, 50 insertions(+), 57 deletions(-) diff --git a/arch/arm/plat-rk/Kconfig b/arch/arm/plat-rk/Kconfig index c02435d6cb14..feeb4da065c1 100644 --- a/arch/arm/plat-rk/Kconfig +++ b/arch/arm/plat-rk/Kconfig @@ -133,7 +133,7 @@ config RK_DEBUG_UART Select a UART for debugging. -1 disable. config RK_SRAM_DMA - bool "Sound playback DMA buffer in internal SRAM" + bool "Sound DMA buffer in internal SRAM" depends on ARCH_RK30 endif diff --git a/sound/soc/rk29/rk29_pcm.c b/sound/soc/rk29/rk29_pcm.c index 048038077c62..20b21e391f3d 100755 --- a/sound/soc/rk29/rk29_pcm.c +++ b/sound/soc/rk29/rk29_pcm.c @@ -31,7 +31,7 @@ #define PCM_DMA_DEBUG 0 #if 0 -#define DBG(x...) printk(KERN_INFO x) +#define DBG(x...) printk(KERN_DEBUG x) #else #define DBG(x...) do { } while (0) #endif @@ -50,13 +50,13 @@ static const struct snd_pcm_hardware rockchip_pcm_hardware = { .channels_min = 2, .channels_max = 8, #ifdef CONFIG_RK_SRAM_DMA - .buffer_bytes_max = 48*1024, + .buffer_bytes_max = 24*1024,//period_bytes_max * periods_max #else .buffer_bytes_max = 128*1024, #endif .period_bytes_min = 64, ///PAGE_SIZE, #ifdef CONFIG_RK_SRAM_DMA - .period_bytes_max = 4096*4, + .period_bytes_max = 8*1024, #else .period_bytes_max = 2048*4,///PAGE_SIZE*2, #endif @@ -99,12 +99,11 @@ static void rockchip_pcm_enqueue(struct snd_pcm_substream *substream) dma_addr_t pos = prtd->dma_pos; int ret; - DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); +// DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); - while (prtd->dma_loaded < prtd->dma_limit) { + while (prtd->dma_loaded < prtd->dma_limit) { unsigned long len = prtd->dma_period; - - DBG("dma_loaded: %d\n", prtd->dma_loaded); +// DBG("dma_loaded: %d\n", prtd->dma_loaded); if ((pos + len) > prtd->dma_end) { len = prtd->dma_end - pos; } @@ -125,11 +124,10 @@ static void rockchip_pcm_enqueue(struct snd_pcm_substream *substream) } - ret = rk29_dma_enqueue(prtd->params->channel, - substream, pos, len); - - DBG("Enter::%s, %d, ret=%d, Channel=%d, Addr=0x%X, Len=%lu\n", - __FUNCTION__,__LINE__, ret, prtd->params->channel, pos, len); + ret = rk29_dma_enqueue(prtd->params->channel,substream, pos, len); +// if(prtd->params->channel == 2) + DBG("Enter::%s, %d, ret=%d, Channel=%d, Addr=0x%X, Len=%lu\n", + __FUNCTION__,__LINE__, ret, prtd->params->channel, pos, len); if (ret == 0) { prtd->dma_loaded++; pos += prtd->dma_period; @@ -145,7 +143,7 @@ static void rockchip_pcm_enqueue(struct snd_pcm_substream *substream) void rk29_audio_buffdone(void *dev_id, int size, enum rk29_dma_buffresult result) { - struct snd_pcm_substream *substream = dev_id; + struct snd_pcm_substream *substream = dev_id; struct rockchip_runtime_data *prtd; #if PCM_DMA_DEBUG static ktime_t before = {0},after = {0}; @@ -165,27 +163,30 @@ void rk29_audio_buffdone(void *dev_id, int size, #endif DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); - if (!substream) + if (!substream){ + DBG("substream is free\n"); return; - if (!substream->runtime) + } + if (!substream->runtime){ + DBG("substream->runtime is free\n"); return; + } switch(result) { case RK29_RES_OK: - DBG("::%s----%d RK29_RES_OK\n",__FUNCTION__,__LINE__); break; case RK29_RES_ERR: - DBG("::%s----%d RK29_RES_ERR\n",__FUNCTION__,__LINE__); - break; case RK29_RES_ABORT: - DBG("Enter::%s----%d RK29_RES_ABORT \n",__FUNCTION__,__LINE__); + DBG("Enter::%s dma about or error result = %d \n",__FUNCTION__,result); return; } prtd = substream->runtime->private_data; + +// if(prtd->params->channel == 2) + DBG("Enter::%s----%d channel =%d \n",__FUNCTION__,__LINE__); if(!(prtd->state & ST_RUNNING)) return; - DBG("Enter::%s----%d, substream=%p, prtd=%p\n",__FUNCTION__,__LINE__, substream, prtd); if (substream){ snd_pcm_period_elapsed(substream); } @@ -215,15 +216,6 @@ static int rockchip_pcm_hw_params(struct snd_pcm_substream *substream, int ret = 0; DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); - /*by Vincent Hsiung for EQ Vol Change*/ - #define HW_PARAMS_FLAG_EQVOL_ON 0x21 - #define HW_PARAMS_FLAG_EQVOL_OFF 0x22 - - if ((params->flags == HW_PARAMS_FLAG_EQVOL_ON)||(params->flags == HW_PARAMS_FLAG_EQVOL_OFF)) - { - return 0; - } - /* return if this is a bufferless transfer e.g. * codec <--> BT codec or GSM modem -- lg FIXME */ if (!dma) @@ -235,19 +227,9 @@ static int rockchip_pcm_hw_params(struct snd_pcm_substream *substream, /* prepare DMA */ prtd->params = dma; #ifdef CONFIG_SND_I2S_DMA_EVENT_DYNAMIC - DBG("params %p, client %p, channel %d\n", prtd->params, - prtd->params->client, prtd->params->channel); - - ret = rk29_dma_request(prtd->params->channel, prtd->params->client, NULL); - DBG("Enter::%s, %d, ret=%d, Channel=%d\n", __FUNCTION__, __LINE__, ret, prtd->params->channel); -/* - if(ret){ - for(prtd->params->channel=5;prtd->params->channel>0;prtd->params->channel--){ - ret = request_dma(prtd->params->channel, "i2s"); - if(!ret)break; - } - } -*/ + DBG("params %p, client %p, channel %d\n", prtd->params,prtd->params->client, prtd->params->channel); + ret = rk29_dma_request(prtd->params->channel, prtd->params->client, NULL); + DBG("Enter::%s, %d, ret=%d, Channel=%d\n", __FUNCTION__, __LINE__, ret, prtd->params->channel); if (ret) { DBG(KERN_ERR "failed to get dma channel\n"); return ret; @@ -255,15 +237,18 @@ static int rockchip_pcm_hw_params(struct snd_pcm_substream *substream, #endif } - rk29_dma_set_buffdone_fn(prtd->params->channel, rk29_audio_buffdone); - + ret = rk29_dma_set_buffdone_fn(prtd->params->channel, rk29_audio_buffdone); + if(ret < 0){ + DBG(KERN_ERR "failed to rk29_dma_set_buffdone_fn\n"); + return ret; + } snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); runtime->dma_bytes = totbytes; spin_lock_irq(&prtd->lock); prtd->dma_loaded = 0; - prtd->dma_limit = runtime->hw.periods_min; + prtd->dma_limit = params_periods(params);//runtime->hw.periods_min; prtd->dma_period = params_period_bytes(params); prtd->dma_start = runtime->dma_addr; prtd->dma_pos = prtd->dma_start; @@ -273,7 +258,7 @@ static int rockchip_pcm_hw_params(struct snd_pcm_substream *substream, prtd->next = NULL; prtd->end = NULL; spin_unlock_irq(&prtd->lock); - return 0; + return ret; } static int rockchip_pcm_hw_free(struct snd_pcm_substream *substream) @@ -406,10 +391,10 @@ rockchip_pcm_pointer(struct snd_pcm_substream *substream) dma_addr_t src, dst; snd_pcm_uframes_t ret; - DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); + spin_lock(&prtd->lock); - rk29_dma_getposition(prtd->params->channel, &src, &dst); + rk29_dma_getposition(prtd->params->channel, &src, &dst); if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) res = dst - prtd->dma_start; @@ -418,11 +403,13 @@ rockchip_pcm_pointer(struct snd_pcm_substream *substream) spin_unlock(&prtd->lock); - DBG("Pointer %x %x\n",src,dst); - ret = bytes_to_frames(runtime, res); if (ret == runtime->buffer_size) ret = 0; + + if(prtd->params->channel == 2) + DBG("Enter:%s src = %x res = %x ret = %d\n",__FUNCTION__,src,res,ret); + return ret; } @@ -501,8 +488,10 @@ static struct snd_pcm_ops rockchip_pcm_ops = { }; #ifdef CONFIG_ARCH_RK30 -#define SRAM_DMA_PHYS (dma_addr_t)(RK30_IMEM_PHYS + 16*1024) -#define SRAM_DMA_START (RK30_IMEM_NONCACHED + 16*1024) +#define SRAM_DMA_PHYS_PLAYBACK (dma_addr_t)(RK30_IMEM_PHYS + 16*1024) +#define SRAM_DMA_START_PLAYBACK (RK30_IMEM_NONCACHED + 16*1024) +#define SRAM_DMA_PHYS_CAPTURE (dma_addr_t)(SRAM_DMA_PHYS_PLAYBACK + 24*1024) +#define SRAM_DMA_START_CAPTURE (SRAM_DMA_START_PLAYBACK + 24*1024) #endif static int rockchip_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) @@ -518,12 +507,16 @@ static int rockchip_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) buf->private_data = NULL; #ifdef CONFIG_RK_SRAM_DMA if (stream == SNDRV_PCM_STREAM_PLAYBACK) { - buf->area = SRAM_DMA_START; - buf->addr = SRAM_DMA_PHYS; - } else -#endif + buf->area = SRAM_DMA_START_PLAYBACK; + buf->addr = SRAM_DMA_PHYS_PLAYBACK; + } else{ + buf->area = SRAM_DMA_START_CAPTURE; + buf->addr = SRAM_DMA_PHYS_CAPTURE; + } +#else buf->area = dma_alloc_writecombine(pcm->card->dev, size, &buf->addr, GFP_KERNEL); +#endif if (!buf->area) return -ENOMEM; buf->bytes = size; -- 2.34.1