Audio noise

Hi,

We got unexpected pop sound with the audio codec we added on agx Xavier.

The audio codec is MAX98357 and is connected to I2S1.

The pop sound shows as the start and the stop of every audio playback.

From the signal we measured, LRCLK and BCLK are almost enabled as the same time. (see below.) However, MAX98357’s requirement is LRCLK must start at least 1/2 BCLK after BCLK starts.

SD_MODE is set to high still as BCLK and LRCLK are set to be stopped. However, MAX98357’s requirement is if BCLK and LRCLK need to be stopped, SD_MODE must first be set to 0V.

Is there a way to adjust the I2S1 LRCLK enabled timing and SD_MODE(I2S1_SDIN) on agx?

CH1 : BCLK, CH2 : LRCLK, CH3 : SD_MODE, CH4 : OUTP
image
image
image
image

Thank you for any advice,

Hi HuiW,

Looking at the signals, SD_MODE is always high, which probably is the issue. Few questions:

  1. Are you interfacing MAX98357 with AGX Xavier via I2S interface exposed through 40pin HDR (J30)? If not, which I2S interface is getting used.

  2. Can you confirm if https://github.com/torvalds/linux/blob/master/sound/soc/codecs/max98357a.c or similar driver is getting used to control SD_MODE signal as GPIO in your BSP?

  3. Which GPIO (“sdmode”) is mentioned in MAX98357 device node entry in the DT?

Thanks,
Sharad

Hi Sharad,

Thank you for your support.
Sorry for not adding information clearly.
MAX98357 is connected to I2S1.
BCLK — I2S1_CLK
SD_MODE — I2S1_SDOUT
DIN — I2S1_SDIN
LRCLK — I2S1_LRCLK

MAX98357 is a Class D audio Amp and does not require any s/w.

Thank you,

Hi HuiW,

Though there is no register configuration required for MAX98357 but to toggle SD_MODE signal, there is a simple ALSA driver required on CPU side. You can either look at upstream version of the driver @https://patchwork.kernel.org/patch/5815381/ or https://github.com/torvalds/linux/blob/master/sound/soc/codecs/max98357a.c. This driver is specifically added to avoid pop noise. Please refer to the DT bindings document for MAX98357.

I suggest to get in touch with Maxim regarding the same.

In your earlier comment, I think you meant I2S1_SDIN (not I2S1_SDOUT) for SD_MODE .

On AGX Xavier dev kit, I2S1 connects to Realtek Codec on the baseboard. Looks like you are using AGX Xavier Module with a custom baseboard.

Since in your design, I2S1_SDIN requires toggling as GPIO (via MAX98357 ASoC driver), it requires some changes in default pinmux as well for I2S1_SDIN. Kindly refer to Developer Guide to make default pinmux changes to use I2S1_SDIN as GPIO.

Please use below GPIO in MAX98357 device node:
“sdmode-gpios = <&tegra_main_gpio TEGRA194_MAIN_GPIO(S, 2) 0>;”

Thanks,
Sharad

Hi Sharad,

Thank you for your prompt support.

You are right.
I2S1_SDIN is for SD_MODE .
Sorry for my typo.

Actually, Maxim gave the update of “MAX98357 is a Class D audio Amp and does not require any s/w.”

We will try your suggestion.

Plus, from MAX98357 evb board, the BCLK / LRCLK clock are turned on always. It looks no idle mode even no playback /recoding.
Is there a way to set agx ASoC core not into idle mode? how?
Will this help to avoid pop sound?

Thank you,

Hi HuiW,

Using ASoC driver for handling sdmode signal is the best and cleaner solution. Please get in touch with Maxim and share references to the driver and DT bindings so that they respond in the correct context.

Regarding keeping BCLK/LRCLK always on : These clocks are generated by I2S controller when controller is enabled. Also these clocks are a function of Audio sampling rate etc… So not sure how MAX98357 behaves if rates are change runtime (based on usecase e.g. 8Kz to 48Khz etc…). There are many unknows since we haven’t used this Amp or the EVM at our end.

Kindly give us couple of days, we could possibly share few things for you to tryout but all that would be hacky.

Thanks,
Sharad

Hi HuiW,

Can you try below command to set 100ms of DAPM pop delay:

$ echo 100 | sudo tee /sys/kernel/debug/asoc/tegra-snd-t186ref-mobile-rt565x/dapm_pop_time

If 100 ms doesn’t work , you could try changing the delay (increase/decrease).

Thanks,
Sharad

Hi Sharadg,

Sorry. We did try this command before, and it did not work.

dapm_pop_time default is 0. ( see

dapm_pop_time set to 100.
– got more pop sound actually.

dapm_pop_time set could not be set to negative value.

MAX98357’s requirement is LRCLK must start at least 1/2 BCLK after BCLK starts.

Thank you,

Hi HuiW,

Indeed, from your above experiments looks like the gap between BCLK and LRCLK seems to be causing noise and dapm_pop_time is actually adding more delay for LRCLK.

I still believe if ASoC code driver is used to handle sdmode_gpios and sdmode_delay, it could solve the issue. However, we are checking if it’s possible to keep these clocks always “ON” without major code changes.

I shall update as soon as we have something ready for you to try.

Thanks for your patience.

Thanks,
Sharad

Could you please try below settings before running the usecase and probe signals:

echo 49152000 > /sys/kernel/debug/bpmp/debug/clk/pll_a_out0/rate
echo 245760000 > /sys/kernel/debug/bpmp/debug/clk/pll_a/rate
amixer -c 1 cset name="I2S5 Mux" "I2S1"

Thanks,
Sharad

Hi Sharad,

Thank you for your prompt support.

After running the command you provided kept these clocks always “ON”, as we tested it.
And also avoided the pop noise.

It would be great if you could address more about the command.
Is there any we need to care about to use the command?

Thank you,

Hi HuiW,

Glad to hear above settings helped for your usecase.

echo 49152000 > /sys/kernel/debug/bpmp/debug/clk/pll_a_out0/rate
echo 245760000 > /sys/kernel/debug/bpmp/debug/clk/pll_a/rate

Above commands are just to set default PLL rates (these rates could get overridden based on usecase). Important command that enables SCK and LRCLK on I2S1 is below:

amixer -c 1 cset name=“I2S5 Mux” “I2S1”

This basically sets up I2S1 (capture) -> I2S5 (playback) path within audio subsystem. It ensures that all clocks going out of the I2S1 controller are enabled even when your usecase (playback over I2S1) is not running. You could use any free I2S instance inplace of I2S5 as per your HW design.

Thanks,
Sharad

Hi Sharad,

Thank you so much for your clear information.
By the way, is there a way to revise back to default?

The rate value will change back to default value after restart.
But amixer setting seems remained to the changed state.
And amixer -c 1 cset name=“I2S1 Mux” “I2S1” did not change back, either.
And amixer -c 1 cget does not get the current control content.
Is there a way to get the current amixer setting?

Thank you,

Thank you,

To reset the path I2S1- > I2S5, use below command:

amixer -c 1 cset name=“I2S5 Mux” “None”

To read control, one at a time, please use below command:

amixer -c 1 cget name=“Control” for example: amixer -c 1 cget name=“I2S5 Mux”

To read all controls and current settings, please use below command:

amixer -c 1 contents

Thanks,
Sharad

Hi Sharad,

Thank you so much.
The commands you provided work.

Thanks,