static irqreturn_t headset_button_irq_handler(int irq, void *dev)
{

	struct _headset_gpio *hgp = dev;
	int det_status;

	wake_lock_timeout(&hgp->gpio_wakelock,HZ*4);
	del_timer(&hgp->gpio_timer);
	det_status = headset_gpio_get_value(hgp->gpio);

	pr_debug("%s : %s %s\n", __func__, hgp->desc, hgp->active ? "active" : "inactive");

	if(det_status != 1){
		hgp->active = 1;
		headset_gpio_set_irq_type(hgp->irq, hgp->irq_type_inactive);
		mod_timer(&hgp->gpio_timer, jiffies + msecs_to_jiffies(100));
	}
	else {
		hgp->active = 0;
		headset_gpio_set_irq_type(hgp->irq, hgp->irq_type_active);
		mod_timer(&hgp->gpio_timer,jiffies + msecs_to_jiffies(100));
	}

	return IRQ_HANDLED;
}
static void headset_detect_gpio_work(struct work_struct *work)
{
	struct _headset_gpio *hgp = container_of(work, struct _headset_gpio, gpio_work);
	int com_detect = headset_gpio_get_value(HEADSET_COM_DETECT_GPIO);
	
	if (hgp->active) {
		/* Active=1 plug in case - ffkaka */
		
		if(com_detect == 1){
			pr_info("[headset] Fake hs detection interrupt!!! com_detect[%d]\n",com_detect);
			det_cnt=0;
			headset_gpio_set_irq_type(hgp->irq, hgp->irq_type_active);
			return;
		}

		if(det_cnt < HEADSET_DET_RETRY_CNT){
			det_cnt++;
			mod_timer(&hgp->gpio_timer,jiffies + msecs_to_jiffies(75));
			return;
		}
		
		headset_hs_detect_mode(hgp);
		if (hgp->parent->headphone) {
			switch_set_state(&hgp->parent->sdev, BIT_HEADSET_NO_MIC);
			/* add for control of external mic bias REV0.1 - ffkaka */
			headset_mic_bias_control(0);
			pr_info("[headset] headphone plug in\n");
		} else {
			switch_set_state(&hgp->parent->sdev, BIT_HEADSET_MIC);
			pr_info("[headset] headset plug in\n");
			headset_gpio_set_irq_type(hgp->parent->button.irq, hgp->parent->button.irq_type_active);
			headset_gpio_irq_enable(1, &hgp->parent->button);
		}
	} else {
	/* Active=0 unplug case - ffkaka */
		headset_gpio_irq_enable(0, &hgp->parent->button);
		/* add for control of external mic bias REV0.1 - ffkaka */
		headset_mic_bias_control(0);
		if (hgp->parent->headphone){
			hgp->parent->headphone = 0;
			pr_info("[headset] headphone unplugged\n");
		}
		else
			pr_info("[headset] headset unplugged\n");
		switch_set_state(&hgp->parent->sdev, BIT_HEADSET_OUT);
	}

	det_cnt=0;

}
Пример #3
0
static irqreturn_t headset_gpio_irq_handler(int irq, void *dev)
{
	struct _headset_gpio *hgp = dev;
	hrtimer_cancel(&hgp->timer);
	hgp->active = hgp->active_low ^ headset_gpio_get_value(hgp->gpio);
	headset_gpio_set_irq_type(hgp->irq, hgp->active ? hgp->irq_type_inactive : hgp->irq_type_active);
	pr_debug("%s : %s %s\n", __func__, hgp->desc, hgp->active ? "active" : "inactive");
	hgp->holded = 0;
	hrtimer_start(&hgp->timer,
			ktime_set(HEADSET_GPIO_DEBOUNCE_SW_SAMPLE_PERIOD / 1000,
				(HEADSET_GPIO_DEBOUNCE_SW_SAMPLE_PERIOD % 1000) * 1000000),
			HRTIMER_MODE_REL);
	return IRQ_HANDLED;
}
Пример #4
0
static enum hrtimer_restart report_headset_detect_status(int active, struct _headset_gpio *hgp)
{
	struct regulator *mic_regulator;
	mic_regulator = regulator_get(NULL, REGU_NAME_MIC);
	int adc_value;

	if (active) {
		if (!IS_ERR(mic_regulator)) {
			regulator_set_voltage(mic_regulator, 2800000, 2800000);
			regulator_enable(mic_regulator);
		}
		mdelay(20);

		headset_hook_detect(1);
		hgp->parent->headphone = 0;
		/*hgp->parent->headphone = hgp->parent->button.active_low ^ headset_gpio_get_value(hgp->parent->button.gpio);*/
		adc_value = sci_adc_get_value(ADC_CHANNEL_TEMP, false);

		hgp->parent->headphone = adc_value > 0x05? 0 : 1;

		if (hgp->parent->headphone) {
			switch_set_state(&hgp->parent->sdev, BIT_HEADSET_NO_MIC);
			if (!IS_ERR(mic_regulator))
				regulator_disable(mic_regulator);
			pr_info("headphone plug in\n");
		} else {

			switch_set_state(&hgp->parent->sdev, BIT_HEADSET_MIC);
			pr_info("headset plug in\n");
			headset_gpio_set_irq_type(hgp->parent->button.irq, hgp->parent->button.irq_type_active);
			headset_gpio_irq_enable(1, &hgp->parent->button);
		}
	} else {
		headset_gpio_irq_enable(0, &hgp->parent->button);
		hgp->parent->button.callback(-1, &hgp->parent->button);
		headset_hook_detect(0);
		if (hgp->parent->headphone)
			pr_info("headphone plug out\n");
		else {
			if (!IS_ERR(mic_regulator))
				regulator_disable(mic_regulator);
			pr_info("headset plug out\n");
		}
		switch_set_state(&hgp->parent->sdev, BIT_HEADSET_OUT);
	}
	/* use below code only when gpio irq misses state ? */
	/* headset_gpio_set_irq_type(hgp->irq, active ? hgp->irq_type_inactive : hgp->irq_type_active); */
	return HRTIMER_NORESTART;
}