From: 邱建斌 Date: Thu, 12 Jan 2012 08:33:28 +0000 (+0800) Subject: headset: if headset have not MIC will reported BIT_HEADSET_NO_MIC else reported BIT_H... X-Git-Tag: firefly_0821_release~9677 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=33b0473d0a4d652a6c4ea5002ca179927fbb2c9c;p=firefly-linux-kernel-4.4.55.git headset: if headset have not MIC will reported BIT_HEADSET_NO_MIC else reported BIT_HEADSET --- diff --git a/arch/arm/mach-rk29/board-rk29-phonesdk.c b/arch/arm/mach-rk29/board-rk29-phonesdk.c index faeec9723b0c..c8ed5a3c2443 100755 --- a/arch/arm/mach-rk29/board-rk29-phonesdk.c +++ b/arch/arm/mach-rk29/board-rk29-phonesdk.c @@ -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, }; diff --git a/arch/arm/mach-rk29/board-rk29-td8801_v2.c b/arch/arm/mach-rk29/board-rk29-td8801_v2.c index 32b488de50c9..767e5607cb79 100755 --- a/arch/arm/mach-rk29/board-rk29-td8801_v2.c +++ b/arch/arm/mach-rk29/board-rk29-td8801_v2.c @@ -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, }; diff --git a/arch/arm/mach-rk29/board-rk29-z5.c b/arch/arm/mach-rk29/board-rk29-z5.c index 5817b15873cb..3bb356b39ffe 100644 --- a/arch/arm/mach-rk29/board-rk29-z5.c +++ b/arch/arm/mach-rk29/board-rk29-z5.c @@ -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, }; diff --git a/drivers/headset_observe/rk_headset.c b/drivers/headset_observe/rk_headset.c index ab47661ca195..4f5b489c5116 100755 --- a/drivers/headset_observe/rk_headset.c +++ b/drivers/headset_observe/rk_headset.c @@ -42,7 +42,7 @@ #include /* Debug */ -#if 1 +#if 0 #define DBG(x...) printk(x) #else #define DBG(x...) do { } while (0) @@ -62,10 +62,10 @@ #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; } diff --git a/include/linux/mfd/wm8994/pdata.h b/include/linux/mfd/wm8994/pdata.h index 66da98e51d08..151623a8e8ea 100755 --- a/include/linux/mfd/wm8994/pdata.h +++ b/include/linux/mfd/wm8994/pdata.h @@ -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]; diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index fd0fd1e3d1ee..20ffa09743d8 100755 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -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: