Loading Documentation/sound/index.rst +1 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ Linux Sound Subsystem Documentation kernel-api/index designs/index soc/index alsa-configuration hd-audio/index cards/index Loading Documentation/sound/alsa/soc/clocking.txt→Documentation/sound/soc/clocking.rst +4 −9 Original line number Diff line number Diff line ============== Audio Clocking ============== Loading Loading @@ -30,15 +31,9 @@ runs at exactly the sample rate (LRC = Rate). Bit Clock can be generated as follows:- BCLK = MCLK / x or BCLK = LRC * x or BCLK = LRC * Channels * Word Size - BCLK = MCLK / x, or - BCLK = LRC * x, or - BCLK = LRC * Channels * Word Size This relationship depends on the codec or SoC CPU in particular. In general it is best to configure BCLK to the lowest possible speed (depending on your Loading Documentation/sound/soc/codec-to-codec.rst 0 → 100644 +108 −0 Original line number Diff line number Diff line ============================================== Creating codec to codec dai link for ALSA dapm ============================================== Mostly the flow of audio is always from CPU to codec so your system will look as below: :: --------- --------- | | dai | | CPU -------> codec | | | | --------- --------- In case your system looks as below: :: --------- | | codec-2 | | --------- | dai-2 | ---------- --------- | | dai-1 | | CPU -------> codec-1 | | | | ---------- --------- | dai-3 | --------- | | codec-3 | | --------- Suppose codec-2 is a bluetooth chip and codec-3 is connected to a speaker and you have a below scenario: codec-2 will receive the audio data and the user wants to play that audio through codec-3 without involving the CPU.This aforementioned case is the ideal case when codec to codec connection should be used. Your dai_link should appear as below in your machine file: :: /* * this pcm stream only supports 24 bit, 2 channel and * 48k sampling rate. */ static const struct snd_soc_pcm_stream dsp_codec_params = { .formats = SNDRV_PCM_FMTBIT_S24_LE, .rate_min = 48000, .rate_max = 48000, .channels_min = 2, .channels_max = 2, }; { .name = "CPU-DSP", .stream_name = "CPU-DSP", .cpu_dai_name = "samsung-i2s.0", .codec_name = "codec-2, .codec_dai_name = "codec-2-dai_name", .platform_name = "samsung-i2s.0", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM, .ignore_suspend = 1, .params = &dsp_codec_params, }, { .name = "DSP-CODEC", .stream_name = "DSP-CODEC", .cpu_dai_name = "wm0010-sdi2", .codec_name = "codec-3, .codec_dai_name = "codec-3-dai_name", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM, .ignore_suspend = 1, .params = &dsp_codec_params, }, Above code snippet is motivated from sound/soc/samsung/speyside.c. Note the "params" callback which lets the dapm know that this dai_link is a codec to codec connection. In dapm core a route is created between cpu_dai playback widget and codec_dai capture widget for playback path and vice-versa is true for capture path. In order for this aforementioned route to get triggered, DAPM needs to find a valid endpoint which could be either a sink or source widget corresponding to playback and capture path respectively. In order to trigger this dai_link widget, a thin codec driver for the speaker amp can be created as demonstrated in wm8727.c file, it sets appropriate constraints for the device even if it needs no control. Make sure to name your corresponding cpu and codec playback and capture dai names ending with "Playback" and "Capture" respectively as dapm core will link and power those dais based on the name. Note that in current device tree there is no way to mark a dai_link as codec to codec. However, it may change in future. Documentation/sound/alsa/soc/codec.txt→Documentation/sound/soc/codec.rst +43 −32 Original line number Diff line number Diff line ======================= ASoC Codec Class Driver ======================= Loading @@ -9,16 +10,16 @@ machine drivers respectively. Each codec class driver *must* provide the following features:- 1) Codec DAI and PCM configuration 2) Codec control IO - using RegMap API 3) Mixers and audio controls 4) Codec audio operations 5) DAPM description. 6) DAPM event handler. 1. Codec DAI and PCM configuration 2. Codec control IO - using RegMap API 3. Mixers and audio controls 4. Codec audio operations 5. DAPM description. 6. DAPM event handler. Optionally, codec drivers can also provide:- 7) DAC Digital mute control. 7. DAC Digital mute control. Its probably best to use this guide in conjunction with the existing codec driver code in sound/soc/codecs/ Loading @@ -26,13 +27,14 @@ driver code in sound/soc/codecs/ ASoC Codec driver breakdown =========================== 1 - Codec DAI and PCM configuration ----------------------------------- Codec DAI and PCM configuration ------------------------------- Each codec driver must have a struct snd_soc_dai_driver to define its DAI and PCM capabilities and operations. This struct is exported so that it can be registered with the core by your machine driver. e.g. :: static struct snd_soc_dai_ops wm8731_dai_ops = { .prepare = wm8731_pcm_prepare, Loading Loading @@ -62,22 +64,24 @@ struct snd_soc_dai_driver wm8731_dai = { }; 2 - Codec control IO -------------------- Codec control IO ---------------- The codec can usually be controlled via an I2C or SPI style interface (AC97 combines control with data in the DAI). The codec driver should use the Regmap API for all codec IO. Please see include/linux/regmap.h and existing codec drivers for example regmap usage. 3 - Mixers and audio controls ----------------------------- Mixers and audio controls ------------------------- All the codec mixers and audio controls can be defined using the convenience macros defined in soc.h. :: #define SOC_SINGLE(xname, reg, shift, mask, invert) Defines a single control as follows:- :: xname = Control name e.g. "Playback Volume" reg = codec register Loading @@ -86,18 +90,22 @@ Defines a single control as follows:- invert = the control is inverted Other macros include:- :: #define SOC_DOUBLE(xname, reg, shift_left, shift_right, mask, invert) A stereo control :: #define SOC_DOUBLE_R(xname, reg_left, reg_right, shift, mask, invert) A stereo control spanning 2 registers :: #define SOC_ENUM_SINGLE(xreg, xshift, xmask, xtexts) Defines an single enumerated control as follows:- :: xreg = register xshift = control bit(s) offset in register Loading @@ -109,9 +117,10 @@ Defines an single enumerated control as follows:- Defines a stereo enumerated control 4 - Codec Audio Operations -------------------------- Codec Audio Operations ---------------------- The codec driver also supports the following ALSA PCM operations:- :: /* SoC audio ops */ struct snd_soc_ops { Loading @@ -126,8 +135,8 @@ Please refer to the ALSA driver PCM documentation for details. http://www.alsa-project.org/~iwai/writing-an-alsa-driver/ 5 - DAPM description. --------------------- DAPM description ---------------- The Dynamic Audio Power Management description describes the codec power components and their relationships and registers to the ASoC core. Please read dapm.txt for details of building the description. Loading @@ -135,13 +144,14 @@ Please read dapm.txt for details of building the description. Please also see the examples in other codec drivers. 6 - DAPM event handler ---------------------- DAPM event handler ------------------ This function is a callback that handles codec domain PM calls and system domain PM calls (e.g. suspend and resume). It is used to put the codec to sleep when not in use. Power states:- :: SNDRV_CTL_POWER_D0: /* full On */ /* vref/mid, clk and osc on, active */ Loading @@ -155,8 +165,8 @@ Power states:- SNDRV_CTL_POWER_D3cold: /* Everything Off, without power */ 7 - Codec DAC digital mute control ---------------------------------- Codec DAC digital mute control ------------------------------ Most codecs have a digital mute before the DACs that can be used to minimise any system noise. The mute stops any digital data from entering the DAC. Loading @@ -165,6 +175,7 @@ A callback can be created that is called by the core for each codec DAI when the mute is applied or freed. i.e. :: static int wm8974_mute(struct snd_soc_dai *dai, int mute) { Loading Documentation/sound/alsa/soc/DAI.txt→Documentation/sound/soc/dai.rst +18 −10 Original line number Diff line number Diff line ================================== ASoC Digital Audio Interface (DAI) ================================== ASoC currently supports the three main Digital Audio Interfaces (DAI) found on SoC controllers and portable audio CODECs today, namely AC97, I2S and PCM. Loading @@ -12,7 +16,7 @@ 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 :- The AC97 specification can be found at : http://www.intel.com/p/en_US/business/design Loading @@ -30,13 +34,15 @@ different sample rates. I2S has several different operating modes:- o I2S - MSB is transmitted on the falling edge of the first BCLK after LRC 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. Left Justified MSB is transmitted on transition of LRC. o Right Justified - MSB is transmitted sample size BCLKs before LRC transition. Right Justified MSB is transmitted sample size BCLKs before LRC transition. PCM === Loading @@ -51,6 +57,8 @@ 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. 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. Mode B MSB is transmitted on rising edge of FRAME/SYNC. Loading
Documentation/sound/index.rst +1 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ Linux Sound Subsystem Documentation kernel-api/index designs/index soc/index alsa-configuration hd-audio/index cards/index Loading
Documentation/sound/alsa/soc/clocking.txt→Documentation/sound/soc/clocking.rst +4 −9 Original line number Diff line number Diff line ============== Audio Clocking ============== Loading Loading @@ -30,15 +31,9 @@ runs at exactly the sample rate (LRC = Rate). Bit Clock can be generated as follows:- BCLK = MCLK / x or BCLK = LRC * x or BCLK = LRC * Channels * Word Size - BCLK = MCLK / x, or - BCLK = LRC * x, or - BCLK = LRC * Channels * Word Size This relationship depends on the codec or SoC CPU in particular. In general it is best to configure BCLK to the lowest possible speed (depending on your Loading
Documentation/sound/soc/codec-to-codec.rst 0 → 100644 +108 −0 Original line number Diff line number Diff line ============================================== Creating codec to codec dai link for ALSA dapm ============================================== Mostly the flow of audio is always from CPU to codec so your system will look as below: :: --------- --------- | | dai | | CPU -------> codec | | | | --------- --------- In case your system looks as below: :: --------- | | codec-2 | | --------- | dai-2 | ---------- --------- | | dai-1 | | CPU -------> codec-1 | | | | ---------- --------- | dai-3 | --------- | | codec-3 | | --------- Suppose codec-2 is a bluetooth chip and codec-3 is connected to a speaker and you have a below scenario: codec-2 will receive the audio data and the user wants to play that audio through codec-3 without involving the CPU.This aforementioned case is the ideal case when codec to codec connection should be used. Your dai_link should appear as below in your machine file: :: /* * this pcm stream only supports 24 bit, 2 channel and * 48k sampling rate. */ static const struct snd_soc_pcm_stream dsp_codec_params = { .formats = SNDRV_PCM_FMTBIT_S24_LE, .rate_min = 48000, .rate_max = 48000, .channels_min = 2, .channels_max = 2, }; { .name = "CPU-DSP", .stream_name = "CPU-DSP", .cpu_dai_name = "samsung-i2s.0", .codec_name = "codec-2, .codec_dai_name = "codec-2-dai_name", .platform_name = "samsung-i2s.0", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM, .ignore_suspend = 1, .params = &dsp_codec_params, }, { .name = "DSP-CODEC", .stream_name = "DSP-CODEC", .cpu_dai_name = "wm0010-sdi2", .codec_name = "codec-3, .codec_dai_name = "codec-3-dai_name", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM, .ignore_suspend = 1, .params = &dsp_codec_params, }, Above code snippet is motivated from sound/soc/samsung/speyside.c. Note the "params" callback which lets the dapm know that this dai_link is a codec to codec connection. In dapm core a route is created between cpu_dai playback widget and codec_dai capture widget for playback path and vice-versa is true for capture path. In order for this aforementioned route to get triggered, DAPM needs to find a valid endpoint which could be either a sink or source widget corresponding to playback and capture path respectively. In order to trigger this dai_link widget, a thin codec driver for the speaker amp can be created as demonstrated in wm8727.c file, it sets appropriate constraints for the device even if it needs no control. Make sure to name your corresponding cpu and codec playback and capture dai names ending with "Playback" and "Capture" respectively as dapm core will link and power those dais based on the name. Note that in current device tree there is no way to mark a dai_link as codec to codec. However, it may change in future.
Documentation/sound/alsa/soc/codec.txt→Documentation/sound/soc/codec.rst +43 −32 Original line number Diff line number Diff line ======================= ASoC Codec Class Driver ======================= Loading @@ -9,16 +10,16 @@ machine drivers respectively. Each codec class driver *must* provide the following features:- 1) Codec DAI and PCM configuration 2) Codec control IO - using RegMap API 3) Mixers and audio controls 4) Codec audio operations 5) DAPM description. 6) DAPM event handler. 1. Codec DAI and PCM configuration 2. Codec control IO - using RegMap API 3. Mixers and audio controls 4. Codec audio operations 5. DAPM description. 6. DAPM event handler. Optionally, codec drivers can also provide:- 7) DAC Digital mute control. 7. DAC Digital mute control. Its probably best to use this guide in conjunction with the existing codec driver code in sound/soc/codecs/ Loading @@ -26,13 +27,14 @@ driver code in sound/soc/codecs/ ASoC Codec driver breakdown =========================== 1 - Codec DAI and PCM configuration ----------------------------------- Codec DAI and PCM configuration ------------------------------- Each codec driver must have a struct snd_soc_dai_driver to define its DAI and PCM capabilities and operations. This struct is exported so that it can be registered with the core by your machine driver. e.g. :: static struct snd_soc_dai_ops wm8731_dai_ops = { .prepare = wm8731_pcm_prepare, Loading Loading @@ -62,22 +64,24 @@ struct snd_soc_dai_driver wm8731_dai = { }; 2 - Codec control IO -------------------- Codec control IO ---------------- The codec can usually be controlled via an I2C or SPI style interface (AC97 combines control with data in the DAI). The codec driver should use the Regmap API for all codec IO. Please see include/linux/regmap.h and existing codec drivers for example regmap usage. 3 - Mixers and audio controls ----------------------------- Mixers and audio controls ------------------------- All the codec mixers and audio controls can be defined using the convenience macros defined in soc.h. :: #define SOC_SINGLE(xname, reg, shift, mask, invert) Defines a single control as follows:- :: xname = Control name e.g. "Playback Volume" reg = codec register Loading @@ -86,18 +90,22 @@ Defines a single control as follows:- invert = the control is inverted Other macros include:- :: #define SOC_DOUBLE(xname, reg, shift_left, shift_right, mask, invert) A stereo control :: #define SOC_DOUBLE_R(xname, reg_left, reg_right, shift, mask, invert) A stereo control spanning 2 registers :: #define SOC_ENUM_SINGLE(xreg, xshift, xmask, xtexts) Defines an single enumerated control as follows:- :: xreg = register xshift = control bit(s) offset in register Loading @@ -109,9 +117,10 @@ Defines an single enumerated control as follows:- Defines a stereo enumerated control 4 - Codec Audio Operations -------------------------- Codec Audio Operations ---------------------- The codec driver also supports the following ALSA PCM operations:- :: /* SoC audio ops */ struct snd_soc_ops { Loading @@ -126,8 +135,8 @@ Please refer to the ALSA driver PCM documentation for details. http://www.alsa-project.org/~iwai/writing-an-alsa-driver/ 5 - DAPM description. --------------------- DAPM description ---------------- The Dynamic Audio Power Management description describes the codec power components and their relationships and registers to the ASoC core. Please read dapm.txt for details of building the description. Loading @@ -135,13 +144,14 @@ Please read dapm.txt for details of building the description. Please also see the examples in other codec drivers. 6 - DAPM event handler ---------------------- DAPM event handler ------------------ This function is a callback that handles codec domain PM calls and system domain PM calls (e.g. suspend and resume). It is used to put the codec to sleep when not in use. Power states:- :: SNDRV_CTL_POWER_D0: /* full On */ /* vref/mid, clk and osc on, active */ Loading @@ -155,8 +165,8 @@ Power states:- SNDRV_CTL_POWER_D3cold: /* Everything Off, without power */ 7 - Codec DAC digital mute control ---------------------------------- Codec DAC digital mute control ------------------------------ Most codecs have a digital mute before the DACs that can be used to minimise any system noise. The mute stops any digital data from entering the DAC. Loading @@ -165,6 +175,7 @@ A callback can be created that is called by the core for each codec DAI when the mute is applied or freed. i.e. :: static int wm8974_mute(struct snd_soc_dai *dai, int mute) { Loading
Documentation/sound/alsa/soc/DAI.txt→Documentation/sound/soc/dai.rst +18 −10 Original line number Diff line number Diff line ================================== ASoC Digital Audio Interface (DAI) ================================== ASoC currently supports the three main Digital Audio Interfaces (DAI) found on SoC controllers and portable audio CODECs today, namely AC97, I2S and PCM. Loading @@ -12,7 +16,7 @@ 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 :- The AC97 specification can be found at : http://www.intel.com/p/en_US/business/design Loading @@ -30,13 +34,15 @@ different sample rates. I2S has several different operating modes:- o I2S - MSB is transmitted on the falling edge of the first BCLK after LRC 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. Left Justified MSB is transmitted on transition of LRC. o Right Justified - MSB is transmitted sample size BCLKs before LRC transition. Right Justified MSB is transmitted sample size BCLKs before LRC transition. PCM === Loading @@ -51,6 +57,8 @@ 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. 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. Mode B MSB is transmitted on rising edge of FRAME/SYNC.