コード例 #1
0
static void hook_once_work(struct work_struct *work)
{
	int ret,val;

	#ifdef CONFIG_SND_SOC_WM8994
	wm8994_headset_mic_detect(true);
	#endif

	#if defined (CONFIG_SND_SOC_RT3261) || defined (CONFIG_SND_SOC_RT3224)
	rt3261_headset_mic_detect(true);
	#endif

	#ifdef CONFIG_SND_SOC_RT5631_PHONE
	rt5631_headset_mic_detect(true);
	#endif

        ret = iio_read_channel_raw(headset_info->chan, &val);
        if (ret < 0) {
                pr_err("read hook_once_work adc channel() error: %d\n", ret);
        }
	else
		DBG("hook_once_work read adc value: %d\n",val);

	if(val >= 0 && val < HOOK_LEVEL_LOW)
	{
		headset_info->isMic= 0;//No microphone
		#ifdef CONFIG_SND_SOC_WM8994
		wm8994_headset_mic_detect(false);
		#endif

		#if defined (CONFIG_SND_SOC_RT3261) || defined (CONFIG_SND_SOC_RT3224)
		rt3261_headset_mic_detect(false);
		#endif	

		#ifdef CONFIG_SND_SOC_RT5631_PHONE
		rt5631_headset_mic_detect(false);
		#endif					
	}	
	else if(val >= HOOK_LEVEL_HIGH)
	{
		headset_info->isMic = 1;//have mic
		schedule_delayed_work(&headset_info->hook_work,msecs_to_jiffies(100));
	}

	headset_info->cur_headset_status = headset_info->isMic ? BIT_HEADSET:BIT_HEADSET_NO_MIC;
	
	switch_set_state(&headset_info->sdev, headset_info->cur_headset_status);	
	DBG("%s notice android headset status = %d\n",__func__,headset_info->cur_headset_status);
}
コード例 #2
0
//1
static irqreturn_t headset_interrupt(int irq, void *dev_id)
{
	struct rk_headset_pdata *pdata = headset_info->pdata;
	static unsigned int old_status = 0;
	int i,level = 0;	
	
	disable_irq_nosync(headset_info->irq[HEADSET]);
	if(headset_info->heatset_irq_working == BUSY || headset_info->heatset_irq_working == WAIT)
		return IRQ_HANDLED;

	DBG("In the headset_interrupt\n");		
	headset_info->heatset_irq_working = BUSY;
	msleep(150);
	for(i=0; i<3; i++)
	{
		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);
			msleep(1);
			continue;
		}
		else
		break;
	}
	if(level < 0)
	{
		printk("%s:get pin level  err!\n",__FUNCTION__);
		goto out;
	}
	else
		printk("%s:get pin level again,pin=%d,i=%d\n",__FUNCTION__,pdata->headset_gpio,i);

	old_status = headset_info->headset_status;
	switch(pdata->headset_insert_type)
	{
	case HEADSET_IN_HIGH:
		if(level > 0)
			headset_info->headset_status = HEADSET_IN;
		else if(level == 0)
			headset_info->headset_status = HEADSET_OUT;	
		break;
	case HEADSET_IN_LOW:
		if(level == 0)
			headset_info->headset_status = HEADSET_IN;
		else if(level > 0)
			headset_info->headset_status = HEADSET_OUT;		
		break;			
	default:
		DBG("---- ERROR: on headset headset_insert_type error -----\n");
		break;			
	}
	if(old_status == headset_info->headset_status)
	{
		DBG("Read Headset IO level old status == now status =%d\n",headset_info->headset_status);
		goto out;
	}

	DBG("(headset in is %s)headset status is %s\n",
		pdata->headset_insert_type?"high level":"low level",
		headset_info->headset_status?"in":"out");
	if(headset_info->headset_status == HEADSET_IN)
	{
		if(pdata->chan != 0)
		{
			//detect Hook key
			schedule_delayed_work(&headset_info->h_delayed_work[HOOK],msecs_to_jiffies(200));
		}
		else
		{
			headset_info->isMic= 0;//No microphone
			headset_info->cur_headset_status = BIT_HEADSET_NO_MIC;

			switch_set_state(&headset_info->sdev, headset_info->cur_headset_status);	
			DBG("headset notice android headset status = %d\n",headset_info->cur_headset_status);
		}

		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);
	}
	else if(headset_info->headset_status == HEADSET_OUT)
	{
		headset_info->cur_headset_status = ~(BIT_HEADSET|BIT_HEADSET_NO_MIC);
		cancel_delayed_work(&headset_info->hook_work);
		if(headset_info->isMic)
		{
			headset_info->hook_status = HOOK_UP;
			#ifdef CONFIG_SND_SOC_WM8994
			//rt5625_headset_mic_detect(false);
			wm8994_headset_mic_detect(false);
			#endif
			#if defined (CONFIG_SND_SOC_RT3261) || defined (CONFIG_SND_SOC_RT3224)
			rt3261_headset_mic_detect(false);
			#endif
			#ifdef CONFIG_SND_SOC_RT5631_PHONE
			rt5631_headset_mic_detect(false);
			#endif				
		}	

		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);	

		switch_set_state(&headset_info->sdev, headset_info->cur_headset_status);	
		DBG("headset notice android headset status = %d\n",headset_info->cur_headset_status);		
	}	
