audio: rk3036 spdif

debug rk3036 spdif, add DTS node and math dts node name.

Signed-off-by: dgl@rock-chips.com
This commit is contained in:
dgl
2014-07-28 15:04:38 +08:00
parent 50fe670e0b
commit d54505daaf
6 changed files with 108 additions and 92 deletions

View File

@@ -318,7 +318,7 @@
};
};
gpio1_spdif {
gpio0_spdif {
spdif_tx: spdif-tx {
rockchip,pins = <SPDIF_TX>;
rockchip,pull = <VALUE_PULL_DEFAULT>;

View File

@@ -107,6 +107,20 @@
};
};
codec_hdmi_spdif: codec-hdmi-spdif {
compatible = "hdmi-spdif";
};
rockchip-hdmi-spdif {
compatible = "rockchip-hdmi-spdif";
dais {
dai0 {
audio-codec = <&codec_hdmi_spdif>;
i2s-controller = <&spdif>;
};
};
};
rockchip-audio {
compatible = "rk3036-audio";
dais {

View File

@@ -408,8 +408,8 @@
dmas = <&pdma 13>;
//#dma-cells = <1>;
dma-names = "tx";
//pinctrl-names = "default";
//pinctrl-0 = <&spdif_tx>;
pinctrl-names = "default";
pinctrl-0 = <&spdif_tx>;
};
pwm0: pwm@20050000 {
@@ -695,8 +695,8 @@
reg = <0x10200000 0x4000>;
interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "macirq";
clocks = <&clk_mac_pll>, <&clk_mac_ref>,
<&clk_mac_pll_div>, <&clk_mac_ref_div>,
clocks = <&clk_mac_pll>, <&clk_mac_ref>,
<&clk_mac_pll_div>, <&clk_mac_ref_div>,
<&clk_gates2 6>, <&clk_gates3 5>;
clock-names = "clk_mac_pll", "clk_mac_ref",
"clk_mac_pll_div", "clk_mac_ref_div",

View File

@@ -23,6 +23,16 @@
#include <sound/pcm.h>
#include <sound/initval.h>
#undef DEBUG_HDMI_SPDIF
#define DEBUG_HDMI_SPDIF 0
#if DEBUG_HDMI_SPDIF
#define RK_HDMISPDIF_DBG(x...) pr_info("hdmi_spdif:"x)
#else
#define RK_HDMISPDIF_DBG(x...) do { } while (0)
#endif
#define DRV_NAME "spdif-dit"
#define STUB_RATES SNDRV_PCM_RATE_8000_96000
@@ -33,7 +43,7 @@ static struct snd_soc_codec_driver soc_codec_spdif_dit;
static struct snd_soc_dai_driver dit_stub_dai = {
.name = "rk-hdmi-spdif-hifi",
.playback = {
.playback = {
.stream_name = "Playback",
.channels_min = 1,
.channels_max = 384,
@@ -42,23 +52,24 @@ static struct snd_soc_dai_driver dit_stub_dai = {
},
};
static int rockchip_hdmi_spdif_audio_probe(struct platform_device *pdev)
static int hdmi_spdif_audio_probe(struct platform_device *pdev)
{
int ret;
//set dev name to driver->name for sound card register
/* set dev name to driver->name for sound card register. */
dev_set_name(&pdev->dev, "%s", pdev->dev.driver->name);
ret = snd_soc_register_codec(&pdev->dev, &soc_codec_spdif_dit,
&dit_stub_dai, 1);
ret = snd_soc_register_codec(&pdev->
dev, &soc_codec_spdif_dit, &dit_stub_dai, 1);
if (ret)
printk("%s() register codec failed:%d\n", __FUNCTION__, ret);
RK_HDMISPDIF_DBG("%s register codec failed:%d\n"
, __func__, ret);
return ret;
}
static int rockchip_hdmi_spdif_audio_remove(struct platform_device *pdev)
static int hdmi_spdif_audio_remove(struct platform_device *pdev)
{
snd_soc_unregister_codec(&pdev->dev);
@@ -66,24 +77,24 @@ static int rockchip_hdmi_spdif_audio_remove(struct platform_device *pdev)
}
#ifdef CONFIG_OF
static const struct of_device_id rockchip_hdmi_spdif_of_match[] = {
{ .compatible = "hdmi-spdif", },
{},
static const struct of_device_id hdmi_spdif_of_match[] = {
{ .compatible = "hdmi-spdif", },
{},
};
MODULE_DEVICE_TABLE(of, rockchip_hdmi_spdif_of_match);
MODULE_DEVICE_TABLE(of, hdmi_spdif_of_match);
#endif /* CONFIG_OF */
static struct platform_driver rockchip_hdmi_spdif_audio_driver = {
.driver = {
.name = "hdmi-spdif",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(rockchip_hdmi_spdif_of_match),
},
.probe = rockchip_hdmi_spdif_audio_probe,
.remove = rockchip_hdmi_spdif_audio_remove,
static struct platform_driver hdmi_spdif_audio_driver = {
.driver = {
.name = "hdmi-spdif",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(hdmi_spdif_of_match),
},
.probe = hdmi_spdif_audio_probe,
.remove = hdmi_spdif_audio_remove,
};
module_platform_driver(rockchip_hdmi_spdif_audio_driver);
module_platform_driver(hdmi_spdif_audio_driver);
MODULE_AUTHOR("Steve Chen <schen@mvista.com>");
MODULE_DESCRIPTION("SPDIF dummy codec driver");

View File

@@ -20,7 +20,7 @@ choice
bool "Set audio support for HDMI"
default SND_RK_SOC_HDMI_I2S
config SND_RK_SOC_HDMI_I2S
depends on (!RK616_USE_MCLK_12M || !SND_RK_SOC_RK616) && !SND_RK_SOC_RK3036
depends on !RK616_USE_MCLK_12M || !SND_RK_SOC_RK616
select SND_RK_SOC_I2S
select SND_SOC_HDMI_I2S
tristate "HDMI use I2S"

123
sound/soc/rockchip/rk_spdif.c Executable file → Normal file
View File

@@ -39,18 +39,18 @@
#include <sound/initval.h>
#include <sound/soc.h>
#include <sound/dmaengine_pcm.h>
#include <linux/spinlock.h>
#include "rk_pcm.h"
#if 0
#undef DEBUG_SPDIF
#define DEBUG_SPDIF 0
#if DEBUG_SPDIF
#define RK_SPDIF_DBG(x...) pr_info("rk_spdif:"x)
#else
#define RK_SPDIF_DBG(x...) do { } while (0)
#endif
/* Registers */
#define CFGR 0x00
#define SDBLR 0x04
@@ -137,7 +137,7 @@
#define INTCR_SDBEIE_MASK (1<<4)
struct rockchip_spdif_info {
spinlock_t lock;
spinlock_t lock;/*lock parmeter setting.*/
void __iomem *regs;
unsigned long clk_rate;
struct clk *clk;
@@ -165,33 +165,33 @@ static void spdif_snd_txctrl(struct rockchip_spdif_info *spdif, int on)
opr |= DMACR_TRAN_DMA_ENABLE;
writel(xfer, regs + XFER);
writel(opr, regs + DMACR);
RK_SPDIF_DBG("on xfer=0x%x,opr=0x%x\n",
readl(regs + XFER), readl(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, regs + DMACR);
writel(1<<7, regs + CFGR);
RK_SPDIF_DBG("off xfer=0x%x,opr=0x%x\n",
readl(regs + XFER), readl(regs + DMACR));
RK_SPDIF_DBG("off xfer=0x%x,opr=0x%x\n", readl(
regs + XFER), readl(regs + DMACR));
}
}
static int spdif_set_syclk(struct snd_soc_dai *cpu_dai,
int clk_id, unsigned int freq, int dir)
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);
RK_SPDIF_DBG("Entered %s\n", __func__);
RK_SPDIF_DBG("Entered %s sysclk=%d\n", __func__, freq);
spdif->clk_rate = freq;
return 0;
}
static int spdif_trigger(struct snd_pcm_substream *substream, int cmd,
struct snd_soc_dai *dai)
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);
@@ -221,10 +221,9 @@ static int spdif_trigger(struct snd_pcm_substream *substream, int cmd,
return 0;
}
static int spdif_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
static int spdif_hw_params(struct snd_pcm_substream *
substream, struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
struct rockchip_spdif_info *spdif = to_info(dai);
void __iomem *regs = spdif->regs;
@@ -235,9 +234,9 @@ static int spdif_hw_params(struct snd_pcm_substream *substream,
RK_SPDIF_DBG("Entered %s\n", __func__);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
dai->playback_dma_data = &spdif->dma_playback;
else {
} else {
pr_err("spdif:Capture is not supported\n");
return -EINVAL;
}
@@ -314,8 +313,9 @@ static int spdif_hw_params(struct snd_pcm_substream *substream,
chnsr_byte[0] |= (0x1<<1);
chnsr_byte[4] = (0x0<<4)|(0x00<<1|0x0);
}
writel((chnsr_byte[4] << 16) | (chnsr_byte[4]),
regs + SPDIF_CHNSR02_ADDR);
writel((chnsr_byte[4] << 16)
| (chnsr_byte[4]),
regs + SPDIF_CHNSR02_ADDR);
writel((chnsr_byte[3] << 24) | (chnsr_byte[2] << 16) |
(chnsr_byte[3] << 8) | (chnsr_byte[2]),
regs + SPDIF_CHNSR01_ADDR);
@@ -412,61 +412,58 @@ static const struct snd_soc_component_driver rockchip_spdif_component = {
static int spdif_probe(struct platform_device *pdev)
{
/*struct device_node *spdif_np = pdev->dev.of_node;*/
struct resource *memregion;
struct resource *mem_res;
struct rockchip_spdif_info *spdif;
struct clk *spdif_hclk;
int ret;
RK_SPDIF_DBG("Entered %s\n", __func__);
spdif = devm_kzalloc(&pdev->dev,
sizeof(struct rockchip_spdif_info),
GFP_KERNEL);
spdif = devm_kzalloc(&pdev->dev, sizeof(
struct rockchip_spdif_info), GFP_KERNEL);
if (!spdif) {
dev_err(&pdev->dev, "Can't allocate spdif info\n");
return -ENOMEM;
}
platform_set_drvdata(pdev, spdif);
spin_lock_init(&spdif->lock);
/* get spdif register regoin. */
mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!mem_res) {
pr_err("spdif:Unable to get register resource.\n");
return -ENXIO;
dev_err(&pdev->dev, "No memory resource\n");
ret = -ENOENT;
goto err_;
}
memregion = devm_request_mem_region(&pdev->
dev, mem_res->start,
resource_size(mem_res), "rockchip-spdif");
if (!memregion) {
dev_err(&pdev->dev, "Memory region already claimed\n");
ret = -EBUSY;
goto err_;
}
spdif->regs = devm_ioremap(&pdev->dev, memregion->
start, resource_size(memregion));
if (!spdif->regs) {
dev_err(&pdev->dev, "ioremap failed\n");
ret = -ENOMEM;
goto err_;
}
spdif->clk = clk_get(&pdev->dev, "spdif_8ch_mclk");
/* get spdif clock and init. */
spdif->clk = devm_clk_get(&pdev->dev, "spdif_mclk");
if (IS_ERR(spdif->clk)) {
dev_err(&pdev->dev, "Can't retrieve spdif clock\n");
return PTR_ERR(spdif->clk);
ret = -ENOMEM;
goto err_;
}
clk_set_rate(spdif->clk, 12288000);
clk_set_rate(spdif->clk, 11289600);
clk_prepare_enable(spdif->clk);
spdif_hclk = clk_get(&pdev->dev, "spdif_hclk");
if(IS_ERR(spdif_hclk) ) {
dev_err(&pdev->dev, "get spdif_hclk failed.\n");
} else {
clk_prepare_enable(spdif_hclk);
}
/* Request S/PDIF Register's memory region */
if (!request_mem_region(mem_res->start,
resource_size(mem_res), "rockchip-spdif")) {
pr_err("spdif:Unable to request register region\n");
ret = -EBUSY;
goto err_clk_put;
}
spdif->regs = devm_ioremap(&pdev->dev,
mem_res->start, resource_size(mem_res));
if (!spdif->regs) {
dev_err(&pdev->dev, "ioremap failed\n");
ret = -ENOMEM;
goto err_clk_put;
}
spdif->dma_playback.addr = mem_res->start + DATA_OUTBUF;
spdif->dma_playback.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
spdif->dma_playback.maxburst = 4;
@@ -474,33 +471,27 @@ static int spdif_probe(struct platform_device *pdev)
/* set dev name to driver->name for sound card register */
dev_set_name(&pdev->dev, "%s", pdev->dev.driver->name);
ret = snd_soc_register_component(&pdev->dev,
&rockchip_spdif_component,
&rockchip_spdif_dai, 1);
ret = snd_soc_register_component(&pdev->
dev, &rockchip_spdif_component, &rockchip_spdif_dai, 1);
if (ret) {
dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
ret = -ENOMEM;
goto err_clk_put;
goto err_;
}
ret = rockchip_pcm_platform_register(&pdev->dev);
if (ret) {
dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
goto err_unregister_component;
goto err_;
}
dev_set_drvdata(&pdev->dev, spdif);
writel_relaxed(SPDIF_CHANNEL_SEL_8CH,
RK_GRF_VIRT + RK3288_GRF_SOC_CON2);
RK_SPDIF_DBG("spdif:spdif probe ok!\n");
return 0;
err_unregister_component:
snd_soc_unregister_component(&pdev->dev);
err_clk_put:
clk_put(spdif->clk);
err_:
platform_set_drvdata(pdev, NULL);
return ret;
}