Пример #1
0
/*
 * The pm8058_nc_ir detects insert / remove of the headset (for NO and NC),
 * as well as button press / release (for NC type).
 * The current state of the headset is maintained in othc_ir_state variable.
 */
static irqreturn_t pm8058_nc_ir(int irq, void *dev_id)
{
	struct pm8058_othc *dd = dev_id;
	struct othc_hsed_config *hsed_config = dd->othc_pdata->hsed_config;

	if (hsed_config->othc_headset == OTHC_HEADSET_NC)
		othc_process_nc(dd);
	else {
		/* disable irq, this gets enabled in the workqueue */
		disable_irq_nosync(dd->othc_irq_ir);
		/* Processing for NO type headset */
		if (dd->othc_ir_state == false) {
			/*  headset jack inserted */
			dd->othc_ir_state = true;
			pm8058_headset_switch(dd->othc_ipd,
					SW_HEADPHONE_INSERT, 1);
		} else {
			/* headset jack removed */
			dd->othc_ir_state = false;
			pm8058_headset_switch(dd->othc_ipd,
					SW_HEADPHONE_INSERT, 0);
		}
	}
	input_sync(dd->othc_ipd);

	return IRQ_HANDLED;
}
Пример #2
0
/*
 * The pm8058_nc_ir detects insert / remove of the headset (for NO and NC),
 * as well as button press / release (for NC type).
 * The current state of the headset is maintained in othc_ir_state variable.
 * Due to a hardware bug, false switch interrupts are seen during headset
 * insert. This is handled in the software by rejecting the switch interrupts
 * for a small period of time after the headset has been inserted.
 */
static irqreturn_t pm8058_nc_ir(int irq, void *dev_id)
{
	unsigned long flags;
	struct pm8058_othc *dd = dev_id;
	struct othc_hsed_config *hsed_config = dd->othc_pdata->hsed_config;

	spin_lock_irqsave(&dd->lock, flags);
	/* Enable the switch reject flag */
	dd->switch_reject = true;
	spin_unlock_irqrestore(&dd->lock, flags);

	/* Start the HR timer if one is not active */
	if (hrtimer_active(&dd->timer))
		hrtimer_cancel(&dd->timer);

	hrtimer_start(&dd->timer,
		ktime_set((dd->switch_debounce_ms / 1000),
		(dd->switch_debounce_ms % 1000) * 1000000), HRTIMER_MODE_REL);

	if (hsed_config->othc_headset == OTHC_HEADSET_NC)
		othc_process_nc(dd);
	else {
		/* disable irq, this gets enabled in the workqueue */
		disable_irq_nosync(dd->othc_irq_ir);
		/* Processing for NO type headset */
		if (dd->othc_ir_state == false) {
			/*  headset jack inserted */
			dd->othc_ir_state = true;
			pm8058_headset_switch(dd->othc_ipd,
					SW_HEADPHONE_INSERT, 1);
		} else {
			/* headset jack removed */
			dd->othc_ir_state = false;
			pm8058_headset_switch(dd->othc_ipd,
					SW_HEADPHONE_INSERT, 0);
		}
	}
	input_sync(dd->othc_ipd);

	return IRQ_HANDLED;
}