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