diff --git a/sound/soc/codecs/wcd934x/wcd934x-mbhc.c b/sound/soc/codecs/wcd934x/wcd934x-mbhc.c index 5dbdb9a2df00..0e0c26dc72cd 100644 --- a/sound/soc/codecs/wcd934x/wcd934x-mbhc.c +++ b/sound/soc/codecs/wcd934x/wcd934x-mbhc.c @@ -905,6 +905,29 @@ static const struct snd_kcontrol_new impedance_detect_controls[] = { tavil_hph_impedance_get, NULL), }; +/* + * tavil_mbhc_get_impedance: get impedance of headphone left and right channels + * @wcd934x_mbhc: handle to struct wcd934x_mbhc * + * @zl: handle to left-ch impedance + * @zr: handle to right-ch impedance + * return 0 for success or error code in case of failure + */ +int tavil_mbhc_get_impedance(struct wcd934x_mbhc *wcd934x_mbhc, + uint32_t *zl, uint32_t *zr) +{ + if (!wcd934x_mbhc) { + pr_err("%s: mbhc not initialized!\n", __func__); + return -EINVAL; + } + if (!zl || !zr) { + pr_err("%s: zl or zr null!\n", __func__); + return -EINVAL; + } + + return wcd_mbhc_get_impedance(&wcd934x_mbhc->wcd_mbhc, zl, zr); +} +EXPORT_SYMBOL(tavil_mbhc_get_impedance); + /* * tavil_mbhc_hs_detect: starts mbhc insertion/removal functionality * @codec: handle to snd_soc_codec * diff --git a/sound/soc/codecs/wcd934x/wcd934x-mbhc.h b/sound/soc/codecs/wcd934x/wcd934x-mbhc.h index 3c88a12194af..0b27f3f62b02 100644 --- a/sound/soc/codecs/wcd934x/wcd934x-mbhc.h +++ b/sound/soc/codecs/wcd934x/wcd934x-mbhc.h @@ -44,6 +44,8 @@ extern int tavil_mbhc_hs_detect(struct snd_soc_codec *codec, extern void tavil_mbhc_deinit(struct snd_soc_codec *codec); extern int tavil_mbhc_post_ssr_init(struct wcd934x_mbhc *mbhc, struct snd_soc_codec *codec); +extern int tavil_mbhc_get_impedance(struct wcd934x_mbhc *wcd934x_mbhc, + uint32_t *zl, uint32_t *zr); #endif /* __WCD934X_MBHC_H__ */ diff --git a/sound/soc/codecs/wcd934x/wcd934x.c b/sound/soc/codecs/wcd934x/wcd934x.c index 8be608c8511c..f797babe41ed 100644 --- a/sound/soc/codecs/wcd934x/wcd934x.c +++ b/sound/soc/codecs/wcd934x/wcd934x.c @@ -175,6 +175,7 @@ enum { VI_SENSE_2, AUDIO_NOMINAL, HPH_PA_DELAY, + CLSH_Z_CONFIG, }; enum { @@ -2241,6 +2242,7 @@ static int tavil_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, u8 dem_inp; int ret = 0; struct tavil_dsd_config *dsd_conf = tavil->dsd_config; + uint32_t impedl = 0, impedr = 0; dev_dbg(codec->dev, "%s wname: %s event: %d hph_mode: %d\n", __func__, w->name, event, hph_mode); @@ -2277,6 +2279,18 @@ static int tavil_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, WCD_CLSH_EVENT_PRE_DAC, WCD_CLSH_STATE_HPHL, hph_mode); + + ret = tavil_mbhc_get_impedance(tavil->mbhc, + &impedl, &impedr); + if (!ret) { + wcd_clsh_imped_config(codec, impedl, false); + set_bit(CLSH_Z_CONFIG, &tavil->status_mask); + } else { + dev_dbg(codec->dev, "%s: Failed to get mbhc impedance %d\n", + __func__, ret); + ret = 0; + } + break; case SND_SOC_DAPM_POST_PMD: /* 1000us required as per HW requirement */ @@ -2295,6 +2309,11 @@ static int tavil_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, WCD934X_HPH_NEW_INT_RDAC_GAIN_CTL, 0xF0, 0x0); + + if (test_bit(CLSH_Z_CONFIG, &tavil->status_mask)) { + wcd_clsh_imped_config(codec, impedl, true); + clear_bit(CLSH_Z_CONFIG, &tavil->status_mask); + } break; default: break;