^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) ==============================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) Creating codec to codec dai link for ALSA dapm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) ==============================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) Mostly the flow of audio is always from CPU to codec so your system
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) will look as below:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) ::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) --------- ---------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) | | dai | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) CPU -------> codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) | | | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) --------- ---------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) In case your system looks as below:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) ::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) ---------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) codec-2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) ---------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) dai-2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) ---------- ---------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) | | dai-1 | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) CPU -------> codec-1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) | | | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) ---------- ---------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) dai-3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) ---------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) codec-3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) ---------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) Suppose codec-2 is a bluetooth chip and codec-3 is connected to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) a speaker and you have a below scenario:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) codec-2 will receive the audio data and the user wants to play that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) audio through codec-3 without involving the CPU.This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) aforementioned case is the ideal case when codec to codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) connection should be used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) Your dai_link should appear as below in your machine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) file:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) ::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * this pcm stream only supports 24 bit, 2 channel and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * 48k sampling rate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static const struct snd_soc_pcm_stream dsp_codec_params = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) .formats = SNDRV_PCM_FMTBIT_S24_LE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) .rate_min = 48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) .rate_max = 48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) .channels_min = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) .channels_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) .name = "CPU-DSP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) .stream_name = "CPU-DSP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) .cpu_dai_name = "samsung-i2s.0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) .codec_name = "codec-2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) .codec_dai_name = "codec-2-dai_name",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) .platform_name = "samsung-i2s.0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) | SND_SOC_DAIFMT_CBM_CFM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) .ignore_suspend = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) .params = &dsp_codec_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) .name = "DSP-CODEC",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) .stream_name = "DSP-CODEC",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) .cpu_dai_name = "wm0010-sdi2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) .codec_name = "codec-3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) .codec_dai_name = "codec-3-dai_name",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) | SND_SOC_DAIFMT_CBM_CFM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) .ignore_suspend = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) .params = &dsp_codec_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) Above code snippet is motivated from sound/soc/samsung/speyside.c.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) Note the "params" callback which lets the dapm know that this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) dai_link is a codec to codec connection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) In dapm core a route is created between cpu_dai playback widget
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) and codec_dai capture widget for playback path and vice-versa is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) true for capture path. In order for this aforementioned route to get
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) triggered, DAPM needs to find a valid endpoint which could be either
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) a sink or source widget corresponding to playback and capture path
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) respectively.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) In order to trigger this dai_link widget, a thin codec driver for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) the speaker amp can be created as demonstrated in wm8727.c file, it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) sets appropriate constraints for the device even if it needs no control.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) Make sure to name your corresponding cpu and codec playback and capture
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) dai names ending with "Playback" and "Capture" respectively as dapm core
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) will link and power those dais based on the name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) A dai_link in a "simple-audio-card" will automatically be detected as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) codec to codec when all DAIs on the link belong to codec components.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) The dai_link will be initialized with the subset of stream parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) (channels, format, sample rate) supported by all DAIs on the link. Since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) there is no way to provide these parameters in the device tree, this is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) mostly useful for communication with simple fixed-function codecs, such
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) as a Bluetooth controller or cellular modem.