From 8971e7babe429452199c62fbb84817dc17dd214e Mon Sep 17 00:00:00 2001
From: =?utf8?q?=E9=82=B1=E5=BB=BA=E6=96=8C?= <qjb@rock-chips.com>
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