I2s freezing on MT7628

I have problem with i2s configuration on SKW92A, it's a module on mt7628an. I have a board with wm8960 codec, but i2s is freezing and restarting my board. i2c part works correctly (sets proper registers in codec and codec is responding), refclk is outputting signal, but when I start aplay or even copy data to /dev/dsp, i2c data is sent, but no i2s data (checked with logic analyzer).

My dts (after trying some different pin configurations):

....
        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 =
                        "Speaker", "Speaker";

                simple-audio-card,routing =
                        "Speaker", "SPK_LN",
                        "Speaker", "SPK_LP";

                simple-audio-card,cpu {
                        sound-dai = <&i2s>;
                };

                dailink0_master: simple-audio-card,codec {
                        sound-dai = <&codec>;
                        system-clock-frequency = <12288000>;
                };
        };
};

&pinctrl {
        state_default: pinctrl0 {
                gpio {
                        ralink,group = "wdt", "wled_an", "pwm0", "pwm1", "spis", "uart2", "sdmode";
                        ralink,function = "gpio";
                };
                refclk {
                        ralink,group = "refclk";
                        ralink,function = "refclk";
                };


        };
    i2s_pins: i2s {
        i2s {
            ralink,group = "i2s";
            ralink,function = "i2s";
        };
/*      wm8960_mclk {
            ralink,group = "refclk";
            ralink,function = "refclk";
        }; */
    };

/*    wm8960_mclk_pins: wm8960_mclk {
    }; */
};

&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>;
};

&gdma {
        status = "okay";
};
...

Startup logs:

[   14.192663] i2c /dev entries driver
[   14.202766] gdma-rt2880 10002800.gdma: revision: 3, channels: 16
[   14.298431] i2c-mt7621 10000900.i2c: clock 100KHz, re-start not support
[   14.337208] ralink-i2s 10000a00.i2s: mclk 480MHz
[   14.410908] asoc-simple-card sound: wm8960-hifi <-> 10000a00.i2s mapping ok

Some more data:

# cat /sys/kernel/debug/pinctrl/pinctrl/pinmux-pins
pin 0 (io0): 10000a00.i2s (GPIO UNCLAIMED) function i2s group i2s
pin 1 (io1): 10000a00.i2s (GPIO UNCLAIMED) function i2s group i2s
pin 2 (io2): 10000a00.i2s (GPIO UNCLAIMED) function i2s group i2s
pin 3 (io3): 10000a00.i2s (GPIO UNCLAIMED) function i2s group i2s
pin 4 (io4): 10000900.i2c (GPIO UNCLAIMED) function i2c group i2c
pin 5 (io5): 10000900.i2c (GPIO UNCLAIMED) function i2c group i2c
...

# aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: Audio [I2S Audio], device 0: ralink-i2s-wm8960-hifi wm8960-hifi-0 [ralink-i2s-wm8960-hifi wm8960-hifi-0]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

 aplay -f cd -r 48000 -v /dev/urandom
Playing raw data '/dev/urandom' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo
Plug PCM: Hardware PCM card 0 'I2S Audio' device 0 subdevice 0
Its setup is:
  stream       : PLAYBACK
  access       : RW_INTERLEAVED
  format       : S16_LE
  subformat    : STD
  channels     : 2
  rate         : 48000
  exact rate   : 48000 (48000/1)
  msbits       : 16
  buffer_size  : 24576
  period_size  : 2048
  period_time  : 42666
  tstamp_mode  : NONE
  tstamp_type  : MONOTONIC
  period_step  : 1
  avail_min    : 2048
  period_event : 0
  start_threshold  : 24576
  stop_threshold   : 24576
  silence_threshold: 0
  silence_size : 0
  boundary     : 1610612736
  appl_ptr     : 0
  hw_ptr       : 0
aplay: pcm_write

After "aplay: pcm_write" there is some time and watchdog restarts system.

What more can I check? Is it something with pincontrol, dma or ralink-i2s driver? I can only confirm, that this same module is working with this codec on other firmware, but it's from chinese vendor and I don't have sources.

Check /boot for some devicetree/hardware mask. I2S should be mapped to particular pins, but if you've got kernel panic, it could be wrongly mapped. Also try to disable hardware watchdog if there's an option. Listen dmesg -hKw through UART while tinkering, so when you've got another kernel panic, log is still readable.

One update - freeze was caused by using /dev/urandom and it couldn't supply data fast enough. When I've tried with aplay in background and dmesg in foreground, I got lots of info about underruns from aplay, but no dmesg messages. When I tried to play some random file, no info about underruns, nothing hanged, but also nothing in dmesg. Pins are mapped right, I've cross-checked again with module pinout.

Looks like old standard codec didn't work. I had to download "MT76x8 WM8960 ALSA SoC machine driver", from https://github.com/redchenjs/mt762x-wm8960 from branch linux-4.9, setup dts according to example, and now both i2c and i2s work, aplay works properly. I still don't hear anything but now this is only this board issue. Thanks @token0 for help.

1 Like

Also, if anyone has problems with clock - apparently with mt7628 you can put refclk on pin 37 (WDT_RST_N /I2S_MCLK / GPIO#38/O, IPU) or on pin 11 (gpio0, POWER_ON# / GPIO#11/IPD). You can configure standard refclk as gpio with:

                refclk {
                        ralink,group = "refclk";
                        ralink,function = "gpio";
                };

But you SHOULD be able to configure gpio0 as refclk with:

                refclk2 {
                        ralink,group = "gpio";
                        ralink,function = "refclk";
                };

This is according to source file group definitions, but I have no idea why this does not work. Putting those two definitions in dts results with refclk pin configured correctly, but gpio is left as is. Could anyone explain why second snipped doesn't work? When I write directly to gpio configuration register, everything works. I think I've wrote second snippet incorrectly, but have no idea what is wrong.

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.