YP-CP3: make the WM8750 the I2S master

The WM8750 frames its ADC on ADCLRC and its DAC on DACLRC. As the I2S
slave both are inputs, and the rk27xx has a single LRCK, which on the
YP-CP3 evidently does not reach ADCLRC: with the rk27xx as the master,
the recording DMA got exact zeros on most visits to the recording
screen and real samples only by chance, sometimes changing partway
through a visit. That stays so with the codec PLL no longer glitching
the I2S clocks (previous commit); with the codec as the master it does
not happen.

The codec now drives BCLK and both LRCKs itself, and the rk27xx I2S
transmitter and receiver are slaves. The codec's MCLK still comes from
the rk27xx codec PLL at 256 fs, so sample rates stay exact. The
original firmware runs the codec as master too, but off a fixed 12 MHz
in USB mode.

RK27XX_I2S_MCLK says the rk27xx makes the codec's MCLK, apart from
CODEC_SLAVE, which also makes it the I2S master. The YP-CP3 drops
CODEC_SLAVE for RK27XX_I2S_MCLK, and the WM8750 driver sets its master
bit as it does for any codec that is not a slave.

Tested on a YP-CP3: playback, FM radio, the recording screen's peak
meter on every visit, recording from the microphone and from FM.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: I0dc93d3b2c45fddf61649702a931d11806e78cbf
This commit is contained in:
Marcin Bukat 2026-10-05 22:30:01 +02:00
parent ce968e7da1
commit 361913fdd2
2 changed files with 11 additions and 8 deletions

View file

@ -94,13 +94,15 @@
#define CONFIG_LCD LCD_SPFD5420A #define CONFIG_LCD LCD_SPFD5420A
/* Wolfson WM8750 on I2C, headphones on its OUT2. The codec is the I2S /* Wolfson WM8750 on I2C, headphones on its OUT2. The codec is the I2S
* slave: the rk27xx drives the bus and clocks the codec from its codec PLL * master, driving BCLK and both of its LRCKs: as a slave it frames the ADC
* at 256 fs for every rate (pcm-rk27xx.c), so the codec's CLOCKING register * on its ADCLRC input, which the rk27xx's one LRCK does not reach, and
* is its normal-mode 256 fs setting throughout. The original firmware runs * records zeros. Its MCLK comes from the rk27xx's codec PLL at 256 fs for
* the codec as master off a fixed 12 MHz instead, in USB mode, which puts * every rate (pcm-rk27xx.c), so the codec's CLOCKING register is its
* normal-mode 256 fs setting throughout. The original firmware runs the
* codec as master off a fixed 12 MHz instead, in USB mode, which puts
* 44.1 kHz at 44.118. */ * 44.1 kHz at 44.118. */
#define HAVE_WM8750 #define HAVE_WM8750
#define CODEC_SLAVE #define RK27XX_I2S_MCLK
#define CODEC_SRCTRL_11025HZ 0 #define CODEC_SRCTRL_11025HZ 0
#define CODEC_SRCTRL_22050HZ 0 #define CODEC_SRCTRL_22050HZ 0
#define CODEC_SRCTRL_44100HZ 0 #define CODEC_SRCTRL_44100HZ 0

View file

@ -196,8 +196,9 @@ static void i2s_init(void)
#endif #endif
} }
#ifdef CODEC_SLAVE #if defined(CODEC_SLAVE) || defined(RK27XX_I2S_MCLK)
/* When codec is slave we need to setup i2s MCLK clock using codec pll. /* When codec is slave, or master off our MCLK (RK27XX_I2S_MCLK), we need
* to setup i2s MCLK clock using codec pll.
* The MCLK frequency is 256*codec frequency as i2s setup is: * The MCLK frequency is 256*codec frequency as i2s setup is:
* LRCK/SCLK = 64 and MCLK/SCLK = 4 (see i2s_init() for reference) * LRCK/SCLK = 64 and MCLK/SCLK = 4 (see i2s_init() for reference)
* *
@ -278,7 +279,7 @@ static void sink_dma_init(void)
static void sink_set_freq(uint16_t freq) static void sink_set_freq(uint16_t freq)
{ {
#ifdef CODEC_SLAVE #if defined(CODEC_SLAVE) || defined(RK27XX_I2S_MCLK)
set_codec_freq(freq); set_codec_freq(freq);
#endif #endif