rk2928phonepad:
author邱建斌 <qjb@rock-chips.com>
Fri, 19 Oct 2012 02:48:56 +0000 (10:48 +0800)
committer邱建斌 <qjb@rock-chips.com>
Fri, 19 Oct 2012 02:48:56 +0000 (10:48 +0800)
     add support rk2928 codec for phonepad

arch/arm/mach-rk2928/board-rk2928-phonepad.c
drivers/headset_observe/rk_headset.c
drivers/misc/Kconfig
drivers/misc/Makefile
drivers/misc/modem_sound.c [new file with mode: 0755]
drivers/misc/modem_sound.h [new file with mode: 0755]
sound/soc/codecs/rk2928_codec.c

index 36905f67c6ca58c203a58c9a449211d027f6789e..66dc02bead5e5abcb957ee87c072176e9c62a9a2 100755 (executable)
 #include <linux/sensor-dev.h>
 #include <linux/mfd/tps65910.h>
 #include <linux/regulator/rk29-pwm-regulator.h>
+#if defined(CONFIG_MODEM_SOUND)
+#include "../../../drivers/misc/modem_sound.h"
+#endif
 #if defined(CONFIG_HDMI_RK30)
        #include "../../../drivers/video/rockchip/hdmi/rk_hdmi.h"
 #endif
+#include "../../../drivers/headset_observe/rk_headset.h"
 
 #if defined(CONFIG_SPIM_RK29)
 #include "../../../drivers/spi/rk29_spim.h"
@@ -500,7 +504,7 @@ static struct rk30_adc_battery_platform_data rk30_adc_battery_platdata = {
         .batt_low_pin    = INVALID_GPIO,
         .charge_set_pin  = INVALID_GPIO,
         .charge_ok_pin   = RK2928_PIN1_PA0,
-        .dc_det_level    = GPIO_LOW,  //
+        .dc_det_level    = GPIO_HIGH,  //
         .charge_ok_level = GPIO_HIGH,
 };
 
@@ -567,6 +571,22 @@ struct platform_device pwm_regulator_device[1] = {
        },
 };
 #endif
+
+#if defined(CONFIG_MODEM_SOUND)
+
+struct modem_sound_data modem_sound_info = {
+       .spkctl_io = RK2928_PIN3_PD4,
+       .spkctl_active = GPIO_HIGH,
+};
+
+struct platform_device modem_sound_device = {
+       .name = "modem_sound",
+       .id = -1,
+       .dev            = {
+       .platform_data = &modem_sound_info,
+               }
+       };
+#endif
 /**************************************************************************************************
  * SDMMC devices,  include the module of SD,MMC,and sdio.noted by xbw at 2012-03-05
 **************************************************************************************************/
@@ -736,6 +756,53 @@ struct platform_device rk29_device_sc6610 = {
         }
     };
 #endif
