diff options
-rw-r--r-- | sound/soc/codecs/wm8523.c | 26 | ||||
-rw-r--r-- | sound/soc/codecs/wm8741.c | 61 |
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 | ||
116 | static struct { | ||
117 | int value; | ||
118 | int ratio; | ||
119 | } bclk_ratios[WM8523_NUM_RATES] = { | ||
120 | { 2, 32 }, | ||
121 | { 3, 64 }, | ||
122 | { 4, 128 }, | ||
123 | }; | ||
124 | |||
116 | static int wm8523_startup(struct snd_pcm_substream *substream, | 125 | static 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 | ||
128 | static 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 | |||
140 | static const unsigned int rates_11289[] = { | 128 | static 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 | |||
213 | static int wm8741_startup(struct snd_pcm_substream *substream, | 200 | static 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; |