Commit 3a5d89a9 authored by Richard Fitzgerald's avatar Richard Fitzgerald Committed by Mark Brown

ASoC: cs42l42: Constrain sample rate to prevent illegal SCLK

The lowest valid SCLK corresponds to 44.1 kHz at 16-bit. Sample
rates less than this would produce SCLK below the minimum when using
a normal I2S frame. A constraint must be applied to prevent this.

The constraint is not applied if the machine driver sets SCLK, to
allow setups where the host generates additional bits per LRCLK
phase to increase the SCLK frequency. In these cases the machine
driver would always have to inform this driver of the actual SCLK,
and it must select a legal SCLK.
Signed-off-by: default avatarRichard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20210805161111.10410-3-rf@opensource.cirrus.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent 0c2f2ad4
...@@ -807,6 +807,25 @@ static int cs42l42_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) ...@@ -807,6 +807,25 @@ static int cs42l42_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
return 0; return 0;
} }
static int cs42l42_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
{
struct snd_soc_component *component = dai->component;
struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component);
/*
* Sample rates < 44.1 kHz would produce an out-of-range SCLK with
* a standard I2S frame. If the machine driver sets SCLK it must be
* legal.
*/
if (cs42l42->sclk)
return 0;
/* Machine driver has not set a SCLK, limit bottom end to 44.1 kHz */
return snd_pcm_hw_constraint_minmax(substream->runtime,
SNDRV_PCM_HW_PARAM_RATE,
44100, 192000);
}
static int cs42l42_pcm_hw_params(struct snd_pcm_substream *substream, static int cs42l42_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params, struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai) struct snd_soc_dai *dai)
...@@ -966,8 +985,8 @@ static int cs42l42_mute_stream(struct snd_soc_dai *dai, int mute, int stream) ...@@ -966,8 +985,8 @@ static int cs42l42_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
SNDRV_PCM_FMTBIT_S24_LE |\ SNDRV_PCM_FMTBIT_S24_LE |\
SNDRV_PCM_FMTBIT_S32_LE ) SNDRV_PCM_FMTBIT_S32_LE )
static const struct snd_soc_dai_ops cs42l42_ops = { static const struct snd_soc_dai_ops cs42l42_ops = {
.startup = cs42l42_dai_startup,
.hw_params = cs42l42_pcm_hw_params, .hw_params = cs42l42_pcm_hw_params,
.set_fmt = cs42l42_set_dai_fmt, .set_fmt = cs42l42_set_dai_fmt,
.set_sysclk = cs42l42_set_sysclk, .set_sysclk = cs42l42_set_sysclk,
......
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