Subject: Re: new sound driver

From: Johannes Berg <[email-masked]>
Date: Thu, 23 Mar 2006 18:00:31 +0100

Obviously, I'm still collecting information. For future reference and
archiving, here's the contents of a file I just added to my code
describing how apple derives i2s clocks. Well, as far as I can see from
their code. 

Short description of the i2s clock derivation system Apple uses.

The i2s chip Apple uses has three available clocks: 18432000, 45158400 and
49152000 Hz. These are used to drive the codec's system clock as well as the
i2s transfer bus.

The clocks for these are derived as follows:
First, you need to know the sampling frequency you want to use, and the
system clock the codec requires. The pcm3052 (onyx) for example requires a
system clock of 256*sampling frequency.

Thus, you divide the clock source speed by the sampling frequency and then
the factor the codec chip requires. This is the 'mclk divisor'.
Now you can derive the system clock from the clock source by taking only
every 'mclk divisor' transition of the clock, and thus you get a system
clock of the required speed.

Next, you need to know the i2s bus speed wrt. the sampling frequency. For
Sony and I2S 32x serial formats, this is 32*sampling frequency, for the I2S
64x format it is 64*sampling frequency. Since the i2s wire clock is derived
from the system clock we have already derived from the clock source, you
need to put as 'sclk divisor' the factor between the system clock of the
codec and the bus clock, for example 256/32 (=8) if the codec is driven in
Sony mode.

For the 'sclk divisor' you have to take care that it is an even number or 1
or 3, other values cannot be represented to the i2s chip (see logic in
i2sbus.h).

With a codec system clock (MClk) of 256*sampling frequency, you can have the
following frequencies (in the range from 8KHz to 96KHz) depending on the
clock source you use:
18432000: 9000 12000 14400 18000 24000 36000 72000
45158400: 8820 9800 11025 12600 14700 17640 22050 29400 35280 44100 58800 88200
49152000: 8000 9600 12000 16000 19200 24000 32000 38400 48000 64000 96000
(this is exactly what we can do with the onyx chip)

to create this table use calc (debian package apcalc):
min=8000
max=96000
clock=49152000
factor=256
for (f=min;f<=max;f++) {
  if ((clock%f==0) && ((clock/f)%factor == 0)) {
    div = clock/f/factor ;
    n = ceil(div/2-1) ;
    if ((div==1||div==3||div==5||div==14||(2*(n+1)==div && n<0x1f))
       && (1))
      print f,
  }
}
print ''