[PATCH v1 0/4] ASoC: codecs: ES8326: Solving headphone detection and
We propose four patches to solve headphone detection and suspend issues. And there are several registers that should be read-only registers. So we create es8326_writeable_register, and set these registers to false.
Zhang Yi (4): ASoC: codecs: ES8326: Slove headphone detection issue ASoC: codecs: ES8326: codec can't enter suspend issue ASoC: codecs: ES8326: Minimize the pop noise ASoC: codecs: ES8326: regcache_sync error issue
sound/soc/codecs/es8326.c | 62 +++++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 12 deletions(-)
We modify the trigger conditions for enable_micbias and disable_micbias to make sure the codec can enter suspend
Signed-off-by: Zhang Yi zhangyi@everest-semi.com --- sound/soc/codecs/es8326.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/sound/soc/codecs/es8326.c b/sound/soc/codecs/es8326.c index 8c9d79686185..e103ba5405b4 100755 --- a/sound/soc/codecs/es8326.c +++ b/sound/soc/codecs/es8326.c @@ -787,6 +787,7 @@ static void es8326_jack_button_handler(struct work_struct *work) SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2); button_to_report = 0; } + es8326_disable_micbias(es8326->component); } mutex_unlock(&es8326->lock); } @@ -860,7 +861,6 @@ static void es8326_jack_detect_handler(struct work_struct *work) regmap_write(es8326->regmap, ES8326_INT_SOURCE, 0x00); regmap_update_bits(es8326->regmap, ES8326_HPDET_TYPE, 0x03, 0x01); regmap_update_bits(es8326->regmap, ES8326_HPDET_TYPE, 0x10, 0x00); - es8326_enable_micbias(es8326->component); usleep_range(50000, 70000); regmap_update_bits(es8326->regmap, ES8326_HPDET_TYPE, 0x03, 0x00); regmap_update_bits(es8326->regmap, ES8326_HPDET_TYPE, 0x10, 0x10); @@ -879,6 +879,7 @@ static void es8326_jack_detect_handler(struct work_struct *work) dev_dbg(comp->dev, "button pressed\n"); regmap_write(es8326->regmap, ES8326_INT_SOURCE, (ES8326_INT_SRC_PIN9 | ES8326_INT_SRC_BUTTON)); + es8326_enable_micbias(es8326->component); queue_delayed_work(system_wq, &es8326->button_press_work, 10); goto exit; } @@ -1053,6 +1054,7 @@ static int es8326_resume(struct snd_soc_component *component) ES8326_MUTE);
regmap_write(es8326->regmap, ES8326_ADC_MUTE, 0x0f); + es8326_disable_micbias(es8326->component);
es8326_irq(es8326->irq, es8326); return 0;
Executing regcache_sync at initialization time, we can hear a pop noise. So we created es8326_init instead of executing es8326_resume
Signed-off-by: Zhang Yi zhangyi@everest-semi.com --- sound/soc/codecs/es8326.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-)
diff --git a/sound/soc/codecs/es8326.c b/sound/soc/codecs/es8326.c index e103ba5405b4..51ca17b779c2 100755 --- a/sound/soc/codecs/es8326.c +++ b/sound/soc/codecs/es8326.c @@ -975,14 +975,10 @@ static int es8326_calibrate(struct snd_soc_component *component) return 0; }
-static int es8326_resume(struct snd_soc_component *component) +static void es8326_init(struct snd_soc_component *component) { struct es8326_priv *es8326 = snd_soc_component_get_drvdata(component);
- regcache_cache_only(es8326->regmap, false); - regcache_sync(es8326->regmap); - - /* reset internal clock state */ regmap_write(es8326->regmap, ES8326_RESET, 0x1f); regmap_write(es8326->regmap, ES8326_VMIDSEL, 0x0E); regmap_write(es8326->regmap, ES8326_ANA_LP, 0xf0); @@ -1038,7 +1034,6 @@ static int es8326_resume(struct snd_soc_component *component) es8326_enable_micbias(es8326->component); usleep_range(50000, 70000); regmap_update_bits(es8326->regmap, ES8326_HPDET_TYPE, 0x03, 0x00); - regmap_write(es8326->regmap, ES8326_INT_SOURCE, ES8326_INT_SRC_PIN9); regmap_write(es8326->regmap, ES8326_INTOUT_IO, es8326->interrupt_clk); regmap_write(es8326->regmap, ES8326_SDINOUT1_IO, @@ -1054,8 +1049,30 @@ static int es8326_resume(struct snd_soc_component *component) ES8326_MUTE);
regmap_write(es8326->regmap, ES8326_ADC_MUTE, 0x0f); + regmap_write(es8326->regmap, ES8326_CLK_DIV_LRCK, 0xff); es8326_disable_micbias(es8326->component);
+ msleep(200); + regmap_write(es8326->regmap, ES8326_INT_SOURCE, ES8326_INT_SRC_PIN9); +} + +static int es8326_resume(struct snd_soc_component *component) +{ + struct es8326_priv *es8326 = snd_soc_component_get_drvdata(component); + unsigned int reg; + + regcache_cache_only(es8326->regmap, false); + regcache_cache_bypass(es8326->regmap, true); + regmap_read(es8326->regmap, ES8326_CLK_RESAMPLE, ®); + regcache_cache_bypass(es8326->regmap, false); + /* reset internal clock state */ + if (reg == 0x05) + regmap_write(es8326->regmap, ES8326_CLK_CTL, ES8326_CLK_ON); + else + es8326_init(component); + + regcache_sync(es8326->regmap); + es8326_irq(es8326->irq, es8326); return 0; } @@ -1114,7 +1131,7 @@ static int es8326_probe(struct snd_soc_component *component) } dev_dbg(component->dev, "interrupt-clk %x", es8326->interrupt_clk);
- es8326_resume(component); + es8326_init(component); return 0; }
We modified the headphone detection setting to avoid an error button state after codec resume from suspend state
Signed-off-by: Zhang Yi zhangyi@everest-semi.com --- sound/soc/codecs/es8326.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/sound/soc/codecs/es8326.c b/sound/soc/codecs/es8326.c index 4d87bebca5c1..8c9d79686185 100755 --- a/sound/soc/codecs/es8326.c +++ b/sound/soc/codecs/es8326.c @@ -877,6 +877,8 @@ static void es8326_jack_detect_handler(struct work_struct *work) if (es8326->jack->status & SND_JACK_HEADSET) { /* detect button */ dev_dbg(comp->dev, "button pressed\n"); + regmap_write(es8326->regmap, ES8326_INT_SOURCE, + (ES8326_INT_SRC_PIN9 | ES8326_INT_SRC_BUTTON)); queue_delayed_work(system_wq, &es8326->button_press_work, 10); goto exit; } @@ -1052,11 +1054,6 @@ static int es8326_resume(struct snd_soc_component *component)
regmap_write(es8326->regmap, ES8326_ADC_MUTE, 0x0f);
- es8326->jack_remove_retry = 0; - es8326->hp = 0; - es8326->hpl_vol = 0x03; - es8326->hpr_vol = 0x03; - es8326_irq(es8326->irq, es8326); return 0; } @@ -1211,6 +1208,10 @@ static int es8326_i2c_probe(struct i2c_client *i2c) }
es8326->irq = i2c->irq; + es8326->jack_remove_retry = 0; + es8326->hp = 0; + es8326->hpl_vol = 0x03; + es8326->hpr_vol = 0x03; INIT_DELAYED_WORK(&es8326->jack_detect_work, es8326_jack_detect_handler); INIT_DELAYED_WORK(&es8326->button_press_work,
There are several registers that should be read-only registers. If these registers are written while synchronizing the register values, the codec will enter an error state.So we create es8326_writeable_register, and set these registers to false
Signed-off-by: Zhang Yi zhangyi@everest-semi.com --- sound/soc/codecs/es8326.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
diff --git a/sound/soc/codecs/es8326.c b/sound/soc/codecs/es8326.c index 51ca17b779c2..d665fdbfc94f 100755 --- a/sound/soc/codecs/es8326.c +++ b/sound/soc/codecs/es8326.c @@ -329,11 +329,29 @@ static bool es8326_volatile_register(struct device *dev, unsigned int reg) } }
+static bool es8326_writeable_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case ES8326_BIAS_SW1: + case ES8326_BIAS_SW2: + case ES8326_BIAS_SW3: + case ES8326_BIAS_SW4: + case ES8326_ADC_HPFS1: + case ES8326_ADC_HPFS2: + return false; + default: + return true; + } +} + static const struct regmap_config es8326_regmap_config = { .reg_bits = 8, .val_bits = 8, .max_register = 0xff, + .use_single_read = true, + .use_single_write = true, .volatile_reg = es8326_volatile_register, + .writeable_reg = es8326_writeable_register, .cache_type = REGCACHE_RBTREE, };
On Tue, Jun 25, 2024 at 04:41:03PM +0800, Zhang Yi wrote:
We propose four patches to solve headphone detection and suspend issues. And there are several registers that should be read-only registers. So we create es8326_writeable_register, and set these registers to false.
Please don't resend the same set of patches with the same version without tagging it as a resend, if there is a new version then please change the version.
participants (2)
-
Mark Brown
-
Zhang Yi