void hi6402_jack_report(struct hi6402_mbhc_platform_data *pdata) { enum hisi_jack_states jack_status = pdata->hs_status; int jack_report = 0; switch(pdata->hs_status) { case HISI_JACK_NONE: jack_report = 0; pr_info("%s : plug out\n", __FUNCTION__); break; case HISI_JACK_HEADSET: jack_report = SND_JACK_HEADSET; pr_info("%s : 4-pole headset plug in\n", __FUNCTION__); break; case HISI_JACK_INVERT: jack_report = SND_JACK_HEADPHONE; pr_info("%s : invert headset plug in\n", __FUNCTION__); break; case HISI_JACK_HEADPHONE: jack_report = SND_JACK_HEADPHONE; pr_info("%s : 3-pole headphone plug in\n", __FUNCTION__); break; default: pr_err("%s : error hs_status(%d)\n", __FUNCTION__, pdata->hs_status); break; } /* clear btn event */ hi6402_soc_jack_report(0, HI6402_BTN_MASK); /* btn_report jack status */ hi6402_soc_jack_report(jack_report, SND_JACK_HEADSET); #ifdef CONFIG_SWITCH switch_set_state(&pdata->sdev, jack_status); #endif }
static irqreturn_t hi6402_btnup_eco_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)) return IRQ_HANDLED; wake_lock_timeout(&pdata->wake_lock, 100); if (HISI_JACK_INVERT == pdata->hs_status) { pr_err("%s: further detect\n", __FUNCTION__); /* further detect */ hi6402_plug_in_detect(pdata); } else if (0 == pdata->btn_report){ if (HISI_JACK_HEADSET != pdata->hs_status) { /* further detect */ hi6402_plug_in_detect(pdata); } return IRQ_HANDLED; } else { mutex_lock(&pdata->status_mutex); pdata->btn_report = 0; hi6402_soc_jack_report(pdata->btn_report, HI6402_BTN_MASK); mutex_unlock(&pdata->status_mutex); pr_info("%s(%u) : btn up !\n", __FUNCTION__, __LINE__); } return IRQ_HANDLED; }
void hi6402_btnup_workfunc(struct work_struct *work) { struct hi6402_mbhc_platform_data *pdata = container_of(work, struct hi6402_mbhc_platform_data, headset_btn_up_delay_work.work); BUG_ON(NULL == pdata); pr_info("%s(%u) : btn up !\n", __FUNCTION__, __LINE__); pdata->btn_report = 0; hi6402_soc_jack_report(pdata->btn_report, HI6402_BTN_MASK); /* mask btn up interrupt*/ mask_irq(pdata->irq[HI6402_IRQ_BTNUP_COMP1], true); /* unmask btn down interrupt*/ mask_irq(pdata->irq[HI6402_IRQ_BTNDOWN_COMP1], false); return; }
void hi6402_btn_down(struct hi6402_mbhc_platform_data *pdata) { int saradc_value = 0; if (!check_headset_pluged_in(pdata)) { pr_info("%s(%u) : hs pluged out \n", __FUNCTION__, __LINE__); return; } wake_lock(&pdata->wake_lock); if (HISI_JACK_HEADSET == pdata->hs_status) { /* micbias on */ hi6402_irq_micbias_mbhc_enable(pdata->p_irq, true); /* auto read */ saradc_value = hi6402_read_saradc_value_detect(pdata); /* micbias off */ hi6402_irq_micbias_mbhc_enable(pdata->p_irq, false); msleep(30); if (!check_headset_pluged_in(pdata)) { pr_info("%s(%u) : hs pluged out \n", __FUNCTION__, __LINE__); goto end; } if ((saradc_value >= pdata->hs_4_pole_min_voltage) && (saradc_value <= pdata->hs_4_pole_max_voltage)) { pr_info("%s(%u) : process as btn up! \n", __FUNCTION__, __LINE__); mutex_lock(&pdata->status_mutex); pdata->btn_report = 0; mutex_unlock(&pdata->status_mutex); } else if ((saradc_value >= pdata->btn_play_min_voltage) && (saradc_value <= pdata->btn_play_max_voltage)) { mutex_lock(&pdata->status_mutex); pdata->btn_report = SND_JACK_BTN_0; mutex_unlock(&pdata->status_mutex); } else if (pdata->btn_volume_up_min_voltage < saradc_value && saradc_value <= pdata->btn_volume_up_max_voltage) { mutex_lock(&pdata->status_mutex); pdata->btn_report = SND_JACK_BTN_1; mutex_unlock(&pdata->status_mutex); } else if (pdata->btn_volume_down_min_voltage < saradc_value && saradc_value <= pdata->btn_volume_down_max_voltage) { mutex_lock(&pdata->status_mutex); pdata->btn_report = SND_JACK_BTN_2; mutex_unlock(&pdata->status_mutex); } else { msleep(30); hi6402_plug_in_detect(pdata); goto end; } if (!check_headset_pluged_in(pdata)) { pr_info("%s(%u) : hs pluged out \n", __FUNCTION__, __LINE__); goto end; } /*btn_report key event*/ pr_info("%s(%u): btn_report type = 0x%x, status=0x%x\n", __FUNCTION__, __LINE__, pdata->btn_report, pdata->hs_status); hi6402_soc_jack_report(pdata->btn_report, HI6402_BTN_MASK); } end: wake_unlock(&pdata->wake_lock); return; }
void hi6402_btndown_workfunc(struct work_struct *work) { int saradc_value = 0; struct hi6402_mbhc_platform_data *pdata = container_of(work, struct hi6402_mbhc_platform_data, headset_btn_down_delay_work.work); BUG_ON(NULL == pdata); if (!check_headset_pluged_in(pdata)) { pr_info("%s(%u) : hs pluged out \n", __FUNCTION__, __LINE__); return; } pr_info("%s(%u) : btn down !\n", __FUNCTION__, __LINE__); wake_lock(&pdata->wake_lock); if (HISI_JACK_HEADSET == pdata->hs_status) { /* power on hs-micbias */ //hi6401_hs_micbias_saradc_enable(codec, true); //saradc_value = hi6401_read_saradc_value(codec); //pr_info("%s(%u) :saradc_value: %d \n", __FUNCTION__, __LINE__, saradc_value); //hi6401_hs_micbias_saradc_enable(codec, false); if (!check_headset_pluged_in(pdata)) { pr_info("%s(%u) : hs pluged out \n", __FUNCTION__, __LINE__); /* mask all btn interrupt*/ mask_irq(pdata->irq[HI6402_IRQ_BTNUP_COMP1], true); mask_irq(pdata->irq[HI6402_IRQ_BTNDOWN_COMP1], true); goto end; } if ((saradc_value >= pdata->hs_4_pole_min_voltage) && (saradc_value <= pdata->hs_4_pole_max_voltage)) { pr_info("%s(%u) : process as btn up! \n", __FUNCTION__, __LINE__); mutex_lock(&pdata->status_mutex); pdata->btn_report = 0; mutex_unlock(&pdata->status_mutex); } else if ((saradc_value >= pdata->btn_play_min_voltage) && (saradc_value <= pdata->btn_play_max_voltage)) { mutex_lock(&pdata->status_mutex); pdata->btn_report = SND_JACK_BTN_0; mutex_unlock(&pdata->status_mutex); } else if (pdata->btn_volume_up_min_voltage < saradc_value && saradc_value <= pdata->btn_volume_up_max_voltage) { mutex_lock(&pdata->status_mutex); pdata->btn_report = SND_JACK_BTN_1; mutex_unlock(&pdata->status_mutex); } else if (pdata->btn_volume_down_min_voltage < saradc_value && saradc_value <= pdata->btn_volume_down_max_voltage) { mutex_lock(&pdata->status_mutex); pdata->btn_report = SND_JACK_BTN_2; mutex_unlock(&pdata->status_mutex); } else { msleep(30); hi6402_plug_in_detect(pdata); goto end; } if (!check_headset_pluged_in(pdata)) { pr_info("%s(%u) : hs pluged out \n", __FUNCTION__, __LINE__); /* mask all btn interrupt*/ mask_irq(pdata->irq[HI6402_IRQ_BTNUP_COMP1], true); mask_irq(pdata->irq[HI6402_IRQ_BTNDOWN_COMP1], true); goto end; } /*btn_report key event*/ pr_info("%s(%u): btn_report type = 0x%x, status=0x%x\n", __FUNCTION__, __LINE__, pdata->btn_report, pdata->hs_status); hi6402_soc_jack_report(pdata->btn_report, HI6402_BTN_MASK); } /* mask btn down interrupt*/ mask_irq(pdata->irq[HI6402_IRQ_BTNDOWN_COMP1], true); /* unmask btn up interrupt*/ mask_irq(pdata->irq[HI6402_IRQ_BTNUP_COMP1], false); end: wake_unlock(&pdata->wake_lock); return; }