From: 邱建斌 Date: Tue, 28 Feb 2012 07:57:15 +0000 (+0800) Subject: update i2s codec X-Git-Tag: firefly_0821_release~9595^2~114 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=35d60559db3747a13da2f9ae98900fae77e6bc29;p=firefly-linux-kernel-4.4.55.git update i2s codec --- diff --git a/arch/arm/mach-rk30/board-rk30-sdk.c b/arch/arm/mach-rk30/board-rk30-sdk.c index 45e40eb37ab8..ab88fafa6fb8 100755 --- a/arch/arm/mach-rk30/board-rk30-sdk.c +++ b/arch/arm/mach-rk30/board-rk30-sdk.c @@ -329,6 +329,16 @@ static struct platform_device *devices[] __initdata = { #ifdef CONFIG_FB_ROCKCHIP &device_fb, #endif +#ifdef CONFIG_SND_RK29_SOC_I2S_8CH + &rk_device_iis0_8ch, +#endif +#ifdef CONFIG_SND_RK29_SOC_I2S_2CH + &rk_device_iis1_2ch, +#endif +#ifdef CONFIG_SND_RK_SOC_I2S2_2CH + &rk_device_iis2_2ch, +#endif + }; // i2c @@ -343,7 +353,18 @@ static struct i2c_board_info __initdata i2c0_info[] = { .platform_data = &mma8452_info, }, #endif - +#if defined (CONFIG_SND_SOC_RK1000) + { + .type = "rk1000_i2c_codec", + .addr = 0x60, + .flags = 0, + }, + { + .type = "rk1000_control", + .addr = 0x40, + .flags = 0, + }, +#endif }; #endif diff --git a/arch/arm/mach-rk30/devices.c b/arch/arm/mach-rk30/devices.c index 4dda764689c0..b155da00c16b 100755 --- a/arch/arm/mach-rk30/devices.c +++ b/arch/arm/mach-rk30/devices.c @@ -792,6 +792,104 @@ static struct platform_device device_ipp = { }; #endif +#ifdef CONFIG_SND_RK29_SOC_I2S +static struct resource rk_iis0_8ch_resource[] = { + [0] = { + .start = RK30_I2S0_8CH_PHYS, + .end = RK30_I2S0_8CH_PHYS + RK30_I2S0_8CH_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = DMACH_I2S0_8CH_TX, + .end = DMACH_I2S0_8CH_TX, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = DMACH_I2S0_8CH_RX, + .end = DMACH_I2S0_8CH_RX, + .flags = IORESOURCE_DMA, + }, + [3] = { + .start = IRQ_I2S0_8CH, + .end = IRQ_I2S0_8CH, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device rk_device_iis0_8ch = { + .name = "rk29_i2s", + .id = 0, + .num_resources = ARRAY_SIZE(rk_iis0_8ch_resource), + .resource = rk_iis0_8ch_resource, +}; + +static struct resource rk_iis1_2ch_resource[] = { + [0] = { + .start = RK30_I2S1_2CH_PHYS, + .end = RK30_I2S1_2CH_PHYS + RK30_I2S1_2CH_SIZE -1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = DMACH_I2S1_2CH_TX, + .end = DMACH_I2S1_2CH_TX, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = DMACH_I2S1_2CH_RX, + .end = DMACH_I2S1_2CH_RX, + .flags = IORESOURCE_DMA, + }, + [3] = { + .start = IRQ_I2S1_2CH, + .end = IRQ_I2S1_2CH, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device rk_device_iis1_2ch = { + .name = "rk29_i2s", + .id = 1, + .num_resources = ARRAY_SIZE(rk_iis1_2ch_resource), + .resource = rk_iis1_2ch_resource, +}; + +static struct resource rk_iis2_2ch_resource[] = { + [0] = { + .start = RK30_I2S2_2CH_PHYS, + .end = RK30_I2S2_2CH_PHYS + RK30_I2S2_2CH_SIZE -1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = DMACH_I2S2_2CH_TX, + .end = DMACH_I2S2_2CH_TX, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = DMACH_I2S2_2CH_RX, + .end = DMACH_I2S2_2CH_RX, + .flags = IORESOURCE_DMA, + }, + [3] = { + .start = IRQ_I2S2_2CH, + .end = IRQ_I2S2_2CH, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device rk_device_iis2_2ch = { + .name = "rk29_i2s", + .id = 2, + .num_resources = ARRAY_SIZE(rk_iis2_2ch_resource), + .resource = rk_iis2_2ch_resource, +}; + +#endif + +static struct platform_device rk29_device_pcm = { + .name = "rockchip-audio", + .id = -1, +}; + #ifdef CONFIG_KEYS_RK29 extern struct rk29_keys_platform_data rk29_keys_pdata; static struct platform_device device_keys = { @@ -891,6 +989,7 @@ static int __init rk30_init_devices(void) #ifdef CONFIG_FIQ_DEBUGGER rk_serial_debug_init(RK30_UART1_PHYS, IRQ_UART1, IRQ_UART_SIGNAL, -1); #endif + platform_device_register(&rk29_device_pcm); return 0; } diff --git a/arch/arm/mach-rk30/include/mach/board.h b/arch/arm/mach-rk30/include/mach/board.h index 07d71ef0ee1c..640c0abe5327 100755 --- a/arch/arm/mach-rk30/include/mach/board.h +++ b/arch/arm/mach-rk30/include/mach/board.h @@ -46,4 +46,9 @@ void __init rk30_clock_init(void); extern struct sys_timer rk30_timer; + +extern struct platform_device rk_device_iis2_2ch; +extern struct platform_device rk_device_iis1_2ch; +extern struct platform_device rk_device_iis0_8ch; + #endif diff --git a/arch/arm/mach-rk30/include/mach/iomux.h b/arch/arm/mach-rk30/include/mach/iomux.h index f2794f93e555..7a3385bcfb1f 100755 --- a/arch/arm/mach-rk30/include/mach/iomux.h +++ b/arch/arm/mach-rk30/include/mach/iomux.h @@ -70,7 +70,7 @@ #define GPIO0C_GPIO0C3 0 #define GPIO0C_I2S1_2CH_LRCK_TX 1 #define GPIO0C_GPIO0C2 0 -#define GPIO0C_I2S_8CH_LRCK_RX 1 +#define GPIO0C_I2S1_2CH_LRCK_RX 1 #define GPIO0C_GPIO0C1 0 #define GPIO0C_I2S1_2CH_SCLK 1 #define GPIO0C_GPIO0C0 0 @@ -87,13 +87,13 @@ #define GPIO0D_I2S2_2CH_SDO 1 #define GPIO0D_SMC_ADDR1 2 #define GPIO0D_GPIO0D4 0 -#define GPIO0D_I2S1_2CH_SDI 1 +#define GPIO0D_I2S2_2CH_SDI 1 #define GPIO0D_SMC_ADDR0 2 #define GPIO0D_GPIO0D3 0 -#define GPIO0D_I2S1_2CH_LRCK_TX 1 +#define GPIO0D_I2S2_2CH_LRCK_TX 1 #define GPIO0D_SMC_ADV_N 2 #define GPIO0D_GPIO0D2 0 -#define GPIO0D_I2S1_2CH_LRCK_RX 1 +#define GPIO0D_I2S2_2CH_LRCK_RX 1 #define GPIO0D_SMC_OE_N 2 #define GPIO0D_GPIO0D1 0 #define GPIO0D_I2S2_2CH_SCLK 1 @@ -606,7 +606,7 @@ #define GPIO0C5_I2S12CHSDO_NAME "gpio0c5_i2s12chsdo_name" #define GPIO0C4_I2S12CHSDI_NAME "gpio0c4_i2s12chsdi_name" #define GPIO0C3_I2S12CHLRCKTX_NAME "gpio0c3_i2s12chlrcktx_name" -#define GPIO0C2_I2S8CHLRCKRX_NAME "gpio0c2_i2s8chlrckrx_name" +#define GPIO0C2_I2S12CHLRCKRX_NAME "gpio0c2_i2s12chlrckrx_name" #define GPIO0C1_I2S12CHSCLK_NAME "gpio0c1_i2s12chsclk_name" #define GPIO0C0_I2S12CHCLK_NAME "gpio0c0_i2s12chclk_name" @@ -615,9 +615,9 @@ #define GPIO0D7_PWM3_NAME "gpio0d7_pwm3_name" #define GPIO0D6_PWM2_NAME "gpio0d6_pwm2_name" #define GPIO0D5_I2S22CHSDO_SMCADDR1_NAME "gpio0d5_i2s22chsdo_smcaddr1_name" -#define GPIO0D4_I2S12CHSDI_SMCADDR0_NAME "gpio0d4_i2s12chsdi_smcaddr0_name" -#define GPIO0D3_I2S12CHLRCKTX_SMCADVN_NAME "gpio0d3_i2s12chlrcktx_smcadvn_name" -#define GPIO0D2_I2S12CHLRCKRX_SMCOEN_NAME "gpio0d2_i2s12chlrckrx_smcoen_name" +#define GPIO0D4_I2S22CHSDI_SMCADDR0_NAME "gpio0d4_i2s22chsdi_smcaddr0_name" +#define GPIO0D3_I2S22CHLRCKTX_SMCADVN_NAME "gpio0d3_i2s22chlrcktx_smcadvn_name" +#define GPIO0D2_I2S22CHLRCKRX_SMCOEN_NAME "gpio0d2_i2s22chlrckrx_smcoen_name" #define GPIO0D1_I2S22CHSCLK_SMCWEN_NAME "gpio0d1_i2s22chsclk_smcwen_name" #define GPIO0D0_I2S22CHCLK_SMCCSN0_NAME "gpio0d0_i2s22chclk_smccsn0_name" diff --git a/arch/arm/mach-rk30/iomux.c b/arch/arm/mach-rk30/iomux.c index 27cc8598d28e..7f427450fb64 100755 --- a/arch/arm/mach-rk30/iomux.c +++ b/arch/arm/mach-rk30/iomux.c @@ -55,7 +55,7 @@ MUX_CFG(GPIO0C6_TRACECLK_SMCADDR2_NAME, GPIO0C, 12, 2, 0, DEFAULT) MUX_CFG(GPIO0C5_I2S12CHSDO_NAME, GPIO0C, 10, 2, 0, DEFAULT) MUX_CFG(GPIO0C4_I2S12CHSDI_NAME, GPIO0C, 8, 2, 0, DEFAULT) MUX_CFG(GPIO0C3_I2S12CHLRCKTX_NAME, GPIO0C, 6, 2, 0, DEFAULT) -MUX_CFG(GPIO0C2_I2S8CHLRCKRX_NAME, GPIO0C, 4, 2, 0, DEFAULT) +MUX_CFG(GPIO0C2_I2S12CHLRCKRX_NAME, GPIO0C, 4, 2, 0, DEFAULT) MUX_CFG(GPIO0C1_I2S12CHSCLK_NAME, GPIO0C, 2, 2, 0, DEFAULT) MUX_CFG(GPIO0C0_I2S12CHCLK_NAME, GPIO0C, 0, 2, 0, DEFAULT) @@ -63,9 +63,9 @@ MUX_CFG(GPIO0C0_I2S12CHCLK_NAME, GPIO0C, 0, 2, 0, DEFAULT) MUX_CFG(GPIO0D7_PWM3_NAME, GPIO0D, 14, 2, 0, DEFAULT) MUX_CFG(GPIO0D6_PWM2_NAME, GPIO0D, 12, 2, 0, DEFAULT) MUX_CFG(GPIO0D5_I2S22CHSDO_SMCADDR1_NAME, GPIO0D, 10, 2, 0, DEFAULT) -MUX_CFG(GPIO0D4_I2S12CHSDI_SMCADDR0_NAME, GPIO0D, 8, 2, 0, DEFAULT) -MUX_CFG(GPIO0D3_I2S12CHLRCKTX_SMCADVN_NAME, GPIO0D, 6, 2, 0, DEFAULT) -MUX_CFG(GPIO0D2_I2S12CHLRCKRX_SMCOEN_NAME, GPIO0D, 4, 2, 0, DEFAULT) +MUX_CFG(GPIO0D4_I2S22CHSDI_SMCADDR0_NAME, GPIO0D, 8, 2, 0, DEFAULT) +MUX_CFG(GPIO0D3_I2S22CHLRCKTX_SMCADVN_NAME, GPIO0D, 6, 2, 0, DEFAULT) +MUX_CFG(GPIO0D2_I2S22CHLRCKRX_SMCOEN_NAME, GPIO0D, 4, 2, 0, DEFAULT) MUX_CFG(GPIO0D1_I2S22CHSCLK_SMCWEN_NAME, GPIO0D, 2, 2, 0, DEFAULT) MUX_CFG(GPIO0D0_I2S22CHCLK_SMCCSN0_NAME, GPIO0D, 0, 2, 0, DEFAULT) diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 95da908c85f9..012792738795 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -393,7 +393,7 @@ config SND_SOC_WM9713 config SND_SOC_RK1000 tristate - depends on RK1000_CONTROL +# depends on RK1000_CONTROL # Amp config SND_SOC_LM4857 diff --git a/sound/soc/codecs/rk1000_codec.c b/sound/soc/codecs/rk1000_codec.c old mode 100644 new mode 100755 index 8014f314b94e..bc3505507580 --- a/sound/soc/codecs/rk1000_codec.c +++ b/sound/soc/codecs/rk1000_codec.c @@ -18,21 +18,32 @@ #include #include #include +#include +#include +#include #include +#include #include #include #include -#include #include +#include +#include #include #include #include "rk1000_codec.h" - +#define RK1000_CODEC_PROC +#ifdef RK1000_CODEC_PROC +#include +#include +#include +char debug_write_read = 0; +#endif /* * Debug */ -#if 0 +#if 1 #define DBG(x...) printk(KERN_INFO x) #else #define DBG(x...) @@ -45,7 +56,9 @@ #define OUT_CAPLESS (0) //ÊÇ·ñΪÎÞµçÈÝÊä³ö£¬1:ÎÞµçÈÝÊä³ö£¬0:ÓеçÈÝÊä³ö -///static u32 gVolReg = 0x0f; ///0x0f; //ÓÃÓڼǼÒôÁ¿¼Ä´æÆ÷ +static struct snd_soc_codec *rk1000_codec_codec; + +//static u32 gVolReg = 0x0f; ///0x0f; //ÓÃÓڼǼÒôÁ¿¼Ä´æÆ÷ //static u32 gCodecVol = 0x0f; static u8 gR0AReg = 0; //ÓÃÓڼǼR0A¼Ä´æÆ÷µÄÖµ£¬ÓÃÓڸıä²ÉÑùÂÊǰͨ¹ýR0AÍ£Ö¹clk static u8 gR0BReg = 0; //ÓÃÓڼǼR0B¼Ä´æÆ÷µÄÖµ£¬ÓÃÓڸıä²ÉÑùÂÊǰͨ¹ýR0BÍ£Ö¹interplateºÍdecimation @@ -60,16 +73,18 @@ static const u16 rk1000_codec_reg[] = { 0x0005, 0x0004, 0x00fd, 0x00f3, /* 0 */ 0x0003, 0x0000, 0x0000, 0x0000, /* 4 */ 0x0000, 0x0005, 0x0000, 0x0000, /* 8 */ - 0x0097, 0x0097, 0x0097, 0x0097, /* 12 */ - 0x0097, 0x0097, 0x00cc, 0x0000, /* 16 */ - 0x0000, 0x00f1, 0x0090, 0x00ff, /* 20 */ - 0x00ff, 0x00ff, 0x009c, 0x0000, /* 24 */ - 0x0000, 0x00ff, 0x00ff, 0x00ff, /* 28 */ + 0x0097, 0x0097, 0x0097, 0x0097, /* 0x0a */ + 0x0097, 0x0097, 0x00cc, 0x0000, /* 0x10 */ + 0x0000, 0x00f1, 0x0090, 0x00ff, /* 0x14 */ + 0x00ff, 0x00ff, 0x009c, 0x0000, /* 0x18 */ + 0x0000, 0x00ff, 0x00ff, 0x00ff, /* 0x1a */ }; - /* codec private data */ struct rk1000_codec_priv { + enum snd_soc_control_type control_type; + void *control_data; + unsigned int sysclk; struct snd_soc_codec codec; struct snd_pcm_hw_constraint_list *sysclk_constraints; @@ -100,7 +115,7 @@ static unsigned int rk1000_codec_read(struct snd_soc_codec *codec, unsigned int xfer[0].flags = I2C_M_RD; xfer[0].len = 1; xfer[0].buf = ® - + xfer[0].scl_rate = 100*1000; ret = i2c_transfer(client->adapter, xfer, 1); if (ret != 1) { dev_err(&client->dev, "i2c_transfer() returned %d\n", ret); @@ -109,6 +124,7 @@ static unsigned int rk1000_codec_read(struct snd_soc_codec *codec, unsigned int return reg; } + /* * write rk1000 register cache */ @@ -126,16 +142,16 @@ static int rk1000_codec_write(struct snd_soc_codec *codec, unsigned int reg, { u8 data[2]; struct i2c_client *i2c; - DBG("Enter::%s, %d, reg=0x%02X, value=0x%02X\n",__FUNCTION__,__LINE__, reg, value); + DBG("Enter-%s::reg=0x%02X, value=0x%02X\n",__FUNCTION__, reg, value); data[0] = value & 0x00ff; rk1000_codec_write_reg_cache (codec, reg, value); i2c = (struct i2c_client *)codec->control_data; i2c->addr = (i2c->addr & 0x60)|reg; if (codec->hw_write(codec->control_data, data, 1) == 1){ - DBG("================%s Run OK================\n",__FUNCTION__,__LINE__); +// DBG("================%s Run OK====%d============\n",__FUNCTION__,__LINE__); return 0; }else{ - DBG("================%s Run EIO================\n",__FUNCTION__,__LINE__); + DBG("================%s Run EIO=======%d=========\n",__FUNCTION__,__LINE__); return -EIO; } } @@ -370,9 +386,9 @@ static int rk1000_codec_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id, unsigned int freq, int dir) { struct snd_soc_codec *codec = codec_dai->codec; - struct rk1000_codec_priv *rk1000_codec = codec->private_data; + struct rk1000_codec_priv *rk1000_codec = snd_soc_codec_get_drvdata(codec); - DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); + DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); switch (freq) { case 11289600: @@ -463,23 +479,25 @@ static int rk1000_codec_set_dai_fmt(struct snd_soc_dai *codec_dai, static int rk1000_codec_pcm_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { - struct snd_soc_codec *codec = dai->codec; - struct rk1000_codec_priv *rk1000_codec = codec->private_data; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_codec *codec = rtd->codec; + struct rk1000_codec_priv *rk1000_codec = snd_soc_codec_get_drvdata(codec); /* The set of sample rates that can be supported depends on the * MCLK supplied to the CODEC - enforce this. */ DBG("Enter::%s----%d rk1000_codec->sysclk=%d\n",__FUNCTION__,__LINE__,rk1000_codec->sysclk); - if (!rk1000_codec->sysclk) { - dev_err(codec->dev, - "No MCLK configured, call set_sysclk() on init\n"); - return -EINVAL; - } +// if (!rk1000_codec->sysclk) { +// dev_err(codec->dev, +// "No MCLK configured, call set_sysclk() on init\n"); +// return -EINVAL; +// } - snd_pcm_hw_constraint_list(substream->runtime, 0, +#if 0 + snd_pcm_hw_constraint_list(substream->runtime, 0, SNDRV_PCM_HW_PARAM_RATE, rk1000_codec->sysclk_constraints); - +#endif return 0; } @@ -488,13 +506,14 @@ static int rk1000_codec_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; - struct rk1000_codec_priv *rk1000_codec = codec->private_data; + struct snd_soc_codec *codec = rtd->codec; + struct rk1000_codec_priv *rk1000_codec = snd_soc_codec_get_drvdata(codec); + u16 iface = rk1000_codec_read_reg_cache(codec, ACCELCODEC_R09) & 0x1f3; u16 srate = rk1000_codec_read_reg_cache(codec, ACCELCODEC_R00) & 0x180; int coeff; - + + rk1000_codec->sysclk = 12000000; /*by Vincent Hsiung for EQ Vol Change*/ #define HW_PARAMS_FLAG_EQVOL_ON 0x21 #define HW_PARAMS_FLAG_EQVOL_OFF 0x22 @@ -546,64 +565,71 @@ static int rk1000_codec_pcm_hw_params(struct snd_pcm_substream *substream, DBG("Enter::%s----%d iface=%x srate =%x rate=%d\n",__FUNCTION__,__LINE__,iface,srate,params_rate(params)); rk1000_codec_write(codec,ACCELCODEC_R0C, 0x17); - rk1000_codec_write(codec,ACCELCODEC_R04, ASC_INT_MUTE_L|ASC_INT_MUTE_R|ASC_SIDETONE_L_OFF|ASC_SIDETONE_R_OFF); //soft mute - //±ØÐëÏȽ«clkºÍEN_INT¶¼disableµô£¬·ñÔòÇл»bclk·ÖƵֵ¿ÉÄܵ¼ÖÂcodecÄÚ²¿Ê±Ðò»ìÂÒµô£¬ - //±íÏÖ³öÀ´µÄÏÖÏóÊÇ£¬ÒÔºóµÄÒôÀÖ¶¼±ä³ÉÁËÔëÒô£¬¶øÇÒ¾ÍËã°ÑÊäÈëcodecµÄI2S_DATAOUT¶Ï¿ªÒ²Ò»Ñù³öÔëÒô - rk1000_codec_write(codec,ACCELCODEC_R0B, ASC_DEC_DISABLE|ASC_INT_DISABLE); //0x00 + rk1000_codec_write(codec,ACCELCODEC_R04, ASC_INT_MUTE_L|ASC_INT_MUTE_R|ASC_SIDETONE_L_OFF|ASC_SIDETONE_R_OFF); //soft mute + //±ØÐëÏȽ«clkºÍEN_INT¶¼disableµô£¬·ñÔòÇл»bclk·ÖƵֵ¿ÉÄܵ¼ÖÂcodecÄÚ²¿Ê±Ðò»ìÂÒµô£¬ + //±íÏÖ³öÀ´µÄÏÖÏóÊÇ£¬ÒÔºóµÄÒôÀÖ¶¼±ä³ÉÁËÔëÒô£¬¶øÇÒ¾ÍËã°ÑÊäÈëcodecµÄI2S_DATAOUT¶Ï¿ªÒ²Ò»Ñù³öÔëÒô + rk1000_codec_write(codec,ACCELCODEC_R0B, ASC_DEC_DISABLE|ASC_INT_DISABLE); //0x00 /* set iface & srate */ rk1000_codec_write(codec, ACCELCODEC_R09, iface); - if (coeff >= 0){ - rk1000_codec_write(codec, ACCELCODEC_R0A, (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb|ASC_CLKNODIV|ASC_CLK_ENABLE); - rk1000_codec_write(codec, ACCELCODEC_R00, srate|coeff_div[coeff].bclk); + if (coeff >= 0) + { + // rk1000_codec_write(codec, ACCELCODEC_R0A, (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb|ASC_CLKNODIV|ASC_CLK_ENABLE); + rk1000_codec_write(codec, ACCELCODEC_R0A, 0xa0); + // rk1000_codec_write(codec, ACCELCODEC_R00, srate|coeff_div[coeff].bclk); } - rk1000_codec_write(codec,ACCELCODEC_R0B, gR0BReg); + rk1000_codec_write(codec,ACCELCODEC_R0B, gR0BReg); + return 0; } void PhaseOut(struct snd_soc_codec *codec,u32 nStep, u32 us) { DBG("%s[%d]\n",__FUNCTION__,__LINE__); - rk1000_codec_write(codec,ACCELCODEC_R17, 0x0F|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN); //AOL - rk1000_codec_write(codec,ACCELCODEC_R18, 0x0F|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN); //AOR + rk1000_codec_write(codec,ACCELCODEC_R17, 0x00|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN); //AOL + rk1000_codec_write(codec,ACCELCODEC_R18, 0x00|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN); //AOR udelay(us); } void PhaseIn(struct snd_soc_codec *codec,u32 nStep, u32 us) { DBG("%s[%d]\n",__FUNCTION__,__LINE__); - rk1000_codec_write(codec,ACCELCODEC_R17, 0x0f|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN); //AOL gVolReg|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN); //AOL - rk1000_codec_write(codec,ACCELCODEC_R18, 0x0f|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN); //gVolReg|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN); //AOR + rk1000_codec_write(codec,ACCELCODEC_R17, 0x00|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN); //AOL gVolReg|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN); //AOL + rk1000_codec_write(codec,ACCELCODEC_R18, 0x00|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN); //gVolReg|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN); //AOR udelay(us); } static int rk1000_codec_mute(struct snd_soc_dai *dai, int mute) { - struct snd_soc_codec *codec = dai->codec; + struct snd_soc_codec *codec = dai->codec; - DBG("Enter::%s----%d--mute=%d\n",__FUNCTION__,__LINE__,mute); + DBG("Enter::%s----%d--mute=%d\n",__FUNCTION__,__LINE__,mute); - if (mute){ - PhaseOut(codec,1, 5000); - rk1000_codec_write(codec,ACCELCODEC_R19, 0xFF); //AOM - rk1000_codec_write(codec,ACCELCODEC_R04, ASC_INT_MUTE_L|ASC_INT_MUTE_R|ASC_SIDETONE_L_OFF|ASC_SIDETONE_R_OFF); //soft mute - }else{ - rk1000_codec_write(codec,ACCELCODEC_R1D, 0x2a); //setup Vmid and Vref, other module power down - rk1000_codec_write(codec,ACCELCODEC_R1E, 0x40); ///|ASC_PDASDML_ENABLE); - rk1000_codec_write(codec,ACCELCODEC_R1F, 0x09|ASC_PDMIXM_ENABLE|ASC_PDPAM_ENABLE); ///|ASC_PDMICB_ENABLE|ASC_PDMIXM_ENABLE); - PhaseIn(codec,1, 5000); - ///if(gCodecVol != 0){ - rk1000_codec_write(codec,ACCELCODEC_R04, ASC_INT_ACTIVE_L|ASC_INT_ACTIVE_R|ASC_SIDETONE_L_OFF|ASC_SIDETONE_R_OFF); - //} - rk1000_codec_write(codec,ACCELCODEC_R19, 0x7F); //AOM - #if 0 - /*disable speaker */ - rockchip_mux_api_set(SPK_IOMUX_PIN_NAME, SPK_IOMUX_PIN_DIR); - GPIOSetPinDirection(SPK_CTRL_PIN,GPIO_OUT); - GPIOSetPinLevel(SPK_CTRL_PIN,GPIO_HIGH); - #endif + if (mute) + { + PhaseOut(codec,1, 5000); + rk1000_codec_write(codec,ACCELCODEC_R19, 0xFF); //AOM + rk1000_codec_write(codec,ACCELCODEC_R04, ASC_INT_MUTE_L|ASC_INT_MUTE_R|ASC_SIDETONE_L_OFF|ASC_SIDETONE_R_OFF); //soft mute + } + else + { + rk1000_codec_write(codec,ACCELCODEC_R1D, 0x2a); //setup Vmid and Vref, other module power down + rk1000_codec_write(codec,ACCELCODEC_R1E, 0x40); ///|ASC_PDASDML_ENABLE); + rk1000_codec_write(codec,ACCELCODEC_R1F, 0x09|ASC_PDMIXM_ENABLE|ASC_PDPAM_ENABLE); ///|ASC_PDMICB_ENABLE|ASC_PDMIXM_ENABLE); + PhaseIn(codec,1, 5000); + // if(gCodecVol != 0) + { + rk1000_codec_write(codec,ACCELCODEC_R04, ASC_INT_ACTIVE_L|ASC_INT_ACTIVE_R|ASC_SIDETONE_L_OFF|ASC_SIDETONE_R_OFF); } - return 0; + rk1000_codec_write(codec,ACCELCODEC_R19, 0x7F); //AOM + #if 0 + /*disable speaker */ + rockchip_mux_api_set(SPK_IOMUX_PIN_NAME, SPK_IOMUX_PIN_DIR); + GPIOSetPinDirection(SPK_CTRL_PIN,GPIO_OUT); + GPIOSetPinLevel(SPK_CTRL_PIN,GPIO_HIGH); + #endif + } + return 0; } static int rk1000_codec_set_bias_level(struct snd_soc_codec *codec, @@ -621,7 +647,7 @@ static int rk1000_codec_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { /* VREF, VMID=2x5k */ rk1000_codec_write(codec, ACCELCODEC_R1D, pwr_reg | 0x0080); @@ -637,7 +663,7 @@ static int rk1000_codec_set_bias_level(struct snd_soc_codec *codec, rk1000_codec_write(codec, ACCELCODEC_R1D, 0x0000); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -654,40 +680,37 @@ static struct snd_soc_dai_ops rk1000_codec_ops = { .digital_mute = rk1000_codec_mute, }; -struct snd_soc_dai rk1000_codec_dai = { - .name = "rk1000_codec", - .playback = { - .stream_name = "Playback", - .channels_min = 1, - .channels_max = 2, - .rates = RK1000_CODEC_RATES, - .formats = RK1000_CODEC_FORMATS, - }, - .capture = { - .stream_name = "Capture", - .channels_min = 1, - .channels_max = 2, - .rates = RK1000_CODEC_RATES, - .formats = RK1000_CODEC_FORMATS, - }, - .ops = &rk1000_codec_ops, - .symmetric_rates = 1, +static struct snd_soc_dai_driver rk1000_codec_dai[] = { + { + .name = "rk1000_codec", + .playback = { + .stream_name = "Playback", + .channels_min = 1, + .channels_max = 2, + .rates = RK1000_CODEC_RATES, + .formats = RK1000_CODEC_FORMATS, + }, + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 2, + .rates = RK1000_CODEC_RATES, + .formats = RK1000_CODEC_FORMATS, + }, + .ops = &rk1000_codec_ops, + .symmetric_rates = 1, + } }; -EXPORT_SYMBOL_GPL(rk1000_codec_dai); -static int rk1000_codec_suspend(struct platform_device *pdev, pm_message_t state) +static int rk1000_codec_suspend(struct snd_soc_codec *codec, pm_message_t state) { - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); rk1000_codec_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; } -static int rk1000_codec_resume(struct platform_device *pdev) +static int rk1000_codec_resume(struct snd_soc_codec *codec) { - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; int i; u8 data[2]; struct i2c_client *i2c; @@ -707,113 +730,8 @@ static int rk1000_codec_resume(struct platform_device *pdev) return 0; } -static struct snd_soc_codec *rk1000_codec_codec; - -static int rk1000_codec_probe(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec; - int ret = 0; - - if (rk1000_codec_codec == NULL) { - dev_err(&pdev->dev, "Codec device not registered\n"); - return -ENODEV; - } - - socdev->card->codec = rk1000_codec_codec; - codec = rk1000_codec_codec; - - /* register pcms */ - ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); - if (ret < 0) { - dev_err(codec->dev, "failed to create pcms: %d\n", ret); - goto pcm_err; - } - - snd_soc_add_controls(codec, rk1000_codec_snd_controls, - ARRAY_SIZE(rk1000_codec_snd_controls)); - snd_soc_dapm_new_controls(codec, rk1000_codec_dapm_widgets, - ARRAY_SIZE(rk1000_codec_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); - snd_soc_dapm_new_widgets(codec); - - ret = snd_soc_init_card(socdev); - if (ret < 0) { - dev_err(codec->dev, "failed to register card: %d\n", ret); - goto card_err; - } - - return ret; - -card_err: - snd_soc_free_pcms(socdev); - snd_soc_dapm_free(socdev); -pcm_err: - return ret; -} - -static int rk1000_codec_remove(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - snd_soc_free_pcms(socdev); - snd_soc_dapm_free(socdev); - return 0; -} - -struct snd_soc_codec_device soc_codec_dev_rk1000_codec = { - .probe = rk1000_codec_probe, - .remove = rk1000_codec_remove, - .suspend = rk1000_codec_suspend, - .resume = rk1000_codec_resume, -}; -EXPORT_SYMBOL_GPL(soc_codec_dev_rk1000_codec); - -static int rk1000_codec_register(struct rk1000_codec_priv *rk1000_codec, - enum snd_soc_control_type control) +static void rk1000_reg_init(struct snd_soc_codec *codec) { - struct snd_soc_codec *codec = &rk1000_codec->codec; - int ret; - - if (rk1000_codec_codec) { - dev_err(codec->dev, "Another rk1000 codec is registered\n"); - ret = -EINVAL; - goto err; - } - DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); - mutex_init(&codec->mutex); - INIT_LIST_HEAD(&codec->dapm_widgets); - INIT_LIST_HEAD(&codec->dapm_paths); - - codec->private_data = rk1000_codec; - codec->name = "RK1000_CODEC"; - codec->owner = THIS_MODULE; - codec->dai = &rk1000_codec_dai; - codec->num_dai = 1; - codec->reg_cache_size = ARRAY_SIZE(rk1000_codec->reg_cache); - codec->reg_cache = &rk1000_codec->reg_cache; - codec->bias_level = SND_SOC_BIAS_OFF; - codec->set_bias_level = rk1000_codec_set_bias_level; - - memcpy(codec->reg_cache, rk1000_codec_reg, - sizeof(rk1000_codec_reg)); - - codec->write = rk1000_codec_write; - codec->read = rk1000_codec_read; - codec->hw_write = (hw_write_t)i2c_master_send; - - //ret = snd_soc_codec_set_cache_io(codec, 0, 8, control); - //if (ret < 0) { - //dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); - //goto err; - //} - -#if 0 //fzf rk2818 is SPK_CTL - gpio_request(RK2818_PIN_PF7, "rk1000_codec"); - rk2818_mux_api_set(GPIOE_SPI1_FLASH_SEL_NAME, IOMUXA_GPIO1_A3B7); - gpio_direction_output(RK2818_PIN_PF7,GPIO_HIGH); - -#endif -#if 1 rk1000_codec_write(codec,ACCELCODEC_R1D, 0x00); rk1000_codec_write(codec,ACCELCODEC_R17, 0xFF); //AOL rk1000_codec_write(codec,ACCELCODEC_R18, 0xFF); //AOR @@ -867,7 +785,7 @@ static int rk1000_codec_register(struct rk1000_codec_priv *rk1000_codec, rk1000_codec_write(codec,ACCELCODEC_R1B, 0x32); rk1000_codec_write(codec,ACCELCODEC_R1C, ASC_DEM_ENABLE); ///0x00); //use default value - ///dac mode + //dac mode rk1000_codec_write(codec,ACCELCODEC_R17, 0xBF); //AOL ÒôÁ¿×îµÍ rk1000_codec_write(codec,ACCELCODEC_R18, 0xBF); //AOR @@ -892,88 +810,102 @@ static int rk1000_codec_register(struct rk1000_codec_priv *rk1000_codec, rk1000_codec_write(codec,ACCELCODEC_R14, 0x00); gR1314Reg = 0x00; rk1000_codec_write(codec,ACCELCODEC_R1C, ASC_DEM_ENABLE); //0x00); //use default value -#endif +} - rk1000_codec_set_bias_level(&rk1000_codec->codec, SND_SOC_BIAS_STANDBY); +static int rk1000_codec_probe(struct snd_soc_codec *codec) +{ + struct rk1000_codec_priv *rk1000_codec_priv = snd_soc_codec_get_drvdata(codec); - rk1000_codec_dai.dev = codec->dev; + int ret = 0; + DBG("%s::%d\n",__FUNCTION__,__LINE__); rk1000_codec_codec = codec; - - ret = snd_soc_register_codec(codec); + + codec->control_data = rk1000_codec_priv->control_data; + + ret = snd_soc_codec_set_cache_io(codec, 8, 8, rk1000_codec_priv->control_type); if (ret != 0) { - dev_err(codec->dev, "Failed to register codec: %d\n", ret); - goto err; + dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); + return ret; } + + codec->reg_cache = kmemdup(rk1000_codec_reg, sizeof(rk1000_codec_reg), GFP_KERNEL); + if (codec->reg_cache == NULL) + return -ENOMEM; - ret = snd_soc_register_dai(&rk1000_codec_dai); - if (ret != 0) { - dev_err(codec->dev, "Failed to register DAI: %d\n", ret); - snd_soc_unregister_codec(codec); - goto err_codec; - } + rk1000_reg_init(codec); +// snd_soc_add_controls(codec, rk1000_codec_snd_controls, +// ARRAY_SIZE(rk1000_codec_snd_controls)); +// snd_soc_dapm_new_controls(codec, rk1000_codec_dapm_widgets, +// ARRAY_SIZE(rk1000_codec_dapm_widgets)); +// snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); - return 0; -err_codec: - snd_soc_unregister_codec(codec); -err: - kfree(rk1000_codec); return ret; } -static void rk1000_codec_unregister(struct rk1000_codec_priv *rk1000_codec) +static int rk1000_codec_remove(struct snd_soc_codec *codec) { - rk1000_codec_set_bias_level(&rk1000_codec->codec, SND_SOC_BIAS_OFF); - snd_soc_unregister_dai(&rk1000_codec_dai); - snd_soc_unregister_codec(&rk1000_codec->codec); - kfree(rk1000_codec); - rk1000_codec_codec = NULL; + struct rk1000_codec_priv *rk1000_codec_priv = snd_soc_codec_get_drvdata(codec); + + rk1000_codec_set_bias_level(codec, SND_SOC_BIAS_OFF); + kfree(rk1000_codec_priv); + return 0; } -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) -static int rk1000_codec_i2c_probe(struct i2c_client *i2c, +static struct snd_soc_codec_driver soc_codec_dev_rk1000_codec = { + .probe = rk1000_codec_probe, + .remove = rk1000_codec_remove, + .suspend = rk1000_codec_suspend, + .resume = rk1000_codec_resume, + .set_bias_level = rk1000_codec_set_bias_level, + .read = rk1000_codec_read, + .write = rk1000_codec_write, +// .readable_register = rk1000_codec_read_reg_cache, +// .writable_register = rk1000_codec_write_reg_cache, +// .volatile_register = wm8994_volatile, + .reg_cache_size = ARRAY_SIZE(rk1000_codec_reg), + .reg_word_size = sizeof(u8), + .reg_cache_default = rk1000_codec_reg, +}; + +#ifdef RK1000_CODEC_PROC +static int rk1000_codec_proc_init(void); +#endif + +static __devinit int rk1000_codec_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct rk1000_codec_priv *rk1000_codec; - struct snd_soc_codec *codec; - + int ret; + DBG("%s::%d\n",__FUNCTION__,__LINE__); rk1000_codec = kzalloc(sizeof(struct rk1000_codec_priv), GFP_KERNEL); if (rk1000_codec == NULL) return -ENOMEM; - codec = &rk1000_codec->codec; - i2c_set_clientdata(i2c, rk1000_codec); - codec->control_data = i2c; - - codec->dev = &i2c->dev; + rk1000_codec->control_type = SND_SOC_I2C; + rk1000_codec->control_data = i2c; + + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rk1000_codec, + rk1000_codec_dai, ARRAY_SIZE(rk1000_codec_dai)); + if (ret < 0) + kfree(rk1000_codec); + +#ifdef RK1000_CODEC_PROC + rk1000_codec_proc_init(); +#endif - return rk1000_codec_register(rk1000_codec, SND_SOC_I2C); + return ret; } -static int rk1000_codec_i2c_remove(struct i2c_client *client) +static __devexit int rk1000_codec_i2c_remove(struct i2c_client *client) { - struct rk1000_codec_priv *rk1000_codec = i2c_get_clientdata(client); - rk1000_codec_unregister(rk1000_codec); + snd_soc_unregister_codec(&client->dev); + kfree(i2c_get_clientdata(client)); return 0; } -#ifdef CONFIG_PM -static int rk1000_codec_i2c_suspend(struct i2c_client *client, pm_message_t msg) -{ - return snd_soc_suspend_device(&client->dev); -} - -static int rk1000_codec_i2c_resume(struct i2c_client *client) -{ - return snd_soc_resume_device(&client->dev); -} -#else -#define rk1000_codec_i2c_suspend NULL -#define rk1000_codec_i2c_resume NULL -#endif - static const struct i2c_device_id rk1000_codec_i2c_id[] = { { "rk1000_i2c_codec", 0 }, { } @@ -987,21 +919,15 @@ static struct i2c_driver rk1000_codec_i2c_driver = { .owner = THIS_MODULE, }, .probe = rk1000_codec_i2c_probe, - .remove = rk1000_codec_i2c_remove, - .suspend = rk1000_codec_i2c_suspend, - .resume = rk1000_codec_i2c_resume, + .remove = __devexit_p(rk1000_codec_i2c_remove), .id_table = rk1000_codec_i2c_id, }; -#endif + static int __init rk1000_codec_modinit(void) { - int ret; - - ret = i2c_add_driver(&rk1000_codec_i2c_driver); - if (ret != 0) - pr_err("rk1000 codec: Unable to register I2C driver: %d\n", ret); - return ret; + DBG("%s::%d\n",__FUNCTION__,__LINE__); + return i2c_add_driver(&rk1000_codec_i2c_driver); } module_init(rk1000_codec_modinit); @@ -1011,6 +937,229 @@ static void __exit rk1000_codec_exit(void) } module_exit(rk1000_codec_exit); +#ifdef RK1000_CODEC_PROC +void rk1000_codec_reg_read(void) +{ + struct snd_soc_codec *codec = rk1000_codec_codec; + int i; + unsigned int data; + + for (i=0; i<=0x1f; i++){ + data = rk1000_codec_read(codec, i); + printk("reg[0x%x]=0x%x\n",i,data); + } +} + +static ssize_t rk1000_codec_proc_write(struct file *file, const char __user *buffer, + unsigned long len, void *data) +{ + char *cookie_pot; + char *p; + int reg; + int value; + + cookie_pot = (char *)vmalloc( len ); + if (!cookie_pot) + { + return -ENOMEM; + } + else + { + if (copy_from_user( cookie_pot, buffer, len )) + return -EFAULT; + } + + switch(cookie_pot[0]) + { + case 'd': + case 'D': + debug_write_read ++; + debug_write_read %= 2; + if(debug_write_read != 0) + printk("Debug read and write reg on\n"); + else + printk("Debug read and write reg off\n"); + break; + case 'r': + case 'R': + printk("Read reg debug\n"); + if(cookie_pot[1] ==':') + { + debug_write_read = 1; + strsep(&cookie_pot,":"); + while((p=strsep(&cookie_pot,","))) + { + reg = simple_strtol(p,NULL,16); + value = rk1000_codec_read(rk1000_codec_codec,reg); + printk("rk1000_codec_read:0x%04x = 0x%04x",reg,value); + } + debug_write_read = 0; + printk("\n"); + } + else + { + printk("Error Read reg debug.\n"); + printk("For example: echo 'r:22,23,24,25'>wm8994_ts\n"); + } + break; + case 'w': + case 'W': + printk("Write reg debug\n"); + if(cookie_pot[1] ==':') + { + debug_write_read = 1; + strsep(&cookie_pot,":"); + while((p=strsep(&cookie_pot,"="))) + { + reg = simple_strtol(p,NULL,16); + p=strsep(&cookie_pot,","); + value = simple_strtol(p,NULL,16); + rk1000_codec_write(rk1000_codec_codec,reg,value); + printk("rk1000_codec_write:0x%04x = 0x%04x\n",reg,value); + } + debug_write_read = 0; + printk("\n"); + } + else + { + printk("Error Write reg debug.\n"); + printk("For example: w:22=0,23=0,24=0,25=0\n"); + } + break; + case 'p'://enable pa + rk1000_codec_reg_read(); + break; + default: + printk("Help for rk1000_codec_ts .\n-->The Cmd list: \n"); + printk("-->'d&&D' Open or Off the debug\n"); + printk("-->'r&&R' Read reg debug,Example: echo 'r:22,23,24,25'>rk1000_codec_ts\n"); + printk("-->'w&&W' Write reg debug,Example: echo 'w:22=0,23=0,24=0,25=0'>rk1000_codec_ts\n"); + break; + } + + return len; +} +static const struct file_operations rk1000_codec_proc_fops = { + .owner = THIS_MODULE, + //.open = snd_mem_proc_open, + //.read = seq_read, +//#ifdef CONFIG_PCI +// .write = rk1000_codec_proc_write, +//#endif + //.llseek = seq_lseek, + //.release = single_release, +}; + +static int rk1000_codec_proc_init(void) +{ + struct proc_dir_entry *rk1000_codec_proc_entry; + rk1000_codec_proc_entry = create_proc_entry("driver/rk1000_codec", 0777, NULL); + if(rk1000_codec_proc_entry != NULL) + { + rk1000_codec_proc_entry->write_proc = rk1000_codec_proc_write; + return -1; + } + else + { + printk("create rk1000_codec proc error !\n"); + } + return 0; +} + +#endif + +#if 1 +int reg_send_data(struct i2c_client *client, const char start_reg, + const char *buf, int count, unsigned int scl_rate) +{ + int ret; + struct i2c_adapter *adap = client->adapter; + struct i2c_msg msg; + char tx_buf[count + 1]; + + tx_buf[0] = start_reg; + memcpy(tx_buf+1, buf, count); + + msg.addr = client->addr; + msg.buf = tx_buf; + msg.len = count +1; + msg.flags = client->flags; + msg.scl_rate = scl_rate; + + ret = i2c_transfer(adap, &msg, 1); + + return ret; +} + +static int rk1000_control_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int ret; + char data[4] = {0x88, 0x0d, 0x22, 0x00}; +// reg[0x00] = 0x88, --> ADC_CON +// reg[0x01] = 0x0d, --> CODEC_CON +// reg[0x02] = 0x22, --> I2C_CON +// reg[0x03] = 0x00, --> TVE_CON + #ifdef CONFIG_SND_SOC_RK1000 + data[1] = 0x00; + #endif + + DBG("%s::%d\n",__FUNCTION__,__LINE__); + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) + { + dev_err(&client->dev, "i2c bus does not support the rk1000_control\n"); + return -EIO; + } + + msleep(50); + ret = reg_send_data(client, 0x00, data, 4, 100 * 1000); +#if 1 + printk("i2c write ret = 0x%x\n",ret); + memset(data,0,sizeof(data)); + ret = i2c_master_reg8_recv(client, 0, data, (int)4, 20*1000); + printk("i2c read reg %x, %x, %x, %x ret=x%x\n",data[0],data[1],data[2],data[3],ret); +#endif + + if (ret > 0) + ret = 0; + + return ret; +} + +static int rk1000_control_remove(struct i2c_client *client) +{ + return 0; +} + +static const struct i2c_device_id rk1000_control_id[] = { + { "rk1000_control", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, rk1000_control_id); + +static struct i2c_driver rk1000_control_driver = { + .driver = { + .name = "rk1000_control", + }, + .probe = rk1000_control_probe, + .remove = rk1000_control_remove, + .id_table = rk1000_control_id, +}; + +static int __init rk1000_control_init(void) +{ + return i2c_add_driver(&rk1000_control_driver); +} + +static void __exit rk1000_control_exit(void) +{ + i2c_del_driver(&rk1000_control_driver); +} + +module_init(rk1000_control_init); +module_exit(rk1000_control_exit); + MODULE_DESCRIPTION("ASoC RK1000 CODEC driver"); MODULE_AUTHOR("lhh lhh@rock-chips.com"); MODULE_LICENSE("GPL"); +#endif \ No newline at end of file diff --git a/sound/soc/codecs/rk1000_codec.h b/sound/soc/codecs/rk1000_codec.h old mode 100644 new mode 100755 index 96e564f8bde3..817219903b8b --- a/sound/soc/codecs/rk1000_codec.h +++ b/sound/soc/codecs/rk1000_codec.h @@ -259,7 +259,7 @@ #define LINE_2_MIXER_GAIN (0x5) //left and right PA gain #define RK1000_CODEC_NUM_REG 0x20 -extern struct snd_soc_dai rk1000_codec_dai; -extern struct snd_soc_codec_device soc_codec_dev_rk1000_codec; +//extern struct snd_soc_dai rk1000_codec_dai; +//extern struct snd_soc_codec_device soc_codec_dev_rk1000_codec; #endif diff --git a/sound/soc/rk29/Kconfig b/sound/soc/rk29/Kconfig index d2772c079bb1..2cd8bfb71aad 100755 --- a/sound/soc/rk29/Kconfig +++ b/sound/soc/rk29/Kconfig @@ -1,6 +1,6 @@ config SND_RK29_SOC - tristate "SoC Audio for the rockchip RK29 System-on-Chip" - depends on ARCH_RK29 && SND_SOC + tristate "SoC Audio for the rockchip RK29/RK30 System-on-Chip" + depends on (ARCH_RK29 || ARCH_RK30)&& SND_SOC help Say Y or M if you want to add support for codecs attached to the ROCKCHIP IIS interface. You will also need @@ -9,21 +9,28 @@ config SND_RK29_SOC config SND_RK29_SOC_I2S tristate +config SND_RK29_SOC_I2S_8CH + bool "Soc RK29 I2S 8 Channel support(I2S0)" + default y + depends on SND_RK29_SOC_I2S + help + This supports the use of the 8 Channel I2S interface on rk29 processors. + config SND_RK29_SOC_I2S_2CH - bool "Soc RK29 I2S 2 Channel support" + bool "Soc RK29 I2S 2 Channel support(I2S1)" default n depends on SND_RK29_SOC_I2S help This supports the use of the 2 Channel I2S interface on rk29 processors. -config SND_RK29_SOC_I2S_8CH - bool "Soc RK29 I2S 8 Channel support" - default y - depends on SND_RK29_SOC_I2S +config SND_RK_SOC_I2S2_2CH + bool "Soc RK29 I2S 2 Channel support(I2S2)" + default n + depends on SND_RK29_SOC_I2S && ARCH_RK30 help - This supports the use of the 8 Channel I2S interface on rk29 processors. + This supports the use of the 2 Channel I2S2 interface on rk30 processors. -if SND_RK29_SOC_I2S_2CH || SND_RK29_SOC_I2S_8CH +if SND_RK29_SOC_I2S_2CH || SND_RK29_SOC_I2S_8CH || SND_RK_SOC_I2S2_2CH choice bool "Set i2s on DMA event mode" default SND_I2S_DMA_EVENT_STATIC @@ -37,7 +44,7 @@ endif config SND_RK29_SOC_WM8988 tristate "SoC I2S Audio support for rockchip - WM8988" - depends on SND_RK29_SOC && I2C_RK29 + depends on SND_RK29_SOC && (I2C_RK29 || I2C_RK30) select SND_RK29_SOC_I2S select SND_SOC_WM8988 help @@ -46,7 +53,7 @@ config SND_RK29_SOC_WM8988 config SND_RK29_SOC_WM8900 tristate "SoC I2S Audio support for rockchip - WM8900" - depends on SND_RK29_SOC && I2C_RK29 + depends on SND_RK29_SOC && (I2C_RK29 || I2C_RK30) select SND_RK29_SOC_I2S select SND_SOC_WM8900 help @@ -54,7 +61,7 @@ config SND_RK29_SOC_WM8900 with the WM8900. config SND_RK29_SOC_RT5621 tristate "SoC I2S Audio support for rockchip - rt5621" - depends on SND_RK29_SOC && I2C_RK29 + depends on SND_RK29_SOC && (I2C_RK29 || I2C_RK30) select SND_RK29_SOC_I2S select SND_SOC_RT5621 help @@ -62,7 +69,7 @@ config SND_RK29_SOC_RT5621 with the rt5621. config SND_RK29_SOC_RT5631 tristate "SoC I2S Audio support for rockchip - RT5631" - depends on SND_RK29_SOC && I2C_RK29 + depends on SND_RK29_SOC && (I2C_RK29 || I2C_RK30) select SND_RK29_SOC_I2S select SND_SOC_RT5631 help @@ -71,7 +78,7 @@ config SND_RK29_SOC_RT5631 config SND_RK29_SOC_RT5625 tristate "SoC I2S Audio support for rockchip - RT5625" - depends on SND_RK29_SOC && I2C_RK29 + depends on SND_RK29_SOC && (I2C_RK29 || I2C_RK30) select SND_RK29_SOC_I2S select SND_SOC_RT5625 help @@ -80,7 +87,7 @@ config SND_RK29_SOC_RT5625 config SND_RK29_SOC_WM8994 tristate "SoC I2S Audio support for rockchip - WM8994" - depends on SND_RK29_SOC && I2C_RK29 + depends on SND_RK29_SOC && (I2C_RK29 || I2C_RK30) select SND_RK29_SOC_I2S select SND_SOC_WM8994 help @@ -89,7 +96,7 @@ config SND_RK29_SOC_WM8994 config SND_RK29_SOC_CS42L52 tristate "SoC I2S Audio support for rockchip - CS42L52" - depends on SND_RK29_SOC && I2C_RK29 + depends on SND_RK29_SOC && (I2C_RK29 || I2C_RK30) select SND_RK29_SOC_I2S select SND_SOC_CS42L52 help @@ -98,7 +105,7 @@ config SND_RK29_SOC_CS42L52 config SND_RK29_SOC_AIC3111 tristate "SoC I2S Audio support for rockchip - AIC3111" - depends on SND_RK29_SOC && I2C_RK29 + depends on SND_RK29_SOC && (I2C_RK29 || I2C_RK30) select SND_RK29_SOC_I2S select SND_SOC_TLV320AIC3111 help @@ -107,7 +114,7 @@ config SND_RK29_SOC_AIC3111 config SND_RK29_SOC_RK1000 tristate "SoC I2S Audio support for rockchip - RK1000" - depends on SND_RK29_SOC && RK1000_CONTROL && I2C_RK29 + depends on SND_RK29_SOC && (I2C_RK29 || I2C_RK30) select SND_RK29_SOC_I2S select SND_SOC_RK1000 help @@ -116,7 +123,8 @@ config SND_RK29_SOC_RK1000 if SND_RK29_SOC_WM8988 || SND_RK29_SOC_RK1000 || SND_RK29_SOC_WM8994 || SND_RK29_SOC_WM8900 || SND_RK29_SOC_RT5621 || SND_RK29_SOC_RT5631 || SND_RK29_SOC_RT5625 || SND_RK29_SOC_CS42L52 || SND_RK29_SOC_AIC3111 choice - prompt "Set i2s type" + bool "Set i2s type" + default SND_RK29_CODEC_SOC_SLAVE config SND_RK29_CODEC_SOC_MASTER tristate "Codec run in Master" diff --git a/sound/soc/rk29/rk29_i2s.c b/sound/soc/rk29/rk29_i2s.c index 3c129885ba73..9275e958f43b 100755 --- a/sound/soc/rk29/rk29_i2s.c +++ b/sound/soc/rk29/rk29_i2s.c @@ -27,13 +27,21 @@ #include #include +#ifdef ARCH_RK29 #include #include #include #include #include #include - +#else +#include +#include +#include +#include +#include +#include +#endif #include "rk29_pcm.h" #include "rk29_i2s.h" @@ -52,15 +60,15 @@ struct rk29_i2s_info { struct device *dev; void __iomem *regs; - u32 feature; + u32 feature; struct clk *iis_clk; struct clk *iis_pclk; - unsigned char master; + unsigned char master; - struct rockchip_pcm_dma_params *dma_playback; - struct rockchip_pcm_dma_params *dma_capture; + struct rockchip_pcm_dma_params *dma_playback; + struct rockchip_pcm_dma_params *dma_capture; u32 suspend_iismod; u32 suspend_iiscon; @@ -127,7 +135,7 @@ static struct rockchip_pcm_dma_params rockchip_i2s_pcm_stereo_in[MAX_I2S] = { }; */ -#if 1 +#ifdef ARCH_RK29 static u32 i2s0_clk_enter(void) { u32 clk = cru_readl(CRU_CLKSEL3_CON); @@ -143,7 +151,7 @@ static void i2s0_clk_exit(u32 clk) mdelay(1); } #else -static u32 i2s0_clk_enter() +static u32 i2s0_clk_enter(void) { return 0; } @@ -288,11 +296,11 @@ static void rockchip_snd_rxctrl(struct rk29_i2s_info *i2s, int on, bool stopI2S) * Set Rockchip I2S DAI format */ static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai, - unsigned int fmt) + unsigned int fmt) { - struct rk29_i2s_info *i2s = to_info(cpu_dai); - u32 tx_ctl,rx_ctl; - + struct rk29_i2s_info *i2s = to_info(cpu_dai); + u32 tx_ctl,rx_ctl; +#ifdef ARCH_RK29 I2S_DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); tx_ctl = readl(&(pheadi2s->I2S_TXCR)); @@ -309,26 +317,48 @@ static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai, default: I2S_DBG("unknwon master/slave format\n"); return -EINVAL; - } + } +#else + u32 iis_ckr_value;//clock generation register + + I2S_DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_RIGHT_J: - tx_ctl &= ~I2S_BUS_MODE_MASK; //I2S Bus Mode - tx_ctl |= I2S_BUS_MODE_RSJM; - break; - case SND_SOC_DAIFMT_LEFT_J: - tx_ctl &= ~I2S_BUS_MODE_MASK; //I2S Bus Mode - tx_ctl |= I2S_BUS_MODE_LSJM; - break; - case SND_SOC_DAIFMT_I2S: - tx_ctl &= ~I2S_BUS_MODE_MASK; //I2S Bus Mode - tx_ctl |= I2S_BUS_MODE_NOR; - break; - default: - I2S_DBG("Unknown data format\n"); - return -EINVAL; - } - I2S_DBG("Enter::%s----%d, I2S_TXCR=0x%X\n",__FUNCTION__,__LINE__,tx_ctl); + tx_ctl = readl(&(pheadi2s->I2S_TXCR)); + iis_ckr_value = readl(&(pheadi2s->I2S_CKR)); + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + iis_ckr_value &= ~I2S_MODE_MASK; + iis_ckr_value |= I2S_MASTER_MODE; + break; + case SND_SOC_DAIFMT_CBS_CFS: + iis_ckr_value &= ~I2S_MODE_MASK; + iis_ckr_value |= I2S_SLAVE_MODE; + break; + default: + I2S_DBG("unknwon master/slave format\n"); + return -EINVAL; + } + writel(iis_ckr_value, &(pheadi2s->I2S_CKR)); +#endif + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_RIGHT_J: + tx_ctl &= ~I2S_BUS_MODE_MASK; //I2S Bus Mode + tx_ctl |= I2S_BUS_MODE_RSJM; + break; + case SND_SOC_DAIFMT_LEFT_J: + tx_ctl &= ~I2S_BUS_MODE_MASK; //I2S Bus Mode + tx_ctl |= I2S_BUS_MODE_LSJM; + break; + case SND_SOC_DAIFMT_I2S: + tx_ctl &= ~I2S_BUS_MODE_MASK; //I2S Bus Mode + tx_ctl |= I2S_BUS_MODE_NOR; + break; + default: + I2S_DBG("Unknown data format\n"); + return -EINVAL; + } + I2S_DBG("Enter::%s----%d, I2S_TXCR=0x%X\n",__FUNCTION__,__LINE__,tx_ctl); #if 0//defined(CONFIG_SND_RK29_SOC_alc5631) || defined(CONFIG_SND_RK29_SOC_alc5621) rx_ctl = tx_ctl; rx_ctl &= ~I2S_MODE_MASK; @@ -337,9 +367,9 @@ static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai, #else writel(tx_ctl, &(pheadi2s->I2S_TXCR)); #endif - rx_ctl = tx_ctl & 0x00007FFF; - writel(rx_ctl, &(pheadi2s->I2S_RXCR)); - return 0; + rx_ctl = tx_ctl & 0x00007FFF; + writel(rx_ctl, &(pheadi2s->I2S_RXCR)); + return 0; } static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream, @@ -354,15 +384,9 @@ static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream, #endif u32 iismod; u32 dmarc; - - I2S_DBG("Enter %s, %d >>>>>>>>>>>\n", __func__, __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; - } + u32 iis_ckr_value;//clock generation register + + I2S_DBG("Enter %s, %d >>>>>>>>>>>\n", __func__, __LINE__); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) @@ -383,7 +407,8 @@ static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream, /* Working copies of register */ iismod = readl(&(pheadi2s->I2S_TXCR)); - //iismod &= (~((1<<5)-1)); + +// iismod &= (~((1<<5)-1)); switch (params_format(params)) { case SNDRV_PCM_FORMAT_S8: iismod |= SAMPLE_DATA_8bit; @@ -392,33 +417,43 @@ static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream, iismod |= I2S_DATA_WIDTH(15); break; case SNDRV_PCM_FORMAT_S20_3LE: - iismod |= I2S_DATA_WIDTH(19); - break; + iismod |= I2S_DATA_WIDTH(19); + break; case SNDRV_PCM_FORMAT_S24_LE: - iismod |= I2S_DATA_WIDTH(23); - break; + iismod |= I2S_DATA_WIDTH(23); + break; case SNDRV_PCM_FORMAT_S32_LE: - iismod |= I2S_DATA_WIDTH(31); - break; - } - #if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE) - iismod &= ~I2S_SLAVE_MODE; - #endif - - #if defined (CONFIG_SND_RK29_CODEC_SOC_MASTER) - iismod |= I2S_SLAVE_MODE; - #endif + iismod |= I2S_DATA_WIDTH(31); + break; + } +#ifdef ARCH29 + #if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE) + iismod &= ~I2S_SLAVE_MODE; + #endif + + #if defined (CONFIG_SND_RK29_CODEC_SOC_MASTER) + iismod |= I2S_SLAVE_MODE; + #endif +#else + iis_ckr_value = readl(&(pheadi2s->I2S_CKR)); + #if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE) + iis_ckr_value &= ~I2S_SLAVE_MODE; + #endif + #if defined (CONFIG_SND_RK29_CODEC_SOC_MASTER) + iis_ckr_value |= I2S_SLAVE_MODE; + #endif + writel(iis_ckr_value, &(pheadi2s->I2S_CKR)); +#endif +// writel((16<<24) |(16<<18)|(16<<12)|(16<<6)|16, &(pheadi2s->I2S_FIFOLR)); + dmarc = readl(&(pheadi2s->I2S_DMACR)); - //writel((16<<24) |(16<<18)|(16<<12)|(16<<6)|16, &(pheadi2s->I2S_FIFOLR)); - dmarc = readl(&(pheadi2s->I2S_DMACR)); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - dmarc = ((dmarc & 0xFFFFFE00) | 16); - else - dmarc = ((dmarc & 0xFE00FFFF) | 16<<16); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + dmarc = ((dmarc & 0xFFFFFE00) | 16); + else + dmarc = ((dmarc & 0xFE00FFFF) | 16<<16); - writel(dmarc, &(pheadi2s->I2S_DMACR)); - I2S_DBG("Enter %s, %d I2S_TXCR=0x%08X\n", __func__, __LINE__, iismod); + writel(dmarc, &(pheadi2s->I2S_DMACR)); + I2S_DBG("Enter %s, %d I2S_TXCR=0x%08X\n", __func__, __LINE__, iismod); #if 0//defined(CONFIG_SND_RK29_SOC_alc5631) || defined(CONFIG_SND_RK29_SOC_alc5621) dmarc = iismod; dmarc &= ~I2S_MODE_MASK; @@ -427,25 +462,24 @@ static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream, #else writel(iismod, &(pheadi2s->I2S_TXCR)); #endif - iismod = iismod & 0x00007FFF; - writel(iismod, &(pheadi2s->I2S_RXCR)); - return 0; + iismod = iismod & 0x00007FFF; + writel(iismod, &(pheadi2s->I2S_RXCR)); + return 0; } - static int rockchip_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { - int ret = 0; - struct snd_soc_pcm_runtime *rtd = substream->private_data; + int ret = 0; + struct snd_soc_pcm_runtime *rtd = substream->private_data; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) struct rk29_i2s_info *i2s = to_info(rtd->cpu_dai); #else struct rk29_i2s_info *i2s = to_info(rtd->dai->cpu_dai); #endif - bool stopI2S = false; + bool stopI2S = false; - I2S_DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); - switch (cmd) { + I2S_DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); + switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: @@ -467,9 +501,9 @@ static int rockchip_i2s_trigger(struct snd_pcm_substream *substream, int cmd, st default: ret = -EINVAL; break; - } + } - return ret; + return ret; } /* * Set Rockchip Clock source @@ -477,14 +511,14 @@ static int rockchip_i2s_trigger(struct snd_pcm_substream *substream, int cmd, st static int rockchip_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, int clk_id, unsigned int freq, int dir) { - struct rk29_i2s_info *i2s; + struct rk29_i2s_info *i2s; - i2s = to_info(cpu_dai); + i2s = to_info(cpu_dai); - I2S_DBG("Enter:%s, %d, i2s=0x%p, freq=%d\n", __FUNCTION__, __LINE__, i2s, freq); + I2S_DBG("Enter:%s, %d, i2s=0x%p, freq=%d\n", __FUNCTION__, __LINE__, i2s, freq); /*add scu clk source and enable clk*/ - clk_set_rate(i2s->iis_clk, freq); - return 0; +// clk_set_rate(i2s->iis_clk, freq); + return 0; } /* @@ -493,19 +527,20 @@ static int rockchip_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, static int rockchip_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai, int div_id, int div) { - struct rk29_i2s_info *i2s; - u32 reg; +/* + struct rk29_i2s_info *i2s; + u32 reg; - i2s = to_info(cpu_dai); + i2s = to_info(cpu_dai); - /*stereo mode MCLK/SCK=4*/ + //stereo mode MCLK/SCK=4 - reg = readl(&(pheadi2s->I2S_TXCKR)); + reg = readl(&(pheadi2s->I2S_TXCKR)); - I2S_DBG("Enter:%s, %d, div_id=0x%08X, div=0x%08X\n", __FUNCTION__, __LINE__, div_id, div); + I2S_DBG("Enter:%s, %d, div_id=0x%08X, div=0x%08X\n", __FUNCTION__, __LINE__, div_id, div); - /*when i2s in master mode ,must set codec pll div*/ - switch (div_id) { + //when i2s in master mode ,must set codec pll div + switch (div_id) { case ROCKCHIP_DIV_BCLK: reg &= ~I2S_TX_SCLK_DIV_MASK; reg |= I2S_TX_SCLK_DIV(div); @@ -519,36 +554,26 @@ static int rockchip_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai, break; default: return -EINVAL; - } - writel(reg, &(pheadi2s->I2S_TXCKR)); - writel(reg, &(pheadi2s->I2S_RXCKR)); - return 0; -} - -/* - * To avoid duplicating clock code, allow machine driver to - * get the clockrate from here. - */ -u32 rockchip_i2s_get_clockrate(void) -{ - I2S_DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); - return 0; ///clk_get_rate(s3c24xx_i2s.iis_clk); + } + writel(reg, &(pheadi2s->I2S_TXCKR)); + writel(reg, &(pheadi2s->I2S_RXCKR)); +*/ + return 0; } -EXPORT_SYMBOL_GPL(rockchip_i2s_get_clockrate); #ifdef CONFIG_PM int rockchip_i2s_suspend(struct snd_soc_dai *cpu_dai) { - I2S_DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); - //clk_disable(clk); - return 0; + I2S_DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); +// clk_disable(clk); + return 0; } int rockchip_i2s_resume(struct snd_soc_dai *cpu_dai) { - I2S_DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); - //clk_enable(clk); - return 0; + I2S_DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); +// clk_enable(clk); + return 0; } #else #define rockchip_i2s_suspend NULL @@ -578,7 +603,7 @@ static int rockchip_i2s_dai_probe(struct platform_device *pdev, struct snd_soc_d #endif { I2S_DBG("Enter %s, %d >>>>>>>>>>>\n", __func__, __LINE__); - +#ifdef ARCH_RK29 switch(dai->id) { case 0: rk29_mux_api_set(GPIO2D0_I2S0CLK_MIIRXCLKIN_NAME, GPIO2H_I2S0_CLK); @@ -605,6 +630,40 @@ static int rockchip_i2s_dai_probe(struct platform_device *pdev, struct snd_soc_d I2S_DBG("Enter:%s, %d, Error For DevId!!!", __FUNCTION__, __LINE__); return -EINVAL; } +#else + switch(dai->id) { + case 0: + rk30_mux_api_set(GPIO0A7_I2S8CHSDI_NAME, GPIO0A_I2S_8CH_SDI); + rk30_mux_api_set(GPIO0B0_I2S8CHCLK_NAME, GPIO0B_I2S_8CH_CLK); + rk30_mux_api_set(GPIO0B1_I2S8CHSCLK_NAME, GPIO0B_I2S_8CH_SCLK); + rk30_mux_api_set(GPIO0B2_I2S8CHLRCKRX_NAME, GPIO0B_I2S_8CH_LRCK_RX); + rk30_mux_api_set(GPIO0B3_I2S8CHLRCKTX_NAME, GPIO0B_I2S_8CH_LRCK_TX); + rk30_mux_api_set(GPIO0B4_I2S8CHSDO0_NAME, GPIO0B_I2S_8CH_SDO0); + rk30_mux_api_set(GPIO0B5_I2S8CHSDO1_NAME, GPIO0B_I2S_8CH_SDO1); + rk30_mux_api_set(GPIO0B6_I2S8CHSDO2_NAME, GPIO0B_I2S_8CH_SDO2); + rk30_mux_api_set(GPIO0B7_I2S8CHSDO3_NAME, GPIO0B_I2S_8CH_SDO3); + break; + case 1: + rk30_mux_api_set(GPIO0C0_I2S12CHCLK_NAME, GPIO0C_I2S1_2CH_CLK); + rk30_mux_api_set(GPIO0C1_I2S12CHSCLK_NAME, GPIO0C_I2S1_2CH_SCLK); + rk30_mux_api_set(GPIO0C2_I2S12CHLRCKRX_NAME, GPIO0C_I2S1_2CH_LRCK_RX); + rk30_mux_api_set(GPIO0C3_I2S12CHLRCKTX_NAME, GPIO0C_I2S1_2CH_LRCK_TX); + rk30_mux_api_set(GPIO0C4_I2S12CHSDI_NAME, GPIO0C_I2S1_2CH_SDI); + rk30_mux_api_set(GPIO0C5_I2S12CHSDO_NAME, GPIO0C_I2S1_2CH_SDO); + break; + case 2: + rk30_mux_api_set(GPIO0D0_I2S22CHCLK_SMCCSN0_NAME, GPIO0D_I2S2_2CH_CLK); + rk30_mux_api_set(GPIO0D1_I2S22CHSCLK_SMCWEN_NAME, GPIO0D_I2S2_2CH_SCLK); + rk30_mux_api_set(GPIO0D2_I2S22CHLRCKRX_SMCOEN_NAME, GPIO0D_I2S2_2CH_LRCK_RX); + rk30_mux_api_set(GPIO0D3_I2S22CHLRCKTX_SMCADVN_NAME, GPIO0D_I2S2_2CH_LRCK_TX); + rk30_mux_api_set(GPIO0D4_I2S22CHSDI_SMCADDR0_NAME, GPIO0D_I2S2_2CH_SDI); + rk30_mux_api_set(GPIO0D5_I2S22CHSDO_SMCADDR1_NAME, GPIO0D_I2S2_2CH_SDO); + break; + default: + I2S_DBG("Enter:%s, %d, Error For DevId!!!", __FUNCTION__, __LINE__); + return -EINVAL; + } +#endif return 0; } @@ -614,13 +673,13 @@ static int rk29_i2s_probe(struct platform_device *pdev, #else struct snd_soc_dai *dai, #endif - struct rk29_i2s_info *i2s, - unsigned long base) + struct rk29_i2s_info *i2s, + unsigned long base) { struct device *dev = &pdev->dev; - struct resource *res; + struct resource *res; - I2S_DBG("Enter %s, %d >>>>>>>>>>>\n", __func__, __LINE__); + I2S_DBG("Enter %s, %d >>>>>>>>>>>\n", __func__, __LINE__); i2s->dev = dev; @@ -674,28 +733,30 @@ static int rk29_i2s_probe(struct platform_device *pdev, static int __devinit rockchip_i2s_probe(struct platform_device *pdev) { - struct rk29_i2s_info *i2s; + struct rk29_i2s_info *i2s; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) struct snd_soc_dai_driver *dai; #else struct snd_soc_dai *dai; #endif - int ret; + int ret; - I2S_DBG("Enter %s, %d pdev->id = %d >>>>>>>>>>>\n", __func__, __LINE__, pdev->id); + I2S_DBG("Enter %s, %d pdev->id = %d >>>>>>>>>>>\n", __func__, __LINE__, pdev->id); - if(pdev->id >= MAX_I2S) { - dev_err(&pdev->dev, "id %d out of range\n", pdev->id); - return -EINVAL; - } + if(pdev->id >= MAX_I2S) { + dev_err(&pdev->dev, "id %d out of range\n", pdev->id); + return -EINVAL; + } - i2s = &rk29_i2s[pdev->id]; - dai = &rk29_i2s_dai[pdev->id]; + i2s = &rk29_i2s[pdev->id]; + dai = &rk29_i2s_dai[pdev->id]; #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)) dai->dev = &pdev->dev; #endif dai->id = pdev->id; dai->symmetric_rates = 1; + +#ifdef ARCH_RK29 if(pdev->id == 0) { dai->name = "rk29_i2s.0"; dai->playback.channels_min = 2; @@ -705,6 +766,26 @@ static int __devinit rockchip_i2s_probe(struct platform_device *pdev) dai->playback.channels_min = 2; dai->playback.channels_max = 2; } +#else + switch(pdev->id) + { + case 0: + dai->name = "rk29_i2s.0"; + dai->playback.channels_min = 2; + dai->playback.channels_max = 8; + break; + case 1: + dai->name = "rk29_i2s.1"; + dai->playback.channels_min = 2; + dai->playback.channels_max = 2; + break; + case 2: + dai->name = "rk29_i2s.2"; + dai->playback.channels_min = 2; + dai->playback.channels_max = 2; + break; + } +#endif dai->playback.rates = ROCKCHIP_I2S_RATES; dai->playback.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE; dai->capture.channels_min = 2; @@ -716,11 +797,10 @@ static int __devinit rockchip_i2s_probe(struct platform_device *pdev) dai->suspend = rockchip_i2s_suspend; dai->resume = rockchip_i2s_resume; - //i2s->feature |= S3C_FEATURE_CDCLKCON; - i2s->dma_capture = &rk29_i2s_pcm_stereo_in[pdev->id]; i2s->dma_playback = &rk29_i2s_pcm_stereo_out[pdev->id]; - + +#ifdef ARCH_RK29 if (pdev->id == 1) { i2s->dma_capture->channel = DMACH_I2S_2CH_RX; i2s->dma_capture->dma_addr = RK29_I2S_2CH_PHYS + I2S_RXR_BUFF; @@ -732,7 +812,29 @@ static int __devinit rockchip_i2s_probe(struct platform_device *pdev) i2s->dma_playback->channel = DMACH_I2S_8CH_TX; i2s->dma_playback->dma_addr = RK29_I2S_8CH_PHYS + I2S_TXR_BUFF; } - +#else + switch(pdev->id) + { + case 0: + i2s->dma_capture->channel = DMACH_I2S0_8CH_RX; + i2s->dma_capture->dma_addr = RK30_I2S0_8CH_PHYS + I2S_RXR_BUFF; + i2s->dma_playback->channel = DMACH_I2S0_8CH_TX; + i2s->dma_playback->dma_addr = RK30_I2S0_8CH_PHYS + I2S_TXR_BUFF; + break; + case 1: + i2s->dma_capture->channel = DMACH_I2S1_2CH_RX; + i2s->dma_capture->dma_addr = RK30_I2S1_2CH_PHYS + I2S_RXR_BUFF; + i2s->dma_playback->channel = DMACH_I2S1_2CH_TX; + i2s->dma_playback->dma_addr = RK30_I2S1_2CH_PHYS + I2S_TXR_BUFF; + break; + case 2: + i2s->dma_capture->channel = DMACH_I2S2_2CH_RX; + i2s->dma_capture->dma_addr = RK30_I2S2_2CH_PHYS + I2S_RXR_BUFF; + i2s->dma_playback->channel = DMACH_I2S2_2CH_TX; + i2s->dma_playback->dma_addr = RK30_I2S2_2CH_PHYS + I2S_TXR_BUFF; + break; + } +#endif i2s->dma_capture->client = &rk29_dma_client_in; i2s->dma_capture->dma_size = 4; i2s->dma_capture->flag = 0; //add by sxj, used for burst change @@ -752,7 +854,7 @@ static int __devinit rockchip_i2s_probe(struct platform_device *pdev) } clk_enable(i2s->iis_clk); - clk_set_rate(i2s->iis_clk, 11289600); +// clk_set_rate(i2s->iis_clk, 11289600); ret = rk29_i2s_probe(pdev, dai, i2s, 0); if (ret) goto err_clk; @@ -771,7 +873,6 @@ err: return ret; } - static int __devexit rockchip_i2s_remove(struct platform_device *pdev) { #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) @@ -779,7 +880,6 @@ static int __devexit rockchip_i2s_remove(struct platform_device *pdev) #else snd_soc_unregister_dai(&rk29_i2s_dai); #endif - return 0; } @@ -794,8 +894,8 @@ static struct platform_driver rockchip_i2s_driver = { static int __init rockchip_i2s_init(void) { - I2S_DBG("Enter %s, %d >>>>>>>>>>>\n", __func__, __LINE__); - + I2S_DBG("Enter %s, %d >>>>>>>>>>>\n", __func__, __LINE__); + return platform_driver_register(&rockchip_i2s_driver); } module_init(rockchip_i2s_init); @@ -815,6 +915,7 @@ MODULE_LICENSE("GPL"); #ifdef CONFIG_PROC_FS #include #include +#ifdef ARCK_RK29 static int proc_i2s_show(struct seq_file *s, void *v) { struct rk29_i2s_info *i2s=&rk29_i2s[0]; @@ -834,6 +935,24 @@ static int proc_i2s_show(struct seq_file *s, void *v) return 0; } +#else +static int proc_i2s_show(struct seq_file *s, void *v) +{ + struct rk29_i2s_info *i2s=&rk29_i2s[1]; + printk("========Show I2S reg========\n"); + + printk("I2S_TXCR = 0x%08X\n", readl(&(pheadi2s->I2S_TXCR))); + printk("I2S_RXCR = 0x%08X\n", readl(&(pheadi2s->I2S_RXCR))); + printk("I2S_CKR = 0x%08X\n", readl(&(pheadi2s->I2S_CKR))); + printk("I2S_DMACR = 0x%08X\n", readl(&(pheadi2s->I2S_DMACR))); + printk("I2S_INTCR = 0x%08X\n", readl(&(pheadi2s->I2S_INTCR))); + printk("I2S_INTSR = 0x%08X\n", readl(&(pheadi2s->I2S_INTSR))); + printk("I2S_XFER = 0x%08X\n", readl(&(pheadi2s->I2S_XFER))); + + printk("========Show I2S reg========\n"); + return 0; +} +#endif static int proc_i2s_open(struct inode *inode, struct file *file) { return single_open(file, proc_i2s_show, NULL); @@ -850,7 +969,6 @@ static int __init i2s_proc_init(void) { proc_create("i2s_reg", 0, NULL, &proc_i2s_fops); return 0; - } late_initcall(i2s_proc_init); #endif /* CONFIG_PROC_FS */ diff --git a/sound/soc/rk29/rk29_i2s.h b/sound/soc/rk29/rk29_i2s.h index ae9eb51ee886..47273b75c141 100755 --- a/sound/soc/rk29/rk29_i2s.h +++ b/sound/soc/rk29/rk29_i2s.h @@ -7,6 +7,7 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#include #ifndef _ROCKCHIP_IIS_H #define _ROCKCHIP_IIS_H @@ -22,10 +23,13 @@ #define CHANNEL_2_EN (1<<15) #define CHANNEL_3_EN (2<<15) #define CHANNLE_4_EN (3<<15) - +#ifdef ARCH_RK29 #define TX_MODE_MASTER (0<<13) #define TX_MODE_SLAVE (1<<13) - +#else +#define TX_MODE_MASTER (0<<27) +#define TX_MODE_SLAVE (1<<27) +#endif #define RESET_TX (1<<17) #define RESET_RX (1<<16) @@ -94,11 +98,15 @@ #define I2S_HWT_16BIT (0<<14) #define I2S_HWT_32BIT (1<<14) - +#ifdef ARCH_RK29 #define I2S_MASTER_MODE (0<<13) #define I2S_SLAVE_MODE (1<<13) #define I2S_MODE_MASK (1<<13) - +#else +#define I2S_MASTER_MODE (0<<27) +#define I2S_SLAVE_MODE (1<<27) +#define I2S_MODE_MASK (1<<27) +#endif #define I2S_JUSTIFIED_RIGHT (0<<12) #define I2S_JUSTIFIED_LEFT (1<<12) @@ -179,6 +187,7 @@ #define I2S_TXR_BUFF 0x20 #define I2S_RXR_BUFF 0x24 +#ifdef ARCH_RK29 //I2S Registers typedef volatile struct tagIIS_STRUCT { @@ -196,12 +205,28 @@ typedef volatile struct tagIIS_STRUCT unsigned int I2S_TXRST; unsigned int I2S_RXRST; }I2S_REG,*pI2S_REG; +#else +typedef volatile struct tagIIS_STRUCT +{ + unsigned int I2S_TXCR;//0xF 0 + unsigned int I2S_RXCR;//0xF 4 + unsigned int I2S_CKR;//0x3F 8 + unsigned int I2S_FIFOLR;//c + unsigned int I2S_DMACR;//0x001F0110 10 + unsigned int I2S_INTCR;//0x01F00000 14 + unsigned int I2S_INTSR;//0x00 18 + unsigned int I2S_XFER;//0x00000003 1c + unsigned int I2S_CLR;//20 + unsigned int I2S_TXDR;//24 + unsigned int I2S_RXDR; +}I2S_REG,*pI2S_REG; +#endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) extern struct snd_soc_dai_driver rk29_i2s_dai[]; #else extern struct snd_soc_dai rk29_i2s_dai[]; #endif -//extern void rockchip_add_device_i2s(void); + #endif /* _ROCKCHIP_IIS_H */ diff --git a/sound/soc/rk29/rk29_pcm.c b/sound/soc/rk29/rk29_pcm.c index a2cb3e96a8dc..8cbc3de72ab4 100755 --- a/sound/soc/rk29/rk29_pcm.c +++ b/sound/soc/rk29/rk29_pcm.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -24,10 +25,15 @@ #include #include +#ifdef ARCH_RK29 #include - +#else +#include +#endif #include "rk29_pcm.h" +#include + #if 0 #define DBG(x...) printk(KERN_INFO x) #else @@ -173,7 +179,7 @@ static int rockchip_pcm_hw_params(struct snd_pcm_substream *substream, struct rockchip_pcm_dma_params *dma = rtd->dai->cpu_dai->dma_data; #endif unsigned long totbytes = params_buffer_bytes(params); - int ret = 0; +// int ret = 0; DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); /*by Vincent Hsiung for EQ Vol Change*/ @@ -278,7 +284,7 @@ static int rockchip_pcm_prepare(struct snd_pcm_substream *substream) } DBG("Enter::%s, %d, ret=%d, Channel=%d, Addr=0x%X\n", __FUNCTION__, __LINE__, ret, prtd->params->channel, prtd->params->dma_addr); ret = rk29_dma_config(prtd->params->channel, - prtd->params->dma_size, 16); + prtd->params->dma_size, 1); DBG("Enter:%s, %d, ret = %d, Channel=%d, Size=%d\n", __FUNCTION__, __LINE__, ret, prtd->params->channel, @@ -509,9 +515,8 @@ static int rockchip_pcm_new(struct snd_card *card, struct snd_soc_dai *dai, struct snd_pcm *pcm) { int ret = 0; - DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); - + if (!card->dev->dma_mask) card->dev->dma_mask = &rockchip_pcm_dmamask; if (!card->dev->coherent_dma_mask) @@ -551,7 +556,7 @@ static struct snd_soc_platform_driver rockchip_pcm_platform = { static int __devinit rockchip_pcm_platform_probe(struct platform_device *pdev) { - DBG("Enter::%s, %d\n", __FUNCTION__, __LINE__); + DBG("Enter::%s, %d\n", __FUNCTION__, __LINE__); return snd_soc_register_platform(&pdev->dev, &rockchip_pcm_platform); } @@ -572,7 +577,7 @@ static struct platform_driver rockchip_pcm_driver = { static int __init snd_rockchip_pcm_init(void) { - DBG("Enter::%s, %d\n", __FUNCTION__, __LINE__); + DBG("Enter::%s, %d\n", __FUNCTION__, __LINE__); return platform_driver_register(&rockchip_pcm_driver); } module_init(snd_rockchip_pcm_init); @@ -593,7 +598,7 @@ EXPORT_SYMBOL_GPL(rk29_soc_platform); static int __init rockchip_soc_platform_init(void) { - DBG("Enter::%s, %d\n", __FUNCTION__, __LINE__); + DBG("Enter::%s, %d\n", __FUNCTION__, __LINE__); return snd_soc_register_platform(&rk29_soc_platform); } module_init(rockchip_soc_platform_init); @@ -610,3 +615,4 @@ MODULE_AUTHOR("rockchip"); MODULE_DESCRIPTION("ROCKCHIP PCM ASoC Interface"); MODULE_LICENSE("GPL"); + diff --git a/sound/soc/rk29/rk29_rk1000codec.c b/sound/soc/rk29/rk29_rk1000codec.c old mode 100644 new mode 100755 index bee8341cb1e6..b5457b986803 --- a/sound/soc/rk29/rk29_rk1000codec.c +++ b/sound/soc/rk29/rk29_rk1000codec.c @@ -19,12 +19,11 @@ #include #include #include -#include #include "../codecs/rk1000_codec.h" #include "rk29_pcm.h" #include "rk29_i2s.h" -#if 0 +#if 1 #define DBG(x...) printk(KERN_INFO x) #else #define DBG(x...) @@ -33,145 +32,97 @@ static int rk29_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 *codec_dai = rtd->dai->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; int ret; - 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)) - { - ret = codec_dai->ops->hw_params(substream, params, codec_dai); //by Vincent - DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); - } - else - { - /* set codec DAI configuration */ - #if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE) - ret = codec_dai->ops->set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); - #endif - #if defined (CONFIG_SND_RK29_CODEC_SOC_MASTER) - ret = codec_dai->ops->set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM ); - #endif - if (ret < 0) - return ret; - /* set cpu DAI configuration */ - #if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE) - ret = cpu_dai->ops->set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | + DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); + + /* set codec DAI configuration */ + #if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE) + ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); + #endif + #if defined (CONFIG_SND_RK29_CODEC_SOC_MASTER) + ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM ); + #endif + if (ret < 0) + return ret; + /* set cpu DAI configuration */ + #if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE) + ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); - #endif - #if defined (CONFIG_SND_RK29_CODEC_SOC_MASTER) - ret = cpu_dai->ops->set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | + #endif + #if defined (CONFIG_SND_RK29_CODEC_SOC_MASTER) + ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); - #endif - if (ret < 0) - return ret; - } - - return 0; -} - -static const struct snd_soc_dapm_widget rk29_dapm_widgets[] = { - SND_SOC_DAPM_LINE("Audio Out", NULL), - SND_SOC_DAPM_LINE("Line in", NULL), - SND_SOC_DAPM_MIC("Micn", NULL), - SND_SOC_DAPM_MIC("Micp", NULL), -}; + #endif + if (ret < 0) + return ret; -static const struct snd_soc_dapm_route audio_map[]= { - - {"Audio Out", NULL, "LOUT1"}, - {"Audio Out", NULL, "ROUT1"}, - {"Line in", NULL, "RINPUT1"}, - {"Line in", NULL, "LINPUT1"}, - {"Micn", NULL, "RINPUT2"}, - {"Micp", NULL, "LINPUT2"}, -}; +//ÉèÖ÷ÖƵ²¿·Ö£¬ÔÝʱδÉèÖà + return 0; +} /* * Logic for a rk1000 codec as connected on a rockchip board. */ -static int rk29_rk1000_codec_init(struct snd_soc_codec *codec) +static int rk29_rk1000_codec_init(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_dai *codec_dai = &codec->dai[0]; - int ret; - - DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); - - ret = snd_soc_dai_set_sysclk(codec_dai, 0, - 12000000, SND_SOC_CLOCK_IN); - if (ret < 0) { - printk(KERN_ERR "Failed to set WM8988 SYSCLK: %d\n", ret); - return ret; - } - - /* Add specific widgets */ - snd_soc_dapm_new_controls(codec, rk29_dapm_widgets, - ARRAY_SIZE(rk29_dapm_widgets)); - - /* Set up specific audio path audio_mapnects */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); - - snd_soc_dapm_sync(codec); - - return 0; + return 0; } static struct snd_soc_ops rk29_ops = { .hw_params = rk29_hw_params, }; -static struct snd_soc_dai_link rk29_dai = { - .name = "RK1000_CODEC", +static struct snd_soc_dai_link rk29_dai[] = { + { + .name = "RK1000", .stream_name = "RK1000 CODEC PCM", - .cpu_dai = &rk29_i2s_dai, - .codec_dai = &rk1000_codec_dai, + .platform_name = "rockchip-audio", + .codec_name = "RK1000_CODEC.0-0060", + .codec_dai_name = "rk1000_codec", + .cpu_dai_name = "rk29_i2s.1", .init = rk29_rk1000_codec_init, .ops = &rk29_ops, + } }; static struct snd_soc_card snd_soc_card_rk29 = { - .name = "RK1000_CODEC", - .platform = &rk29_soc_platform, - .dai_link = &rk29_dai, - .num_links = 1, + .name = "RK29_RK1000", + .dai_link = rk29_dai, + .num_links = 1, }; -static struct snd_soc_device rk29_snd_devdata = { - .card = &snd_soc_card_rk29, - .codec_dev = &soc_codec_dev_rk1000_codec, -}; - static struct platform_device *rk29_snd_device; static int __init audio_card_init(void) { int ret =0; - DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); + + DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); + rk29_snd_device = platform_device_alloc("soc-audio", -1); if (!rk29_snd_device) { - DBG("platform device allocation failed\n"); + printk("platform device allocation failed\n"); ret = -ENOMEM; return ret; } - DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); - platform_set_drvdata(rk29_snd_device, &rk29_snd_devdata); - DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); - rk29_snd_devdata.dev = &rk29_snd_device->dev; + + platform_set_drvdata(rk29_snd_device, &snd_soc_card_rk29); ret = platform_device_add(rk29_snd_device); - DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); if (ret) { - DBG("platform device add failed\n"); - platform_device_put(rk29_snd_device); + printk("platform device add failed\n"); + platform_device_put(rk29_snd_device); } + printk("audio_card_init end....\n"); return ret; } + static void __exit audio_card_exit(void) { platform_device_unregister(rk29_snd_device);