aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/jz4740/jz4740-i2s.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/jz4740/jz4740-i2s.c')
-rw-r--r--sound/soc/jz4740/jz4740-i2s.c107
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
109static inline struct jz4740_i2s *jz4740_dai_to_i2s(struct snd_soc_dai *dai)
110{
111 return dai->private_data;
112}
113
114static int jz4740_i2s_startup(struct snd_pcm_substream *substream, 108static 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,
136static void jz4740_i2s_shutdown(struct snd_pcm_substream *substream, 130static 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,
152static int jz4740_i2s_trigger(struct snd_pcm_substream *substream, int cmd, 146static 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
187static int jz4740_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 181static 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)
238static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream, 232static 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,
288static int jz4740_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id, 282static 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
313static int jz4740_i2s_suspend(struct snd_soc_dai *dai) 307static 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
331static int jz4740_i2s_resume(struct snd_soc_dai *dai) 325static 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
349static int jz4740_i2s_probe(struct platform_device *pdev, struct snd_soc_dai *dai) 343static 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
366static 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
387static 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
366static struct snd_soc_dai_ops jz4740_i2s_dai_ops = { 395static 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
378struct snd_soc_dai jz4740_i2s_dai = { 407static 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};
398EXPORT_SYMBOL_GPL(jz4740_i2s_dai);
399
400static 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
423static int __devinit jz4740_i2s_dev_probe(struct platform_device *pdev) 428static 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
482err_clk_put_i2s: 481err_clk_put_i2s:
483 clk_disable(i2s->clk_aic);
484 clk_put(i2s->clk_i2s); 482 clk_put(i2s->clk_i2s);
485err_clk_put_aic: 483err_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