aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/fsl
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/fsl')
-rw-r--r--sound/soc/fsl/fsl_ssi.c89
1 files changed, 46 insertions, 43 deletions
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index a85268bb4507..a96ab4e60652 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -108,13 +108,6 @@ static inline void write_ssi_mask(u32 __iomem *addr, u32 clear, u32 set)
108 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_LE) 108 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_LE)
109#endif 109#endif
110 110
111/* SIER bitflag of interrupts to enable */
112#define SIER_FLAGS (CCSR_SSI_SIER_TFRC_EN | CCSR_SSI_SIER_TDMAE | \
113 CCSR_SSI_SIER_TIE | CCSR_SSI_SIER_TUE0_EN | \
114 CCSR_SSI_SIER_TUE1_EN | CCSR_SSI_SIER_RFRC_EN | \
115 CCSR_SSI_SIER_RDMAE | CCSR_SSI_SIER_RIE | \
116 CCSR_SSI_SIER_ROE0_EN | CCSR_SSI_SIER_ROE1_EN)
117
118#define FSLSSI_SIER_DBG_RX_FLAGS (CCSR_SSI_SIER_RFF0_EN | \ 111#define FSLSSI_SIER_DBG_RX_FLAGS (CCSR_SSI_SIER_RFF0_EN | \
119 CCSR_SSI_SIER_RLS_EN | CCSR_SSI_SIER_RFS_EN | \ 112 CCSR_SSI_SIER_RLS_EN | CCSR_SSI_SIER_RFS_EN | \
120 CCSR_SSI_SIER_ROE0_EN | CCSR_SSI_SIER_RFRC_EN) 113 CCSR_SSI_SIER_ROE0_EN | CCSR_SSI_SIER_RFRC_EN)
@@ -584,6 +577,41 @@ static void fsl_ssi_tx_config(struct fsl_ssi_private *ssi_private, bool enable)
584 fsl_ssi_config(ssi_private, enable, &ssi_private->rxtx_reg_val.tx); 577 fsl_ssi_config(ssi_private, enable, &ssi_private->rxtx_reg_val.tx);
585} 578}
586 579
580/*
581 * Setup rx/tx register values used to enable/disable the streams. These will
582 * be used later in fsl_ssi_config to setup the streams without the need to
583 * check for all different SSI modes.
584 */
585static void fsl_ssi_setup_reg_vals(struct fsl_ssi_private *ssi_private)
586{
587 struct fsl_ssi_rxtx_reg_val *reg = &ssi_private->rxtx_reg_val;
588
589 reg->rx.sier = CCSR_SSI_SIER_RFF0_EN;
590 reg->rx.srcr = CCSR_SSI_SRCR_RFEN0;
591 reg->rx.scr = 0;
592 reg->tx.sier = CCSR_SSI_SIER_TFE0_EN;
593 reg->tx.stcr = CCSR_SSI_STCR_TFEN0;
594 reg->tx.scr = 0;
595
596 if (!ssi_private->imx_ac97) {
597 reg->rx.scr = CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE;
598 reg->rx.sier |= CCSR_SSI_SIER_RFF0_EN;
599 reg->tx.scr = CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE;
600 reg->tx.sier |= CCSR_SSI_SIER_TFE0_EN;
601 }
602
603 if (ssi_private->use_dma) {
604 reg->rx.sier |= CCSR_SSI_SIER_RDMAE;
605 reg->tx.sier |= CCSR_SSI_SIER_TDMAE;
606 } else {
607 reg->rx.sier |= CCSR_SSI_SIER_RIE;
608 reg->tx.sier |= CCSR_SSI_SIER_TIE;
609 }
610
611 reg->rx.sier |= FSLSSI_SIER_DBG_RX_FLAGS;
612 reg->tx.sier |= FSLSSI_SIER_DBG_TX_FLAGS;
613}
614
587static void fsl_ssi_setup_ac97(struct fsl_ssi_private *ssi_private) 615static void fsl_ssi_setup_ac97(struct fsl_ssi_private *ssi_private)
588{ 616{
589 struct ccsr_ssi __iomem *ssi = ssi_private->ssi; 617 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
@@ -620,6 +648,8 @@ static int fsl_ssi_setup(struct fsl_ssi_private *ssi_private)
620 u8 wm; 648 u8 wm;
621 int synchronous = ssi_private->cpu_dai_drv.symmetric_rates; 649 int synchronous = ssi_private->cpu_dai_drv.symmetric_rates;
622 650
651 fsl_ssi_setup_reg_vals(ssi_private);
652
623 if (ssi_private->imx_ac97) 653 if (ssi_private->imx_ac97)
624 ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_NORMAL | CCSR_SSI_SCR_NET; 654 ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_NORMAL | CCSR_SSI_SCR_NET;
625 else 655 else
@@ -643,13 +673,12 @@ static int fsl_ssi_setup(struct fsl_ssi_private *ssi_private)
643 ssi_private->i2s_mode | 673 ssi_private->i2s_mode |
644 (synchronous ? CCSR_SSI_SCR_SYN : 0)); 674 (synchronous ? CCSR_SSI_SCR_SYN : 0));
645 675
646 write_ssi(CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFEN0 | 676 write_ssi(CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFSI |
647 CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TEFS | 677 CCSR_SSI_STCR_TEFS | CCSR_SSI_STCR_TSCKP, &ssi->stcr);
648 CCSR_SSI_STCR_TSCKP, &ssi->stcr); 678
679 write_ssi(CCSR_SSI_SRCR_RXBIT0 | CCSR_SSI_SRCR_RFSI |
680 CCSR_SSI_SRCR_REFS | CCSR_SSI_SRCR_RSCKP, &ssi->srcr);
649 681
650 write_ssi(CCSR_SSI_SRCR_RXBIT0 | CCSR_SSI_SRCR_RFEN0 |
651 CCSR_SSI_SRCR_RFSI | CCSR_SSI_SRCR_REFS |
652 CCSR_SSI_SRCR_RSCKP, &ssi->srcr);
653 /* 682 /*
654 * The DC and PM bits are only used if the SSI is the clock master. 683 * The DC and PM bits are only used if the SSI is the clock master.
655 */ 684 */
@@ -1023,51 +1052,26 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
1023{ 1052{
1024 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1053 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1025 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai); 1054 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai);
1026 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
1027 unsigned int sier_bits;
1028 unsigned long flags; 1055 unsigned long flags;
1029 1056
1030 /*
1031 * Enable only the interrupts and DMA requests
1032 * that are needed for the channel. As the fiq
1033 * is polling for this bits, we have to ensure
1034 * that this are aligned with the preallocated
1035 * buffers
1036 */
1037
1038 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1039 if (ssi_private->use_dma)
1040 sier_bits = SIER_FLAGS;
1041 else
1042 sier_bits = CCSR_SSI_SIER_TIE | CCSR_SSI_SIER_TFE0_EN;
1043 } else {
1044 if (ssi_private->use_dma)
1045 sier_bits = SIER_FLAGS;
1046 else
1047 sier_bits = CCSR_SSI_SIER_RIE | CCSR_SSI_SIER_RFF0_EN;
1048 }
1049
1050 switch (cmd) { 1057 switch (cmd) {
1051 case SNDRV_PCM_TRIGGER_START: 1058 case SNDRV_PCM_TRIGGER_START:
1052 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 1059 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1053 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 1060 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1054 write_ssi_mask(&ssi->scr, 0, 1061 fsl_ssi_tx_config(ssi_private, true);
1055 CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE);
1056 else 1062 else
1057 write_ssi_mask(&ssi->scr, 0, 1063 fsl_ssi_rx_config(ssi_private, true);
1058 CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE);
1059 break; 1064 break;
1060 1065
1061 case SNDRV_PCM_TRIGGER_STOP: 1066 case SNDRV_PCM_TRIGGER_STOP:
1062 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 1067 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1063 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 1068 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1064 write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_TE, 0); 1069 fsl_ssi_tx_config(ssi_private, false);
1065 else 1070 else
1066 write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_RE, 0); 1071 fsl_ssi_rx_config(ssi_private, false);
1067 1072
1068 if (!ssi_private->imx_ac97 && (read_ssi(&ssi->scr) & 1073 if (!ssi_private->imx_ac97 && (read_ssi(&ssi->scr) &
1069 (CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE)) == 0) { 1074 (CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE)) == 0) {
1070 write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, 0);
1071 spin_lock_irqsave(&ssi_private->baudclk_lock, flags); 1075 spin_lock_irqsave(&ssi_private->baudclk_lock, flags);
1072 ssi_private->baudclk_locked = false; 1076 ssi_private->baudclk_locked = false;
1073 spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags); 1077 spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags);
@@ -1078,7 +1082,6 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
1078 return -EINVAL; 1082 return -EINVAL;
1079 } 1083 }
1080 1084
1081 write_ssi(sier_bits, &ssi->sier);
1082 1085
1083 return 0; 1086 return 0;
1084} 1087}