From: 邱建斌 Date: Sun, 7 Apr 2013 08:04:01 +0000 (+0800) Subject: rk610 codec : add modem sound control X-Git-Tag: firefly_0821_release~7292 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=fd339aaca353221b7f44ba2b6e1c67f50f08c758;p=firefly-linux-kernel-4.4.55.git rk610 codec : add modem sound control --- diff --git a/arch/arm/mach-rk30/board-rk3168-tb.c b/arch/arm/mach-rk30/board-rk3168-tb.c index d8b722cf5d33..19ecf4669ce1 100755 --- a/arch/arm/mach-rk30/board-rk3168-tb.c +++ b/arch/arm/mach-rk30/board-rk3168-tb.c @@ -752,7 +752,7 @@ static int rk610_codec_io_init(void) } static struct rk610_codec_platform_data rk610_codec_pdata = { - .spk_ctl_io = RK30_PIN4_PC6, + .spk_ctl_io = RK30_PIN2_PD7, .io_init = rk610_codec_io_init, }; #endif diff --git a/drivers/misc/modem_sound.c b/drivers/misc/modem_sound.c index 329122560665..f273f46b26b2 100755 --- a/drivers/misc/modem_sound.c +++ b/drivers/misc/modem_sound.c @@ -23,7 +23,7 @@ #define DISABLE 0 static struct modem_sound_data *modem_sound; -#ifdef CONFIG_SND_RK_SOC_RK2928 +#if defined(CONFIG_SND_RK_SOC_RK2928)|| defined(CONFIG_SND_RK29_SOC_RK610) extern void call_set_spk(int on); #endif int modem_sound_spkctl(int status) diff --git a/sound/soc/codecs/rk610_codec.c b/sound/soc/codecs/rk610_codec.c index 2f5ee435457c..d735aba1cc75 100755 --- a/sound/soc/codecs/rk610_codec.c +++ b/sound/soc/codecs/rk610_codec.c @@ -37,26 +37,14 @@ #include #include #endif +#define HP_OUT 0 +#define HP_IN 1 //if you find resume rk610 cannot work,you can try RESUME_PROBLEM 1. //if rk610 Normal working on RESUME_PROBLEM 1, you must detect Machine other driver queue. //you can look soc-core.c the resume source.s #define RESUME_PROBLEM 0 -//old control method,please filling rk610_codec_platform_data into Board-xx-xx.c -//qjb 2013-01-14 -#if 0 -#if defined(CONFIG_MACH_RK3168_DS1006H)|| defined(CONFIG_MACH_RK3168_LR097) -#define RK610_SPK_CTRL_PIN RK30_PIN2_PD7 -#elif defined(CONFIG_ARCH_RK3066B) -#define RK610_SPK_CTRL_PIN RK30_PIN2_PA0 -#elif defined(CONFIG_ARCH_RK30) -#define RK610_SPK_CTRL_PIN RK30_PIN4_PC6 -#else -#define RK610_SPK_CTRL_PIN RK29_PIN6_PB6 -#endif -#endif - //1:set pll from rk610 #define RK610_CTL_PLL 0 @@ -116,8 +104,31 @@ struct rk610_codec_priv { int rk610_workstatus; #endif struct rk610_codec_platform_data *pdata; + int call_enable; + int headset_status; }; +static void spk_ctrl_fun(int status) +{ + struct rk610_codec_priv *rk610_codec = NULL; + if(rk610_codec_codec == NULL) + return; + rk610_codec = snd_soc_codec_get_drvdata(rk610_codec_codec); + if(rk610_codec == NULL) + return; +#ifdef CONFIG_MODEM_SOUND + if(rk610_codec->call_enable){ + DBG("%s:: is calling cannot set spk\n",__FUNCTION__); + return; + } +#endif + if(rk610_codec->spk_ctrl_io) + { + DBG("%s:: spk status = %d\n",__FUNCTION__,status); + gpio_set_value(rk610_codec->spk_ctrl_io, status); + } +} + void codec_set_spk(bool on) { struct rk610_codec_priv *rk610_codec; @@ -185,8 +196,13 @@ static inline void rk610_codec_write_reg_cache(struct snd_soc_codec *codec, static int rk610_codec_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) { + struct rk610_codec_priv *rk610_codec = snd_soc_codec_get_drvdata(rk610_codec_codec); u8 data[2]; struct i2c_client *i2c; +#ifdef CONFIG_MODEM_SOUND + if(rk610_codec->call_enable) + return 0; +#endif DBG("Enter::%s, %d, reg=0x%02X, value=0x%02X\n",__FUNCTION__,__LINE__, reg, value); data[0] = value & 0x00ff; rk610_codec_write_reg_cache (codec, reg, value); @@ -202,32 +218,107 @@ static int rk610_codec_write(struct snd_soc_codec *codec, unsigned int reg, } } -void rk610_codec_reg_read(void) +#ifdef CONFIG_MODEM_SOUND +static int rk610_codec_write_incall(struct snd_soc_codec *codec, unsigned int reg, + unsigned int value) { - struct snd_soc_codec *codec = rk610_codec_codec; - int i; - unsigned int data; + u8 data[2]; + struct i2c_client *i2c; + DBG("Enter::%s, %d, reg=0x%02X, value=0x%02X\n",__FUNCTION__,__LINE__, reg, value); + data[0] = value & 0x00ff; + rk610_codec_write_reg_cache (codec, reg, value); + i2c = (struct i2c_client *)codec->control_data; + i2c->addr = (i2c->addr & 0x60)|reg; - for (i=0; i<=0x1f; i++){ - data = rk610_codec_read(codec, i); - printk("reg[0x%x]=0x%x\n",i,data); - } + if (codec->hw_write(codec->control_data, data, 1) == 1) + return 0; + else + return -EIO; } -static void spk_ctrl_fun(int status) +void call_set_spk(int on) { - struct rk610_codec_priv *rk610_codec = NULL; - if(rk610_codec_codec == NULL) + struct rk610_codec_priv *rk610_codec; + if(!rk610_codec_codec) return; rk610_codec = snd_soc_codec_get_drvdata(rk610_codec_codec); - if(rk610_codec == NULL) + if(!rk610_codec) return; - if(rk610_codec->spk_ctrl_io) + switch(on) { - DBG("--------%s----------status = %d\n",__FUNCTION__,status); - gpio_set_value(rk610_codec->spk_ctrl_io, status); + case 0: + //modem exit call,codec disable loopback + printk("%s modem exit call \n", __FUNCTION__); + rk610_codec_write(rk610_codec_codec,ACCELCODEC_R0E, 0x80); + rk610_codec->call_enable = 0; + break; + case 1: + //modem calling,codec enable loopback,spk hp different volume + printk("%s spk incalling\n", __FUNCTION__); + rk610_codec_write(rk610_codec_codec,ACCELCODEC_R0E, 0x00); + rk610_codec->call_enable = 1; + return; + case 2: + printk("%s hp incalling\n", __FUNCTION__); + rk610_codec_write(rk610_codec_codec,ACCELCODEC_R0E, 0x00); + rk610_codec->call_enable = 1; + break; + case 3: + printk("%s bt incalling\n", __FUNCTION__); + rk610_codec_write(rk610_codec_codec,ACCELCODEC_R0E, 0x00); + rk610_codec->call_enable = 1; + break; } + + return; +} +#endif +#ifdef CONFIG_RK_HEADSET_DET +//for headset +void rk2928_codec_set_spk(bool on) +{ + struct rk610_codec_priv *rk610_codec; + if(!rk610_codec_codec) + return; + rk610_codec=snd_soc_codec_get_drvdata(rk610_codec_codec); + if(!rk610_codec) + return; + + if(on) + rk610_codec->headset_status = HP_IN; + else + rk610_codec->headset_status = HP_OUT; + + if(rk610_codec->call_enable) + return; + + printk("%s: headset %s %s PA bias_level=%d\n",__FUNCTION__,on?"in":"out",on?"disable":"enable",codec->dapm.bias_level); + if(on) { + if(rk610_codec->spk_ctrl_io) + gpio_set_value(rk610_codec->spk_ctrl_io, GPIO_LOW); + } + else { + if(codec->dapm.bias_level == SND_SOC_BIAS_STANDBY + || codec->dapm.bias_level == SND_SOC_BIAS_OFF){ + return; + } + if(rk610_codec->spk_ctrl_io) + gpio_set_value(rk610_codec->spk_ctrl_io, GPIO_HIGH); + } +} +#endif + +void rk610_codec_reg_read(void) +{ + struct snd_soc_codec *codec = rk610_codec_codec; + int i; + unsigned int data; + + for (i=0; i<=0x1f; i++){ + data = rk610_codec_read(codec, i); + printk("reg[0x%x]=0x%x\n",i,data); + } } struct _coeff_div { @@ -766,22 +857,6 @@ static int rk610_codec_probe(struct snd_soc_codec *codec) INIT_DELAYED_WORK(&rk610_codec->rk610_delayed_work, rk610_delayedwork_fun); -//old control method,please filling rk610_codec_platform_data into Board-xx-xx.c -//qjb 2013-01-14 -#if 0 -#ifdef RK610_SPK_CTRL_PIN - rk610_codec->spk_ctrl_io = RK610_SPK_CTRL_PIN; - ret = gpio_request(rk610_codec->spk_ctrl_io, "rk610 spk_ctrl"); - if (ret){ - printk("rk610_control request gpio fail!\n"); - return ret; - } - gpio_direction_output(rk610_codec->spk_ctrl_io, GPIO_LOW); - gpio_set_value(rk610_codec->spk_ctrl_io, GPIO_LOW); -#else - rk610_codec->spk_ctrl_io = 0; -#endif -#endif if(rk610_codec->spk_ctrl_io) { ret = gpio_request(rk610_codec->spk_ctrl_io, "rk610 spk_ctrl"); @@ -794,6 +869,8 @@ static int rk610_codec_probe(struct snd_soc_codec *codec) } rk610_codec->hdmi_ndet = true; + rk610_codec->call_enable = 0; + rk610_codec->headset_status = HP_OUT; #if RESUME_PROBLEM rk610_codec->rk610_workstatus = SND_SOC_DAPM_STREAM_NOP; #endif diff --git a/sound/soc/codecs/rk610_codec.h b/sound/soc/codecs/rk610_codec.h old mode 100644 new mode 100755 index 10b7e75f84bd..db007789ebc4 --- a/sound/soc/codecs/rk610_codec.h +++ b/sound/soc/codecs/rk610_codec.h @@ -134,7 +134,7 @@ #define ASC_INT_ENABLE (0x1 << 1) //interpolate filter enable #define ASC_INT_DISABLE (0x0 << 1) -//Input +//Input ACCELCODEC_R0E #define ASC_INPUT_MUTE (0x1 << 7) #define ASC_INPUT_ACTIVE (0x0 << 7) #define ASC_INPUT_VOL_0DB (0x0)