From eb1a6af39b70375d93ed25e7c916f64463e00614 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Fri, 6 Oct 2006 18:34:51 +0200 Subject: [ALSA] ASoC: documentation & maintainer This patch adds documentation describing the ASoC architecture and a maintainer entry for ASoC. The documentation includes the following files:- codec.txt: Codec driver internals. DAI.txt: Description of Digital Audio Interface standards and how to configure a DAI within your codec and CPU DAI drivers. dapm.txt: Dynamic Audio Power Management. platform.txt: Platform audio DMA and DAI. machine.txt: Machine driver internals. pop_clicks.txt: How to minimise audio artifacts. clocking.txt: ASoC clocking for best power performance. Signed-off-by: Liam Girdwood Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- Documentation/sound/alsa/soc/DAI.txt | 380 +++++++++++++++++++++++++++++++++++ 1 file changed, 380 insertions(+) create mode 100644 Documentation/sound/alsa/soc/DAI.txt (limited to 'Documentation/sound/alsa/soc/DAI.txt') diff --git a/Documentation/sound/alsa/soc/DAI.txt b/Documentation/sound/alsa/soc/DAI.txt new file mode 100644 index 00000000000..919de76bab8 --- /dev/null +++ b/Documentation/sound/alsa/soc/DAI.txt @@ -0,0 +1,380 @@ +ASoC currently supports the three main Digital Audio Interfaces (DAI) found on +SoC controllers and portable audio CODECS today, namely AC97, I2S and PCM. + + +AC97 +==== + + AC97 is a five wire interface commonly found on many PC sound cards. It is +now also popular in many portable devices. This DAI has a reset line and time +multiplexes its data on its SDATA_OUT (playback) and SDATA_IN (capture) lines. +The bit clock (BCLK) is always driven by the CODEC (usually 12.288MHz) and the +frame (FRAME) (usually 48kHz) is always driven by the controller. Each AC97 +frame is 21uS long and is divided into 13 time slots. + +The AC97 specification can be found at http://intel.com/ + + +I2S +=== + + I2S is a common 4 wire DAI used in HiFi, STB and portable devices. The Tx and +Rx lines are used for audio transmision, whilst the bit clock (BCLK) and +left/right clock (LRC) synchronise the link. I2S is flexible in that either the +controller or CODEC can drive (master) the BCLK and LRC clock lines. Bit clock +usually varies depending on the sample rate and the master system clock +(SYSCLK). LRCLK is the same as the sample rate. A few devices support separate +ADC and DAC LRCLK's, this allows for similtanious capture and playback at +different sample rates. + +I2S has several different operating modes:- + + o I2S - MSB is transmitted on the falling edge of the first BCLK after LRC + transition. + + o Left Justified - MSB is transmitted on transition of LRC. + + o Right Justified - MSB is transmitted sample size BCLK's before LRC + transition. + +PCM +=== + +PCM is another 4 wire interface, very similar to I2S, that can support a more +flexible protocol. It has bit clock (BCLK) and sync (SYNC) lines that are used +to synchronise the link whilst the Tx and Rx lines are used to transmit and +receive the audio data. Bit clock usually varies depending on sample rate +whilst sync runs at the sample rate. PCM also supports Time Division +Multiplexing (TDM) in that several devices can use the bus similtaniuosly (This +is sometimes referred to as network mode). + +Common PCM operating modes:- + + o Mode A - MSB is transmitted on falling edge of first BCLK after FRAME/SYNC. + + o Mode B - MSB is transmitted on rising edge of FRAME/SYNC. + + +ASoC DAI Configuration +====================== + +Every CODEC DAI and SoC DAI must have their capabilities defined in order to +be configured together at runtime when the audio and clocking parameters are +known. This is achieved by creating an array of struct snd_soc_hw_mode in the +the CODEC and SoC interface drivers. Each element in the array describes a DAI +mode and each mode is usually based upon the DAI system clock to sample rate +ratio (FS). + +i.e. 48k sample rate @ 256 FS = sytem clock of 12.288 MHz + 48000 * 256 = 12288000 + +The CPU and Codec DAI modes are then ANDed together at runtime to determine the +rutime DAI configuration for both the Codec and CPU. + +When creating a new codec or SoC DAI it's probably best to start of with a few +sample rates first and then test your interface. + +struct snd_soc_dai_mode is defined (in soc.h) as:- + +/* SoC DAI mode */ +struct snd_soc_hw_mode { + unsigned int fmt:16; /* SND_SOC_DAIFMT_* */ + unsigned int tdm:16; /* SND_SOC_DAITDM_* */ + unsigned int pcmfmt:6; /* SNDRV_PCM_FORMAT_* */ + unsigned int pcmrate:16; /* SND_SOC_DAIRATE_* */ + unsigned int pcmdir:2; /* SND_SOC_DAIDIR_* */ + unsigned int flags:8; /* hw flags */ + unsigned int fs:32; /* mclk to rate dividers */ + unsigned int bfs:16; /* mclk to bclk dividers */ + unsigned long priv; /* private mode data */ +}; + +fmt: +---- +This field defines the DAI mode hardware format (e.g. I2S settings) and +supports the following settings:- + + 1) hardware DAI formats + +#define SND_SOC_DAIFMT_I2S (1 << 0) /* I2S mode */ +#define SND_SOC_DAIFMT_RIGHT_J (1 << 1) /* Right justified mode */ +#define SND_SOC_DAIFMT_LEFT_J (1 << 2) /* Left Justified mode */ +#define SND_SOC_DAIFMT_DSP_A (1 << 3) /* L data msb after FRM */ +#define SND_SOC_DAIFMT_DSP_B (1 << 4) /* L data msb during FRM */ +#define SND_SOC_DAIFMT_AC97 (1 << 5) /* AC97 */ + + 2) hw DAI signal inversions + +#define SND_SOC_DAIFMT_NB_NF (1 << 8) /* normal bit clock + frame */ +#define SND_SOC_DAIFMT_NB_IF (1 << 9) /* normal bclk + inv frm */ +#define SND_SOC_DAIFMT_IB_NF (1 << 10) /* invert bclk + nor frm */ +#define SND_SOC_DAIFMT_IB_IF (1 << 11) /* invert bclk + frm */ + + 3) hw clock masters + This is wrt the codec, the inverse is true for the interface + i.e. if the codec is clk and frm master then the interface is + clk and frame slave. + +#define SND_SOC_DAIFMT_CBM_CFM (1 << 12) /* codec clk & frm master */ +#define SND_SOC_DAIFMT_CBS_CFM (1 << 13) /* codec clk slave & frm master */ +#define SND_SOC_DAIFMT_CBM_CFS (1 << 14) /* codec clk master & frame slave */ +#define SND_SOC_DAIFMT_CBS_CFS (1 << 15) /* codec clk & frm slave */ + +At least one option from each section must be selected. Multiple selections are +also supported e.g. + + .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_RIGHT_J | \ + SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_NB_IF | SND_SOC_DAIFMT_IB_NF | \ + SND_SOC_DAIFMT_IB_IF + + +tdm: +------ +This field defines the Time Division Multiplexing left and right word +positions for the DAI mode if applicable. Set to SND_SOC_DAITDM_LRDW(0,0) for +no TDM. + + +pcmfmt: +--------- +The hardware PCM format. This describes the PCM formats supported by the DAI +mode e.g. + + .hwpcmfmt = SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S20_3LE | \ + SNDRV_PCM_FORMAT_S24_3LE + +pcmrate: +---------- +The PCM sample rates supported by the DAI mode. e.g. + + .hwpcmrate = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \ + SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 + + +pcmdir: +--------- +The stream directions supported by this mode. e.g. playback and capture + + +flags: +-------- +The DAI hardware flags supported by the mode. + +SND_SOC_DAI_BFS_DIV +This flag states that bit clock is generated by dividing MCLK in this mode, if +this flag is absent the bitclock generated by mulitiplying sample rate. + +NOTE: Bitclock division and mulitiplication modes can be safely matched by the +core logic. + + +fs: +----- +The FS supported by this DAI mode FS is the ratio between the system clock and +the sample rate. See above + +bfs: +------ +BFS is the ratio of BCLK to MCLK or the ratio of BCLK to sample rate (this +depends on the codec or CPU DAI). + +The BFS supported by the DAI mode. This can either be the ratio between the +bitclock (BCLK) and the sample rate OR the ratio between the system clock and +the sample rate. Depends on the SND_SOC_DAI_BFS_DIV flag above. + +priv: +----- +private codec mode data. + + + +Examples +======== + +Note that Codec DAI and CPU DAI examples are interchangeable in these examples +as long as the bus master is reversed. i.e. + + SND_SOC_DAIFMT_CBM_CFM would become SND_SOC_DAIFMT_CBS_CFS + and vice versa. + +This applies to all SND_SOC_DAIFMT_CB*_CF*. + +Example 1 +--------- + +Simple codec that only runs at 8k & 48k @ 256FS in master mode, can generate a +BCLK of either MCLK/2 or MCLK/4. + + /* codec master */ + {SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), + SNDRV_PCM_FORMAT_S16_LE, SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, + SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, SND_SOC_DAI_BFS_DIV, + 256, SND_SOC_FSBD(2) | SND_SOC_FSBD(4)}, + + +Example 2 +--------- +Simple codec that only runs at 8k & 48k @ 256FS in master mode, can generate a +BCLK of either Rate * 32 or Rate * 64. + + /* codec master */ + {SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), + SNDRV_PCM_FORMAT_S16_LE, SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, + SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, 0, + 256, SND_SOC_FSB(32) | SND_SOC_FSB(64)}, + + +Example 3 +--------- +Codec that only runs at 8k & 48k @ 256FS in master mode, can generate a +BCLK of either Rate * 32 or Rate * 64. Codec can also run in slave mode as long +as BCLK is rate * 32 or rate * 64. + + /* codec master */ + {SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), + SNDRV_PCM_FORMAT_S16_LE, SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, + SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, 0, + 256, SND_SOC_FSB(32) | SND_SOC_FSB(64)}, + + /* codec slave */ + {SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS, SND_SOC_DAITDM_LRDW(0,0), + SNDRV_PCM_FORMAT_S16_LE, SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, + SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, 0, + SND_SOC_FS_ALL, SND_SOC_FSB(32) | SND_SOC_FSB(64)}, + + +Example 4 +--------- +Codec that only runs at 8k, 16k, 32k, 48k, 96k @ 128FS, 192FS & 256FS in master +mode and can generate a BCLK of MCLK / (1,2,4,8,16). Codec can also run in slave +mode as and does not care about FS or BCLK (as long as there is enough bandwidth). + + #define CODEC_FSB \ + (SND_SOC_FSBD(1) | SND_SOC_FSBD(2) | SND_SOC_FSBD(4) | \ + SND_SOC_FSBD(8) | SND_SOC_FSBD(16)) + + #define CODEC_RATES \ + (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_32000 |\ + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000) + + /* codec master @ 128, 192 & 256 FS */ + {SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), + SNDRV_PCM_FORMAT_S16_LE, CODEC_RATES, + SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, SND_SOC_DAI_BFS_DIV, + 128, CODEC_FSB}, + + {SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), + SNDRV_PCM_FORMAT_S16_LE, CODEC_RATES, + SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, SND_SOC_DAI_BFS_DIV, + 192, CODEC_FSB}, + + {SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), + SNDRV_PCM_FORMAT_S16_LE, CODEC_RATES, + SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, SND_SOC_DAI_BFS_DIV, + 256, CODEC_FSB}, + + /* codec slave */ + {SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS, SND_SOC_DAITDM_LRDW(0,0), + SNDRV_PCM_FORMAT_S16_LE, CODEC_RATES, + SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, 0, + SND_SOC_FS_ALL, SND_SOC_FSB_ALL}, + + +Example 5 +--------- +Codec that only runs at 8k, 44.1k, 48k @ different FS in master mode (for use +with a fixed MCLK) and can generate a BCLK of MCLK / (1,2,4,8,16). +Codec can also run in slave mode as and does not care about FS or BCLK (as long +as there is enough bandwidth). Codec can support 16, 24 and 32 bit PCM sample +sizes. + + #define CODEC_FSB \ + (SND_SOC_FSBD(1) | SND_SOC_FSBD(2) | SND_SOC_FSBD(4) | \ + SND_SOC_FSBD(8) | SND_SOC_FSBD(16)) + + #define CODEC_PCM_FORMATS \ + (SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S20_3LE | \ + SNDRV_PCM_FORMAT_S24_3LE | SNDRV_PCM_FORMAT_S24_LE | SNDRV_PCM_FORMAT_S32_LE) + + /* codec master */ + {SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), + SNDRV_PCM_FORMAT_S16_LE, SNDRV_PCM_RATE_8000, + SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, SND_SOC_DAI_BFS_DIV, + 1536, CODEC_FSB}, + + {SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), + SNDRV_PCM_FORMAT_S16_LE, SNDRV_PCM_RATE_44100, + SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, SND_SOC_DAI_BFS_DIV, + 272, CODEC_FSB}, + + {SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), + SNDRV_PCM_FORMAT_S16_LE, SNDRV_PCM_RATE_48000, + SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, SND_SOC_DAI_BFS_DIV, + 256, CODEC_FSB}, + + /* codec slave */ + {SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS, SND_SOC_DAITDM_LRDW(0,0), + SNDRV_PCM_FORMAT_S16_LE, CODEC_RATES, + SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, 0, + SND_SOC_FS_ALL, SND_SOC_FSB_ALL}, + + +Example 6 +--------- +AC97 Codec that does not support VRA (i.e only runs at 48k). + + #define AC97_DIR \ + (SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE) + + + #define AC97_PCM_FORMATS \ + (SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S18_3LE | \ + SNDRV_PCM_FORMAT_S20_3LE) + + /* AC97 with no VRA */ + {0, 0, AC97_PCM_FORMATS, SNDRV_PCM_RATE_48000}, + + +Example 7 +--------- + +CPU DAI that supports 8k - 48k @ 256FS and BCLK = MCLK / 4 in master mode. +Slave mode (CPU DAI is FRAME master) supports 8k - 96k at any FS as long as +BCLK = 64 * rate. (Intel XScale I2S controller). + + #define PXA_I2S_DAIFMT \ + (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF) + + #define PXA_I2S_DIR \ + (SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE) + + #define PXA_I2S_RATES \ + (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \ + SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) + + /* pxa2xx I2S frame and clock master modes */ + {PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, SND_SOC_DAITDM_LRDW(0,0), SNDRV_PCM_FORMAT_S16_LE, + SNDRV_PCM_RATE_8000, PXA_I2S_DIR, SND_SOC_DAI_BFS_DIV, 256, + SND_SOC_FSBD(4), 0x48}, + {PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, SND_SOC_DAITDM_LRDW(0,0), SNDRV_PCM_FORMAT_S16_LE, + SNDRV_PCM_RATE_11025, PXA_I2S_DIR, SND_SOC_DAI_BFS_DIV, 256, + SND_SOC_FSBD(4), 0x34}, + {PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, SND_SOC_DAITDM_LRDW(0,0), SNDRV_PCM_FORMAT_S16_LE, + SNDRV_PCM_RATE_16000, PXA_I2S_DIR, SND_SOC_DAI_BFS_DIV, 256, + SND_SOC_FSBD(4), 0x24}, + {PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, SND_SOC_DAITDM_LRDW(0,0), SNDRV_PCM_FORMAT_S16_LE, + SNDRV_PCM_RATE_22050, PXA_I2S_DIR, SND_SOC_DAI_BFS_DIV, 256, + SND_SOC_FSBD(4), 0x1a}, + {PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, SND_SOC_DAITDM_LRDW(0,0), SNDRV_PCM_FORMAT_S16_LE, + SNDRV_PCM_RATE_44100, PXA_I2S_DIR, SND_SOC_DAI_BFS_DIV, 256, + SND_SOC_FSBD(4), 0xd}, + {PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, SND_SOC_DAITDM_LRDW(0,0), SNDRV_PCM_FORMAT_S16_LE, + SNDRV_PCM_RATE_48000, PXA_I2S_DIR, SND_SOC_DAI_BFS_DIV, 256, + SND_SOC_FSBD(4), 0xc}, + + /* pxa2xx I2S frame master and clock slave mode */ + {PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBM_CFS, SND_SOC_DAITDM_LRDW(0,0), SNDRV_PCM_FORMAT_S16_LE, + PXA_I2S_RATES, PXA_I2S_DIR, 0, SND_SOC_FS_ALL, SND_SOC_FSB(64)}, + -- cgit v1.2.3 From a71a468a50f1385855e28864e26251b02df829bb Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Thu, 19 Oct 2006 20:35:56 +0200 Subject: [ALSA] ASoC: Add support for BCLK based on (Rate * Chn * Word Size) This patch adds support for the DAI BCLK to be generated by multiplying Rate * Channels * Word Size (RCW). This now gives 3 options for BCLK clocking and synchronisation :- 1. BCLK = Rate * x 2. BCLK = MCLK / x 3. BCLK = Rate * Chn * Word Size. (New) Changes:- o Add support for RCW generation of BCLK o Update Documentation to include RCW. o Update DAI documentation for label = value DAI modes. o Add RCW support to wm8731, wm8750 and pxa2xx-i2s drivers. Signed-off-by: Liam Girdwood Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- Documentation/sound/alsa/soc/DAI.txt | 358 +++++++++++++++++++++++++---------- 1 file changed, 262 insertions(+), 96 deletions(-) (limited to 'Documentation/sound/alsa/soc/DAI.txt') diff --git a/Documentation/sound/alsa/soc/DAI.txt b/Documentation/sound/alsa/soc/DAI.txt index 919de76bab8..251545a8869 100644 --- a/Documentation/sound/alsa/soc/DAI.txt +++ b/Documentation/sound/alsa/soc/DAI.txt @@ -12,7 +12,8 @@ The bit clock (BCLK) is always driven by the CODEC (usually 12.288MHz) and the frame (FRAME) (usually 48kHz) is always driven by the controller. Each AC97 frame is 21uS long and is divided into 13 time slots. -The AC97 specification can be found at http://intel.com/ +The AC97 specification can be found at :- +http://www.intel.com/design/chipsets/audio/ac97_r23.pdf I2S @@ -77,16 +78,16 @@ sample rates first and then test your interface. struct snd_soc_dai_mode is defined (in soc.h) as:- /* SoC DAI mode */ -struct snd_soc_hw_mode { - unsigned int fmt:16; /* SND_SOC_DAIFMT_* */ - unsigned int tdm:16; /* SND_SOC_DAITDM_* */ - unsigned int pcmfmt:6; /* SNDRV_PCM_FORMAT_* */ - unsigned int pcmrate:16; /* SND_SOC_DAIRATE_* */ - unsigned int pcmdir:2; /* SND_SOC_DAIDIR_* */ - unsigned int flags:8; /* hw flags */ - unsigned int fs:32; /* mclk to rate dividers */ - unsigned int bfs:16; /* mclk to bclk dividers */ - unsigned long priv; /* private mode data */ +struct snd_soc_dai_mode { + u16 fmt; /* SND_SOC_DAIFMT_* */ + u16 tdm; /* SND_SOC_HWTDM_* */ + u64 pcmfmt; /* SNDRV_PCM_FMTBIT_* */ + u16 pcmrate; /* SND_SOC_HWRATE_* */ + u16 pcmdir:2; /* SND_SOC_HWDIR_* */ + u16 flags:8; /* hw flags */ + u16 fs; /* mclk to rate divider */ + u64 bfs; /* mclk to bclk dividers */ + unsigned long priv; /* private mode data */ }; fmt: @@ -140,14 +141,14 @@ pcmfmt: The hardware PCM format. This describes the PCM formats supported by the DAI mode e.g. - .hwpcmfmt = SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S20_3LE | \ + .pcmfmt = SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S20_3LE | \ SNDRV_PCM_FORMAT_S24_3LE pcmrate: ---------- The PCM sample rates supported by the DAI mode. e.g. - .hwpcmrate = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \ + .pcmrate = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \ SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 @@ -161,9 +162,14 @@ flags: -------- The DAI hardware flags supported by the mode. -SND_SOC_DAI_BFS_DIV -This flag states that bit clock is generated by dividing MCLK in this mode, if -this flag is absent the bitclock generated by mulitiplying sample rate. +/* use bfs mclk divider mode (BCLK = MCLK / x) */ +#define SND_SOC_DAI_BFS_DIV 0x1 +/* use bfs rate mulitplier (BCLK = RATE * x)*/ +#define SND_SOC_DAI_BFS_RATE 0x2 +/* use bfs rcw multiplier (BCLK = RATE * CHN * WORD SIZE) */ +#define SND_SOC_DAI_BFS_RCW 0x4 +/* capture and playback can use different clocks */ +#define SND_SOC_DAI_ASYNC 0x8 NOTE: Bitclock division and mulitiplication modes can be safely matched by the core logic. @@ -181,7 +187,7 @@ depends on the codec or CPU DAI). The BFS supported by the DAI mode. This can either be the ratio between the bitclock (BCLK) and the sample rate OR the ratio between the system clock and -the sample rate. Depends on the SND_SOC_DAI_BFS_DIV flag above. +the sample rate. Depends on the flags above. priv: ----- @@ -207,10 +213,15 @@ Simple codec that only runs at 8k & 48k @ 256FS in master mode, can generate a BCLK of either MCLK/2 or MCLK/4. /* codec master */ - {SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), - SNDRV_PCM_FORMAT_S16_LE, SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, - SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, SND_SOC_DAI_BFS_DIV, - 256, SND_SOC_FSBD(2) | SND_SOC_FSBD(4)}, + { + .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, + .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, + .pcmrate = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, + .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, + .flags = SND_SOC_DAI_BFS_DIV, + .fs = 256, + .bfs = SND_SOC_FSBD(2) | SND_SOC_FSBD(4), + } Example 2 @@ -219,32 +230,95 @@ Simple codec that only runs at 8k & 48k @ 256FS in master mode, can generate a BCLK of either Rate * 32 or Rate * 64. /* codec master */ - {SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), - SNDRV_PCM_FORMAT_S16_LE, SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, - SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, 0, - 256, SND_SOC_FSB(32) | SND_SOC_FSB(64)}, + { + .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, + .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, + .pcmrate = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, + .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, + .flags = SND_SOC_DAI_BFS_RATE, + .fs = 256, + .bfs = 32, + }, + { + .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, + .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, + .pcmrate = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, + .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, + .flags = SND_SOC_DAI_BFS_RATE, + .fs = 256, + .bfs = 64, + }, Example 3 --------- +Codec that runs at 8k & 48k @ 256FS in master mode, can generate a BCLK that +is a multiple of Rate * channels * word size. (RCW) i.e. + + BCLK = 8000 * 2 * 16 (8k, stereo, 16bit) + = 256kHz + +This codecs supports a RCW multiple of 1,2 + + { + .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, + .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, + .pcmrate = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, + .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, + .flags = SND_SOC_DAI_BFS_RCW, + .fs = 256, + .bfs = SND_SOC_FSBW(1) | SND_SOC_FSBW(2), + } + + +Example 4 +--------- Codec that only runs at 8k & 48k @ 256FS in master mode, can generate a BCLK of either Rate * 32 or Rate * 64. Codec can also run in slave mode as long as BCLK is rate * 32 or rate * 64. /* codec master */ - {SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), - SNDRV_PCM_FORMAT_S16_LE, SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, - SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, 0, - 256, SND_SOC_FSB(32) | SND_SOC_FSB(64)}, + { + .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, + .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, + .pcmrate = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, + .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, + .flags = SND_SOC_DAI_BFS_RATE, + .fs = 256, + .bfs = 32, + }, + { + .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, + .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, + .pcmrate = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, + .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, + .flags = SND_SOC_DAI_BFS_RATE, + .fs = 256, + .bfs = 64, + }, /* codec slave */ - {SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS, SND_SOC_DAITDM_LRDW(0,0), - SNDRV_PCM_FORMAT_S16_LE, SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, - SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, 0, - SND_SOC_FS_ALL, SND_SOC_FSB(32) | SND_SOC_FSB(64)}, + { + .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS, + .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, + .pcmdir = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, + .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, + .flags = SND_SOC_DAI_BFS_RATE, + .fs = SND_SOC_FS_ALL, + .bfs = 32, + }, + { + .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS, + .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, + .pcmdir = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, + .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, + .flags = SND_SOC_DAI_BFS_RATE, + .fs = SND_SOC_FS_ALL, + .bfs = 64, + }, -Example 4 +Example 5 --------- Codec that only runs at 8k, 16k, 32k, 48k, 96k @ 128FS, 192FS & 256FS in master mode and can generate a BCLK of MCLK / (1,2,4,8,16). Codec can also run in slave @@ -259,29 +333,48 @@ mode as and does not care about FS or BCLK (as long as there is enough bandwidth SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000) /* codec master @ 128, 192 & 256 FS */ - {SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), - SNDRV_PCM_FORMAT_S16_LE, CODEC_RATES, - SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, SND_SOC_DAI_BFS_DIV, - 128, CODEC_FSB}, - - {SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), - SNDRV_PCM_FORMAT_S16_LE, CODEC_RATES, - SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, SND_SOC_DAI_BFS_DIV, - 192, CODEC_FSB}, - - {SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), - SNDRV_PCM_FORMAT_S16_LE, CODEC_RATES, - SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, SND_SOC_DAI_BFS_DIV, - 256, CODEC_FSB}, + { + .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, + .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, + .pcmrate = CODEC_RATES, + .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, + .flags = SND_SOC_DAI_BFS_DIV, + .fs = 128, + .bfs = CODEC_FSB, + }, + + { + .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, + .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, + .pcmrate = CODEC_RATES, + .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, + .flags = SND_SOC_DAI_BFS_DIV, + .fs = 192, + .bfs = CODEC_FSB + }, + + { + .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, + .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, + .pcmrate = CODEC_RATES, + .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, + .flags = SND_SOC_DAI_BFS_DIV, + .fs = 256, + .bfs = CODEC_FSB, + }, /* codec slave */ - {SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS, SND_SOC_DAITDM_LRDW(0,0), - SNDRV_PCM_FORMAT_S16_LE, CODEC_RATES, - SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, 0, - SND_SOC_FS_ALL, SND_SOC_FSB_ALL}, + { + .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS, + .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, + .pcmrate = CODEC_RATES, + .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, + .fs = SND_SOC_FS_ALL, + .bfs = SND_SOC_FSB_ALL, + }, -Example 5 +Example 6 --------- Codec that only runs at 8k, 44.1k, 48k @ different FS in master mode (for use with a fixed MCLK) and can generate a BCLK of MCLK / (1,2,4,8,16). @@ -298,45 +391,66 @@ sizes. SNDRV_PCM_FORMAT_S24_3LE | SNDRV_PCM_FORMAT_S24_LE | SNDRV_PCM_FORMAT_S32_LE) /* codec master */ - {SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), - SNDRV_PCM_FORMAT_S16_LE, SNDRV_PCM_RATE_8000, - SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, SND_SOC_DAI_BFS_DIV, - 1536, CODEC_FSB}, - - {SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), - SNDRV_PCM_FORMAT_S16_LE, SNDRV_PCM_RATE_44100, - SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, SND_SOC_DAI_BFS_DIV, - 272, CODEC_FSB}, - - {SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), - SNDRV_PCM_FORMAT_S16_LE, SNDRV_PCM_RATE_48000, - SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, SND_SOC_DAI_BFS_DIV, - 256, CODEC_FSB}, + { + .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, + .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, + .pcmrate = SNDRV_PCM_RATE_8000, + .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, + .flags = SND_SOC_DAI_BFS_DIV, + .fs = 1536, + .bfs = CODEC_FSB, + }, + + { + .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, + .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, + .pcmrate = SNDRV_PCM_RATE_44100, + .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, + .flags = SND_SOC_DAI_BFS_DIV, + .fs = 272, + .bfs = CODEC_FSB, + }, + + { + .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, + .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, + .pcmrate = SNDRV_PCM_RATE_48000, + .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, + .flags = SND_SOC_DAI_BFS_DIV, + .fs = 256, + .bfs = CODEC_FSB, + }, /* codec slave */ - {SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS, SND_SOC_DAITDM_LRDW(0,0), - SNDRV_PCM_FORMAT_S16_LE, CODEC_RATES, - SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, 0, - SND_SOC_FS_ALL, SND_SOC_FSB_ALL}, + { + .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS, + .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, + .pcmrate = CODEC_RATES, + .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, + .fs = SND_SOC_FS_ALL, + .bfs = SND_SOC_FSB_ALL, + }, -Example 6 +Example 7 --------- AC97 Codec that does not support VRA (i.e only runs at 48k). #define AC97_DIR \ (SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE) - #define AC97_PCM_FORMATS \ (SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S18_3LE | \ SNDRV_PCM_FORMAT_S20_3LE) /* AC97 with no VRA */ - {0, 0, AC97_PCM_FORMATS, SNDRV_PCM_RATE_48000}, + { + .pcmfmt = AC97_PCM_FORMATS, + .pcmrate = SNDRV_PCM_RATE_48000, + } -Example 7 +Example 8 --------- CPU DAI that supports 8k - 48k @ 256FS and BCLK = MCLK / 4 in master mode. @@ -354,27 +468,79 @@ BCLK = 64 * rate. (Intel XScale I2S controller). SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) + /* priv is divider */ + static struct snd_soc_dai_mode pxa2xx_i2s_modes[] = { /* pxa2xx I2S frame and clock master modes */ - {PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, SND_SOC_DAITDM_LRDW(0,0), SNDRV_PCM_FORMAT_S16_LE, - SNDRV_PCM_RATE_8000, PXA_I2S_DIR, SND_SOC_DAI_BFS_DIV, 256, - SND_SOC_FSBD(4), 0x48}, - {PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, SND_SOC_DAITDM_LRDW(0,0), SNDRV_PCM_FORMAT_S16_LE, - SNDRV_PCM_RATE_11025, PXA_I2S_DIR, SND_SOC_DAI_BFS_DIV, 256, - SND_SOC_FSBD(4), 0x34}, - {PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, SND_SOC_DAITDM_LRDW(0,0), SNDRV_PCM_FORMAT_S16_LE, - SNDRV_PCM_RATE_16000, PXA_I2S_DIR, SND_SOC_DAI_BFS_DIV, 256, - SND_SOC_FSBD(4), 0x24}, - {PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, SND_SOC_DAITDM_LRDW(0,0), SNDRV_PCM_FORMAT_S16_LE, - SNDRV_PCM_RATE_22050, PXA_I2S_DIR, SND_SOC_DAI_BFS_DIV, 256, - SND_SOC_FSBD(4), 0x1a}, - {PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, SND_SOC_DAITDM_LRDW(0,0), SNDRV_PCM_FORMAT_S16_LE, - SNDRV_PCM_RATE_44100, PXA_I2S_DIR, SND_SOC_DAI_BFS_DIV, 256, - SND_SOC_FSBD(4), 0xd}, - {PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, SND_SOC_DAITDM_LRDW(0,0), SNDRV_PCM_FORMAT_S16_LE, - SNDRV_PCM_RATE_48000, PXA_I2S_DIR, SND_SOC_DAI_BFS_DIV, 256, - SND_SOC_FSBD(4), 0xc}, + { + .fmt = PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, + .pcmfmt = SNDRV_PCM_FMTBIT_S16_LE, + .pcmrate = SNDRV_PCM_RATE_8000, + .pcmdir = PXA_I2S_DIR, + .flags = SND_SOC_DAI_BFS_DIV, + .fs = 256, + .bfs = SND_SOC_FSBD(4), + .priv = 0x48, + }, + { + .fmt = PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, + .pcmfmt = SNDRV_PCM_FMTBIT_S16_LE, + .pcmrate = SNDRV_PCM_RATE_11025, + .pcmdir = PXA_I2S_DIR, + .flags = SND_SOC_DAI_BFS_DIV, + .fs = 256, + .bfs = SND_SOC_FSBD(4), + .priv = 0x34, + }, + { + .fmt = PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, + .pcmfmt = SNDRV_PCM_FMTBIT_S16_LE, + .pcmrate = SNDRV_PCM_RATE_16000, + .pcmdir = PXA_I2S_DIR, + .flags = SND_SOC_DAI_BFS_DIV, + .fs = 256, + .bfs = SND_SOC_FSBD(4), + .priv = 0x24, + }, + { + .fmt = PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, + .pcmfmt = SNDRV_PCM_FMTBIT_S16_LE, + .pcmrate = SNDRV_PCM_RATE_22050, + .pcmdir = PXA_I2S_DIR, + .flags = SND_SOC_DAI_BFS_DIV, + .fs = 256, + .bfs = SND_SOC_FSBD(4), + .priv = 0x1a, + }, + { + .fmt = PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, + .pcmfmt = SNDRV_PCM_FMTBIT_S16_LE, + .pcmrate = SNDRV_PCM_RATE_44100, + .pcmdir = PXA_I2S_DIR, + .flags = SND_SOC_DAI_BFS_DIV, + .fs = 256, + .bfs = SND_SOC_FSBD(4), + .priv = 0xd, + }, + { + .fmt = PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, + .pcmfmt = SNDRV_PCM_FMTBIT_S16_LE, + .pcmrate = SNDRV_PCM_RATE_48000, + .pcmdir = PXA_I2S_DIR, + .flags = SND_SOC_DAI_BFS_DIV, + .fs = 256, + .bfs = SND_SOC_FSBD(4), + .priv = 0xc, + }, /* pxa2xx I2S frame master and clock slave mode */ - {PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBM_CFS, SND_SOC_DAITDM_LRDW(0,0), SNDRV_PCM_FORMAT_S16_LE, - PXA_I2S_RATES, PXA_I2S_DIR, 0, SND_SOC_FS_ALL, SND_SOC_FSB(64)}, - + { + .fmt = PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBM_CFS, + .pcmfmt = SNDRV_PCM_FMTBIT_S16_LE, + .pcmrate = PXA_I2S_RATES, + .pcmdir = PXA_I2S_DIR, + .fs = SND_SOC_FS_ALL, + .flags = SND_SOC_DAI_BFS_RATE, + .bfs = 64, + .priv = 0x48, + }, +}; -- cgit v1.2.3 From 10b98527c34dca3f461256f5fcfff9b3790066e0 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Thu, 8 Feb 2007 17:06:09 +0100 Subject: [ALSA] ASoC documentation updates This patch updates the documentation for ASoC to reflect the recent changes in API between 0.12.x and 0.13.x Changes:- o Removed all reference to old API's. o Removed references and examples of automatic DAI config and matching. o Fixed 80 char line length on some files. Signed-off-by: Liam Girdwood Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- Documentation/sound/alsa/soc/DAI.txt | 490 ----------------------------------- 1 file changed, 490 deletions(-) (limited to 'Documentation/sound/alsa/soc/DAI.txt') diff --git a/Documentation/sound/alsa/soc/DAI.txt b/Documentation/sound/alsa/soc/DAI.txt index 251545a8869..58cbfd01ea8 100644 --- a/Documentation/sound/alsa/soc/DAI.txt +++ b/Documentation/sound/alsa/soc/DAI.txt @@ -54,493 +54,3 @@ Common PCM operating modes:- o Mode A - MSB is transmitted on falling edge of first BCLK after FRAME/SYNC. o Mode B - MSB is transmitted on rising edge of FRAME/SYNC. - - -ASoC DAI Configuration -====================== - -Every CODEC DAI and SoC DAI must have their capabilities defined in order to -be configured together at runtime when the audio and clocking parameters are -known. This is achieved by creating an array of struct snd_soc_hw_mode in the -the CODEC and SoC interface drivers. Each element in the array describes a DAI -mode and each mode is usually based upon the DAI system clock to sample rate -ratio (FS). - -i.e. 48k sample rate @ 256 FS = sytem clock of 12.288 MHz - 48000 * 256 = 12288000 - -The CPU and Codec DAI modes are then ANDed together at runtime to determine the -rutime DAI configuration for both the Codec and CPU. - -When creating a new codec or SoC DAI it's probably best to start of with a few -sample rates first and then test your interface. - -struct snd_soc_dai_mode is defined (in soc.h) as:- - -/* SoC DAI mode */ -struct snd_soc_dai_mode { - u16 fmt; /* SND_SOC_DAIFMT_* */ - u16 tdm; /* SND_SOC_HWTDM_* */ - u64 pcmfmt; /* SNDRV_PCM_FMTBIT_* */ - u16 pcmrate; /* SND_SOC_HWRATE_* */ - u16 pcmdir:2; /* SND_SOC_HWDIR_* */ - u16 flags:8; /* hw flags */ - u16 fs; /* mclk to rate divider */ - u64 bfs; /* mclk to bclk dividers */ - unsigned long priv; /* private mode data */ -}; - -fmt: ----- -This field defines the DAI mode hardware format (e.g. I2S settings) and -supports the following settings:- - - 1) hardware DAI formats - -#define SND_SOC_DAIFMT_I2S (1 << 0) /* I2S mode */ -#define SND_SOC_DAIFMT_RIGHT_J (1 << 1) /* Right justified mode */ -#define SND_SOC_DAIFMT_LEFT_J (1 << 2) /* Left Justified mode */ -#define SND_SOC_DAIFMT_DSP_A (1 << 3) /* L data msb after FRM */ -#define SND_SOC_DAIFMT_DSP_B (1 << 4) /* L data msb during FRM */ -#define SND_SOC_DAIFMT_AC97 (1 << 5) /* AC97 */ - - 2) hw DAI signal inversions - -#define SND_SOC_DAIFMT_NB_NF (1 << 8) /* normal bit clock + frame */ -#define SND_SOC_DAIFMT_NB_IF (1 << 9) /* normal bclk + inv frm */ -#define SND_SOC_DAIFMT_IB_NF (1 << 10) /* invert bclk + nor frm */ -#define SND_SOC_DAIFMT_IB_IF (1 << 11) /* invert bclk + frm */ - - 3) hw clock masters - This is wrt the codec, the inverse is true for the interface - i.e. if the codec is clk and frm master then the interface is - clk and frame slave. - -#define SND_SOC_DAIFMT_CBM_CFM (1 << 12) /* codec clk & frm master */ -#define SND_SOC_DAIFMT_CBS_CFM (1 << 13) /* codec clk slave & frm master */ -#define SND_SOC_DAIFMT_CBM_CFS (1 << 14) /* codec clk master & frame slave */ -#define SND_SOC_DAIFMT_CBS_CFS (1 << 15) /* codec clk & frm slave */ - -At least one option from each section must be selected. Multiple selections are -also supported e.g. - - .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_RIGHT_J | \ - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_NB_IF | SND_SOC_DAIFMT_IB_NF | \ - SND_SOC_DAIFMT_IB_IF - - -tdm: ------- -This field defines the Time Division Multiplexing left and right word -positions for the DAI mode if applicable. Set to SND_SOC_DAITDM_LRDW(0,0) for -no TDM. - - -pcmfmt: ---------- -The hardware PCM format. This describes the PCM formats supported by the DAI -mode e.g. - - .pcmfmt = SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S20_3LE | \ - SNDRV_PCM_FORMAT_S24_3LE - -pcmrate: ----------- -The PCM sample rates supported by the DAI mode. e.g. - - .pcmrate = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \ - SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ - SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 - - -pcmdir: ---------- -The stream directions supported by this mode. e.g. playback and capture - - -flags: --------- -The DAI hardware flags supported by the mode. - -/* use bfs mclk divider mode (BCLK = MCLK / x) */ -#define SND_SOC_DAI_BFS_DIV 0x1 -/* use bfs rate mulitplier (BCLK = RATE * x)*/ -#define SND_SOC_DAI_BFS_RATE 0x2 -/* use bfs rcw multiplier (BCLK = RATE * CHN * WORD SIZE) */ -#define SND_SOC_DAI_BFS_RCW 0x4 -/* capture and playback can use different clocks */ -#define SND_SOC_DAI_ASYNC 0x8 - -NOTE: Bitclock division and mulitiplication modes can be safely matched by the -core logic. - - -fs: ------ -The FS supported by this DAI mode FS is the ratio between the system clock and -the sample rate. See above - -bfs: ------- -BFS is the ratio of BCLK to MCLK or the ratio of BCLK to sample rate (this -depends on the codec or CPU DAI). - -The BFS supported by the DAI mode. This can either be the ratio between the -bitclock (BCLK) and the sample rate OR the ratio between the system clock and -the sample rate. Depends on the flags above. - -priv: ------ -private codec mode data. - - - -Examples -======== - -Note that Codec DAI and CPU DAI examples are interchangeable in these examples -as long as the bus master is reversed. i.e. - - SND_SOC_DAIFMT_CBM_CFM would become SND_SOC_DAIFMT_CBS_CFS - and vice versa. - -This applies to all SND_SOC_DAIFMT_CB*_CF*. - -Example 1 ---------- - -Simple codec that only runs at 8k & 48k @ 256FS in master mode, can generate a -BCLK of either MCLK/2 or MCLK/4. - - /* codec master */ - { - .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, - .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, - .pcmrate = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, - .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, - .flags = SND_SOC_DAI_BFS_DIV, - .fs = 256, - .bfs = SND_SOC_FSBD(2) | SND_SOC_FSBD(4), - } - - -Example 2 ---------- -Simple codec that only runs at 8k & 48k @ 256FS in master mode, can generate a -BCLK of either Rate * 32 or Rate * 64. - - /* codec master */ - { - .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, - .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, - .pcmrate = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, - .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, - .flags = SND_SOC_DAI_BFS_RATE, - .fs = 256, - .bfs = 32, - }, - { - .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, - .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, - .pcmrate = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, - .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, - .flags = SND_SOC_DAI_BFS_RATE, - .fs = 256, - .bfs = 64, - }, - - -Example 3 ---------- -Codec that runs at 8k & 48k @ 256FS in master mode, can generate a BCLK that -is a multiple of Rate * channels * word size. (RCW) i.e. - - BCLK = 8000 * 2 * 16 (8k, stereo, 16bit) - = 256kHz - -This codecs supports a RCW multiple of 1,2 - - { - .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, - .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, - .pcmrate = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, - .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, - .flags = SND_SOC_DAI_BFS_RCW, - .fs = 256, - .bfs = SND_SOC_FSBW(1) | SND_SOC_FSBW(2), - } - - -Example 4 ---------- -Codec that only runs at 8k & 48k @ 256FS in master mode, can generate a -BCLK of either Rate * 32 or Rate * 64. Codec can also run in slave mode as long -as BCLK is rate * 32 or rate * 64. - - /* codec master */ - { - .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, - .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, - .pcmrate = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, - .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, - .flags = SND_SOC_DAI_BFS_RATE, - .fs = 256, - .bfs = 32, - }, - { - .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, - .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, - .pcmrate = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, - .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, - .flags = SND_SOC_DAI_BFS_RATE, - .fs = 256, - .bfs = 64, - }, - - /* codec slave */ - { - .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS, - .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, - .pcmdir = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, - .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, - .flags = SND_SOC_DAI_BFS_RATE, - .fs = SND_SOC_FS_ALL, - .bfs = 32, - }, - { - .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS, - .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, - .pcmdir = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, - .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, - .flags = SND_SOC_DAI_BFS_RATE, - .fs = SND_SOC_FS_ALL, - .bfs = 64, - }, - - -Example 5 ---------- -Codec that only runs at 8k, 16k, 32k, 48k, 96k @ 128FS, 192FS & 256FS in master -mode and can generate a BCLK of MCLK / (1,2,4,8,16). Codec can also run in slave -mode as and does not care about FS or BCLK (as long as there is enough bandwidth). - - #define CODEC_FSB \ - (SND_SOC_FSBD(1) | SND_SOC_FSBD(2) | SND_SOC_FSBD(4) | \ - SND_SOC_FSBD(8) | SND_SOC_FSBD(16)) - - #define CODEC_RATES \ - (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_32000 |\ - SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000) - - /* codec master @ 128, 192 & 256 FS */ - { - .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, - .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, - .pcmrate = CODEC_RATES, - .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, - .flags = SND_SOC_DAI_BFS_DIV, - .fs = 128, - .bfs = CODEC_FSB, - }, - - { - .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, - .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, - .pcmrate = CODEC_RATES, - .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, - .flags = SND_SOC_DAI_BFS_DIV, - .fs = 192, - .bfs = CODEC_FSB - }, - - { - .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, - .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, - .pcmrate = CODEC_RATES, - .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, - .flags = SND_SOC_DAI_BFS_DIV, - .fs = 256, - .bfs = CODEC_FSB, - }, - - /* codec slave */ - { - .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS, - .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, - .pcmrate = CODEC_RATES, - .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, - .fs = SND_SOC_FS_ALL, - .bfs = SND_SOC_FSB_ALL, - }, - - -Example 6 ---------- -Codec that only runs at 8k, 44.1k, 48k @ different FS in master mode (for use -with a fixed MCLK) and can generate a BCLK of MCLK / (1,2,4,8,16). -Codec can also run in slave mode as and does not care about FS or BCLK (as long -as there is enough bandwidth). Codec can support 16, 24 and 32 bit PCM sample -sizes. - - #define CODEC_FSB \ - (SND_SOC_FSBD(1) | SND_SOC_FSBD(2) | SND_SOC_FSBD(4) | \ - SND_SOC_FSBD(8) | SND_SOC_FSBD(16)) - - #define CODEC_PCM_FORMATS \ - (SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S20_3LE | \ - SNDRV_PCM_FORMAT_S24_3LE | SNDRV_PCM_FORMAT_S24_LE | SNDRV_PCM_FORMAT_S32_LE) - - /* codec master */ - { - .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, - .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, - .pcmrate = SNDRV_PCM_RATE_8000, - .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, - .flags = SND_SOC_DAI_BFS_DIV, - .fs = 1536, - .bfs = CODEC_FSB, - }, - - { - .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, - .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, - .pcmrate = SNDRV_PCM_RATE_44100, - .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, - .flags = SND_SOC_DAI_BFS_DIV, - .fs = 272, - .bfs = CODEC_FSB, - }, - - { - .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, - .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, - .pcmrate = SNDRV_PCM_RATE_48000, - .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, - .flags = SND_SOC_DAI_BFS_DIV, - .fs = 256, - .bfs = CODEC_FSB, - }, - - /* codec slave */ - { - .fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS, - .pcmfmt = SNDRV_PCM_FORMAT_S16_LE, - .pcmrate = CODEC_RATES, - .pcmdir = SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE, - .fs = SND_SOC_FS_ALL, - .bfs = SND_SOC_FSB_ALL, - }, - - -Example 7 ---------- -AC97 Codec that does not support VRA (i.e only runs at 48k). - - #define AC97_DIR \ - (SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE) - - #define AC97_PCM_FORMATS \ - (SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S18_3LE | \ - SNDRV_PCM_FORMAT_S20_3LE) - - /* AC97 with no VRA */ - { - .pcmfmt = AC97_PCM_FORMATS, - .pcmrate = SNDRV_PCM_RATE_48000, - } - - -Example 8 ---------- - -CPU DAI that supports 8k - 48k @ 256FS and BCLK = MCLK / 4 in master mode. -Slave mode (CPU DAI is FRAME master) supports 8k - 96k at any FS as long as -BCLK = 64 * rate. (Intel XScale I2S controller). - - #define PXA_I2S_DAIFMT \ - (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF) - - #define PXA_I2S_DIR \ - (SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE) - - #define PXA_I2S_RATES \ - (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \ - SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ - SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) - - /* priv is divider */ - static struct snd_soc_dai_mode pxa2xx_i2s_modes[] = { - /* pxa2xx I2S frame and clock master modes */ - { - .fmt = PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, - .pcmfmt = SNDRV_PCM_FMTBIT_S16_LE, - .pcmrate = SNDRV_PCM_RATE_8000, - .pcmdir = PXA_I2S_DIR, - .flags = SND_SOC_DAI_BFS_DIV, - .fs = 256, - .bfs = SND_SOC_FSBD(4), - .priv = 0x48, - }, - { - .fmt = PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, - .pcmfmt = SNDRV_PCM_FMTBIT_S16_LE, - .pcmrate = SNDRV_PCM_RATE_11025, - .pcmdir = PXA_I2S_DIR, - .flags = SND_SOC_DAI_BFS_DIV, - .fs = 256, - .bfs = SND_SOC_FSBD(4), - .priv = 0x34, - }, - { - .fmt = PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, - .pcmfmt = SNDRV_PCM_FMTBIT_S16_LE, - .pcmrate = SNDRV_PCM_RATE_16000, - .pcmdir = PXA_I2S_DIR, - .flags = SND_SOC_DAI_BFS_DIV, - .fs = 256, - .bfs = SND_SOC_FSBD(4), - .priv = 0x24, - }, - { - .fmt = PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, - .pcmfmt = SNDRV_PCM_FMTBIT_S16_LE, - .pcmrate = SNDRV_PCM_RATE_22050, - .pcmdir = PXA_I2S_DIR, - .flags = SND_SOC_DAI_BFS_DIV, - .fs = 256, - .bfs = SND_SOC_FSBD(4), - .priv = 0x1a, - }, - { - .fmt = PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, - .pcmfmt = SNDRV_PCM_FMTBIT_S16_LE, - .pcmrate = SNDRV_PCM_RATE_44100, - .pcmdir = PXA_I2S_DIR, - .flags = SND_SOC_DAI_BFS_DIV, - .fs = 256, - .bfs = SND_SOC_FSBD(4), - .priv = 0xd, - }, - { - .fmt = PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, - .pcmfmt = SNDRV_PCM_FMTBIT_S16_LE, - .pcmrate = SNDRV_PCM_RATE_48000, - .pcmdir = PXA_I2S_DIR, - .flags = SND_SOC_DAI_BFS_DIV, - .fs = 256, - .bfs = SND_SOC_FSBD(4), - .priv = 0xc, - }, - - /* pxa2xx I2S frame master and clock slave mode */ - { - .fmt = PXA_I2S_DAIFMT | SND_SOC_DAIFMT_CBM_CFS, - .pcmfmt = SNDRV_PCM_FMTBIT_S16_LE, - .pcmrate = PXA_I2S_RATES, - .pcmdir = PXA_I2S_DIR, - .fs = SND_SOC_FS_ALL, - .flags = SND_SOC_DAI_BFS_RATE, - .bfs = 64, - .priv = 0x48, - }, -}; -- cgit v1.2.3