From 9aafbf9ca913503d52d00ef955ac7f4ae9863d09 Mon Sep 17 00:00:00 2001 From: Sebastian Leonhardt Date: Mon, 13 Oct 2025 20:31:50 +0200 Subject: [PATCH] STMP37xx/iMX233: reduce popping noise on power on/off (Version 1) Version 1: this patch prolongs startup time by 2 seconds, because the sleep happens early before other threads have started. The patch is tested on CreativeZEN and Fuze+. The datasheet was not very helpfull, so some experimentation was needed. I came to the following conclusions: * setting HP to ground: to prevent popping noises, the headphone output can be set to ground. This however must be done before any part of the audioout module is powered up (setting HP to ground itself will lead to a pop otherwise). This consequently means that HP must NOT be set to ground for powerdown sequence! Further study showed that setting HP out to ground has no audible benefit, controversly not setting/resetting allows for noiseless RoLo-ing. * headphone amp class A/AB mode: initially the HP amp is in class A mode, and should be set to class AB before playing audio, as the datasheet mentions. If the HP output is set to ground, it must be released BEFORE setting class AB! Releasing from ground while in AB mode leads to a very loud pop! * release HP from ground: as said before: never release the HP from ground if the HP amp is set to class AB mode. Therefore the correct order is to power up the headphone amp, wait some time, release HP from ground, and then set the amp to class AB mode. To prevent pop, some time is needed before releasing the HP from gnd. On CreativeZEN 2 sec seems to be ideal; 1 sec have no audible effect, 1.5 sec softenes the pop to some degree. * shutting player off The popping noise when shutting off is much quieter that on power up, so depopping measures are not absolutely necessary. However the power off pop can be silenced by inserting a wait time after the audioout block is closed and before the rest of the chip is powered down. The longer the better, a time of 5 sec practically eliminates the pop. Note that RoLo-ing can still produce noise, because the audio device is not properly shut down. Change-Id: Ib20e1d613b346433d2a711c442e303ededc26e78 --- firmware/target/arm/imx233/audioout-imx233.c | 21 +++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/firmware/target/arm/imx233/audioout-imx233.c b/firmware/target/arm/imx233/audioout-imx233.c index 2d8527ed16..79ee0ce757 100644 --- a/firmware/target/arm/imx233/audioout-imx233.c +++ b/firmware/target/arm/imx233/audioout-imx233.c @@ -54,6 +54,10 @@ static int hp_unmute_cb(struct timeout *tmo) void imx233_audioout_preinit(void) { + /* we forego setting HP output to ground; it seems it doesn't have an + audible benefit, but produces loud noise if done at the wrong place */ + /* when RoLo-ing the headphone is still unmuted; mute to reduce noise */ + BF_SET(AUDIOOUT_HPVOL, MUTE); /* Enable AUDIOOUT block */ imx233_reset_block(&HW_AUDIOOUT_CTRL); /* Enable digital filter clock */ @@ -70,10 +74,14 @@ void imx233_audioout_preinit(void) BF_SET(AUDIOOUT_CTRL, WORD_LENGTH); /* Power up DAC */ BF_CLR(AUDIOOUT_PWRDN, DAC); - /* Hold HP to ground to avoid pop, then release and power up HP */ - BF_SET(AUDIOOUT_ANACTRL, HP_HOLD_GND); + /* power up HP */ BF_CLR(AUDIOOUT_PWRDN, HEADPHONE); - /* Set HP mode to AB */ + /* wait until voltages have settled after powering on HP amp. + * The time delay may be target dependant; on CreativeZEN (STMP3760) + * 1.5 sec still isn't enough (only softening the pop) */ + sleep(HZ*2); + /* Set HP mode to class AB. This must be done after HP is released from + * GND; releasing while AB mode is activated leads to a REALLY loud pop! */ BF_SET(AUDIOOUT_ANACTRL, HP_CLASSAB); /* change bias to -50% */ BF_WR(AUDIOOUT_TEST, HP_I1_ADJ(1)); @@ -82,8 +90,6 @@ void imx233_audioout_preinit(void) BF_SET(AUDIOOUT_REFCTRL, RAISE_REF); #endif BF_SET(AUDIOOUT_REFCTRL, XTAL_BGR_BIAS); - /* Stop holding to ground */ - BF_CLR(AUDIOOUT_ANACTRL, HP_HOLD_GND); /* Set dmawait count to 31 (see errata, workaround random stop) */ BF_WR(AUDIOOUT_CTRL, DMAWAIT_COUNT(31)); /* start converting audio */ @@ -107,8 +113,6 @@ void imx233_audioout_close(void) { /* Switch to class A */ BF_CLR(AUDIOOUT_ANACTRL, HP_CLASSAB); - /* Hold HP to ground */ - BF_SET(AUDIOOUT_ANACTRL, HP_HOLD_GND); /* Mute HP and power down */ BF_SET(AUDIOOUT_HPVOL, MUTE); /* Power down HP */ @@ -123,6 +127,9 @@ void imx233_audioout_close(void) imx233_clkctrl_enable(CLK_FILT, false); /* will also gate off the module */ BF_CLR(AUDIOOUT_CTRL, RUN); + /* power-off-pop is reduced when waiting after shutting off + * the audioout module and before powering down the whole chip. */ + sleep(HZ*2); } /* volume in half dB