Hi again, I have a system that has separate DACs and ADCs, as opposed to bidirectional CODECS.
The ADCs have a snd_soc_dai_driver structure that have a .capture field defined with a .rates parameter, and the DACs have a snd_soc_dai_driver structure that have a .playback field defined with a .rates parameter.
However, the ADCs have no .playback.rates, and the DACs have no .capture.rates. Even though the ADC can record at a given rate and the DAC can play at that same rate, the soc_pcm_init_runtime_hw function calculates the rates in this loop:
------------------------------ /* first calculate min/max only for CODECs in the DAI link */ for (i = 0; i < rtd->num_codecs; i++) { codec_dai_drv = rtd->codec_dais[i]->driver; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) codec_stream = &codec_dai_drv->playback; else codec_stream = &codec_dai_drv->capture; chan_min = max(chan_min, codec_stream->channels_min); chan_max = min(chan_max, codec_stream->channels_max); rate_min = max(rate_min, codec_stream->rate_min); rate_max = min_not_zero(rate_max, codec_stream->rate_max); formats &= codec_stream->formats; rates = snd_pcm_rate_mask_intersect(codec_stream->rates, rates); } ------------------------------
which can't work out that one side is play only and the other is record only, yet they do in fact have matching rates. So, I get a "no matching channels" error.
Here are my example drivers declarations: for the ADC: ---------------------- static struct snd_soc_dai_driver cs53l30_dai = { .name = "cs53l30-hifi", .capture = { .stream_name = "Capture", .channels_min = 4, .channels_max = 16, .rates = SNDRV_PCM_RATE_16000, .formats =SNDRV_PCM_FMTBIT_S16_LE, }, }; --------------------
and for the DAC
---------------------- static struct snd_soc_dai_driver tlv320dac3100_dai = { .name = "tlv320dac3100-hifi", .playback = { .stream_name = "Playback", .channels_min = 2, .channels_max = 16, .rates = SNDRV_PCM_RATE_16000, .formats =SNDRV_PCM_FMTBIT_S16_LE, }, .ops = &tlv320dac3100_dai_ops, }; ------------------------------
I was able to fake it out by adding a .playback field to my ADC with 0 channels, and a .capture field to my DAC with 0 channels.
My question is: what's the right way to manage this? I assume we should probably tweak soc_pcm_init_runtime_hw, right?
Thanks, -Caleb