diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-08-08 12:52:44 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-08-09 14:34:28 -0400 |
commit | cbd840dadeb03826b6cc074e38f380bbd4faaea5 (patch) | |
tree | e5de2e23bdd6afc14a6b9168f1fd5acdb3f02009 /sound/soc/codecs | |
parent | 28d528c8dbab5c6b3cf2fc4f0e91470a9a63dbc0 (diff) |
ASoC: arizona: Implement OPCLK support
Arizona devices support two output system clocks. Provide support for
configuring these via set_sysclk(). Once the clock API is more useful
we should migrate over to that.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/codecs')
-rw-r--r-- | sound/soc/codecs/arizona.c | 66 | ||||
-rw-r--r-- | sound/soc/codecs/arizona.h | 6 |
2 files changed, 70 insertions, 2 deletions
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 5c9cacaf2d52..5e96a0a1669c 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c | |||
@@ -229,6 +229,69 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w, | |||
229 | } | 229 | } |
230 | EXPORT_SYMBOL_GPL(arizona_out_ev); | 230 | EXPORT_SYMBOL_GPL(arizona_out_ev); |
231 | 231 | ||
232 | static unsigned int arizona_sysclk_48k_rates[] = { | ||
233 | 6144000, | ||
234 | 12288000, | ||
235 | 22579200, | ||
236 | 49152000, | ||
237 | }; | ||
238 | |||
239 | static unsigned int arizona_sysclk_44k1_rates[] = { | ||
240 | 5644800, | ||
241 | 11289600, | ||
242 | 24576000, | ||
243 | 45158400, | ||
244 | }; | ||
245 | |||
246 | static int arizona_set_opclk(struct snd_soc_codec *codec, unsigned int clk, | ||
247 | unsigned int freq) | ||
248 | { | ||
249 | struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); | ||
250 | unsigned int reg; | ||
251 | unsigned int *rates; | ||
252 | int ref, div, refclk; | ||
253 | |||
254 | switch (clk) { | ||
255 | case ARIZONA_CLK_OPCLK: | ||
256 | reg = ARIZONA_OUTPUT_SYSTEM_CLOCK; | ||
257 | refclk = priv->sysclk; | ||
258 | break; | ||
259 | case ARIZONA_CLK_ASYNC_OPCLK: | ||
260 | reg = ARIZONA_OUTPUT_ASYNC_CLOCK; | ||
261 | refclk = priv->asyncclk; | ||
262 | break; | ||
263 | default: | ||
264 | return -EINVAL; | ||
265 | } | ||
266 | |||
267 | if (refclk % 8000) | ||
268 | rates = arizona_sysclk_44k1_rates; | ||
269 | else | ||
270 | rates = arizona_sysclk_48k_rates; | ||
271 | |||
272 | for (ref = 0; ref < ARRAY_SIZE(arizona_sysclk_48k_rates) && | ||
273 | rates[ref] <= refclk; ref++) { | ||
274 | div = 1; | ||
275 | while (rates[ref] / div >= freq && div < 32) { | ||
276 | if (rates[ref] / div == freq) { | ||
277 | dev_dbg(codec->dev, "Configured %dHz OPCLK\n", | ||
278 | freq); | ||
279 | snd_soc_update_bits(codec, reg, | ||
280 | ARIZONA_OPCLK_DIV_MASK | | ||
281 | ARIZONA_OPCLK_SEL_MASK, | ||
282 | (div << | ||
283 | ARIZONA_OPCLK_DIV_SHIFT) | | ||
284 | ref); | ||
285 | return 0; | ||
286 | } | ||
287 | div++; | ||
288 | } | ||
289 | } | ||
290 | |||
291 | dev_err(codec->dev, "Unable to generate %dHz OPCLK\n", freq); | ||
292 | return -EINVAL; | ||
293 | } | ||
294 | |||
232 | int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id, | 295 | int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id, |
233 | int source, unsigned int freq, int dir) | 296 | int source, unsigned int freq, int dir) |
234 | { | 297 | { |
@@ -252,6 +315,9 @@ int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id, | |||
252 | reg = ARIZONA_ASYNC_CLOCK_1; | 315 | reg = ARIZONA_ASYNC_CLOCK_1; |
253 | clk = &priv->asyncclk; | 316 | clk = &priv->asyncclk; |
254 | break; | 317 | break; |
318 | case ARIZONA_CLK_OPCLK: | ||
319 | case ARIZONA_CLK_ASYNC_OPCLK: | ||
320 | return arizona_set_opclk(codec, clk_id, freq); | ||
255 | default: | 321 | default: |
256 | return -EINVAL; | 322 | return -EINVAL; |
257 | } | 323 | } |
diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h index 59caca8865e8..eb66b52777c9 100644 --- a/sound/soc/codecs/arizona.h +++ b/sound/soc/codecs/arizona.h | |||
@@ -17,8 +17,10 @@ | |||
17 | 17 | ||
18 | #include <sound/soc.h> | 18 | #include <sound/soc.h> |
19 | 19 | ||
20 | #define ARIZONA_CLK_SYSCLK 1 | 20 | #define ARIZONA_CLK_SYSCLK 1 |
21 | #define ARIZONA_CLK_ASYNCCLK 2 | 21 | #define ARIZONA_CLK_ASYNCCLK 2 |
22 | #define ARIZONA_CLK_OPCLK 3 | ||
23 | #define ARIZONA_CLK_ASYNC_OPCLK 4 | ||
22 | 24 | ||
23 | #define ARIZONA_CLK_SRC_MCLK1 0x0 | 25 | #define ARIZONA_CLK_SRC_MCLK1 0x0 |
24 | #define ARIZONA_CLK_SRC_MCLK2 0x1 | 26 | #define ARIZONA_CLK_SRC_MCLK2 0x1 |