headset: if headset have not MIC will reported BIT_HEADSET_NO_MIC else reported BIT_H...
author邱建斌 <qjb@rock-chips.com>
Thu, 12 Jan 2012 08:33:28 +0000 (16:33 +0800)
committer邱建斌 <qjb@rock-chips.com>
Thu, 12 Jan 2012 08:33:28 +0000 (16:33 +0800)
arch/arm/mach-rk29/board-rk29-phonesdk.c
arch/arm/mach-rk29/board-rk29-td8801_v2.c
arch/arm/mach-rk29/board-rk29-z5.c
drivers/headset_observe/rk_headset.c
include/linux/mfd/wm8994/pdata.h
sound/soc/codecs/wm8994.c

index faeec9723b0c3108e1d900a5b399cb491e16eb5f..c8ed5a3c2443ed6dea629f8bd941dbfd369ce142 100755 (executable)
@@ -1805,20 +1805,21 @@ static struct wm8994_pdata wm8994_platform_data = {
 #if defined (CONFIG_GPIO_WM8994)       
        .gpio_base = WM8994_GPIO_EXPANDER_BASE,
        //Fill value to initialize the GPIO     
-       .gpio_defaults ={},
-#endif         
+//     .gpio_defaults ={},
        /* configure gpio1 function: 0x0001(Logic level input/output) */
 //     .gpio_defaults[0] = 0x0001,
        /* configure gpio3/4/5/7 function for AIF2 voice */
-//     .gpio_defaults[2] = 0x8100,
-//     .gpio_defaults[3] = 0x8100,
-//     .gpio_defaults[4] = 0x8100,
+       .gpio_defaults[2] = 0x2100,
+       .gpio_defaults[3] = 0x2100,
+       .gpio_defaults[4] = 0xA100,
 //     .gpio_defaults[6] = 0x0100,
        /* configure gpio8/9/10/11 function for AIF3 BT */
-//     .gpio_defaults[7] = 0x8100,
-//     .gpio_defaults[8] = 0x0100,
-//     .gpio_defaults[9] = 0x0100,
-//     .gpio_defaults[10] = 0x0100,
+       .gpio_defaults[7] = 0xA100,
+       .gpio_defaults[8] = 0x2100,
+       .gpio_defaults[9] = 0x2100,
+       .gpio_defaults[10] = 0x2100,    
+#endif         
+
        .ldo[0] = { RK29_PIN5_PA1, NULL, &wm8994_ldo1_data },   /* XM0FRNB_2 */
        .ldo[1] = { 0, NULL, &wm8994_ldo2_data },
 
@@ -1832,7 +1833,7 @@ static struct wm8994_pdata wm8994_platform_data = {
 struct rk_headset_pdata rk_headset_info = {
        .Headset_gpio           = RK29_PIN4_PD2,
        .headset_in_type= HEADSET_IN_HIGH,
-//     .Hook_gpio = RK29_PIN4_PD1,//Detection Headset--Must be set
+       .Hook_gpio = RK29_PIN4_PD1,//Detection Headset--Must be set
        .hook_key_code = KEY_MEDIA,
 };
 
index 32b488de50c94113bbeecf708f2e39658b8d6716..767e5607cb79536a24c91f7336e2728012a3da24 100755 (executable)
@@ -1739,7 +1739,7 @@ static struct wm8994_pdata wm8994_platform_data = {
 struct rk_headset_pdata rk_headset_info = {
        .Headset_gpio           = RK29_PIN4_PD2,
        .headset_in_type= HEADSET_IN_HIGH,
-       .Hook_gpio = 0,//Detection Headset--Must be set
+       .Hook_gpio = RK29_PIN6_PB6,//Detection Headset--Must be set
        .hook_key_code = KEY_MEDIA,
 };
 
index 5817b15873cb05b808ac51a424ab7fc88c803913..3bb356b39ffee8b7e78ba5b59067af89e4faa3a1 100644 (file)
@@ -1963,7 +1963,7 @@ static struct wm8994_pdata wm8994_platform_data = {
 struct rk_headset_pdata rk_headset_info = {
        .Headset_gpio           = RK29_PIN4_PD2,
        .headset_in_type= HEADSET_IN_HIGH,
-//     .Hook_gpio = RK29_PIN4_PD1,//Detection Headset--Must be set
+       .Hook_gpio = RK29_PIN4_PD1,//Detection Headset--Must be set
        .hook_key_code = KEY_MEDIA,
 };
 
index ab47661ca19590affecfac8fd50b1815d285f47b..4f5b489c5116be12d19c2283d58085cd615904d8 100755 (executable)
@@ -42,7 +42,7 @@
 #include <linux/slab.h>
 
 /* Debug */
-#if 1
+#if 0
 #define DBG(x...) printk(x)
 #else
 #define DBG(x...) do { } while (0)
 #define disable 0
 
 
-/*#ifdef CONFIG_SND_SOC_WM8994
+#ifdef CONFIG_SND_SOC_WM8994
 extern int wm8994_set_status(void);
 #endif
-*/
+
 /* headset private data */
 struct headset_priv {
        struct input_dev *input_dev;
@@ -94,14 +94,14 @@ EXPORT_SYMBOL_GPL(Headset_isMic);
 
 static irqreturn_t headset_interrupt(int irq, void *dev_id)
 {
-//     DBG("---headset_interrupt---\n");       
+       DBG("---headset_interrupt---\n");       
        schedule_delayed_work(&headset_info->h_delayed_work[HEADSET], msecs_to_jiffies(50));
        return IRQ_HANDLED;
 }
 
 static irqreturn_t Hook_interrupt(int irq, void *dev_id)
 {
-//     DBG("---Hook_interrupt---\n");  
+       DBG("---Hook_interrupt---\n");  
 //     disable_irq_nosync(headset_info->irq[HOOK]);
        schedule_delayed_work(&headset_info->h_delayed_work[HOOK], msecs_to_jiffies(100));
        return IRQ_HANDLED;
@@ -110,16 +110,16 @@ static irqreturn_t Hook_interrupt(int irq, void *dev_id)
 static int headset_change_irqtype(int type,unsigned int irq_type)
 {
        int ret = 0;
-//     DBG("--------%s----------\n",__FUNCTION__);
+       DBG("--------%s----------\n",__FUNCTION__);
        free_irq(headset_info->irq[type],NULL);
        
        switch(type)
        {
        case HOOK:
-               ret = request_irq(headset_info->irq[type], Hook_interrupt, irq_type, NULL, NULL);
+               ret = request_irq(headset_info->irq[type], Hook_interrupt, irq_type, "headset_input", NULL);
                break;
        case HEADSET:
-               ret = request_irq(headset_info->irq[type], headset_interrupt, irq_type, NULL, NULL);
+               ret = request_irq(headset_info->irq[type], headset_interrupt, irq_type, "headset_hook", NULL);
                break;
        default:
                ret = -1;
@@ -139,7 +139,7 @@ static void headsetobserve_work(struct work_struct *work)
        int i,level = 0;
        struct rk_headset_pdata *pdata = headset_info->pdata;
        static unsigned int old_status = 0;
-//     DBG("---headsetobserve_work---\n");
+       DBG("---headsetobserve_work---\n");
        mutex_lock(&headset_info->mutex_lock[HEADSET]);
 
        for(i=0; i<3; i++)
@@ -190,61 +190,67 @@ static void headsetobserve_work(struct work_struct *work)
        case HEADSET_IN_HIGH:
                if(level > 0)
                {//in--High level
-               //      DBG("--- HEADSET_IN_HIGH headset in HIGH---\n");
-               //      enable_irq(headset_info->irq[HOOK]);
-                       headset_info->cur_headset_status = BIT_HEADSET;
+                       DBG("--- HEADSET_IN_HIGH headset in HIGH---\n");
+                       headset_info->cur_headset_status = BIT_HEADSET_NO_MIC;
                        headset_change_irqtype(HEADSET,IRQF_TRIGGER_FALLING);//
-                       if (pdata->Hook_gpio != NULL) {
+                       if (pdata->Hook_gpio) {
                                del_timer(&headset_info->headset_timer);//Start the timer, wait for switch to the headphone channel
-                               headset_info->headset_timer.expires = jiffies + 500;
+                       //      headset_info->headset_timer.expires = jiffies + 500;
+                               headset_info->headset_timer.expires = jiffies + 10;
                                add_timer(&headset_info->headset_timer);
                        }
                }
                else if(level == 0)
                {//out--Low level
-               //      DBG("---HEADSET_IN_HIGH headset out HIGH---\n");        
+                       DBG("---HEADSET_IN_HIGH headset out HIGH---\n");        
                        if(headset_info->isHook_irq == enable)
                        {
-                       //      DBG("disable_irq\n");
+                               DBG("disable headset_hook irq\n");
                                headset_info->isHook_irq = disable;
                                disable_irq(headset_info->irq[HOOK]);           
                        }       
                        headset_info->cur_headset_status = ~(BIT_HEADSET|BIT_HEADSET_NO_MIC);
                        headset_change_irqtype(HEADSET,IRQF_TRIGGER_RISING);//
+                       rk28_send_wakeup_key();
+                       switch_set_state(&headset_info->sdev, headset_info->cur_headset_status);        
+                       DBG("headset_info->cur_headset_status = %d\n",headset_info->cur_headset_status);                        
                }
                break;
        case HEADSET_IN_LOW:
                if(level == 0)
                {//in--High level
-               //      DBG("---HEADSET_IN_LOW headset in LOW ---\n");
-                       headset_info->cur_headset_status = BIT_HEADSET;
+                       DBG("---HEADSET_IN_LOW headset in LOW ---\n");
+                       headset_info->cur_headset_status = BIT_HEADSET_NO_MIC;
                        headset_change_irqtype(HEADSET,IRQF_TRIGGER_RISING);//
-                       if (pdata->Hook_gpio != NULL) {                 
+                       if (pdata->Hook_gpio) {                 
                                del_timer(&headset_info->headset_timer);//Start the timer, wait for switch to the headphone channel
-                               headset_info->headset_timer.expires = jiffies + 500;
+                       //      headset_info->headset_timer.expires = jiffies + 500;
+                               headset_info->headset_timer.expires = jiffies + 10;
                                add_timer(&headset_info->headset_timer);
                        }
                }
                else if(level > 0)
                {//out--High level
-               //      DBG("---HEADSET_IN_LOW headset out LOW ---\n");
+                       DBG("---HEADSET_IN_LOW headset out LOW ---\n");
                        if(headset_info->isHook_irq == enable)
                        {
-                       //      DBG("disable_irq\n");
+                               DBG("disable headset_hook irq\n");
                                headset_info->isHook_irq = disable;
                                disable_irq(headset_info->irq[HOOK]);           
                        }                               
                        headset_info->cur_headset_status = ~(BIT_HEADSET|BIT_HEADSET_NO_MIC);
                        headset_change_irqtype(HEADSET,IRQF_TRIGGER_FALLING);//
+                       rk28_send_wakeup_key();
+                       switch_set_state(&headset_info->sdev, headset_info->cur_headset_status);        
+                       DBG("headset_info->cur_headset_status = %d\n",headset_info->cur_headset_status);                        
                }
                break;                  
        default:
                DBG("---- ERROR: on headset headset_in_type error -----\n");
                break;                  
        }
-       rk28_send_wakeup_key();
-       switch_set_state(&headset_info->sdev, headset_info->cur_headset_status);        
-       DBG("headset_info->cur_headset_status = %d\n",headset_info->cur_headset_status);
+       
+
 RE_ERROR:
        mutex_unlock(&headset_info->mutex_lock[HEADSET]);       
 }
@@ -255,20 +261,20 @@ static void Hook_work(struct work_struct *work)
        struct rk_headset_pdata *pdata = headset_info->pdata;
        static unsigned int old_status = HOOK_UP;
 
-//     DBG("---Hook_work---\n");
+       DBG("---Hook_work---\n");
        mutex_lock(&headset_info->mutex_lock[HOOK]);
        if(headset_info->headset_status == HEADSET_OUT)
        {
                DBG("Headset is out\n");
                goto RE_ERROR;
        }       
-       /*#ifdef CONFIG_SND_SOC_WM8994
-       if(wm8994_set_status() < 0)
+       #ifdef CONFIG_SND_SOC_WM8994
+       if(wm8994_set_status() != 0)
        {
                DBG("wm8994 is not set on heatset channel or suspend\n");
                goto RE_ERROR;
        }
-       #endif*/
+       #endif
        for(i=0; i<3; i++)
        {
                level = gpio_get_value(pdata->Hook_gpio);
@@ -322,22 +328,23 @@ static void headset_timer_callback(unsigned long arg)
        struct rk_headset_pdata *pdata = headset->pdata;
        int i,level = 0;
        
-       DBG("headset_timer_callback,headset->headset_status=%d\n",headset->headset_status);     
+       printk("headset_timer_callback,headset->headset_status=%d\n",headset->headset_status);  
 
        if(headset->headset_status == HEADSET_OUT)
        {
-               DBG("Headset is out\n");
+               printk("Headset is out\n");
                goto out;
        }
-       /*#ifdef CONFIG_SND_SOC_WM8994
-       if(wm8994_set_status() < 0)
+       #ifdef CONFIG_SND_SOC_WM8994
+       if(wm8994_set_status() != 0)
        {
-               DBG("wm8994 is not set on heatset channel\n");
-               headset_info->headset_timer.expires = jiffies + 500;
+               printk("with wm8994 set the MICB2\n");
+       //      headset_info->headset_timer.expires = jiffies + 500;
+               headset_info->headset_timer.expires = jiffies + 10;
                add_timer(&headset_info->headset_timer);        
                goto out;
        }
-       #endif*/
+       #endif
        for(i=0; i<3; i++)
        {
                level = gpio_get_value(pdata->Hook_gpio);
@@ -357,15 +364,25 @@ static void headset_timer_callback(unsigned long arg)
        }
 
        if(level == 0)
+       {
                headset->isMic= 0;//No microphone
+               headset_info->cur_headset_status = BIT_HEADSET_NO_MIC;
+               printk("headset->isMic = %d\n",headset->isMic);         
+       }       
        else if(level > 0)      
        {       
                headset->isMic = 1;//have mic
-       //      DBG("enable_irq\n");    
+               DBG("enable headset_hook irq\n");
                enable_irq(headset_info->irq[HOOK]);
                headset->isHook_irq = enable;
-       }       
-       DBG("headset->isMic = %d\n",headset->isMic);
+               headset_info->cur_headset_status = BIT_HEADSET; 
+               printk("headset->isMic = %d\n",headset->isMic);         
+       }
+       
+       rk28_send_wakeup_key();
+       switch_set_state(&headset_info->sdev, headset_info->cur_headset_status);        
+       DBG("headset_info->cur_headset_status = %d\n",headset_info->cur_headset_status);        
+
 out:
        return;
 }
@@ -437,7 +454,7 @@ static int rockchip_headsetobserve_probe(struct platform_device *pdev)
 //     headset->headset_timer.expires = jiffies + 1000;
 //     add_timer(&headset->headset_timer);     
 //------------------------------------------------------------------
-       if (pdata->Headset_gpio != NULL) {
+       if (pdata->Headset_gpio) {
                ret = gpio_request(pdata->Headset_gpio, NULL);
                if (ret) 
                        goto failed_free;
@@ -454,8 +471,10 @@ static int rockchip_headsetobserve_probe(struct platform_device *pdev)
                        goto failed_free;
                enable_irq_wake(headset->irq[HEADSET]);
        }
+       else
+               goto failed_free;
 //------------------------------------------------------------------
-       if (pdata->Hook_gpio != NULL) {
+       if (pdata->Hook_gpio) {
                ret = gpio_request(pdata->Hook_gpio , NULL);
                if (ret) 
                        goto failed_free;
@@ -521,7 +540,8 @@ failed_free_dev:
        platform_set_drvdata(pdev, NULL);
        input_free_device(headset->input_dev);
 failed_free:
-       kfree(headset); 
+       dev_err(&pdev->dev, "failed to headset probe\n");
+       kfree(headset);
        return ret;
 }
 
index 66da98e51d08623a50e0b34490bdc8d1609d2b52..151623a8e8ea5d03c968d27bd7be1df77d00a2be 100755 (executable)
@@ -128,7 +128,8 @@ struct wm8994_pdata {
 
        struct wm8994_ldo_pdata ldo[WM8994_NUM_LDO];
        
-       int irq_base;  /** Base IRQ number for WM8994, required for IRQs */
+       /** Base IRQ number for WM8994, required for IRQs */
+       int irq_base;   //do not use
 
         int num_drc_cfgs;
         struct wm8994_drc_cfg *drc_cfgs;
@@ -150,24 +151,24 @@ struct wm8994_pdata {
 
         /* LINEOUT can be differential or single ended */
         unsigned int lineout1_diff:1;
-        unsigned int lineout2_diff:1;
+        unsigned int lineout2_diff:1;//do not use
 
         /* Common mode feedback */
         unsigned int lineout1fb:1;
-        unsigned int lineout2fb:1;
+        unsigned int lineout2fb:1;//do not use
 
        /* IRQ for microphone detection if brought out directly as a
         * signal.
         */
-       int micdet_irq;
+       int micdet_irq;//do not use
 
         /* WM8994 microphone biases: 0=0.9*AVDD1 1=0.65*AVVD1 */
-        unsigned int micbias1_lvl:1;
-        unsigned int micbias2_lvl:1;
+        unsigned int micbias1_lvl:1;//do not use
+        unsigned int micbias2_lvl:1;//do not use
 
         /* WM8994 jack detect threashold levels, see datasheet for values */
-        unsigned int jd_scthr:2;
-        unsigned int jd_thr:2;
+        unsigned int jd_scthr:2;//do not use
+        unsigned int jd_thr:2;//do not use
 
        /* WM8958 microphone bias configuration */
        int micbias[2];
index fd0fd1e3d1ee9ff87fc4be13ac5eabb15dd0f999..20ffa09743d8ad278ecd032964432d7c48715797 100755 (executable)
@@ -204,6 +204,25 @@ static unsigned int wm8994_read(struct snd_soc_codec *codec,
        return val;
 }
 
+int wm8994_set_status(void)
+{
+       struct wm8994_priv *wm8994 = NULL;
+//     DBG("%s::%d\n",__FUNCTION__,__LINE__);
+
+       if(wm8994_codec == NULL )
+               return -1;
+       
+       wm8994 = snd_soc_codec_get_drvdata(wm8994_codec);
+
+       if(wm8994 == NULL)
+               return -1;
+       
+       return snd_soc_test_bits(wm8994_codec, WM8994_POWER_MANAGEMENT_1,
+                       WM8994_MICB2_ENA ,
+                       WM8994_MICB2_ENA);
+}
+EXPORT_SYMBOL_GPL(wm8994_set_status);
+
 static int configure_aif_clock(struct snd_soc_codec *codec, int aif)
 {
        struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
@@ -1577,9 +1596,9 @@ static const struct snd_soc_dapm_route intercon[] = {
        
        { "IN1L PGA", NULL , "MICBIAS2" },
        { "IN1R PGA", NULL , "MICBIAS1" },
-       { "MICBIAS2", NULL , "IN1LP"},
+       { "MICBIAS2", NULL , "IN1LP"},//headset
        { "MICBIAS2", NULL , "IN1LN"},
-       { "MICBIAS1", NULL , "IN1RP"},
+       { "MICBIAS1", NULL , "IN1RP"},//mainMIC
        { "MICBIAS1", NULL , "IN1RN"},
        
 };
@@ -2208,6 +2227,10 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
        int id = dai->id - 1;
 
        int i, cur_val, best_val, bclk_rate, best;
+       
+       snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
+                       WM8994_MICB2_ENA ,
+                       WM8994_MICB2_ENA);
 
        switch (dai->id) {
        case 1: