aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/soc/davinci/davinci-i2s.c1
-rw-r--r--sound/soc/davinci/davinci-mcasp.c105
-rw-r--r--sound/soc/davinci/davinci-mcasp.h5
-rw-r--r--sound/soc/davinci/davinci-pcm.c4
-rw-r--r--sound/soc/davinci/davinci-pcm.h1
5 files changed, 107 insertions, 9 deletions
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c
index 2a56fb78f67a..12a6c549ee6e 100644
--- a/sound/soc/davinci/davinci-i2s.c
+++ b/sound/soc/davinci/davinci-i2s.c
@@ -406,6 +406,7 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
406 return -EINVAL; 406 return -EINVAL;
407 } 407 }
408 408
409 dma_params->acnt = dma_params->data_type;
409 rcr |= DAVINCI_MCBSP_RCR_RFRLEN1(1); 410 rcr |= DAVINCI_MCBSP_RCR_RFRLEN1(1);
410 xcr |= DAVINCI_MCBSP_XCR_XFRLEN1(1); 411 xcr |= DAVINCI_MCBSP_XCR_XFRLEN1(1);
411 412
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index f0c034771062..e672f431323d 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -102,6 +102,11 @@
102/* Receive Buffer for Serializer n */ 102/* Receive Buffer for Serializer n */
103#define DAVINCI_MCASP_RXBUF_REG 0x280 103#define DAVINCI_MCASP_RXBUF_REG 0x280
104 104
105/* McASP FIFO Registers */
106#define DAVINCI_MCASP_WFIFOCTL (0x1010)
107#define DAVINCI_MCASP_WFIFOSTS (0x1014)
108#define DAVINCI_MCASP_RFIFOCTL (0x1018)
109#define DAVINCI_MCASP_RFIFOSTS (0x101C)
105 110
106/* 111/*
107 * DAVINCI_MCASP_PWREMUMGT_REG - Power Down and Emulation Management 112 * DAVINCI_MCASP_PWREMUMGT_REG - Power Down and Emulation Management
@@ -276,6 +281,13 @@
276 */ 281 */
277#define TXDATADMADIS BIT(0) 282#define TXDATADMADIS BIT(0)
278 283
284/*
285 * DAVINCI_MCASP_W[R]FIFOCTL - Write/Read FIFO Control Register bits
286 */
287#define FIFO_ENABLE BIT(16)
288#define NUMEVT_MASK (0xFF << 8)
289#define NUMDMA_MASK (0xFF)
290
279#define DAVINCI_MCASP_NUM_SERIALIZER 16 291#define DAVINCI_MCASP_NUM_SERIALIZER 16
280 292
281static inline void mcasp_set_bits(void __iomem *reg, u32 val) 293static inline void mcasp_set_bits(void __iomem *reg, u32 val)
@@ -345,6 +357,9 @@ static void mcasp_start_rx(struct davinci_audio_dev *dev)
345 357
346static void mcasp_start_tx(struct davinci_audio_dev *dev) 358static void mcasp_start_tx(struct davinci_audio_dev *dev)
347{ 359{
360 u8 offset = 0, i;
361 u32 cnt;
362
348 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXHCLKRST); 363 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXHCLKRST);
349 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXCLKRST); 364 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXCLKRST);
350 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXSERCLR); 365 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXSERCLR);
@@ -353,6 +368,19 @@ static void mcasp_start_tx(struct davinci_audio_dev *dev)
353 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXSMRST); 368 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXSMRST);
354 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXFSRST); 369 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXFSRST);
355 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXBUF_REG, 0); 370 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXBUF_REG, 0);
371 for (i = 0; i < dev->num_serializer; i++) {
372 if (dev->serial_dir[i] == TX_MODE) {
373 offset = i;
374 break;
375 }
376 }
377
378 /* wait for TX ready */
379 cnt = 0;
380 while (!(mcasp_get_reg(dev->base + DAVINCI_MCASP_XRSRCTL_REG(offset)) &
381 TXSTATE) && (cnt < 100000))
382 cnt++;
383
356 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXBUF_REG, 0); 384 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXBUF_REG, 0);
357} 385}
358 386
@@ -362,6 +390,13 @@ static void davinci_mcasp_start(struct davinci_audio_dev *dev, int stream)
362 mcasp_start_tx(dev); 390 mcasp_start_tx(dev);
363 else 391 else
364 mcasp_start_rx(dev); 392 mcasp_start_rx(dev);
393
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);
365} 400}
366 401
367static void mcasp_stop_rx(struct davinci_audio_dev *dev) 402static void mcasp_stop_rx(struct davinci_audio_dev *dev)
@@ -382,6 +417,13 @@ static void davinci_mcasp_stop(struct davinci_audio_dev *dev, int stream)
382 mcasp_stop_tx(dev); 417 mcasp_stop_tx(dev);
383 else 418 else
384 mcasp_stop_rx(dev); 419 mcasp_stop_rx(dev);
420
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);
385} 427}
386 428
387static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, 429static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
@@ -401,7 +443,6 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
401 443
402 mcasp_set_bits(base + DAVINCI_MCASP_PDIR_REG, (0x7 << 26)); 444 mcasp_set_bits(base + DAVINCI_MCASP_PDIR_REG, (0x7 << 26));
403 break; 445 break;
404
405 case SND_SOC_DAIFMT_CBM_CFM: 446 case SND_SOC_DAIFMT_CBM_CFM:
406 /* codec is clock and frame master */ 447 /* codec is clock and frame master */
407 mcasp_clr_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE); 448 mcasp_clr_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE);
@@ -505,6 +546,8 @@ static int davinci_config_channel_size(struct davinci_audio_dev *dev,
505static void davinci_hw_common_param(struct davinci_audio_dev *dev, int stream) 546static void davinci_hw_common_param(struct davinci_audio_dev *dev, int stream)
506{ 547{
507 int i; 548 int i;
549 u8 tx_ser = 0;
550 u8 rx_ser = 0;
508 551
509 /* Default configuration */ 552 /* Default configuration */
510 mcasp_set_bits(dev->base + DAVINCI_MCASP_PWREMUMGT_REG, MCASP_SOFT); 553 mcasp_set_bits(dev->base + DAVINCI_MCASP_PWREMUMGT_REG, MCASP_SOFT);
@@ -525,12 +568,37 @@ static void davinci_hw_common_param(struct davinci_audio_dev *dev, int stream)
525 for (i = 0; i < dev->num_serializer; i++) { 568 for (i = 0; i < dev->num_serializer; i++) {
526 mcasp_set_bits(dev->base + DAVINCI_MCASP_XRSRCTL_REG(i), 569 mcasp_set_bits(dev->base + DAVINCI_MCASP_XRSRCTL_REG(i),
527 dev->serial_dir[i]); 570 dev->serial_dir[i]);
528 if (dev->serial_dir[i] == TX_MODE) 571 if (dev->serial_dir[i] == TX_MODE) {
529 mcasp_set_bits(dev->base + DAVINCI_MCASP_PDIR_REG, 572 mcasp_set_bits(dev->base + DAVINCI_MCASP_PDIR_REG,
530 AXR(i)); 573 AXR(i));
531 else if (dev->serial_dir[i] == RX_MODE) 574 tx_ser++;
575 } else if (dev->serial_dir[i] == RX_MODE) {
532 mcasp_clr_bits(dev->base + DAVINCI_MCASP_PDIR_REG, 576 mcasp_clr_bits(dev->base + DAVINCI_MCASP_PDIR_REG,
533 AXR(i)); 577 AXR(i));
578 rx_ser++;
579 }
580 }
581
582 if (dev->txnumevt && stream == SNDRV_PCM_STREAM_PLAYBACK) {
583 if (dev->txnumevt * tx_ser > 64)
584 dev->txnumevt = 1;
585
586 mcasp_mod_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, tx_ser,
587 NUMDMA_MASK);
588 mcasp_mod_bits(dev->base + DAVINCI_MCASP_WFIFOCTL,
589 ((dev->txnumevt * tx_ser) << 8), NUMEVT_MASK);
590 mcasp_set_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, FIFO_ENABLE);
591 }
592
593 if (dev->rxnumevt && stream == SNDRV_PCM_STREAM_CAPTURE) {
594 if (dev->rxnumevt * rx_ser > 64)
595 dev->rxnumevt = 1;
596
597 mcasp_mod_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, rx_ser,
598 NUMDMA_MASK);
599 mcasp_mod_bits(dev->base + DAVINCI_MCASP_RFIFOCTL,
600 ((dev->rxnumevt * rx_ser) << 8), NUMEVT_MASK);
601 mcasp_set_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, FIFO_ENABLE);
534 } 602 }
535} 603}
536 604
@@ -543,6 +611,8 @@ static void davinci_hw_param(struct davinci_audio_dev *dev, int stream)
543 for (i = 0; i < active_slots; i++) 611 for (i = 0; i < active_slots; i++)
544 mask |= (1 << i); 612 mask |= (1 << i);
545 613
614 mcasp_clr_bits(dev->base + DAVINCI_MCASP_ACLKXCTL_REG, TX_ASYNC);
615
546 if (stream == SNDRV_PCM_STREAM_PLAYBACK) { 616 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
547 /* bit stream is MSB first with no delay */ 617 /* bit stream is MSB first with no delay */
548 /* DSP_B mode */ 618 /* DSP_B mode */
@@ -622,8 +692,16 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
622 struct davinci_pcm_dma_params *dma_params = 692 struct davinci_pcm_dma_params *dma_params =
623 dev->dma_params[substream->stream]; 693 dev->dma_params[substream->stream];
624 int word_length; 694 int word_length;
695 u8 numevt;
625 696
626 davinci_hw_common_param(dev, substream->stream); 697 davinci_hw_common_param(dev, substream->stream);
698 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
699 numevt = dev->txnumevt;
700 else
701 numevt = dev->rxnumevt;
702
703 if (!numevt)
704 numevt = 1;
627 705
628 if (dev->op_mode == DAVINCI_MCASP_DIT_MODE) 706 if (dev->op_mode == DAVINCI_MCASP_DIT_MODE)
629 davinci_hw_dit_param(dev); 707 davinci_hw_dit_param(dev);
@@ -650,6 +728,13 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
650 printk(KERN_WARNING "davinci-mcasp: unsupported PCM format"); 728 printk(KERN_WARNING "davinci-mcasp: unsupported PCM format");
651 return -EINVAL; 729 return -EINVAL;
652 } 730 }
731
732 if (dev->version == MCASP_VERSION_2) {
733 dma_params->data_type *= numevt;
734 dma_params->acnt = 4 * numevt;
735 } else
736 dma_params->acnt = dma_params->data_type;
737
653 davinci_config_channel_size(dev, word_length); 738 davinci_config_channel_size(dev, word_length);
654 739
655 return 0; 740 return 0;
@@ -778,6 +863,9 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
778 dev->num_serializer = pdata->num_serializer; 863 dev->num_serializer = pdata->num_serializer;
779 dev->serial_dir = pdata->serial_dir; 864 dev->serial_dir = pdata->serial_dir;
780 dev->codec_fmt = pdata->codec_fmt; 865 dev->codec_fmt = pdata->codec_fmt;
866 dev->version = pdata->version;
867 dev->txnumevt = pdata->txnumevt;
868 dev->rxnumevt = pdata->rxnumevt;
781 869
782 dma_data[count].name = "I2S PCM Stereo out"; 870 dma_data[count].name = "I2S PCM Stereo out";
783 dma_data[count].eventq_no = pdata->eventq_no; 871 dma_data[count].eventq_no = pdata->eventq_no;
@@ -807,9 +895,9 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
807 } 895 }
808 896
809 dma_data[count].channel = res->start; 897 dma_data[count].channel = res->start;
810 davinci_mcasp_dai[pdev->id].private_data = dev; 898 davinci_mcasp_dai[pdata->op_mode].private_data = dev;
811 davinci_mcasp_dai[pdev->id].dev = &pdev->dev; 899 davinci_mcasp_dai[pdata->op_mode].dev = &pdev->dev;
812 ret = snd_soc_register_dai(&davinci_mcasp_dai[pdev->id]); 900 ret = snd_soc_register_dai(&davinci_mcasp_dai[pdata->op_mode]);
813 901
814 if (ret != 0) 902 if (ret != 0)
815 goto err_release_region; 903 goto err_release_region;
@@ -827,12 +915,13 @@ err_release_dev:
827 915
828static int davinci_mcasp_remove(struct platform_device *pdev) 916static int davinci_mcasp_remove(struct platform_device *pdev)
829{ 917{
918 struct snd_platform_data *pdata = pdev->dev.platform_data;
830 struct davinci_pcm_dma_params *dma_data; 919 struct davinci_pcm_dma_params *dma_data;
831 struct davinci_audio_dev *dev; 920 struct davinci_audio_dev *dev;
832 struct resource *mem; 921 struct resource *mem;
833 922
834 snd_soc_unregister_dai(&davinci_mcasp_dai[pdev->id]); 923 snd_soc_unregister_dai(&davinci_mcasp_dai[pdata->op_mode]);
835 dev = davinci_mcasp_dai[pdev->id].private_data; 924 dev = davinci_mcasp_dai[pdata->op_mode].private_data;
836 clk_disable(dev->clk); 925 clk_disable(dev->clk);
837 clk_put(dev->clk); 926 clk_put(dev->clk);
838 dev->clk = NULL; 927 dev->clk = NULL;
diff --git a/sound/soc/davinci/davinci-mcasp.h b/sound/soc/davinci/davinci-mcasp.h
index 36b71047a06c..554354c1cc2f 100644
--- a/sound/soc/davinci/davinci-mcasp.h
+++ b/sound/soc/davinci/davinci-mcasp.h
@@ -50,6 +50,11 @@ struct davinci_audio_dev {
50 u8 op_mode; 50 u8 op_mode;
51 u8 num_serializer; 51 u8 num_serializer;
52 u8 *serial_dir; 52 u8 *serial_dir;
53 u8 version;
54
55 /* McASP FIFO related */
56 u8 txnumevt;
57 u8 rxnumevt;
53}; 58};
54 59
55#endif /* DAVINCI_MCASP_H */ 60#endif /* DAVINCI_MCASP_H */
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index ab43a539c11d..091dacb78b4d 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -67,6 +67,7 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
67 dma_addr_t src, dst; 67 dma_addr_t src, dst;
68 unsigned short src_bidx, dst_bidx; 68 unsigned short src_bidx, dst_bidx;
69 unsigned int data_type; 69 unsigned int data_type;
70 unsigned short acnt;
70 unsigned int count; 71 unsigned int count;
71 72
72 period_size = snd_pcm_lib_period_bytes(substream); 73 period_size = snd_pcm_lib_period_bytes(substream);
@@ -91,11 +92,12 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
91 dst_bidx = data_type; 92 dst_bidx = data_type;
92 } 93 }
93 94
95 acnt = prtd->params->acnt;
94 edma_set_src(lch, src, INCR, W8BIT); 96 edma_set_src(lch, src, INCR, W8BIT);
95 edma_set_dest(lch, dst, INCR, W8BIT); 97 edma_set_dest(lch, dst, INCR, W8BIT);
96 edma_set_src_index(lch, src_bidx, 0); 98 edma_set_src_index(lch, src_bidx, 0);
97 edma_set_dest_index(lch, dst_bidx, 0); 99 edma_set_dest_index(lch, dst_bidx, 0);
98 edma_set_transfer_params(lch, data_type, count, 1, 0, ASYNC); 100 edma_set_transfer_params(lch, acnt, count, 1, 0, ASYNC);
99 101
100 prtd->period++; 102 prtd->period++;
101 if (unlikely(prtd->period >= runtime->periods)) 103 if (unlikely(prtd->period >= runtime->periods))
diff --git a/sound/soc/davinci/davinci-pcm.h b/sound/soc/davinci/davinci-pcm.h
index eb4287faa3d5..63d96253c73a 100644
--- a/sound/soc/davinci/davinci-pcm.h
+++ b/sound/soc/davinci/davinci-pcm.h
@@ -19,6 +19,7 @@
19struct davinci_pcm_dma_params { 19struct davinci_pcm_dma_params {
20 char *name; /* stream identifier */ 20 char *name; /* stream identifier */
21 int channel; /* sync dma channel ID */ 21 int channel; /* sync dma channel ID */
22 unsigned short acnt;
22 dma_addr_t dma_addr; /* device physical address for DMA */ 23 dma_addr_t dma_addr; /* device physical address for DMA */
23 enum dma_event_q eventq_no; /* event queue number */ 24 enum dma_event_q eventq_no; /* event queue number */
24 unsigned char data_type; /* xfer data type */ 25 unsigned char data_type; /* xfer data type */