From: yzq Date: Mon, 6 May 2013 13:05:03 +0000 (+0800) Subject: Revert "rk3188: spdif support" X-Git-Tag: firefly_0821_release~7153 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=4a0528ea18ffcd132ccf2fb1d6a365172b153b67;p=firefly-linux-kernel-4.4.55.git Revert "rk3188: spdif support" This reverts commit 20b654aab5ddc3650aa3bb7d8f5359c43df8567d. --- diff --git a/arch/arm/mach-rk30/devices.c b/arch/arm/mach-rk30/devices.c index a51ae35545c6..32ddb4b9f1a4 100755 --- a/arch/arm/mach-rk30/devices.c +++ b/arch/arm/mach-rk30/devices.c @@ -1112,35 +1112,6 @@ static void __init rk30_init_sdmmc(void) #endif } -#ifdef CONFIG_SND_RK_SOC_SPDIF -static struct resource resources_spdif[] = { - [0] = { - .name = "spdif_base", - .start = RK30_SPDIF_PHYS, - .end = RK30_SPDIF_PHYS + RK30_SPDIF_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .name = "spdif_irq", - .start = IRQ_SPDIF, - .end = IRQ_SPDIF, - .flags = IORESOURCE_IRQ, - }, - [2] = { - .name = "spdif_dma", - .start = DMACH_SPDIF_TX, - .end = DMACH_SPDIF_TX, - .flags = IORESOURCE_DMA, - }, -}; -struct platform_device rk29_device_spdif = { - .name = "rk-spdif", - .id = 0, - .num_resources = ARRAY_SIZE(resources_spdif), - .resource = resources_spdif, -}; -#endif - #ifdef CONFIG_RK29_VMAC static u64 eth_dmamask = DMA_BIT_MASK(32); static struct resource resources_vmac[] = { @@ -1249,10 +1220,6 @@ static int __init rk30_init_devices(void) rk_serial_debug_init(DEBUG_UART_BASE, IRQ_DEBUG_UART, IRQ_UART_SIGNAL, -1); #endif rk30_init_i2s(); - -#ifdef CONFIG_SND_RK_SOC_SPDIF - platform_device_register(&rk29_device_spdif); -#endif #ifdef CONFIG_RK29_VMAC platform_device_register(&device_vmac); #endif diff --git a/sound/soc/rk29/Kconfig b/sound/soc/rk29/Kconfig index 682fb18917b4..739f55e24c49 100755 --- a/sound/soc/rk29/Kconfig +++ b/sound/soc/rk29/Kconfig @@ -42,9 +42,6 @@ config SND_RK_SOC_I2S2_2CH help This supports the use of the 2 Channel I2S2 interface on rk30 processors. -config SND_ROCKCHIP_SPDIF - tristate - select SND_SOC_SPDIF if SND_RK29_SOC_I2S_2CH || SND_RK29_SOC_I2S_8CH || SND_RK_SOC_I2S2_2CH choice bool "Set i2s on DMA event mode" @@ -56,14 +53,7 @@ choice tristate "static mode" endchoice endif -config SND_RK_SOC_SPDIF - bool "spdif support for rockchip rk29 or rk30" - depends on SND_RK29_SOC - select SND_ROCKCHIP_SPDIF - help - Say Y if you want to add support for SoC audio on rockchip - with the spdif. - + config SND_RK29_SOC_SPDIF bool "Soc RK29 SPDIF support" depends on SND_RK29_SOC diff --git a/sound/soc/rk29/Makefile b/sound/soc/rk29/Makefile index 728bdae8dcde..cfd5e3bbc1a2 100755 --- a/sound/soc/rk29/Makefile +++ b/sound/soc/rk29/Makefile @@ -5,11 +5,11 @@ snd-soc-rockchip-i2s-objs := rk29_i2s.o else snd-soc-rockchip-i2s-objs := rk30_i2s.o endif -snd-soc-rockchip-spdif-objs := spdif.o +snd-soc-rockchip-spdif-objs := rk29_spdif.o obj-$(CONFIG_SND_RK29_SOC) += snd-soc-rockchip.o obj-$(CONFIG_SND_RK29_SOC_I2S) += snd-soc-rockchip-i2s.o -obj-$(CONFIG_SND_ROCKCHIP_SPDIF) += snd-soc-rockchip-spdif.o +obj-$(CONFIG_SND_RK29_SOC_SPDIF) += snd-soc-rockchip-spdif.o # ROCKCHIP Machine Support snd-soc-wm8900-objs := rk29_wm8900.o @@ -33,7 +33,6 @@ snd-soc-rk616-objs := rk_rk616.o snd-soc-aic3262-objs := rk29_aic3262.o snd-soc-rk2928-objs := rk2928-card.o snd-soc-es8323-objs := rk29_es8323.o -snd-soc-rk_spdif-objs := rk_spdif.o obj-$(CONFIG_SND_RK29_SOC_WM8994) += snd-soc-wm8994.o obj-$(CONFIG_SND_RK29_SOC_WM8988) += snd-soc-wm8988.o @@ -54,6 +53,5 @@ obj-$(CONFIG_SND_RK29_SOC_AIC3262) += snd-soc-aic3262.o obj-$(CONFIG_SND_RK29_SOC_HDMI) += snd-soc-hdmi.o obj-$(CONFIG_SND_RK29_SOC_RK610) += snd-soc-rk610.o obj-$(CONFIG_SND_RK29_SOC_RK616) += snd-soc-rk616.o -obj-$(CONFIG_SND_RK_SOC_SPDIF) += snd-soc-rk_spdif.o obj-$(CONFIG_SND_RK_SOC_RK2928) += snd-soc-rk2928.o obj-$(CONFIG_SND_RK29_SOC_ES8323) += snd-soc-es8323.o diff --git a/sound/soc/rk29/rk29_pcm.c b/sound/soc/rk29/rk29_pcm.c index 4c37b4dd0ccf..69b871a3bd98 100755 --- a/sound/soc/rk29/rk29_pcm.c +++ b/sound/soc/rk29/rk29_pcm.c @@ -28,6 +28,7 @@ #include "rk29_pcm.h" +#define PCM_DMA_DEBUG 0 #if 0 #define DBG(x...) printk(KERN_INFO x) @@ -35,6 +36,12 @@ #define DBG(x...) do { } while (0) #endif +#define INFIN_LOOP +#ifdef INFIN_LOOP +#define DMA_INFIN_LOOP() rk29_dma_has_infiniteloop() +#else +#define DMA_INFIN_LOOP() 0 +#endif static const struct snd_pcm_hardware rockchip_pcm_hardware = { .info = SNDRV_PCM_INFO_INTERLEAVED | @@ -48,9 +55,17 @@ static const struct snd_pcm_hardware rockchip_pcm_hardware = { SNDRV_PCM_FMTBIT_S16_LE, .channels_min = 2, .channels_max = 8, +#ifdef CONFIG_RK_SRAM_DMA + .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 = 8*1024, +#else .period_bytes_max = 2048*4,///PAGE_SIZE*2, +#endif .periods_min = 3,///2, .periods_max = 128, .fifo_size = 16, @@ -88,92 +103,125 @@ static void rockchip_pcm_enqueue(struct snd_pcm_substream *substream) { struct rockchip_runtime_data *prtd = substream->runtime->private_data; dma_addr_t pos = prtd->dma_pos; + unsigned int limit; int ret; - DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); - - while (prtd->dma_loaded < prtd->dma_limit) { - unsigned long len = prtd->dma_period; - - DBG("dma_loaded: %d\n", prtd->dma_loaded); - if ((pos + len) > prtd->dma_end) { - len = prtd->dma_end - pos; - } + DBG("Enter::%s----%d prtd->dma_period = %d prtd->dma_limit = %d\n",__FUNCTION__,__LINE__,prtd->dma_period,prtd->dma_limit); - if((len%(prtd->params->dma_size*16) == 0) && (prtd->params->flag == 1)) - { - ret = rk29_dma_config(prtd->params->channel, - prtd->params->dma_size, 16); - prtd->params->flag = 0; - DBG("size = 16, channel = %d, flag = %d\n",prtd->params->channel,prtd->params->flag); - } - else if((len%(prtd->params->dma_size*16) != 0) && (prtd->params->flag == 0)) - { - ret = rk29_dma_config(prtd->params->channel, - prtd->params->dma_size, 1); - prtd->params->flag = 1; - DBG("size = 1, channel = %d, flag = %d\n",prtd->params->channel,prtd->params->flag); - } + if (rk29_dma_has_circular()) + limit = (prtd->dma_end - prtd->dma_start) / prtd->dma_period; + else + limit = prtd->dma_limit; + + if (DMA_INFIN_LOOP()) { + if(prtd->dma_period % (prtd->params->dma_size*16)){ + printk("dma_period(%d) is not an integer multiple of dma_size(%d)",prtd->dma_period,prtd->params->dma_size*16); + rk29_dma_config(prtd->params->channel, + prtd->params->dma_size, 1); + } + else + rk29_dma_config(prtd->params->channel, + prtd->params->dma_size, 16); + ret = rk29_dma_enqueue_ring(prtd->params->channel, + substream, pos, prtd->dma_period, limit ,true); + if (ret == 0) + pos = prtd->dma_start; + } else { + while (prtd->dma_loaded < prtd->dma_limit) { + unsigned long len = prtd->dma_period; + // DBG("dma_loaded: %d\n", prtd->dma_loaded); + if ((pos + len) > prtd->dma_end) { + len = prtd->dma_end - pos; + } + if((len%(prtd->params->dma_size*16) == 0) && (prtd->params->flag == 1)) + { + ret = rk29_dma_config(prtd->params->channel, + prtd->params->dma_size, 16); + prtd->params->flag = 0; + DBG("size = 16, channel = %d, flag = %d\n",prtd->params->channel,prtd->params->flag); + } + else if((len%(prtd->params->dma_size*16) != 0) && (prtd->params->flag == 0)) + { + ret = rk29_dma_config(prtd->params->channel, + prtd->params->dma_size, 1); + prtd->params->flag = 1; + DBG("size = 1, channel = %d, flag = %d\n",prtd->params->channel,prtd->params->flag); + } - 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); - - if (ret == 0) { - prtd->dma_loaded++; - pos += prtd->dma_period; - if (pos >= prtd->dma_end) - pos = prtd->dma_start; - } else - break; - } + 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; + if (pos >= prtd->dma_end) + pos = prtd->dma_start; + } else + break; + } + } prtd->dma_pos = pos; } - void rk29_audio_buffdone(void *dev_id, int size, enum rk29_dma_buffresult result) { struct snd_pcm_substream *substream = dev_id; struct rockchip_runtime_data *prtd; - +#if PCM_DMA_DEBUG + static ktime_t before = {0},after = {0}; + s64 t; + before = after; + after = ktime_get(); + t = ktime_to_us(ktime_sub(after, before)); + if(result == RK29_RES_OK) + { + if(t > prtd->dma_period/4/44100 +73 && t != ktime_to_us(after)) // (23220)4096/4/44100 + 32/44100 + { + printk(KERN_DEBUG "Time out:: Audio DMA buffdone time out!!! the time = %lld!\n", t); + } + printk(KERN_DEBUG "audio DMA callback time = %lld\n", t); + } +// printk(KERN_DEBUG "a %d %d\n", size, result); +#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__,prtd->params->channel); 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); } spin_lock(&prtd->lock); - prtd->dma_loaded--; - if (prtd->state & ST_RUNNING) { + if (!DMA_INFIN_LOOP() && prtd->state & ST_RUNNING) { + prtd->dma_loaded--; rockchip_pcm_enqueue(substream); } - spin_unlock(&prtd->lock); - + spin_unlock(&prtd->lock); } static int rockchip_pcm_hw_params(struct snd_pcm_substream *substream, @@ -193,54 +241,39 @@ 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) return 0; -DBG("Enter::11111%s----%d\n",__FUNCTION__,__LINE__); + /* this may get called several times by oss emulation * with different params -HW */ if (prtd->params == NULL) { /* prepare DMA */ prtd->params = dma; - 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; - } - } -*/ +#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) { DBG(KERN_ERR "failed to get dma channel\n"); return ret; } +#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; @@ -250,8 +283,7 @@ DBG("Enter::11111%s----%d\n",__FUNCTION__,__LINE__); 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) @@ -260,12 +292,13 @@ static int rockchip_pcm_hw_free(struct snd_pcm_substream *substream) DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); /* TODO - do we need to ensure DMA flushed */ - snd_pcm_set_runtime_buffer(substream, NULL); if (prtd->params) { +#ifdef CONFIG_SND_I2S_DMA_EVENT_DYNAMIC rk29_dma_free(prtd->params->channel, prtd->params->client); prtd->params = NULL; +#endif } return 0; @@ -348,7 +381,6 @@ static int rockchip_pcm_trigger(struct snd_pcm_substream *substream, int 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: @@ -363,12 +395,7 @@ static int rockchip_pcm_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_PAUSE_PUSH: DBG(" STOPS \n"); prtd->state &= ~ST_RUNNING; - rk29_dma_ctrl(prtd->params->channel, RK29_DMAOP_STOP); -#ifdef CONFIG_ANDROID_POWER - android_unlock_suspend(&audio_lock ); - DBG("%s::stop audio , unlock system suspend\n" , __func__ ); -#endif break; default: ret = -EINVAL; @@ -388,12 +415,12 @@ rockchip_pcm_pointer(struct snd_pcm_substream *substream) unsigned long res; 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); - + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) res = dst - prtd->dma_start; else @@ -401,11 +428,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; } @@ -443,7 +472,6 @@ static int rockchip_pcm_close(struct snd_pcm_substream *substream) if (prtd->params) rk29_dma_set_buffdone_fn(prtd->params->channel, NULL); - sg_buf = prtd->curr; while (sg_buf != NULL) { @@ -464,12 +492,19 @@ static int rockchip_pcm_mmap(struct snd_pcm_substream *substream, { struct snd_pcm_runtime *runtime = substream->runtime; - DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); + DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); +#ifdef CONFIG_RK_SRAM_DMA + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); + return remap_pfn_range(vma, vma->vm_start, + substream->dma_buffer.addr >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, vma->vm_page_prot); +#else return dma_mmap_writecombine(substream->pcm->card->dev, vma, runtime->dma_area, runtime->dma_addr, runtime->dma_bytes); +#endif } static struct snd_pcm_ops rockchip_pcm_ops = { @@ -484,6 +519,14 @@ static struct snd_pcm_ops rockchip_pcm_ops = { .mmap = rockchip_pcm_mmap, }; +#if defined(CONFIG_ARCH_RK3066B) +#elif defined(CONFIG_ARCH_RK30) +#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) { struct snd_pcm_substream *substream = pcm->streams[stream].substream; @@ -495,8 +538,18 @@ static int rockchip_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) buf->dev.type = SNDRV_DMA_TYPE_DEV; buf->dev.dev = pcm->card->dev; buf->private_data = NULL; +#ifdef CONFIG_RK_SRAM_DMA + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { + 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; diff --git a/sound/soc/rk29/rk_spdif.c b/sound/soc/rk29/rk_spdif.c deleted file mode 100644 index 6ec311ed63bd..000000000000 --- a/sound/soc/rk29/rk_spdif.c +++ /dev/null @@ -1,186 +0,0 @@ -/*$_FOR_ROCKCHIP_RBOX_$*/ -/*$_rbox_$_modify_$_huangzhibao for spdif output*/ - -/* - * smdk_spdif.c -- S/PDIF audio for SMDK - * - * Copyright 2010 Samsung Electronics Co. Ltd. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - */ - -#include - -#include - -#include "spdif.h" -#include - -#if 0 -#define RK_SPDIF_DBG(x...) printk(KERN_INFO "rk_spdif:"x) -#else -#define RK_SPDIF_DBG(x...) do { } while (0) -#endif - - -static int set_audio_clock_rate(unsigned long pll_rate, - unsigned long audio_rate) -{ - struct clk *hclk_spdif, *sclk_spdif; - -#if defined (CONFIG_ARCH_RK30) || (CONFIG_ARCH_RK3188) - hclk_spdif = clk_get(NULL, "hclk_spdif"); - if (IS_ERR(hclk_spdif)) { - printk(KERN_ERR "spdif:failed to get hclk_spdif\n"); - return -ENOENT; - } - - clk_set_rate(hclk_spdif, pll_rate); - clk_put(hclk_spdif); -#endif - - sclk_spdif = clk_get(NULL, "spdif"); - if (IS_ERR(sclk_spdif)) { - printk(KERN_ERR "spdif:failed to get sclk_spdif\n"); - return -ENOENT; - } - - clk_set_rate(sclk_spdif, audio_rate); - clk_put(sclk_spdif); - - return 0; -} - -static int rk_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - unsigned long pll_out, rclk_rate; - int ret, ratio; - - RK_SPDIF_DBG("spdif:Entered %s\n", __func__); - - switch (params_rate(params)) { - case 44100: - pll_out = 11289600; - break; - case 32000: - pll_out = 8192000; - break; - case 48000: - pll_out = 12288000; - break; - case 96000: - pll_out = 24576000; - break; - default: - printk("rk_spdif: params not support\n"); - return -EINVAL; - } - - ratio = 256; - rclk_rate = params_rate(params) * ratio; - - /* Set audio source clock rates */ - ret = set_audio_clock_rate(pll_out, rclk_rate); - if (ret < 0) - return ret; - - /* Set S/PDIF uses internal source clock */ - //ret = snd_soc_dai_set_sysclk(cpu_dai, SND_SOC_SPDIF_INT_MCLK, - //rclk_rate, SND_SOC_CLOCK_IN); - //if (ret < 0) - //return ret; - - return ret; -} - -static struct snd_soc_ops rk_spdif_ops = { - .hw_params = rk_hw_params, -}; - -static struct snd_soc_dai_link rk_dai = { - .name = "SPDIF", - .stream_name = "SPDIF PCM Playback", - .platform_name = "rockchip-audio", - .cpu_dai_name = "rk-spdif.0", - .codec_dai_name = "dit-hifi", - .codec_name = "spdif-dit", - .ops = &rk_spdif_ops, -}; - -static struct snd_soc_card rk_spdif = { - .name = "ROCKCHIP-SPDIF", - .dai_link = &rk_dai, - .num_links = 1, -}; - -static struct platform_device *rk_snd_spdif_dit_device; -static struct platform_device *rk_snd_spdif_device; - -static int __init rk_spdif_init(void) -{ - int ret; - - RK_SPDIF_DBG("Entered %s\n", __func__); - - rk_snd_spdif_dit_device = platform_device_alloc("spdif-dit", -1); - if (!rk_snd_spdif_dit_device){ - printk("spdif:platform_device_alloc spdif-dit\n"); - return -ENOMEM; - } - ret = platform_device_add(rk_snd_spdif_dit_device); - if (ret) - goto err1; - - rk_snd_spdif_device = platform_device_alloc("soc-audio", -3); - if (!rk_snd_spdif_device) { - printk("spdif:platform_device_alloc rk_soc-audio\n"); - ret = -ENOMEM; - goto err2; - } - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) - platform_set_drvdata(rk_snd_spdif_device, &rk_spdif); -#else - platform_set_drvdata(rk_snd_spdif_device, &rk_spdif); - rk_spdif.dev = &rk_snd_spdif_device->dev; -#endif - - //platform_set_drvdata(rk_snd_spdif_device, &rk_spdif); - - ret = platform_device_add(rk_snd_spdif_device); - if (ret) - goto err3; - - RK_SPDIF_DBG("rk_spdif_init ok\n"); - return ret; -err3: - platform_device_put(rk_snd_spdif_device); -err2: - platform_device_del(rk_snd_spdif_dit_device); -err1: - platform_device_put(rk_snd_spdif_dit_device); - - return ret; -} - -static void __exit rk_spdif_exit(void) -{ - platform_device_unregister(rk_snd_spdif_device); - platform_device_unregister(rk_snd_spdif_dit_device); -} - -//using late_initcall to make sure spdif is after board codec. added by zxg. -//module_init(rk_spdif_init); -late_initcall(rk_spdif_init); -module_exit(rk_spdif_exit); - -MODULE_AUTHOR("hzb, "); -MODULE_DESCRIPTION("ALSA SoC RK+S/PDIF"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/rk29/spdif.c b/sound/soc/rk29/spdif.c deleted file mode 100644 index 53e4e7b12992..000000000000 --- a/sound/soc/rk29/spdif.c +++ /dev/null @@ -1,485 +0,0 @@ -/*$_FOR_ROCKCHIP_RBOX_$*/ -/*$_rbox_$_modify_$_huangzhibao for spdif output*/ - -/* sound/soc/rockchip/spdif.c - * - * ALSA SoC Audio Layer - rockchip S/PDIF Controller driver - * - * Copyright (c) 2010 rockchip Electronics Co. Ltd - * http://www.rockchip.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#if defined (CONFIG_ARCH_RK29) -#include -#endif - -#if defined (CONFIG_ARCH_RK30) -#include -#endif - -#if defined (CONFIG_ARCH_RK3188) -#include -#endif - -#include "rk29_pcm.h" -#include "spdif.h" - -#if 1 -#define RK_SPDIF_DBG(x...) printk(KERN_INFO "spdif:"x) -#else -#define RK_SPDIF_DBG(x...) do { } while (0) -#endif - - -/* Registers */ -#define CFGR 0x00 -#define SDBLR 0x04 -#define DMACR 0x08 -#define INTCR 0x0C -#define INTSR 0x10 -#define XFER 0x18 -#define SMPDR 0x20 - -#define DATA_OUTBUF 0x20 - -#define CFGR_MASK 0x0ffffff -#define CFGR_VALID_DATA_16bit (00) -#define CFGR_VALID_DATA_20bit (01) -#define CFGR_VALID_DATA_24bit (10) -#define CFGR_VALID_DATA_MASK (11) - -#define CFGR_HALFWORD_TX_ENABLE (0x1 << 2) -#define CFGR_HALFWORD_TX_DISABLE (0x0 << 2) -#define CFGR_HALFWORD_TX_MASK (0x1 << 2) - -#define CFGR_CLK_RATE_MASK (0xFF<<16) - -#define CFGR_JUSTIFIED_RIGHT (0<<3) -#define CFGR_JUSTIFIED_LEFT (1<<3) -#define CFGR_JUSTIFIED_MASK (1<<3) - -#define XFER_TRAN_STOP (0) -#define XFER_TRAN_START (1) -#define XFER_MASK (1) - -#define DMACR_TRAN_DMA_DISABLE (0<<5) -#define DMACR_TRAN_DMA_ENABLE (1<<5) -#define DMACR_TRAN_DMA_CTL_MASK (1<<5) - -#define DMACR_TRAN_DATA_LEVEL 0x10 -#define DMACR_TRAN_DATA_LEVEL_MASK 0x1F - -#define DMACR_TRAN_DMA_MASK (0x3F) - - - -struct rockchip_spdif_info { - spinlock_t lock; - struct device *dev; - void __iomem *regs; - unsigned long clk_rate; - struct clk *hclk; - struct clk *clk; - u32 saved_clkcon; - u32 saved_con; - u32 saved_cstas; - struct rockchip_pcm_dma_params *dma_playback; -}; - -static struct rk29_dma_client spdif_dma_client_out = { - .name = "SPDIF Stereo out" -}; - -static struct rockchip_pcm_dma_params spdif_stereo_out; - -static struct rockchip_spdif_info spdif_info; - -static inline struct rockchip_spdif_info *to_info(struct snd_soc_dai *cpu_dai) -{ - return snd_soc_dai_get_drvdata(cpu_dai); -} - -static void spdif_snd_txctrl(struct rockchip_spdif_info *spdif, int on) -{ - void __iomem *regs = spdif->regs; - u32 opr,xfer; - - RK_SPDIF_DBG( "Entered %s\n", __func__); - - xfer = readl(regs + XFER) & XFER_MASK; - opr = readl(regs + DMACR) & DMACR_TRAN_DMA_MASK & (~DMACR_TRAN_DMA_CTL_MASK); - - if (on){ - xfer |= XFER_TRAN_START; - opr |= DMACR_TRAN_DMA_ENABLE; - writel(xfer, regs + XFER); - writel(opr|0x10, regs + DMACR); - RK_SPDIF_DBG("on xfer=0x%x,opr=0x%x\n",readl(regs + XFER),readl(regs + DMACR)); - } else{ - xfer &= ~XFER_TRAN_START; - opr &= ~DMACR_TRAN_DMA_ENABLE; - writel(xfer, regs + XFER); - writel(opr|0x10, regs + DMACR); - } -} - -static int spdif_set_syclk(struct snd_soc_dai *cpu_dai, - int clk_id, unsigned int freq, int dir) -{ - struct rockchip_spdif_info *spdif = to_info(cpu_dai); - u32 clkcon; - - RK_SPDIF_DBG("Entered %s\n", __func__); - - spdif->clk_rate = freq; - - return 0; -} - -static int spdif_trigger(struct snd_pcm_substream *substream, int cmd, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct rockchip_spdif_info *spdif = to_info(rtd->cpu_dai); - unsigned long flags; - - RK_SPDIF_DBG( "Entered %s\n", __func__); - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - spin_lock_irqsave(&spdif->lock, flags); - spdif_snd_txctrl(spdif, 1); - spin_unlock_irqrestore(&spdif->lock, flags); - break; - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - spin_lock_irqsave(&spdif->lock, flags); - spdif_snd_txctrl(spdif, 0); - spin_unlock_irqrestore(&spdif->lock, flags); - break; - default: - return -EINVAL; - } - - return 0; -} - - -static int spdif_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *socdai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct rockchip_spdif_info *spdif = to_info(rtd->cpu_dai); - void __iomem *regs = spdif->regs; - struct rockchip_pcm_dma_params *dma_data; - unsigned long flags; - int i, cfgr, dmac; - - RK_SPDIF_DBG("Entered %s\n", __func__); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - dma_data = spdif->dma_playback; - else { - printk("spdif:Capture is not supported\n"); - return -EINVAL; - } - - snd_soc_dai_set_dma_data(rtd->cpu_dai, substream, dma_data); - spin_lock_irqsave(&spdif->lock, flags); - - cfgr = readl(regs + CFGR) & CFGR_VALID_DATA_MASK; - - cfgr &= ~CFGR_VALID_DATA_MASK; - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: - cfgr |= CFGR_VALID_DATA_16bit; - break; - case SNDRV_PCM_FMTBIT_S20_3LE : - cfgr |= CFGR_VALID_DATA_20bit; - break; - case SNDRV_PCM_FORMAT_S24_LE: - cfgr |= CFGR_VALID_DATA_24bit; - break; - default: - goto err; - } - - cfgr &= ~CFGR_HALFWORD_TX_MASK; - cfgr |= CFGR_HALFWORD_TX_ENABLE; - - cfgr &= ~CFGR_CLK_RATE_MASK; - cfgr |= (1<<16); - - cfgr &= ~CFGR_JUSTIFIED_MASK; - cfgr |= CFGR_JUSTIFIED_RIGHT; - - writel(cfgr, regs + CFGR); - - dmac = readl(regs + DMACR) & DMACR_TRAN_DMA_MASK & (~DMACR_TRAN_DATA_LEVEL_MASK); - dmac |= 0x10; - writel(dmac, regs + DMACR); - - spin_unlock_irqrestore(&spdif->lock, flags); - - return 0; -err: - spin_unlock_irqrestore(&spdif->lock, flags); - return -EINVAL; -} - -static void spdif_shutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct rockchip_spdif_info *spdif = to_info(rtd->cpu_dai); - void __iomem *regs = spdif->regs; - u32 con, clkcon; - - RK_SPDIF_DBG( "spdif:Entered %s\n", __func__); - -} - -#ifdef CONFIG_PM -static int spdif_suspend(struct snd_soc_dai *cpu_dai) -{ - struct rockchip_spdif_info *spdif = to_info(cpu_dai); - u32 con = spdif->saved_con; - - RK_SPDIF_DBG( "spdif:Entered %s\n", __func__); - - return 0; -} - -static int spdif_resume(struct snd_soc_dai *cpu_dai) -{ - struct rockchip_spdif_info *spdif = to_info(cpu_dai); - - RK_SPDIF_DBG( "spdif:Entered %s\n", __func__); - - return 0; -} -#else -#define spdif_suspend NULL -#define spdif_resume NULL -#endif - -static struct snd_soc_dai_ops spdif_dai_ops = { - .set_sysclk = spdif_set_syclk, - .trigger = spdif_trigger, - .hw_params = spdif_hw_params, - .shutdown = spdif_shutdown, -}; - -struct snd_soc_dai_driver rockchip_spdif_dai = { - .name = "rk-spdif", - .playback = { - .stream_name = "SPDIF Playback", - .channels_min = 2, - .channels_max = 2, - .rates = (SNDRV_PCM_RATE_32000 | - SNDRV_PCM_RATE_44100 | - SNDRV_PCM_RATE_48000 | - SNDRV_PCM_RATE_96000), - .formats = SNDRV_PCM_FMTBIT_S16_LE| - SNDRV_PCM_FMTBIT_S20_3LE| - SNDRV_PCM_FMTBIT_S24_LE, }, - .ops = &spdif_dai_ops, - .suspend = spdif_suspend, - .resume = spdif_resume, -}; - - -static __devinit int spdif_probe(struct platform_device *pdev) -{ - struct s3c_audio_pdata *spdif_pdata; - struct resource *mem_res, *dma_res; - struct rockchip_spdif_info *spdif; - int ret; - - spdif_pdata = pdev->dev.platform_data; - - RK_SPDIF_DBG("Entered %s\n", __func__); - -#if defined (CONFIG_ARCH_RK29) - rk29_mux_api_set(GPIO4A7_SPDIFTX_NAME, GPIO4L_SPDIF_TX); -#endif - -#if defined (CONFIG_ARCH_RK30) - rk30_mux_api_set(GPIO1B2_SPDIFTX_NAME, GPIO1B_SPDIF_TX); -#elif defined (CONFIG_ARCH_RK3188) - iomux_set(SPDIF_TX); -#endif - - - dma_res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "spdif_dma"); - if (!dma_res) { - printk("spdif:Unable to get dma resource.\n"); - return -ENXIO; - } - - mem_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "spdif_base"); - if (!mem_res) { - printk("spdif:Unable to get register resource.\n"); - return -ENXIO; - } - - spdif = &spdif_info; - spdif->dev = &pdev->dev; - - spin_lock_init(&spdif->lock); - - spdif->clk = clk_get(&pdev->dev, "spdif"); - if (IS_ERR(spdif->clk)) { - printk("spdif:failed to get internal source clock\n"); - ret = -ENOENT; - goto err1; - } - clk_enable(spdif->clk); - clk_set_rate(spdif->clk, 11289600); - -#if 1// defined (CONFIG_ARCH_RK30) - spdif->hclk = clk_get(&pdev->dev, "hclk_spdif"); - if (IS_ERR(spdif->hclk)) { - printk("spdif:failed to get spdif hclk\n"); - ret = -ENOENT; - goto err0; - } - clk_enable(spdif->hclk); - clk_set_rate(spdif->hclk, 11289600); -#endif - - /* Request S/PDIF Register's memory region */ - if (!request_mem_region(mem_res->start, - resource_size(mem_res), "rockchip-spdif")) { - printk("spdif:Unable to request register region\n"); - ret = -EBUSY; - goto err2; - } - - spdif->regs = ioremap(mem_res->start, mem_res->end - mem_res->start + 1); - if (spdif->regs == NULL) { - printk("spdif:Cannot ioremap registers\n"); - ret = -ENXIO; - goto err3; - } - - dev_set_drvdata(&pdev->dev, spdif); - - ret = snd_soc_register_dai(&pdev->dev, &rockchip_spdif_dai); - if (ret != 0) { - printk("spdif:fail to register dai\n"); - goto err4; - } - - spdif_stereo_out.dma_size = 4; - spdif_stereo_out.client = &spdif_dma_client_out; - spdif_stereo_out.dma_addr = mem_res->start + DATA_OUTBUF; - spdif_stereo_out.channel = dma_res->start; - - spdif->dma_playback = &spdif_stereo_out; -#ifdef CONFIG_SND_DMA_EVENT_STATIC - WARN_ON(rk29_dma_request(spdif_stereo_out.channel, spdif_stereo_out.client, NULL)); -#endif - - RK_SPDIF_DBG("spdif:spdif probe ok!\n"); - - return 0; - -err4: - iounmap(spdif->regs); -err3: - release_mem_region(mem_res->start, resource_size(mem_res)); -err2: - clk_disable(spdif->clk); - clk_put(spdif->clk); -err1: - clk_disable(spdif->hclk); - clk_put(spdif->hclk); -#if 1//defined (CONFIG_ARCH_RK30) -err0: -#endif - return ret; -} - -static __devexit int spdif_remove(struct platform_device *pdev) -{ - struct rockchip_spdif_info *spdif = &spdif_info; - struct resource *mem_res; - - RK_SPDIF_DBG("Entered %s\n", __func__); - - snd_soc_unregister_dai(&pdev->dev); - - iounmap(spdif->regs); - - mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (mem_res) - release_mem_region(mem_res->start, resource_size(mem_res)); - - clk_disable(spdif->clk); - clk_put(spdif->clk); - clk_disable(spdif->hclk); - clk_put(spdif->hclk); - - return 0; -} - - -static struct platform_driver rockchip_spdif_driver = { - .probe = spdif_probe, - .remove = spdif_remove, - .driver = { - .name = "rk-spdif", - .owner = THIS_MODULE, - }, -}; - - -static int __init spdif_init(void) -{ - RK_SPDIF_DBG("Entered %s\n", __func__); - return platform_driver_register(&rockchip_spdif_driver); -} -module_init(spdif_init); - -static void __exit spdif_exit(void) -{ - RK_SPDIF_DBG("Entered %s\n", __func__); - platform_driver_unregister(&rockchip_spdif_driver); -} -module_exit(spdif_exit); - -MODULE_AUTHOR("Seungwhan Youn, "); -MODULE_DESCRIPTION("rockchip S/PDIF Controller Driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:rockchip-spdif"); diff --git a/sound/soc/rk29/spdif.h b/sound/soc/rk29/spdif.h deleted file mode 100644 index d669f7defa8e..000000000000 --- a/sound/soc/rk29/spdif.h +++ /dev/null @@ -1,18 +0,0 @@ -/*$_FOR_ROCKCHIP_RBOX_$*/ -/*$_rbox_$_modify_$_huangzhibao for spdif output*/ - -/* - * - * ALSA SoC Audio Layer - - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __SND_SOC_SAMSUNG_SPDIF_H -#define __SND_SOC_SAMSUNG_SPDIF_H __FILE__ - - -#endif /* __SND_SOC_RK_SPDIF_H */