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.