diff options
Diffstat (limited to 'sound/soc/jz4740/jz4740-i2s.c')
-rw-r--r-- | sound/soc/jz4740/jz4740-i2s.c | 107 |
1 files changed, 52 insertions, 55 deletions
diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c index eb518f0c5e01..cd22a54b2f14 100644 --- a/sound/soc/jz4740/jz4740-i2s.c +++ b/sound/soc/jz4740/jz4740-i2s.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <sound/pcm.h> | 28 | #include <sound/pcm.h> |
29 | #include <sound/pcm_params.h> | 29 | #include <sound/pcm_params.h> |
30 | #include <sound/soc.h> | 30 | #include <sound/soc.h> |
31 | #include <sound/soc-dapm.h> | ||
32 | #include <sound/initval.h> | 31 | #include <sound/initval.h> |
33 | 32 | ||
34 | #include "jz4740-i2s.h" | 33 | #include "jz4740-i2s.h" |
@@ -106,15 +105,10 @@ static inline void jz4740_i2s_write(const struct jz4740_i2s *i2s, | |||
106 | writel(value, i2s->base + reg); | 105 | writel(value, i2s->base + reg); |
107 | } | 106 | } |
108 | 107 | ||
109 | static inline struct jz4740_i2s *jz4740_dai_to_i2s(struct snd_soc_dai *dai) | ||
110 | { | ||
111 | return dai->private_data; | ||
112 | } | ||
113 | |||
114 | static int jz4740_i2s_startup(struct snd_pcm_substream *substream, | 108 | static int jz4740_i2s_startup(struct snd_pcm_substream *substream, |
115 | struct snd_soc_dai *dai) | 109 | struct snd_soc_dai *dai) |
116 | { | 110 | { |
117 | struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai); | 111 | struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); |
118 | uint32_t conf, ctrl; | 112 | uint32_t conf, ctrl; |
119 | 113 | ||
120 | if (dai->active) | 114 | if (dai->active) |
@@ -136,10 +130,10 @@ static int jz4740_i2s_startup(struct snd_pcm_substream *substream, | |||
136 | static void jz4740_i2s_shutdown(struct snd_pcm_substream *substream, | 130 | static void jz4740_i2s_shutdown(struct snd_pcm_substream *substream, |
137 | struct snd_soc_dai *dai) | 131 | struct snd_soc_dai *dai) |
138 | { | 132 | { |
139 | struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai); | 133 | struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); |
140 | uint32_t conf; | 134 | uint32_t conf; |
141 | 135 | ||
142 | if (!dai->active) | 136 | if (dai->active) |
143 | return; | 137 | return; |
144 | 138 | ||
145 | conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF); | 139 | conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF); |
@@ -152,7 +146,7 @@ static void jz4740_i2s_shutdown(struct snd_pcm_substream *substream, | |||
152 | static int jz4740_i2s_trigger(struct snd_pcm_substream *substream, int cmd, | 146 | static int jz4740_i2s_trigger(struct snd_pcm_substream *substream, int cmd, |
153 | struct snd_soc_dai *dai) | 147 | struct snd_soc_dai *dai) |
154 | { | 148 | { |
155 | struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai); | 149 | struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); |
156 | 150 | ||
157 | uint32_t ctrl; | 151 | uint32_t ctrl; |
158 | uint32_t mask; | 152 | uint32_t mask; |
@@ -186,7 +180,7 @@ static int jz4740_i2s_trigger(struct snd_pcm_substream *substream, int cmd, | |||
186 | 180 | ||
187 | static int jz4740_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | 181 | static int jz4740_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) |
188 | { | 182 | { |
189 | struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai); | 183 | struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); |
190 | 184 | ||
191 | uint32_t format = 0; | 185 | uint32_t format = 0; |
192 | uint32_t conf; | 186 | uint32_t conf; |
@@ -238,7 +232,7 @@ static int jz4740_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | |||
238 | static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream, | 232 | static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream, |
239 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) | 233 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) |
240 | { | 234 | { |
241 | struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai); | 235 | struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); |
242 | enum jz4740_dma_width dma_width; | 236 | enum jz4740_dma_width dma_width; |
243 | struct jz4740_pcm_config *pcm_config; | 237 | struct jz4740_pcm_config *pcm_config; |
244 | unsigned int sample_size; | 238 | unsigned int sample_size; |
@@ -288,7 +282,7 @@ static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream, | |||
288 | static int jz4740_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id, | 282 | static int jz4740_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id, |
289 | unsigned int freq, int dir) | 283 | unsigned int freq, int dir) |
290 | { | 284 | { |
291 | struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai); | 285 | struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); |
292 | struct clk *parent; | 286 | struct clk *parent; |
293 | int ret = 0; | 287 | int ret = 0; |
294 | 288 | ||
@@ -312,7 +306,7 @@ static int jz4740_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id, | |||
312 | 306 | ||
313 | static int jz4740_i2s_suspend(struct snd_soc_dai *dai) | 307 | static int jz4740_i2s_suspend(struct snd_soc_dai *dai) |
314 | { | 308 | { |
315 | struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai); | 309 | struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); |
316 | uint32_t conf; | 310 | uint32_t conf; |
317 | 311 | ||
318 | if (dai->active) { | 312 | if (dai->active) { |
@@ -330,7 +324,7 @@ static int jz4740_i2s_suspend(struct snd_soc_dai *dai) | |||
330 | 324 | ||
331 | static int jz4740_i2s_resume(struct snd_soc_dai *dai) | 325 | static int jz4740_i2s_resume(struct snd_soc_dai *dai) |
332 | { | 326 | { |
333 | struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai); | 327 | struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); |
334 | uint32_t conf; | 328 | uint32_t conf; |
335 | 329 | ||
336 | clk_enable(i2s->clk_aic); | 330 | clk_enable(i2s->clk_aic); |
@@ -346,11 +340,38 @@ static int jz4740_i2s_resume(struct snd_soc_dai *dai) | |||
346 | return 0; | 340 | return 0; |
347 | } | 341 | } |
348 | 342 | ||
349 | static int jz4740_i2s_probe(struct platform_device *pdev, struct snd_soc_dai *dai) | 343 | static void jz4740_i2c_init_pcm_config(struct jz4740_i2s *i2s) |
344 | { | ||
345 | struct jz4740_dma_config *dma_config; | ||
346 | |||
347 | /* Playback */ | ||
348 | dma_config = &i2s->pcm_config_playback.dma_config; | ||
349 | dma_config->src_width = JZ4740_DMA_WIDTH_32BIT, | ||
350 | dma_config->transfer_size = JZ4740_DMA_TRANSFER_SIZE_16BYTE; | ||
351 | dma_config->request_type = JZ4740_DMA_TYPE_AIC_TRANSMIT; | ||
352 | dma_config->flags = JZ4740_DMA_SRC_AUTOINC; | ||
353 | dma_config->mode = JZ4740_DMA_MODE_SINGLE; | ||
354 | i2s->pcm_config_playback.fifo_addr = i2s->phys_base + JZ_REG_AIC_FIFO; | ||
355 | |||
356 | /* Capture */ | ||
357 | dma_config = &i2s->pcm_config_capture.dma_config; | ||
358 | dma_config->dst_width = JZ4740_DMA_WIDTH_32BIT, | ||
359 | dma_config->transfer_size = JZ4740_DMA_TRANSFER_SIZE_16BYTE; | ||
360 | dma_config->request_type = JZ4740_DMA_TYPE_AIC_RECEIVE; | ||
361 | dma_config->flags = JZ4740_DMA_DST_AUTOINC; | ||
362 | dma_config->mode = JZ4740_DMA_MODE_SINGLE; | ||
363 | i2s->pcm_config_capture.fifo_addr = i2s->phys_base + JZ_REG_AIC_FIFO; | ||
364 | } | ||
365 | |||
366 | static int jz4740_i2s_dai_probe(struct snd_soc_dai *dai) | ||
350 | { | 367 | { |
351 | struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai); | 368 | struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); |
352 | uint32_t conf; | 369 | uint32_t conf; |
353 | 370 | ||
371 | clk_enable(i2s->clk_aic); | ||
372 | |||
373 | jz4740_i2c_init_pcm_config(i2s); | ||
374 | |||
354 | conf = (7 << JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) | | 375 | conf = (7 << JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) | |
355 | (8 << JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) | | 376 | (8 << JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) | |
356 | JZ_AIC_CONF_OVERFLOW_PLAY_LAST | | 377 | JZ_AIC_CONF_OVERFLOW_PLAY_LAST | |
@@ -363,6 +384,14 @@ static int jz4740_i2s_probe(struct platform_device *pdev, struct snd_soc_dai *da | |||
363 | return 0; | 384 | return 0; |
364 | } | 385 | } |
365 | 386 | ||
387 | static int jz4740_i2s_dai_remove(struct snd_soc_dai *dai) | ||
388 | { | ||
389 | struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); | ||
390 | |||
391 | clk_disable(i2s->clk_aic); | ||
392 | return 0; | ||
393 | } | ||
394 | |||
366 | static struct snd_soc_dai_ops jz4740_i2s_dai_ops = { | 395 | static struct snd_soc_dai_ops jz4740_i2s_dai_ops = { |
367 | .startup = jz4740_i2s_startup, | 396 | .startup = jz4740_i2s_startup, |
368 | .shutdown = jz4740_i2s_shutdown, | 397 | .shutdown = jz4740_i2s_shutdown, |
@@ -375,9 +404,9 @@ static struct snd_soc_dai_ops jz4740_i2s_dai_ops = { | |||
375 | #define JZ4740_I2S_FMTS (SNDRV_PCM_FMTBIT_S8 | \ | 404 | #define JZ4740_I2S_FMTS (SNDRV_PCM_FMTBIT_S8 | \ |
376 | SNDRV_PCM_FMTBIT_S16_LE) | 405 | SNDRV_PCM_FMTBIT_S16_LE) |
377 | 406 | ||
378 | struct snd_soc_dai jz4740_i2s_dai = { | 407 | static struct snd_soc_dai_driver jz4740_i2s_dai = { |
379 | .name = "jz4740-i2s", | 408 | .probe = jz4740_i2s_dai_probe, |
380 | .probe = jz4740_i2s_probe, | 409 | .remove = jz4740_i2s_dai_remove, |
381 | .playback = { | 410 | .playback = { |
382 | .channels_min = 1, | 411 | .channels_min = 1, |
383 | .channels_max = 2, | 412 | .channels_max = 2, |
@@ -395,30 +424,6 @@ struct snd_soc_dai jz4740_i2s_dai = { | |||
395 | .suspend = jz4740_i2s_suspend, | 424 | .suspend = jz4740_i2s_suspend, |
396 | .resume = jz4740_i2s_resume, | 425 | .resume = jz4740_i2s_resume, |
397 | }; | 426 | }; |
398 | EXPORT_SYMBOL_GPL(jz4740_i2s_dai); | ||
399 | |||
400 | static void __devinit jz4740_i2c_init_pcm_config(struct jz4740_i2s *i2s) | ||
401 | { | ||
402 | struct jz4740_dma_config *dma_config; | ||
403 | |||
404 | /* Playback */ | ||
405 | dma_config = &i2s->pcm_config_playback.dma_config; | ||
406 | dma_config->src_width = JZ4740_DMA_WIDTH_32BIT, | ||
407 | dma_config->transfer_size = JZ4740_DMA_TRANSFER_SIZE_16BYTE; | ||
408 | dma_config->request_type = JZ4740_DMA_TYPE_AIC_TRANSMIT; | ||
409 | dma_config->flags = JZ4740_DMA_SRC_AUTOINC; | ||
410 | dma_config->mode = JZ4740_DMA_MODE_SINGLE; | ||
411 | i2s->pcm_config_playback.fifo_addr = i2s->phys_base + JZ_REG_AIC_FIFO; | ||
412 | |||
413 | /* Capture */ | ||
414 | dma_config = &i2s->pcm_config_capture.dma_config; | ||
415 | dma_config->dst_width = JZ4740_DMA_WIDTH_32BIT, | ||
416 | dma_config->transfer_size = JZ4740_DMA_TRANSFER_SIZE_16BYTE; | ||
417 | dma_config->request_type = JZ4740_DMA_TYPE_AIC_RECEIVE; | ||
418 | dma_config->flags = JZ4740_DMA_DST_AUTOINC; | ||
419 | dma_config->mode = JZ4740_DMA_MODE_SINGLE; | ||
420 | i2s->pcm_config_capture.fifo_addr = i2s->phys_base + JZ_REG_AIC_FIFO; | ||
421 | } | ||
422 | 427 | ||
423 | static int __devinit jz4740_i2s_dev_probe(struct platform_device *pdev) | 428 | static int __devinit jz4740_i2s_dev_probe(struct platform_device *pdev) |
424 | { | 429 | { |
@@ -463,24 +468,17 @@ static int __devinit jz4740_i2s_dev_probe(struct platform_device *pdev) | |||
463 | goto err_clk_put_aic; | 468 | goto err_clk_put_aic; |
464 | } | 469 | } |
465 | 470 | ||
466 | clk_enable(i2s->clk_aic); | 471 | platform_set_drvdata(pdev, i2s); |
467 | 472 | ret = snd_soc_register_dai(&pdev->dev, &jz4740_i2s_dai); | |
468 | jz4740_i2c_init_pcm_config(i2s); | ||
469 | |||
470 | jz4740_i2s_dai.private_data = i2s; | ||
471 | ret = snd_soc_register_dai(&jz4740_i2s_dai); | ||
472 | 473 | ||
473 | if (ret) { | 474 | if (ret) { |
474 | dev_err(&pdev->dev, "Failed to register DAI\n"); | 475 | dev_err(&pdev->dev, "Failed to register DAI\n"); |
475 | goto err_clk_put_i2s; | 476 | goto err_clk_put_i2s; |
476 | } | 477 | } |
477 | 478 | ||
478 | platform_set_drvdata(pdev, i2s); | ||
479 | |||
480 | return 0; | 479 | return 0; |
481 | 480 | ||
482 | err_clk_put_i2s: | 481 | err_clk_put_i2s: |
483 | clk_disable(i2s->clk_aic); | ||
484 | clk_put(i2s->clk_i2s); | 482 | clk_put(i2s->clk_i2s); |
485 | err_clk_put_aic: | 483 | err_clk_put_aic: |
486 | clk_put(i2s->clk_aic); | 484 | clk_put(i2s->clk_aic); |
@@ -498,9 +496,8 @@ static int __devexit jz4740_i2s_dev_remove(struct platform_device *pdev) | |||
498 | { | 496 | { |
499 | struct jz4740_i2s *i2s = platform_get_drvdata(pdev); | 497 | struct jz4740_i2s *i2s = platform_get_drvdata(pdev); |
500 | 498 | ||
501 | snd_soc_unregister_dai(&jz4740_i2s_dai); | 499 | snd_soc_unregister_dai(&pdev->dev); |
502 | 500 | ||
503 | clk_disable(i2s->clk_aic); | ||
504 | clk_put(i2s->clk_i2s); | 501 | clk_put(i2s->clk_i2s); |
505 | clk_put(i2s->clk_aic); | 502 | clk_put(i2s->clk_aic); |
506 | 503 | ||