Compile LEDE with audio suport on linkit 7688

Hello,

I try compile LEDE for my linkit 7688, I want use baresip on this board, but when I install this firmware in my board, I cant use sound, I make aplay -l but I receive a message no sound cards found

When I make /proc/asound in linkit with openwrt I receive this result

root@mylinkit:/# ls /proc/asound/
I2S      cards    hwdep    oss      seq      version card0    devices  modules  pcm      timers

When I make /proc/asound in linkit with LEDE I receive this result

  root@OpenWrt:/# ls /proc/asound/
  cards    devices  hwdep    oss      pcm      seq      timers   version

When I make lsmod in LEDE I receive

root@OpenWrt:/# lsmod | grep snd
regmap_mmio             2020  1 snd_soc_ralink_i2s
snd_ac97_codec         79838  1 snd_soc_ac97
snd_compress            7172  0 
snd_hwdep               4446  0 
snd_mixer_oss          12857  1 snd_pcm_oss
snd_pcm_oss            37105  0 
snd_rawmidi            15498  1 snd_seq_midi
snd_seq                43470  2 snd_seq_midi,snd_seq_midi_event
snd_seq_device          2255  3 snd_seq_midi,snd_seq,snd_rawmidi
snd_seq_midi            3984  0 
snd_seq_midi_event      3887  1 snd_seq_midi
snd_soc_ac97            1616  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 

I try rebuild the lede firmware with some new params in kernel modules, but I the sound if off.

Someone can help-me?

Hey, have you been able to implement audio support on MT7688? I'm facing similar problem.

Hi there, glad to see someone is also looking exactly at that!

I have the same problem and tried to find some more info:

  • audio works on the OpenWRT image provided by Mediatek here, version 0.9.4 specifically
    On this version, available kernel modules are:
root@mylinkit:/# ls /lib/modules/3.18.23/snd*
/lib/modules/3.18.23/snd-ac97-codec.ko
/lib/modules/3.18.23/snd-compress.ko
/lib/modules/3.18.23/snd-hwdep.ko
/lib/modules/3.18.23/snd-mixer-oss.ko
/lib/modules/3.18.23/snd-pcm-oss.ko
/lib/modules/3.18.23/snd-pcm.ko
/lib/modules/3.18.23/snd-rawmidi.ko
/lib/modules/3.18.23/snd-seq-device.ko
/lib/modules/3.18.23/snd-soc-core.ko
/lib/modules/3.18.23/snd-soc-mt76xx-i2s-ctl.ko
/lib/modules/3.18.23/snd-soc-mt76xx-i2s.ko
/lib/modules/3.18.23/snd-soc-mt76xx-machine.ko
/lib/modules/3.18.23/snd-soc-mt76xx-pcm.ko
/lib/modules/3.18.23/snd-soc-wm8960.ko
/lib/modules/3.18.23/snd-timer.ko
/lib/modules/3.18.23/snd.ko

Even though the names are different, it's very similar.

The above package, even though it refers to a (slightly) different SOC, includes a module for the very codec that is found on the LinkIt audio breakout board that I have, namely wm8960.

I'm trying to figure out as much as possible of the build process. I understand the Mediatek's OpenWRT takes its feed from there github repo.
Even though I can't find a dts file, which would help us a lot!
The current official OpenWRT dts is here: https://github.com/openwrt/openwrt/blob/master/target/linux/ramips/dts/LINKIT7688.dts

I got audio on the LinkIt Smart 7688 with breakout v2 somewhat working on OpenWrt 18.06.

The necessary drivers are contained in the packages kmod-sound-mt7620 and kmod-i2c-mt7628. To actually enable them, an audio card needs to be defined in the device tree. Here is a patch to do that:

diff -ru a/target/linux/ramips/dts/LINKIT7688.dts b/target/linux/ramips/dts/LINKIT7688.dts
--- a/target/linux/ramips/dts/LINKIT7688.dts
+++ b/target/linux/ramips/dts/LINKIT7688.dts
@@ -49,6 +49,40 @@
 			linux,code = <KEY_WPS_BUTTON>;
 		};
 	};
