From 599818e2a22e55a5abb4a241da0c60bf128e6e78 Mon Sep 17 00:00:00 2001 From: yaozm1 Date: Thu, 21 Mar 2019 13:55:59 +0800 Subject: [PATCH] Asoc:Apply cirrus' patch to fix hp detect issue From: Charles Keepax Date: Tue, 19 Mar 2019 17:29:02 +0000 Subject: [PATCH] ASoC: madera: Force EP demux over to headphones to run HPDET The EP demux needs to be set to the headphones for the HPDET to run the correct value. Change-Id: I7bcc0cdca28b2a1b3144ee03f3af84056ddcaba4 Signed-off-by: Charles Keepax Signed-off-by: yaozm1 Change-Id: I24c057510dfff3b531cd75e3c8aafa255727e87e Reviewed-on: https://gerrit.mot.com/1324759 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Xiangpo Zhao Submit-Approved: Jira Key --- drivers/extcon/extcon-madera.c | 79 +++++++++------------------------ include/linux/mfd/madera/core.h | 1 + sound/soc/codecs/madera.c | 40 ++++++++++------- 3 files changed, 46 insertions(+), 74 deletions(-) diff --git a/drivers/extcon/extcon-madera.c b/drivers/extcon/extcon-madera.c index 0d4420ac0f9a..e4b999b096fe 100755 --- a/drivers/extcon/extcon-madera.c +++ b/drivers/extcon/extcon-madera.c @@ -769,9 +769,7 @@ static void madera_jds_timeout_work(struct work_struct *work) static void madera_extcon_hp_clamp(struct madera_extcon *info, bool clamp) { struct madera *madera = info->madera; - unsigned int mask = 0, val = 0; - unsigned int edre_reg = 0, edre_val = 0; - unsigned int ep_sel = 0; + unsigned int mask = 0, ep_mask = 0, val = 0; int ret; snd_soc_dapm_mutex_lock(madera->dapm); @@ -779,38 +777,14 @@ static void madera_extcon_hp_clamp(struct madera_extcon *info, bool clamp) switch (madera->type) { case CS47L15: case CS47L35: - case CS47L92: - case CS47L93: - /* - * check whether audio is routed to EPOUT, do not disable OUT1 - * in that case - */ - regmap_read(madera->regmap, MADERA_OUTPUT_ENABLES_1, &ep_sel); - ep_sel &= MADERA_EP_SEL_MASK; - break; - default: - break; - }; - - switch (madera->type) { - case CS47L35: + ep_mask = MADERA_EP_SEL_MASK; break; case CS47L85: case WM1840: - edre_reg = MADERA_EDRE_MANUAL; - mask = MADERA_HP1L_SHRTO | MADERA_HP1L_FLWR | MADERA_HP1L_SHRTI; - if (clamp) { - val = MADERA_HP1L_SHRTO; - edre_val = MADERA_EDRE_OUT1L_MANUAL | - MADERA_EDRE_OUT1R_MANUAL; - } else { - val = MADERA_HP1L_FLWR | MADERA_HP1L_SHRTI; - edre_val = 0; - } break; default: mask = MADERA_HPD_OVD_ENA_SEL_MASK; - if (clamp) + if (!clamp) val = MADERA_HPD_OVD_ENA_SEL_MASK; else val = 0; @@ -819,13 +793,14 @@ static void madera_extcon_hp_clamp(struct madera_extcon *info, bool clamp) madera->out_clamp[0] = clamp; - /* Keep the HP output stages disabled while doing the clamp */ - if (clamp && !ep_sel) { + /* Keep the HP output stages disabled while disabling the clamp */ + if (!clamp) { ret = regmap_update_bits(madera->regmap, MADERA_OUTPUT_ENABLES_1, - (MADERA_OUT1L_ENA | + ep_mask | + ((MADERA_OUT1L_ENA | MADERA_OUT1R_ENA) << - (2 * (info->pdata->output - 1)), + (2 * (info->pdata->output - 1))), 0); if (ret) dev_warn(info->dev, @@ -833,33 +808,13 @@ static void madera_extcon_hp_clamp(struct madera_extcon *info, bool clamp) ret); } - if (edre_reg && !ep_sel) { - ret = regmap_update_bits(madera->regmap, edre_reg, - MADERA_EDRE_OUT1L_MANUAL_MASK | - MADERA_EDRE_OUT1R_MANUAL_MASK, - edre_val); - if (ret) - dev_warn(info->dev, - "Failed to set EDRE Manual: %d\n", ret); - } - - dev_warn(info->dev, "%s clamp mask=0x%x val=0x%x\n", + dev_dbg(info->dev, "%s clamp mask=0x%x val=0x%x\n", clamp ? "Setting" : "Clearing", mask, val); switch (madera->type) { case CS47L35: - break; case CS47L85: case WM1840: - ret = regmap_update_bits(madera->regmap, - MADERA_HP_CTRL_1L, mask, val); - if (ret) - dev_warn(info->dev, "Failed to do clamp: %d\n", ret); - - ret = regmap_update_bits(madera->regmap, - MADERA_HP_CTRL_1R, mask, val); - if (ret) - dev_warn(info->dev, "Failed to do clamp: %d\n", ret); break; default: ret = regmap_update_bits(madera->regmap, @@ -871,12 +826,22 @@ static void madera_extcon_hp_clamp(struct madera_extcon *info, bool clamp) break; } - /* Restore the desired state while not doing the clamp */ - if (!clamp) { + /* Restore the desired state when restoring the clamp */ + if (clamp) { + if (ep_mask) { + ret = regmap_update_bits(madera->regmap, + MADERA_OUTPUT_ENABLES_1, + ep_mask, madera->ep_sel); + if (ret) + dev_warn(info->dev, + "Failed to restore output demux: %d\n", + ret); + } + madera->out_shorted[0] = (madera->hp_impedance_x100[0] <= info->hpdet_short_x100); - if (!madera->out_shorted[0] && !ep_sel) { + if (!madera->out_shorted[0]) { ret = regmap_update_bits(madera->regmap, MADERA_OUTPUT_ENABLES_1, (MADERA_OUT1L_ENA | diff --git a/include/linux/mfd/madera/core.h b/include/linux/mfd/madera/core.h index 090440ff0b5e..a08db0bd1d79 100755 --- a/include/linux/mfd/madera/core.h +++ b/include/linux/mfd/madera/core.h @@ -164,6 +164,7 @@ struct madera { unsigned int out_clamp[MADERA_MAX_OUTPUT]; unsigned int out_shorted[MADERA_MAX_OUTPUT]; unsigned int hp_ena; + unsigned int ep_sel; unsigned int hp_impedance_x100[MADERA_MAX_ACCESSORY]; struct snd_soc_dapm_context *dapm; diff --git a/sound/soc/codecs/madera.c b/sound/soc/codecs/madera.c index 59a4bf329ce5..669c55189e27 100755 --- a/sound/soc/codecs/madera.c +++ b/sound/soc/codecs/madera.c @@ -522,20 +522,21 @@ int madera_out1_demux_put(struct snd_kcontrol *kcontrol, snd_soc_dapm_kcontrol_dapm(kcontrol); struct madera *madera = dev_get_drvdata(codec->dev->parent); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - unsigned int ep_sel, mux, change; - int ret, demux_change_ret; + unsigned int mux, change; + int ret, demux_change_ret = 0; bool out_mono, restore_out = true; if (ucontrol->value.enumerated.item[0] > e->items - 1) return -EINVAL; mux = ucontrol->value.enumerated.item[0]; - ep_sel = mux << MADERA_EP_SEL_SHIFT; snd_soc_dapm_mutex_lock(dapm); + madera->ep_sel = mux << MADERA_EP_SEL_SHIFT; + change = snd_soc_test_bits(codec, MADERA_OUTPUT_ENABLES_1, - MADERA_EP_SEL_MASK, ep_sel); + MADERA_EP_SEL_MASK, madera->ep_sel); if (!change) goto end; @@ -550,23 +551,25 @@ int madera_out1_demux_put(struct snd_kcontrol *kcontrol, usleep_range(2000, 3000); /* wait for wseq to complete */ /* - * if HP detection clamp is applied while switching to HPOUT - * OUT1 should remain disabled and EDRE should be set to manual + * if HPDET has disabled the clamp while switching to HPOUT + * OUT1 should remain disabled */ - if (!ep_sel && - (madera->out_clamp[0] || madera->out_shorted[0])) + if (!madera->ep_sel && + (!madera->out_clamp[0] || madera->out_shorted[0])) restore_out = false; /* change demux setting */ - demux_change_ret = regmap_update_bits(madera->regmap, - MADERA_OUTPUT_ENABLES_1, - MADERA_EP_SEL_MASK, ep_sel); + if (madera->out_clamp[0]) + demux_change_ret = regmap_update_bits(madera->regmap, + MADERA_OUTPUT_ENABLES_1, + MADERA_EP_SEL_MASK, + madera->ep_sel); if (demux_change_ret) { dev_err(madera->dev, "Failed to set OUT1 demux: %d\n", demux_change_ret); } else { /* apply correct setting for mono mode */ - if (!ep_sel && !madera->pdata.codec.out_mono[0]) + if (!madera->ep_sel && !madera->pdata.codec.out_mono[0]) out_mono = false; /* stereo HP */ else out_mono = true; /* EP or mono HP */ @@ -605,11 +608,14 @@ int madera_out1_demux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol); - unsigned int val; - val = snd_soc_read(codec, MADERA_OUTPUT_ENABLES_1); - val &= MADERA_EP_SEL_MASK; - val >>= MADERA_EP_SEL_SHIFT; - ucontrol->value.enumerated.item[0] = val; + struct snd_soc_dapm_context *dapm = + snd_soc_dapm_kcontrol_dapm(kcontrol); + struct madera *madera = dev_get_drvdata(codec->dev->parent); + + snd_soc_dapm_mutex_lock(dapm); + ucontrol->value.enumerated.item[0] = madera->ep_sel >> MADERA_EP_SEL_SHIFT; + snd_soc_dapm_mutex_unlock(dapm); + return 0; } EXPORT_SYMBOL_GPL(madera_out1_demux_get); -- 2.20.1