diff options
author | Ian Lartey <ian@opensource.wolfsonmicro.com> | 2010-08-27 10:26:27 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-08-28 04:46:42 -0400 |
commit | 3fe4a5ee9c312b7652cc92715ee30d3760b83e5b (patch) | |
tree | f70a02e8d8981adb1a908b86b93c6bd58a2371b9 | |
parent | 7eba6c05c5075f885f0b26244e1fdac76355f562 (diff) |
ASoC: Complete supported clock ratios and rate constraints for wm8741
Signed-off-by: Ian Lartey <ian@opensource.wolfsonmicro.com>
Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r-- | sound/soc/codecs/wm8741.c | 175 |
1 files changed, 124 insertions, 51 deletions
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c index fdd24da89a1e..c8e7a264bbae 100644 --- a/sound/soc/codecs/wm8741.c +++ b/sound/soc/codecs/wm8741.c | |||
@@ -36,7 +36,7 @@ static const char *wm8741_supply_names[WM8741_NUM_SUPPLIES] = { | |||
36 | "DVDD", | 36 | "DVDD", |
37 | }; | 37 | }; |
38 | 38 | ||
39 | #define WM8741_NUM_RATES 4 | 39 | #define WM8741_NUM_RATES 6 |
40 | 40 | ||
41 | /* codec private data */ | 41 | /* codec private data */ |
42 | struct wm8741_priv { | 42 | struct wm8741_priv { |
@@ -44,8 +44,7 @@ struct wm8741_priv { | |||
44 | u16 reg_cache[WM8741_REGISTER_COUNT]; | 44 | u16 reg_cache[WM8741_REGISTER_COUNT]; |
45 | struct regulator_bulk_data supplies[WM8741_NUM_SUPPLIES]; | 45 | struct regulator_bulk_data supplies[WM8741_NUM_SUPPLIES]; |
46 | unsigned int sysclk; | 46 | unsigned int sysclk; |
47 | unsigned int rate_constraint_list[WM8741_NUM_RATES]; | 47 | struct snd_pcm_hw_constraint_list *sysclk_constraints; |
48 | struct snd_pcm_hw_constraint_list rate_constraint; | ||
49 | }; | 48 | }; |
50 | 49 | ||
51 | static const u16 wm8741_reg_defaults[WM8741_REGISTER_COUNT] = { | 50 | static const u16 wm8741_reg_defaults[WM8741_REGISTER_COUNT] = { |
@@ -108,10 +107,84 @@ static struct { | |||
108 | int value; | 107 | int value; |
109 | int ratio; | 108 | int ratio; |
110 | } lrclk_ratios[WM8741_NUM_RATES] = { | 109 | } lrclk_ratios[WM8741_NUM_RATES] = { |
111 | { 1, 256 }, | 110 | { 1, 128 }, |
112 | { 2, 384 }, | 111 | { 2, 192 }, |
113 | { 3, 512 }, | 112 | { 3, 256 }, |
114 | { 4, 768 }, | 113 | { 4, 384 }, |
114 | { 5, 512 }, | ||
115 | { 6, 768 }, | ||
116 | }; | ||
117 | |||
118 | static unsigned int rates_11289[] = { | ||
119 | 44100, 88235, | ||
120 | }; | ||
121 | |||
122 | static struct snd_pcm_hw_constraint_list constraints_11289 = { | ||
123 | .count = ARRAY_SIZE(rates_11289), | ||
124 | .list = rates_11289, | ||
125 | }; | ||
126 | |||
127 | static unsigned int rates_12288[] = { | ||
128 | 32000, 48000, 96000, | ||
129 | }; | ||
130 | |||
131 | static struct snd_pcm_hw_constraint_list constraints_12288 = { | ||
132 | .count = ARRAY_SIZE(rates_12288), | ||
133 | .list = rates_12288, | ||
134 | }; | ||
135 | |||
136 | static unsigned int rates_16384[] = { | ||
137 | 32000, | ||
138 | }; | ||
139 | |||
140 | static struct snd_pcm_hw_constraint_list constraints_16384 = { | ||
141 | .count = ARRAY_SIZE(rates_16384), | ||
142 | .list = rates_16384, | ||
143 | }; | ||
144 | |||
145 | static unsigned int rates_16934[] = { | ||
146 | 44100, 88235, | ||
147 | }; | ||
148 | |||
149 | static struct snd_pcm_hw_constraint_list constraints_16934 = { | ||
150 | .count = ARRAY_SIZE(rates_16934), | ||
151 | .list = rates_16934, | ||
152 | }; | ||
153 | |||
154 | static unsigned int rates_18432[] = { | ||
155 | 48000, 96000, | ||
156 | }; | ||
157 | |||
158 | static struct snd_pcm_hw_constraint_list constraints_18432 = { | ||
159 | .count = ARRAY_SIZE(rates_18432), | ||
160 | .list = rates_18432, | ||
161 | }; | ||
162 | |||
163 | static unsigned int rates_22579[] = { | ||
164 | 44100, 88235, 1764000 | ||
165 | }; | ||
166 | |||
167 | static struct snd_pcm_hw_constraint_list constraints_22579 = { | ||
168 | .count = ARRAY_SIZE(rates_22579), | ||
169 | .list = rates_22579, | ||
170 | }; | ||
171 | |||
172 | static unsigned int rates_24576[] = { | ||
173 | 32000, 48000, 96000, 192000 | ||
174 | }; | ||
175 | |||
176 | static struct snd_pcm_hw_constraint_list constraints_24576 = { | ||
177 | .count = ARRAY_SIZE(rates_24576), | ||
178 | .list = rates_24576, | ||
179 | }; | ||
180 | |||
181 | static unsigned int rates_36864[] = { | ||
182 | 48000, 96000, 19200 | ||
183 | }; | ||
184 | |||
185 | static struct snd_pcm_hw_constraint_list constraints_36864 = { | ||
186 | .count = ARRAY_SIZE(rates_36864), | ||
187 | .list = rates_36864, | ||
115 | }; | 188 | }; |
116 | 189 | ||
117 | 190 | ||
@@ -132,7 +205,7 @@ static int wm8741_startup(struct snd_pcm_substream *substream, | |||
132 | 205 | ||
133 | snd_pcm_hw_constraint_list(substream->runtime, 0, | 206 | snd_pcm_hw_constraint_list(substream->runtime, 0, |
134 | SNDRV_PCM_HW_PARAM_RATE, | 207 | SNDRV_PCM_HW_PARAM_RATE, |
135 | &wm8741->rate_constraint); | 208 | wm8741->sysclk_constraints); |
136 | 209 | ||
137 | return 0; | 210 | return 0; |
138 | } | 211 | } |
@@ -192,47 +265,52 @@ static int wm8741_set_dai_sysclk(struct snd_soc_dai *codec_dai, | |||
192 | { | 265 | { |
193 | struct snd_soc_codec *codec = codec_dai->codec; | 266 | struct snd_soc_codec *codec = codec_dai->codec; |
194 | struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec); | 267 | struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec); |
195 | unsigned int val; | ||
196 | int i; | ||
197 | 268 | ||
198 | dev_dbg(codec->dev, "wm8741_set_dai_sysclk info: freq=%dHz\n", freq); | 269 | dev_dbg(codec->dev, "wm8741_set_dai_sysclk info: freq=%dHz\n", freq); |
199 | 270 | ||
200 | wm8741->sysclk = freq; | 271 | switch (freq) { |
201 | 272 | case 11289600: | |
202 | wm8741->rate_constraint.count = 0; | 273 | wm8741->sysclk_constraints = &constraints_11289; |
203 | 274 | wm8741->sysclk = freq; | |
204 | for (i = 0; i < ARRAY_SIZE(lrclk_ratios); i++) { | 275 | return 0; |
205 | dev_dbg(codec->dev, "index = %d, ratio = %d, freq = %d", | 276 | |
206 | i, lrclk_ratios[i].ratio, freq); | 277 | case 12288000: |
207 | 278 | wm8741->sysclk_constraints = &constraints_12288; | |
208 | val = freq / lrclk_ratios[i].ratio; | 279 | wm8741->sysclk = freq; |
209 | /* Check that it's a standard rate since core can't | 280 | return 0; |
210 | * cope with others and having the odd rates confuses | 281 | |
211 | * constraint matching. | 282 | case 16384000: |
212 | */ | 283 | wm8741->sysclk_constraints = &constraints_16384; |
213 | switch (val) { | 284 | wm8741->sysclk = freq; |
214 | case 32000: | 285 | return 0; |
215 | case 44100: | 286 | |
216 | case 48000: | 287 | case 16934400: |
217 | case 64000: | 288 | wm8741->sysclk_constraints = &constraints_16934; |
218 | case 88200: | 289 | wm8741->sysclk = freq; |
219 | case 96000: | 290 | return 0; |
220 | dev_dbg(codec->dev, "Supported sample rate: %dHz\n", | 291 | |
221 | val); | 292 | case 18432000: |
222 | wm8741->rate_constraint_list[i] = val; | 293 | wm8741->sysclk_constraints = &constraints_18432; |
223 | wm8741->rate_constraint.count++; | 294 | wm8741->sysclk = freq; |
224 | break; | 295 | return 0; |
225 | default: | 296 | |
226 | dev_dbg(codec->dev, "Skipping sample rate: %dHz\n", | 297 | case 22579200: |
227 | val); | 298 | case 33868800: |
228 | } | 299 | wm8741->sysclk_constraints = &constraints_22579; |
300 | wm8741->sysclk = freq; | ||
301 | return 0; | ||
302 | |||
303 | case 24576000: | ||
304 | wm8741->sysclk_constraints = &constraints_24576; | ||
305 | wm8741->sysclk = freq; | ||
306 | return 0; | ||
307 | |||
308 | case 36864000: | ||
309 | wm8741->sysclk_constraints = &constraints_36864; | ||
310 | wm8741->sysclk = freq; | ||
311 | return 0; | ||
229 | } | 312 | } |
230 | 313 | return -EINVAL; | |
231 | /* Need at least one supported rate... */ | ||
232 | if (wm8741->rate_constraint.count == 0) | ||
233 | return -EINVAL; | ||
234 | |||
235 | return 0; | ||
236 | } | 314 | } |
237 | 315 | ||
238 | static int wm8741_set_dai_fmt(struct snd_soc_dai *codec_dai, | 316 | static int wm8741_set_dai_fmt(struct snd_soc_dai *codec_dai, |
@@ -391,10 +469,6 @@ static int wm8741_i2c_probe(struct i2c_client *i2c, | |||
391 | if (wm8741 == NULL) | 469 | if (wm8741 == NULL) |
392 | return -ENOMEM; | 470 | return -ENOMEM; |
393 | 471 | ||
394 | wm8741->rate_constraint.list = &wm8741->rate_constraint_list[0]; | ||
395 | wm8741->rate_constraint.count = | ||
396 | ARRAY_SIZE(wm8741->rate_constraint_list); | ||
397 | |||
398 | for (i = 0; i < ARRAY_SIZE(wm8741->supplies); i++) | 472 | for (i = 0; i < ARRAY_SIZE(wm8741->supplies); i++) |
399 | wm8741->supplies[i].supply = wm8741_supply_names[i]; | 473 | wm8741->supplies[i].supply = wm8741_supply_names[i]; |
400 | 474 | ||
@@ -464,9 +538,8 @@ static int __init wm8741_modinit(void) | |||
464 | 538 | ||
465 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 539 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
466 | ret = i2c_add_driver(&wm8741_i2c_driver); | 540 | ret = i2c_add_driver(&wm8741_i2c_driver); |
467 | if (ret != 0) { | 541 | if (ret != 0) |
468 | pr_err("Failed to register WM8741 I2C driver: %d\n", ret); | 542 | pr_err("Failed to register WM8741 I2C driver: %d\n", ret); |
469 | } | ||
470 | #endif | 543 | #endif |
471 | 544 | ||
472 | return ret; | 545 | return ret; |