ASoC: wcd9335: Add support mono/stereo plug detection

Headphone can be mono/stereo type. Add support to detect
whether inserted plug is mono or stereo headset.

Change-Id: I9fff758748b7fd20da81f3f7b2c7fcac290cc3c3
Signed-off-by: Phani Kumar Uppalapati <phaniu@codeaurora.org>
Signed-off-by: Laxminath Kasam <lkasam@codeaurora.org>
This commit is contained in:
Laxminath Kasam 2015-09-23 04:59:11 +05:30 committed by Gerrit - the friendly Code Review server
parent 1207eccf4d
commit 3e02e10444
2 changed files with 47 additions and 1 deletions

View file

@ -22,6 +22,8 @@
#define WCD_MBHC_KEYCODE_NUM 8
#define WCD_MBHC_USLEEP_RANGE_MARGIN_US 100
#define WCD_MBHC_THR_HS_MICB_MV 2700
/* z value defined in Ohms */
#define WCD_MONO_HS_MIN_THR 2
#define WCD_MBHC_STRINGIFY(s) __stringify(s)
struct wcd_mbhc;

View file

@ -1417,7 +1417,8 @@ static void tasha_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl,
struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
s16 reg0, reg1, reg2, reg3, reg4;
int32_t z1L, z1R;
int32_t z1L, z1R, z1Ls;
int zMono, z_diff1, z_diff2;
bool is_fsm_disable = false;
bool is_change = false;
struct tasha_mbhc_zdet_param zdet_param[] = {
@ -1536,6 +1537,49 @@ right_ch_impedance:
dev_dbg(codec->dev, "%s: impedance on HPH_R = %d(ohms)\n",
__func__, *zr);
/* mono/stereo detection */
if ((*zl == TASHA_ZDET_FLOATING_IMPEDANCE) &&
(*zr == TASHA_ZDET_FLOATING_IMPEDANCE)) {
dev_dbg(codec->dev,
"%s: plug type is invalid or extension cable\n",
__func__);
goto zdet_complete;
}
if ((*zl == TASHA_ZDET_FLOATING_IMPEDANCE) ||
(*zr == TASHA_ZDET_FLOATING_IMPEDANCE) ||
((*zl < WCD_MONO_HS_MIN_THR) && (*zr > WCD_MONO_HS_MIN_THR)) ||
((*zl > WCD_MONO_HS_MIN_THR) && (*zr < WCD_MONO_HS_MIN_THR))) {
dev_dbg(codec->dev,
"%s: Mono plug type with one ch floating or shorted to GND\n",
__func__);
mbhc->hph_type = WCD_MBHC_HPH_MONO;
goto zdet_complete;
}
snd_soc_update_bits(codec, WCD9335_HPH_R_ATEST, 0x02, 0x02);
snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x40, 0x01);
if (*zl < (TASHA_ZDET_VAL_32/1000))
tasha_mbhc_zdet_ramp(codec, &zdet_param[0], &z1Ls, NULL, d1);
else
tasha_mbhc_zdet_ramp(codec, &zdet_param[1], &z1Ls, NULL, d1);
snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x40, 0x00);
snd_soc_update_bits(codec, WCD9335_HPH_R_ATEST, 0x02, 0x00);
z1Ls /= 1000;
tasha_wcd_mbhc_qfuse_cal(codec, &z1Ls, 0);
/* parallel of left Z and 9 ohm pull down resistor */
zMono = ((*zl) * 9) / ((*zl) + 9);
z_diff1 = (z1Ls > zMono) ? (z1Ls - zMono) : (zMono - z1Ls);
z_diff2 = ((*zl) > z1Ls) ? ((*zl) - z1Ls) : (z1Ls - (*zl));
if ((z_diff1 * (*zl + z1Ls)) > (z_diff2 * (z1Ls + zMono))) {
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;
}
zdet_complete:
snd_soc_write(codec, WCD9335_ANA_MBHC_BTN5, reg0);
snd_soc_write(codec, WCD9335_ANA_MBHC_BTN6, reg1);
snd_soc_write(codec, WCD9335_ANA_MBHC_BTN7, reg2);