Categories
DIY HOWTO LINUX OrangePI

[DIY] OrangePI Zero SPDIF

Have you ever wondered how could you play your favourite song using a dirty cheap SBC?
Okay… OPI SBCs are not that cheap, as it appeared in the news.

Most of the OPI boards are using some Allwinner SoCs. The common ones are uses the 32bit H3 and 64bit H5. Thankfully for the SUNXI project, we could use some of the up-to-date distributions, so we are no longer forced to use some very old sourceless binary image. See SUNXI’s Linux mainlining effort page for more information.

Is digital audio a hidden feature?

According to:

there is something called One Wire Audio(OWA). Even some TV boxes are equipped with SPDIF output, but that’s really hard to found some information about the possibility to use the well known IEC958 standard.
Don’t worry, this is why this page was created. You don’t need to spend hours with the investigation, because I did it for you!

$ modinfo sun4i_spdif
filename:       /lib/modules/5.10.21-sunxi64/kernel/sound/soc/sunxi/sun4i-spdif.ko
alias:          platform:sun4i-spdif
license:        GPL
description:    Allwinner sun4i SPDIF SoC Interface
author:         Andrea Venturi <be17068@iperbole.bo.it>
author:         Marcus Cooper <codekipper@gmail.com>
alias:          of:N*T*Callwinner,sun50i-h6-spdifC*
alias:          of:N*T*Callwinner,sun50i-h6-spdif
alias:          of:N*T*Callwinner,sun8i-h3-spdifC*
alias:          of:N*T*Callwinner,sun8i-h3-spdif
alias:          of:N*T*Callwinner,sun6i-a31-spdifC*
alias:          of:N*T*Callwinner,sun6i-a31-spdif
alias:          of:N*T*Callwinner,sun4i-a10-spdifC*
alias:          of:N*T*Callwinner,sun4i-a10-spdif
depends:
intree:         Y
name:           sun4i_spdif
vermagic:       5.10.21-sunxi64 SMP mod_unload aarch64
sig_id:         PKCS#7
signer:         Build time autogenerated kernel key
sig_key:        09:5C:81:AD:3B:4D:EA:B2:98:DE:30:A8:4F:38:A7:CE:1C:01:1F:3F
sig_hashalgo:   sha1
signature:      93:F4:F5:E0:7B:5F:38:FF:8C:5C:74:DF:62:BD:03:75:35:22:3D:CD:
        ED:D9:82:92:7C:43:5E:4A:2E:04:5A:BE:82:D8:F1:86:2D:7E:04:08:
        63:3B:8D:AE:49:40:5B:F4:A8:43:8F:16:0F:0D:99:4D:10:15:9B:8A:
        70:C6:C5:0E:8B:99:34:21:EE:45:2A:51:5C:1E:F5:19:5D:49:9E:9F:
        85:37:B5:1E:F2:57:46:71:4B:17:49:7D:CF:A1:6B:BF:FA:CE:65:55:
        22:1D:0F:8D:DB:80:2A:37:65:EB:62:08:B7:98:BD:52:AA:2A:72:FE:
        55:1F:2F:77:F6:D2:D8:1E:B1:17:34:E0:F8:52:47:D3:42:C2:45:6B:
        FB:C5:BA:D7:3C:74:C9:84:69:9E:39:20:45:63:D1:79:6C:8A:B9:53:
        79:0E:62:2E:33:FB:52:7A:8C:43:A8:2A:2D:A4:CD:DD:9E:97:05:4A:
        8E:7F:0A:30:09:80:C3:75:9A:CF:11:30:CC:B2:31:F8:15:49:02:40:
        29:51:47:95:52:9B:9F:71:4F:A8:7A:26:93:6E:2F:87:D3:A4:34:8C:
        B8:80:1E:42:6B:41:2D:09:BF:79:7B:87:BC:CA:A1:51:80:C9:29:81:
        BA:6B:AB:DE:F2:CE:29:CC:0C:03:13:49:45:B1:95:3A:83:3C:77:81:
        A6:E5:C0:11:09:CB:AD:C0:9B:68:AD:CE:BD:27:3B:A2:AF:19:B8:05:
        4D:64:5B:E5:D8:85:F4:B8:10:00:EF:CC:2E:45:10:DF:1F:C9:F2:08:
        1B:2A:E5:2A:13:FF:8E:7C:6B:EC:09:95:7A:E6:B1:A4:0F:A3:88:4D:
        7A:78:7A:38:C4:E9:E3:80:8B:C4:7F:47:1C:5A:B5:75:6A:61:5A:D6:
        BC:60:D9:34:66:75:20:DD:4C:47:51:FB:B1:2E:B6:20:1F:6C:4C:7E:
        B5:D7:21:C6:F1:D4:A7:2C:F2:DF:25:89:AE:C0:3B:0D:7C:DD:57:5C:
        6E:77:5C:6C:56:34:C7:96:EA:66:74:DF:5E:F3:1C:B0:ED:36:FE:14:
        20:C7:AB:9E:BD:24:73:BF:0F:6E:B7:67:BA:69:5F:C4:7A:9A:9A:7C:
        38:E6:8C:25:31:BA:C8:80:AB:A1:34:75:0A:8C:4D:33:F2:6B:04:1D:
        10:AC:9F:31:61:1F:BF:54:24:BD:CE:F8:84:F0:8B:85:31:C6:94:58:
        C6:88:D8:93:A1:18:E5:EC:96:D9:FD:81:55:0B:C0:47:EF:7B:E5:6B:
        F0:76:03:E8:B5:50:59:41:EF:2F:E3:2D:8B:7D:EE:FC:AD:4A:03:50:
        20:0E:47:9D:75:E7:79:77:CF:8D:20:15

