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/z9H67DHdThese are my attempts at including the DAC with the ADC:
https://pastebin.com/RLsKNsiR
https://pastebin.com/rmJVcCz1Do 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:
-
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.
-
Device tree configuration is not as trivial as I imagined, especially if you are new and are trying to implement something not very common.
-
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.
-
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)