Loading sound/soc/codecs/wcd-mbhc-v2.c +46 −28 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ #define HS_VREF_MIN_VAL 1400 #define FW_READ_ATTEMPTS 15 #define FW_READ_TIMEOUT 4000000 #define FAKE_REM_RETRY_ATTEMPTS 3 static int det_extn_cable_en; module_param(det_extn_cable_en, int, Loading Loading @@ -464,7 +465,7 @@ static void wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, struct snd_soc_codec *codec = mbhc->codec; s16 impedance_l, impedance_r; s16 impedance_l_fixed; s16 reg0, reg1, reg2; s16 reg0, reg1, reg2, reg3, reg4; bool high = false; pr_debug("%s: enter\n", __func__); Loading @@ -473,11 +474,16 @@ static void wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, reg0 = snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MBHC_DBNC_TIMER); reg1 = snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MBHC_BTN2_ZDETH_CTL); reg2 = snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MBHC_DET_CTL_2); reg3 = snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MICB_2_EN); reg4 = snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MBHC_FSM_CTL); /* disable FSM */ /* disable FSM and micbias*/ snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MBHC_FSM_CTL, 0x80, 0x00); snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_2_EN, 0x80, 0x00); /* * Enable legacy electrical detection current sources * and disable fast ramp and enable manual switching Loading Loading @@ -628,13 +634,8 @@ static void wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, 0x02, 0x00); exit: /* * Enable the FSM and button source back for * button detection. */ snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MBHC_FSM_CTL, 0xFF, 0xB0); snd_soc_write(codec, MSM8X16_WCD_A_ANALOG_MBHC_FSM_CTL, reg4); snd_soc_write(codec, MSM8X16_WCD_A_ANALOG_MICB_2_EN, reg3); snd_soc_write(codec, MSM8X16_WCD_A_ANALOG_MBHC_BTN2_ZDETH_CTL, reg1); snd_soc_write(codec, MSM8X16_WCD_A_ANALOG_MBHC_DBNC_TIMER, reg0); snd_soc_write(codec, MSM8X16_WCD_A_ANALOG_MBHC_DET_CTL_2, reg2); Loading Loading @@ -775,6 +776,11 @@ static void wcd_mbhc_find_plug_and_report(struct wcd_mbhc *mbhc, WCD_MBHC_RSC_ASSERT_LOCKED(mbhc); if (mbhc->current_plug == plug_type) { pr_debug("%s: cable already reported, exit\n", __func__); goto exit; } if (plug_type == MBHC_PLUG_TYPE_HEADPHONE) { /* * Nothing was reported previously Loading Loading @@ -828,6 +834,7 @@ static void wcd_mbhc_find_plug_and_report(struct wcd_mbhc *mbhc, WARN(1, "Unexpected current plug_type %d, plug_type %d\n", mbhc->current_plug, plug_type); } exit: pr_debug("%s: leave\n", __func__); } Loading Loading @@ -1035,7 +1042,7 @@ static void wcd_correct_swch_plug(struct work_struct *work) wrk_complete = false; } } if (mbhc->btn_press_intr) { if (!wrk_complete && mbhc->btn_press_intr) { pr_debug("%s: Can be slow insertion of headphone\n", __func__); plug_type = MBHC_PLUG_TYPE_HEADPHONE; } Loading Loading @@ -1307,10 +1314,6 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc) snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MBHC_DET_CTL_2, 0x06, 0x00); /* Enable current source */ snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MBHC_FSM_CTL, 0x30, 0x30); wcd_mbhc_report_plug(mbhc, 0, SND_JACK_HEADSET); } else if (mbhc->current_plug == MBHC_PLUG_TYPE_HIGH_HPH) { wcd9xxx_spmi_disable_irq( Loading @@ -1323,10 +1326,6 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc) snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MBHC_DET_CTL_2, 0x06, 0x00); /* Enable current source */ snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MBHC_FSM_CTL, 0x30, 0x30); wcd_mbhc_report_plug(mbhc, 0, SND_JACK_LINEOUT); } } else if (!detection_type) { Loading Loading @@ -1467,6 +1466,12 @@ determine_plug: 0x80, 0x80); hphl_trigerred = 0; mic_trigerred = 0; /* * even if controls comes here, it is taking more than * debounce time to detect cable as headphone, so wait * for 20msec for the mic line to stabilize */ msleep(20); wcd_mbhc_detect_plug_type(mbhc); WCD_MBHC_RSC_UNLOCK(mbhc); pr_debug("%s: leave\n", __func__); Loading @@ -1482,20 +1487,27 @@ static irqreturn_t wcd_mbhc_hs_rem_irq(int irq, void *data) static u16 mic_trigerred; unsigned long timeout; bool removed = true; int retry = 0; pr_debug("%s: enter\n", __func__); WCD_MBHC_RSC_LOCK(mbhc); wcd_cancel_hs_detect_plug(mbhc, &mbhc->correct_plug_swch); timeout = jiffies + msecs_to_jiffies(WCD_FAKE_REMOVAL_MIN_PERIOD_MS); do { retry++; /* * read the result2 register every 10ms to look for * any change in HS_COMP_RESULT bit */ usleep_range(10000, 10100); result2 = (snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MBHC_ZDET_ELECT_RESULT)); pr_debug("%s: check result2 for fake removal: %x\n", __func__, result2); if (!(result2 & 0x01)) { if ((!(result2 & 0x01)) && retry > FAKE_REM_RETRY_ATTEMPTS) { removed = false; break; } Loading Loading @@ -1537,7 +1549,21 @@ static irqreturn_t wcd_mbhc_hs_rem_irq(int irq, void *data) report_unplug: /* cancel pending button press */ if (wcd_cancel_btn_work(mbhc)) pr_debug("%s: button press is canceled\n", __func__); /* cancel correct work function */ wcd_cancel_hs_detect_plug(mbhc, &mbhc->correct_plug_swch); pr_debug("%s: Report extension cable\n", __func__); wcd_mbhc_report_plug(mbhc, 1, SND_JACK_LINEOUT); /* * If PA is enabled HPHL schmitt trigger can * be unreliable, make sure to disable it */ if (test_bit(WCD_MBHC_EVENT_PA_HPHL, &mbhc->event_state)) wcd_mbhc_set_and_turnoff_hph_padac(mbhc); /* * Disable HPHL trigger and MIC Schmitt triggers. * Setup for insertion detection. Loading @@ -1555,7 +1581,6 @@ report_unplug: snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MBHC_DET_CTL_1, 0x01, 0x01); wcd9xxx_spmi_enable_irq(mbhc->intr_ids->mbhc_hs_ins_intr); wcd_mbhc_report_plug(mbhc, 1, SND_JACK_LINEOUT); hphl_trigerred = 0; mic_trigerred = 0; WCD_MBHC_RSC_UNLOCK(mbhc); Loading Loading @@ -1644,13 +1669,6 @@ irqreturn_t wcd_mbhc_btn_press_handler(int irq, void *data) goto done; } if (mbhc->current_plug != MBHC_PLUG_TYPE_HEADSET) { if (mbhc->current_plug == MBHC_PLUG_TYPE_HIGH_HPH) { pr_debug("%s: Ignore this button press\n", __func__); mbhc->btn_press_intr = false; mbhc->is_btn_press = false; goto done; } pr_debug("%s: Plug isn't headset, ignore button press\n", __func__); goto done; Loading Loading
sound/soc/codecs/wcd-mbhc-v2.c +46 −28 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ #define HS_VREF_MIN_VAL 1400 #define FW_READ_ATTEMPTS 15 #define FW_READ_TIMEOUT 4000000 #define FAKE_REM_RETRY_ATTEMPTS 3 static int det_extn_cable_en; module_param(det_extn_cable_en, int, Loading Loading @@ -464,7 +465,7 @@ static void wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, struct snd_soc_codec *codec = mbhc->codec; s16 impedance_l, impedance_r; s16 impedance_l_fixed; s16 reg0, reg1, reg2; s16 reg0, reg1, reg2, reg3, reg4; bool high = false; pr_debug("%s: enter\n", __func__); Loading @@ -473,11 +474,16 @@ static void wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, reg0 = snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MBHC_DBNC_TIMER); reg1 = snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MBHC_BTN2_ZDETH_CTL); reg2 = snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MBHC_DET_CTL_2); reg3 = snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MICB_2_EN); reg4 = snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MBHC_FSM_CTL); /* disable FSM */ /* disable FSM and micbias*/ snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MBHC_FSM_CTL, 0x80, 0x00); snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_2_EN, 0x80, 0x00); /* * Enable legacy electrical detection current sources * and disable fast ramp and enable manual switching Loading Loading @@ -628,13 +634,8 @@ static void wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, 0x02, 0x00); exit: /* * Enable the FSM and button source back for * button detection. */ snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MBHC_FSM_CTL, 0xFF, 0xB0); snd_soc_write(codec, MSM8X16_WCD_A_ANALOG_MBHC_FSM_CTL, reg4); snd_soc_write(codec, MSM8X16_WCD_A_ANALOG_MICB_2_EN, reg3); snd_soc_write(codec, MSM8X16_WCD_A_ANALOG_MBHC_BTN2_ZDETH_CTL, reg1); snd_soc_write(codec, MSM8X16_WCD_A_ANALOG_MBHC_DBNC_TIMER, reg0); snd_soc_write(codec, MSM8X16_WCD_A_ANALOG_MBHC_DET_CTL_2, reg2); Loading Loading @@ -775,6 +776,11 @@ static void wcd_mbhc_find_plug_and_report(struct wcd_mbhc *mbhc, WCD_MBHC_RSC_ASSERT_LOCKED(mbhc); if (mbhc->current_plug == plug_type) { pr_debug("%s: cable already reported, exit\n", __func__); goto exit; } if (plug_type == MBHC_PLUG_TYPE_HEADPHONE) { /* * Nothing was reported previously Loading Loading @@ -828,6 +834,7 @@ static void wcd_mbhc_find_plug_and_report(struct wcd_mbhc *mbhc, WARN(1, "Unexpected current plug_type %d, plug_type %d\n", mbhc->current_plug, plug_type); } exit: pr_debug("%s: leave\n", __func__); } Loading Loading @@ -1035,7 +1042,7 @@ static void wcd_correct_swch_plug(struct work_struct *work) wrk_complete = false; } } if (mbhc->btn_press_intr) { if (!wrk_complete && mbhc->btn_press_intr) { pr_debug("%s: Can be slow insertion of headphone\n", __func__); plug_type = MBHC_PLUG_TYPE_HEADPHONE; } Loading Loading @@ -1307,10 +1314,6 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc) snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MBHC_DET_CTL_2, 0x06, 0x00); /* Enable current source */ snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MBHC_FSM_CTL, 0x30, 0x30); wcd_mbhc_report_plug(mbhc, 0, SND_JACK_HEADSET); } else if (mbhc->current_plug == MBHC_PLUG_TYPE_HIGH_HPH) { wcd9xxx_spmi_disable_irq( Loading @@ -1323,10 +1326,6 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc) snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MBHC_DET_CTL_2, 0x06, 0x00); /* Enable current source */ snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MBHC_FSM_CTL, 0x30, 0x30); wcd_mbhc_report_plug(mbhc, 0, SND_JACK_LINEOUT); } } else if (!detection_type) { Loading Loading @@ -1467,6 +1466,12 @@ determine_plug: 0x80, 0x80); hphl_trigerred = 0; mic_trigerred = 0; /* * even if controls comes here, it is taking more than * debounce time to detect cable as headphone, so wait * for 20msec for the mic line to stabilize */ msleep(20); wcd_mbhc_detect_plug_type(mbhc); WCD_MBHC_RSC_UNLOCK(mbhc); pr_debug("%s: leave\n", __func__); Loading @@ -1482,20 +1487,27 @@ static irqreturn_t wcd_mbhc_hs_rem_irq(int irq, void *data) static u16 mic_trigerred; unsigned long timeout; bool removed = true; int retry = 0; pr_debug("%s: enter\n", __func__); WCD_MBHC_RSC_LOCK(mbhc); wcd_cancel_hs_detect_plug(mbhc, &mbhc->correct_plug_swch); timeout = jiffies + msecs_to_jiffies(WCD_FAKE_REMOVAL_MIN_PERIOD_MS); do { retry++; /* * read the result2 register every 10ms to look for * any change in HS_COMP_RESULT bit */ usleep_range(10000, 10100); result2 = (snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MBHC_ZDET_ELECT_RESULT)); pr_debug("%s: check result2 for fake removal: %x\n", __func__, result2); if (!(result2 & 0x01)) { if ((!(result2 & 0x01)) && retry > FAKE_REM_RETRY_ATTEMPTS) { removed = false; break; } Loading Loading @@ -1537,7 +1549,21 @@ static irqreturn_t wcd_mbhc_hs_rem_irq(int irq, void *data) report_unplug: /* cancel pending button press */ if (wcd_cancel_btn_work(mbhc)) pr_debug("%s: button press is canceled\n", __func__); /* cancel correct work function */ wcd_cancel_hs_detect_plug(mbhc, &mbhc->correct_plug_swch); pr_debug("%s: Report extension cable\n", __func__); wcd_mbhc_report_plug(mbhc, 1, SND_JACK_LINEOUT); /* * If PA is enabled HPHL schmitt trigger can * be unreliable, make sure to disable it */ if (test_bit(WCD_MBHC_EVENT_PA_HPHL, &mbhc->event_state)) wcd_mbhc_set_and_turnoff_hph_padac(mbhc); /* * Disable HPHL trigger and MIC Schmitt triggers. * Setup for insertion detection. Loading @@ -1555,7 +1581,6 @@ report_unplug: snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MBHC_DET_CTL_1, 0x01, 0x01); wcd9xxx_spmi_enable_irq(mbhc->intr_ids->mbhc_hs_ins_intr); wcd_mbhc_report_plug(mbhc, 1, SND_JACK_LINEOUT); hphl_trigerred = 0; mic_trigerred = 0; WCD_MBHC_RSC_UNLOCK(mbhc); Loading Loading @@ -1644,13 +1669,6 @@ irqreturn_t wcd_mbhc_btn_press_handler(int irq, void *data) goto done; } if (mbhc->current_plug != MBHC_PLUG_TYPE_HEADSET) { if (mbhc->current_plug == MBHC_PLUG_TYPE_HIGH_HPH) { pr_debug("%s: Ignore this button press\n", __func__); mbhc->btn_press_intr = false; mbhc->is_btn_press = false; goto done; } pr_debug("%s: Plug isn't headset, ignore button press\n", __func__); goto done; Loading