We have upgraded the community system as part of the upgrade a password reset is required for all users before login in.

[Onion Omega 2S] I2S audio card / output for external I2S DAC not working (ALSA) ("no soundcards")

  • (see C.) for a list of related topics in this community or the inet - didn't help me)

    A) Problem: When connecting an I2S audio DAC to the Onion Omega 2S it is not possible to playback audio due to "software" issues: no sound card is found.

    The Omega is reporting, that it does not have any sound cards:

    root@Omega-C8DC:/# cat /proc/asound/cards 
    --- no soundcards ---

    The kernel modules are loaded:

    root@Omega-C8DC:/# lsmod | grep "snd"
    regmap_i2c              2298  1 snd_soc_wm8960
    snd                    41582 10 snd_soc_wm8960,snd_soc_core,snd_compress,snd_pcm_oss,snd_mixer_oss,snd_pcm,snd_timer,snd_rawmidi,snd_seq_device,snd_hwdep
    snd_compress           10436  0 
    snd_hwdep               4286  0 
    snd_mixer_oss          12729  1 snd_pcm_oss
    snd_pcm                61710  5 snd_soc_ralink_i2s,snd_soc_wm8960,snd_soc_core,snd_pcm_dmaengine,snd_pcm_oss
    snd_pcm_dmaengine       2971  1 snd_soc_core
    snd_pcm_oss            36177  0 
    snd_rawmidi            16298  0 
    snd_seq_device          2191  1 snd_rawmidi
    snd_soc_core          114758  4 snd_soc_simple_card,snd_soc_simple_card_utils,snd_soc_ralink_i2s,snd_soc_wm8960
    snd_soc_ralink_i2s      7088  0 
    snd_soc_simple_card     4304  0 
    snd_soc_simple_card_utils    5095  1 snd_soc_simple_card
    snd_soc_wm8960         24224  0 
    snd_timer              15806  1 snd_pcm
    soundcore               3836  1 snd

    The utilities are also compiled correctly but also recognize no sound card:

    root@Omega-C8DC:/# aplay -lL
        Discard all samples (playback) or generate zero samples (capture)
    aplay: device_list:272: no soundcards found...

    dmesg does not show any information on "sound" at boot:

    root@Omega-C8DC:/# dmesg | grep "ralink-i2s"
    root@Omega-C8DC:/# dmesg | grep "i2s"
    root@Omega-C8DC:/# dmesg | grep "sound"
    root@Omega-C8DC:/# dmesg | grep "snd"
    root@Omega-C8DC:/# dmesg | grep "wlan"
    [   56.522549] IPv6: ADDRCONF(NETDEV_UP): br-wlan: link is not ready
    [   70.344185] br-wlan: port 1(ra0) entered blocking state
    [   70.349499] br-wlan: port 1(ra0) entered disabled state
    [   70.360126] br-wlan: port 1(ra0) entered blocking state
    .... just for control, that it works ;-)

    The device overlay files target/linux/ramips/dts/OMEGA2.dtsi and target/linux/ramips/dts/OMEGA2.dts are unchanged.

    B) My setup: I've checked out https://github.com/OnionIoT/source (used the Docker image for building and did git pull to be on latest on branch openwrt-18.06) and selected the configuration .config.O2-minimum (cp .config.O2-minimum .config). Then I ran make menuconfig and selected (Main Menu --->) Kernel modules ---> Sound Support and selected the options kmod-sound-core, kmod-ac97, kmod-sound-mt7620, kmod-sound-soc-core.


    Under (Main Menu --->) Sound I selected alsa-utils, alsa-utils-tests and mpg123 to have software to use to test out the playback.

    I wired up the DAC to the Onion Omega 2S as e.g. described by Omega in a blog article herre and also wired the DAC up to a Raspberry Pi and used the hifiberry-dac driver, which is an I2S driver, and tested the hardware which works fine and should cancel out mostly any hardware issues.

    C) Other resources: I did a lot of tinkering around with the DTS/DTSI files, poked around inside the system and also search the internet and found the following related resources:

    D) Conclusion: so I had a long tinker day and found many resources but hadn't any luck to find a solution. I've the feeling that the software tooling (also kernel modules) is in place and a configuration is missing which glues everything together.

    Does anybody have any ideas?

  • After a looong night of tinkering and digging I finally got it working πŸŽ‰ 🎊

    TL;DR: you can find under [1] a patch or diff file which will make it work. It basically performs three important steps:

    • add the sound device to the device tree along with a codec, which is basically the HW device to play it back
    • enable I2S (see pinctrl), gdma and configure I2S
    • add the driver for the MAX98357A "codec" or hardware playback device to the kernel

    FYI: the last point was the step I was missing and in this case it does not work or it seems that nothing is happening

    The "MAX98357A" coded or I2S DAC IC is a generic one which accepts standard I2S audio and therefore others should work like PCM5102A etc. with this driver.

    Please note: currently the driver outputs on GPIO18 (<&gpio0 18 GPIO_ACTIVE_HIGH>) the SDMODE signal (active low) which indicates if sound is currently playing. So you cannot use this pin for another peripheral (it is PWM0). However I changed it to 19 (PWM1), because I'm using PWM0 already. I tested both 18/19 and they worked fine for me.

    The next thing is now to setup software volume control since we don't want to playback everything at full volume πŸ˜† For this you create a file /etc/asound.conf with the following contents:

    pcm.!default {
          type plug
          slave.pcm "softvol"
    pcm.softvol {
         type softvol
          slave {
              pcm "hw:0"
          control {
              name "Master"
              card 0
         min_dB -57.2
         max_dB -6.2
    ctl.!default {
            type hw
            card 0
    ctl.softvol {
            type hw
            card 0

    This will then enable software volume control which can be utilized by the alsa tools. To "activate" this config you need to play a "file"; I'm just doing cat /dev/urandom | aplay and pressing CTRL+C after 1 sec or so. Then, when running amixer controls you get:

    root@Omega-C8DC:/mnt/sda1# amixer controls

    and now you can control the volume e.g. with: amixer sset 'Master' 50%

    I didn't yet figure out why you also need to "activate" the config after reboot and how to configure it "properly" so that it works automatically.

    References: (further links which helped me):

    I hope that this explanation/question/how-to is helpful for somebody else, saving time in debugging πŸ˜€

    Have fun!

    [1] Patch file to apply on branch openwrt-18.06 of https://github.com/OnionIoT/source

    diff --git a/target/linux/ramips/dts/OMEGA2.dtsi b/target/linux/ramips/dts/OMEGA2.dtsi
    index 67910b4ce0..0fdffc9067 100644
    --- a/target/linux/ramips/dts/OMEGA2.dtsi
    +++ b/target/linux/ramips/dts/OMEGA2.dtsi
    @@ -30,6 +30,33 @@
     			linux,code = <KEY_RESTART>;
    +	sound {
    +		compatible = "simple-audio-card";
    +		simple-audio-card,name = "Audio-I2S";
    +		simple-audio-card,format = "i2s";
    +		simple-audio-card,bitclock-master = <&cpu_dai_master>;
    +		simple-audio-card,frame-master = <&cpu_dai_master>;
    +		simple-audio-card,widgets =
    +			"Speaker", "External Speaker";
    +		cpu_dai_master: simple-audio-card,cpu {
    +			sound-dai = <&i2s>;
    +		};
    +		dailink0_master: simple-audio-card,codec {
    +			sound-dai = <&codec>;
    +		};
    +	};
    +  codec: max98357a {
    +		#sound-dai-cells = <0>;
    +    compatible = "maxim,max98357a";
    +    sdmode-gpios = <&gpio0 18 GPIO_ACTIVE_HIGH>;
    +  };
     &pinctrl {
    @@ -51,7 +78,7 @@
     		i2s {
     			ralink,group = "i2s";
    -			ralink,function = "gpio";
    +			ralink,function = "i2s";
     		spis {
    @@ -164,6 +191,16 @@
     	status = "okay";
    +&gdma {
    +	status = "okay";
    +&i2s {
    +	#sound-dai-cells = <0>;
    +	status = "okay";
     &pwm {
     	status = "okay";
    diff --git a/target/linux/ramips/modules.mk b/target/linux/ramips/modules.mk
    index 88e83a487f..d9206c1c23 100644
    --- a/target/linux/ramips/modules.mk
    +++ b/target/linux/ramips/modules.mk
    @@ -121,13 +121,15 @@ define KernelPackage/sound-mt7620
    +	CONFIG_SND_SOC_WM8960 \
       FILES:= \
     	$(LINUX_DIR)/sound/soc/ralink/snd-soc-ralink-i2s.ko \
     	$(LINUX_DIR)/sound/soc/generic/snd-soc-simple-card.ko \
     	$(LINUX_DIR)/sound/soc/generic/snd-soc-simple-card-utils.ko \
    -	$(LINUX_DIR)/sound/soc/codecs/snd-soc-wm8960.ko
    -  AUTOLOAD:=$(call AutoLoad,90,snd-soc-wm8960 snd-soc-ralink-i2s snd-soc-simple-card)
    +	$(LINUX_DIR)/sound/soc/codecs/snd-soc-wm8960.ko \
    +	$(LINUX_DIR)/sound/soc/codecs/snd-soc-max98357a.ko
    +  AUTOLOAD:=$(call AutoLoad,90,snd-soc-wm8960 snd-soc-max98357a snd-soc-ralink-i2s snd-soc-simple-card)
       $(call AddDepends/sound)

    You should be able to run git apply the-patch.diff on the current branch if you put the patch into the file the-patch.diff.

  • @mythbu thanks a lot for sharing this!

    I remember my own long nights back in 2018, where @sza2-sza2 and me finally got i2s working (that forum thread you found and linked above πŸ™‚ ).

    Sorry that I did not see your original question earlier, only the solution now - if I did, I might have been able to help a bit.

    Anyway, glad to hear you got it working!

    But what I donβ€˜t understand: why did the i2s support disappear again after b177? As Iβ€˜m using only custom openwrt images, I lost track of details happening in the official onion releases. Since b177, i2s support was a ticked checkbox in my mind…

Looks like your connection to Community was lost, please wait while we try to reconnect.