OrangePi Zero 2w and I2S: only left channel

Hi everyone,

I’m managed to play some audio using i2s and max98357a (violet board), but then I realized … I’m only playing the left channel.

With SD hanging (disconnected), I should be able to hear both channels, right? Eventually, I want to support 2 boards, one channel each, but I got stuck at the first step.

Here is my dts:

/dts-v1/;
/plugin/;
/ {
    compatible = "allwinner,sun50i-h616";
    fragment@0 {
        target = <&pio>;
        __overlay__ {
            ahub_daudio0_pins_a: ahub_daudio0@0 {
                pins = "PI0", "PI1", "PI2";
                function = "i2s0";
                drive-strength = <0x14>;
                bias-disable;
            };
            ahub_daudio0_pins_b: ahub_daudio0@1 {
                pins = "PI3";
                function = "i2s0_dout0";
                drive-strength = <0x14>;
                bias-disable;
            };
            ahub_daudio0_pins_c: ahub_daudio0@2 {
                pins = "PI4";
                function = "i2s0_din0";
	        drive-strength = <0x14>;
		bias-disable;
            };
            ahub_daudio0_pins_d: ahub_daudio0_sleep {
		pins = "PI0", "PI1", "PI2", "PI3", "PI4";
		function = "gpio_in";
		drive-strength = <0x14>;
        	bias-disable;
            };
        };
    };
    fragment@1 {
        target-path = "/soc";
        __overlay__ {
            ahub0_plat: ahub0_plat {
                #sound-dai-cells = <0>;
		compatible	= "allwinner,sunxi-snd-plat-ahub";
                apb_num		= <2>;	/* for dma port 5 */
		dmas		= <&dma 5>, <&dma 5>;
		dma-names	= "tx", "rx";
		playback_cma	= <128>;
		capture_cma	= <128>;
		tx_fifo_size	= <128>;
		rx_fifo_size	= <128>;
        tdm_num         = <0>;
        tx_pin          = <0>;
        rx_pin          = <0>;

		pinctrl-names = "default", "sleep";
                pinctrl_used;
		pinctrl-0 = <&ahub_daudio0_pins_a>, <&ahub_daudio0_pins_b>, <&ahub_daudio0_pins_c>;
		pinctrl-1 = <&ahub_daudio0_pins_d>;

                status = "okay";
            };
            ahub0_mach: ahub0_mach {
                compatible = "allwinner,sunxi-snd-mach";
		soundcard-mach,name = "ahubi2s0";
		soundcard-mach,format = "i2s";
                soundcard-mach,frame-master = <&ahub0_cpu>;
                soundcard-mach,bitclock-master = <&ahub0_cpu>;
                soundcard-mach,slot-num = <2>;
                soundcard-mach,slot-width = <32>;

		status = "okay";

                ahub0_cpu: soundcard-mach,cpu {
		    sound-dai = <&ahub0_plat>;
                    soundcard-mach,pll-fs   = <4>;
                    soundcard-mach,mclk-fs  = <0x100>;
		};

		ahub0_codec: soundcard-mach,codec {
		};
            };
            hdmi: hdmi@6000000 {
                status = "disabled";
            };
        };
    };
};

When running: speaker-test -D hw:1,0 -c 2 -t wav , I can only hear “Front left”.

Has anyone succesfully played stereo on a single board and using two boards?

Cheers!

Hello, first clear some misunderstanding:

It’s a mono amplifier, so with one board you will never get stereo. But you could play the same signal (if you have a stereo source: left, right or a mix of it) through two speakers, which is still mono because it’s exact the same signal without any stereo info.
So I assume you wanna play the mono signal through 2 speakers, not just one.
SD hanging/floating defaults to left channel

To get a signal through both channels the SD mode needs to be between ~0.16–0.77 V.

I’ve read about 0.5 V to get an even mix between left and right.

Sure, with two boards you can get true stereo, setting one to floating and the other to a voltage between 0.8 and 1.4 V

reference: https://wiki.dfrobot.com/SKU_DFR0954_MAX98357_I2S_Amplifier_Module#SD%20Mode

https://cdn-learn.adafruit.com/downloads/pdf/adafruit-max98357-i2s-class-d-mono-amp.pdf

https://www.analog.com/media/en/technical-documentation/data-sheets/max98357a-max98357b.pdf

I know it is mono, but it should be able to play (L + R) / 2.

I checked my boards with ESP32, and I’m able to select channels easily, so this must be a kernel/DTS or alsa issue. Considering I’m operating on hw devices, skipping the whole alsa setup, my wild guess is DTS?

Hello mtojek

In my script you can see some little difference , the part with it under this line

fragment@1 {
		target-path = "/soc";
		__overlay__ {
			ahub0_plat: ahub0_plat {
				#sound-dai-cells = <0>;
				compatible = "allwinner,sunxi-snd-plat-ahub";
				apb_num = <0>; /* for dma port 3 */
				dmas = <&dma 3>, <&dma 3>;
				dma-names = "tx", "rx";
				playback_cma = <128>;
				capture_cma = <128>;
				tx_fifo_size = <128>;
				rx_fifo_size = <128>;
				pinctrl-names = "default", "sleep";
				pinctrl_used;
				pinctrl-0 = <&ahub_daudio0_pins_a>, <&ahub_daudio0_pins_b>, <&ahub_daudio0_pins_c>;
				pinctrl-1 = <&ahub_daudio0_pins_d>;
				status = "okay";
			};
			ahub0_mach: ahub0_mach {
				compatible = "allwinner,sunxi-snd-mach";
				soundcard-mach,name = "soundbox";
				soundcard-mach,format = "i2s";
				soundcard-mach,frame-master = <&ahub0_cpu>;
			        soundcard-mach,bitclock-master = <&ahub0_cpu>;
			        soundcard-mach,slot-num = <2>;
			        soundcard-mach,slot-width = <32>;
				status = "okay";

				ahub0_cpu: soundcard-mach,cpu {
					sound-dai = <&ahub0_plat>;
					soundcard-mach,pll-fs = <4>;
				        soundcard-mach,mclk-fs = <0>;
				};

				soundcard-mach,codec {
				};
			};
		};
	};

After some test with my PCM5102A this morning
This is good for separate left and right channels
as well as stereo effects with test tracks under LMS and Squeezelight.

Thanks for sharing.

I see that your config does not define tdm_num and tx/rx pins, so probably you have warnings in dmesg. Considering your dts works well, it gives me more confidence that this must be a kernel issue, unless PCM5102A acts differently. I suspect that max98357a may accidentally get into TDM mode, which is useless in this case - we have just 2 channels.

Hello mtojek
Good point, I corrected the three lines

tdm_num         = <0>;
tx_pin          = <0>;
rx_pin          = <0>;

and no more messages in dmesg, thanks a lot
Otherwise, it doesn’t change anything for my PCM5102A and the stereo test sounds;
it still works with your fix.

Thank you :wink:

As I set, to do this you need to set it at around 0.5V and not let it float/hang, like they say in the linked official documentation of the board.

SD Mode

  • Turn off amplifier when SD is connected to GND(Voltage below 0.16V)

  • Output mix channel(Default) when the voltage on SD is between 0.16V to 0.77V, R1 resistance is 680k.

  • Output right channel when the voltage on SD is between 0.77V to 1.4V, R1 resistance is 330K.

  • Output left channel when the voltage on SD is over 1.4V, R1 resistance is 100K

I confirmed the voltage values with ESP32, but for some reason, there is no difference while running on Pi.