[PATCH 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 | 92 ++++++++++++++++++++++----------------- 1 file changed, 52 insertions(+), 40 deletions(-)
Executing regcache_sync at initialization, we can hear a gentle pop noise. So we created es8326_init for initialization 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 95bf751d8bab..4f10ab5394ec 100755 --- a/sound/soc/codecs/es8326.c +++ b/sound/soc/codecs/es8326.c @@ -950,14 +950,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); @@ -1013,7 +1009,6 @@ static int es8326_resume(struct snd_soc_component *component) regmap_update_bits(es8326->regmap, ES8326_ANA_MICBIAS, 0x0C, 0x0C); 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, @@ -1029,6 +1024,28 @@ 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); + + 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; @@ -1088,7 +1105,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 regmap_config members to fix cach sync error. 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 4f10ab5394ec..d209865be9e1 100755 --- a/sound/soc/codecs/es8326.c +++ b/sound/soc/codecs/es8326.c @@ -327,11 +327,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, };
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,
When widgets "MICBIAS1" and "MICBIAS2" are active, the codec cannot enter suspend mode. So we removed these two widgets.We replaced enable_micbias and disable_micbias with regmap_update_bits to make sure the codec can enter suspend mode.
Signed-off-by: Zhang Yi zhangyi@everest-semi.com --- sound/soc/codecs/es8326.c | 34 +++++----------------------------- 1 file changed, 5 insertions(+), 29 deletions(-)
diff --git a/sound/soc/codecs/es8326.c b/sound/soc/codecs/es8326.c index 8c9d79686185..95bf751d8bab 100755 --- a/sound/soc/codecs/es8326.c +++ b/sound/soc/codecs/es8326.c @@ -286,8 +286,6 @@ static const struct snd_soc_dapm_widget es8326_dapm_widgets[] = { /* Analog Power Supply*/ SND_SOC_DAPM_DAC("Right DAC", NULL, ES8326_ANA_PDN, 0, 1), SND_SOC_DAPM_DAC("Left DAC", NULL, ES8326_ANA_PDN, 1, 1), - SND_SOC_DAPM_SUPPLY("MICBIAS1", ES8326_ANA_MICBIAS, 2, 0, NULL, 0), - SND_SOC_DAPM_SUPPLY("MICBIAS2", ES8326_ANA_MICBIAS, 3, 0, NULL, 0),
SND_SOC_DAPM_PGA("LHPMIX", ES8326_DAC2HPMIX, 7, 0, NULL, 0), SND_SOC_DAPM_PGA("RHPMIX", ES8326_DAC2HPMIX, 3, 0, NULL, 0), @@ -697,28 +695,6 @@ static struct snd_soc_dai_driver es8326_dai = { .symmetric_rate = 1, };
-static void es8326_enable_micbias(struct snd_soc_component *component) -{ - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); - - snd_soc_dapm_mutex_lock(dapm); - snd_soc_dapm_force_enable_pin_unlocked(dapm, "MICBIAS1"); - snd_soc_dapm_force_enable_pin_unlocked(dapm, "MICBIAS2"); - snd_soc_dapm_sync_unlocked(dapm); - snd_soc_dapm_mutex_unlock(dapm); -} - -static void es8326_disable_micbias(struct snd_soc_component *component) -{ - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); - - snd_soc_dapm_mutex_lock(dapm); - snd_soc_dapm_disable_pin_unlocked(dapm, "MICBIAS1"); - snd_soc_dapm_disable_pin_unlocked(dapm, "MICBIAS2"); - snd_soc_dapm_sync_unlocked(dapm); - snd_soc_dapm_mutex_unlock(dapm); -} - /* * For button detection, set the following in soundcard * snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); @@ -822,7 +798,7 @@ static void es8326_jack_detect_handler(struct work_struct *work) if ((iface & ES8326_HPINSERT_FLAG) == 0) { /* Jack unplugged or spurious IRQ */ dev_dbg(comp->dev, "No headset detected\n"); - es8326_disable_micbias(es8326->component); + regmap_update_bits(es8326->regmap, ES8326_ANA_MICBIAS, 0x0C, 0x00); if (es8326->jack->status & SND_JACK_HEADPHONE) { dev_dbg(comp->dev, "Report hp remove event\n"); snd_soc_jack_report(es8326->jack, 0, SND_JACK_HEADSET); @@ -860,7 +836,7 @@ 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); + regmap_update_bits(es8326->regmap, ES8326_ANA_MICBIAS, 0x0C, 0x0C); usleep_range(50000, 70000); regmap_update_bits(es8326->regmap, ES8326_HPDET_TYPE, 0x03, 0x00); regmap_update_bits(es8326->regmap, ES8326_HPDET_TYPE, 0x10, 0x10); @@ -1034,7 +1010,7 @@ static int es8326_resume(struct snd_soc_component *component) (ES8326_HP_DET_SRC_PIN9 | es8326->jack_pol) : (ES8326_HP_DET_SRC_PIN9 | es8326->jack_pol | 0x04))); usleep_range(5000, 10000); - es8326_enable_micbias(es8326->component); + regmap_update_bits(es8326->regmap, ES8326_ANA_MICBIAS, 0x0C, 0x0C); 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); @@ -1063,7 +1039,7 @@ static int es8326_suspend(struct snd_soc_component *component) struct es8326_priv *es8326 = snd_soc_component_get_drvdata(component);
cancel_delayed_work_sync(&es8326->jack_detect_work); - es8326_disable_micbias(component); + regmap_update_bits(es8326->regmap, ES8326_ANA_MICBIAS, 0x0C, 0x00); es8326->calibrated = false; regmap_write(es8326->regmap, ES8326_CLK_MUX, 0x2d); regmap_write(es8326->regmap, ES8326_DAC2HPMIX, 0x00); @@ -1142,7 +1118,7 @@ static void es8326_disable_jack_detect(struct snd_soc_component *component)
mutex_lock(&es8326->lock); if (es8326->jack->status & SND_JACK_MICROPHONE) { - es8326_disable_micbias(component); + regmap_update_bits(es8326->regmap, ES8326_ANA_MICBIAS, 0x0C, 0x00); snd_soc_jack_report(es8326->jack, 0, SND_JACK_HEADSET); } es8326->jack = NULL;
On Mon, Jun 24, 2024 at 11:06:05AM +0800, Zhang Yi wrote:
When widgets "MICBIAS1" and "MICBIAS2" are active, the codec cannot enter suspend mode. So we removed these two widgets.We replaced enable_micbias and disable_micbias with regmap_update_bits to make sure the codec can enter suspend mode.
Should mark the widgets with snd_soc_dapm_ignore_suspend() to allow the device to suspend with the widgets enabled.
On Mon, 24 Jun 2024 11:06:03 +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.
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
[...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[1/4] ASoC: codecs: ES8326: Slove headphone detection issue commit: 4eed78198b30c4c5975e454e7b1e6e25a7ac7353 [3/4] ASoC: codecs: ES8326: Minimize the pop noise commit: 7e7dbdee96cbc660e7e8d3d9d7a512acaa6ca69d [4/4] ASoC: codecs: ES8326: regcache_sync error issue commit: 34fa846f52f9fbef8aa262d3b39e71188e8dd884
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
participants (2)
-
Mark Brown
-
Zhang Yi