欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

高通耳机阻抗估算流程

程序员文章站 2022-06-10 09:58:41
Msm-analog-cdc.c (vendor\qcom\opensource\audio-kernel\asoc\codecs\sdm660_cdc)static struct platform_driver msm_anlg_codec_driver = {.driver= {.owner = THIS_MODULE,.name = DRV_NAME,.of_match_table = of_match_ptr(sdm660_co....

Msm-analog-cdc.c (vendor\qcom\opensource\audio-kernel\asoc\codecs\sdm660_cdc)  模拟编解码器驱动

static struct platform_driver msm_anlg_codec_driver = {
	.driver		= {
		.owner          = THIS_MODULE,
		.name           = DRV_NAME,
		.of_match_table = of_match_ptr(sdm660_codec_of_match)
	},
	.probe          = msm_anlg_cdc_probe,
	.remove         = msm_anlg_cdc_remove,
};

msm_anlg_cdc_probe()

static int msm_anlg_cdc_probe(struct platform_device *pdev)
{
	int ret = 0;
	struct sdm660_cdc_priv *sdm660_cdc = NULL;
	struct sdm660_cdc_pdata *pdata;
	int adsp_state;
	const char *parent_dev = NULL;
	adsp_state = apr_get_subsys_state();
	if (adsp_state == APR_SUBSYS_DOWN ||
		!q6core_is_adsp_ready()) {
		dev_err(&pdev->dev, "Adsp is not loaded yet %d\n",
			adsp_state);
		return -EPROBE_DEFER;
	}
	device_init_wakeup(&pdev->dev, true);

	if (pdev->dev.of_node) {
		dev_dbg(&pdev->dev, "%s:Platform data from device tree\n",
			__func__);
		pdata = msm_anlg_cdc_populate_dt_pdata(&pdev->dev);
		pdev->dev.platform_data = pdata;
	} else {
		dev_dbg(&pdev->dev, "%s:Platform data from board file\n",
			__func__);
		pdata = pdev->dev.platform_data;
	}
	if (pdata == NULL) {
		dev_err(&pdev->dev, "%s:Platform data failed to populate\n",
			__func__);
		goto rtn;
	}
	sdm660_cdc = devm_kzalloc(&pdev->dev, sizeof(struct sdm660_cdc_priv),
				     GFP_KERNEL);
	if (sdm660_cdc == NULL) {
		ret = -ENOMEM;
		goto rtn;
	}

	sdm660_cdc->dev = &pdev->dev;
	ret = msm_anlg_cdc_init_supplies(sdm660_cdc, pdata);
	if (ret) {
		dev_err(&pdev->dev, "%s: Fail to enable Codec supplies\n",
			__func__);
		goto rtn;
	}
	ret = msm_anlg_cdc_enable_static_supplies(sdm660_cdc, pdata);
	if (ret) {
		dev_err(&pdev->dev,
			"%s: Fail to enable Codec pre-reset supplies\n",
			__func__);
		goto rtn;
	}
	/* Allow supplies to be ready */
	usleep_range(5, 6);

	wcd9xxx_spmi_set_dev(pdev, 0);
	wcd9xxx_spmi_set_dev(pdev, 1);
	if (wcd9xxx_spmi_irq_init()) {
		dev_err(&pdev->dev,
			"%s: irq initialization failed\n", __func__);
	} else {
		dev_dbg(&pdev->dev,
			"%s: irq initialization passed\n", __func__);
	}
	dev_set_drvdata(&pdev->dev, sdm660_cdc);

	ret = snd_soc_register_codec(&pdev->dev,
				     &soc_codec_dev_sdm660_cdc,
				     msm_anlg_cdc_i2s_dai,
				     ARRAY_SIZE(msm_anlg_cdc_i2s_dai));
	if (ret) {
		dev_err(&pdev->dev,
			"%s:snd_soc_register_codec failed with error %d\n",
			__func__, ret);
		goto err_supplies;
	}
	BLOCKING_INIT_NOTIFIER_HEAD(&sdm660_cdc->notifier);
	BLOCKING_INIT_NOTIFIER_HEAD(&sdm660_cdc->notifier_mbhc);

	sdm660_cdc->dig_plat_data.handle = (void *) sdm660_cdc;
	sdm660_cdc->dig_plat_data.set_compander_mode = set_compander_mode;
	sdm660_cdc->dig_plat_data.update_clkdiv = update_clkdiv;
	sdm660_cdc->dig_plat_data.get_cdc_version = get_cdc_version;
	sdm660_cdc->dig_plat_data.register_notifier =
					msm_anlg_cdc_dig_register_notifier;
	INIT_WORK(&sdm660_cdc->msm_anlg_add_child_devices_work,
		  msm_anlg_add_child_devices);
	schedule_work(&sdm660_cdc->msm_anlg_add_child_devices_work);
	parent_dev = pdev->dev.parent->of_node->full_name;
	if (parent_dev) {
		snprintf(sdm660_cdc->pmic_analog, PMIC_ANOLOG_SIZE, "spmi0-0%s",
			 parent_dev + strlen(parent_dev)-1);
		parent_dev = NULL;
	}
	return ret;
err_supplies:
	msm_anlg_cdc_disable_supplies(sdm660_cdc, pdata);
rtn:
	return ret;
}

ret = snd_soc_register_codec(&pdev->dev,
                     &soc_codec_dev_sdm660_cdc,
                     msm_anlg_cdc_i2s_dai,
                     ARRAY_SIZE(msm_anlg_cdc_i2s_dai));

static struct snd_soc_codec_driver soc_codec_dev_sdm660_cdc = {
	.probe	= msm_anlg_cdc_soc_probe,
	.remove	= msm_anlg_cdc_soc_remove,
	.suspend = msm_anlg_cdc_suspend,
	.resume = msm_anlg_cdc_resume,
	.reg_word_size = 1,
	.get_regmap = msm_anlg_get_regmap,
	.component_driver = {
		.controls = msm_anlg_cdc_snd_controls,
		.num_controls = ARRAY_SIZE(msm_anlg_cdc_snd_controls),
		.dapm_widgets = msm_anlg_cdc_dapm_widgets,
		.num_dapm_widgets = ARRAY_SIZE(msm_anlg_cdc_dapm_widgets),
		.dapm_routes = audio_map,
		.num_dapm_routes = ARRAY_SIZE(audio_map),
	},
};

msm_anlg_cdc_soc_probe()

wcd_mbhc_init(&sdm660_cdc->mbhc, codec, &mbhc_cb, &intr_ids,
		      wcd_mbhc_registers, true);
static const struct wcd_mbhc_cb mbhc_cb = {
	.enable_mb_source = msm_anlg_cdc_enable_ext_mb_source,
	.trim_btn_reg = msm_anlg_cdc_trim_btn_reg,
	.compute_impedance = msm_anlg_cdc_mbhc_calc_impedance,//估算阻抗
	.set_micbias_value = msm_anlg_cdc_set_micb_v,//设置mic偏置值
	.set_auto_zeroing = msm_anlg_cdc_set_auto_zeroing,//设置自动调零
	.get_hwdep_fw_cal = msm_anlg_cdc_get_hwdep_fw_cal,
	.set_cap_mode = msm_anlg_cdc_configure_cap,
	.register_notifier = msm_anlg_cdc_mbhc_register_notifier,//注册通知
	.request_irq = msm_anlg_cdc_request_irq,//请求中断
	.irq_control = wcd9xxx_spmi_irq_control,//中断控制
	.free_irq = msm_anlg_cdc_free_irq,
	.clk_setup = msm_anlg_cdc_mbhc_clk_setup,
	.map_btn_code_to_num = msm_anlg_cdc_mbhc_map_btn_code_to_num,
	.lock_sleep = msm_anlg_cdc_spmi_lock_sleep,
	.micbias_enable_status = msm_anlg_cdc_micb_en_status,
	.mbhc_bias = msm_anlg_cdc_enable_master_bias,
	.mbhc_common_micb_ctrl = msm_anlg_cdc_mbhc_common_micb_ctrl,
	.micb_internal = msm_anlg_cdc_mbhc_internal_micbias_ctrl,
	.hph_pa_on_status = msm_anlg_cdc_mbhc_hph_pa_on_status,
	.set_btn_thr = msm_anlg_cdc_mbhc_program_btn_thr,
	.extn_use_mb = msm_anlg_cdc_use_mb,
};

msm_anlg_cdc_mbhc_calc_impedance()计算阻抗值

static void msm_anlg_cdc_mbhc_calc_impedance(struct wcd_mbhc *mbhc,
					     uint32_t *zl, uint32_t *zr)
{
	struct snd_soc_codec *codec = mbhc->codec;
	struct sdm660_cdc_priv *sdm660_cdc =
					snd_soc_codec_get_drvdata(codec);
	s16 impedance_l, impedance_r;
	s16 impedance_l_fixed;
	s16 reg0, reg1, reg2, reg3, reg4;
	bool high = false;
	bool min_range_used =  false;

	WCD_MBHC_RSC_ASSERT_LOCKED(mbhc);
	reg0 = snd_soc_read(codec, MSM89XX_PMIC_ANALOG_MBHC_DBNC_TIMER);
	reg1 = snd_soc_read(codec, MSM89XX_PMIC_ANALOG_MBHC_BTN2_ZDETH_CTL);
	reg2 = snd_soc_read(codec, MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2);
	reg3 = snd_soc_read(codec, MSM89XX_PMIC_ANALOG_MICB_2_EN);
	reg4 = snd_soc_read(codec, MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL);

	sdm660_cdc->imped_det_pin = WCD_MBHC_DET_BOTH;
	mbhc->hph_type = WCD_MBHC_HPH_NONE;

	/* 禁用FSM和micbias,启用上拉*/
	snd_soc_update_bits(codec,
			MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL,
			0x80, 0x00);
	snd_soc_update_bits(codec,
			MSM89XX_PMIC_ANALOG_MICB_2_EN,
			0xA5, 0x25);
	/*
	 * Enable legacy electrical detection current sources
	 * and disable fast ramp and enable manual switching
	 * of extra capacitance
	 */
	dev_dbg(codec->dev, "%s: Setup for impedance det\n", __func__);

	msm_anlg_cdc_set_ref_current(codec, I_h4_UA);

	snd_soc_update_bits(codec,
			MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2,
			0x06, 0x02);
	snd_soc_update_bits(codec,
			MSM89XX_PMIC_ANALOG_MBHC_DBNC_TIMER,
			0x02, 0x02);
	snd_soc_update_bits(codec,
			MSM89XX_PMIC_ANALOG_MBHC_BTN2_ZDETH_CTL,
			0x02, 0x00);

	dev_dbg(codec->dev, "%s: Start performing impedance detection\n",
		 __func__);
    //开始阻抗检测,进入此函数
	wcd_mbhc_meas_imped(codec, &impedance_l, &impedance_r);

	if (impedance_l > 2 || impedance_r > 2) {
		high = true;
		if (!mbhc->mbhc_cfg->mono_stero_detection) {
			/* Set ZDET_CHG to 0  to discharge ramp */
			snd_soc_update_bits(codec,
					MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL,
					0x02, 0x00);
			/* wait 40ms for the discharge ramp to complete */
			usleep_range(40000, 40100);
			snd_soc_update_bits(codec,
				MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL,
				0x03, 0x00);
			sdm660_cdc->imped_det_pin = (impedance_l > 2 &&
						      impedance_r > 2) ?
						      WCD_MBHC_DET_NONE :
						      ((impedance_l > 2) ?
						      WCD_MBHC_DET_HPHR :
						      WCD_MBHC_DET_HPHL);
			if (sdm660_cdc->imped_det_pin == WCD_MBHC_DET_NONE)
				goto exit;
		} else {
			if (get_codec_version(sdm660_cdc) >= CAJON) {
				if (impedance_l == 63 && impedance_r == 63) {
					dev_dbg(codec->dev,
						"%s: HPHL and HPHR are floating\n",
						 __func__);
					sdm660_cdc->imped_det_pin =
							WCD_MBHC_DET_NONE;
					mbhc->hph_type = WCD_MBHC_HPH_NONE;
				} else if (impedance_l == 63
					   && impedance_r < 63) {
					dev_dbg(codec->dev,
						"%s: Mono HS with HPHL floating\n",
						 __func__);
					sdm660_cdc->imped_det_pin =
							WCD_MBHC_DET_HPHR;
					mbhc->hph_type = WCD_MBHC_HPH_MONO;
				} else if (impedance_r == 63 &&
					   impedance_l < 63) {
					dev_dbg(codec->dev,
						"%s: Mono HS with HPHR floating\n",
						 __func__);
					sdm660_cdc->imped_det_pin =
							WCD_MBHC_DET_HPHL;
					mbhc->hph_type = WCD_MBHC_HPH_MONO;
				} else if (impedance_l > 3 && impedance_r > 3 &&
					(impedance_l == impedance_r)) {
					snd_soc_update_bits(codec,
					MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2,
					0x06, 0x06);
					wcd_mbhc_meas_imped(codec, &impedance_l,
							    &impedance_r);
					if (impedance_r == impedance_l)
						dev_dbg(codec->dev,
							"%s: Mono Headset\n",
							__func__);
						sdm660_cdc->imped_det_pin =
							WCD_MBHC_DET_NONE;
						mbhc->hph_type =
							WCD_MBHC_HPH_MONO;
				} else {
					dev_dbg(codec->dev,
						"%s: STEREO headset is found\n",
						 __func__);
					sdm660_cdc->imped_det_pin =
							WCD_MBHC_DET_BOTH;
					mbhc->hph_type = WCD_MBHC_HPH_STEREO;
				}
			}
		}
	}

	msm_anlg_cdc_set_ref_current(codec, I_pt5_UA);
	msm_anlg_cdc_set_ref_current(codec, I_14_UA);

	/* Enable RAMP_L , RAMP_R & ZDET_CHG*/
	snd_soc_update_bits(codec,
			MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL,
			0x03, 0x03);
	snd_soc_update_bits(codec,
			MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL,
			0x02, 0x02);
	/* wait for 50msec for the HW to apply ramp on HPHL and HPHR */
	usleep_range(50000, 50100);
	/* Enable ZDET_DISCHG_CAP_CTL  to add extra capacitance */
	snd_soc_update_bits(codec,
			MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL,
			0x01, 0x01);
	/* wait for 5msec for the voltage to get stable */
	usleep_range(5000, 5100);

	wcd_mbhc_meas_imped(codec, &impedance_l, &impedance_r);

	min_range_used = msm_anlg_cdc_adj_ref_current(codec,
						&impedance_l, &impedance_r);
	if (!mbhc->mbhc_cfg->mono_stero_detection) {
		/* Set ZDET_CHG to 0  to discharge ramp */
		snd_soc_update_bits(codec,
				MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL,
				0x02, 0x00);
		/* wait for 40msec for the capacitor to discharge */
		usleep_range(40000, 40100);
		snd_soc_update_bits(codec,
				MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL,
				0x03, 0x00);
		goto exit;
	}

	/* we are setting ref current to the minimun range or the measured
	 * value larger than the minimum value, so min_range_used is true.
	 * If the headset is mono headset with either HPHL or HPHR floating
	 * then we have already done the mono stereo detection and do not
	 * need to continue further.
	 */

	if (!min_range_used ||
	    sdm660_cdc->imped_det_pin == WCD_MBHC_DET_HPHL ||
	    sdm660_cdc->imped_det_pin == WCD_MBHC_DET_HPHR)
		goto exit;


	/* Disable Set ZDET_CONN_RAMP_L and enable ZDET_CONN_FIXED_L */
	snd_soc_update_bits(codec,
			MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL,
			0x02, 0x00);
	snd_soc_update_bits(codec,
			MSM89XX_PMIC_ANALOG_MBHC_BTN1_ZDETM_CTL,
			0x02, 0x02);
	/* Set ZDET_CHG to 0  */
	snd_soc_update_bits(codec,
			MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL,
			0x02, 0x00);
	/* wait for 40msec for the capacitor to discharge */
	usleep_range(40000, 40100);

	/* Set ZDET_CONN_RAMP_R to 0  */
	snd_soc_update_bits(codec,
			MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL,
			0x01, 0x00);
	/* Enable ZDET_L_MEAS_EN */
	snd_soc_update_bits(codec,
			MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL,
			0x08, 0x08);
	/* wait for 2msec for the HW to compute left inpedance value */
	usleep_range(2000, 2100);
	/* Read Left impedance value from Result1 */
	impedance_l_fixed = snd_soc_read(codec,
			MSM89XX_PMIC_ANALOG_MBHC_BTN_RESULT);
	/* Disable ZDET_L_MEAS_EN */
	snd_soc_update_bits(codec,
			MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL,
			0x08, 0x00);
	/*
	 * Assume impedance_l is L1, impedance_l_fixed is L2.
	 * If the following condition is met, we can take this
	 * headset as mono one with impedance of L2.
	 * Otherwise, take it as stereo with impedance of L1.
	 * Condition:
	 * abs[(L2-0.5L1)/(L2+0.5L1)] < abs [(L2-L1)/(L2+L1)]
	 */
	if ((abs(impedance_l_fixed - impedance_l/2) *
		(impedance_l_fixed + impedance_l)) >=
		(abs(impedance_l_fixed - impedance_l) *
		(impedance_l_fixed + impedance_l/2))) {
		dev_dbg(codec->dev,
			"%s: STEREO plug type detected\n",
			 __func__);
		mbhc->hph_type = WCD_MBHC_HPH_STEREO;
	} else {
		dev_dbg(codec->dev,
			"%s: MONO plug type detected\n",
			__func__);
		mbhc->hph_type = WCD_MBHC_HPH_MONO;
		impedance_l = impedance_l_fixed;
	}
	/* Enable ZDET_CHG  */
	snd_soc_update_bits(codec,
			MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL,
			0x02, 0x02);
	/* wait for 10msec for the capacitor to charge */
	usleep_range(10000, 10100);
	snd_soc_update_bits(codec,
			MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL,
			0x02, 0x02);
	snd_soc_update_bits(codec,
			MSM89XX_PMIC_ANALOG_MBHC_BTN1_ZDETM_CTL,
			0x02, 0x00);
	/* Set ZDET_CHG to 0  to discharge HPHL */
	snd_soc_update_bits(codec,
			MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL,
			0x02, 0x00);
	/* wait for 40msec for the capacitor to discharge */
	usleep_range(40000, 40100);
	snd_soc_update_bits(codec,
			MSM89XX_PMIC_ANALOG_MBHC_BTN0_ZDETL_CTL,
			0x02, 0x00);

exit:
	snd_soc_write(codec, MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL, reg4);
	snd_soc_write(codec, MSM89XX_PMIC_ANALOG_MICB_2_EN, reg3);
	snd_soc_write(codec, MSM89XX_PMIC_ANALOG_MBHC_BTN2_ZDETH_CTL, reg1);
	snd_soc_write(codec, MSM89XX_PMIC_ANALOG_MBHC_DBNC_TIMER, reg0);
	snd_soc_write(codec, MSM89XX_PMIC_ANALOG_MBHC_DET_CTL_2, reg2);
	msm_anlg_cdc_compute_impedance(codec, impedance_l, impedance_r,
				      zl, zr, high);

	dev_dbg(codec->dev, "%s: RL %d ohm, RR %d ohm\n", __func__, *zl, *zr);
	dev_dbg(codec->dev, "%s: Impedance detection completed\n", __func__);
}

wcd_mbhc_meas_imped()    阻抗检测

static void wcd_mbhc_meas_imped(struct snd_soc_codec *codec,
				s16 *impedance_l, s16 *impedance_r)
{
	struct sdm660_cdc_priv *sdm660_cdc =
					snd_soc_codec_get_drvdata(codec);

	if ((sdm660_cdc->imped_det_pin == WCD_MBHC_DET_BOTH) ||
	    (sdm660_cdc->imped_det_pin == WCD_MBHC_DET_HPHL)) {
		/* Enable ZDET_L_MEAS_EN */
		snd_soc_update_bits(codec,
				MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL,
				0x08, 0x08);
		/* Wait for 2ms for measurement to complete */
		usleep_range(2000, 2100);
		/* Read Left impedance value from Result1 */
		*impedance_l = snd_soc_read(codec,
				MSM89XX_PMIC_ANALOG_MBHC_BTN_RESULT);
		/* Enable ZDET_R_MEAS_EN */
		snd_soc_update_bits(codec,
				MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL,
				0x08, 0x00);
	}
	if ((sdm660_cdc->imped_det_pin == WCD_MBHC_DET_BOTH) ||
	    (sdm660_cdc->imped_det_pin == WCD_MBHC_DET_HPHR)) {
		snd_soc_update_bits(codec,
				MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL,
				0x04, 0x04);
		/* Wait for 2ms for measurement to complete */
		usleep_range(2000, 2100);
		/* Read Right impedance value from Result1 */
		*impedance_r = snd_soc_read(codec,
				MSM89XX_PMIC_ANALOG_MBHC_BTN_RESULT);
		snd_soc_update_bits(codec,
				MSM89XX_PMIC_ANALOG_MBHC_FSM_CTL,
				0x04, 0x00);
	}
}

msm_anlg_cdc_compute_impedance()    估算阻抗

static void msm_anlg_cdc_compute_impedance(struct snd_soc_codec *codec, s16 l,
					   s16 r, uint32_t *zl, uint32_t *zr,
					   bool high)
{
	struct sdm660_cdc_priv *sdm660_cdc =
					snd_soc_codec_get_drvdata(codec);
	uint32_t rl = 0, rr = 0;
	struct wcd_imped_i_ref R = sdm660_cdc->imped_i_ref;
	int codec_ver = get_codec_version(sdm660_cdc);

	switch (codec_ver) {
	case TOMBAK_1_0:
	case TOMBAK_2_0:
	case CONGA:
		if (high) {
			dev_dbg(codec->dev,
				"%s: This plug has high range impedance\n",
				 __func__);
			rl = (uint32_t)(((100 * (l * 400 - 200))/96) - 230);
			rr = (uint32_t)(((100 * (r * 400 - 200))/96) - 230);
		} else {
			dev_dbg(codec->dev,
				"%s: This plug has low range impedance\n",
				 __func__);
			rl = (uint32_t)(((1000 * (l * 2 - 1))/1165) - (13/10));
			rr = (uint32_t)(((1000 * (r * 2 - 1))/1165) - (13/10));
		}
		break;
	case CAJON:
	case CAJON_2_0:
	case DIANGU:
	case DRAX_CDC:
		if (sdm660_cdc->imped_det_pin == WCD_MBHC_DET_HPHL) {
			rr = (uint32_t)(((DEFAULT_MULTIPLIER * (10 * r - 5)) -
			   (DEFAULT_OFFSET * DEFAULT_GAIN))/DEFAULT_GAIN);
			rl = (uint32_t)(((10000 * (R.multiplier * (10 * l - 5)))
			      - R.offset * R.gain_adj)/(R.gain_adj * 100));
		} else if (sdm660_cdc->imped_det_pin == WCD_MBHC_DET_HPHR) {
			rr = (uint32_t)(((10000 * (R.multiplier * (10 * r - 5)))
			      - R.offset * R.gain_adj)/(R.gain_adj * 100));
			rl = (uint32_t)(((DEFAULT_MULTIPLIER * (10 * l - 5))-
			   (DEFAULT_OFFSET * DEFAULT_GAIN))/DEFAULT_GAIN);
		} else if (sdm660_cdc->imped_det_pin == WCD_MBHC_DET_NONE) {
			rr = (uint32_t)(((DEFAULT_MULTIPLIER * (10 * r - 5)) -
			   (DEFAULT_OFFSET * DEFAULT_GAIN))/DEFAULT_GAIN);
			rl = (uint32_t)(((DEFAULT_MULTIPLIER * (10 * l - 5))-
			   (DEFAULT_OFFSET * DEFAULT_GAIN))/DEFAULT_GAIN);
		} else {
			rr = (uint32_t)(((10000 * (R.multiplier * (10 * r - 5)))
			      - R.offset * R.gain_adj)/(R.gain_adj * 100));
			rl = (uint32_t)(((10000 * (R.multiplier * (10 * l - 5)))
			      - R.offset * R.gain_adj)/(R.gain_adj * 100));
		}
		break;
	default:
		dev_dbg(codec->dev, "%s: No codec mentioned\n", __func__);
		break;
	}
	*zl = rl;
	*zr = rr;
}

根据不同的编解码器,用了不同的算法把阻抗值传到了相应的地址。至此阻抗估算的大体流程就结束了。

本文地址:https://blog.csdn.net/qq_36247447/article/details/108128965

相关标签: 耳机 android