Hey guys, I have a Medion MD-86097 / E89030 WLAN USB Remote Hub, which has some limitations on stock firmware and therefore lay around over a long time. The SoC is supported by OpenWrt and it was easy to compile a firmware that boots up and if it is flashed, settings are stored. Ethernet, wireless, LEDs, Buttons and the onboard USB hub are working. Now I would like to configure OpenWrt to initialize the audio chip, so that it is recognized by alsa as a soundcard and could be used by any player app (e.g. for webradio) or services like mtd.

First some specs:

  • Ralink RT3052F MIPS SoC @384 MHz

  • 32 MB SDRAM (2x winbond W9812G6IH)

  • 4 MB CMOS Flash via SPI (Macronix MX25L3205D)

  • 802.11n WLAN 2.4 GHz (SoC)

  • 1x 10/100 Ethernet (SoC)

  • 4x USB 2.0 (Genesys Logic GL852)

  • 1x Audio out (3.5 mm Stereo jack) (Realtek ALC5621, I2S Audio codec)

  • Serial Console: Yes - 57600 8N1 (connector J2: 3.3V / RX / GND / TX )

  • JTAG: No

Well I'm somewhat stuck with the audio chip of that device. The codec chip uses i2s for the sound and i2c for control commands. So I enabled I2C and I2S via dts file and defined a simple-audio-card with the alc5621, which is in the kernel drivers. On boot console it says:

[   11.048678] i2c-ralink 10000900.i2c: clock 100KHz, re-start not support
[   11.084344] ralink-i2s 10000a00.i2s: mclk 128KHz
[   11.099784] alc562x-codec 0-001a: failed to read vendor ID1: -6

With this, I'm not surprised that alsa says "no soundcards found".

I also tried i2cdetect, which responds at nearly every address:

root@OpenWrt:/# i2cdetect 0
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-0.
I will probe address range 0x03-0x77.
Continue? [Y/n] y
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 
10: 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 
20: 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 
30: -- -- -- -- -- -- -- -- 38 39 3a 3b 3c 3d 3e 3f 
40: 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 
70: 70 71 72 73 74 75 76 77 

It could mean that the i2c bus is pulled low, so I'm quite sure that the alc5621 does not respond to anything yet. The solution is most probably the MCLK pin, the codec chip needs a master clock input. On stock firmware I can measure about 1.7V on that pin, so there seems to be a signal (I don't have a scope) - with my OpenWrt firmware it is at 0V. On stock firmware, when I connect to the sound port with that windows tool they provide for that, I have these lines on console:

=====> RALINK_SYSCTL_BASE+0x30 = 0x00042880
=====> PCM_PCMCFG = 0x43000000
enable_pcm_clk: enabled
i2s_open succeeds
audio_thread started...

I found in the RT3050/52 Datasheet that the first line would configure "Clock Configuration Register 1" (base: 0x1000.0000, offset: 0x30) to the following values:

  • Bit 30 "PBUS_DIV2" = 0 : Pbus clock is running at the same frequency as System clock

  • Bit 18 "OTG_CLK_EN" = 1 : USB OTG clock is enabled

  • Bit 15 "I2S_CLK_EN" = 0 : I2S clock is gated

  • Bit 14 "I2S_CLK_SEL" = 0 : internal 15.625Mhz reference clock

  • Bits 13:8 "I2S_CLK_DIV" = 0b101000 = 40 : I2S clock divider will divide the reference clock by (I2S_CLK_DIV+1)

  • Bit 7 "PCM_CLK_EN" = 1 : PCM clock is enabled

  • Bit 6 "PCM_CLK_SEL" = 0 : internal 15.625Mhz reference clock

  • Bits 5:0 "PCM_CLK_DIV" = 0 : The PCM clock divider will divide the reference clock by (PCM_CLK_DIV+1)

(I2S is probably enabled later?)
The second line would configure PCM_CFG register (base: 0x1000.0400, offset: 0x04) like this:

  • Bit 31 "EXT_CLK_EN" = 0 : PCM_CLK is generated by internal clock divider

  • Bit 30 "CLKOUT_EN" = 1 : Enable the PCM_CLK_OUT to be free run

  • Bit 27 "EXT_FSYNC" = 0 : FSYNC is generated by internal circuit

  • Bit 26 "LONG_FSYNC" = 0 : FSYNC mode is short FSYNC

  • Bit 25 "FSYNC_POL" = 1 : Polarity of FSYNC is high active

  • Bit 24 "DRX_TRI" = 1 : Tristate the DRX as fall edge as LSB bit

  • Bits 2:0 "SLOT_MODE" = 0 : 4 slots each PCM frame, PCM clock out/in should be 256KHz

So my guess is that the codec's MCLK pin is connected to the RT3052's PCMCLK pin, and I would have to use UARTF_SHARE_MODE = PCM, I2S. I did not find anything like "ralink,rt3050-pcm" that I could add to the dts/dtsi files, so how would I setup and enable the PCM clock? Should I really write directly to those registers, like the stock firmware seems to do? What is the command for that and where would I place a device specific startup/configuration script in OpenWrt (that most probably needs to be executed before loading alc562x-codec)?

I hope you can give me a hint or example for that.
Thanks,
rumpelzwo