From a094bf2b77ce63a68ce3ec53fb7cbc06fb8b8723 Mon Sep 17 00:00:00 2001 From: yaozm1 Date: Sat, 23 Mar 2019 14:56:17 +0800 Subject: [PATCH] Audio:Re-apply Cirrus' patch for hp detect Force EP demux over to headphones to run HPDET Add invert logic clamp. Set clamp default value to true. Change-Id: Ib4202e2d226e5585506acdf114c3056b60ab8d2b Signed-off-by: yaozm1 Reviewed-on: https://gerrit.mot.com/1326172 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 | 90 +++++++++++---------------------- include/linux/mfd/madera/core.h | 1 + sound/soc/codecs/madera.c | 44 +++++++++------- 3 files changed, 55 insertions(+), 80 deletions(-) diff --git a/drivers/extcon/extcon-madera.c b/drivers/extcon/extcon-madera.c index 0d4420ac0f9a..ccd7db620555 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 | @@ -1684,7 +1649,7 @@ int madera_hpdet_start(struct madera_extcon *info) case CS47L35: case CS47L85: case WM1840: - madera_extcon_hp_clamp(info, true); + madera_extcon_hp_clamp(info, false); ret = regmap_update_bits(madera->regmap, MADERA_ACCESSORY_DETECT_MODE_1, MADERA_ACCDET_MODE_MASK, @@ -1735,7 +1700,7 @@ int madera_hpdet_start(struct madera_extcon *info) "Failed to set HPDET sense: %d\n", ret); goto err; } - madera_extcon_hp_clamp(info, true); + madera_extcon_hp_clamp(info, false); madera_hpdet_start_micd(info); break; } @@ -1750,7 +1715,7 @@ int madera_hpdet_start(struct madera_extcon *info) return 0; err: - madera_extcon_hp_clamp(info, false); + madera_extcon_hp_clamp(info, true); pm_runtime_put_autosuspend(info->dev); @@ -1848,7 +1813,7 @@ void madera_hpdet_stop(struct madera_extcon *info) break; } - madera_extcon_hp_clamp(info, false); + madera_extcon_hp_clamp(info, true); pm_runtime_mark_last_busy(info->dev); pm_runtime_put_autosuspend(info->dev); @@ -3286,6 +3251,9 @@ static int madera_extcon_probe(struct platform_device *pdev) madera_extcon_set_micd_clamp_mode(info); + /*Since Invert the calmp was set, the calmp need to set true as init in case EPOUT will be mute */ + madera->out_clamp[0]=true; + if ((info->num_micd_modes > 2) && !info->micd_pol_gpio) dev_warn(info->dev, "Have >1 mic_configs but no pol_gpio\n"); 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..994621fe27c8 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); @@ -2742,9 +2748,9 @@ int madera_hp_ev(struct snd_soc_dapm_widget *w, regmap_read(madera->regmap, MADERA_OUTPUT_ENABLES_1, &ep_sel); ep_sel &= MADERA_EP_SEL_MASK; - /* Force off if HPDET clamp is active for this output */ + /* Force off if HPDET disabled the clamp for this output */ if (!ep_sel && - (madera->out_clamp[out_num] || madera->out_shorted[out_num])) + (!madera->out_clamp[out_num] || madera->out_shorted[out_num])) val = 0; regmap_update_bits(madera->regmap, MADERA_OUTPUT_ENABLES_1, mask, val); -- 2.20.1