+#if defined (CONFIG_RK_HEADSET_DET) || defined (CONFIG_RK_HEADSET_IRQ_HOOK_ADC_DET)
+static int rk_headset_io_init(int gpio, char *iomux_name, int iomux_mode)
+{
+       int ret;
+       ret = gpio_request(gpio, "headset_io");
+       if(ret) 
+               return ret;
+
+       rk30_mux_api_set(iomux_name, iomux_mode);
+       gpio_pull_updown(gpio, PullDisable);
+       gpio_direction_input(gpio);
+       mdelay(50);
+       return 0;
+};
+
+static int rk_hook_io_init(int gpio, char *iomux_name, int iomux_mode)
+{
+       int ret;
+       ret = gpio_request(gpio, "hook_io");
+       if(ret) 
+               return ret;
+
+       rk30_mux_api_set(iomux_name, iomux_mode);
+       gpio_pull_updown(gpio, PullDisable);
+       gpio_direction_input(gpio);
+       mdelay(50);
+       return 0;
+};
+
+struct rk_headset_pdata rk_headset_info = {
+               .Headset_gpio           = RK2928_PIN1_PB4,
+               .Hook_gpio  = RK2928_PIN0_PD1,
+               .headset_in_type = HEADSET_IN_HIGH,
+               .hook_key_code = KEY_MEDIA,
+               .headset_gpio_info = {GPIO1B4_SPI_CSN1_NAME, GPIO1B_GPIO1B4},
+               .headset_io_init = rk_headset_io_init,
+               .hook_gpio_info = {GPIO0D1_UART2_CTSN_NAME, GPIO0D_GPIO0D1},
+               .hook_io_init = rk_hook_io_init,
+};
+struct platform_device rk_device_headset = {
+               .name   = "rk_headsetdet",
+               .id     = 0,
+               .dev    = {
+                           .platform_data = &rk_headset_info,
+               }
+};
+#endif
 #ifdef CONFIG_SND_SOC_RK2928
 static struct resource resources_acodec[] = {
        {
@@ -782,6 +849,12 @@ static struct platform_device *devices[] __initdata = {
         &rk29_device_sc6610,
 
 #endif
+#if defined (CONFIG_RK_HEADSET_DET) ||  defined (CONFIG_RK_HEADSET_IRQ_HOOK_ADC_DET)
+       &rk_device_headset,
+#endif
+#if defined (CONFIG_MODEM_SOUND)
+ &modem_sound_device,
+#endif
 };
 //i2c
 #ifdef CONFIG_I2C0_RK30
index e9f39d805ed6dd0e21194b940d980c2804203614..3365da599cfa96df38afcd343d5cb24daa83e53e 100755 (executable)
@@ -61,7 +61,9 @@
 #define enable 1
 #define disable 0
 
-
+#ifdef CONFIG_SND_RK_SOC_RK2928
+extern void rk2928_codec_set_spk(bool on);
+#endif
 #ifdef CONFIG_SND_SOC_WM8994
 extern int wm8994_set_status(void);
 #endif
@@ -92,6 +94,16 @@ int Headset_isMic(void)
 }
 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 irqreturn_t headset_interrupt(int irq, void *dev_id)
 {
        DBG("---headset_interrupt---\n");       
@@ -210,6 +222,9 @@ static void headsetobserve_work(struct work_struct *work)
                                disable_irq(headset_info->irq[HOOK]);           
                        }       
                        headset_info->cur_headset_status = ~(BIT_HEADSET|BIT_HEADSET_NO_MIC);
+       #ifdef CONFIG_SND_RK_SOC_RK2928
+       rk2928_codec_set_spk(HEADSET_OUT);
+       #endif                                          
                        headset_change_irqtype(HEADSET,IRQF_TRIGGER_RISING);//
                        rk28_send_wakeup_key();
                        switch_set_state(&headset_info->sdev, headset_info->cur_headset_status);        
@@ -237,7 +252,10 @@ static void headsetobserve_work(struct work_struct *work)
                                DBG("disable headset_hook irq\n");
                                headset_info->isHook_irq = disable;
                                disable_irq(headset_info->irq[HOOK]);           
-                       }                               
+                       }
+       #ifdef CONFIG_SND_RK_SOC_RK2928
+       rk2928_codec_set_spk(HEADSET_OUT);
+       #endif          
                        headset_info->cur_headset_status = ~(BIT_HEADSET|BIT_HEADSET_NO_MIC);
                        headset_change_irqtype(HEADSET,IRQF_TRIGGER_FALLING);//
                        rk28_send_wakeup_key();
@@ -378,7 +396,9 @@ static void headset_timer_callback(unsigned long arg)
                headset_info->cur_headset_status = BIT_HEADSET; 
                printk("headset->isMic = %d\n",headset->isMic);         
        }
-       
+       #ifdef CONFIG_SND_RK_SOC_RK2928
+       rk2928_codec_set_spk(HEADSET_IN);
+       #endif
        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);        
