aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/soc/codecs/wm8523.c26
-rw-r--r--sound/soc/codecs/wm8741.c61
2 files changed, 52 insertions, 35 deletions
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c
index 8c5b9df3e542..43ea8ae5f871 100644
--- a/sound/soc/codecs/wm8523.c
+++ b/sound/soc/codecs/wm8523.c
@@ -113,6 +113,15 @@ static struct {
113 { 7, 1152 }, 113 { 7, 1152 },
114}; 114};
115 115
116static struct {
117 int value;
118 int ratio;
119} bclk_ratios[WM8523_NUM_RATES] = {
120 { 2, 32 },
121 { 3, 64 },
122 { 4, 128 },
123};
124
116static int wm8523_startup(struct snd_pcm_substream *substream, 125static int wm8523_startup(struct snd_pcm_substream *substream,
117 struct snd_soc_dai *dai) 126 struct snd_soc_dai *dai)
118{ 127{
@@ -162,6 +171,23 @@ static int wm8523_hw_params(struct snd_pcm_substream *substream,
162 aifctrl2 &= ~WM8523_SR_MASK; 171 aifctrl2 &= ~WM8523_SR_MASK;
163 aifctrl2 |= lrclk_ratios[i].value; 172 aifctrl2 |= lrclk_ratios[i].value;
164 173
174 if (aifctrl1 & WM8523_AIF_MSTR) {
175 /* Find a fs->bclk ratio */
176 for (i = 0; i < ARRAY_SIZE(bclk_ratios); i++)
177 if (params_width(params) * 2 <= bclk_ratios[i].ratio)
178 break;
179
180 if (i == ARRAY_SIZE(bclk_ratios)) {
181 dev_err(codec->dev,
182 "No matching BCLK/fs ratio for word length %d\n",
183 params_width(params));
184 return -EINVAL;
185 }
186
187 aifctrl2 &= ~WM8523_BCLKDIV_MASK;
188 aifctrl2 |= bclk_ratios[i].value << WM8523_BCLKDIV_SHIFT;
189 }
190
165 aifctrl1 &= ~WM8523_WL_MASK; 191 aifctrl1 &= ~WM8523_WL_MASK;
166 switch (params_width(params)) { 192 switch (params_width(params)) {
167 case 16: 193 case 16:
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c
index 09ff01f2fc1e..b34623786e35 100644
--- a/sound/soc/codecs/wm8741.c
+++ b/sound/soc/codecs/wm8741.c
@@ -125,18 +125,6 @@ static const struct snd_soc_dapm_route wm8741_dapm_routes[] = {
125 { "VOUTRN", NULL, "DACR" }, 125 { "VOUTRN", NULL, "DACR" },
126}; 126};
127 127
128static struct {
129 int value;
130 int ratio;
131} lrclk_ratios[WM8741_NUM_RATES] = {
132 { 1, 128 },
133 { 2, 192 },
134 { 3, 256 },
135 { 4, 384 },
136 { 5, 512 },
137 { 6, 768 },
138};
139
140static const unsigned int rates_11289[] = { 128static const unsigned int rates_11289[] = {
141 44100, 88200, 129 44100, 88200,
142}; 130};
@@ -209,25 +197,16 @@ static const struct snd_pcm_hw_constraint_list constraints_36864 = {
209 .list = rates_36864, 197 .list = rates_36864,
210}; 198};
211 199
212
213static int wm8741_startup(struct snd_pcm_substream *substream, 200static int wm8741_startup(struct snd_pcm_substream *substream,
214 struct snd_soc_dai *dai) 201 struct snd_soc_dai *dai)
215{ 202{
216 struct snd_soc_codec *codec = dai->codec; 203 struct snd_soc_codec *codec = dai->codec;
217 struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec); 204 struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
218 205
219 /* The set of sample rates that can be supported depends on the 206 if (wm8741->sysclk)
220 * MCLK supplied to the CODEC - enforce this. 207 snd_pcm_hw_constraint_list(substream->runtime, 0,
221 */ 208 SNDRV_PCM_HW_PARAM_RATE,
222 if (!wm8741->sysclk) { 209 wm8741->sysclk_constraints);
223 dev_err(codec->dev,
224 "No MCLK configured, call set_sysclk() on init\n");
225 return -EINVAL;
226 }
227
228 snd_pcm_hw_constraint_list(substream->runtime, 0,
229 SNDRV_PCM_HW_PARAM_RATE,
230 wm8741->sysclk_constraints);
231 210
232 return 0; 211 return 0;
233} 212}
@@ -241,17 +220,24 @@ static int wm8741_hw_params(struct snd_pcm_substream *substream,
241 u16 iface = snd_soc_read(codec, WM8741_FORMAT_CONTROL) & 0x1FC; 220 u16 iface = snd_soc_read(codec, WM8741_FORMAT_CONTROL) & 0x1FC;
242 int i; 221 int i;
243 222
244 /* Find a supported LRCLK ratio */ 223 /* The set of sample rates that can be supported depends on the
245 for (i = 0; i < ARRAY_SIZE(lrclk_ratios); i++) { 224 * MCLK supplied to the CODEC - enforce this.
246 if (wm8741->sysclk / params_rate(params) == 225 */
247 lrclk_ratios[i].ratio) 226 if (!wm8741->sysclk) {
227 dev_err(codec->dev,
228 "No MCLK configured, call set_sysclk() on init or in hw_params\n");
229 return -EINVAL;
230 }
231
232 /* Find a supported LRCLK rate */
233 for (i = 0; i < wm8741->sysclk_constraints->count; i++) {
234 if (wm8741->sysclk_constraints->list[i] == params_rate(params))
248 break; 235 break;
249 } 236 }
250 237
251 /* Should never happen, should be handled by constraints */ 238 if (i == wm8741->sysclk_constraints->count) {
252 if (i == ARRAY_SIZE(lrclk_ratios)) { 239 dev_err(codec->dev, "LRCLK %d unsupported with MCLK %d\n",
253 dev_err(codec->dev, "MCLK/fs ratio %d unsupported\n", 240 params_rate(params), wm8741->sysclk);
254 wm8741->sysclk / params_rate(params));
255 return -EINVAL; 241 return -EINVAL;
256 } 242 }
257 243
@@ -274,8 +260,8 @@ static int wm8741_hw_params(struct snd_pcm_substream *substream,
274 return -EINVAL; 260 return -EINVAL;
275 } 261 }
276 262
277 dev_dbg(codec->dev, "wm8741_hw_params: bit size param = %d", 263 dev_dbg(codec->dev, "wm8741_hw_params: bit size param = %d, rate param = %d",
278 params_width(params)); 264 params_width(params), params_rate(params));
279 265
280 snd_soc_write(codec, WM8741_FORMAT_CONTROL, iface); 266 snd_soc_write(codec, WM8741_FORMAT_CONTROL, iface);
281 return 0; 267 return 0;
@@ -290,6 +276,11 @@ static int wm8741_set_dai_sysclk(struct snd_soc_dai *codec_dai,
290 dev_dbg(codec->dev, "wm8741_set_dai_sysclk info: freq=%dHz\n", freq); 276 dev_dbg(codec->dev, "wm8741_set_dai_sysclk info: freq=%dHz\n", freq);
291 277
292 switch (freq) { 278 switch (freq) {
279 case 0:
280 wm8741->sysclk_constraints = NULL;
281 wm8741->sysclk = freq;
282 return 0;
283
293 case 11289600: 284 case 11289600:
294 wm8741->sysclk_constraints = &constraints_11289; 285 wm8741->sysclk_constraints = &constraints_11289;
295 wm8741->sysclk = freq; 286 wm8741->sysclk = freq;