From 144cd50fad2108c8ef497761d685627e01bbb8c4 Mon Sep 17 00:00:00 2001 From: qjb Date: Mon, 24 Mar 2014 20:50:35 +0800 Subject: [PATCH] kernel 3.10 headset : headset driver support --- drivers/Kconfig | 2 + drivers/Makefile | 1 + drivers/headset_observe/Kconfig | 13 +- drivers/headset_observe/Makefile | 3 +- drivers/headset_observe/rk_headset.c | 161 ++++--------- drivers/headset_observe/rk_headset.h | 36 +-- .../headset_observe/rk_headset_irq_hook_adc.c | 116 ++++----- .../headset_observe/rockchip_headset_core.c | 222 ++++++++++++++++++ 8 files changed, 345 insertions(+), 209 deletions(-) mode change 100644 => 100755 drivers/Kconfig mode change 100644 => 100755 drivers/Makefile create mode 100755 drivers/headset_observe/rockchip_headset_core.c diff --git a/drivers/Kconfig b/drivers/Kconfig old mode 100644 new mode 100755 index ba3c789ad9b8..0f9b78a4489a --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -170,4 +170,6 @@ source "drivers/reset/Kconfig" source "drivers/gator/Kconfig" +source "drivers/headset_observe/Kconfig" + endmenu diff --git a/drivers/Makefile b/drivers/Makefile old mode 100644 new mode 100755 index 1c92047b81bd..8379b43d8618 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -155,3 +155,4 @@ obj-$(CONFIG_IPACK_BUS) += ipack/ obj-$(CONFIG_NTB) += ntb/ obj-$(CONFIG_GATOR) += gator/ +obj-y += headset_observe/ \ No newline at end of file diff --git a/drivers/headset_observe/Kconfig b/drivers/headset_observe/Kconfig index 78f2551fad2f..ae10bff0762e 100755 --- a/drivers/headset_observe/Kconfig +++ b/drivers/headset_observe/Kconfig @@ -4,15 +4,12 @@ menu "Headset device support" -config RK_HEADSET_DET - tristate "RK headset detect support" +config RK_HEADSET + tristate "Rockchips HeadSet support" ---help--- - Universal headphone driver(write begin rk29) - -config RK_HEADSET_IRQ_HOOK_ADC_DET - tristate "RK headset irq hook adc detect support" - ---help--- - if you use headset irq and hook adc detect, choose it + Rockchips HeadSet support: + support hook interrupt mode. + support hook adc mode. endmenu diff --git a/drivers/headset_observe/Makefile b/drivers/headset_observe/Makefile index 932fdfbb0492..43ca02b1653b 100755 --- a/drivers/headset_observe/Makefile +++ b/drivers/headset_observe/Makefile @@ -1,2 +1 @@ -obj-$(CONFIG_RK_HEADSET_DET) += rk_headset.o -obj-$(CONFIG_RK_HEADSET_IRQ_HOOK_ADC_DET) += rk_headset_irq_hook_adc.o +obj-$(CONFIG_RK_HEADSET) += rockchip_headset_core.o rk_headset.o rk_headset_irq_hook_adc.o diff --git a/drivers/headset_observe/rk_headset.c b/drivers/headset_observe/rk_headset.c index b324861ca6e7..d72b0c46acf8 100755 --- a/drivers/headset_observe/rk_headset.c +++ b/drivers/headset_observe/rk_headset.c @@ -14,7 +14,6 @@ */ #include -#include #include #include #include @@ -35,11 +34,13 @@ #include #include #include +#include +#include +#include #include "rk_headset.h" +#ifdef CONFIG_HAS_EARLYSUSPEND #include -#include -#include -#include +#endif /* Debug */ #if 0 @@ -94,33 +95,18 @@ static struct headset_priv *headset_info; void Modem_Mic_switch(int value) { if(value == HP_MIC) - gpio_set_value(headset_info->pdata->Sw_mic_gpio, headset_info->pdata->Hp_mic_io_value); + gpio_set_value(headset_info->pdata->mic_switch_gpio, headset_info->pdata->hp_mic_io_value); else if(value == MAIN_MIC) - gpio_set_value(headset_info->pdata->Sw_mic_gpio,headset_info->pdata->Main_mic_io_value); + gpio_set_value(headset_info->pdata->mic_switch_gpio,headset_info->pdata->main_mic_io_value); } void Modem_Mic_release(void) { if(headset_info->cur_headset_status == 1) - gpio_set_value(headset_info->pdata->Sw_mic_gpio, headset_info->pdata->Hp_mic_io_value); + gpio_set_value(headset_info->pdata->mic_switch_gpio, headset_info->pdata->hp_mic_io_value); else - gpio_set_value(headset_info->pdata->Sw_mic_gpio,headset_info->pdata->Main_mic_io_value); + gpio_set_value(headset_info->pdata->mic_switch_gpio,headset_info->pdata->main_mic_io_value); } #endif -int Headset_isMic(void) -{ - return headset_info->isMic; -} -EXPORT_SYMBOL_GPL(Headset_isMic); - -int Headset_status(void) -{ - if(headset_info->cur_headset_status == BIT_HEADSET_NO_MIC || - headset_info->cur_headset_status == BIT_HEADSET ) - return HEADSET_IN; - else - return HEADSET_OUT; -} -EXPORT_SYMBOL_GPL(Headset_status); static int read_gpio(int gpio) { @@ -150,7 +136,7 @@ static irqreturn_t headset_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static irqreturn_t Hook_interrupt(int irq, void *dev_id) +static irqreturn_t hook_interrupt(int irq, void *dev_id) { DBG("---Hook_interrupt---\n"); // disable_irq_nosync(headset_info->irq[HOOK]); @@ -167,17 +153,17 @@ static void headsetobserve_work(struct work_struct *work) DBG("---headsetobserve_work---\n"); mutex_lock(&headset_info->mutex_lock[HEADSET]); - level = read_gpio(pdata->Headset_gpio); + level = read_gpio(pdata->headset_gpio); if(level < 0) goto out; msleep(100); - level2 = read_gpio(pdata->Headset_gpio); + level2 = read_gpio(pdata->headset_gpio); if(level2 < 0) goto out; if(level2 != level) goto out; old_status = headset_info->headset_status; - if(pdata->headset_in_type == HEADSET_IN_HIGH) + if(pdata->headset_insert_type == HEADSET_IN_HIGH) headset_info->headset_status = level?HEADSET_IN:HEADSET_OUT; else headset_info->headset_status = level?HEADSET_OUT:HEADSET_IN; @@ -188,17 +174,17 @@ static void headsetobserve_work(struct work_struct *work) } DBG("(headset in is %s)headset status is %s\n", - pdata->headset_in_type?"high level":"low level", + pdata->headset_insert_type?"high level":"low level", headset_info->headset_status?"in":"out"); if(headset_info->headset_status == HEADSET_IN) { headset_info->cur_headset_status = BIT_HEADSET_NO_MIC; - if(pdata->headset_in_type == HEADSET_IN_HIGH) + if(pdata->headset_insert_type == HEADSET_IN_HIGH) irq_set_irq_type(headset_info->irq[HEADSET],IRQF_TRIGGER_FALLING); else irq_set_irq_type(headset_info->irq[HEADSET],IRQF_TRIGGER_RISING); - if (pdata->Hook_gpio) { + 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 + 100; add_timer(&headset_info->headset_timer); @@ -218,12 +204,12 @@ static void headsetobserve_work(struct work_struct *work) //#if defined(CONFIG_SND_RK_SOC_RK2928) || defined(CONFIG_SOC_RK3028) //rk2928_codec_set_spk(HEADSET_OUT); //#endif - if(pdata->headset_in_type == HEADSET_IN_HIGH) + if(pdata->headset_insert_type == HEADSET_IN_HIGH) irq_set_irq_type(headset_info->irq[HEADSET],IRQF_TRIGGER_RISING); else irq_set_irq_type(headset_info->irq[HEADSET],IRQF_TRIGGER_FALLING); } - rk28_send_wakeup_key(); +// rk28_send_wakeup_key(); switch_set_state(&headset_info->sdev, headset_info->cur_headset_status); #if defined(CONFIG_SND_RK_SOC_RK2928) || defined(CONFIG_SND_RK29_SOC_RK610) if (headset_info->headset_status == HEADSET_OUT) @@ -239,7 +225,7 @@ out: mutex_unlock(&headset_info->mutex_lock[HEADSET]); } -static void Hook_work(struct work_struct *work) +static void hook_work(struct work_struct *work) { int level = 0; struct rk_headset_pdata *pdata = headset_info->pdata; @@ -259,7 +245,7 @@ static void Hook_work(struct work_struct *work) } #endif - level = read_gpio(pdata->Hook_gpio); + level = read_gpio(pdata->hook_gpio); if(level < 0) goto RE_ERROR; @@ -267,9 +253,9 @@ static void Hook_work(struct work_struct *work) DBG("Hook_work -- level = %d\n",level); if(level == 0) - headset_info->hook_status = pdata->Hook_down_type == HOOK_DOWN_HIGH?HOOK_UP:HOOK_DOWN; + headset_info->hook_status = pdata->hook_down_type == HOOK_DOWN_HIGH?HOOK_UP:HOOK_DOWN; else if(level > 0) - headset_info->hook_status = pdata->Hook_down_type == HOOK_DOWN_HIGH?HOOK_DOWN:HOOK_UP; + headset_info->hook_status = pdata->hook_down_type == HOOK_DOWN_HIGH?HOOK_DOWN:HOOK_UP; if(old_status == headset_info->hook_status) { @@ -279,19 +265,19 @@ static void Hook_work(struct work_struct *work) DBG("Hook_work -- level = %d hook status is %s\n",level,headset_info->hook_status?"key down":"key up"); if(headset_info->hook_status == HOOK_DOWN) { - if(pdata->Hook_down_type == HOOK_DOWN_HIGH) + if(pdata->hook_down_type == HOOK_DOWN_HIGH) irq_set_irq_type(headset_info->irq[HOOK],IRQF_TRIGGER_FALLING); else irq_set_irq_type(headset_info->irq[HOOK],IRQF_TRIGGER_RISING); } else { - if(pdata->Hook_down_type == HOOK_DOWN_HIGH) + if(pdata->hook_down_type == HOOK_DOWN_HIGH) irq_set_irq_type(headset_info->irq[HOOK],IRQF_TRIGGER_RISING); else irq_set_irq_type(headset_info->irq[HOOK],IRQF_TRIGGER_FALLING); } - input_report_key(headset_info->input_dev,pdata->hook_key_code,headset_info->hook_status); + input_report_key(headset_info->input_dev,HOOK_KEY_CODE,headset_info->hook_status); input_sync(headset_info->input_dev); RE_ERROR: mutex_unlock(&headset_info->mutex_lock[HOOK]); @@ -320,21 +306,21 @@ static void headset_timer_callback(unsigned long arg) goto out; } #endif - level = read_gpio(pdata->Hook_gpio); + level = read_gpio(pdata->hook_gpio); if(level < 0) goto out; - if((level > 0 && pdata->Hook_down_type == HOOK_DOWN_LOW) - || (level == 0 && pdata->Hook_down_type == HOOK_DOWN_HIGH)) + if((level > 0 && pdata->hook_down_type == HOOK_DOWN_LOW) + || (level == 0 && pdata->hook_down_type == HOOK_DOWN_HIGH)) { headset->isMic = 1;//have mic DBG("enable headset_hook irq\n"); enable_irq(headset_info->irq[HOOK]); headset->isHook_irq = enable; headset_info->hook_status = HOOK_UP; - if(pdata->Hook_down_type == HOOK_DOWN_HIGH) - irq_set_irq_type(headset_info->irq[HOOK],IRQF_TRIGGER_RISING); - else - irq_set_irq_type(headset_info->irq[HOOK],IRQF_TRIGGER_FALLING); + if(pdata->hook_down_type == HOOK_DOWN_HIGH) + irq_set_irq_type(headset_info->irq[HOOK],IRQF_TRIGGER_RISING); + else + irq_set_irq_type(headset_info->irq[HOOK],IRQF_TRIGGER_FALLING); } else @@ -347,7 +333,7 @@ static void headset_timer_callback(unsigned long arg) if(headset_info->cur_headset_status == 1) gpio_set_value(pdata->Sw_mic_gpio, pdata->Hp_mic_io_value); #endif - rk28_send_wakeup_key(); +// 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); @@ -371,33 +357,32 @@ static void headset_early_resume(struct early_suspend *h) static struct early_suspend hs_early_suspend; #endif -static int rk_Hskey_open(struct input_dev *dev) +static int rk_hskey_open(struct input_dev *dev) { //struct rk28_adckey *adckey = input_get_drvdata(dev); // DBG("===========rk_Hskey_open===========\n"); return 0; } -static void rk_Hskey_close(struct input_dev *dev) +static void rk_hskey_close(struct input_dev *dev) { // DBG("===========rk_Hskey_close===========\n"); // struct rk28_adckey *adckey = input_get_drvdata(dev); } -static int rockchip_headsetobserve_probe(struct platform_device *pdev) +int rk_headset_probe(struct platform_device *pdev,struct rk_headset_pdata *pdata) { int ret; struct headset_priv *headset; - struct rk_headset_pdata *pdata; headset = kzalloc(sizeof(struct headset_priv), GFP_KERNEL); if (headset == NULL) { dev_err(&pdev->dev, "failed to allocate driver data\n"); return -ENOMEM; - } - headset->pdata = pdev->dev.platform_data; - pdata = headset->pdata; + } + + headset->pdata = pdata; headset->headset_status = HEADSET_OUT; headset->hook_status = HOOK_UP; headset->isHook_irq = disable; @@ -412,7 +397,7 @@ static int rockchip_headsetobserve_probe(struct platform_device *pdev) mutex_init(&headset->mutex_lock[HOOK]); INIT_DELAYED_WORK(&headset->h_delayed_work[HEADSET], headsetobserve_work); - INIT_DELAYED_WORK(&headset->h_delayed_work[HOOK], Hook_work); + INIT_DELAYED_WORK(&headset->h_delayed_work[HOOK], hook_work); headset->isMic = 0; setup_timer(&headset->headset_timer, headset_timer_callback, (unsigned long)headset); @@ -425,8 +410,8 @@ static int rockchip_headsetobserve_probe(struct platform_device *pdev) goto failed_free; } headset->input_dev->name = pdev->name; - headset->input_dev->open = rk_Hskey_open; - headset->input_dev->close = rk_Hskey_close; + headset->input_dev->open = rk_hskey_open; + headset->input_dev->close = rk_hskey_close; headset->input_dev->dev.parent = &pdev->dev; //input_dev->phys = KEY_PHYS_NAME; headset->input_dev->id.vendor = 0x0001; @@ -438,7 +423,7 @@ static int rockchip_headsetobserve_probe(struct platform_device *pdev) dev_err(&pdev->dev, "failed to register input device\n"); goto failed_free_dev; } - input_set_capability(headset->input_dev, EV_KEY, pdata->hook_key_code); + input_set_capability(headset->input_dev, EV_KEY,HOOK_KEY_CODE); #ifdef CONFIG_HAS_EARLYSUSPEND hs_early_suspend.suspend = NULL; @@ -447,18 +432,15 @@ static int rockchip_headsetobserve_probe(struct platform_device *pdev) register_early_suspend(&hs_early_suspend); #endif //------------------------------------------------------------------ - if (pdata->Headset_gpio) { - if(pdata->Headset_gpio == NULL){ + if (pdata->headset_gpio) { + if(!pdata->headset_gpio){ dev_err(&pdev->dev,"failed init headset,please full hook_io_init function in board\n"); goto failed_free_dev; } - ret = pdata->headset_io_init(pdata->Headset_gpio); - if (ret) - goto failed_free_dev; - headset->irq[HEADSET] = gpio_to_irq(pdata->Headset_gpio); + headset->irq[HEADSET] = gpio_to_irq(pdata->headset_gpio); - if(pdata->headset_in_type == HEADSET_IN_HIGH) + if(pdata->headset_insert_type == HEADSET_IN_HIGH) headset->irq_type[HEADSET] = IRQF_TRIGGER_RISING; else headset->irq_type[HEADSET] = IRQF_TRIGGER_FALLING; @@ -470,18 +452,11 @@ static int rockchip_headsetobserve_probe(struct platform_device *pdev) else goto failed_free_dev; //------------------------------------------------------------------ - if (pdata->Hook_gpio) { - if(pdata->hook_io_init == NULL){ - dev_err(&pdev->dev,"failed init hook,please full hook_io_init function in board\n"); - goto failed_free_dev; - } - ret = pdata->hook_io_init(pdata->Hook_gpio); - if (ret) - goto failed_free_dev; - headset->irq[HOOK] = gpio_to_irq(pdata->Hook_gpio); - headset->irq_type[HOOK] = pdata->Hook_down_type == HOOK_DOWN_HIGH ? IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING; + if (pdata->hook_gpio) { + headset->irq[HOOK] = gpio_to_irq(pdata->hook_gpio); + headset->irq_type[HOOK] = pdata->hook_down_type == HOOK_DOWN_HIGH ? IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING; - ret = request_irq(headset->irq[HOOK], Hook_interrupt, headset->irq_type[HOOK] , "headset_hook", NULL); + ret = request_irq(headset->irq[HOOK], hook_interrupt, headset->irq_type[HOOK] , "headset_hook", NULL); if (ret) goto failed_free_dev; disable_irq(headset->irq[HOOK]); @@ -500,39 +475,5 @@ failed_free: return ret; } -static int rockchip_headsetobserve_suspend(struct platform_device *pdev, pm_message_t state) -{ - DBG("%s----%d\n",__FUNCTION__,__LINE__); - disable_irq(headset_info->irq[HEADSET]); - disable_irq(headset_info->irq[HOOK]); - - return 0; -} - -static int rockchip_headsetobserve_resume(struct platform_device *pdev) -{ - DBG("%s----%d\n",__FUNCTION__,__LINE__); - enable_irq(headset_info->irq[HEADSET]); - enable_irq(headset_info->irq[HOOK]); - - return 0; -} -static struct platform_driver rockchip_headsetobserve_driver = { - .probe = rockchip_headsetobserve_probe, -// .resume = rockchip_headsetobserve_resume, -// .suspend = rockchip_headsetobserve_suspend, - .driver = { - .name = "rk_headsetdet", - .owner = THIS_MODULE, - }, -}; -static int __init rockchip_headsetobserve_init(void) -{ - platform_driver_register(&rockchip_headsetobserve_driver); - return 0; -} -late_initcall(rockchip_headsetobserve_init); -MODULE_DESCRIPTION("Rockchip Headset Driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/headset_observe/rk_headset.h b/drivers/headset_observe/rk_headset.h index 1afd36897779..3cba398f6024 100755 --- a/drivers/headset_observe/rk_headset.h +++ b/drivers/headset_observe/rk_headset.h @@ -7,24 +7,26 @@ #define HOOK_DOWN_HIGH 0x00000001 #define HOOK_DOWN_LOW 0x00000000 -struct io_info{ - char iomux_name[50]; - int iomux_mode; -}; - - struct rk_headset_pdata{ - unsigned int Hook_gpio;//Detection Headset--Must be set - unsigned int Sw_mic_gpio; - unsigned int Hp_mic_io_value; - unsigned int Main_mic_io_value; - unsigned int Hook_adc_chn; //adc channel - unsigned int Hook_down_type; //Hook key down status - int hook_key_code; - unsigned int Headset_gpio;//Detection Headset--Must be set - unsigned int headset_in_type;// Headphones into the state level--Must be set - int (*headset_io_init)(int); - int (*hook_io_init)(int); +//heaset about + unsigned int headset_gpio; + unsigned int headset_insert_type;// Headphones into the state level +//hook about + int hook_adc_chn; //adc channel + unsigned int hook_gpio; + unsigned int hook_down_type; //Hook key down status +#ifdef CONFIG_MODEM_MIC_SWITCH +//mic about + unsigned int mic_switch_gpio; + unsigned int hp_mic_io_value; + unsigned int main_mic_io_value; +#endif }; +#define HOOK_KEY_CODE KEY_MEDIA + +extern int rk_headset_probe(struct platform_device *pdev,struct rk_headset_pdata *pdata); +extern int rk_headset_adc_probe(struct platform_device *pdev,struct rk_headset_pdata *pdata); +extern int rk_headset_adc_suspend(struct platform_device *pdev, pm_message_t state); +extern int rk_headset_adc_resume(struct platform_device *pdev); #endif diff --git a/drivers/headset_observe/rk_headset_irq_hook_adc.c b/drivers/headset_observe/rk_headset_irq_hook_adc.c index 74ed75a063c1..aa9902a98ae6 100755 --- a/drivers/headset_observe/rk_headset_irq_hook_adc.c +++ b/drivers/headset_observe/rk_headset_irq_hook_adc.c @@ -1,5 +1,4 @@ -/* arch/arm/mach-rockchip/rk28_headset.c - * +/* * Copyright (C) 2009 Rockchip Corporation. * * This software is licensed under the terms of the GNU General Public @@ -14,7 +13,6 @@ */ #include -#include #include #include #include @@ -35,13 +33,16 @@ #include #include #include -#include "rk_headset.h" +#include +#include +#include + +#ifdef CONFIG_HAS_EARLYSUSPEND #include -#include -#include -#include +#endif #include #include +#include "rk_headset.h" /* Debug */ #if 1 @@ -109,12 +110,6 @@ struct headset_priv { }; static struct headset_priv *headset_info; -int Headset_isMic(void) -{ - return headset_info->isMic; -} -EXPORT_SYMBOL_GPL(Headset_isMic); - //1 static irqreturn_t headset_interrupt(int irq, void *dev_id) { @@ -130,10 +125,10 @@ static irqreturn_t headset_interrupt(int irq, void *dev_id) msleep(150); for(i=0; i<3; i++) { - level = gpio_get_value(pdata->Headset_gpio); + level = gpio_get_value(pdata->headset_gpio); if(level < 0) { - printk("%s:get pin level again,pin=%d,i=%d\n",__FUNCTION__,pdata->Headset_gpio,i); + printk("%s:get pin level again,pin=%d,i=%d\n",__FUNCTION__,pdata->headset_gpio,i); msleep(1); continue; } @@ -147,7 +142,7 @@ static irqreturn_t headset_interrupt(int irq, void *dev_id) } old_status = headset_info->headset_status; - switch(pdata->headset_in_type) + switch(pdata->headset_insert_type) { case HEADSET_IN_HIGH: if(level > 0) @@ -162,7 +157,7 @@ static irqreturn_t headset_interrupt(int irq, void *dev_id) headset_info->headset_status = HEADSET_OUT; break; default: - DBG("---- ERROR: on headset headset_in_type error -----\n"); + DBG("---- ERROR: on headset headset_insert_type error -----\n"); break; } if(old_status == headset_info->headset_status) @@ -172,7 +167,7 @@ static irqreturn_t headset_interrupt(int irq, void *dev_id) } DBG("(headset in is %s)headset status is %s\n", - pdata->headset_in_type?"high level":"low level", + pdata->headset_insert_type?"high level":"low level", headset_info->headset_status?"in":"out"); if(headset_info->headset_status == HEADSET_IN) { @@ -188,16 +183,16 @@ static irqreturn_t headset_interrupt(int irq, void *dev_id) break; msleep(50); - if(pdata->headset_in_type == HEADSET_IN_HIGH) - old_status = headset_info->headset_status = gpio_get_value(pdata->Headset_gpio)?HEADSET_IN:HEADSET_OUT; + if(pdata->headset_insert_type == HEADSET_IN_HIGH) + old_status = headset_info->headset_status = gpio_get_value(pdata->headset_gpio)?HEADSET_IN:HEADSET_OUT; else - old_status = headset_info->headset_status = gpio_get_value(pdata->Headset_gpio)?HEADSET_OUT:HEADSET_IN; + old_status = headset_info->headset_status = gpio_get_value(pdata->headset_gpio)?HEADSET_OUT:HEADSET_IN; if(headset_info->headset_status == HEADSET_OUT) goto out1; msleep(5); } #endif - if(pdata->Hook_adc_chn>=0 && 3>=pdata->Hook_adc_chn) + if(pdata->hook_adc_chn>=0 && 3>=pdata->hook_adc_chn) { // wait for find Hook key //#ifdef CONFIG_SND_SOC_RT5625 @@ -234,7 +229,7 @@ static irqreturn_t headset_interrupt(int irq, void *dev_id) { printk("codec is error\n"); headset_info->heatset_irq_working = WAIT; - if(pdata->headset_in_type == HEADSET_IN_HIGH) + if(pdata->headset_insert_type == HEADSET_IN_HIGH) irq_set_irq_type(headset_info->irq[HEADSET],IRQF_TRIGGER_LOW|IRQF_ONESHOT); else irq_set_irq_type(headset_info->irq[HEADSET],IRQF_TRIGGER_HIGH|IRQF_ONESHOT); @@ -258,7 +253,7 @@ static irqreturn_t headset_interrupt(int irq, void *dev_id) headset_info->cur_headset_status = BIT_HEADSET_NO_MIC; } printk("headset->isMic = %d\n",headset_info->isMic); - if(pdata->headset_in_type == HEADSET_IN_HIGH) + if(pdata->headset_insert_type == HEADSET_IN_HIGH) irq_set_irq_type(headset_info->irq[HEADSET],IRQF_TRIGGER_FALLING); else irq_set_irq_type(headset_info->irq[HEADSET],IRQF_TRIGGER_RISING); @@ -281,13 +276,13 @@ static irqreturn_t headset_interrupt(int irq, void *dev_id) rt5631_headset_mic_detect(false); #endif } - if(pdata->headset_in_type == HEADSET_IN_HIGH) + if(pdata->headset_insert_type == HEADSET_IN_HIGH) irq_set_irq_type(headset_info->irq[HEADSET],IRQF_TRIGGER_RISING); else irq_set_irq_type(headset_info->irq[HEADSET],IRQF_TRIGGER_FALLING); } - rk28_send_wakeup_key(); +// rk28_send_wakeup_key(); switch_set_state(&headset_info->sdev, headset_info->cur_headset_status); DBG("headset notice android headset status = %d\n",headset_info->cur_headset_status); @@ -332,7 +327,7 @@ static void headsetobserve_work(struct work_struct *work) free_irq(headset_info->irq[HEADSET],NULL); msleep(100); - if(pdata->headset_in_type == HEADSET_IN_HIGH) + if(pdata->headset_insert_type == HEADSET_IN_HIGH) headset_info->irq_type[HEADSET] = IRQF_TRIGGER_HIGH|IRQF_ONESHOT; else headset_info->irq_type[HEADSET] = IRQF_TRIGGER_LOW|IRQF_ONESHOT; @@ -341,14 +336,14 @@ static void headsetobserve_work(struct work_struct *work) return; } /* - if(pdata->headset_in_type == HEADSET_IN_HIGH && headset_info->headset_status == HEADSET_IN) + if(pdata->headset_insert_type == HEADSET_IN_HIGH && headset_info->headset_status == HEADSET_IN) headset_change_irqtype(HEADSET,IRQF_TRIGGER_FALLING); - else if(pdata->headset_in_type == HEADSET_IN_LOW && headset_info->headset_status == HEADSET_IN) + else if(pdata->headset_insert_type == HEADSET_IN_LOW && headset_info->headset_status == HEADSET_IN) headset_change_irqtype(HEADSET,IRQF_TRIGGER_RISING); - if(pdata->headset_in_type == HEADSET_IN_HIGH && headset_info->headset_status == HEADSET_OUT) + if(pdata->headset_insert_type == HEADSET_IN_HIGH && headset_info->headset_status == HEADSET_OUT) headset_change_irqtype(HEADSET,IRQF_TRIGGER_RISING); - else if(pdata->headset_in_type == HEADSET_IN_LOW && headset_info->headset_status == HEADSET_OUT) + else if(pdata->headset_insert_type == HEADSET_IN_LOW && headset_info->headset_status == HEADSET_OUT) headset_change_irqtype(HEADSET,IRQF_TRIGGER_FALLING); */ } @@ -371,7 +366,7 @@ static void hook_adc_callback(struct adc_client *client, void *client_param, int if(headset->headset_status == HEADSET_OUT || headset->heatset_irq_working == BUSY || headset->heatset_irq_working == WAIT - || pdata->headset_in_type?gpio_get_value(pdata->Headset_gpio) == 0:gpio_get_value(pdata->Headset_gpio) > 0) + || pdata->headset_insert_type?gpio_get_value(pdata->headset_gpio) == 0:gpio_get_value(pdata->headset_gpio) > 0) { DBG("Headset is out or waiting for headset is in or out,after same time check HOOK key\n"); return; @@ -399,11 +394,11 @@ static void hook_adc_callback(struct adc_client *client, void *client_param, int if(headset->headset_status == HEADSET_OUT || headset->heatset_irq_working == BUSY || headset->heatset_irq_working == WAIT - || (pdata->headset_in_type?gpio_get_value(pdata->Headset_gpio) == 0:gpio_get_value(pdata->Headset_gpio) > 0)) + || (pdata->headset_insert_type?gpio_get_value(pdata->headset_gpio) == 0:gpio_get_value(pdata->headset_gpio) > 0)) DBG("headset is out,HOOK status must discard\n"); else { - input_report_key(headset->input_dev,pdata->hook_key_code,headset->hook_status); + input_report_key(headset->input_dev,HOOK_KEY_CODE,headset->hook_status); input_sync(headset->input_dev); } } @@ -435,25 +430,24 @@ static void headset_early_resume(struct early_suspend *h) static struct early_suspend hs_early_suspend; #endif -static int rk_Hskey_open(struct input_dev *dev) +static int rk_hskey_open(struct input_dev *dev) { //struct rk28_adckey *adckey = input_get_drvdata(dev); // DBG("===========rk_Hskey_open===========\n"); return 0; } -static void rk_Hskey_close(struct input_dev *dev) +static void rk_hskey_close(struct input_dev *dev) { // DBG("===========rk_Hskey_close===========\n"); // struct rk28_adckey *adckey = input_get_drvdata(dev); } -static int rockchip_headsetobserve_probe(struct platform_device *pdev) +int rk_headset_adc_probe(struct platform_device *pdev,struct rk_headset_pdata *pdata) { int ret; struct headset_priv *headset; - struct rk_headset_pdata *pdata; headset = kzalloc(sizeof(struct headset_priv), GFP_KERNEL); if (headset == NULL) { @@ -461,8 +455,7 @@ static int rockchip_headsetobserve_probe(struct platform_device *pdev) return -ENOMEM; } headset_info = headset; - headset->pdata = pdev->dev.platform_data; - pdata = headset->pdata; + headset->pdata = pdata; headset->headset_status = HEADSET_OUT; headset->heatset_irq_working = IDLE; headset->hook_status = HOOK_UP; @@ -489,8 +482,8 @@ static int rockchip_headsetobserve_probe(struct platform_device *pdev) goto failed_free; } headset->input_dev->name = pdev->name; - headset->input_dev->open = rk_Hskey_open; - headset->input_dev->close = rk_Hskey_close; + headset->input_dev->open = rk_hskey_open; + headset->input_dev->close = rk_hskey_close; headset->input_dev->dev.parent = &pdev->dev; //input_dev->phys = KEY_PHYS_NAME; headset->input_dev->id.vendor = 0x0001; @@ -503,20 +496,17 @@ static int rockchip_headsetobserve_probe(struct platform_device *pdev) goto failed_free_dev; } - input_set_capability(headset->input_dev, EV_KEY, pdata->hook_key_code); + input_set_capability(headset->input_dev, EV_KEY, HOOK_KEY_CODE); //------------------------------------------------------------------ - if (pdata->Headset_gpio) { - if(pdata->Headset_gpio == NULL){ + if (pdata->headset_gpio) { + if(!pdata->headset_gpio){ dev_err(&pdev->dev,"failed init headset,please full hook_io_init function in board\n"); goto failed_free_dev; } - ret = pdata->headset_io_init(pdata->Headset_gpio); - if (ret) - goto failed_free_dev; - headset->irq[HEADSET] = gpio_to_irq(pdata->Headset_gpio); + headset->irq[HEADSET] = gpio_to_irq(pdata->headset_gpio); - if(pdata->headset_in_type == HEADSET_IN_HIGH) + if(pdata->headset_insert_type == HEADSET_IN_HIGH) headset->irq_type[HEADSET] = IRQF_TRIGGER_HIGH|IRQF_ONESHOT; else headset->irq_type[HEADSET] = IRQF_TRIGGER_LOW|IRQF_ONESHOT; @@ -528,9 +518,9 @@ static int rockchip_headsetobserve_probe(struct platform_device *pdev) else goto failed_free_dev; //------------------------------------------------------------------ - if(pdata->Hook_adc_chn>=0 && 3>=pdata->Hook_adc_chn) + if(pdata->hook_adc_chn>=0 && 3>=pdata->hook_adc_chn) { - headset->client = adc_register(pdata->Hook_adc_chn, hook_adc_callback, (void *)headset); + headset->client = adc_register(pdata->hook_adc_chn, hook_adc_callback, (void *)headset); if(!headset->client) { printk("hook adc register error\n"); ret = -EINVAL; @@ -558,7 +548,7 @@ failed_free: return ret; } -static int rockchip_headsetobserve_suspend(struct platform_device *pdev, pm_message_t state) +int rk_headset_adc_suspend(struct platform_device *pdev, pm_message_t state) { DBG("%s----%d\n",__FUNCTION__,__LINE__); // disable_irq(headset_info->irq[HEADSET]); @@ -566,7 +556,7 @@ static int rockchip_headsetobserve_suspend(struct platform_device *pdev, pm_mess return 0; } -static int rockchip_headsetobserve_resume(struct platform_device *pdev) +int rk_headset_adc_resume(struct platform_device *pdev) { DBG("%s----%d\n",__FUNCTION__,__LINE__); // enable_irq(headset_info->irq[HEADSET]); @@ -575,22 +565,4 @@ static int rockchip_headsetobserve_resume(struct platform_device *pdev) return 0; } -static struct platform_driver rockchip_headsetobserve_driver = { - .probe = rockchip_headsetobserve_probe, - .resume = rockchip_headsetobserve_resume, - .suspend = rockchip_headsetobserve_suspend, - .driver = { - .name = "rk_headsetdet", - .owner = THIS_MODULE, - }, -}; - -static int __init rockchip_headsetobserve_init(void) -{ - platform_driver_register(&rockchip_headsetobserve_driver); - return 0; -} -late_initcall(rockchip_headsetobserve_init); -MODULE_DESCRIPTION("Rockchip Headset Driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/headset_observe/rockchip_headset_core.c b/drivers/headset_observe/rockchip_headset_core.c new file mode 100755 index 000000000000..6ed6326391e5 --- /dev/null +++ b/drivers/headset_observe/rockchip_headset_core.c @@ -0,0 +1,222 @@ +/* + * Copyright (C) 2014 Rockchip Corporation. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "rk_headset.h" +#include +#include +/* Debug */ +#if 0 +#define DBG(x...) printk(x) +#else +#define DBG(x...) do { } while (0) +#endif + +/* + rockchip_headset { + compatible = "rockchip_headset"; + headset_gpio = ; + headset_insert_type = ; // 0 = low 1 = high + hook_gpio = ; + hook_down_type = ; //interrupt hook key down status + hook_adc_chn = ;//adc channel + mic_switch_gpio = ; + hp_mic_io_value = ; + main_mic_io_value = ; + hook_key_code = KEY_MEDIA; + }; +*/ +struct rk_headset_pdata *pdata_info; + +static int rockchip_headset_probe(struct platform_device *pdev) +{ + struct device_node *node = pdev->dev.of_node; + struct rk_headset_pdata *pdata; + int ret; + enum of_gpio_flags flags; + + pdata = kzalloc(sizeof(struct rk_headset_pdata), GFP_KERNEL); + if (pdata == NULL) { + printk("%s failed to allocate driver data\n",__FUNCTION__); + return -ENOMEM; + } + memset(pdata,0,sizeof(struct rk_headset_pdata)); + pdata_info = pdata; +//headset + ret = of_get_named_gpio_flags(node, "headset_gpio", 0, &flags); + if (ret < 0) { + printk("%s() Can not read property headset_gpio\n", __FUNCTION__); + goto err; + } else { + pdata->headset_gpio = ret; + ret = devm_gpio_request(&pdev->dev, pdata->headset_gpio, "headset_gpio"); + if(ret < 0){ + printk("%s() devm_gpio_request headset_gpio request ERROR\n", __FUNCTION__); + goto err; + } + //gpio_pull_updown(pdata->headset_gpio, PullDisable); + ret = gpio_direction_input(pdata->headset_gpio); + if(ret < 0){ + printk("%s() gpio_direction_input headset_gpio set ERROR\n", __FUNCTION__); + goto err; + } + } + + ret = of_property_read_u32(node, "headset_insert_type", &pdata->headset_insert_type); + if (ret < 0) { + DBG("%s() have not set headset_insert_type,set >headset< insert type low level default\n", __FUNCTION__); + pdata->headset_insert_type = 0; + } +//hook + ret = of_get_named_gpio_flags(node, "hook_gpio", 0, &pdata->hook_gpio); + if (ret < 0) { + DBG("%s() Can not read property hook_gpio\n", __FUNCTION__); + pdata->hook_gpio = 0; + //adc mode + ret = of_property_read_u32(node, "hook_adc_chn", &pdata->hook_adc_chn); + if (ret < 0) { + DBG("%s() have not set hook_adc_chn\n", __FUNCTION__); + pdata->hook_adc_chn = -1; + } + } else { + ret = of_property_read_u32(node, "hook_down_type", &pdata->hook_down_type); + if (ret < 0) { + DBG("%s() have not set hook_down_type,set >hook< insert type low level default\n", __FUNCTION__); + pdata->hook_down_type = 0; + } + ret = devm_gpio_request(&pdev->dev, pdata->hook_gpio, "hook_gpio"); + if(ret < 0){ + printk("%s() devm_gpio_request hook_gpio request ERROR\n", __FUNCTION__); + goto err; + } + //gpio_pull_updown(pdata->hook_gpio, PullDisable); + ret = gpio_direction_input(pdata->hook_gpio); + if(ret < 0){ + printk("%s() gpio_direction_input hook_gpio set ERROR\n", __FUNCTION__); + goto err; + } + } +#ifdef CONFIG_MODEM_MIC_SWITCH +//mic + ret = of_get_named_gpio_flags(node, "mic_switch_gpio", 0, &flags); + if (ret < 0) { + DBG("%s() Can not read property mic_switch_gpio\n", __FUNCTION__); + } else { + pdata->headset_gpio = ret; + ret = of_property_read_u32(node, "hp_mic_io_value", &pdata->hp_mic_io_value); + if (ret < 0) { + DBG("%s() have not set hp_mic_io_value ,so default set pull down low level\n", __FUNCTION__); + pdata->hp_mic_io_value = 0; + } + ret = of_property_read_u32(node, "main_mic_io_value", &pdata->main_mic_io_value); + if (ret < 0) { + DBG("%s() have not set main_mic_io_value ,so default set pull down low level\n", __FUNCTION__); + pdata->main_mic_io_value = 1; + } + } +#endif + if(pdata->hook_adc_chn >= 0) + {//hook adc mode + printk("%s() headset have hook adc mode\n",__FUNCTION__); + ret = rk_headset_adc_probe(pdev,pdata); + if(ret < 0) + { + goto err; + } + } + else + {//hook interrupt mode and not hook + printk("%s() headset have %s mode\n",__FUNCTION__,pdata->hook_gpio?"interrupt hook":"no hook"); + ret = rk_headset_probe(pdev,pdata); + if(ret < 0) + { + goto err; + } + } + + return 0; +err: + kfree(pdata); + return ret; +} + +static int rockchip_headset_remove(struct platform_device *pdev) +{ + if(pdata_info) + kfree(pdata_info); + return 0; +} + +static int rockchip_headset_suspend(struct platform_device *pdev, pm_message_t state) +{ + DBG("%s----%d\n",__FUNCTION__,__LINE__); + if(pdata_info->hook_adc_chn >= 0) + { + return rk_headset_adc_suspend(pdev,state); + } + return 0; +} + +static int rockchip_headset_resume(struct platform_device *pdev) +{ + DBG("%s----%d\n",__FUNCTION__,__LINE__); + if(pdata_info->hook_adc_chn >= 0) + { + return rk_headset_adc_resume(pdev); + } + return 0; +} + +static const struct of_device_id rockchip_headset_of_match[] = { + { .compatible = "rockchip_headset", }, + {}, +}; +MODULE_DEVICE_TABLE(of, rockchip_headset_of_match); + +static struct platform_driver rockchip_headset_driver = { + .probe = rockchip_headset_probe, + .remove = rockchip_headset_remove, + .resume = rockchip_headset_resume, + .suspend = rockchip_headset_suspend, + .driver = { + .name = "rockchip_headset", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(rockchip_headset_of_match), + }, +}; + +static int __init rockchip_headset_init(void) +{ + platform_driver_register(&rockchip_headset_driver); + return 0; +} + +static void __exit rockchip_headset_exit(void) +{ + platform_driver_unregister(&rockchip_headset_driver); +} + +late_initcall(rockchip_headset_init); +MODULE_DESCRIPTION("Rockchip Headset Core Driver"); +MODULE_LICENSE("GPL"); -- 2.34.1