/* * 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; }
/* * 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; }