Software and hardware mapping, the Allwinner way

Allwinner used to implement it’s proprietary FEX file/format to assign defined functions to certain GPIO pins. In it’s current form that’s a pretty useful way to explore functionalities, hardware capabalities and gain some knowledge about the PCB wirings. This file is used to accessible on the devices, if you are using some of the FW download mode. For more information about how FEX works, please visit the Fex Guide on SUNXI’s webpage.

Software and hardware mapping, the mainline Linux way

For some years, the Linux kernel uses the devicetree model: Linux and the Devicetree.
This is the way how various projects like Armbian, OpenWRT and U-Boot define the GPIO mappings for certain architectures like ARM, MIPS and it’s derived devices.

In our case, you can see H3 and H5 has the same DTS(device tree source) file, where SPDIF’s TX pin is defined.
sunxi-h3-h5.dtsi:464

            spdif_tx_pin: spdif-tx-pin {
                pins = "PA17";
                function = "spdif";
            };

And in which file the functionality is disabled.
sunxi-h3-h5.dtsi:619

        spdif: spdif@1c21000 {
            #sound-dai-cells = <0>;
            compatible = "allwinner,sun8i-h3-spdif";
            reg = <0x01c21000 0x400>;
            interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
            clocks = <&ccu CLK_BUS_SPDIF>, <&ccu CLK_SPDIF>;
            resets = <&ccu RST_BUS_SPDIF>;
            clock-names = "apb", "spdif";
            dmas = <&dma 2>;
            dma-names = "tx";
            status = "disabled";
        };

This SoC related file defines the default GPIO mappings, however each device has their own changes. These two files are in parent-children relations.
OrangePI devices tree files define some features differently. In case of SPDIF there is no change. You can take a look on the H2+ based Zero file: here.

Beelink’s X2 has it’s option to turn on the SPDIF functionality as you can see below:

&spdif {
    pinctrl-names = "default";
    pinctrl-0 = <&spdif_tx_pin>;
    status = "okay";
};

sun8i-h3-beelink-x2.dts

Modify the hardware

According to the schematics, most of the OrangePI Zero (vanilla, LTS, Plus, etc…) boards are using the dedicated PA17 SPDIF GPIO port to control the red status LED. SPDIF is not remappable, so we need to solder a wire on the pull resistor.
img
OrangePi_zero_schematic_v1.5.pdf
OrangePi_ZeroPlus_schematic_v1.0.pdf

img

Enable the SPDIF output, the Armbian way

Please note, whatever trigger was set for the status led, that will be gone. You couldn’t use any of the triggers, if SPDIF has been enabled in the device tree. Example:

$ cat /sys/class/leds/orangepi:red:status/trigger
none usb-gadget usb-host kbd-scrolllock kbd-numlock kbd-capslock kbd-kanalock kbd-shiftlock kbd-altgrlock kbd-ctrllock kbd-altlock kbd-shiftllock kbd-shiftrlock kbd-ctrlllock kbd-ctrlrlock usbport disk-activity disk-read disk-write ide-disk mtd nand-disk [heartbeat] cpu cpu0 mmc0 cpu1 cpu2 cpu3 mmc1 activity default-on panic rfkill-any rfkill-none rfkill0 0.2:01:link 0.2:01:1Gbps 0.2:01:100Mbps 0.2:01:10Mbps

Check the current status:

$ cat /sys/firmware/devicetree/base/soc/spdif@1c21000/status
disabled

Modify the device tree, and enable the SPDIF function:
System -> Hardware -> spdif-out

# armbian-config

After a reboot, the original device tree binary file will be extended with the SPDIF overlay:

$ grep overlay /boot/armbianEnv.txt
overlay_prefix=sun50i-h5
overlays=spdif-out usbhost2 usbhost3
########
/boot/dtb-5.10.21-sunxi64/allwinner/sun50i-h5-orangepi-zero-plus.dtb
/boot/dtb-5.10.21-sunxi64/allwinner/overlay/sun50i-h5-spdif-out.dtb
$ cat /sys/firmware/devicetree/base/soc/spdif@1c21000/status
okay
$ cat /proc/asound/cards
 0 [SPDIF          ]: On-board_SPDIF - On-board SPDIF
                      On-board SPDIF
$ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: SPDIF [On-board SPDIF], device 0: spdif-dit-hifi dit-hifi-0 [spdif-dit-hifi dit-hifi-0]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

Hook up the connector

You can use any of the coaxial or TOSLINK connectors. I desoldered my connector from and old motherboard. Long story short:

  • coaxial needs data (PA17) and GND, while
  • toslink needs data (PA17), GND and 5V.
    img

Enjoy

img

Thanks for the hint hyphop
More info about: Armbian DT overlays