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;
}
/* add for control of external mic bias - ffkaka */
static void headset_mic_bias_control(int mode)
{

	int gpio_value;
	
	gpio_value=headset_gpio_get_value(HEADSET_MICBIAS_GPIO);

	//pr_info("[headset] before gpio_value=0x%08x \n",gpio_value);

	if(mode){
		if(gpio_value == 0x00){
			gpio_direction_output(HEADSET_MICBIAS_GPIO,1);
			pr_info("[headset] Enable Headset MIC BIAS!!!\n");
		}
		else
			pr_info("[headset] MIC BIAS was already enabled!!!\n");
		//sprd_codec_auxmic_bias_control(1);
	}
	else{
		if(gpio_value == 0x01){
			gpio_direction_output(HEADSET_MICBIAS_GPIO,0);
			pr_info("[headset] Disable Headset MIC BIAS!!!\n");
		}
		else
			pr_info("[headset] MIC BIAS was already disabled!!!\n");
		//sprd_codec_auxmic_bias_control(0);
	}
	
}
Exemplo n.º 3
0
static enum hrtimer_restart headset_gpio_timer_func(struct hrtimer *timer)
{
	enum hrtimer_restart restart = HRTIMER_RESTART;
	struct _headset_gpio *hgp =
		container_of(timer, struct _headset_gpio, timer);
	int active = hgp->active_low ^ headset_gpio_get_value(hgp->gpio); /* hgp->active */
	int green_ch = (!active && &hgp->parent->detect == hgp);
	if (active != hgp->active) {
		pr_info("The value %s mismatch [%d:%d] at %dms!\n",
				hgp->desc, active, hgp->active, hgp->holded);
		hgp->holded = 0;
	}
	pr_debug("%s : %s %s green_ch[%d], holed=%d, debounce_sw=%d\n", __func__,
			hgp->desc, active ? "active" : "inactive", green_ch, hgp->holded, hgp->debounce_sw);
	hgp->holded += HEADSET_GPIO_DEBOUNCE_SW_SAMPLE_PERIOD;
	if (hgp->holded >= hgp->debounce_sw || green_ch) {
		if (hgp->holded == hgp->debounce_sw || \
			hgp->holded == hgp->timeout_ms || \
			green_ch) {
			pr_debug("call headset gpio handler\n");
			restart = hgp->callback(active, hgp);
		} else
			pr_debug("gpio <%d> has kept active for %d ms\n", hgp->gpio, hgp->holded);
	}
	if (restart == HRTIMER_RESTART)
		hrtimer_forward_now(timer,
			ktime_set(HEADSET_GPIO_DEBOUNCE_SW_SAMPLE_PERIOD / 1000,
					(HEADSET_GPIO_DEBOUNCE_SW_SAMPLE_PERIOD % 1000) * 1000000)); /* repeat timer */
	return restart;
}
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;

}
Exemplo n.º 5
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;
}
/* gnd detect sys fs - ffkaka */
static ssize_t headset_gnd_detect_show(struct device *dev, struct device_attribute *attr,char *buf)
{
	return sprintf(buf,"GND DET= %d\n",headset_gpio_get_value(HEADSET_COM_DETECT_GPIO));
}