I2S ADC Headaches



  • Just when I thought I've got this I2S thing all figured out I've hit a deadend with trying to integrate an ADC to record some audio.

    I have managed to configure I2S to play audio through a PCM5102 device link this cheapy from banggood PCM5102a.

    I now need to record and since I had the PCM5102 as a DAC I decided why not look at what else Texes Instruments has to offer in terms of its counterpart the ADC. Sure enough I came across a ADC part number PCM1860 and its all been downhill from there.

    Ive got the PCM1860 connected to the Omega I2S's CLK, WS and SDI pins. however I am struggling to get the device recognised. This is most likely due to incorrect Device Tree configuration as I could not find a device tree binding for this specific ADC, closest was PCM186x, however this seem to be for the PCM1862+ which have I2C control pins whereas the PCM1860 is HW controlled through pullup/downs etc.

    In the hope that someone might point me in the correct direction these are the dtsi configurations I have tried, but none expose the ADC in arecord -l.

    This DTSI allows the DAC only to function
    https://pastebin.com/z9H67DHd

    These are my attempts at including the DAC with the ADC:
    https://pastebin.com/RLsKNsiR
    https://pastebin.com/rmJVcCz1

    Do share if anyone has managed to do any I2S audio capture.
    Thanks,
    UFD



  • If it helps anyone, I think I made some headway here.

    After much messing around and multiple builds later I started getting a basic understanding of codecs (i.e. devices that support sound playback and/or capture), alsa and linux kernels.

    codecs are built as part of the kernel build process. codec IC's are apparently made by multiple manufactures and although most comply with standard protocols like I2S or PCM (for audio data transfer) they each have differences in how they are controlled. like one chip might have 4 ADC sound inputs, or offer sound level control functionality. These control commands are not supported by the I2S protocol and are rather implemented using I2C(mostly) or SPI or general gpio 1/0. With I2C etc each chip will have different registers to set and configure its functionality. This is why you need a codec for your specific chip. Codecs supported by linux are listed here codec documents.

    Here are some of the gotchas i faced:

    1. Codecs are continually added to linux kernel source. openwrt(what onion runs) is still on version 4.14 of the kernel whereas some codecs were added later. I found it was not as simple as patching in the missing files as there were lower level dependancies.

    2. Device tree configuration is not as trivial as I imagined, especially if you are new and are trying to implement something not very common.

    3. I did not succeed in finding a way to enable debugging logs of sort to aid with the codec loading issues. My approach was: change something, rebuild, test, repeat x100

    However for "simple" I2S devices with no control protocol, like the PCM5102a, MAX98367A or PCM1860 you might get away with two generic codecs supported by the kernel i.e. spdif-receiver and spdif-transmitter, which to my knowledge are generic devices with limited capabilities.

    Using these generic codecs I have managed to create a build that supports both playback and capture. I2S_Audio_Image based on latest code 0.3.2 b233.

    The Device Tree modifications include:

        sound {
                compatible = "simple-audio-card";
                simple-audio-card,name = "Audio-I2S";
                simple-audio-card,format = "i2s";
                simple-audio-card,widgets =
                        "Speaker", "External Speaker",
                        "Microphone", "Microphone Jack";
    
                simple-audio-card,dai-link@0{
                    format = "i2s";
                    cpu {
                        sound-dai = <&i2s>;
                    };
                    codec {
                        sound-dai = <&codec_out>;
                   };
               };
    
               simple-audio-card,dai-link@1{
                   format = "i2s";
                   cpu {
                       sound-dai = <&i2s>;
                   };
                   codec {
                       sound-dai = <&codec_in>;
                   };
               };
    
        };
    
        codec_out: txcodec {
            #sound-dai-cells = <0>;
            #address-cells = <0>;
            #size-cells = <0>;
            compatible = "linux,spdif-dit";
            status = "okay";
        };
    
        codec_in: rxcodec {
            #sound-dai-cells = <0>;
            compatible = "linux,spdif-dir";
        };
    

    Regards,
    UFD



  • I am very, very interested in getting this i2s module to work with Omega.
    Do you have a connection guide?



  • Hi, @UFD, can you share your build config? I failed to replicate your build. After hours of trying I was able to replicate your device tree (with help of this topic), but I still got 0 soundcards. I suspect its the lack of snd_soc_spdif_tx/rx modules to blame, but I cant figure out how to add them.



  • @zazu-z You already quoted the thread where I described my i2s adventures from a few years back now. I struggled a long time to get the extra codec I wanted to build, but in the end it was a few lines added to target/linux/ramips/modules.mk.

    Maybe looking at my original patch here, which adds the max98357A codec, might help to do the same for any of the other codecs available (visible in build_dir/target-mipsel_24kc_musl/linux-ramips_mt76x8/linux-4.14.151/sound/soc/codecs).



  • Hey @zazu-z , indeed @luz is correct.

    You will need to add the config to target/linux/ramips/modules.mk

    At the end of the file my changes are as follows:

    define KernelPackage/sound-mt7620
      TITLE:=MT7620 PCM/I2S Alsa Driver
      DEPENDS:=@TARGET_ramips +kmod-sound-soc-core +kmod-regmap +kmod-dma-ralink @!TARGET_ramips_rt288x
      KCONFIG:= \
        CONFIG_SND_RALINK_SOC_I2S \
        CONFIG_SND_SIMPLE_CARD \
        CONFIG_SND_SIMPLE_CARD_UTILS \
        CONFIG_SND_SOC_SPDIF
      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-spdif-rx.ko \
        $(LINUX_DIR)/sound/soc/codecs/snd-soc-spdif-tx.ko
      AUTOLOAD:=$(call AutoLoad,90,snd-soc-spdif-rx snd-soc-spdif-tx snd-soc-ralink-i2s snd-soc-simple-card)
      $(call AddDepends/sound)
    endef
    
    define KernelPackage/sound-mt7620/description
     Alsa modules for ralink i2s controller.
    endef
    

    If I recall correctly the above can also more correctly be achieved by doing a:

    make kernel_menuconfig
    

    And enabling the SPDIF module in:

    Device Drivers -> Sound card support -> Advanced Linux Sound Architecture -> ALSA for SoC audio support -> CODEC drivers
    

    Hope that helps.
    Regards,
    UFD



  • @luz, @UFD guys, you are awesome. I wasted about week to get it work and you told me an answer withing few hours. I can confirm working i2s virtual card. I still can't get sound from mic, but this is hardware problem as I understand.



  • @zazu-z , Its only because I've spend the last 6 months trying to figure it out. I've also found value in the forum and therefore Im always happy to give back.
    The solution is not perfect and I am actually experiencing alsa overrun issues when recording. In my books it's still a challenge that needs a fully understood solution.



  • @UFD
    What are you recording onto? bigger also buffer or making the process run as a higher priority can help.

    I tried your build as I have also spent ages trying to get i2s audio out
    and it does work well with my 1502 board( own design) - thanks.

    I never got any official reply on whether i2s audio I/o would be part if the 'factory' builds... šŸ˜ž There is project in the docs that says i2s audio is included and shows
    a setup , but its out of date and doesn't work.

    I'm looking at manufacturing a combined pcm1502a + pcm186x board
    and currently considering the omega2+ as the host processor.



  • @Denis-Mikhalsky

    For playback into a pcm1502a board the wiring here will work:
    https://onion.io/2bt-omega-i2s-audio/
    You can ignore the setup stuff, just use UFDs build and it works.



  • @luz said in I2S ADC Headaches:

    max98357A

    Hi @luz I was trying to make max98357A work and have find your post and patches but it doens't work, please let me now your thoughts about the process I've followed..

    Basically I've downloaded a clean onion distro and download 210-omega2-sound-max98357a.diff. After configure onion-minimal-build.sh I've apply your patch. "make" works but alsa shows now audio cards.

    I'm afraid that I've to insert max98357A module after board boots.. but not sure. It would be nice to know your opinion.



  • @sergiosmail do you get anything when doing the following?

    root@pixelboard:~# cat /proc/asound/cards
    0 [AudioI2S       ]: Audio-I2S - Audio-I2S
                          Audio-I2S
    

    If not, please check that you have enabled the kernel package sound-mt7620 in menuconfig.

    The 210-omega2-sound-max98357a.diff patch makes sure that the snd_soc_max98357a module should get automatically loaded at startup. You can check in /etc/modules.d:

    root@pixelboard:~# ls -la /etc/modules.d/*sound*
    -rw-r--r--    1 root     root           126 Jan 30  2019 /etc/modules.d/30-sound-core
    -rw-r--r--    1 root     root            13 Jan 30  2019 /etc/modules.d/55-sound-soc-core
    -rw-r--r--    1 root     root            72 Jan 30  2019 /etc/modules.d/90-sound-mt7620
    
    root@pixelboard:~# cat /etc/modules.d/90-sound-mt7620
    snd-soc-wm8960
    snd-soc-max98357a
    snd-soc-ralink-i2s
    snd-soc-simple-card
    

    Finally, before you can play sounds:

    root@pixelboard:~# alsactl init
    Found hardware: "Audio-I2S" "" "" "" ""
    Hardware is initialized using a generic method
    

    From here on aplay and other sound tools should work

    aplay /path/to/sound.wav
    

    If you want more control, such as a mixer with two separate volumes for background music and game sounds, look at pixelboard's asound.conf

    Also, playing mod files is fun (need very littel disk space, lots of tunes can be found online), possible with the hxcmodplayer package



  • @luz I've repeat all the mentioned steps and it works now... I can't belive šŸ˜„

    My fault was that I wasn't applying 210-omega2-sound-max98357a.diff correctly. The patch fails for 0.3.2 b238, and I wasn't applying it correctly (doing changes manually)

    I've tested using mpg123 mp3 player and aplay commands. Works fine.

    Also thank you for the tip about mixer and hxcmodplayer



  • I tried to connects I2S sound card CJMCU-4344 (alternate PCM5102), based on Cirrus Logic CS4344. I cant understand: all I2S modules are already loaded, why I have no any soundcard device?

    These are my sound modules that is loaded:

    root@Omega-D913:~# lsmod | grep snd_
    regmap_i2c              2298  1 snd_soc_wm8960
    snd                    41582 12 snd_usb_audio,snd_usbmidi_lib,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  1 snd_usb_audio
    snd_mixer_oss          12729  1 snd_pcm_oss
    snd_pcm                61710  6 snd_usb_audio,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  1 snd_usbmidi_lib
    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
    snd_usb_audio         121378  0
    snd_usbmidi_lib        16883  1 snd_usb_audio
    usbcore               137059 29 option,uvcvideo,usb_wwan,snd_usb_audio,pl2303,ftdi_sio,cp210x,ch341,usbserial,usblp,usbhid,ums_usbat,ums_sddr55,ums_sddr09,ums_karma,ums_jumpshot,ums_isd200,ums_freecom,ums_datafab,ums_cypress,ums_alauda,snd_usbmidi_lib,cdc_acm,btusb,usb_storage,ohci_platform,ohci_hcd,ehci_platform,ehci_hcd
    

    And we can see no any card installed!

    root@Omega-D913:~# aplay -l
    aplay: device_list:272: no soundcards found...
    
    root@Omega-D913:~# alsactl init
    alsactl: init:1757: No soundcards found...
    
    root@Omega-D913:~# aplay -L
    null
        Discard all samples (playback) or generate zero samples (capture)
    
    root@Omega-D913:~# cat /proc/asound/cards
    --- no soundcards ---
    

    Onion OS: 0.3.2 b233, kernel version 4.14.81



  • The kernel objects in the Linux OS' are very capricious thing and one of the biggest problem. So... kernel object will work only in the same kernel version and build number, well I want to say these are likely static feature than dynamical as it give us.

    We (users) can't append sound driver or TFT-display (frame buffer driver and his friends), PCI Express->SATA controller, etc.!

    To append your own kernel object you have to build you own firmware - it's not convenient. Second way - build kernel objects on the omega (direct compilation), but it needs special tools, like linux-headers-*, that's out of repositories too.

    Let's type code in Python! ((



  • Hi,

    I have configured the I2S as it is shown in this topic and the I2S Output work perfectly.
    Now, I'm testing the I2S Input and I've found some problems.

    I'm trying a loopback between I2S_DOUT and I2S_DIN to test the I2S input.
    When I try to use the arecord command there is an error:

    arecord: main:828: audio open error: No such file or directory
    

    Could you indicate how did you test the I2S input?

    Thank you

    PD: here are the output of the arecord -l and arecord -L:

    root@OpenWrt:/# arecord -l
    **** List of CAPTURE Hardware Devices ****
    card 0: AudioI2S [Audio-I2S], device 1: ralink-i2s-dir-hifi dir-hifi-1 [ralink-i2s-dir-hifi dir-hifi-1]
      Subdevices: 1/1
      Subdevice #0: subdevice #0
    root@OpenWrt:/# arecord -L
    null
        Discard all samples (playback) or generate zero samples (capture)
    

Log in to reply
 

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