From b41d6195b2f0c5d5df009aa518958f3c46e66d9a Mon Sep 17 00:00:00 2001 From: Derek Fang Date: Mon, 7 Mar 2022 18:21:54 +0800 Subject: [PATCH] ASoC: rt5682s: Stabilize the combo jack detection Changes: 1. Revise rt5682s_sar_power_mode and rt5682s_headset_detect to be more rational. 2. Manually set to the jack-unplugging state via rt5682s_headset_detect during going to suspend. Close unnecessary powers and prepare for re-detecting the CBJ during resuming. 3. Simplize rt5682s_resume. Signed-off-by: Derek Fang Link: https://lore.kernel.org/r/20220307102154.26065-1-derek.fang@realtek.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5682s.c | 47 +++++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/sound/soc/codecs/rt5682s.c b/sound/soc/codecs/rt5682s.c index efa1016..8f3d59c 100644 --- a/sound/soc/codecs/rt5682s.c +++ b/sound/soc/codecs/rt5682s.c @@ -644,8 +644,7 @@ enum { SAR_PWR_SAVING, }; -static void rt5682s_sar_power_mode(struct snd_soc_component *component, - int mode, int jd_step) +static void rt5682s_sar_power_mode(struct snd_soc_component *component, int mode) { struct rt5682s_priv *rt5682s = snd_soc_component_get_drvdata(component); @@ -675,16 +674,17 @@ static void rt5682s_sar_power_mode(struct snd_soc_component *component, snd_soc_component_update_bits(component, RT5682S_CBJ_CTRL_1, RT5682S_MB1_PATH_MASK | RT5682S_MB2_PATH_MASK, RT5682S_CTRL_MB1_FSM | RT5682S_CTRL_MB2_FSM); - if (!jd_step) { - snd_soc_component_update_bits(component, RT5682S_SAR_IL_CMD_1, - RT5682S_SAR_SEL_MB1_2_CTL_MASK, RT5682S_SAR_SEL_MB1_2_AUTO); - usleep_range(5000, 5500); - snd_soc_component_update_bits(component, RT5682S_SAR_IL_CMD_1, - RT5682S_SAR_BUTDET_MASK | RT5682S_SAR_BUTDET_POW_MASK, - RT5682S_SAR_BUTDET_EN | RT5682S_SAR_BUTDET_POW_NORM); - } + snd_soc_component_update_bits(component, RT5682S_SAR_IL_CMD_1, + RT5682S_SAR_SEL_MB1_2_CTL_MASK, RT5682S_SAR_SEL_MB1_2_AUTO); + usleep_range(5000, 5500); + snd_soc_component_update_bits(component, RT5682S_SAR_IL_CMD_1, + RT5682S_SAR_BUTDET_MASK | RT5682S_SAR_BUTDET_POW_MASK, + RT5682S_SAR_BUTDET_EN | RT5682S_SAR_BUTDET_POW_NORM); break; case SAR_PWR_OFF: + snd_soc_component_update_bits(component, RT5682S_CBJ_CTRL_1, + RT5682S_MB1_PATH_MASK | RT5682S_MB2_PATH_MASK, + RT5682S_CTRL_MB1_FSM | RT5682S_CTRL_MB2_FSM); snd_soc_component_update_bits(component, RT5682S_SAR_IL_CMD_1, RT5682S_SAR_BUTDET_MASK | RT5682S_SAR_BUTDET_POW_MASK | RT5682S_SAR_SEL_MB1_2_CTL_MASK, RT5682S_SAR_BUTDET_DIS | @@ -702,6 +702,10 @@ static void rt5682s_enable_push_button_irq(struct snd_soc_component *component) { snd_soc_component_update_bits(component, RT5682S_SAR_IL_CMD_13, RT5682S_SAR_SOUR_MASK, RT5682S_SAR_SOUR_BTN); + snd_soc_component_update_bits(component, RT5682S_SAR_IL_CMD_1, + RT5682S_SAR_BUTDET_MASK | RT5682S_SAR_BUTDET_POW_MASK | + RT5682S_SAR_SEL_MB1_2_CTL_MASK, RT5682S_SAR_BUTDET_EN | + RT5682S_SAR_BUTDET_POW_NORM | RT5682S_SAR_SEL_MB1_2_AUTO); snd_soc_component_write(component, RT5682S_IL_CMD_1, 0x0040); snd_soc_component_update_bits(component, RT5682S_4BTN_IL_CMD_2, RT5682S_4BTN_IL_MASK | RT5682S_4BTN_IL_RST_MASK, @@ -718,6 +722,10 @@ static void rt5682s_disable_push_button_irq(struct snd_soc_component *component) RT5682S_4BTN_IL_MASK, RT5682S_4BTN_IL_DIS); snd_soc_component_update_bits(component, RT5682S_SAR_IL_CMD_13, RT5682S_SAR_SOUR_MASK, RT5682S_SAR_SOUR_TYPE); + snd_soc_component_update_bits(component, RT5682S_SAR_IL_CMD_1, + RT5682S_SAR_BUTDET_MASK | RT5682S_SAR_BUTDET_POW_MASK | + RT5682S_SAR_SEL_MB1_2_CTL_MASK, RT5682S_SAR_BUTDET_DIS | + RT5682S_SAR_BUTDET_POW_SAV | RT5682S_SAR_SEL_MB1_2_MANU); } /** @@ -753,7 +761,8 @@ static int rt5682s_headset_detect(struct snd_soc_component *component, int jack_ RT5682S_OSW_L_DIS | RT5682S_OSW_R_DIS); snd_soc_component_update_bits(component, RT5682S_SAR_IL_CMD_13, RT5682S_SAR_SOUR_MASK, RT5682S_SAR_SOUR_TYPE); - rt5682s_sar_power_mode(component, SAR_PWR_NORMAL, 1); + snd_soc_component_update_bits(component, RT5682S_CBJ_CTRL_3, + RT5682S_CBJ_IN_BUF_MASK, RT5682S_CBJ_IN_BUF_EN); snd_soc_component_update_bits(component, RT5682S_CBJ_CTRL_1, RT5682S_TRIG_JD_MASK, RT5682S_TRIG_JD_LOW); usleep_range(45000, 50000); @@ -779,9 +788,8 @@ static int rt5682s_headset_detect(struct snd_soc_component *component, int jack_ RT5682S_FAST_OFF_MASK, RT5682S_FAST_OFF_EN); snd_soc_component_update_bits(component, RT5682S_SAR_IL_CMD_1, RT5682S_SAR_SEL_MB1_2_MASK, val << RT5682S_SAR_SEL_MB1_2_SFT); - if (!snd_soc_dapm_get_pin_status(&component->dapm, "SAR")) - rt5682s_sar_power_mode(component, SAR_PWR_SAVING, 1); rt5682s_enable_push_button_irq(component); + rt5682s_sar_power_mode(component, SAR_PWR_SAVING); break; default: jack_type = SND_JACK_HEADPHONE; @@ -792,7 +800,7 @@ static int rt5682s_headset_detect(struct snd_soc_component *component, int jack_ RT5682S_OSW_L_EN | RT5682S_OSW_R_EN); usleep_range(35000, 40000); } else { - rt5682s_sar_power_mode(component, SAR_PWR_OFF, 1); + rt5682s_sar_power_mode(component, SAR_PWR_OFF); rt5682s_disable_push_button_irq(component); snd_soc_component_update_bits(component, RT5682S_CBJ_CTRL_1, RT5682S_TRIG_JD_MASK, RT5682S_TRIG_JD_LOW); @@ -1403,10 +1411,10 @@ static int sar_power_event(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: - rt5682s_sar_power_mode(component, SAR_PWR_NORMAL, 0); + rt5682s_sar_power_mode(component, SAR_PWR_NORMAL); break; case SND_SOC_DAPM_POST_PMD: - rt5682s_sar_power_mode(component, SAR_PWR_SAVING, 0); + rt5682s_sar_power_mode(component, SAR_PWR_SAVING); break; } @@ -2835,9 +2843,8 @@ static int rt5682s_suspend(struct snd_soc_component *component) cancel_delayed_work_sync(&rt5682s->jack_detect_work); cancel_delayed_work_sync(&rt5682s->jd_check_work); - if (rt5682s->hs_jack && rt5682s->jack_type == SND_JACK_HEADSET) - snd_soc_component_update_bits(component, RT5682S_4BTN_IL_CMD_2, - RT5682S_4BTN_IL_MASK, RT5682S_4BTN_IL_DIS); + if (rt5682s->hs_jack) + rt5682s->jack_type = rt5682s_headset_detect(component, 0); regcache_cache_only(rt5682s->regmap, true); regcache_mark_dirty(rt5682s->regmap); @@ -2853,8 +2860,6 @@ static int rt5682s_resume(struct snd_soc_component *component) regcache_sync(rt5682s->regmap); if (rt5682s->hs_jack) { - rt5682s->jack_type = 0; - rt5682s_sar_power_mode(component, SAR_PWR_NORMAL, 0); mod_delayed_work(system_power_efficient_wq, &rt5682s->jack_detect_work, msecs_to_jiffies(0)); } -- 2.7.4