//	rk_send_wakeup_key();	
out:
	headset_info->heatset_irq_working = IDLE;
	enable_irq(headset_info->irq[HEADSET]);
	return IRQ_HANDLED;
}
コード例 #3
0
//1
static irqreturn_t headset_interrupt(int irq, void *dev_id)
{
	struct rk_headset_pdata *pdata = headset_info->pdata;
	static unsigned int old_status = 0;
	int i,level = 0;	
	int adc_value = 0;
	wake_lock(&headset_info->headset_on_wake);
	if(headset_info->heatset_irq_working == BUSY || headset_info->heatset_irq_working == WAIT)
		return IRQ_HANDLED;
	DBG("In the headset_interrupt for read headset level  wake_lock headset_on_wake\n");		
	headset_info->heatset_irq_working = BUSY;
	msleep(150);
	for(i=0; i<3; i++)
	{
		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);
			msleep(1);
			continue;
		}
		else
		break;
	}
	if(level < 0)
	{
		printk("%s:get pin level  err!\n",__FUNCTION__);
		goto out;
	}

	old_status = headset_info->headset_status;
	switch(pdata->headset_in_type)
	{
	case HEADSET_IN_HIGH:
		if(level > 0)
			headset_info->headset_status = HEADSET_IN;
		else if(level == 0)
			headset_info->headset_status = HEADSET_OUT;	
		break;
	case HEADSET_IN_LOW:
		if(level == 0)
			headset_info->headset_status = HEADSET_IN;
		else if(level > 0)
			headset_info->headset_status = HEADSET_OUT;		
		break;			
	default:
		DBG("---- ERROR: on headset headset_in_type error -----\n");
		break;			
	}
	if(old_status == headset_info->headset_status)
	{
		DBG("Read Headset IO level old status == now status\n");
		goto out;
	}

	DBG("(headset in is %s)headset status is %s\n",
		pdata->headset_in_type?"high level":"low level",
		headset_info->headset_status?"in":"out");
	if(headset_info->headset_status == HEADSET_IN)
	{
		#if 0
		while(1)
		{
			if(adc_sync_read(headset_info->client) > HOOK_DEFAULT_VAL
			 || adc_sync_read(headset_info->client) < 0)
			{
				printk("headset is showly inside\n");
			}
			else
				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;
			else
				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)
		{
		// wait for find Hook key
			//#ifdef CONFIG_SND_SOC_RT5625
			CHECK_AGAIN:
			//headset_info->isMic = rt5625_headset_mic_detect(true);
			#ifdef CONFIG_SND_SOC_WM8994
			wm8994_headset_mic_detect(true);
			#endif
			#if defined (CONFIG_SND_SOC_RT3261) || defined (CONFIG_SND_SOC_RT3224)
			rt3261_headset_mic_detect(true);
			#endif
			#ifdef CONFIG_SND_SOC_RT5631_PHONE
			rt5631_headset_mic_detect(true);
			#endif			
			//mdelay(400);
			adc_value = adc_sync_read(headset_info->client);
			if(adc_value >= 0 && adc_value < HOOK_LEVEL_LOW)
			{
				headset_info->isMic= 0;//No microphone
				#ifdef CONFIG_SND_SOC_WM8994
				wm8994_headset_mic_detect(false);
				#endif
				#if defined (CONFIG_SND_SOC_RT3261) || defined (CONFIG_SND_SOC_RT3224)
				rt3261_headset_mic_detect(false);
				#endif	
				#ifdef CONFIG_SND_SOC_RT5631_PHONE
				rt5631_headset_mic_detect(false);
				#endif					
			}	
			else if(adc_value >= HOOK_LEVEL_HIGH)
				headset_info->isMic = 1;//have mic

			if(headset_info->isMic < 0)	
			{
				printk("codec is error\n");
				headset_info->heatset_irq_working = WAIT;
				if(pdata->headset_in_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);
				schedule_delayed_work(&headset_info->h_delayed_work[HEADSET], msecs_to_jiffies(0));	
				wake_unlock(&headset_info->headset_on_wake);
				return IRQ_HANDLED;
			}
			//adc_value = adc_sync_read(headset_info->client);
			printk("headset adc value = %d\n",adc_value);
			if(headset_info->isMic) {
				if(adc_value > HOOK_DEFAULT_VAL || adc_value < HOOK_LEVEL_HIGH)
					goto CHECK_AGAIN;
				mod_timer(&headset_info->hook_timer, jiffies + msecs_to_jiffies(1000));
			}	
			//#endif		
			headset_info->cur_headset_status = headset_info->isMic ? BIT_HEADSET:BIT_HEADSET_NO_MIC;
		}
		else
		{
			headset_info->isMic= 0;//No microphone
			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)
			irq_set_irq_type(headset_info->irq[HEADSET],IRQF_TRIGGER_FALLING);
		else
			irq_set_irq_type(headset_info->irq[HEADSET],IRQF_TRIGGER_RISING);
	}
	else if(headset_info->headset_status == HEADSET_OUT)
	{
		headset_info->cur_headset_status = ~(BIT_HEADSET|BIT_HEADSET_NO_MIC);
		del_timer(&headset_info->hook_timer);
		if(headset_info->isMic)
		{
			headset_info->hook_status = HOOK_UP;
			#ifdef CONFIG_SND_SOC_WM8994
			//rt5625_headset_mic_detect(false);
			wm8994_headset_mic_detect(false);
			#endif
			#if defined (CONFIG_SND_SOC_RT3261) || defined (CONFIG_SND_SOC_RT3224)
			rt3261_headset_mic_detect(false);
			#endif
			#ifdef CONFIG_SND_SOC_RT5631_PHONE
			rt5631_headset_mic_detect(false);
			#endif				
		}	
		if(pdata->headset_in_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();			
	switch_set_state(&headset_info->sdev, headset_info->cur_headset_status);	
	DBG("headset notice android headset status = %d\n",headset_info->cur_headset_status);	

//	schedule_delayed_work(&headset_info->h_delayed_work[HEADSET], msecs_to_jiffies(0));
out:
	headset_info->heatset_irq_working = IDLE;
	wake_unlock(&headset_info->headset_on_wake);
	return IRQ_HANDLED;
}