From: root Date: Thu, 23 May 2013 03:21:54 +0000 (+0800) Subject: phonepad:add modem_sound and headset X-Git-Tag: firefly_0821_release~7048 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=a14c912649b62515b6cd838d440b66a727da6d82;p=firefly-linux-kernel-4.4.55.git phonepad:add modem_sound and headset --- diff --git a/drivers/headset_observe/rk_headset.c b/drivers/headset_observe/rk_headset.c index bb1653b290f2..8a017e662f14 100755 --- a/drivers/headset_observe/rk_headset.c +++ b/drivers/headset_observe/rk_headset.c @@ -61,7 +61,7 @@ #define enable 1 #define disable 0 -#ifdef CONFIG_SND_RK_SOC_RK2928 +#if defined(CONFIG_SND_RK_SOC_RK2928) || defined(CONFIG_SND_RK29_SOC_RK610) extern void rk2928_codec_set_spk(bool on); #endif #ifdef CONFIG_SND_SOC_WM8994 @@ -88,6 +88,24 @@ struct headset_priv { }; static struct headset_priv *headset_info; +#ifdef CONFIG_MODEM_MIC_SWITCH +#define HP_MIC 0 +#define MAIN_MIC 1 +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); + else if(value == MAIN_MIC) + gpio_set_value(headset_info->pdata->Sw_mic_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); + else + gpio_set_value(headset_info->pdata->Sw_mic_gpio,headset_info->pdata->Main_mic_io_value); +} +#endif int Headset_isMic(void) { return headset_info->isMic; @@ -143,6 +161,7 @@ static irqreturn_t Hook_interrupt(int irq, void *dev_id) static void headsetobserve_work(struct work_struct *work) { int level = 0; + int level2 = 0; struct rk_headset_pdata *pdata = headset_info->pdata; static unsigned int old_status = 0; DBG("---headsetobserve_work---\n"); @@ -151,7 +170,12 @@ static void headsetobserve_work(struct work_struct *work) level = read_gpio(pdata->Headset_gpio); if(level < 0) goto out; - + msleep(100); + 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) headset_info->headset_status = level?HEADSET_IN:HEADSET_OUT; @@ -190,8 +214,8 @@ static void headsetobserve_work(struct work_struct *work) headset_info->isHook_irq = disable; disable_irq(headset_info->irq[HOOK]); } - headset_info->cur_headset_status = ~(BIT_HEADSET|BIT_HEADSET_NO_MIC); - //#ifdef CONFIG_SND_RK_SOC_RK2928 + headset_info->cur_headset_status = 0;//~(BIT_HEADSET|BIT_HEADSET_NO_MIC); + //#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) @@ -201,11 +225,12 @@ static void headsetobserve_work(struct work_struct *work) } rk28_send_wakeup_key(); switch_set_state(&headset_info->sdev, headset_info->cur_headset_status); - #ifdef CONFIG_SND_RK_SOC_RK2928 + #if defined(CONFIG_SND_RK_SOC_RK2928) || defined(CONFIG_SND_RK29_SOC_RK610) if (headset_info->headset_status == HEADSET_OUT) { mdelay(200); rk2928_codec_set_spk(HEADSET_OUT); + gpio_set_value(pdata->Sw_mic_gpio, headset_info->pdata->Main_mic_io_value); } #endif DBG("headset_info->cur_headset_status = %d\n",headset_info->cur_headset_status); @@ -316,9 +341,11 @@ static void headset_timer_callback(unsigned long arg) headset->isMic= 0;//No microphone printk("headset->isMic = %d\n",headset->isMic); - headset_info->cur_headset_status = headset_info->isMic ? BIT_HEADSET:BIT_HEADSET_NO_MIC; - #ifdef CONFIG_SND_RK_SOC_RK2928 + headset_info->cur_headset_status = headset_info->isMic ? 1:3;//BIT_HEADSET:BIT_HEADSET_NO_MIC;// + #if defined(CONFIG_SND_RK_SOC_RK2928) || defined(CONFIG_SND_RK29_SOC_RK610) rk2928_codec_set_spk(HEADSET_IN); + if(headset_info->cur_headset_status == 1) + gpio_set_value(pdata->Sw_mic_gpio, pdata->Hp_mic_io_value); #endif rk28_send_wakeup_key(); switch_set_state(&headset_info->sdev, headset_info->cur_headset_status); diff --git a/drivers/headset_observe/rk_headset.h b/drivers/headset_observe/rk_headset.h index f3e15094d38d..6c5d7a6f1dca 100755 --- a/drivers/headset_observe/rk_headset.h +++ b/drivers/headset_observe/rk_headset.h @@ -15,6 +15,9 @@ struct io_info{ 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; diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 9a4ee8cfb9d6..3034dceb187d 100755 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -552,6 +552,10 @@ config TDSC8800 config MODEM_SOUND bool "modem sound control driver" default n +config MODEM_MIC_SWITCH + bool "3g modem mic switch control" + depends on MODEM_SOUND + default n config TCC_BT_DEV tristate "TCC Bluetooth dev Control power" diff --git a/drivers/misc/modem_sound.c b/drivers/misc/modem_sound.c index f273f46b26b2..41ff7c3e8e16 100755 --- a/drivers/misc/modem_sound.c +++ b/drivers/misc/modem_sound.c @@ -26,6 +26,28 @@ static struct modem_sound_data *modem_sound; #if defined(CONFIG_SND_RK_SOC_RK2928)|| defined(CONFIG_SND_RK29_SOC_RK610) extern void call_set_spk(int on); #endif +#define HP_MIC 0 +#define MAIN_MIC 1 +#if defined(CONFIG_MODEM_MIC_SWITCH) +extern void Modem_Mic_switch(int value); +extern void Modem_Mic_release(void); +void Modem_Sound_Mic_switch(int value) +{ + Modem_Mic_switch(value); +} +void Modem_Sound_Mic_release() +{ + Modem_Mic_release(); +} +#else +void Modem_Sound_Mic_switch(int value) +{ +} +void Modem_Sound_Mic_release() +{ +} +#endif + int modem_sound_spkctl(int status) { if(status == ENABLE) @@ -78,16 +100,19 @@ static long modem_sound_ioctl(struct file *filp, unsigned int cmd, unsigned long switch (cmd){ case IOCTL_MODEM_EAR_PHOEN: DBG("modem_sound_ioctl: MODEM_EAR_PHONE\n"); + Modem_Sound_Mic_switch(MAIN_MIC); call_set_spk(3); modem_sound_spkctl(DISABLE); break; case IOCTL_MODEM_SPK_PHONE: DBG("modem_sound_ioctl: MODEM_SPK_PHONE\n"); + Modem_Sound_Mic_switch(MAIN_MIC); call_set_spk(1); modem_sound_spkctl(ENABLE); break; - case IOCTL_MODEM_HP_PHONE: - DBG("modem_sound_ioctl: MODEM_HP_PHONE\n"); + case IOCTL_MODEM_HP_WITHMIC_PHONE: + DBG("modem_sound_ioctl: MODEM_HP_WITHMIC_PHONE\n"); + Modem_Sound_Mic_switch(HP_MIC); call_set_spk(2); modem_sound_spkctl(DISABLE); break; @@ -99,8 +124,17 @@ static long modem_sound_ioctl(struct file *filp, unsigned int cmd, unsigned long break; case IOCTL_MODEM_STOP_PHONE: DBG("modem_sound_ioctl: MODEM_STOP_PHONE\n"); + Modem_Sound_Mic_release(); call_set_spk(0); + modem_sound_spkctl(ENABLE); break; + case IOCTL_MODEM_HP_NOMIC_PHONE: + DBG("modem_sound_ioctl: MODEM_HP_NOMIC_PHONE\n"); + Modem_Sound_Mic_switch(MAIN_MIC); + call_set_spk(2); + modem_sound_spkctl(DISABLE); + break; + default: printk("unknown ioctl cmd!\n"); diff --git a/drivers/misc/modem_sound.h b/drivers/misc/modem_sound.h index 6de17fd20c35..c3985661346c 100755 --- a/drivers/misc/modem_sound.h +++ b/drivers/misc/modem_sound.h @@ -7,14 +7,16 @@ #define IOCTL_MODEM_EAR_PHOEN _IO(MODEM_SOUND, 0x01) #define IOCTL_MODEM_SPK_PHONE _IO(MODEM_SOUND, 0x02) -#define IOCTL_MODEM_HP_PHONE _IO(MODEM_SOUND, 0x03) +#define IOCTL_MODEM_HP_WITHMIC_PHONE _IO(MODEM_SOUND, 0x03) #define IOCTL_MODEM_BT_PHONE _IO(MODEM_SOUND, 0x04) #define IOCTL_MODEM_STOP_PHONE _IO(MODEM_SOUND, 0x05) +#define IOCTL_MODEM_HP_NOMIC_PHONE _IO(MODEM_SOUND, 0x06) #define IOCTL_SET_EAR_VALUME _IO(MODEM_SOUND, 0x11) #define IOCTL_SET_SPK_VALUME _IO(MODEM_SOUND, 0x12) -#define IOCTL_SET_HP_VALUME _IO(MODEM_SOUND, 0x13) +#define IOCTL_SET_HP_WITHMIC_VALUME _IO(MODEM_SOUND, 0x13) #define IOCTL_SET_BT_VALUME _IO(MODEM_SOUND, 0x14) +#define IOCTL_SET_HP_NOMIC_PHONE _IO(MODEM_SOUND, 0x15) struct modem_sound_data {