Liam Girdwood | eb1a6af | 2006-10-06 18:34:51 +0200 | [diff] [blame^] | 1 | Audio Clocking |
| 2 | ============== |
| 3 | |
| 4 | This text describes the audio clocking terms in ASoC and digital audio in |
| 5 | general. Note: Audio clocking can be complex ! |
| 6 | |
| 7 | |
| 8 | Master Clock |
| 9 | ------------ |
| 10 | |
| 11 | Every audio subsystem is driven by a master clock (sometimes refered to as MCLK |
| 12 | or SYSCLK). This audio master clock can be derived from a number of sources |
| 13 | (e.g. crystal, PLL, CPU clock) and is responsible for producing the correct |
| 14 | audio playback and capture sample rates. |
| 15 | |
| 16 | Some master clocks (e.g. PLL's and CPU based clocks) are configuarble in that |
| 17 | their speed can be altered by software (depending on the system use and to save |
| 18 | power). Other master clocks are fixed at at set frequency (i.e. crystals). |
| 19 | |
| 20 | |
| 21 | DAI Clocks |
| 22 | ---------- |
| 23 | The Digital Audio Interface is usually driven by a Bit Clock (often referred to |
| 24 | as BCLK). This clock is used to drive the digital audio data across the link |
| 25 | between the codec and CPU. |
| 26 | |
| 27 | The DAI also has a frame clock to signal the start of each audio frame. This |
| 28 | clock is sometimes referred to as LRC (left right clock) or FRAME. This clock |
| 29 | runs at exactly the sample rate. |
| 30 | |
| 31 | Bit Clock is usually always a ratio of MCLK or a multiple of LRC. i.e. |
| 32 | |
| 33 | BCLK = MCLK / x |
| 34 | |
| 35 | or |
| 36 | |
| 37 | BCLK = LRC * x |
| 38 | |
| 39 | This relationship depends on the codec or SoC CPU in particular. ASoC can quite |
| 40 | easily match a codec that generates BCLK by division (FSBD) with a CPU that |
| 41 | generates BCLK by multiplication (FSB). |
| 42 | |
| 43 | |
| 44 | ASoC Clocking |
| 45 | ------------- |
| 46 | |
| 47 | The ASoC core determines the clocking for each particular configuration at |
| 48 | runtime. This is to allow for dynamic audio clocking wereby the audio clock is |
| 49 | variable and depends on the system state or device usage scenario. i.e. a voice |
| 50 | call requires slower clocks (and hence less power) than MP3 playback. |
| 51 | |
| 52 | ASoC will call the config_sysclock() function for the target machine during the |
| 53 | audio parameters configuration. The function is responsible for then clocking |
| 54 | the machine audio subsytem and returning the audio clock speed to the core. |
| 55 | This function should also call the codec and cpu DAI clock_config() functions |
| 56 | to configure their respective internal clocking if required. |
| 57 | |
| 58 | |
| 59 | ASoC Clocking Control Flow |
| 60 | -------------------------- |
| 61 | |
| 62 | The ASoC core will call the machine drivers config_sysclock() when most of the |
| 63 | DAI capabilities are known. The machine driver is then responsible for calling |
| 64 | the codec and/or CPU DAI drivers with the selected capabilities and the current |
| 65 | MCLK. Note that the machine driver is also resonsible for setting the MCLK (and |
| 66 | enabling it). |
| 67 | |
| 68 | (1) Match Codec and CPU DAI capabilities. At this point we have |
| 69 | matched the majority of the DAI fields and now need to make sure this |
| 70 | mode is currently clockable. |
| 71 | |
| 72 | (2) machine->config_sysclk() is now called with the matched DAI FS, sample |
| 73 | rate and BCLK master. This function then gets/sets the current audio |
| 74 | clock (depening on usage) and calls the codec and CPUI DAI drivers with |
| 75 | the FS, rate, BCLK master and MCLK. |
| 76 | |
| 77 | (3) Codec/CPU DAI config_sysclock(). This function checks that the FS, rate, |
| 78 | BCLK master and MCLK are acceptable for the codec or CPU DAI. It also |
| 79 | sets the DAI internal state to work with said clocks. |
| 80 | |
| 81 | The config_sysclk() functions for CPU, codec and machine should return the MCLK |
| 82 | on success and 0 on failure. |
| 83 | |
| 84 | |
| 85 | Examples (b = BCLK, l = LRC) |
| 86 | ============================ |
| 87 | |
| 88 | Example 1 |
| 89 | --------- |
| 90 | |
| 91 | Simple codec that only runs at 48k @ 256FS in master mode. |
| 92 | |
| 93 | CPU only runs as slave DAI, however it generates a variable MCLK. |
| 94 | |
| 95 | -------- --------- |
| 96 | | | <----mclk--- | | |
| 97 | | Codec |b -----------> | CPU | |
| 98 | | |l -----------> | | |
| 99 | | | | | |
| 100 | -------- --------- |
| 101 | |
| 102 | The codec driver has the following config_sysclock() |
| 103 | |
| 104 | static unsigned int config_sysclk(struct snd_soc_codec_dai *dai, |
| 105 | struct snd_soc_clock_info *info, unsigned int clk) |
| 106 | { |
| 107 | /* make sure clock is 256 * rate */ |
| 108 | if(info->rate << 8 == clk) { |
| 109 | dai->mclk = clk; |
| 110 | return clk; |
| 111 | } |
| 112 | |
| 113 | return 0; |
| 114 | } |
| 115 | |
| 116 | The CPU I2S DAI driver has the following config_sysclk() |
| 117 | |
| 118 | static unsigned int config_sysclk(struct snd_soc_codec_dai *dai, |
| 119 | struct snd_soc_clock_info *info, unsigned int clk) |
| 120 | { |
| 121 | /* can we support this clk */ |
| 122 | if(set_audio_clk(clk) < 0) |
| 123 | return -EINVAL; |
| 124 | |
| 125 | dai->mclk = clk; |
| 126 | return dai->clk; |
| 127 | } |
| 128 | |
| 129 | The machine driver config_sysclk() in this example is as follows:- |
| 130 | |
| 131 | unsigned int machine_config_sysclk(struct snd_soc_pcm_runtime *rtd, |
| 132 | struct snd_soc_clock_info *info) |
| 133 | { |
| 134 | int clk = info->rate * info->fs; |
| 135 | |
| 136 | /* check that CPU can deliver clock */ |
| 137 | if(rtd->cpu_dai->config_sysclk(rtd->cpu_dai, info, clk) < 0) |
| 138 | return -EINVAL; |
| 139 | |
| 140 | /* can codec work with this clock */ |
| 141 | return rtd->codec_dai->config_sysclk(rtd->codec_dai, info, clk); |
| 142 | } |
| 143 | |
| 144 | |
| 145 | Example 2 |
| 146 | --------- |
| 147 | |
| 148 | Codec that can master at 8k and 48k at various FS (and hence supports a fixed |
| 149 | set of input MCLK's) and can also be slave at various FS . |
| 150 | |
| 151 | The CPU can master at 8k and 48k @256 FS and can be slave at any FS. |
| 152 | |
| 153 | MCLK is a 12.288MHz crystal on this machine. |
| 154 | |
| 155 | -------- --------- |
| 156 | | | <---xtal---> | | |
| 157 | | Codec |b <----------> | CPU | |
| 158 | | |l <----------> | | |
| 159 | | | | | |
| 160 | -------- --------- |
| 161 | |
| 162 | |
| 163 | The codec driver has the following config_sysclock() |
| 164 | |
| 165 | /* supported input clocks */ |
| 166 | const static int hifi_clks[] = {11289600, 12000000, 12288000, |
| 167 | 16934400, 18432000}; |
| 168 | |
| 169 | static unsigned int config_hsysclk(struct snd_soc_codec_dai *dai, |
| 170 | struct snd_soc_clock_info *info, unsigned int clk) |
| 171 | { |
| 172 | int i; |
| 173 | |
| 174 | /* is clk supported */ |
| 175 | for(i = 0; i < ARRAY_SIZE(hifi_clks); i++) { |
| 176 | if(clk == hifi_clks[i]) { |
| 177 | dai->mclk = clk; |
| 178 | return clk; |
| 179 | } |
| 180 | } |
| 181 | |
| 182 | /* this clk is not supported */ |
| 183 | return 0; |
| 184 | } |
| 185 | |
| 186 | The CPU I2S DAI driver has the following config_sysclk() |
| 187 | |
| 188 | static unsigned int config_sysclk(struct snd_soc_codec_dai *dai, |
| 189 | struct snd_soc_clock_info *info, unsigned int clk) |
| 190 | { |
| 191 | /* are we master or slave */ |
| 192 | if (info->bclk_master & |
| 193 | (SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_CBM_CFS)) { |
| 194 | |
| 195 | /* we can only master @ 256FS */ |
| 196 | if(info->rate << 8 == clk) { |
| 197 | dai->mclk = clk; |
| 198 | return dai->mclk; |
| 199 | } |
| 200 | } else { |
| 201 | /* slave we can run at any FS */ |
| 202 | dai->mclk = clk; |
| 203 | return dai->mclk; |
| 204 | } |
| 205 | |
| 206 | /* not supported */ |
| 207 | return dai->clk; |
| 208 | } |
| 209 | |
| 210 | The machine driver config_sysclk() in this example is as follows:- |
| 211 | |
| 212 | unsigned int machine_config_sysclk(struct snd_soc_pcm_runtime *rtd, |
| 213 | struct snd_soc_clock_info *info) |
| 214 | { |
| 215 | int clk = 12288000; /* 12.288MHz */ |
| 216 | |
| 217 | /* who's driving the link */ |
| 218 | if (info->bclk_master & |
| 219 | (SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_CBM_CFS)) { |
| 220 | /* codec master */ |
| 221 | |
| 222 | /* check that CPU can work with clock */ |
| 223 | if(rtd->cpu_dai->config_sysclk(rtd->cpu_dai, info, clk) < 0) |
| 224 | return -EINVAL; |
| 225 | |
| 226 | /* can codec work with this clock */ |
| 227 | return rtd->codec_dai->config_sysclk(rtd->codec_dai, info, clk); |
| 228 | } else { |
| 229 | /* cpu master */ |
| 230 | |
| 231 | /* check that codec can work with clock */ |
| 232 | if(rtd->codec_dai->config_sysclk(rtd->codec_dai, info, clk) < 0) |
| 233 | return -EINVAL; |
| 234 | |
| 235 | /* can CPU work with this clock */ |
| 236 | return rtd->cpu_dai->config_sysclk(rtd->cpu_dai, info, clk); |
| 237 | } |
| 238 | } |
| 239 | |
| 240 | |
| 241 | |
| 242 | Example 3 |
| 243 | --------- |
| 244 | |
| 245 | Codec that masters at 8k ... 48k @256 FS. Codec can also be slave and |
| 246 | doesn't care about FS. The codec has an internal PLL and dividers to generate |
| 247 | the necessary internal clocks (for 256FS). |
| 248 | |
| 249 | CPU can only be slave and doesn't care about FS. |
| 250 | |
| 251 | MCLK is a non controllable 13MHz clock from the CPU. |
| 252 | |
| 253 | |
| 254 | -------- --------- |
| 255 | | | <----mclk--- | | |
| 256 | | Codec |b <----------> | CPU | |
| 257 | | |l <----------> | | |
| 258 | | | | | |
| 259 | -------- --------- |
| 260 | |
| 261 | The codec driver has the following config_sysclock() |
| 262 | |
| 263 | /* valid PCM clock dividers * 2 */ |
| 264 | static int pcm_divs[] = {2, 6, 11, 4, 8, 12, 16}; |
| 265 | |
| 266 | static unsigned int config_vsysclk(struct snd_soc_codec_dai *dai, |
| 267 | struct snd_soc_clock_info *info, unsigned int clk) |
| 268 | { |
| 269 | int i, j, best_clk = info->fs * info->rate; |
| 270 | |
| 271 | /* can we run at this clk without the PLL ? */ |
| 272 | for (i = 0; i < ARRAY_SIZE(pcm_divs); i++) { |
| 273 | if ((best_clk >> 1) * pcm_divs[i] == clk) { |
| 274 | dai->pll_in = 0; |
| 275 | dai->clk_div = pcm_divs[i]; |
| 276 | dai->mclk = best_clk; |
| 277 | return dai->mclk; |
| 278 | } |
| 279 | } |
| 280 | |
| 281 | /* now check for PLL support */ |
| 282 | for (i = 0; i < ARRAY_SIZE(pll_div); i++) { |
| 283 | if (pll_div[i].pll_in == clk) { |
| 284 | for (j = 0; j < ARRAY_SIZE(pcm_divs); j++) { |
| 285 | if (pll_div[i].pll_out == pcm_divs[j] * (best_clk >> 1)) { |
| 286 | dai->pll_in = clk; |
| 287 | dai->pll_out = pll_div[i].pll_out; |
| 288 | dai->clk_div = pcm_divs[j]; |
| 289 | dai->mclk = best_clk; |
| 290 | return dai->mclk; |
| 291 | } |
| 292 | } |
| 293 | } |
| 294 | } |
| 295 | |
| 296 | /* this clk is not supported */ |
| 297 | return 0; |
| 298 | } |
| 299 | |
| 300 | |
| 301 | The CPU I2S DAI driver has the does not need a config_sysclk() as it can slave |
| 302 | at any FS. |
| 303 | |
| 304 | unsigned int config_sysclk(struct snd_soc_pcm_runtime *rtd, |
| 305 | struct snd_soc_clock_info *info) |
| 306 | { |
| 307 | /* codec has pll that generates mclk from 13MHz xtal */ |
| 308 | return rtd->codec_dai->config_sysclk(rtd->codec_dai, info, 13000000); |
| 309 | } |