Hi Sakamoto-san, again
Thanks you for your help. I think I could find my issue on my system. I will post patch, soon
Hmm... Above .be_hw_params_fixup is used to convert sampling rate or channel number or some other related things between SoC / Codec as DPCM feature. Thus, I can't switch to .be_hw_params_fixup to .prepare I guess. But Mark, am I misunderstanding ?
In 'struct snd_pcm_ops.prepare' callback, configured parameters of PCM substream are available via members of 'struct snd_pcm_runtime'. The runtime is a member of 'struct snd_pcm_substream'. It's available in any of .prepare callbacks in ALSA SoC part.
Thank you for detail explain. I investigated this, and I tried to use .prepare with below system.
[44.1kHz] -> CPU -> .be_hw_params_fixup[44.1kHz -> 48kHz] -> Codec
This means, CPU converts 44.1kHz to 48kHz, and Codec want to receive 48kHz as parameter. On CPU/Codec both side, these got 44.1kHz from runtime.
static int cpu/codec_prepare(struct snd_pcm_substream *substream) { /* * In 44.1kHz -> 48kHz convert case, * .be_hw_params_fixup() do convert magic. * but here .prepare, it still receive 44.1kHz */ printk("rate = %d\n", substream->runtime->rate); }
On CPU side, I could get converted parameter somehow (see below), but it has zero chance to get converted parameter on Codec side .prepare ? Converted rate is located only struct snd_pcm_hw_params in my system (= simple-scu-card). Current .be_hw_params_fixup() is saving converted rate/channel in struct snd_interval, but it should save it to struct snd_soc_pcm_runtime ?
void asoc_simple_card_convert_fixup(... struct snd_pcm_hw_params *hw_params) { struct snd_interval *rate = hw_param_interval(hw_params, SNDRV_PCM_HW_PARAM_RATE); struct snd_interval *channels = hw_param_interval(hw_params, SNDRV_PCM_HW_PARAM_CHANNELS); printk("------fixup\n"); if (data->convert_rate) rate->min = rate->max = data->convert_rate;
if (data->convert_channels) channels->min = channels->max = data->convert_channels; }
---- CPU could get converted rate -------------------------- static int cpu_prepare(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *fe = substream->private_data;
/* substream->runtime->rate is still 44.1kHz here */
if (fe->dai_link->dynamic) { int stream = substream->stream; struct snd_soc_dpcm *dpcm; struct snd_pcm_hw_params *be_params;
list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) { be_params = &dpcm->hw_params; /* * I could receive 48kHz here as params_rate(be_params) */ }
}
return 0; }
Best regards
Kuninori Morimoto