void hi6402_plug_out_workfunc(struct work_struct *work) { struct hi6402_mbhc_platform_data *pdata = container_of(work, struct hi6402_mbhc_platform_data, headset_plug_out_delay_work.work); pr_info("%s : hs pluged out\n", __FUNCTION__); BUG_ON(NULL == pdata); wake_lock(&pdata->wake_lock); mutex_lock(&pdata->plug_mutex); mask_irq(pdata->irq[HI6402_IRQ_BTNDOWN_COMP1], true); mask_irq(pdata->irq[HI6402_IRQ_BTNUP_COMP1], true); mask_irq(pdata->irq[HI6402_IRQ_BTNDOWN_ECO], true); /* todo */ hi6402_reg_clr_bit(pdata->p_irq, HI6402_MICBIAS_ECO_REG, 0); hi6402_reg_set_bit(pdata->p_irq, HI6402_MBHC_VREF_REG, 7); mutex_lock(&pdata->status_mutex); pdata->hs_status = HISI_JACK_NONE; pdata->btn_report = 0; mutex_unlock(&pdata->status_mutex); hi6402_jack_report(pdata); mutex_unlock(&pdata->plug_mutex); wake_unlock(&pdata->wake_lock); /* unmask plugin interrupt */ mask_irq(pdata->irq[HI6402_IRQ_PLUGIN], false); }
void hi6402_plug_in_detect(struct hi6402_mbhc_platform_data *pdata) { if (!check_headset_pluged_in(pdata)) return; wake_lock(&pdata->wake_lock); mutex_lock(&pdata->plug_mutex); mutex_lock(&pdata->status_mutex); /* todo : btn_report 4-pole headset only now */ pdata->hs_status = HISI_JACK_HEADSET; pdata->btn_report = SND_JACK_HEADSET; mutex_unlock(&pdata->status_mutex); hi6402_jack_report(pdata); /* todo */ hi6402_reg_clr_bit(pdata->p_irq, HI6402_MBHC_VREF_REG, 7); hi6402_reg_set_bit(pdata->p_irq, HI6402_MICBIAS_ECO_REG, 0); /* unmask btn down irq */ mask_irq(pdata->irq[HI6402_IRQ_BTNDOWN_COMP1], false); mask_irq(pdata->irq[HI6402_IRQ_BTNDOWN_ECO], false); mutex_unlock(&pdata->plug_mutex); wake_unlock(&pdata->wake_lock); }
static irqreturn_t hi6402_plugout_handler(int irq, void *data) { struct hi6402_mbhc_platform_data *pdata = (struct hi6402_mbhc_platform_data *)data; BUG_ON(NULL == pdata); if (check_headset_pluged_in(pdata)) { pr_info("%s : hs still plugin \n", __FUNCTION__); return IRQ_HANDLED; } mutex_lock(&pdata->plug_mutex); hi6402_irq_cancel_delay_work(pdata->p_irq); hi6402_irq_mask_btn_irqs(pdata->p_irq); //stop charge first anc_hs_stop_charge(); /* eco off */ hi6402_reg_clr_bit(pdata->p_irq, HI6402_MICBIAS_ECO_REG, HI6402_MICBIAS_ECO_ON_BIT); mutex_lock(&pdata->p_irq->hs_micbias_mutex); /* hs micbias off */ pdata->p_irq->mbhc_micbias_work = false; pdata->p_irq->dapm_micbias_work = false; mutex_unlock(&pdata->p_irq->hs_micbias_mutex); hi6402_irq_hs_micbias_enable(pdata->p_irq, false); hi6402_irq_clr_btn_irqs(pdata->p_irq); hi6402_irq_mask_btn_irqs(pdata->p_irq); /* eco off */ hi6402_reg_clr_bit(pdata->p_irq, HI6402_MICBIAS_ECO_REG, HI6402_MICBIAS_ECO_ON_BIT); pr_info("%s : eco disable \n", __FUNCTION__); /* vref off */ hi6402_reg_set_bit(pdata->p_irq, HI6402_MBHC_VREF_REG, HI6402_MBHC_VREF_BIT); /* mbhc cmp off */ hi6402_reg_set_bit(pdata->p_irq, HI6402_ANA_REG60, HI6402_MBHC_ON_BIT); mutex_lock(&pdata->status_mutex); pdata->hs_status = HISI_JACK_NONE; pdata->btn_report = 0; mutex_unlock(&pdata->status_mutex); hi6402_jack_report(pdata); hi6402_mbhc_enable_ldo8(pdata, false); mutex_unlock(&pdata->plug_mutex); return IRQ_HANDLED; }
void hi6402_plug_in_detect(struct hi6402_mbhc_platform_data *pdata) { int saradc_value = 0; int anc_type = ANC_HS_REVERT_4POLE; if (!check_headset_pluged_in(pdata)) return; wake_lock(&pdata->wake_lock); mutex_lock(&pdata->plug_mutex); if(check_anc_hs_support()) { //mask btn irqs while control boost hi6402_irq_mask_btn_irqs(pdata->p_irq); anc_hs_start_charge(); } /* micbias on */ hi6402_irq_micbias_mbhc_enable(pdata->p_irq, true); /* mbhc on (normal not auto) */ hi6402_mbhc_on(pdata); /* read hs value */ saradc_value = hi6402_read_saradc_value_detect(pdata); mutex_lock(&pdata->status_mutex); if (pdata->hs_3_pole_max_voltage >= saradc_value) { /* 3-pole headphone */ pr_info("%s : 3 pole is pluged in\n", __FUNCTION__); pdata->hs_status = HISI_JACK_HEADPHONE; anc_type = ANC_HS_3POLE; } else if (pdata->hs_4_pole_min_voltage <= saradc_value && pdata->hs_4_pole_max_voltage >= saradc_value) { /* 4-pole headset */ pr_info("%s : 4 pole is pluged in\n", __FUNCTION__); pdata->hs_status = HISI_JACK_HEADSET; anc_type = ANC_HS_4POLE; } else { /* invert 4-pole headset */ pr_info("%s : need further detect, report as 3-pole headphone\n", __FUNCTION__); pdata->hs_status = HISI_JACK_INVERT; anc_type = ANC_HS_REVERT_4POLE; } mutex_unlock(&pdata->status_mutex); if(check_anc_hs_support()) { //mask btn irqs while control boost hi6402_irq_mask_btn_irqs(pdata->p_irq); anc_hs_charge_detect(saradc_value, anc_type); } hi6402_jack_report(pdata); hi6402_mbhc_enable_ldo8(pdata, true); /* micbias off */ hi6402_irq_micbias_mbhc_enable(pdata->p_irq, false); mutex_unlock(&pdata->plug_mutex); wake_unlock(&pdata->wake_lock); }