rk610 codec : add modem sound control
author邱建斌 <qjb@rock-chips.com>
Sun, 7 Apr 2013 08:04:01 +0000 (16:04 +0800)
committer邱建斌 <qjb@rock-chips.com>
Sun, 7 Apr 2013 08:05:04 +0000 (16:05 +0800)
arch/arm/mach-rk30/board-rk3168-tb.c
drivers/misc/modem_sound.c
sound/soc/codecs/rk610_codec.c
sound/soc/codecs/rk610_codec.h [changed mode: 0644->0755]

index d8b722cf5d331cc439bdefff4ad1810062518fed..19ecf4669ce13c4976a19cf86005271f8a014861 100755 (executable)
@@ -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
index 32912256066587854a93c4cc88834c1408cc88a0..f273f46b26b2739708dcade903c3f521a4046555 100755 (executable)
@@ -23,7 +23,7 @@
 #define DISABLE            0\r
 \r
 static struct modem_sound_data *modem_sound;\r
-#ifdef CONFIG_SND_RK_SOC_RK2928\r
+#if defined(CONFIG_SND_RK_SOC_RK2928)|| defined(CONFIG_SND_RK29_SOC_RK610)\r
 extern void call_set_spk(int on);\r
 #endif\r
 int modem_sound_spkctl(int status)\r
index 2f5ee435457c1cca86e9b1c5fea713466e510ccf..d735aba1cc75269d2fd842fe011252f3dd072a6e 100755 (executable)
 #include <linux/seq_file.h>
 #include <linux/vmalloc.h>
 #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
old mode 100644 (file)
new mode 100755 (executable)
index 10b7e75..db00778
 #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)