diff options
Diffstat (limited to 'sound/soc/fsl')
-rw-r--r-- | sound/soc/fsl/fsl_ssi.c | 89 |
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 | */ | ||
585 | static 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 | |||
587 | static void fsl_ssi_setup_ac97(struct fsl_ssi_private *ssi_private) | 615 | static 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 | } |