Orangepi Zero 2w with PCM5122 work together

@MichaIng and everyone

It’s a great day for me !!! :heart_eyes:

For a long time, I’ve been listening to music using LMS and Squeezelite on an Orange Pi Zero 2W paired with its USB/Ethernet expansion board and a DIY PCM5102A-based DAC
but I’ve always wanted to add a PCM5122 DAC, and I finally got that done this afternoon. I used off-the-shelf components: the board itself, its expansion board, and a PiFi DAC , that will very soon be replaced by a PCM5122 board.
Like this

The test bench

Below is the script to deploy the DAC using I2S0 and I2C1, along with the service that initializes the DAC via I2C when the board boots up.

At the end of the script, you will find the commands to create and deploy it.

A reboot is all that remains, and the PCM5122 DAC should be ready to play music once connected to your hi-fi system.

#!/bin/bash
# ==============================================================================
# SCRIPT DE DÉPLOIEMENT UNIQUE AUTOMATISÉ : PCM5122 + I2C1-PI FUSIONNÉS (COMPATIBLE)
# ==============================================================================

echo "--- [1/6] Installation des dépendances (i2c-tools & compiler) ---"
apt update && apt install -y i2c-tools device-tree-compiler

# Création et bascule dans le répertoire utilisateur
mkdir -p /boot/overlay-user
cd /boot/overlay-user

# Create the overlay source file
echo "--- [2/6] Création du fichier source unique sécurisé (pcm5122.dts) ---"
cat << '_EOF_' > pcm5122.dts
/dts-v1/;
/plugin/;

/ {
	compatible = "allwinner,sun50i-h618";

	fragment@0 {
		target = <&pio>;
		__overlay__ {
			ahub_daudio0_pins_d: ahub_daudio0_sleep {
				pins = "PI0", "PI1", "PI2", "PI3", "PI4";
				function = "gpio_in";
				drive-strength = <20>;
				bias-disable;
			};
			ahub_daudio0_pins_a: ahub_daudio0@0 {
				pins = "PI0", "PI1", "PI2";
				function = "i2s0";
				drive-strength = <20>;
				bias-disable;
			};
			ahub_daudio0_pins_b: ahub_daudio0@1 {
				pins = "PI3";
				function = "i2s0_dout0";
				drive-strength = <20>;
				bias-disable;
			};
			ahub_daudio0_pins_c: ahub_daudio0@2 {
				pins = "PI4";
				function = "i2s0_din0";
				drive-strength = <20>;
				bias-disable;
			};
		};
	};

	fragment@1 {
		target-path = "/soc";
		__overlay__ {
			ahub0_plat: ahub0_plat {
				#sound-dai-cells = <0>;
				compatible = "allwinner,sunxi-snd-plat-ahub";
				apb_num = <0>;
				dmas = <&dma 3>, <&dma 3>;
				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 = "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 {
				};
			};
			codec: codec {
				compatible = "allwinner,sun50i-h616-codec";
				status = "disable";
				allwinner,audio-routing = "Line Out", "LINEOUT";
			};
			ahub_dam_plat: ahub_dam_plat {
				compatible = "allwinner,sunxi-snd-plat-ahub_dam";
				status = "okay";
			};
			ahub1_plat: ahub1_plat {
				compatible = "allwinner,sunxi-snd-plat-ahub";
				#sound-dai-cells = <0>;
				status = "okay";
			};
			ahub1_mach: ahub1_mach {
				compatible = "allwinner,sunxi-snd-mach";
				soundcard-mach,name = "HDMI";
				soundcard-mach,format = "i2s";
				status = "disable";

				soundcard-mach,cpu {
					sound-dai = <&ahub1_plat>;
				};

				soundcard-mach,codec {
				};
			};
			gpu: gpu {
				compatible = "allwinner,sun50i-h616-mali", "arm,mali-bifrost";
				status = "okay";
			};
		};
	};

	fragment@2 {
		target = <&i2c1>;
		__overlay__ {
			#address-cells = <1>;
			#size-cells = <0>;
			pinctrl-names = "default";
			pinctrl-0 = <&i2c1_pi_pins>;
			clock-frequency = <400000>;
			status = "okay";
		};
	};
};
_EOF_

echo "--- [3/6] Compilation de l'overlay unique (pcm5122.dtbo) ---"
dtc -I dts -O dtb -@ -o pcm5122.dtbo pcm5122.dts

echo "--- [4/6] Vérification du binaire via fdtdump ---"
fdtdump pcm5122.dtbo | head -n 20

echo "--- [5/6] Génération et enregistrement de l'initialisation I2C2 ---"
cat << '_EOF_' > /boot/overlay-user/init_dac.sh
#!/bin/bash
for i in {1..10}; do
    if [ -e /dev/i2c-2 ]; then break; fi
    sleep 0.5
done

i2cset -y 2 0x4d 0x01 0x11
sleep 0.2

i2cset -y 2 0x4d 0x02 0x10
i2cset -y 2 0x4d 0x25 0x08
i2cset -y 2 0x4d 0x0d 0x10
i2cset -y 2 0x4d 0x26 0x10
i2cset -y 2 0x4d 0x41 0x00

i2cset -y 2 0x4d 0x02 0x00
i2cset -y 2 0x4d 0x03 0x00
i2cset -y 2 0x4d 0x3d 0x30
i2cset -y 2 0x4d 0x3e 0x30
_EOF_

chmod +x /boot/overlay-user/init_dac.sh
sed -i '/snd_soc_pcm512x/d' /etc/modules

# Création du service d'initialisation au démarrage de la carte
cat << '_EOF_' > /etc/systemd/system/init-dac.service
[Unit]
Description=Initialisation automatique du DAC PCM5122 sur I2C-2 (i2c1-pi) sans MCLK
After=sound.target i2c-dev.target
DefaultDependencies=no

[Service]
Type=oneshot
ExecStart=/boot/overlay-user/init_dac.sh
RemainAfterExit=yes

[Install]
WantedBy=sysinit.target
_EOF_

systemctl daemon-reload
systemctl enable init-dac.service

echo "--- [6/6] Enregistrement du fichier overlay spécifique dans dietpiEnv.txt ---"
sed -i '/user_overlays=/d' /boot/dietpiEnv.txt
echo "user_overlays=pcm5122" >> /boot/dietpiEnv.txt

echo "=============================================================================="
echo " La carte Orangepi zero 2w ne supporte pas la syntaxe moderne pour le .dts    "
echo " La structure en fragments compatibles a été restaurée                        "  
echo " Le bus I2C1 configurer en vitesse personnalisée à 400kHz (100Khz en standard)"
echo " Relancez la carte pour retrouver votre soundbox : 'reboot'                   "
echo "=============================================================================="


# ==============================================================================
# pour l'activer 
# nano deploy_pcm5122.sh
# ctrl +o et ctrl +x
# puis
# bash deploy_pcm5122.sh
# ==============================================================================

For the pcm5122.dts part, I am using the old syntax because an attempt to use the modern syntax was rejected by the compiler. I could look into that further, but I can always modify my script later to fix this.

This script is fully functional and has been verified on my setup. The next step is to create a 3D case to house this ultra-compact assembly;

I’ll post images as the project progresses.

This is where things stand for now.


2 Likes