[Resolved] Attaching PCM5102 to Omega2 (I2S)



  • I have not yet received my Omega2, but I will try the same. By theory, you need to get kernel drivers for the hifiberry running and also you need to connect the i2c lines.



  • I'm trying a similar thing (connecting a MAX98357A i2s audio amp), so I'd be interested in hearing about any experience with i2s from others.

    I'm currently trying to test the hardware setup with the very simple dma-to-i2s kernel driver vocore-gdma which just uses MT7688's GDMA to shove out 2M of raw sound data to i2s. Right now, something is not working yet, I can only produce a small hissing noise 😞



  • I spent the weekend trying to get this (Omega2 + MAX98357A connected via i2s) working. Not yet successful, but here's the status:

    Most of the time I spent trying to understand ALSA (Advanced Linux Sound Architecture), ASoC (ALSA for SoCs), and what components and device tree entries are needed for finally putting a "sound card" together that can be used with the alsactl and aplay utilities.

    Now I have such a setup, but unfortunately, trying to play a sound file with aplay immediately crashes the Omega2 😞

    In order to get the simple MAX98357A codec (similar to PCM5102 in that its a pure output device, with no i2c configuration) built, I had to do three things in LEDE (patches see below):

    • patch the makefile that configures the build for sound-mt7620 to include the snd-soc-max98357a codec
    • add a kernel patch that actually enables building soc-max98357a at all
    • extend the Omega2 device tree to include sound

    Then, in make menuconfig in Kernel modules -> Sound support I enabled kmod-sound-mt7620 and in Sound I selected alsa-utils

    With this, I get a LEDE build where I can see that I have a "sound card" with cat /proc/asound/cards, and successfully (no error, no crash) initialize alsa with alsactl init.

    But as soon as I try to aplay /tmp/mysoundfile, the Omega2 crashes apparently while memmapping something 😞

    Any ideas welcome…

    BTW: The pcm5102 will probably work with the soc-max98357a driver as well. The only difference I see is that the MAX chip has a input (SDMODE) to switch off the amplifier when not in use, via a GPIO. I set gpio 18 for that (via the sdmode-gpios line in the .dts), but it can be omitted.

    Crash:

    [  322.634556] Kernel bug detected[#1]:
    [  322.638208] CPU: 0 PID: 1123 Comm: aplay Tainted: G        W       4.4.61 #0
    [  322.645359] task: 83920000 ti: 83bba000 task.ti: 83bba000
    [  322.650828] $ 0   : 00000000 00000001 00000002 00000002
    [  322.656147] $ 4   : 8310f400 82d89948 82d89948 00004000
    [  322.661457] $ 8   : 00000018 80008c58 77c07000 00004000
    [  322.666770] $12   : 00001000 00006000 fffffffc 00004000
    [  322.672081] $16   : 8310f400 00000008 82d8c500 82c10600
    [  322.677389] $20   : 77c00000 77c04000 00000000 00000004
    [  322.682699] $24   : 00001072 77b74e00                  
    [  322.688011] $28   : 83bba000 83bbbdf8 00000000 83092250
    [  322.693321] Hi    : 00000000
    [  322.696238] Lo    : 00000004
    [  322.699223] epc   : 83092160 snd_pcm_lib_default_mmap+0x30/0x48 [snd_pcm]
    [  322.706121] ra    : 83092250 snd_pcm_mmap_data+0xd8/0xe60 [snd_pcm]
    [  322.712470] Status: 1100e403	KERNEL EXL IE 
    [  322.716723] Cause : 10800024 (ExcCode 09)
    [  322.720787] PrId  : 00019655 (MIPS 24KEc)
    [  322.724847] Modules linked in: i2c_gpio_custom p44_ledchain pppoe ppp_async iptable_nat pppox ppp_generic pl2303 nf_nat_ipv4 nf_conntrack_ipv6 nf_conntrack_ipv4 ipt_REJECT ipt_MASQUERADE ftdi_sio cp210x xt_time xt_tcpudp xt_state xt_nat xt_multiport xt_mark xt_mac xt_limit xt_conntrack xt_comment xt_TCPMSS xt_REDIRECT xt_LOG usbserial spidev spi_gpio spi_bitbang slhc nf_reject_ipv4 nf_nat_redirect nf_nat_masquerade_ipv4 nf_nat nf_log_ipv4 nf_defrag_ipv6 nf_defrag_ipv4 nf_conntrack_rtcache nf_conntrack iptable_mangle iptable_filter ip_tables crc_ccitt snd_soc_simple_card snd_soc_ralink_i2s snd_soc_max98357a snd_soc_wm8960 i2c_mt7621 i2c_gpio snd_soc_core i2c_algo_bit ralink_gdma virt_dma mt76x2e mt7603e i2c_dev mt76 mac80211 cfg80211 compat ledtrig_oneshot ip6t_REJECT nf_reject_ipv6 nf_log_ipv6 nf_log_common ip6table_mangle ip6table_filter ip6_tables x_tables snd_pcm_dmaengine snd_compress snd_pcm_oss snd_mixer_oss snd_pcm snd_timer snd_rawmidi snd_seq_device snd_hwdep snd input_core soundcore regmap_spi regmap_mmio regmap_i2c i2c_core regmap_core lzo_decompress lzo_compress leds_gpio ohci_platform ohci_hcd ledtrig_transient ehci_platform ehci_hcd gpio_button_hotplug usbcore nls_base usb_common
    [  322.832567] Process aplay (pid: 1123, threadinfo=83bba000, task=83920000, tls=77c11d48)
    [  322.840675] Stack : 77c00000 77c04000 00000000 00000000 82d89948 80098938 00000000 00004000
    	  82d8c500 00004000 000000fb 00000000 82d8c500 00000000 00000000 00000010
    	  00000020 803e0000 00000001 82d89478 82d8948c 82d89488 77c00000 000000fb
    	  82d8c500 00004000 00000001 00000002 00000000 00000004 82c10600 80098f38
    	  77c09e24 00000000 83920000 83920030 00000000 832d9020 82c10634 82d8c500
    	  ...
    [  322.876798] Call Trace:
    [  322.879297] [<83092160>] snd_pcm_lib_default_mmap+0x30/0x48 [snd_pcm]
    [  322.885863] [<83092250>] snd_pcm_mmap_data+0xd8/0xe60 [snd_pcm]
    [  322.891903] [<80098938>] mmap_region+0x29c/0x544
    [  322.896589] [<80098f38>] do_mmap+0x358/0x3d4
    [  322.900943] [<8008a558>] vm_mmap_pgoff+0x70/0xb8
    [  322.905631] [<8009744c>] SyS_mmap_pgoff+0x8c/0xd8
    [  322.910413] [<8000682c>] syscall_common+0x30/0x54
    [  322.915178] 
    [  322.916685] 
    Code: 24020002  14620002  00000000 <000c000d> 3c02830a  2442ce08  aca20048  03e00008  00001021 
    [  322.926894] ---[ end trace 23ba50ddf57c2faa ]---
    [  322.934722] Fatal exception: panic in 5 seconds
    [  327.941901] Kernel panic - not syncing: Fatal exception
    [  327.949339] Rebooting in 3 seconds..
    

    Patch for the makefile:

    --- a/target/linux/ramips/modules.mk
    +++ b/target/linux/ramips/modules.mk
    @@ -120,12 +120,14 @@ define KernelPackage/sound-mt7620
       KCONFIG:= \
            CONFIG_SND_RALINK_SOC_I2S \
            CONFIG_SND_SIMPLE_CARD \
    -       CONFIG_SND_SOC_WM8960
    +       CONFIG_SND_SOC_WM8960 \
    +       CONFIG_SND_SOC_MAX98357A
       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/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)
     endef
    

    Patch for the kernel config

    --- /dev/null
    +++ b/target/linux/ramips/patches-4.4/0722-asoc-enable-max98357a-kconfig.patch
    @@ -0,0 +1,11 @@
    +--- a/sound/soc/codecs/Kconfig
    ++++ b/sound/soc/codecs/Kconfig
    +@@ -487,7 +487,7 @@
    +        tristate
    +
    + config SND_SOC_MAX98357A
    +-       tristate
    ++  tristate "Maxim MAX98357A CODEC"
    +
    + config SND_SOC_MAX98925
    +        tristate
    

    Patch for the OMEGA2.dtsi device tree source

    --- a/target/linux/ramips/dts/OMEGA2.dtsi
    +++ b/target/linux/ramips/dts/OMEGA2.dtsi
    @@ -30,6 +30,31 @@
                            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 +76,7 @@
     
                    i2s {
                            ralink,group = "i2s";
    -                       ralink,function = "gpio";
    +                       ralink,function = "i2s";
                    };
     
                    spis {
    @@ -170,5 +195,6 @@
     };
     
     &i2s {
    +       #sound-dai-cells = <0>;
            status = "okay";
     };
    


  • @CPU-Hacker PCM5102 does not have I2C interface.



  • @luz Hi Luz,

    It's been a long time that I opened this thread - and also that you were here...

    Based on your guide I tried to mimic what you did to reproduce the issue but I stuck at the very beginning.

    I've compiled an image with the default settings based on the following:

    https://docs.onion.io/omega2-docs/cross-compiling.html

    The image built successfully, and run correctly on Omega2.

    Then I applied patches you shared, but I cannot find sound related menu in the menuconfig (kernel sound support appears, enabled, compiled, but there is no sound / alsa-utils available in the top level menu).

    Actually, I patched OMEGA2.dtsi manually as the whole section:

     &i2s {
    +       #sound-dai-cells = <0>;
            status = "okay";
     };
    

    was missing.

    Do you have any advice what else should I modify / configure (or what I missed)?

    Thanks,

    /sza2

    Edit:

    Finally I've managed to install alsa stuff by uncommenting some lines in feeds.conf.default and running an update, so now I have alsa.
    However, I cannot see any soundcard:

    root@LEDE:/# cat /proc/asound/cards
    --- no soundcards ---
    root@LEDE:/# cat /proc/asound/devices
     33:        : timer
    root@LEDE:/# cat /proc/asound/timers
    G0: system timer : 10000.000us (10000000 ticks)
    root@LEDE:/# cat /proc/asound/version
    Advanced Linux Sound Architecture Driver Version k4.9.34.
    

    Thus alsactl init does nothing:

    root@LEDE:/# alsactl init
    alsactl: init:1758: No soundcards found...
    

    The MAX98357A module (snd_soc_max98357a) is loaded:

    i2c_core               20006 15 snd_soc_wm8960,v4l2_common,videodev,i2c_tiny_usb,i2c_mt7621,i2c_gpio,i2c_algo_pcf,i2c_algo_pca,i2c_algo_bit,i2c_mux_pca954x,i2c_mux_pca9541,i2c_mux_gpio,i2c_mux,i2c_dev,regmap_i2c
    input_core             25126  5 uvcvideo,rotary_encoder,gpio_beeper,snd,input_polldev
    regmap_core            32572  6 snd_soc_ralink_i2s,snd_soc_wm8960,snd_soc_core,regmap_spi,regmap_mmio,regmap_i2c,[permanent]
    regmap_i2c              2298  1 snd_soc_wm8960
    regmap_mmio             2020  1 snd_soc_ralink_i2s
    snd                    41166 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            7076  0
    snd_hwdep               4382  0
    snd_mixer_oss          12761  1 snd_pcm_oss
    snd_pcm                63733  5 snd_soc_ralink_i2s,snd_soc_wm8960,snd_soc_core,snd_pcm_dmaengine,snd_pcm_oss
    snd_pcm_dmaengine       2907  1 snd_soc_core
    snd_pcm_oss            35793  0
    snd_rawmidi            15370  0
    snd_seq_device          2191  1 snd_rawmidi
    snd_soc_core          100019  5 snd_soc_max98357a,snd_soc_simple_card,snd_soc_simple_card_utils,snd_soc_ralink_i2s,snd_soc_wm8960
    snd_soc_max98357a       1808  0
    snd_soc_ralink_i2s      6320  0
    snd_soc_simple_card     4304  0
    snd_soc_simple_card_utils    2299  1 snd_soc_simple_card
    snd_soc_wm8960         23360  0
    snd_timer              15310  1 snd_pcm
    soundcore               3836  1 snd
    

    but it does not seem to used by any other module.



  • Hi @sza2-sza2,

    glad I'm not the only one still trying to get this working πŸ˜‰

    Maybe you can compare your LEDE diffconfig with my diffconfig that you find here at github. This should reveal what things are missing/different.

    The diffconfig ist the delta between a fresh LEDE default configuration and the configuration used to build a particular image. To create your diffconfig:

    ./scripts/diffconfig.sh >"diffconfig-for-my-setup"
    

    I'm usually building my images from the lede-17.01 branch, my last attempt with alsa soundcard present, but not sound coming out the i2s was built from commit 524ed5088e900821307694180d77038df5a3ea9a. I also apply a few more patches to LEDE than the ones shown above (all patches are collected here), but none of the other ones should be relevant for i2s/sound.

    Hope that helps. It would be nice if we can figure out i2s sound eventually!



  • @luz Hi,

    Here is my diffconfig output. I did not find significant differences compared to yours.

    Additionally, dmesg and lsmod.

    I cannot see any MAX98357A related lines in dmesg and the use count of snd_soc_max98357a module is 0 reported by lsmod.

    I have no clue.

    Do you think you could share a binary image to test?

    /sza2

    Edit: I tried with several kernel configuration (enable / disable stuffs like GPIO / I2C / SPI /whatever - from which I thought that can influence: no success). If I enable "dummy" in sound drivers dummy device appears in /proc/asound/cards and then obviously displayed with alsactl init as well).



  • @sza2-sza2 here's my lsmod snd section:

        snd                    40910 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            6303  0 
    snd_hwdep               4350  0 
    snd_mixer_oss          12761  1 snd_pcm_oss
    snd_pcm                63018  5 snd_soc_ralink_i2s,snd_soc_wm8960,snd_soc_core,snd_pcm_dmaengine,snd_pcm_oss
    snd_pcm_dmaengine       2779  1 snd_soc_core
    snd_pcm_oss            35825  0 
    snd_rawmidi            15402  0 
    snd_seq_device          2191  1 snd_rawmidi
    snd_soc_core           97120  4 snd_soc_simple_card,snd_soc_ralink_i2s,snd_soc_max98357a,snd_soc_wm8960
    snd_soc_max98357a       1776  1 
    snd_soc_ralink_i2s      6064  2 
    snd_soc_simple_card     5216  0 
    snd_soc_wm8960         22720  0 
    snd_timer              15598  1 snd_pcm
    soundcore               3836  1 snd
    

    The difference to yours seems to be that in my case snd_soc_ralink_i2s has a use count of 2.

    I'd guess that snd_soc_ralink_i2s not being used at all must be something in the device tree, so below are my target/linux/ramips/dts/mt7628an.dtsi and target/linux/ramips/dts/OMEGA2.dtsi files. I would have preferred to upload them here, but board software says I am not allowed to upload?! Pastebin, then.



  • @luz Hi,

    Thanks to your help it works now correctly, aplay plays the wav files.

    I played a 2ch / 16bit / 44.1Hz wav (1kHz, 0dB).

    The output on the I2S lines:
    0_1500288215556_i2s_1kHz_0db_data.png

    The waveform on the output of the DAC:
    0_1500288335923_i2s_1kHz_0db_wav.png

    So, now we have to figure out why yours is crashing.

    /sza2



  • @sza2-sza2 Wow! Terrific news!!

    Thanks a lot for the nice diagrams (Saleae Logic is great πŸ˜‰

    Did you apply all of my patches, in particular, did you apply 942-omega2-dma-bughunt-WIP?

    Because since that patch, I can use aplay without crash, and I even see the WS clock running during the time a sound plays, but there is zero output on the data line. So I thought that something is wrong in the DMA setup, such that no data reaches the i2s engine. But if it works in your case, it can't be a fundamental DMA problem. Maybe something as mundane as a short on my PCB… (I'll re-check that, although needs some time to disassemble the pixelboard)

    BTW: what is the SHA of the LEDE (git rev-parse HEAD) you've been using?



  • @luz Hi,

    Actually, I did not apply all the patches. I modified some files manually as the patching was failed (probably the delta was to big to successfully apply - I did not spend so much time to figure out why).

    I cloned the repo first last week commit 78057457912170ceba29792ef02ba441abe8f246 and I did a lot of tinkering, I don't remember the several config changes I made.

    So yesterday I cloned again (cb2a3911e15df3be15126fc17fabe6f3671eee7b) to have a fresh copy and I did the following:

    1. added MAX98357A related stuff to target/linux/ramips/modules.mk (based on your patch)
    2. added target/linux/ramips/patches-4.4/0722-asoc-enable-max98357a-kconfig.patch
      (well, I'm not a kernel guru, so I don't understand why it is necessary to replace tristate with tristate "Maxim MAX98357A CODEC" in Kconfig but the compilation stopped with errors if I did not apply this)
    3. added lines to OMEGA2.dtsi based on your patches (my current OMEGA2.dtsi) - modifications in mt7628an.dtsi was not necessary

    The result of the above was a kernel which supports MAX98357A (thus PCM5102 too).

    Hope this helps.

    /sza2

    PS: I like Saleae - however I ran into trouble due to its limitation that no continuous sampling to disk, but the maximum is the free RAM size. Although the support was good, they offer a full refund of price of the two Logic Pro 16 - well, we chose not to send back but use for other tasks πŸ™‚



  • @sza2-sza2 it works now!! πŸ˜„

    Thanks a lot for the detailed steps!

    I was using lede-17.01 before, which is still on kernel 4.4 and had the problem with DMA that made it either crash or (with my attempt to fix it with 942-omega2-dma-bughunt-WIP) not transfer data to the output.

    Apparently, some work and bugfixes for the mt76xx SoCs got upstreamed into Linux mainline between 4.4 and 4.9. At least, the DMA related LEDE patch target/linux/generic/patches-4.4/132-mips_inline_dma_ops.patch that contains the code which was causing the crash, has disappeared in LEDE master.

    Anyway - i2s sound output with max98357a works now, with less patching than before! Great!

    But no advance without new problems - with kernel 4.9 the PWM support (/sys/class/pwm/)… does not work any more, because it tries and fails to claim gpio18 for some unknown reason, which is already claimed by something else, for another unknown reason πŸ˜‰



  • @luz Hi,

    Glad to hear that I2S works - bad, that something else broken 😞 Currently, I don't plan to use any PWM stuff - but as a newbie I still struggling even with simple GPIOs (it works with official v0.1.9-b159 - so I'm almost sure it is a kernel configuration difference or some user space mistake I made).

    /sza2



  • Hi @luz & @sza2-sza2 have you already tested the quality of sound through i2s on Omega? How is it? Is it worth the fort of compiling custom fw, or it is better to use simple USB-SoundCards?
    Can someone of you please share fw image with working i2s for omega2 or omega2p?



  • @Xplatforms I haven't really tested it, because in my application it's for game sounds (more beeping than music) and connected to a very tiny loudspeaker of limited quality.

    But I see no reason why the sound should be inferior to USB soundcards. i2s as such is lossless, it only depends on the output chip and its specs. I am using the MAX98357A, a really tiny (3x3mm housing) class D mono amplifier chip designed for phone and tablet speakers, and I'd say my setup sounds like a phone.

    On the contrary, USB sound is much more complicated and probably also needs more CPU time from the Omega2.



  • @luz I'm asking because of that comment from onion admins: 0_1502276838089_omega.png
    in this topic: https://community.onion.io/topic/287/solved-i2s-pins-on-omega/5

    Can you share your image for test purpose please?



  • @Xplatforms said in [Resolved] Attaching PCM5102 to Omega2 (I2S):

    @luz I'm asking because of that comment from onion admins: 0_1502276838089_omega.png
    in this topic: https://community.onion.io/topic/287/solved-i2s-pins-on-omega/5

    I see. No idea why Boken came to that conclusion - but then, that was two years ago with the Omega1/AR9331. Could well be that ASoC (ALSA for SoCs) wasn't ready back then. After all, ASoC for the MT7688 started working apparently only with a kernel newer than 4.4.

    Can you share your image for test purpose please?

    The image is highly customized for the application (the "pixelboard" - tetris/game-of-life lounge table)), so it might be a bit difficult to use, but here's the image where aplay works via MAX98357A. You might need to enter "failsafe" mode and edit out the "*" in /etc/shadow for the root user to be able to login.



  • @Xplatforms Hi,

    First of all, I not an audiophile guy. Although my experience with the DAC mentioned in the topic title is pretty good - at least to my ears. You can also take a look at the sine wave I captured, there's no distortion, no noticeable noise on it, that's a quite good waveform.

    I've tested the channels by a 20W class-D amplifier (TPA3100 based), and it was good too. Obviously, the analog part is sensitive to the digital noise generated by the Omega2.

    Regarding the USB sound cards, there are huge differences between specific models. Years ago, I bought one for ~2USD but its sound is terrible (I've tested it with the same Omega2 HW a few month ago - that's why I decided to find some way to use the I2S DAC).

    On the other hand, I heard the sound of a so called Hi-Fi USB sound card and that was rather like my I2S HW (I cannot decide whether it was better or worse, but about the same quality).

    I cannot say anything about the resource side, I assume @luz is right.

    /sza2



  • @luz , @sza2-sza2 thank you very much for your answers and sharing image! I'll try it today



  • @luz I think the gpio18 is used for the max98357a at the dts file,

    sdmode-gpios = <&gpio0 18 GPIO_ACTIVE_HIGH>;
    

    you can remove that pin config, and try.


Log in to reply
 

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