Lines Matching +full:- +full:75 +full:mv
1 // SPDX-License-Identifier: GPL-2.0-only
2 // Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
14 #include "wcd-mbhc-v2.h"
24 #define WCD_MBHC_ADC_HPH_THRESHOLD_MV 75
72 /* Holds type of Headset - Mono/Stereo */
74 /* Holds mbhc detection method - ADC/Legacy */
81 if (!mbhc->fields[field].reg) in wcd_mbhc_write_field()
84 return snd_soc_component_write_field(mbhc->component, in wcd_mbhc_write_field()
85 mbhc->fields[field].reg, in wcd_mbhc_write_field()
86 mbhc->fields[field].mask, val); in wcd_mbhc_write_field()
91 if (!mbhc->fields[field].reg) in wcd_mbhc_read_field()
94 return snd_soc_component_read_field(mbhc->component, in wcd_mbhc_read_field()
95 mbhc->fields[field].reg, in wcd_mbhc_read_field()
96 mbhc->fields[field].mask); in wcd_mbhc_read_field()
101 u32 reg_val = ((mbhc->cfg->v_hs_max - HS_VREF_MIN_VAL) / 100); in wcd_program_hs_vref()
108 struct snd_soc_component *component = mbhc->component; in wcd_program_btn_threshold()
110 mbhc->mbhc_cb->set_btn_thr(component, mbhc->cfg->btn_low, in wcd_program_btn_threshold()
111 mbhc->cfg->btn_high, in wcd_program_btn_threshold()
112 mbhc->cfg->num_btn, micbias); in wcd_program_btn_threshold()
125 if (mbhc->mbhc_cb->mbhc_micbias_control) in wcd_mbhc_curr_micbias_control()
156 dev_err(mbhc->dev, "%s: Invalid parameter", __func__); in wcd_mbhc_curr_micbias_control()
170 component = mbhc->component; in wcd_mbhc_event_notify()
172 if (mbhc->mbhc_cb->micbias_enable_status) in wcd_mbhc_event_notify()
173 micbias2 = mbhc->mbhc_cb->micbias_enable_status(component, MIC_BIAS_2); in wcd_mbhc_event_notify()
178 mbhc->is_hs_recording = true; in wcd_mbhc_event_notify()
182 if (mbhc->mbhc_cb->mbhc_micbias_control) { in wcd_mbhc_event_notify()
186 mbhc->is_hs_recording = true; in wcd_mbhc_event_notify()
196 if (mbhc->mbhc_cb->mbhc_micbias_control/* && !mbhc->micbias_enable*/) { in wcd_mbhc_event_notify()
203 mbhc->is_hs_recording = false; in wcd_mbhc_event_notify()
206 if (!mbhc->mbhc_cb->mbhc_micbias_control) in wcd_mbhc_event_notify()
207 mbhc->is_hs_recording = false; in wcd_mbhc_event_notify()
210 if ((test_bit(WCD_MBHC_EVENT_PA_HPHL, &mbhc->event_state)) || in wcd_mbhc_event_notify()
211 (test_bit(WCD_MBHC_EVENT_PA_HPHR, &mbhc->event_state))) in wcd_mbhc_event_notify()
220 clear_bit(WCD_MBHC_EVENT_PA_HPHL, &mbhc->event_state); in wcd_mbhc_event_notify()
231 clear_bit(WCD_MBHC_EVENT_PA_HPHR, &mbhc->event_state); in wcd_mbhc_event_notify()
241 set_bit(WCD_MBHC_EVENT_PA_HPHL, &mbhc->event_state); in wcd_mbhc_event_notify()
251 set_bit(WCD_MBHC_EVENT_PA_HPHR, &mbhc->event_state); in wcd_mbhc_event_notify()
269 return cancel_delayed_work_sync(&mbhc->mbhc_btn_dwork); in wcd_cancel_btn_work()
274 struct snd_soc_component *component = mbhc->component; in wcd_micbias_disable()
276 if (mbhc->mbhc_cb->mbhc_micbias_control) in wcd_micbias_disable()
277 mbhc->mbhc_cb->mbhc_micbias_control(component, MIC_BIAS_2, MICB_DISABLE); in wcd_micbias_disable()
279 if (mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic) in wcd_micbias_disable()
280 mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(component, MIC_BIAS_2, false); in wcd_micbias_disable()
282 if (mbhc->mbhc_cb->set_micbias_value) { in wcd_micbias_disable()
283 mbhc->mbhc_cb->set_micbias_value(component); in wcd_micbias_disable()
291 mbhc->hph_status &= ~jack_type; in wcd_mbhc_report_plug_removal()
296 if (!wcd_cancel_btn_work(mbhc) && mbhc->buttons_pressed) { in wcd_mbhc_report_plug_removal()
297 snd_soc_jack_report(mbhc->jack, 0, mbhc->buttons_pressed); in wcd_mbhc_report_plug_removal()
298 mbhc->buttons_pressed &= ~WCD_MBHC_JACK_BUTTON_MASK; in wcd_mbhc_report_plug_removal()
302 mbhc->hph_type = WCD_MBHC_HPH_NONE; in wcd_mbhc_report_plug_removal()
303 mbhc->zl = mbhc->zr = 0; in wcd_mbhc_report_plug_removal()
304 snd_soc_jack_report(mbhc->jack, mbhc->hph_status, WCD_MBHC_JACK_MASK); in wcd_mbhc_report_plug_removal()
305 mbhc->current_plug = MBHC_PLUG_TYPE_NONE; in wcd_mbhc_report_plug_removal()
306 mbhc->force_linein = false; in wcd_mbhc_report_plug_removal()
312 if (!mbhc->impedance_detect) in wcd_mbhc_compute_impedance()
315 if (mbhc->cfg->linein_th != 0) { in wcd_mbhc_compute_impedance()
317 /* Set MUX_CTL to AUTO for Z-det */ in wcd_mbhc_compute_impedance()
322 mbhc->mbhc_cb->compute_impedance(mbhc->component, &mbhc->zl, &mbhc->zr); in wcd_mbhc_compute_impedance()
336 if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADSET && in wcd_mbhc_report_plug_insertion()
338 mbhc->hph_status &= ~SND_JACK_HEADSET; in wcd_mbhc_report_plug_insertion()
343 mbhc->current_plug = MBHC_PLUG_TYPE_HEADPHONE; in wcd_mbhc_report_plug_insertion()
346 mbhc->current_plug = MBHC_PLUG_TYPE_HEADSET; in wcd_mbhc_report_plug_insertion()
347 mbhc->jiffies_atreport = jiffies; in wcd_mbhc_report_plug_insertion()
350 mbhc->current_plug = MBHC_PLUG_TYPE_HIGH_HPH; in wcd_mbhc_report_plug_insertion()
361 if ((mbhc->zl > mbhc->cfg->linein_th) && in wcd_mbhc_report_plug_insertion()
362 (mbhc->zr > mbhc->cfg->linein_th) && in wcd_mbhc_report_plug_insertion()
365 mbhc->force_linein = true; in wcd_mbhc_report_plug_insertion()
366 mbhc->current_plug = MBHC_PLUG_TYPE_HIGH_HPH; in wcd_mbhc_report_plug_insertion()
367 if (mbhc->hph_status) { in wcd_mbhc_report_plug_insertion()
368 mbhc->hph_status &= ~(SND_JACK_HEADSET | in wcd_mbhc_report_plug_insertion()
370 snd_soc_jack_report(mbhc->jack, mbhc->hph_status, in wcd_mbhc_report_plug_insertion()
381 if (is_pa_on && mbhc->force_linein) { in wcd_mbhc_report_plug_insertion()
383 mbhc->current_plug = MBHC_PLUG_TYPE_HIGH_HPH; in wcd_mbhc_report_plug_insertion()
384 if (mbhc->hph_status) { in wcd_mbhc_report_plug_insertion()
385 mbhc->hph_status &= ~(SND_JACK_HEADSET | in wcd_mbhc_report_plug_insertion()
387 snd_soc_jack_report(mbhc->jack, mbhc->hph_status, in wcd_mbhc_report_plug_insertion()
392 mbhc->hph_status |= jack_type; in wcd_mbhc_report_plug_insertion()
394 if (jack_type == SND_JACK_HEADPHONE && mbhc->mbhc_cb->mbhc_micb_ramp_control) in wcd_mbhc_report_plug_insertion()
395 mbhc->mbhc_cb->mbhc_micb_ramp_control(mbhc->component, false); in wcd_mbhc_report_plug_insertion()
397 snd_soc_jack_report(mbhc->jack, (mbhc->hph_status | SND_JACK_MECHANICAL), in wcd_mbhc_report_plug_insertion()
405 WARN_ON(!mutex_is_locked(&mbhc->lock)); in wcd_mbhc_report_plug()
417 mbhc->hs_detect_work_stop = true; in wcd_cancel_hs_detect_plug()
418 mutex_unlock(&mbhc->lock); in wcd_cancel_hs_detect_plug()
420 mutex_lock(&mbhc->lock); in wcd_cancel_hs_detect_plug()
428 wcd_cancel_hs_detect_plug(mbhc, &mbhc->correct_plug_swch); in wcd_mbhc_cancel_pending_work()
440 disable_irq_nosync(mbhc->intr_ids->mbhc_hs_rem_intr); in wcd_mbhc_elec_hs_report_unplug()
448 enable_irq(mbhc->intr_ids->mbhc_hs_ins_intr); in wcd_mbhc_elec_hs_report_unplug()
454 if (mbhc->current_plug == plug_type) in wcd_mbhc_find_plug_and_report()
457 mutex_lock(&mbhc->lock); in wcd_mbhc_find_plug_and_report()
470 if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADPHONE) in wcd_mbhc_find_plug_and_report()
472 if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADSET) in wcd_mbhc_find_plug_and_report()
477 mbhc->current_plug, plug_type); in wcd_mbhc_find_plug_and_report()
480 mutex_unlock(&mbhc->lock); in wcd_mbhc_find_plug_and_report()
486 WARN_ON(!mutex_is_locked(&mbhc->lock)); in wcd_schedule_hs_detect_plug()
487 mbhc->hs_detect_work_stop = false; in wcd_schedule_hs_detect_plug()
493 struct snd_soc_component *component = mbhc->component; in wcd_mbhc_adc_detect_plug_type()
495 WARN_ON(!mutex_is_locked(&mbhc->lock)); in wcd_mbhc_adc_detect_plug_type()
497 if (mbhc->mbhc_cb->hph_pull_down_ctrl) in wcd_mbhc_adc_detect_plug_type()
498 mbhc->mbhc_cb->hph_pull_down_ctrl(component, false); in wcd_mbhc_adc_detect_plug_type()
502 if (mbhc->mbhc_cb->mbhc_micbias_control) { in wcd_mbhc_adc_detect_plug_type()
503 mbhc->mbhc_cb->mbhc_micbias_control(component, MIC_BIAS_2, in wcd_mbhc_adc_detect_plug_type()
505 wcd_schedule_hs_detect_plug(mbhc, &mbhc->correct_plug_swch); in wcd_mbhc_adc_detect_plug_type()
516 component = mbhc->component; in wcd_mbhc_mech_plug_detect_irq()
517 mutex_lock(&mbhc->lock); in wcd_mbhc_mech_plug_detect_irq()
519 mbhc->in_swch_irq_handler = true; in wcd_mbhc_mech_plug_detect_irq()
529 if (mbhc->mbhc_cb->mbhc_micb_ramp_control) in wcd_mbhc_mech_plug_detect_irq()
530 mbhc->mbhc_cb->mbhc_micb_ramp_control(component, true); in wcd_mbhc_mech_plug_detect_irq()
533 if (mbhc->current_plug != MBHC_PLUG_TYPE_NONE) in wcd_mbhc_mech_plug_detect_irq()
536 mbhc->mbhc_cb->mbhc_bias(component, true); in wcd_mbhc_mech_plug_detect_irq()
537 mbhc->is_btn_press = false; in wcd_mbhc_mech_plug_detect_irq()
543 mbhc->extn_cable_hph_rem = false; in wcd_mbhc_mech_plug_detect_irq()
545 if (mbhc->current_plug == MBHC_PLUG_TYPE_NONE) in wcd_mbhc_mech_plug_detect_irq()
548 mbhc->is_btn_press = false; in wcd_mbhc_mech_plug_detect_irq()
549 switch (mbhc->current_plug) { in wcd_mbhc_mech_plug_detect_irq()
557 if (mbhc->mbhc_detection_logic == WCD_DETECTION_ADC) in wcd_mbhc_mech_plug_detect_irq()
562 dev_err(mbhc->dev, "Ground and Mic Swapped on plug\n"); in wcd_mbhc_mech_plug_detect_irq()
565 dev_err(mbhc->dev, "Invalid current plug: %d\n", in wcd_mbhc_mech_plug_detect_irq()
566 mbhc->current_plug); in wcd_mbhc_mech_plug_detect_irq()
569 disable_irq_nosync(mbhc->intr_ids->mbhc_hs_rem_intr); in wcd_mbhc_mech_plug_detect_irq()
570 disable_irq_nosync(mbhc->intr_ids->mbhc_hs_ins_intr); in wcd_mbhc_mech_plug_detect_irq()
577 mbhc->in_swch_irq_handler = false; in wcd_mbhc_mech_plug_detect_irq()
578 mutex_unlock(&mbhc->lock); in wcd_mbhc_mech_plug_detect_irq()
620 if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADSET) in wcd_btn_long_press_fn()
621 snd_soc_jack_report(mbhc->jack, mbhc->buttons_pressed, in wcd_btn_long_press_fn()
622 mbhc->buttons_pressed); in wcd_btn_long_press_fn()
631 mutex_lock(&mbhc->lock); in wcd_mbhc_btn_press_handler()
633 mbhc->is_btn_press = true; in wcd_mbhc_btn_press_handler()
634 msec_val = jiffies_to_msecs(jiffies - mbhc->jiffies_atreport); in wcd_mbhc_btn_press_handler()
641 if (mbhc->in_swch_irq_handler) in wcd_mbhc_btn_press_handler()
645 if (mbhc->current_plug != MBHC_PLUG_TYPE_HEADSET) in wcd_mbhc_btn_press_handler()
649 mbhc->buttons_pressed |= mask; in wcd_mbhc_btn_press_handler()
650 if (schedule_delayed_work(&mbhc->mbhc_btn_dwork, msecs_to_jiffies(400)) == 0) in wcd_mbhc_btn_press_handler()
653 mutex_unlock(&mbhc->lock); in wcd_mbhc_btn_press_handler()
662 mutex_lock(&mbhc->lock); in wcd_mbhc_btn_release_handler()
663 if (mbhc->is_btn_press) in wcd_mbhc_btn_release_handler()
664 mbhc->is_btn_press = false; in wcd_mbhc_btn_release_handler()
668 if (!(mbhc->buttons_pressed & WCD_MBHC_JACK_BUTTON_MASK)) in wcd_mbhc_btn_release_handler()
673 snd_soc_jack_report(mbhc->jack, 0, mbhc->buttons_pressed); in wcd_mbhc_btn_release_handler()
675 if (!mbhc->in_swch_irq_handler) { in wcd_mbhc_btn_release_handler()
677 snd_soc_jack_report(mbhc->jack, mbhc->buttons_pressed, in wcd_mbhc_btn_release_handler()
678 mbhc->buttons_pressed); in wcd_mbhc_btn_release_handler()
679 snd_soc_jack_report(mbhc->jack, 0, mbhc->buttons_pressed); in wcd_mbhc_btn_release_handler()
682 mbhc->buttons_pressed &= ~WCD_MBHC_JACK_BUTTON_MASK; in wcd_mbhc_btn_release_handler()
684 mutex_unlock(&mbhc->lock); in wcd_mbhc_btn_release_handler()
693 dev_err(mbhc->dev, "MBHC Over Current on %s detected\n", in wcd_mbhc_hph_ocp_irq()
714 struct snd_soc_component *component = mbhc->component; in wcd_mbhc_initialise()
717 ret = pm_runtime_get_sync(component->dev); in wcd_mbhc_initialise()
718 if (ret < 0 && ret != -EACCES) { in wcd_mbhc_initialise()
719 dev_err_ratelimited(component->dev, in wcd_mbhc_initialise()
722 pm_runtime_put_noidle(component->dev); in wcd_mbhc_initialise()
726 mutex_lock(&mbhc->lock); in wcd_mbhc_initialise()
729 if (mbhc->mbhc_cb->hph_pull_up_control_v2) in wcd_mbhc_initialise()
730 mbhc->mbhc_cb->hph_pull_up_control_v2(component, in wcd_mbhc_initialise()
732 else if (mbhc->mbhc_cb->hph_pull_up_control) in wcd_mbhc_initialise()
733 mbhc->mbhc_cb->hph_pull_up_control(component, I_DEFAULT); in wcd_mbhc_initialise()
737 wcd_mbhc_write_field(mbhc, WCD_MBHC_HPHL_PLUG_TYPE, mbhc->cfg->hphl_swh); in wcd_mbhc_initialise()
738 wcd_mbhc_write_field(mbhc, WCD_MBHC_GND_PLUG_TYPE, mbhc->cfg->gnd_swh); in wcd_mbhc_initialise()
740 if (mbhc->cfg->gnd_det_en && mbhc->mbhc_cb->mbhc_gnd_det_ctrl) in wcd_mbhc_initialise()
741 mbhc->mbhc_cb->mbhc_gnd_det_ctrl(component, true); in wcd_mbhc_initialise()
753 mbhc->mbhc_cb->mbhc_bias(component, true); in wcd_mbhc_initialise()
755 if (mbhc->mbhc_cb->clk_setup) in wcd_mbhc_initialise()
756 mbhc->mbhc_cb->clk_setup(component, true); in wcd_mbhc_initialise()
763 mutex_unlock(&mbhc->lock); in wcd_mbhc_initialise()
765 pm_runtime_mark_last_busy(component->dev); in wcd_mbhc_initialise()
766 pm_runtime_put_autosuspend(component->dev); in wcd_mbhc_initialise()
775 if (mbhc->mbhc_cb->get_micbias_val) { in wcd_mbhc_get_micbias()
776 mbhc->mbhc_cb->get_micbias_val(mbhc->component, &micbias); in wcd_mbhc_get_micbias()
782 * micbias = 1.0V + VOUT_CTL * 50mV in wcd_mbhc_get_micbias()
792 * Voltage = ADC_RESULT*12.5mV*V_MICBIAS/1.8 in wcd_get_voltage_from_adc()
804 /* Pre-requisites for ADC continuous measurement */ in wcd_measure_adc_continuous()
822 while (retry--) { in wcd_measure_adc_continuous()
838 struct device *dev = mbhc->dev; in wcd_measure_adc_once()
858 while (retry--) { in wcd_measure_adc_once()
887 ret = -EINVAL; in wcd_measure_adc_once()
902 /* If PA is enabled, dont check for cross-connection */ in wcd_check_cross_conn()
904 return -EINVAL; in wcd_check_cross_conn()
922 /* Get adc result for HPH R in mV */ in wcd_check_cross_conn()
952 if (mbhc->cfg->hs_thr) { in wcd_mbhc_adc_get_hs_thres()
953 if (mbhc->cfg->micb_mv == micbias_mv) in wcd_mbhc_adc_get_hs_thres()
954 hs_threshold = mbhc->cfg->hs_thr; in wcd_mbhc_adc_get_hs_thres()
956 hs_threshold = (mbhc->cfg->hs_thr * in wcd_mbhc_adc_get_hs_thres()
957 micbias_mv) / mbhc->cfg->micb_mv; in wcd_mbhc_adc_get_hs_thres()
970 if (mbhc->cfg->hph_thr) { in wcd_mbhc_adc_get_hph_thres()
971 if (mbhc->cfg->micb_mv == micbias_mv) in wcd_mbhc_adc_get_hph_thres()
972 hph_threshold = mbhc->cfg->hph_thr; in wcd_mbhc_adc_get_hph_thres()
974 hph_threshold = (mbhc->cfg->hph_thr * in wcd_mbhc_adc_get_hph_thres()
975 micbias_mv) / mbhc->cfg->micb_mv; in wcd_mbhc_adc_get_hph_thres()
993 if (mbhc->mbhc_cb->micbias_enable_status) in wcd_mbhc_adc_update_fsm_source()
994 micbias2 = mbhc->mbhc_cb->micbias_enable_status(mbhc->component, in wcd_mbhc_adc_update_fsm_source()
997 if (!mbhc->is_hs_recording && !micbias2) in wcd_mbhc_adc_update_fsm_source()
1012 if (mbhc->mbhc_cb->bcs_enable) in wcd_mbhc_bcs_enable()
1013 mbhc->mbhc_cb->bcs_enable(mbhc->component, enable); in wcd_mbhc_bcs_enable()
1044 if (mbhc->cfg->hs_thr && mbhc->cfg->micb_mv != WCD_MBHC_ADC_MICBIAS_MV) { in wcd_mbhc_get_spl_hs_thres()
1045 if (mbhc->cfg->micb_mv == micbias_mv) in wcd_mbhc_get_spl_hs_thres()
1046 hs_threshold = mbhc->cfg->hs_thr; in wcd_mbhc_get_spl_hs_thres()
1048 hs_threshold = (mbhc->cfg->hs_thr * micbias_mv) / mbhc->cfg->micb_mv; in wcd_mbhc_get_spl_hs_thres()
1061 if (!mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic) in wcd_mbhc_check_for_spl_headset()
1065 mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(mbhc->component, MIC_BIAS_2, true); in wcd_mbhc_check_for_spl_headset()
1077 mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(mbhc->component, MIC_BIAS_2, false); in wcd_mbhc_check_for_spl_headset()
1098 component = mbhc->component; in wcd_correct_swch_plug()
1100 ret = pm_runtime_get_sync(component->dev); in wcd_correct_swch_plug()
1101 if (ret < 0 && ret != -EACCES) { in wcd_correct_swch_plug()
1102 dev_err_ratelimited(component->dev, in wcd_correct_swch_plug()
1105 pm_runtime_put_noidle(component->dev); in wcd_correct_swch_plug()
1112 disable_irq_nosync(mbhc->intr_ids->mbhc_hs_ins_intr); in wcd_correct_swch_plug()
1122 dev_err(mbhc->dev, "cross connection found, Plug type %d\n", in wcd_correct_swch_plug()
1157 if (mbhc->hs_detect_work_stop) { in wcd_correct_swch_plug()
1184 if (cross_conn > 0) { /* cross-connection */ in wcd_correct_swch_plug()
1199 if (mbhc->cfg->swap_gnd_mic) { in wcd_correct_swch_plug()
1200 if (mbhc->cfg->swap_gnd_mic(component, true)) in wcd_correct_swch_plug()
1207 if (output_mv > hs_threshold || mbhc->force_linein) in wcd_correct_swch_plug()
1234 if (mbhc->mbhc_cb->mbhc_micbias_control) in wcd_correct_swch_plug()
1238 if (mbhc->mbhc_cb->mbhc_micbias_control/* && !mbhc->micbias_enable*/) in wcd_correct_swch_plug()
1239 mbhc->mbhc_cb->mbhc_micbias_control(component, MIC_BIAS_2, MICB_DISABLE); in wcd_correct_swch_plug()
1253 enable_irq(mbhc->intr_ids->mbhc_hs_ins_intr); in wcd_correct_swch_plug()
1256 if (mbhc->mbhc_cb->hph_pull_down_ctrl) in wcd_correct_swch_plug()
1257 mbhc->mbhc_cb->hph_pull_down_ctrl(component, true); in wcd_correct_swch_plug()
1259 pm_runtime_mark_last_busy(component->dev); in wcd_correct_swch_plug()
1260 pm_runtime_put_autosuspend(component->dev); in wcd_correct_swch_plug()
1269 mutex_lock(&mbhc->lock); in wcd_mbhc_adc_hs_rem_irq()
1292 if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADPHONE) in wcd_mbhc_adc_hs_rem_irq()
1293 mbhc->extn_cable_hph_rem = true; in wcd_mbhc_adc_hs_rem_irq()
1302 mutex_unlock(&mbhc->lock); in wcd_mbhc_adc_hs_rem_irq()
1317 if (mbhc->extn_cable_hph_rem == true) { in wcd_mbhc_adc_hs_ins_irq()
1318 mbhc->extn_cable_hph_rem = false; in wcd_mbhc_adc_hs_ins_irq()
1331 } while (--clamp_retry); in wcd_mbhc_adc_hs_ins_irq()
1338 if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADPHONE) { in wcd_mbhc_adc_hs_ins_irq()
1339 disable_irq_nosync(mbhc->intr_ids->mbhc_hs_ins_intr); in wcd_mbhc_adc_hs_ins_irq()
1350 *zl = mbhc->zl; in wcd_mbhc_get_impedance()
1351 *zr = mbhc->zr; in wcd_mbhc_get_impedance()
1356 return -EINVAL; in wcd_mbhc_get_impedance()
1362 mbhc->hph_type = hph_type; in wcd_mbhc_set_hph_type()
1368 return mbhc->hph_type; in wcd_mbhc_get_hph_type()
1376 return -EINVAL; in wcd_mbhc_start()
1378 mbhc->cfg = cfg; in wcd_mbhc_start()
1379 mbhc->jack = jack; in wcd_mbhc_start()
1387 mbhc->current_plug = MBHC_PLUG_TYPE_NONE; in wcd_mbhc_stop()
1388 mbhc->hph_status = 0; in wcd_mbhc_stop()
1389 disable_irq_nosync(mbhc->intr_ids->hph_left_ocp); in wcd_mbhc_stop()
1390 disable_irq_nosync(mbhc->intr_ids->hph_right_ocp); in wcd_mbhc_stop()
1396 struct device_node *np = dev->of_node; in wcd_dt_parse_mbhc_data()
1399 if (of_property_read_bool(np, "qcom,hphl-jack-type-normally-closed")) in wcd_dt_parse_mbhc_data()
1400 cfg->hphl_swh = false; in wcd_dt_parse_mbhc_data()
1402 cfg->hphl_swh = true; in wcd_dt_parse_mbhc_data()
1404 if (of_property_read_bool(np, "qcom,ground-jack-type-normally-closed")) in wcd_dt_parse_mbhc_data()
1405 cfg->gnd_swh = false; in wcd_dt_parse_mbhc_data()
1407 cfg->gnd_swh = true; in wcd_dt_parse_mbhc_data()
1409 ret = of_property_read_u32(np, "qcom,mbhc-headset-vthreshold-microvolt", in wcd_dt_parse_mbhc_data()
1412 dev_dbg(dev, "missing qcom,mbhc-hs-mic-max-vthreshold--microvolt in dt node\n"); in wcd_dt_parse_mbhc_data()
1414 cfg->hs_thr = microvolt/1000; in wcd_dt_parse_mbhc_data()
1416 ret = of_property_read_u32(np, "qcom,mbhc-headphone-vthreshold-microvolt", in wcd_dt_parse_mbhc_data()
1419 dev_dbg(dev, "missing qcom,mbhc-hs-mic-min-vthreshold-microvolt entry\n"); in wcd_dt_parse_mbhc_data()
1421 cfg->hph_thr = microvolt/1000; in wcd_dt_parse_mbhc_data()
1424 "qcom,mbhc-buttons-vthreshold-microvolt", in wcd_dt_parse_mbhc_data()
1425 &cfg->btn_high[0], in wcd_dt_parse_mbhc_data()
1428 dev_err(dev, "missing qcom,mbhc-buttons-vthreshold-microvolt entry\n"); in wcd_dt_parse_mbhc_data()
1432 cfg->btn_high[i] = 500000; in wcd_dt_parse_mbhc_data()
1435 cfg->btn_high[i] = cfg->btn_high[i]/1000; in wcd_dt_parse_mbhc_data()
1448 struct device *dev = component->dev; in wcd_mbhc_init()
1452 if (!intr_ids || !fields || !mbhc_cb || !mbhc_cb->mbhc_bias || !mbhc_cb->set_btn_thr) { in wcd_mbhc_init()
1454 return ERR_PTR(-EINVAL); in wcd_mbhc_init()
1459 return ERR_PTR(-ENOMEM); in wcd_mbhc_init()
1461 mbhc->component = component; in wcd_mbhc_init()
1462 mbhc->dev = dev; in wcd_mbhc_init()
1463 mbhc->intr_ids = intr_ids; in wcd_mbhc_init()
1464 mbhc->mbhc_cb = mbhc_cb; in wcd_mbhc_init()
1465 mbhc->fields = fields; in wcd_mbhc_init()
1466 mbhc->mbhc_detection_logic = WCD_DETECTION_ADC; in wcd_mbhc_init()
1468 if (mbhc_cb->compute_impedance) in wcd_mbhc_init()
1469 mbhc->impedance_detect = impedance_det_en; in wcd_mbhc_init()
1471 INIT_DELAYED_WORK(&mbhc->mbhc_btn_dwork, wcd_btn_long_press_fn); in wcd_mbhc_init()
1473 mutex_init(&mbhc->lock); in wcd_mbhc_init()
1475 INIT_WORK(&mbhc->correct_plug_swch, wcd_correct_swch_plug); in wcd_mbhc_init()
1477 ret = request_threaded_irq(mbhc->intr_ids->mbhc_sw_intr, NULL, in wcd_mbhc_init()
1484 ret = request_threaded_irq(mbhc->intr_ids->mbhc_btn_press_intr, NULL, in wcd_mbhc_init()
1491 ret = request_threaded_irq(mbhc->intr_ids->mbhc_btn_release_intr, NULL, in wcd_mbhc_init()
1498 ret = request_threaded_irq(mbhc->intr_ids->mbhc_hs_ins_intr, NULL, in wcd_mbhc_init()
1505 disable_irq_nosync(mbhc->intr_ids->mbhc_hs_ins_intr); in wcd_mbhc_init()
1507 ret = request_threaded_irq(mbhc->intr_ids->mbhc_hs_rem_intr, NULL, in wcd_mbhc_init()
1514 disable_irq_nosync(mbhc->intr_ids->mbhc_hs_rem_intr); in wcd_mbhc_init()
1516 ret = request_threaded_irq(mbhc->intr_ids->hph_left_ocp, NULL, in wcd_mbhc_init()
1523 ret = request_threaded_irq(mbhc->intr_ids->hph_right_ocp, NULL, in wcd_mbhc_init()
1533 free_irq(mbhc->intr_ids->hph_left_ocp, mbhc); in wcd_mbhc_init()
1535 free_irq(mbhc->intr_ids->mbhc_hs_rem_intr, mbhc); in wcd_mbhc_init()
1537 free_irq(mbhc->intr_ids->mbhc_hs_ins_intr, mbhc); in wcd_mbhc_init()
1539 free_irq(mbhc->intr_ids->mbhc_btn_release_intr, mbhc); in wcd_mbhc_init()
1541 free_irq(mbhc->intr_ids->mbhc_btn_press_intr, mbhc); in wcd_mbhc_init()
1543 free_irq(mbhc->intr_ids->mbhc_sw_intr, mbhc); in wcd_mbhc_init()
1555 free_irq(mbhc->intr_ids->hph_right_ocp, mbhc); in wcd_mbhc_deinit()
1556 free_irq(mbhc->intr_ids->hph_left_ocp, mbhc); in wcd_mbhc_deinit()
1557 free_irq(mbhc->intr_ids->mbhc_hs_rem_intr, mbhc); in wcd_mbhc_deinit()
1558 free_irq(mbhc->intr_ids->mbhc_hs_ins_intr, mbhc); in wcd_mbhc_deinit()
1559 free_irq(mbhc->intr_ids->mbhc_btn_release_intr, mbhc); in wcd_mbhc_deinit()
1560 free_irq(mbhc->intr_ids->mbhc_btn_press_intr, mbhc); in wcd_mbhc_deinit()
1561 free_irq(mbhc->intr_ids->mbhc_sw_intr, mbhc); in wcd_mbhc_deinit()
1563 mutex_lock(&mbhc->lock); in wcd_mbhc_deinit()
1564 wcd_cancel_hs_detect_plug(mbhc, &mbhc->correct_plug_swch); in wcd_mbhc_deinit()
1565 mutex_unlock(&mbhc->lock); in wcd_mbhc_deinit()