@@ -501,11 +521,10 @@ static int rockchip_headsetobserve_probe(struct platform_device *pdev)
 
        //------------------------------------------------------------------
        if (pdata->Headset_gpio) {
-               ret = gpio_request(pdata->Headset_gpio, NULL);
+               ret = pdata->headset_io_init(pdata->Headset_gpio, pdata->headset_gpio_info.iomux_name, pdata->headset_gpio_info.iomux_mode);
                if (ret) 
-                       goto failed_free_dev;
-               gpio_pull_updown(pdata->Headset_gpio, PullDisable);
-               gpio_direction_input(pdata->Headset_gpio);
+                       goto failed_free;       
+
                headset->irq[HEADSET] = gpio_to_irq(pdata->Headset_gpio);
 
                if(pdata->headset_in_type == HEADSET_IN_HIGH)
@@ -521,11 +540,9 @@ static int rockchip_headsetobserve_probe(struct platform_device *pdev)
                goto failed_free_dev;
 //------------------------------------------------------------------
        if (pdata->Hook_gpio) {
-               ret = gpio_request(pdata->Hook_gpio , NULL);
+               ret = pdata->hook_io_init(pdata->Hook_gpio, pdata->hook_gpio_info.iomux_name, pdata->hook_gpio_info.iomux_mode);
                if (ret) 
-                       goto failed_free_dev;
-               gpio_pull_updown(pdata->Hook_gpio, PullDisable);
-               gpio_direction_input(pdata->Hook_gpio);
+                       goto failed_free;
                headset->irq[HOOK] = gpio_to_irq(pdata->Hook_gpio);
                headset->irq_type[HOOK] = IRQF_TRIGGER_FALLING;
        
index 964597fd1c494eb5f4760a11a642e5209962ec95..5e2990cfdd90bc18e18a958d265b7cc9461a3a68 100644 (file)
@@ -539,6 +539,10 @@ config RK29_SC8800
 config TDSC8800
        bool "TDSC8800 modem control driver"
        default n
+config MODEM_SOUND
+       bool "modem sound control driver"
+       default n
+       
        
 
 source "drivers/misc/c2port/Kconfig"
index ea32927a092e51037516d74d1a6d875d718bc9b8..7d02af44d9e8b07b18c54e85cd97a1f2dc3d1af6 100755 (executable)
@@ -59,3 +59,4 @@ obj-y += inv_mpu/
 obj-$(CONFIG_TDSC8800) += tdsc8800.o
 obj-$(CONFIG_RK29_SC8800)      +=      sc8800.o
 obj-y += rk2928_callpad_misc/
+obj-$(CONFIG_MODEM_SOUND) += modem_sound.o
diff --git a/drivers/misc/modem_sound.c b/drivers/misc/modem_sound.c
new file mode 100755 (executable)
index 0000000..1f402b3
--- /dev/null
@@ -0,0 +1,227 @@
+#include <linux/input.h>\r
+#include <linux/module.h>\r
+#include <linux/init.h>\r
+#include <linux/interrupt.h>\r
+#include <linux/kernel.h>\r
+#include <linux/fcntl.h>\r
+#include <linux/delay.h>\r
+#include <linux/device.h>\r
+#include <linux/miscdevice.h>\r
+#include <asm/types.h>\r
+#include <mach/gpio.h>\r
+#include <mach/iomux.h>\r
+#include <linux/platform_device.h>\r
+#include <asm/uaccess.h>\r
+#include <linux/wait.h>\r
+#include "modem_sound.h"\r
+#if 1\r
+#define DBG(x...)      printk(KERN_INFO x)\r
+#else\r
+#define DBG(x...)\r
+#endif\r
+#define MODEM_EARPHOEN     0      //ÌýͲµç»°\r
+#define MODEM_HANDFREE     1   //ÃâÌá\r
+#define MODEM_HPPHONE      2   //¶ú»úµç»°\r
+#define MODEM_BTPHONE      3      //À¶ÑÀµç»°\r
+#define MODEM_STOP_PHONE   4      //ֹͣͨ»°\r
+\r
+#define ENABLE             1\r
+#define DISABLE            0\r
+\r
+static struct modem_sound_data *modem_sound;\r
+#ifdef CONFIG_SND_RK_SOC_RK2928\r
+extern void call_set_spk(bool on);\r
+#endif\r
+int modem_sound_spkctl(int status)\r
+{\r
+       if(status == ENABLE)\r
+               gpio_direction_output(modem_sound->spkctl_io,GPIO_HIGH);//modem_sound->spkctl_io? GPIO_HIGH:GPIO_LOW);\r
+       else \r
+               gpio_direction_output(modem_sound->spkctl_io,GPIO_LOW); //modem_sound->spkctl_io? GPIO_LOW:GPIO_HIGH);\r
+                       \r
+       return 0;\r
+}\r
+\r
+static void modem_sound_delay_power_downup(struct work_struct *work)\r
+{\r
+       struct modem_sound_data *pdata = container_of(work, struct modem_sound_data, work);\r
+       if (pdata == NULL) {\r
+               printk("%s: pdata = NULL\n", __func__);\r
+               return;\r
+       }\r
+\r
+       down(&pdata->power_sem);\r
+       up(&pdata->power_sem);\r
+}\r
+\r
+static int modem_sound_open(struct inode *inode, struct file *filp)\r
+{\r
+    DBG("modem_sound_open\n");\r
+\r
+       return 0;\r
+}\r
+\r
+static ssize_t modem_sound_read(struct file *filp, char __user *ptr, size_t size, loff_t *pos)\r
+{\r
+       if (ptr == NULL)\r
+               printk("%s: user space address is NULL\n", __func__);\r
+       return sizeof(int);\r
+}\r
+\r
+static long modem_sound_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)\r
+{\r
+       long ret = 0;\r
+       struct modem_sound_data *pdata = modem_sound;\r
+\r
+       DBG("modem_sound_ioctl: cmd = %d arg = %ld\n",cmd, arg);\r
+\r
+       ret = down_interruptible(&pdata->power_sem);\r
+       if (ret < 0) {\r
+               printk("%s: down power_sem error ret = %ld\n", __func__, ret);\r
+               return ret;\r
+       }\r
+\r
+       switch (cmd){\r
+               case MODEM_EARPHOEN:\r
+                       DBG("modem_sound_ioctl: MODEM_EAR_PHONE\n");\r
+                       call_set_spk(0);\r
+                       modem_sound_spkctl(DISABLE);\r
+                       break;\r
+               case MODEM_HANDFREE:\r
+                       DBG("modem_sound_ioctl: MODEM_SPK_PHONE\n");\r
+                       call_set_spk(0);\r
+                       modem_sound_spkctl(ENABLE);\r
+                       break;\r
+               case MODEM_HPPHONE:\r
+                       DBG("modem_sound_ioctl: MODEM_HP_PHONE\n");\r
+                       call_set_spk(0);\r
+                       modem_sound_spkctl(DISABLE);\r
+                       break;\r
+                       \r
+               case MODEM_BTPHONE:\r
+                       call_set_spk(0);\r
+                       modem_sound_spkctl(DISABLE);\r
+                       DBG("modem_sound_ioctl: MODEM_BT_PHONE\n");\r
+                       break;\r
+               case MODEM_STOP_PHONE:\r
+                       DBG("modem_sound_ioctl: MODEM_STOP_PHONE\n");\r
+                       call_set_spk(1);\r
+                       break;\r
+\r
+               default:\r
+                       printk("unknown ioctl cmd!\n");\r
+                       up(&pdata->power_sem);\r
+                       ret = -EINVAL;\r
+                       break;\r
+       }\r
+\r
+       up(&pdata->power_sem);\r
+\r
+       return ret;\r
+}\r
+\r
+static int modem_sound_release(struct inode *inode, struct file *filp)\r
+{\r
+    DBG("modem_sound_release\n");\r
+    \r
+       return 0;\r
+}\r
+\r
+static struct file_operations modem_sound_fops = {\r
+       .owner   = THIS_MODULE,\r
+       .open    = modem_sound_open,\r
+       .read    = modem_sound_read,\r
+       .unlocked_ioctl   = modem_sound_ioctl,\r
+       .release = modem_sound_release,\r
+};\r
+\r
+static struct miscdevice modem_sound_dev = \r
+{\r
+    .minor = MISC_DYNAMIC_MINOR,\r
+    .name = "modem_sound",\r
+    .fops = &modem_sound_fops,\r
+};\r
+\r
+static int modem_sound_probe(struct platform_device *pdev)\r
+{\r
+       int ret = 0;\r
+       struct modem_sound_data *pdata = pdev->dev.platform_data;\r
+       if(!pdata)\r
+               return -1;\r
+               \r
+       ret = misc_register(&modem_sound_dev);\r
+       if (ret < 0){\r
+               printk("modem register err!\n");\r
+               return ret;\r
+       }\r
+       \r
+       sema_init(&pdata->power_sem,1);\r
+       pdata->wq = create_freezable_workqueue("modem_sound");\r
+       INIT_WORK(&pdata->work, modem_sound_delay_power_downup);\r
+       modem_sound = pdata;\r
+       printk("%s:modem sound initialized\n",__FUNCTION__);\r
+\r
+       return ret;\r
+}\r
+\r
+static int modem_sound_suspend(struct platform_device *pdev,  pm_message_t state)\r
+{\r
+       struct modem_sound_data *pdata = pdev->dev.platform_data;\r
+\r
+       if(!pdata) {\r
+               printk("%s: pdata = NULL ...... \n", __func__);\r
+               return -1;\r
+       }\r
+       printk("%s\n",__FUNCTION__);\r
+       return 0;       \r
+}\r
+\r
+static int modem_sound_resume(struct platform_device *pdev)\r
+{\r
+       struct modem_sound_data *pdata = pdev->dev.platform_data;\r
+\r
+       if(!pdata) {\r
+               printk("%s: pdata = NULL ...... \n", __func__);\r
+               return -1;\r
+       }\r
+       printk("%s\n",__FUNCTION__);\r
+       return 0;\r
+}\r
+\r
+static int modem_sound_remove(struct platform_device *pdev)\r
+{\r
+       struct modem_sound_data *pdata = pdev->dev.platform_data;\r
+       if(!pdata)\r
+               return -1;\r
+\r
+       misc_deregister(&modem_sound_dev);\r
+\r
+       return 0;\r
+}\r
+\r
+static struct platform_driver modem_sound_driver = {\r
+       .probe  = modem_sound_probe,\r
+       .remove = modem_sound_remove,\r
+       .suspend        = modem_sound_suspend,\r
+       .resume         = modem_sound_resume,\r
+       .driver = {\r
+               .name   = "modem_sound",\r
+               .owner  = THIS_MODULE,\r
+       },\r
+};\r
+\r
+static int __init modem_sound_init(void)\r
+{\r
+       return platform_driver_register(&modem_sound_driver);\r
+}\r
+\r
+static void __exit modem_sound_exit(void)\r
+{\r
+       platform_driver_unregister(&modem_sound_driver);\r
+}\r
+\r
+module_init(modem_sound_init);\r
+module_exit(modem_sound_exit);\r
+MODULE_DESCRIPTION ("modem sound driver");\r
+MODULE_LICENSE("GPL");\r
+\r
diff --git a/drivers/misc/modem_sound.h b/drivers/misc/modem_sound.h
new file mode 100755 (executable)
index 0000000..e78314e
--- /dev/null
@@ -0,0 +1,14 @@
+\r
+#ifndef __MODEM_SOUND_H__\r
+#define __MODEM_SOUND_H__\r
+\r
+struct modem_sound_data {\r
+       int spkctl_io;\r
+       int spkctl_active;\r
+       int codec_flag;\r
+       struct semaphore power_sem;\r
+       struct workqueue_struct *wq;\r
+       struct work_struct work;\r
+};\r
+\r
+#endif\r
index dc77d77416b5a82f964cca900fe4040280f55ab7..adbebd2c1d5e3d20e60229a49c31459dbc029e81 100755 (executable)
 #include <linux/clk.h>
 #include "rk2928_codec.h"
 
+#define HP_OUT 0
+#define HP_IN  1
+
 static struct rk2928_codec_data {
        struct device   *dev;
+       struct snd_soc_codec *codec;
        int                     regbase;
        int                             regbase_phy;
        int                             regsize_phy;
@@ -52,6 +56,8 @@ static struct rk2928_codec_data {
        int                             mute;
        int                             hdmi_enable;
        int                             spkctl;
+       int             call_enable;
+       int             headset_status; 
 } rk2928_data;
 
 static const struct snd_soc_dapm_widget rk2928_dapm_widgets[] = {
@@ -135,6 +141,44 @@ void codec_set_spk(bool on)
                        rk2928_write(NULL, CODEC_REG_DAC_MUTE, v_MUTE_DAC(0));
        }
 }
+#ifdef CONFIG_MODEM_SOUND
+void call_set_spk(bool on)
+{
+       if(on == 0) {
+               printk("%s speaker is disabled\n", __FUNCTION__);
+               rk2928_data.call_enable = 1;
+               rk2928_write(NULL, CODEC_REG_DAC_MUTE, v_MUTE_DAC(1));
+       }
+       else {
+               printk("%s speaker is enabled\n", __FUNCTION__);
+               rk2928_data.call_enable = 0;
+               rk2928_write(NULL, CODEC_REG_DAC_MUTE, v_MUTE_DAC(0));
+       }
+}
+#endif
+#ifdef CONFIG_RK_HEADSET_DET
+//for headset
+void rk2928_codec_set_spk(bool on)
+{
+       struct snd_soc_codec *codec = rk2928_data.codec;
+
+       printk("%s: headset %s %s PA bias_level=%d\n",__FUNCTION__,on?"in":"out",on?"disable":"enable",codec->dapm.bias_level);
+       if(on) {
+               rk2928_data.headset_status = HP_IN;     
+               if(rk2928_data.spkctl != INVALID_GPIO)
+                       gpio_direction_output(rk2928_data.spkctl, GPIO_LOW);
+       }
+       else {
+               rk2928_data.headset_status = HP_OUT;
+               if(codec->dapm.bias_level == SND_SOC_BIAS_STANDBY 
+               || codec->dapm.bias_level == SND_SOC_BIAS_OFF){
+                       return;
+               }               
+               if(rk2928_data.spkctl != INVALID_GPIO)
+                       gpio_direction_output(rk2928_data.spkctl, GPIO_HIGH);
+       }
+}
+#endif
 
 static int rk2928_audio_hw_params(struct snd_pcm_substream *substream,
                                    struct snd_pcm_hw_params *params,
@@ -158,7 +202,10 @@ static int rk2928_audio_trigger(struct snd_pcm_substream *substream, int cmd,
        int err = 0;
        int data, pd_adc;
        DBG("%s cmd 0x%x", __FUNCTION__, cmd);
-       
+#ifdef CONFIG_MODEM_SOUND      
+       if(rk2928_data.call_enable)
+               return err;
+#endif         
        switch (cmd) {
                case SNDRV_PCM_TRIGGER_START:
                case SNDRV_PCM_TRIGGER_RESUME:
@@ -212,7 +259,7 @@ static int rk2928_audio_trigger(struct snd_pcm_substream *substream, int cmd,
                                        rk2928_write(codec, CODEC_REG_DAC_MUTE, v_MUTE_DAC(0));
                                }
                                rk2928_data.mute = 0;
-                               if(rk2928_data.spkctl != INVALID_GPIO) {
+                               if(rk2928_data.spkctl != INVALID_GPIO && rk2928_data.headset_status == HP_OUT) {
                                        gpio_direction_output(rk2928_data.spkctl, GPIO_HIGH);
                                }
                        }
@@ -251,7 +298,7 @@ static int rk2928_audio_startup(struct snd_pcm_substream *substream,
 static int rk2928_set_bias_level(struct snd_soc_codec *codec,
                              enum snd_soc_bias_level level)
 {
-       DBG("%s level %d", __FUNCTION__, level);
+       DBG("%s level %d\n", __FUNCTION__, level);
        
        if(codec == NULL)
                return -1;
@@ -326,7 +373,7 @@ static int rk2928_probe(struct snd_soc_codec *codec)
        else {
                rk2928_data.spkctl = res->start;
        }
-       
+
        if(rk2928_data.spkctl != INVALID_GPIO) {
                ret = gpio_request(rk2928_data.spkctl, NULL);
                if (ret != 0) {
@@ -335,7 +382,7 @@ static int rk2928_probe(struct snd_soc_codec *codec)
                else
                        gpio_direction_output(rk2928_data.spkctl, GPIO_LOW);
        }
-       
+
        // Select SDI input from internal audio codec
        writel(0x04000400, RK2928_GRF_BASE + GRF_SOC_CON0);
        
@@ -352,6 +399,9 @@ static int rk2928_probe(struct snd_soc_codec *codec)
            snd_soc_dapm_add_routes(dapm, rk2926_audio_map, ARRAY_SIZE(rk2926_audio_map));
        }
 
+       rk2928_data.call_enable = 0;
+       rk2928_data.headset_status = HP_OUT;
+       rk2928_data.codec=codec;
        return 0;
        
 err1: