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