+
+	sound {
+		compatible = "simple-audio-card";
+		simple-audio-card,name = "I2S Audio";
+		simple-audio-card,format = "i2s";
+		simple-audio-card,bitclock-master = <&dailink0_master>;
+		simple-audio-card,frame-master = <&dailink0_master>;
+
+		simple-audio-card,widgets =
+			"Headphone", "Headphone Jack",
+			"Speaker", "Speakers",
+			"Microphone", "Microphone Jack",
+			"Line", "Line In";
+
+		simple-audio-card,routing =
+			"Headphone Jack", "HP_L",
+			"Headphone Jack", "HP_R",
+			"Speakers", "SPK_LN",
+			"Speakers", "SPK_LP",
+			"Speakers", "SPK_RN",
+			"Speakers", "SPK_RP",
+			"LINPUT1", "Microphone Jack",
+			"LINPUT2", "Line In",
+			"RINPUT2", "Line In";
+
+		simple-audio-card,cpu {
+			sound-dai = <&i2s>;
+		};
+
+		dailink0_master: simple-audio-card,codec {
+			sound-dai = <&codec>;
+			system-clock-frequency = <12288000>;
+		};
+	};
 };
 
 &pinctrl {
@@ -63,11 +97,6 @@
 			ralink,function = "gpio";
 		};
 
-		i2s {
-			ralink,group = "i2s";
-			ralink,function = "gpio";
-		};
-
 		spis {
 			ralink,group = "spis";
 			ralink,function = "gpio";
@@ -137,6 +166,21 @@
 
 &i2c {
 	status = "okay";
+
+	codec: wm8960@1a {
+		#sound-dai-cells = <0>;
+		compatible = "wlf,wm8960";
+		reg = <0x1a>;
+
+		wlf,shared-lrclk;
+	};
+};
+
+&i2s {
+	#sound-dai-cells = <0>;
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2s_pins>;
 };
 
 &uart1 {
@@ -164,3 +208,6 @@
 	status = "okay";
 };
 
+&gdma {
+	status = "okay";
+};

Then, on the running device, PCM playback needs to be unmuted and the volume must be set using alsamixer or amixer:

amixer set 'Left Output Mixer PCM' on
amixer set 'Right Output Mixer PCM' on
amixer set 'Headphone' 100%
amixer set 'Speaker' 10%

There are still some issues, though:

  • Sampling rates that are not multiples of 8000 kHz don't work (e.g. 44100kHz). This is because the WM8960 codec is connected to a fixed 12.288 MHz clock source, and the required clock for these sampling rates cannot be generated from that using integer division.

    The codec contains a PLL for this case, but there seems to be no way to actually use it without driver changes. Here is a very ugly hack that forces usage of the PLL, when necessary. The patch would need to be placed in target/linux/ramips/patches-4.14:

    --- a/sound/soc/codecs/wm8960.c
    +++ b/sound/soc/codecs/wm8960.c
    @@ -1288,6 +1288,9 @@
     	struct snd_soc_codec *codec = dai->codec;
     	struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
    
    +	clk_id = WM8960_SYSCLK_AUTO;
    +	wm8960->freq_in = freq;
    +
     	switch (clk_id) {
     	case WM8960_SYSCLK_MCLK:
    		snd_soc_update_bits(codec, WM8960_CLOCK1,
    

    A proper solution would probably require writing a custom audio card driver.

  • 24-bit audio does not work (16-bit is fine). It is garbled and played at 0.75x speed. I experimented a bit with the drivers, but did not find a solution. Setting I2S_REG_CFG0_NORM_24 in the ralink-i2s driver makes the playback speed normal, but the output is very quiet.

  • There needs to be a pause of a few seconds between using different sampling rates. Otherwise the audio is played at the wrong speed and/or garbled.

I didn't test audio capture or the speaker output yet.

1 Like

@janh your patch also works with the latest OpenWrt 18.06.5. Thanks for this.

However, there are still some audio issues, that I may need to look back at some patches from Respeaker repo - which has some modifications: