mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-03 17:51:57 +09:00
ASoC: soc-pcm: fixup snd_pcm_limit_hw_rates() timing
soc-pcm has snd_pcm_limit_hw_rates() which determine rate_min/rate_max.
It updates runtime->hw.rate_min/max (A) based on hw->rates (B).
int snd_pcm_limit_hw_rates(...)
{
int i;
for (...) {
(B) if (runtime->hw.rates & (1 << i)) {
(A) runtime->hw.rate_min = ...
break;
}
}
for (...) {
(B) if (runtime->hw.rates & (1 << i)) {
(A) runtime->hw.rate_max = ...
break;
}
}
return 0;
}
This means, setup order is
1) set hw->rates
2) call snd_pcm_limit_hw_rates()
3) update hw->rate_min/max
soc_pcm_init_runtime_hw() is calling it in good order
static void soc_pcm_init_runtime_hw(xxx)
{
...
1) hw->rates = snd_pcm_rate_mask_intersect(...);
2) snd_pcm_limit_hw_rates(...);
3) hw->rate_min = max(...);
hw->rate_min = max(...);
hw->rate_max = min_not_zero(...);
hw->rate_max = min_not_zero(...);
}
But, dpcm_fe_dai_startup() is not.
static int dpcm_fe_dai_startup(xxx)
{
...
1) 3) dpcm_set_fe_runtime(...);
2) snd_pcm_limit_hw_rates(...);
...
}
More detail of dpcm_set_fe_runtime() is
static void dpcm_set_fe_runtime()
{
...
for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
...
3) 1) dpcm_init_runtime_hw(...);
}
...
3) 1) dpcm_runtime_merge_rate(...);
}
This patch fixup these into
static void dpcm_set_fe_runtime()
{
...
for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
...
1) 2) 3) dpcm_init_runtime_hw(...);
}
...
1) 2) 3) dpcm_runtime_merge_rate(...);
}
static int dpcm_fe_dai_startup(xxx)
{
...
dpcm_set_fe_runtime(...);
- snd_pcm_limit_hw_rates(...);
...
}
Link: https://lore.kernel.org/r/87k15l7ewd.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/8735ytaig8.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
committed by
Mark Brown
parent
4b260f4254
commit
dd5abc7834
@@ -1514,6 +1514,10 @@ unwind:
|
||||
static void dpcm_init_runtime_hw(struct snd_pcm_runtime *runtime,
|
||||
struct snd_soc_pcm_stream *stream)
|
||||
{
|
||||
runtime->hw.rates = stream->rates;
|
||||
|
||||
snd_pcm_limit_hw_rates(runtime);
|
||||
|
||||
runtime->hw.rate_min = stream->rate_min;
|
||||
runtime->hw.rate_max = min_not_zero(stream->rate_max, UINT_MAX);
|
||||
runtime->hw.channels_min = stream->channels_min;
|
||||
@@ -1522,7 +1526,6 @@ static void dpcm_init_runtime_hw(struct snd_pcm_runtime *runtime,
|
||||
runtime->hw.formats &= stream->formats;
|
||||
else
|
||||
runtime->hw.formats = stream->formats;
|
||||
runtime->hw.rates = stream->rates;
|
||||
}
|
||||
|
||||
static void dpcm_runtime_merge_format(struct snd_pcm_substream *substream,
|
||||
@@ -1648,9 +1651,12 @@ static void dpcm_runtime_merge_rate(struct snd_pcm_substream *substream,
|
||||
|
||||
pcm = snd_soc_dai_get_pcm_stream(dai, stream);
|
||||
|
||||
hw->rates = snd_pcm_rate_mask_intersect(hw->rates, pcm->rates);
|
||||
|
||||
snd_pcm_limit_hw_rates(runtime);
|
||||
|
||||
hw->rate_min = max(hw->rate_min, pcm->rate_min);
|
||||
hw->rate_max = min_not_zero(hw->rate_max, pcm->rate_max);
|
||||
hw->rates = snd_pcm_rate_mask_intersect(hw->rates, pcm->rates);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1738,7 +1744,6 @@ static int dpcm_apply_symmetry(struct snd_pcm_substream *fe_substream,
|
||||
static int dpcm_fe_dai_startup(struct snd_pcm_substream *fe_substream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *fe = asoc_substream_to_rtd(fe_substream);
|
||||
struct snd_pcm_runtime *runtime = fe_substream->runtime;
|
||||
int stream = fe_substream->stream, ret = 0;
|
||||
|
||||
dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_FE);
|
||||
@@ -1761,7 +1766,6 @@ static int dpcm_fe_dai_startup(struct snd_pcm_substream *fe_substream)
|
||||
fe->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN;
|
||||
|
||||
dpcm_set_fe_runtime(fe_substream);
|
||||
snd_pcm_limit_hw_rates(runtime);
|
||||
|
||||
ret = dpcm_apply_symmetry(fe_substream, stream);
|
||||
if (ret < 0)
|
||||
|
||||
Reference in New Issue
Block a user