Skip to content

Commit 17cc308

Browse files
TE-N-ShengjiuWangbroonie
authored andcommitted
ASoC: wm8524: enable constraints when sysclk is configured.
In some cases, the sysclk won't be configured on init, and sysclk can be changed in hw_params() according to different sample rate, for example, for 44kHz sample rate, the sysclk is 11.2896MHz, for 48kHz sample rate, the sysclk is 12.288MHz. In order to support the above case, only enable constraints when sysclk is configured, and check the rate in hw_params. So overall there are three cases that need to be considered: - call set_sysclk() on init, then constraints will be initialized. - don't call set_sysclk() on init, but call it after startup(), then constraints will be configured, the constraints can be cleared with call set_sysclk() again in shutdown(). - don't call set_sysclk() in the whole flow, then there are no any constraints. The clocks depend on cpu dai. Enlarge the WM8524_NUM_RATES to 12, as the supported rate range is 8kHz to 192kHz. Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com> Reviewed-by: Charles Keepax <ckeepax@opensource.cirrus.com> Link: https://patch.msgid.link/20250620021403.624303-1-shengjiu.wang@nxp.com Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent c4ca928 commit 17cc308

1 file changed

Lines changed: 42 additions & 13 deletions

File tree

sound/soc/codecs/wm8524.c

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
#include <sound/soc.h>
2222
#include <sound/initval.h>
2323

24-
#define WM8524_NUM_RATES 7
24+
#define WM8524_NUM_RATES 12
2525

2626
/* codec private data */
2727
struct wm8524_priv {
@@ -46,7 +46,7 @@ static const struct snd_soc_dapm_route wm8524_dapm_routes[] = {
4646
static const struct {
4747
int value;
4848
int ratio;
49-
} lrclk_ratios[WM8524_NUM_RATES] = {
49+
} lrclk_ratios[] = {
5050
{ 1, 128 },
5151
{ 2, 192 },
5252
{ 3, 256 },
@@ -63,17 +63,12 @@ static int wm8524_startup(struct snd_pcm_substream *substream,
6363
struct wm8524_priv *wm8524 = snd_soc_component_get_drvdata(component);
6464

6565
/* The set of sample rates that can be supported depends on the
66-
* MCLK supplied to the CODEC - enforce this.
66+
* MCLK supplied to the CODEC.
6767
*/
68-
if (!wm8524->sysclk) {
69-
dev_err(component->dev,
70-
"No MCLK configured, call set_sysclk() on init\n");
71-
return -EINVAL;
72-
}
73-
74-
snd_pcm_hw_constraint_list(substream->runtime, 0,
75-
SNDRV_PCM_HW_PARAM_RATE,
76-
&wm8524->rate_constraint);
68+
if (wm8524->sysclk)
69+
snd_pcm_hw_constraint_list(substream->runtime, 0,
70+
SNDRV_PCM_HW_PARAM_RATE,
71+
&wm8524->rate_constraint);
7772

7873
gpiod_set_value_cansleep(wm8524->mute, 1);
7974

@@ -97,9 +92,11 @@ static int wm8524_set_dai_sysclk(struct snd_soc_dai *codec_dai,
9792
unsigned int val;
9893
int i, j = 0;
9994

95+
wm8524->rate_constraint.count = 0;
10096
wm8524->sysclk = freq;
97+
if (!wm8524->sysclk)
98+
return 0;
10199

102-
wm8524->rate_constraint.count = 0;
103100
for (i = 0; i < ARRAY_SIZE(lrclk_ratios); i++) {
104101
val = freq / lrclk_ratios[i].ratio;
105102
/* Check that it's a standard rate since core can't
@@ -108,9 +105,13 @@ static int wm8524_set_dai_sysclk(struct snd_soc_dai *codec_dai,
108105
*/
109106
switch (val) {
110107
case 8000:
108+
case 11025:
109+
case 16000:
110+
case 22050:
111111
case 32000:
112112
case 44100:
113113
case 48000:
114+
case 64000:
114115
case 88200:
115116
case 96000:
116117
case 176400:
@@ -157,6 +158,33 @@ static int wm8524_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
157158
return 0;
158159
}
159160

161+
static int wm8524_hw_params(struct snd_pcm_substream *substream,
162+
struct snd_pcm_hw_params *params,
163+
struct snd_soc_dai *dai)
164+
{
165+
struct snd_soc_component *component = dai->component;
166+
struct wm8524_priv *wm8524 = snd_soc_component_get_drvdata(component);
167+
int i;
168+
169+
/* If sysclk is not configured, no need to check the rate */
170+
if (!wm8524->sysclk)
171+
return 0;
172+
173+
/* Find a supported LRCLK rate */
174+
for (i = 0; i < wm8524->rate_constraint.count; i++) {
175+
if (wm8524->rate_constraint.list[i] == params_rate(params))
176+
break;
177+
}
178+
179+
if (i == wm8524->rate_constraint.count) {
180+
dev_err(component->dev, "LRCLK %d unsupported with MCLK %d\n",
181+
params_rate(params), wm8524->sysclk);
182+
return -EINVAL;
183+
}
184+
185+
return 0;
186+
}
187+
160188
#define WM8524_RATES SNDRV_PCM_RATE_8000_192000
161189

162190
#define WM8524_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
@@ -169,6 +197,7 @@ static const struct snd_soc_dai_ops wm8524_dai_ops = {
169197
.set_sysclk = wm8524_set_dai_sysclk,
170198
.set_fmt = wm8524_set_fmt,
171199
.mute_stream = wm8524_mute_stream,
200+
.hw_params = wm8524_hw_params,
172201
};
173202

174203
static struct snd_soc_dai_driver wm8524_dai = {

0 commit comments

Comments
 (0)