mirror of
https://github.com/torvalds/linux.git
synced 2026-09-23 22:14:03 +02:00
ASoC: meson: aiu-encoder-i2s: use the core symmetric_rate handling
The driver manually implement the interface-wide rate symmetry enforcement in hw_params(), which suffers from the same problem addressed in the previous patch: the restriction is not visible in the hw parameter constraints, so a stream with a mismatching rate only finds out via -EINVAL late in the stream setup. The ASoC core already provides this feature through the DAI's 'symmetric_rate' flag: when another stream of the DAI is active, soc_pcm_apply_symmetry() constrains the rate at open time so the restriction shows up during parameter refinement, and soc_pcm_params_symmetry() still rejects a mismatch at hw_params() time as a backstop. Set 'symmetric_rate' on the I2S encoder DAI and drop the open-coded check along with the now unused 'rate' member of struct gx_iface. Signed-off-by: Valerio Setti <vsetti@baylibre.com> Link: https://patch.msgid.link/20260710-aiu-improve-quirk-check-v1-3-2fdd1b6f8896@baylibre.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
df3c987ab3
commit
e82159384a
|
|
@ -179,28 +179,14 @@ static int aiu_encoder_i2s_hw_params(struct snd_pcm_substream *substream,
|
|||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct gx_stream *ts = snd_soc_dai_get_dma_data(dai, substream);
|
||||
struct gx_iface *iface = ts->iface;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Enforce interface wide rate symmetry only if there is more than
|
||||
* 1 stream active.
|
||||
*/
|
||||
if (snd_soc_dai_active(dai) > 1) {
|
||||
if (iface->rate && iface->rate != params_rate(params)) {
|
||||
dev_err(dai->dev, "can't set iface rate (%d != %d)\n",
|
||||
iface->rate, params_rate(params));
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
ret = aiu_encoder_i2s_set_clocks(substream, params, dai);
|
||||
if (ret) {
|
||||
dev_err(dai->dev, "setting i2s clocks failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
iface->rate = params_rate(params);
|
||||
ts->physical_width = params_physical_width(params);
|
||||
ts->width = params_width(params);
|
||||
ts->channels = params_channels(params);
|
||||
|
|
@ -233,17 +219,14 @@ static int aiu_encoder_i2s_hw_free(struct snd_pcm_substream *substream,
|
|||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct gx_stream *ts = snd_soc_dai_get_dma_data(dai, substream);
|
||||
struct gx_iface *iface = ts->iface;
|
||||
struct snd_soc_component *component = dai->component;
|
||||
|
||||
/*
|
||||
* If this is the last substream being closed then disable the i2s
|
||||
* clock divider and clear 'iface->rate'.
|
||||
* clock divider.
|
||||
*/
|
||||
if (snd_soc_dai_active(dai) <= 1) {
|
||||
if (snd_soc_dai_active(dai) <= 1)
|
||||
aiu_encoder_i2s_divider_enable(component, 0);
|
||||
iface->rate = 0;
|
||||
}
|
||||
|
||||
if (ts->clk_enabled) {
|
||||
clk_disable_unprepare(ts->iface->mclk);
|
||||
|
|
|
|||
|
|
@ -154,6 +154,7 @@ static struct snd_soc_dai_driver aiu_cpu_dai_drv[] = {
|
|||
.formats = AIU_FORMATS,
|
||||
},
|
||||
.ops = &aiu_encoder_i2s_dai_ops,
|
||||
.symmetric_rate = 1,
|
||||
},
|
||||
[CPU_SPDIF_ENCODER] = {
|
||||
.name = "SPDIF Encoder",
|
||||
|
|
|
|||
|
|
@ -19,9 +19,6 @@ struct gx_iface {
|
|||
|
||||
/* format is common to all the DAIs of the iface */
|
||||
unsigned int fmt;
|
||||
|
||||
/* For component wide symmetry */
|
||||
int rate;
|
||||
};
|
||||
|
||||
struct gx_stream {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user