msm8x16 耳机阻抗检测

耳机插入后中断相应,在wcd_mbhc_report_plug上报的时候可以读取阻抗动态,动态的提高驱动能力。

static void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion,
                enum snd_jack_types jack_type)
{
    struct snd_soc_codec *codec = mbhc->codec;
    bool is_pa_on = false;

    WCD_MBHC_RSC_ASSERT_LOCKED(mbhc);

    pr_debug("%s: enter insertion %d hph_status %x\n",
         __func__, insertion, mbhc->hph_status);
    if (!insertion) {
        /* Report removal */
        mbhc->hph_status &= ~jack_type;
        /*
         * cancel possibly scheduled btn work and
         * report release if we reported button press
         */
        if (wcd_cancel_btn_work(mbhc)) {
            pr_debug("%s: button press is canceled\n", __func__);
        } else if (mbhc->buttons_pressed) {
            pr_debug("%s: release of button press%d\n",
                 __func__, jack_type);
            wcd_mbhc_jack_report(mbhc, &mbhc->button_jack, 0,
                        mbhc->buttons_pressed);
            mbhc->buttons_pressed &=
                ~WCD_MBHC_JACK_BUTTON_MASK;
        }

        if (mbhc->micbias_enable) {
            if (mbhc->mbhc_cb->mbhc_micbias_control)
                mbhc->mbhc_cb->mbhc_micbias_control(
                        codec, MIC_BIAS_2,
                        MICB_DISABLE);
            if (mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic)
                mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(
                        codec,
                        MIC_BIAS_2, false);
            if (mbhc->mbhc_cb->set_micbias_value) {
                mbhc->mbhc_cb->set_micbias_value(codec);
                WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_MICB_CTRL, 0);
            }
            mbhc->micbias_enable = false;
        }

        mbhc->hph_type = WCD_MBHC_HPH_NONE;
        mbhc->zl = mbhc->zr = 0;
        pr_debug("%s: Reporting removal %d(%x)\n", __func__,
             jack_type, mbhc->hph_status);
        wcd_mbhc_jack_report(mbhc, &mbhc->headset_jack,
                mbhc->hph_status, WCD_MBHC_JACK_MASK);
        wcd_mbhc_set_and_turnoff_hph_padac(mbhc);
        hphrocp_off_report(mbhc, SND_JACK_OC_HPHR);
        hphlocp_off_report(mbhc, SND_JACK_OC_HPHL);
        mbhc->current_plug = MBHC_PLUG_TYPE_NONE;
        gpio_set_value_cansleep(us_eu_pull_gpio, US_EU_PULL_DOWN);
    } else {
        /*
         * Report removal of current jack type.
         * Headphone to headset shouldn't report headphone
         * removal.
         */
        if (mbhc->mbhc_cfg->detect_extn_cable &&
            (mbhc->current_plug == MBHC_PLUG_TYPE_HIGH_HPH ||
            jack_type == SND_JACK_LINEOUT) &&
            (mbhc->hph_status && mbhc->hph_status != jack_type)) {

            if (mbhc->micbias_enable &&
                mbhc->current_plug == MBHC_PLUG_TYPE_HEADSET) {
                if (mbhc->mbhc_cb->mbhc_micbias_control)
                    mbhc->mbhc_cb->mbhc_micbias_control(
                        codec, MIC_BIAS_2,
                        MICB_DISABLE);
                if (mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic)
                    mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(
                        codec,
                        MIC_BIAS_2, false);
                if (mbhc->mbhc_cb->set_micbias_value) {
                    mbhc->mbhc_cb->set_micbias_value(
                            codec);
                    WCD_MBHC_REG_UPDATE_BITS(
                            WCD_MBHC_MICB_CTRL, 0);
                }
                mbhc->micbias_enable = false;
            }
            mbhc->hph_type = WCD_MBHC_HPH_NONE;
            mbhc->zl = mbhc->zr = 0;
            pr_debug("%s: Reporting removal (%x)\n",
                 __func__, mbhc->hph_status);
            wcd_mbhc_jack_report(mbhc, &mbhc->headset_jack,
                        0, WCD_MBHC_JACK_MASK);

            if (mbhc->hph_status == SND_JACK_LINEOUT) {

                pr_debug("%s: Enable micbias\n", __func__);
                /* Disable current source and enable micbias */
                wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_MB);
                pr_debug("%s: set up elec removal detection\n",
                      __func__);
                WCD_MBHC_REG_UPDATE_BITS(
                        WCD_MBHC_ELECT_DETECTION_TYPE,
                        0);
                usleep_range(200, 210);
                wcd_mbhc_hs_elec_irq(mbhc,
                             WCD_MBHC_ELEC_HS_REM,
                             true);
            }
            mbhc->hph_status &= ~(SND_JACK_HEADSET |
                        SND_JACK_LINEOUT |
                        SND_JACK_ANC_HEADPHONE |
                        SND_JACK_UNSUPPORTED);
        }

        if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADSET &&
            jack_type == SND_JACK_HEADPHONE)
            mbhc->hph_status &= ~SND_JACK_HEADSET;

        /* Report insertion */
        if (jack_type == SND_JACK_HEADPHONE)
            mbhc->current_plug = MBHC_PLUG_TYPE_HEADPHONE;
        else if (jack_type == SND_JACK_UNSUPPORTED)
            mbhc->current_plug = MBHC_PLUG_TYPE_GND_MIC_SWAP;
        else if (jack_type == SND_JACK_HEADSET) {
            mbhc->current_plug = MBHC_PLUG_TYPE_HEADSET;
            mbhc->jiffies_atreport = jiffies;
        } else if (jack_type == SND_JACK_LINEOUT) {
            mbhc->current_plug = MBHC_PLUG_TYPE_HIGH_HPH;
        } else if (jack_type == SND_JACK_ANC_HEADPHONE)
            mbhc->current_plug = MBHC_PLUG_TYPE_ANC_HEADPHONE;

        if (mbhc->mbhc_cb->hph_pa_on_status)
            is_pa_on = mbhc->mbhc_cb->hph_pa_on_status(codec);

        if (mbhc->impedance_detect &&
            mbhc->mbhc_cb->compute_impedance &&
            (mbhc->mbhc_cfg->linein_th != 0) &&
            (!is_pa_on)) {
                mbhc->mbhc_cb->compute_impedance(mbhc,
                        &mbhc->zl, &mbhc->zr);
            if ((mbhc->zl > mbhc->mbhc_cfg->linein_th &&
                mbhc->zl < MAX_IMPED) &&
                (mbhc->zr > mbhc->mbhc_cfg->linein_th &&
                 mbhc->zr < MAX_IMPED) &&
                (jack_type == SND_JACK_HEADPHONE)) {
                jack_type = SND_JACK_LINEOUT;
                mbhc->current_plug = MBHC_PLUG_TYPE_HIGH_HPH;
                if (mbhc->hph_status) {
                    mbhc->hph_status &= ~(SND_JACK_HEADSET |
                            SND_JACK_LINEOUT |
                            SND_JACK_UNSUPPORTED);
                    wcd_mbhc_jack_report(mbhc,
                            &mbhc->headset_jack,
                            mbhc->hph_status,
                            WCD_MBHC_JACK_MASK);
                }
                pr_debug("%s: Marking jack type as SND_JACK_LINEOUT\n",
                __func__);
            }
        }

        mbhc->hph_status |= jack_type;

        pr_debug("%s: Reporting insertion %d(%x)\n", __func__,
             jack_type, mbhc->hph_status);
        wcd_mbhc_jack_report(mbhc, &mbhc->headset_jack,
                    (mbhc->hph_status | SND_JACK_MECHANICAL),
                    WCD_MBHC_JACK_MASK);
        wcd_mbhc_clr_and_turnon_hph_padac(mbhc);
    }
    pr_debug("%s: leave hph_status %x\n", __func__, mbhc->hph_status);
}

compute_impedance

static const struct wcd_mbhc_cb mbhc_cb = {
    .enable_mb_source = msm8x16_wcd_enable_ext_mb_source,
    .trim_btn_reg = msm8x16_trim_btn_reg,
    .compute_impedance = msm8x16_wcd_mbhc_calc_impedance,
    .set_micbias_value = msm8x16_wcd_set_micb_v,
    .set_auto_zeroing = msm8x16_wcd_set_auto_zeroing,
    .get_hwdep_fw_cal = msm8x16_wcd_get_hwdep_fw_cal,
    .set_cap_mode = msm8x16_wcd_configure_cap,
    .register_notifier = msm8x16_register_notifier,
    .request_irq = msm8x16_wcd_request_irq,
    .irq_control = wcd9xxx_spmi_irq_control,
    .free_irq = msm8x16_wcd_free_irq,
    .clk_setup = msm8x16_mbhc_clk_setup,
    .map_btn_code_to_num = msm8x16_mbhc_map_btn_code_to_num,
    .lock_sleep = msm8x16_spmi_lock_sleep,
    .micbias_enable_status = msm8x16_wcd_micb_en_status,
    .mbhc_bias = msm8x16_wcd_enable_master_bias,
    .mbhc_common_micb_ctrl = msm8x16_wcd_mbhc_common_micb_ctrl,
    .micb_internal = msm8x16_wcd_mbhc_internal_micbias_ctrl,
    .hph_pa_on_status = msm8x16_wcd_mbhc_hph_pa_on_status,
    .set_btn_thr = msm8x16_wcd_mbhc_program_btn_thr,
    .extn_use_mb = msm8x16_wcd_use_mb,
};
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值