diff options
Diffstat (limited to 'sound/soc/davinci/davinci-mcasp.c')
-rw-r--r-- | sound/soc/davinci/davinci-mcasp.c | 104 |
1 files changed, 50 insertions, 54 deletions
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index eca22d7829d2..5d1f98a4c978 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c | |||
@@ -332,14 +332,6 @@ static inline void mcasp_set_ctl_reg(void __iomem *regs, u32 val) | |||
332 | printk(KERN_ERR "GBLCTL write error\n"); | 332 | printk(KERN_ERR "GBLCTL write error\n"); |
333 | } | 333 | } |
334 | 334 | ||
335 | static int davinci_mcasp_startup(struct snd_pcm_substream *substream, | ||
336 | struct snd_soc_dai *cpu_dai) | ||
337 | { | ||
338 | struct davinci_audio_dev *dev = cpu_dai->private_data; | ||
339 | cpu_dai->dma_data = dev->dma_params[substream->stream]; | ||
340 | return 0; | ||
341 | } | ||
342 | |||
343 | static void mcasp_start_rx(struct davinci_audio_dev *dev) | 335 | static void mcasp_start_rx(struct davinci_audio_dev *dev) |
344 | { | 336 | { |
345 | mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXHCLKRST); | 337 | mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXHCLKRST); |
@@ -386,17 +378,17 @@ static void mcasp_start_tx(struct davinci_audio_dev *dev) | |||
386 | 378 | ||
387 | static void davinci_mcasp_start(struct davinci_audio_dev *dev, int stream) | 379 | static void davinci_mcasp_start(struct davinci_audio_dev *dev, int stream) |
388 | { | 380 | { |
389 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) | 381 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { |
382 | if (dev->txnumevt) /* enable FIFO */ | ||
383 | mcasp_set_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, | ||
384 | FIFO_ENABLE); | ||
390 | mcasp_start_tx(dev); | 385 | mcasp_start_tx(dev); |
391 | else | 386 | } else { |
387 | if (dev->rxnumevt) /* enable FIFO */ | ||
388 | mcasp_set_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, | ||
389 | FIFO_ENABLE); | ||
392 | mcasp_start_rx(dev); | 390 | mcasp_start_rx(dev); |
393 | 391 | } | |
394 | /* enable FIFO */ | ||
395 | if (dev->txnumevt) | ||
396 | mcasp_set_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, FIFO_ENABLE); | ||
397 | |||
398 | if (dev->rxnumevt) | ||
399 | mcasp_set_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, FIFO_ENABLE); | ||
400 | } | 392 | } |
401 | 393 | ||
402 | static void mcasp_stop_rx(struct davinci_audio_dev *dev) | 394 | static void mcasp_stop_rx(struct davinci_audio_dev *dev) |
@@ -413,17 +405,17 @@ static void mcasp_stop_tx(struct davinci_audio_dev *dev) | |||
413 | 405 | ||
414 | static void davinci_mcasp_stop(struct davinci_audio_dev *dev, int stream) | 406 | static void davinci_mcasp_stop(struct davinci_audio_dev *dev, int stream) |
415 | { | 407 | { |
416 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) | 408 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { |
409 | if (dev->txnumevt) /* disable FIFO */ | ||
410 | mcasp_clr_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, | ||
411 | FIFO_ENABLE); | ||
417 | mcasp_stop_tx(dev); | 412 | mcasp_stop_tx(dev); |
418 | else | 413 | } else { |
414 | if (dev->rxnumevt) /* disable FIFO */ | ||
415 | mcasp_clr_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, | ||
416 | FIFO_ENABLE); | ||
419 | mcasp_stop_rx(dev); | 417 | mcasp_stop_rx(dev); |
420 | 418 | } | |
421 | /* disable FIFO */ | ||
422 | if (dev->txnumevt) | ||
423 | mcasp_clr_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, FIFO_ENABLE); | ||
424 | |||
425 | if (dev->rxnumevt) | ||
426 | mcasp_clr_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, FIFO_ENABLE); | ||
427 | } | 419 | } |
428 | 420 | ||
429 | static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, | 421 | static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, |
@@ -512,34 +504,49 @@ static int davinci_config_channel_size(struct davinci_audio_dev *dev, | |||
512 | int channel_size) | 504 | int channel_size) |
513 | { | 505 | { |
514 | u32 fmt = 0; | 506 | u32 fmt = 0; |
507 | u32 mask, rotate; | ||
515 | 508 | ||
516 | switch (channel_size) { | 509 | switch (channel_size) { |
517 | case DAVINCI_AUDIO_WORD_8: | 510 | case DAVINCI_AUDIO_WORD_8: |
518 | fmt = 0x03; | 511 | fmt = 0x03; |
512 | rotate = 6; | ||
513 | mask = 0x000000ff; | ||
519 | break; | 514 | break; |
520 | 515 | ||
521 | case DAVINCI_AUDIO_WORD_12: | 516 | case DAVINCI_AUDIO_WORD_12: |
522 | fmt = 0x05; | 517 | fmt = 0x05; |
518 | rotate = 5; | ||
519 | mask = 0x00000fff; | ||
523 | break; | 520 | break; |
524 | 521 | ||
525 | case DAVINCI_AUDIO_WORD_16: | 522 | case DAVINCI_AUDIO_WORD_16: |
526 | fmt = 0x07; | 523 | fmt = 0x07; |
524 | rotate = 4; | ||
525 | mask = 0x0000ffff; | ||
527 | break; | 526 | break; |
528 | 527 | ||
529 | case DAVINCI_AUDIO_WORD_20: | 528 | case DAVINCI_AUDIO_WORD_20: |
530 | fmt = 0x09; | 529 | fmt = 0x09; |
530 | rotate = 3; | ||
531 | mask = 0x000fffff; | ||
531 | break; | 532 | break; |
532 | 533 | ||
533 | case DAVINCI_AUDIO_WORD_24: | 534 | case DAVINCI_AUDIO_WORD_24: |
534 | fmt = 0x0B; | 535 | fmt = 0x0B; |
536 | rotate = 2; | ||
537 | mask = 0x00ffffff; | ||
535 | break; | 538 | break; |
536 | 539 | ||
537 | case DAVINCI_AUDIO_WORD_28: | 540 | case DAVINCI_AUDIO_WORD_28: |
538 | fmt = 0x0D; | 541 | fmt = 0x0D; |
542 | rotate = 1; | ||
543 | mask = 0x0fffffff; | ||
539 | break; | 544 | break; |
540 | 545 | ||
541 | case DAVINCI_AUDIO_WORD_32: | 546 | case DAVINCI_AUDIO_WORD_32: |
542 | fmt = 0x0F; | 547 | fmt = 0x0F; |
548 | rotate = 0; | ||
549 | mask = 0xffffffff; | ||
543 | break; | 550 | break; |
544 | 551 | ||
545 | default: | 552 | default: |
@@ -550,6 +557,13 @@ static int davinci_config_channel_size(struct davinci_audio_dev *dev, | |||
550 | RXSSZ(fmt), RXSSZ(0x0F)); | 557 | RXSSZ(fmt), RXSSZ(0x0F)); |
551 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, | 558 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, |
552 | TXSSZ(fmt), TXSSZ(0x0F)); | 559 | TXSSZ(fmt), TXSSZ(0x0F)); |
560 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, TXROT(rotate), | ||
561 | TXROT(7)); | ||
562 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, RXROT(rotate), | ||
563 | RXROT(7)); | ||
564 | mcasp_set_reg(dev->base + DAVINCI_MCASP_TXMASK_REG, mask); | ||
565 | mcasp_set_reg(dev->base + DAVINCI_MCASP_RXMASK_REG, mask); | ||
566 | |||
553 | return 0; | 567 | return 0; |
554 | } | 568 | } |
555 | 569 | ||
@@ -638,7 +652,6 @@ static void davinci_hw_param(struct davinci_audio_dev *dev, int stream) | |||
638 | printk(KERN_ERR "playback tdm slot %d not supported\n", | 652 | printk(KERN_ERR "playback tdm slot %d not supported\n", |
639 | dev->tdm_slots); | 653 | dev->tdm_slots); |
640 | 654 | ||
641 | mcasp_set_reg(dev->base + DAVINCI_MCASP_TXMASK_REG, 0xFFFFFFFF); | ||
642 | mcasp_clr_bits(dev->base + DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); | 655 | mcasp_clr_bits(dev->base + DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); |
643 | } else { | 656 | } else { |
644 | /* bit stream is MSB first with no delay */ | 657 | /* bit stream is MSB first with no delay */ |
@@ -655,7 +668,6 @@ static void davinci_hw_param(struct davinci_audio_dev *dev, int stream) | |||
655 | printk(KERN_ERR "capture tdm slot %d not supported\n", | 668 | printk(KERN_ERR "capture tdm slot %d not supported\n", |
656 | dev->tdm_slots); | 669 | dev->tdm_slots); |
657 | 670 | ||
658 | mcasp_set_reg(dev->base + DAVINCI_MCASP_RXMASK_REG, 0xFFFFFFFF); | ||
659 | mcasp_clr_bits(dev->base + DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); | 671 | mcasp_clr_bits(dev->base + DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); |
660 | } | 672 | } |
661 | } | 673 | } |
@@ -700,7 +712,7 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, | |||
700 | { | 712 | { |
701 | struct davinci_audio_dev *dev = cpu_dai->private_data; | 713 | struct davinci_audio_dev *dev = cpu_dai->private_data; |
702 | struct davinci_pcm_dma_params *dma_params = | 714 | struct davinci_pcm_dma_params *dma_params = |
703 | dev->dma_params[substream->stream]; | 715 | &dev->dma_params[substream->stream]; |
704 | int word_length; | 716 | int word_length; |
705 | u8 numevt; | 717 | u8 numevt; |
706 | 718 | ||
@@ -778,7 +790,6 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream, | |||
778 | } | 790 | } |
779 | 791 | ||
780 | static struct snd_soc_dai_ops davinci_mcasp_dai_ops = { | 792 | static struct snd_soc_dai_ops davinci_mcasp_dai_ops = { |
781 | .startup = davinci_mcasp_startup, | ||
782 | .trigger = davinci_mcasp_trigger, | 793 | .trigger = davinci_mcasp_trigger, |
783 | .hw_params = davinci_mcasp_hw_params, | 794 | .hw_params = davinci_mcasp_hw_params, |
784 | .set_fmt = davinci_mcasp_set_dai_fmt, | 795 | .set_fmt = davinci_mcasp_set_dai_fmt, |
@@ -829,20 +840,12 @@ static int davinci_mcasp_probe(struct platform_device *pdev) | |||
829 | struct resource *mem, *ioarea, *res; | 840 | struct resource *mem, *ioarea, *res; |
830 | struct snd_platform_data *pdata; | 841 | struct snd_platform_data *pdata; |
831 | struct davinci_audio_dev *dev; | 842 | struct davinci_audio_dev *dev; |
832 | int count = 0; | ||
833 | int ret = 0; | 843 | int ret = 0; |
834 | 844 | ||
835 | dev = kzalloc(sizeof(struct davinci_audio_dev), GFP_KERNEL); | 845 | dev = kzalloc(sizeof(struct davinci_audio_dev), GFP_KERNEL); |
836 | if (!dev) | 846 | if (!dev) |
837 | return -ENOMEM; | 847 | return -ENOMEM; |
838 | 848 | ||
839 | dma_data = kzalloc(sizeof(struct davinci_pcm_dma_params) * 2, | ||
840 | GFP_KERNEL); | ||
841 | if (!dma_data) { | ||
842 | ret = -ENOMEM; | ||
843 | goto err_release_dev; | ||
844 | } | ||
845 | |||
846 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 849 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
847 | if (!mem) { | 850 | if (!mem) { |
848 | dev_err(&pdev->dev, "no mem resource?\n"); | 851 | dev_err(&pdev->dev, "no mem resource?\n"); |
@@ -877,11 +880,10 @@ static int davinci_mcasp_probe(struct platform_device *pdev) | |||
877 | dev->txnumevt = pdata->txnumevt; | 880 | dev->txnumevt = pdata->txnumevt; |
878 | dev->rxnumevt = pdata->rxnumevt; | 881 | dev->rxnumevt = pdata->rxnumevt; |
879 | 882 | ||
880 | dma_data[count].name = "I2S PCM Stereo out"; | 883 | dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]; |
881 | dma_data[count].eventq_no = pdata->eventq_no; | 884 | dma_data->eventq_no = pdata->eventq_no; |
882 | dma_data[count].dma_addr = (dma_addr_t) (pdata->tx_dma_offset + | 885 | dma_data->dma_addr = (dma_addr_t) (pdata->tx_dma_offset + |
883 | io_v2p(dev->base)); | 886 | io_v2p(dev->base)); |
884 | dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK] = &dma_data[count]; | ||
885 | 887 | ||
886 | /* first TX, then RX */ | 888 | /* first TX, then RX */ |
887 | res = platform_get_resource(pdev, IORESOURCE_DMA, 0); | 889 | res = platform_get_resource(pdev, IORESOURCE_DMA, 0); |
@@ -890,13 +892,12 @@ static int davinci_mcasp_probe(struct platform_device *pdev) | |||
890 | goto err_release_region; | 892 | goto err_release_region; |
891 | } | 893 | } |
892 | 894 | ||
893 | dma_data[count].channel = res->start; | 895 | dma_data->channel = res->start; |
894 | count++; | 896 | |
895 | dma_data[count].name = "I2S PCM Stereo in"; | 897 | dma_data = &dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]; |
896 | dma_data[count].eventq_no = pdata->eventq_no; | 898 | dma_data->eventq_no = pdata->eventq_no; |
897 | dma_data[count].dma_addr = (dma_addr_t)(pdata->rx_dma_offset + | 899 | dma_data->dma_addr = (dma_addr_t)(pdata->rx_dma_offset + |
898 | io_v2p(dev->base)); | 900 | io_v2p(dev->base)); |
899 | dev->dma_params[SNDRV_PCM_STREAM_CAPTURE] = &dma_data[count]; | ||
900 | 901 | ||
901 | res = platform_get_resource(pdev, IORESOURCE_DMA, 1); | 902 | res = platform_get_resource(pdev, IORESOURCE_DMA, 1); |
902 | if (!res) { | 903 | if (!res) { |
@@ -904,7 +905,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev) | |||
904 | goto err_release_region; | 905 | goto err_release_region; |
905 | } | 906 | } |
906 | 907 | ||
907 | dma_data[count].channel = res->start; | 908 | dma_data->channel = res->start; |
908 | davinci_mcasp_dai[pdata->op_mode].private_data = dev; | 909 | davinci_mcasp_dai[pdata->op_mode].private_data = dev; |
909 | davinci_mcasp_dai[pdata->op_mode].dev = &pdev->dev; | 910 | davinci_mcasp_dai[pdata->op_mode].dev = &pdev->dev; |
910 | ret = snd_soc_register_dai(&davinci_mcasp_dai[pdata->op_mode]); | 911 | ret = snd_soc_register_dai(&davinci_mcasp_dai[pdata->op_mode]); |
@@ -916,8 +917,6 @@ static int davinci_mcasp_probe(struct platform_device *pdev) | |||
916 | err_release_region: | 917 | err_release_region: |
917 | release_mem_region(mem->start, (mem->end - mem->start) + 1); | 918 | release_mem_region(mem->start, (mem->end - mem->start) + 1); |
918 | err_release_data: | 919 | err_release_data: |
919 | kfree(dma_data); | ||
920 | err_release_dev: | ||
921 | kfree(dev); | 920 | kfree(dev); |
922 | 921 | ||
923 | return ret; | 922 | return ret; |
@@ -926,7 +925,6 @@ err_release_dev: | |||
926 | static int davinci_mcasp_remove(struct platform_device *pdev) | 925 | static int davinci_mcasp_remove(struct platform_device *pdev) |
927 | { | 926 | { |
928 | struct snd_platform_data *pdata = pdev->dev.platform_data; | 927 | struct snd_platform_data *pdata = pdev->dev.platform_data; |
929 | struct davinci_pcm_dma_params *dma_data; | ||
930 | struct davinci_audio_dev *dev; | 928 | struct davinci_audio_dev *dev; |
931 | struct resource *mem; | 929 | struct resource *mem; |
932 | 930 | ||
@@ -939,8 +937,6 @@ static int davinci_mcasp_remove(struct platform_device *pdev) | |||
939 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 937 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
940 | release_mem_region(mem->start, (mem->end - mem->start) + 1); | 938 | release_mem_region(mem->start, (mem->end - mem->start) + 1); |
941 | 939 | ||
942 | dma_data = dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]; | ||
943 | kfree(dma_data); | ||
944 | kfree(dev); | 940 | kfree(dev); |
945 | 941 | ||
946 | return 0; | 942 | return 0; |