static void detect_gpio_work_func(struct work_struct *work) { int insert = 0; int ret = 0; HS_DBG(); if ((hi->pdata.eng_cfg == HS_EDE_U) || (hi->pdata.eng_cfg == HS_EDE_TD) || (hi->pdata.eng_cfg == HS_BLE)) { aic3008_set_mic_bias(1); } if ((hi->pdata.eng_cfg == HS_QUO_F_U)) { regulator = regulator_get(NULL, "v_aud_2v85"); if (IS_ERR_OR_NULL(regulator)) { pr_err("htc_headset_gpio_probe:Couldn't get regulator v_aud_2v85\n"); regulator = NULL; return; } regulator_enable(regulator); } insert = gpio_get_value(hi->pdata.hpin_gpio) ? 0 : 1; if (hi->headset_state == insert) return; hi->headset_state = insert; hs_notify_plug_event(insert); if (hi->pdata.key_gpio){ if(!hi->key_irq){ ret = gpio_to_irq(hi->pdata.key_gpio); if (ret < 0) HS_ERR("gpio_to_irq"); hi->key_irq = (unsigned int) ret; ret = request_irq(hi->key_irq, button_irq_handler, hi->key_irq_type, "HS_GPIO_BUTTON", NULL); if (ret < 0) HS_ERR("request irq error;"); disable_irq_nosync(hi->key_irq); } if (hi->key_irq){ if (hi->headset_state == 1){ ret = irq_set_irq_wake(hi->key_irq, 1); if (ret < 0) HS_ERR("set irq wake error"); enable_irq(hi->key_irq); }else{ ret = irq_set_irq_wake(hi->key_irq, 0); if (ret < 0) HS_ERR("set irq wake error"); disable_irq_nosync(hi->key_irq); } } } }
static void insert_detect_work_func(struct work_struct *work) { int state; int mic = HEADSET_NO_MIC; wake_lock_timeout(&hi->hs_wake_lock, HS_WAKE_LOCK_TIMEOUT); HS_DBG(); if (!hi->is_ext_insert) { HS_LOG("Headset has been removed"); return; } hi->insert_jiffies = jiffies; set_35mm_hw_state(1); mutex_lock(&hi->mutex_lock); mic = get_mic_status(); if(mic == HEADSET_UNPLUG){ mdelay(1000); mic = get_mic_status(); if(mic == HEADSET_UNPLUG){ HS_LOG("Headset unplug."); hi->hs_35mm_type = mic; mutex_unlock(&hi->mutex_lock); if ((hi->pdata.eng_cfg == HS_EDE_U) || (hi->pdata.eng_cfg == HS_EDE_TD) || (hi->pdata.eng_cfg == HS_BLE)){ aic3008_set_mic_bias(0); } if ((hi->pdata.eng_cfg == HS_QUO_F_U)){ regulator = regulator_get(NULL, "v_aud_2v85"); if (IS_ERR_OR_NULL(regulator)) { pr_err("htc_headset_gpio_probe:Couldn't get regulator v_aud_2v85\n"); regulator = NULL; return; } regulator_disable(regulator); } return; } } if (mic == HEADSET_NO_MIC) mic = tv_out_detect(); if (mic == HEADSET_TV_OUT && hi->pdata.hptv_sel_gpio) gpio_set_value(hi->pdata.hptv_sel_gpio, 1); if (mic == HEADSET_METRICO && !hi->metrico_status) enable_metrico_headset(1); state = switch_get_state(&hi->sdev); state &= ~MASK_35MM_HEADSET; state |= BIT_35MM_HEADSET; /*run one-wire detect work function if one-wire detection is enable*/ if (hi->pdata.enable_1wire) { int wire = 0; wire = insert_1wire_work_func(); if (wire > 0) { HS_LOG("Enable one-wire detection"); mic = wire; } } switch (mic) { case HEADSET_NO_MIC: state |= BIT_HEADSET_NO_MIC; HS_LOG_TIME("HEADSET_NO_MIC"); break; case HEADSET_MIC: state |= BIT_HEADSET; HS_LOG_TIME("HEADSET_MIC"); break; case HEADSET_METRICO: mic = HEADSET_UNSTABLE; state |= BIT_HEADSET; HS_LOG_TIME("HEADSET_METRICO (UNSTABLE)"); break; case HEADSET_UNKNOWN_MIC: state |= BIT_HEADSET_NO_MIC; HS_LOG_TIME("HEADSET_UNKNOWN_MIC"); break; case HEADSET_TV_OUT: state |= BIT_TV_OUT; HS_LOG_TIME("HEADSET_TV_OUT"); #if defined(CONFIG_FB_MSM_TVOUT) && defined(CONFIG_ARCH_MSM8X60) tvout_enable_detection(1); #endif break; case HEADSET_BEATS: // mic = HEADSET_UNSTABLE; state |= BIT_HEADSET; HS_LOG_TIME("HEADSET_BEATS (UNSTABLE)"); break; case HEADSET_BEATS_SOLO: // mic = HEADSET_UNSTABLE; state |= BIT_HEADSET; HS_LOG_TIME("HEADSET_BEATS_SOLO (UNSTABLE)"); break; case HEADSET_INDICATOR: HS_LOG_TIME("HEADSET_INDICATOR"); break; } hi->hs_35mm_type = mic; switch_set_state(&hi->sdev, state); hpin_report++; mutex_unlock(&hi->mutex_lock); /* FIXME */ /* if (gpio_event_get_quickboot_status()) HS_LOG("quick_boot_status = 1"); */ if (mic == HEADSET_UNKNOWN_MIC) update_mic_status(HS_DEF_MIC_DETECT_COUNT); else if (mic == HEADSET_UNSTABLE) update_mic_status(0); else if (mic == HEADSET_INDICATOR) { if (headset_get_type_sync(3, HS_DELAY_SEC) == HEADSET_INDICATOR) HS_LOG("Delay check: HEADSET_INDICATOR"); else HS_LOG("Delay check: HEADSET_UNKNOWN_MIC"); } }
static void remove_detect_work_func(struct work_struct *work) { int state; wake_lock_timeout(&hi->hs_wake_lock, HS_WAKE_LOCK_TIMEOUT); HS_DBG(); /*remove one-wire detection setting if the project support one-wire detection*/ if(hi->detect_type == HEADSET_1WIRE && hi->pdata.enable_1wire){ HS_LOG("Disable one-wire detection."); closeFile(fp); disable_1wire(); hi->detect_type = HEADSET_ADC; } if (time_before_eq(jiffies, hi->insert_jiffies + HZ)) { HS_LOG("Waiting for HPIN stable"); msleep(HS_DELAY_SEC - HS_DELAY_REMOVE); } if (hi->is_ext_insert) { HS_LOG("Headset has been inserted"); return; } if (hi->hs_35mm_type == HEADSET_INDICATOR && hs_mgr_notifier.indicator_enable) hs_mgr_notifier.indicator_enable(0); set_35mm_hw_state(0); #if defined(CONFIG_FB_MSM_TVOUT) && defined(CONFIG_ARCH_MSM8X60) if (hi->hs_35mm_type == HEADSET_TV_OUT && hi->pdata.hptv_sel_gpio) { HS_LOG_TIME("Remove 3.5mm TVOUT cable"); tvout_enable_detection(0); gpio_set_value(hi->pdata.hptv_sel_gpio, 0); } #endif if (hi->metrico_status) enable_metrico_headset(0); if (atomic_read(&hi->btn_state)) button_released(atomic_read(&hi->btn_state)); mutex_lock(&hi->mutex_lock); state = switch_get_state(&hi->sdev); if (!(state & MASK_35MM_HEADSET)||hi->hs_35mm_type == HEADSET_UNPLUG) { HS_LOG("Headset has been removed"); mutex_unlock(&hi->mutex_lock); return; } hi->hs_35mm_type = HEADSET_UNPLUG; #if 0 if (hi->cable_in1 && !gpio_get_value(hi->cable_in1)) { state &= ~BIT_35MM_HEADSET; switch_set_state(&hi->sdev, state); queue_delayed_work(detect_wq, &detect_h2w_work, HS_DELAY_ZERO_JIFFIES); } else { state &= ~(MASK_35MM_HEADSET | MASK_FM_ATTRIBUTE); switch_set_state(&hi->sdev, state); } #else state &= ~(MASK_35MM_HEADSET | MASK_FM_ATTRIBUTE); switch_set_state(&hi->sdev, state); #endif hpin_report++; HS_LOG_TIME("Remove 3.5mm accessory"); mutex_unlock(&hi->mutex_lock); if ((hi->pdata.eng_cfg == HS_EDE_U) || (hi->pdata.eng_cfg == HS_EDE_TD) || (hi->pdata.eng_cfg == HS_BLE)) { aic3008_set_mic_bias(0); } if ((hi->pdata.eng_cfg == HS_QUO_F_U)) { regulator = regulator_get(NULL, "v_aud_2v85"); if (IS_ERR_OR_NULL(regulator)) { pr_err("htc_headset_gpio_probe:Couldn't get regulator v_aud_2v85\n"); regulator = NULL; return; } regulator_disable(regulator); } /* FIXME */ /* if (gpio_event_get_quickboot_status()) HS_LOG("quick_boot_status = 1"); */ }