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.c135
1 files changed, 35 insertions, 100 deletions
diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index 4c849a49c72a..8f220009e0f6 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -29,9 +29,11 @@
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/initval.h> 31#include <sound/initval.h>
32#include <sound/dmaengine_pcm.h>
33
34#include <asm/mach-jz4740/dma.h>
32 35
33#include "jz4740-i2s.h" 36#include "jz4740-i2s.h"
34#include "jz4740-pcm.h"
35 37
36#define JZ_REG_AIC_CONF 0x00 38#define JZ_REG_AIC_CONF 0x00
37#define JZ_REG_AIC_CTRL 0x04 39#define JZ_REG_AIC_CTRL 0x04
@@ -89,8 +91,8 @@ struct jz4740_i2s {
89 struct clk *clk_aic; 91 struct clk *clk_aic;
90 struct clk *clk_i2s; 92 struct clk *clk_i2s;
91 93
92 struct jz4740_pcm_config pcm_config_playback; 94 struct snd_dmaengine_dai_dma_data playback_dma_data;
93 struct jz4740_pcm_config pcm_config_capture; 95 struct snd_dmaengine_dai_dma_data capture_dma_data;
94}; 96};
95 97
96static inline uint32_t jz4740_i2s_read(const struct jz4740_i2s *i2s, 98static inline uint32_t jz4740_i2s_read(const struct jz4740_i2s *i2s,
@@ -233,8 +235,6 @@ static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream,
233 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 235 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
234{ 236{
235 struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); 237 struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
236 enum jz4740_dma_width dma_width;
237 struct jz4740_pcm_config *pcm_config;
238 unsigned int sample_size; 238 unsigned int sample_size;
239 uint32_t ctrl; 239 uint32_t ctrl;
240 240
@@ -243,11 +243,9 @@ static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream,
243 switch (params_format(params)) { 243 switch (params_format(params)) {
244 case SNDRV_PCM_FORMAT_S8: 244 case SNDRV_PCM_FORMAT_S8:
245 sample_size = 0; 245 sample_size = 0;
246 dma_width = JZ4740_DMA_WIDTH_8BIT;
247 break; 246 break;
248 case SNDRV_PCM_FORMAT_S16: 247 case SNDRV_PCM_FORMAT_S16:
249 sample_size = 1; 248 sample_size = 1;
250 dma_width = JZ4740_DMA_WIDTH_16BIT;
251 break; 249 break;
252 default: 250 default:
253 return -EINVAL; 251 return -EINVAL;
@@ -260,22 +258,13 @@ static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream,
260 ctrl |= JZ_AIC_CTRL_MONO_TO_STEREO; 258 ctrl |= JZ_AIC_CTRL_MONO_TO_STEREO;
261 else 259 else
262 ctrl &= ~JZ_AIC_CTRL_MONO_TO_STEREO; 260 ctrl &= ~JZ_AIC_CTRL_MONO_TO_STEREO;
263
264 pcm_config = &i2s->pcm_config_playback;
265 pcm_config->dma_config.dst_width = dma_width;
266
267 } else { 261 } else {
268 ctrl &= ~JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK; 262 ctrl &= ~JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK;
269 ctrl |= sample_size << JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET; 263 ctrl |= sample_size << JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET;
270
271 pcm_config = &i2s->pcm_config_capture;
272 pcm_config->dma_config.src_width = dma_width;
273 } 264 }
274 265
275 jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl); 266 jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
276 267
277 snd_soc_dai_set_dma_data(dai, substream, pcm_config);
278
279 return 0; 268 return 0;
280} 269}
281 270
@@ -342,25 +331,19 @@ static int jz4740_i2s_resume(struct snd_soc_dai *dai)
342 331
343static void jz4740_i2c_init_pcm_config(struct jz4740_i2s *i2s) 332static void jz4740_i2c_init_pcm_config(struct jz4740_i2s *i2s)
344{ 333{
345 struct jz4740_dma_config *dma_config; 334 struct snd_dmaengine_dai_dma_data *dma_data;
346 335
347 /* Playback */ 336 /* Playback */
348 dma_config = &i2s->pcm_config_playback.dma_config; 337 dma_data = &i2s->playback_dma_data;
349 dma_config->src_width = JZ4740_DMA_WIDTH_32BIT; 338 dma_data->maxburst = 16;
350 dma_config->transfer_size = JZ4740_DMA_TRANSFER_SIZE_16BYTE; 339 dma_data->slave_id = JZ4740_DMA_TYPE_AIC_TRANSMIT;
351 dma_config->request_type = JZ4740_DMA_TYPE_AIC_TRANSMIT; 340 dma_data->addr = i2s->phys_base + JZ_REG_AIC_FIFO;
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 341
356 /* Capture */ 342 /* Capture */
357 dma_config = &i2s->pcm_config_capture.dma_config; 343 dma_data = &i2s->capture_dma_data;
358 dma_config->dst_width = JZ4740_DMA_WIDTH_32BIT; 344 dma_data->maxburst = 16;
359 dma_config->transfer_size = JZ4740_DMA_TRANSFER_SIZE_16BYTE; 345 dma_data->slave_id = JZ4740_DMA_TYPE_AIC_RECEIVE;
360 dma_config->request_type = JZ4740_DMA_TYPE_AIC_RECEIVE; 346 dma_data->addr = i2s->phys_base + JZ_REG_AIC_FIFO;
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} 347}
365 348
366static int jz4740_i2s_dai_probe(struct snd_soc_dai *dai) 349static int jz4740_i2s_dai_probe(struct snd_soc_dai *dai)
@@ -371,6 +354,8 @@ static int jz4740_i2s_dai_probe(struct snd_soc_dai *dai)
371 clk_prepare_enable(i2s->clk_aic); 354 clk_prepare_enable(i2s->clk_aic);
372 355
373 jz4740_i2c_init_pcm_config(i2s); 356 jz4740_i2c_init_pcm_config(i2s);
357 snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data,
358 &i2s->capture_dma_data);
374 359
375 conf = (7 << JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) | 360 conf = (7 << JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) |
376 (8 << JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) | 361 (8 << JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) |
@@ -432,91 +417,41 @@ static const struct snd_soc_component_driver jz4740_i2s_component = {
432static int jz4740_i2s_dev_probe(struct platform_device *pdev) 417static int jz4740_i2s_dev_probe(struct platform_device *pdev)
433{ 418{
434 struct jz4740_i2s *i2s; 419 struct jz4740_i2s *i2s;
420 struct resource *mem;
435 int ret; 421 int ret;
436 422
437 i2s = kzalloc(sizeof(*i2s), GFP_KERNEL); 423 i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
438
439 if (!i2s) 424 if (!i2s)
440 return -ENOMEM; 425 return -ENOMEM;
441 426
442 i2s->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 427 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
443 if (!i2s->mem) { 428 i2s->base = devm_ioremap_resource(&pdev->dev, mem);
444 ret = -ENOENT; 429 if (IS_ERR(i2s->base))
445 goto err_free; 430 return PTR_ERR(i2s->base);
446 }
447
448 i2s->mem = request_mem_region(i2s->mem->start, resource_size(i2s->mem),
449 pdev->name);
450 if (!i2s->mem) {
451 ret = -EBUSY;
452 goto err_free;
453 }
454 431
455 i2s->base = ioremap_nocache(i2s->mem->start, resource_size(i2s->mem)); 432 i2s->phys_base = mem->start;
456 if (!i2s->base) {
457 ret = -EBUSY;
458 goto err_release_mem_region;
459 }
460 433
461 i2s->phys_base = i2s->mem->start; 434 i2s->clk_aic = devm_clk_get(&pdev->dev, "aic");
435 if (IS_ERR(i2s->clk_aic))
436 return PTR_ERR(i2s->clk_aic);
462 437
463 i2s->clk_aic = clk_get(&pdev->dev, "aic"); 438 i2s->clk_i2s = devm_clk_get(&pdev->dev, "i2s");
464 if (IS_ERR(i2s->clk_aic)) { 439 if (IS_ERR(i2s->clk_i2s))
465 ret = PTR_ERR(i2s->clk_aic); 440 return PTR_ERR(i2s->clk_i2s);
466 goto err_iounmap;
467 }
468
469 i2s->clk_i2s = clk_get(&pdev->dev, "i2s");
470 if (IS_ERR(i2s->clk_i2s)) {
471 ret = PTR_ERR(i2s->clk_i2s);
472 goto err_clk_put_aic;
473 }
474 441
475 platform_set_drvdata(pdev, i2s); 442 platform_set_drvdata(pdev, i2s);
476 ret = snd_soc_register_component(&pdev->dev, &jz4740_i2s_component,
477 &jz4740_i2s_dai, 1);
478 443
479 if (ret) { 444 ret = devm_snd_soc_register_component(&pdev->dev,
480 dev_err(&pdev->dev, "Failed to register DAI\n"); 445 &jz4740_i2s_component, &jz4740_i2s_dai, 1);
481 goto err_clk_put_i2s; 446 if (ret)
482 } 447 return ret;
483
484 return 0;
485
486err_clk_put_i2s:
487 clk_put(i2s->clk_i2s);
488err_clk_put_aic:
489 clk_put(i2s->clk_aic);
490err_iounmap:
491 iounmap(i2s->base);
492err_release_mem_region:
493 release_mem_region(i2s->mem->start, resource_size(i2s->mem));
494err_free:
495 kfree(i2s);
496
497 return ret;
498}
499 448
500static int jz4740_i2s_dev_remove(struct platform_device *pdev) 449 return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL,
501{ 450 SND_DMAENGINE_PCM_FLAG_COMPAT);
502 struct jz4740_i2s *i2s = platform_get_drvdata(pdev);
503
504 snd_soc_unregister_component(&pdev->dev);
505
506 clk_put(i2s->clk_i2s);
507 clk_put(i2s->clk_aic);
508
509 iounmap(i2s->base);
510 release_mem_region(i2s->mem->start, resource_size(i2s->mem));
511
512 kfree(i2s);
513
514 return 0;
515} 451}
516 452
517static struct platform_driver jz4740_i2s_driver = { 453static struct platform_driver jz4740_i2s_driver = {
518 .probe = jz4740_i2s_dev_probe, 454 .probe = jz4740_i2s_dev_probe,
519 .remove = jz4740_i2s_dev_remove,
520 .driver = { 455 .driver = {
521 .name = "jz4740-i2s", 456 .name = "jz4740-i2s",
522 .owner = THIS_MODULE, 457 .owner = THIS_MODULE,