2 * rk29_wm8988.c -- SoC audio for rockchip
4 * Driver for rockchip wm8988 audio
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
14 #include <linux/module.h>
15 #include <linux/device.h>
16 #include <sound/core.h>
17 #include <sound/pcm.h>
18 #include <sound/soc.h>
19 #include <sound/soc-dapm.h>
21 #include <mach/hardware.h>
22 #include "../codecs/rk610_codec.h"
27 #define DBG(x...) printk(KERN_ERR x)
32 static int rk29_hw_params(struct snd_pcm_substream *substream,
33 struct snd_pcm_hw_params *params)
35 struct snd_soc_pcm_runtime *rtd = substream->private_data;
36 struct snd_soc_dai *codec_dai = rtd->codec_dai;
37 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
39 unsigned int pll_out = 0;
40 int div_bclk,div_mclk;
41 // struct clk *general_pll;
43 DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
44 /*by Vincent Hsiung for EQ Vol Change*/
45 #define HW_PARAMS_FLAG_EQVOL_ON 0x21
46 #define HW_PARAMS_FLAG_EQVOL_OFF 0x22
47 if ((params->flags == HW_PARAMS_FLAG_EQVOL_ON)||(params->flags == HW_PARAMS_FLAG_EQVOL_OFF))
49 ret = codec_dai->driver->ops->hw_params(substream, params, codec_dai); //by Vincent
53 /* set codec DAI configuration */
54 DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
55 #if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE)
56 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
57 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
58 #elif defined (CONFIG_SND_RK29_CODEC_SOC_MASTER)
59 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
60 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM );
64 /* set cpu DAI configuration */
65 DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
66 #if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE)
67 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
68 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
69 #elif defined (CONFIG_SND_RK29_CODEC_SOC_MASTER)
70 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
71 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
77 switch(params_rate(params)) {
99 DBG("Enter:%s, %d, Error rate=%d\n",__FUNCTION__,__LINE__,params_rate(params));
103 DBG("Enter:%s, %d, rate=%d\n",__FUNCTION__,__LINE__,params_rate(params));
104 snd_soc_dai_set_sysclk(codec_dai, 0, pll_out, SND_SOC_CLOCK_IN);
106 // #if defined (CONFIG_SND_RK29_CODEC_SOC_MASTER)
107 // snd_soc_dai_set_sysclk(cpu_dai, 0, pll_out, 0);
109 #if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE)
111 div_mclk = pll_out/(params_rate(params)*64) - 1;
113 DBG("func is%s,pll_out=%d,div_mclk=%d div_bclk\n",
114 __FUNCTION__,pll_out,div_mclk, div_bclk);
115 snd_soc_dai_set_sysclk(cpu_dai, 0, pll_out, 0);
116 snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_BCLK,div_bclk);
117 snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_MCLK, div_mclk);
118 // DBG("Enter:%s, %d, LRCK=%d\n",__FUNCTION__,__LINE__,(pll_out/4)/params_rate(params));
123 static struct snd_soc_ops rk29_ops = {
124 .hw_params = rk29_hw_params,
127 static struct snd_soc_dai_link rk29_dai = {
128 .name = "RK610_CODEC",
129 .stream_name = "RK610 CODEC PCM",
130 #if defined(CONFIG_MACH_RK3168_DS1006H)|| defined(CONFIG_MACH_RK3168_LR097)
131 .codec_name = "RK610_CODEC.4-0060",
133 .codec_name = "RK610_CODEC.0-0060",
135 .platform_name = "rockchip-audio",
136 #if defined(CONFIG_SND_RK29_SOC_I2S_8CH)
137 .cpu_dai_name = "rk29_i2s.0",
138 #elif defined(CONFIG_SND_RK29_SOC_I2S_2CH)
139 .cpu_dai_name = "rk29_i2s.1",
141 .cpu_dai_name = "rk29_i2s.2",
143 .codec_dai_name = "rk610_codec",
146 static struct snd_soc_card snd_soc_card_rk29 = {
147 .name = "RK29_RK610",
148 .dai_link = &rk29_dai,
153 static struct platform_device *rk29_snd_device;
155 static int __init audio_card_init(void)
158 DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
159 rk29_snd_device = platform_device_alloc("soc-audio", -1);
160 if (!rk29_snd_device) {
161 printk("[%s] platform device allocation failed\n", __FUNCTION__);
165 platform_set_drvdata(rk29_snd_device, &snd_soc_card_rk29);
167 ret = platform_device_add(rk29_snd_device);
169 DBG("platform device add failed\n");
170 platform_device_put(rk29_snd_device);
174 static void __exit audio_card_exit(void)
176 platform_device_unregister(rk29_snd_device);
179 module_init(audio_card_init);
180 module_exit(audio_card_exit);
181 /* Module information */
182 MODULE_AUTHOR("rockchip");
183 MODULE_DESCRIPTION("ROCKCHIP i2s ASoC Interface");
184 MODULE_LICENSE("GPL");