static void remove_h2w_35mm(void) { HS_LOG_TIME("Remove H2W 3.5mm headset"); set_35mm_hw_state(0); if (atomic_read(&hi->btn_state)) button_released(atomic_read(&hi->btn_state)); hi->h2w_35mm_type = HEADSET_UNPLUG; }
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(); 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; } set_35mm_hw_state(0); if (hi->metrico_status) enable_metrico_headset(0); if (atomic_read(&hi->btn_state)) button_released(atomic_read(&hi->btn_state)); hi->ext_35mm_status = HTC_35MM_UNPLUG; mutex_lock(&hi->mutex_lock); state = switch_get_state(&hi->sdev); if (!(state & MASK_35MM_HEADSET)) { HS_LOG("Headset has been removed"); mutex_unlock(&hi->mutex_lock); return; } #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 HS_LOG_TIME("Remove 3.5mm headset"); mutex_unlock(&hi->mutex_lock); }
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); if (hs_mgr_notifier.mic_status) mic = hs_mgr_notifier.mic_status(); 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; state |= (mic == HEADSET_MIC || mic == HEADSET_METRICO) ? BIT_HEADSET : BIT_HEADSET_NO_MIC; if (mic == HEADSET_UNKNOWN_MIC) { hi->ext_35mm_status = HTC_35MM_UNKNOWN_MIC; HS_LOG_TIME("Insert 3.5mm headset with UNKNOWN MIC"); } else if (state & BIT_HEADSET) { hi->ext_35mm_status = HTC_35MM_MIC; HS_LOG_TIME("Insert 3.5mm headset with MIC"); } else { hi->ext_35mm_status = HTC_35MM_NO_MIC; HS_LOG_TIME("Insert 3.5mm headset without MIC"); } switch_set_state(&hi->sdev, state); mutex_unlock(&hi->mutex_lock); if (mic == HEADSET_UNKNOWN_MIC) { HS_LOG("Start MIC status polling"); cancel_delayed_work_sync(&mic_detect_work); hi->mic_detect_counter = HS_DEF_MIC_DETECT_COUNT; queue_delayed_work(detect_wq, &mic_detect_work, HS_JIFFIES_MIC_DETECT); } }
static void insert_h2w_35mm(int *state) { int mic = HEADSET_NO_MIC; HS_LOG_TIME("Insert H2W 3.5mm headset"); set_35mm_hw_state(1); mic = get_mic_status(); if (mic == HEADSET_NO_MIC) { *state |= BIT_HEADSET_NO_MIC; hi->h2w_35mm_type = HEADSET_NO_MIC; HS_LOG_TIME("H2W 3.5mm without microphone"); } else { *state |= BIT_HEADSET; hi->h2w_35mm_type = HEADSET_MIC; HS_LOG_TIME("H2W 3.5mm with microphone"); } }
static void insert_h2w_35mm(int *state) { int mic = HEADSET_NO_MIC; HS_LOG_TIME("Insert H2W 3.5mm headset"); set_35mm_hw_state(1); if (hs_mgr_notifier.mic_status) mic = hs_mgr_notifier.mic_status(); if (mic == HEADSET_NO_MIC) { *state |= BIT_HEADSET_NO_MIC; hi->h2w_35mm_status = HTC_35MM_NO_MIC; HS_LOG_TIME("H2W 3.5mm without microphone"); } else { *state |= BIT_HEADSET; hi->h2w_35mm_status = HTC_35MM_MIC; HS_LOG_TIME("H2W 3.5mm with microphone"); } }
static void insert_detect_work_func(struct work_struct *work) { int state,old_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 (hi->pdata.driver_flag & DRIVER_HS_MGR_FLOAT_DET) { HS_LOG("Headset float detect enable"); if (mic == HEADSET_UNPLUG) { mutex_unlock(&hi->mutex_lock); update_mic_status(HS_DEF_MIC_DETECT_COUNT); 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_h2w); old_state = state; state &= ~MASK_35MM_HEADSET; state |= BIT_35MM_HEADSET; 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; 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: state |= BIT_HEADSET; HS_LOG_TIME("HEADSET_BEATS (UNSTABLE)"); break; case HEADSET_BEATS_SOLO: state |= BIT_HEADSET; HS_LOG_TIME("HEADSET_BEATS_SOLO (UNSTABLE)"); break; case HEADSET_INDICATOR: HS_LOG_TIME("HEADSET_INDICATOR"); break; } if (old_state != state) { if (old_state & state & MASK_35MM_HEADSET) { if (hi->pdata.driver_flag & DRIVER_HS_MGR_OLD_AJ) { state |= old_state; HS_LOG("Old audio jack found, use workaround"); } else { switch_set_state(&hi->sdev_h2w, old_state & ~MASK_35MM_HEADSET); HS_LOG("Report fake remove event"); } } hi->hs_35mm_type = mic; HS_LOG_TIME("Send uevent for state change, %d => %d", old_state, state); switch_set_state(&hi->sdev_h2w, state); } else HS_LOG("No state change"); mutex_unlock(&hi->mutex_lock); #ifdef HTC_HEADSET_CONFIG_QUICK_BOOT if (gpio_event_get_quickboot_status()) HS_LOG("quick_boot_status = 1"); #endif 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(); if (time_before_eq(jiffies, hi->insert_jiffies + HZ)) { HS_LOG("Waiting for HPIN stable"); if (hi->pdata.driver_flag & DRIVER_HS_MGR_OLD_AJ) msleep(HS_DELAY_SEC - HS_DELAY_REMOVE_LONG); else msleep(HS_DELAY_SEC - HS_DELAY_REMOVE_SHORT); } if (hi->is_ext_insert) { HS_LOG("Headset has been reinserted during debounce time"); 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)); hi->hs_35mm_type = HEADSET_UNPLUG; mutex_lock(&hi->mutex_lock); state = switch_get_state(&hi->sdev_h2w); if (!(state & MASK_35MM_HEADSET)) { HS_LOG("Headset has been removed"); mutex_unlock(&hi->mutex_lock); return; } #if 0 if (hi->cable_in1 && !gpio_get_value(hi->cable_in1)) { state &= ~BIT_35MM_HEADSET; switch_set_state(&hi->sdev_h2w, 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_h2w, state); } #else state &= ~(MASK_35MM_HEADSET | MASK_FM_ATTRIBUTE); switch_set_state(&hi->sdev_h2w, state); #endif HS_LOG_TIME("Remove 3.5mm accessory"); mutex_unlock(&hi->mutex_lock); #ifdef HTC_HEADSET_CONFIG_QUICK_BOOT if (gpio_event_get_quickboot_status()) HS_LOG("quick_boot_status = 1"); #endif }
static ssize_t headset_simulate_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long state = 0; HS_DBG(); state = MASK_35MM_HEADSET | MASK_USB_HEADSET; switch_send_event(state, 0); if (strncmp(buf, "headset_unplug", count - 1) == 0) { HS_LOG("Headset simulation: headset_unplug"); set_35mm_hw_state(0); hi->hs_35mm_type = HEADSET_UNPLUG; return count; } set_35mm_hw_state(1); state = BIT_35MM_HEADSET; if (strncmp(buf, "headset_no_mic", count - 1) == 0) { HS_LOG("Headset simulation: headset_no_mic"); hi->hs_35mm_type = HEADSET_NO_MIC; state |= BIT_HEADSET_NO_MIC; } else if (strncmp(buf, "headset_mic", count - 1) == 0) { HS_LOG("Headset simulation: headset_mic"); hi->hs_35mm_type = HEADSET_MIC; state |= BIT_HEADSET; } else if (strncmp(buf, "headset_metrico", count - 1) == 0) { HS_LOG("Headset simulation: headset_metrico"); hi->hs_35mm_type = HEADSET_METRICO; state |= BIT_HEADSET; } else if (strncmp(buf, "headset_unknown_mic", count - 1) == 0) { HS_LOG("Headset simulation: headset_unknown_mic"); hi->hs_35mm_type = HEADSET_UNKNOWN_MIC; state |= BIT_HEADSET_NO_MIC; } else if (strncmp(buf, "headset_tv_out", count - 1) == 0) { HS_LOG("Headset simulation: headset_tv_out"); hi->hs_35mm_type = HEADSET_TV_OUT; state |= BIT_TV_OUT; #if defined(CONFIG_FB_MSM_TVOUT) && defined(CONFIG_ARCH_MSM8X60) tvout_enable_detection(1); #endif } else if (strncmp(buf, "headset_indicator", count - 1) == 0) { HS_LOG("Headset simulation: headset_indicator"); hi->hs_35mm_type = HEADSET_INDICATOR; } else if (strncmp(buf, "headset_beats", count - 1) == 0) { HS_LOG("Headset simulation: headset_beats"); hi->hs_35mm_type = HEADSET_BEATS; state |= BIT_HEADSET; } else if (strncmp(buf, "headset_beats_solo", count - 1) == 0) { HS_LOG("Headset simulation: headset_beats_solo"); hi->hs_35mm_type = HEADSET_BEATS_SOLO; state |= BIT_HEADSET; } else { HS_LOG("Invalid parameter"); return count; } switch_send_event(state, 1); return count; }
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_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; 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: state |= BIT_HEADSET; HS_LOG_TIME("HEADSET_METRICO"); 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: state |= BIT_HEADSET; HS_LOG_TIME("HEADSET_BEATS"); break; case HEADSET_INDICATOR: HS_LOG_TIME("HEADSET_INDICATOR"); break; } hi->hs_35mm_type = mic; switch_set_state(&hi->sdev, state); mutex_unlock(&hi->mutex_lock); if (mic == HEADSET_UNKNOWN_MIC) update_mic_status(HS_DEF_MIC_DETECT_COUNT); 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 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"); */ }
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); if (hs_mgr_notifier.mic_status) mic = hs_mgr_notifier.mic_status(); 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; switch (mic) { case HEADSET_TV_OUT: state |= BIT_TV_OUT; break; case HEADSET_METRICO: case HEADSET_MIC: state |= BIT_HEADSET; break; default: state |= BIT_HEADSET_NO_MIC; } if (mic == HEADSET_UNKNOWN_MIC) { hi->ext_35mm_status = HTC_35MM_UNKNOWN_MIC; HS_LOG_TIME("Insert 3.5mm headset with UNKNOWN MIC"); #if defined(CONFIG_FB_MSM_TVOUT) && defined(CONFIG_ARCH_MSM8X60) } else if (mic == HEADSET_TV_OUT) { hi->ext_35mm_status = HTC_35MM_TV_OUT; HS_LOG_TIME("Insert 3.5mm TV OUT cable"); tvout_enable_detection(1); #endif } else if (state & BIT_HEADSET) { hi->ext_35mm_status = HTC_35MM_MIC; HS_LOG_TIME("Insert 3.5mm headset with MIC"); } else { hi->ext_35mm_status = HTC_35MM_NO_MIC; HS_LOG_TIME("Insert 3.5mm headset without MIC"); } switch_set_state(&hi->sdev, state); mutex_unlock(&hi->mutex_lock); if (mic == HEADSET_UNKNOWN_MIC) { HS_LOG("Start MIC status polling"); cancel_delayed_work_sync(&mic_detect_work); hi->mic_detect_counter = HS_DEF_MIC_DETECT_COUNT; queue_delayed_work(detect_wq, &mic_detect_work, HS_JIFFIES_MIC_DETECT); } }
static void insert_detect_work_func(struct work_struct *work) { int state,old_state; int mic = HEADSET_NO_MIC; int adc = 0; 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; } HS_LOG("Start 1-wire detecting sequence"); if (hi->pdata.uart_tx_gpo) hi->pdata.uart_tx_gpo(0); if (hi->pdata.uart_lv_shift_en) hi->pdata.uart_lv_shift_en(0); msleep(20); if (hi->pdata.uart_lv_shift_en) hi->pdata.uart_lv_shift_en(1); if (hi->pdata.uart_tx_gpo) hi->pdata.uart_tx_gpo(2); hi->insert_jiffies = jiffies; set_35mm_hw_state(1); msleep(150); if (hs_mgr_notifier.remote_adc) hs_mgr_notifier.remote_adc(&adc); mutex_lock(&hi->mutex_lock); hi->one_wire_mode = 0; /*Check one wire accessory for every plug event*/ if (hi->driver_one_wire_exist && adc > 915) { HS_LOG("[HS_1wire]1wire driver exists, starting init"); if (hs_mgr_notifier.key_int_enable) hs_mgr_notifier.key_int_enable(0); if (hs_mgr_notifier.hs_1wire_init() == 0) { hi->one_wire_mode = 1; /*Report as normal headset with MIC*/ state = switch_get_state(&hi->sdev_h2w); state |= BIT_HEADSET; switch_set_state(&hi->sdev_h2w, state); hi->hs_35mm_type = HEADSET_BEATS; mutex_unlock(&hi->mutex_lock); if (hs_mgr_notifier.key_int_enable) hs_mgr_notifier.key_int_enable(1); return; } else { hi->one_wire_mode = 0; HS_LOG("Lagacy mode"); if (hi->pdata.uart_tx_gpo) hi->pdata.uart_tx_gpo(2); if (hs_mgr_notifier.key_int_enable) hs_mgr_notifier.key_int_enable(1); } } mic = get_mic_status(); if (hi->pdata.driver_flag & DRIVER_HS_MGR_FLOAT_DET) { HS_LOG("Headset float detect enable"); if (mic == HEADSET_UNPLUG) { mutex_unlock(&hi->mutex_lock); update_mic_status(HS_DEF_MIC_DETECT_COUNT); 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_h2w); old_state = state; state &= ~MASK_35MM_HEADSET; state |= BIT_35MM_HEADSET; 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; 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: state |= BIT_HEADSET; HS_LOG_TIME("HEADSET_BEATS (UNSTABLE)"); break; case HEADSET_BEATS_SOLO: state |= BIT_HEADSET; HS_LOG_TIME("HEADSET_BEATS_SOLO (UNSTABLE)"); break; case HEADSET_INDICATOR: HS_LOG_TIME("HEADSET_INDICATOR"); break; } if (old_state != state) { if (old_state & state & MASK_35MM_HEADSET) { if (hi->pdata.driver_flag & DRIVER_HS_MGR_OLD_AJ) { state |= old_state; HS_LOG("Old audio jack found, use workaround"); } else { switch_set_state(&hi->sdev_h2w, old_state & ~MASK_35MM_HEADSET); HS_LOG("Report fake remove event"); } } hi->hs_35mm_type = mic; HS_LOG_TIME("Send uevent for state change, %d => %d", old_state, state); switch_set_state(&hi->sdev_h2w, state); hpin_report++; } else HS_LOG("No state change"); mutex_unlock(&hi->mutex_lock); #ifdef HTC_HEADSET_CONFIG_QUICK_BOOT if (gpio_event_get_quickboot_status()) HS_LOG("quick_boot_status = 1"); #endif 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"); } }