#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 },
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,
};
#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;
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;
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;
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++)
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]);
}
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);
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);
}
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;
}
// 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;
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;
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;
}
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);
{ "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"},
};
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: