Commit dd5abc78 authored by Kuninori Morimoto's avatar Kuninori Morimoto Committed by Mark Brown

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.comSigned-off-by: default avatarKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/8735ytaig8.wl-kuninori.morimoto.gx@renesas.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent 4b260f42
...@@ -1514,6 +1514,10 @@ int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream) ...@@ -1514,6 +1514,10 @@ int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream)
static void dpcm_init_runtime_hw(struct snd_pcm_runtime *runtime, static void dpcm_init_runtime_hw(struct snd_pcm_runtime *runtime,
struct snd_soc_pcm_stream *stream) 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_min = stream->rate_min;
runtime->hw.rate_max = min_not_zero(stream->rate_max, UINT_MAX); runtime->hw.rate_max = min_not_zero(stream->rate_max, UINT_MAX);
runtime->hw.channels_min = stream->channels_min; runtime->hw.channels_min = stream->channels_min;
...@@ -1522,7 +1526,6 @@ static void dpcm_init_runtime_hw(struct snd_pcm_runtime *runtime, ...@@ -1522,7 +1526,6 @@ static void dpcm_init_runtime_hw(struct snd_pcm_runtime *runtime,
runtime->hw.formats &= stream->formats; runtime->hw.formats &= stream->formats;
else else
runtime->hw.formats = stream->formats; runtime->hw.formats = stream->formats;
runtime->hw.rates = stream->rates;
} }
static void dpcm_runtime_merge_format(struct snd_pcm_substream *substream, 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, ...@@ -1648,9 +1651,12 @@ static void dpcm_runtime_merge_rate(struct snd_pcm_substream *substream,
pcm = snd_soc_dai_get_pcm_stream(dai, stream); 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_min = max(hw->rate_min, pcm->rate_min);
hw->rate_max = min_not_zero(hw->rate_max, pcm->rate_max); 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, ...@@ -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) 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_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; int stream = fe_substream->stream, ret = 0;
dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_FE); 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) ...@@ -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; fe->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN;
dpcm_set_fe_runtime(fe_substream); dpcm_set_fe_runtime(fe_substream);
snd_pcm_limit_hw_rates(runtime);
ret = dpcm_apply_symmetry(fe_substream, stream); ret = dpcm_apply_symmetry(fe_substream, stream);
if (ret < 0) if (ret < 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment