mirror of
https://github.com/Rockbox/rockbox.git
synced 2026-10-10 08:03:04 -04:00
rk27xx: don't reprogram the codec PLL for an unchanged rate
Every start of recording applies the sample rate again, mostly unchanged, and set_codec_freq() reprogrammed the codec PLL each time. That glitches MCLK and every I2S clock made of it, right before the recording receiver is reset and starts on them. Whether it then kept its framing came down to code timing: on the Samsung YP-CP3 the recording screen's peak meter showed one channel empty and the other saturated on some visits, and builds with debug code added never did. The PLL is now left alone when it already runs the rate asked for. On a real change the lock bit, which may still show the old lock at first, is polled only after the 0.3 ms the datasheet gives for locking, with a timeout of at least a full tick, and the clocks get 1 ms more to settle before anything starts on them. Tested on a YP-CP3, together with the codec as I2S master: the peak meter on every one of many visits to the recording screen, with the microphone and FM, and at 22 kHz. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Change-Id: I2267e17c5bc7d8044715e762dbb6b92f45af4dcc
This commit is contained in:
parent
59f15ca630
commit
ce968e7da1
1 changed files with 16 additions and 2 deletions
|
|
@ -207,8 +207,17 @@ static void i2s_init(void)
|
|||
*/
|
||||
static void set_codec_freq(unsigned int freq)
|
||||
{
|
||||
static unsigned int cur_freq = HW_NUM_FREQ; /* none yet */
|
||||
long timeout;
|
||||
|
||||
/* Reprogramming the PLL glitches MCLK, and with it every clock the
|
||||
* codec makes of it: an I2S side started on them can lose its framing.
|
||||
* The rate is applied again on every start of recording, mostly
|
||||
* unchanged. */
|
||||
if (freq == cur_freq)
|
||||
return;
|
||||
cur_freq = freq;
|
||||
|
||||
/* {CLKR, CLKF, CLKOD, CODECPLL_DIV} */
|
||||
static const unsigned int pcm_freq_params[HW_NUM_FREQ][4] =
|
||||
{
|
||||
|
|
@ -237,13 +246,18 @@ static void set_codec_freq(unsigned int freq)
|
|||
(pcm_freq_params[freq][2]<<1) ; /* CLKOD factor */
|
||||
|
||||
/* wait for CODEC PLL lock with 10 ms timeout
|
||||
* datasheet states that pll lock should take approx. 0.3 ms
|
||||
* datasheet states that pll lock should take approx. 0.3 ms; the lock bit
|
||||
* may still show the old lock at first
|
||||
*/
|
||||
timeout = current_tick + (HZ/100);
|
||||
udelay(300);
|
||||
timeout = current_tick + (HZ/100) + 1;
|
||||
while (!(SCU_STATUS & (1<<2)))
|
||||
if (TIME_AFTER(current_tick, timeout))
|
||||
break;
|
||||
|
||||
/* let the codec's clocks settle before an I2S side starts on them */
|
||||
udelay(1000);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue