diff options
author | Fabio Falzoi <fabio.falzoi84@gmail.com> | 2014-08-04 11:08:07 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-08-07 13:45:38 -0400 |
commit | cf4f7fc3e7336e2e946880890e60ed36178889ea (patch) | |
tree | 6b8c72d36e7ae42833c4807a5a21869238cf20ae | |
parent | ae34a78c430c37c06404f032fb04e51315204281 (diff) |
ASoC: fsl-ssi: Support for SND_SOC_DAIFMT_CBM_CFS
Add SND_SOC_DAIFMT_CBM_CFS support for Freescale architecture.
Successfully tested on i.MX 6Quad Wandboard and UDOO boards connected to
the pcm1792a codec.
In CBM_CFS mode, when using a sample size of 16 bits, we cannot use
CCSR_SSI_SCR_I2S_MODE_MASTER since we get a frame sync every 16 bits.
Signed-off-by: Michael Trimarchi <michael@amarulasolutions.com>
Signed-off-by: Fabio Falzoi <fabio.falzoi84@gmail.com>
Tested-by: Angelo Adamo <adamo.a60@gmail.com>
Acked-by: Timur Tabi <timur@tabi.org>
Signed-off-by: Mark Brown <broonie@linaro.org>
-rw-r--r-- | sound/soc/fsl/fsl_ssi.c | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 87eb5776a39b..2fc3e6683e4f 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c | |||
@@ -259,6 +259,11 @@ static bool fsl_ssi_is_i2s_master(struct fsl_ssi_private *ssi_private) | |||
259 | SND_SOC_DAIFMT_CBS_CFS; | 259 | SND_SOC_DAIFMT_CBS_CFS; |
260 | } | 260 | } |
261 | 261 | ||
262 | static bool fsl_ssi_is_i2s_cbm_cfs(struct fsl_ssi_private *ssi_private) | ||
263 | { | ||
264 | return (ssi_private->dai_fmt & SND_SOC_DAIFMT_MASTER_MASK) == | ||
265 | SND_SOC_DAIFMT_CBM_CFS; | ||
266 | } | ||
262 | /** | 267 | /** |
263 | * fsl_ssi_isr: SSI interrupt handler | 268 | * fsl_ssi_isr: SSI interrupt handler |
264 | * | 269 | * |
@@ -705,6 +710,23 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream, | |||
705 | } | 710 | } |
706 | } | 711 | } |
707 | 712 | ||
713 | if (!fsl_ssi_is_ac97(ssi_private)) { | ||
714 | u8 i2smode; | ||
715 | /* | ||
716 | * Switch to normal net mode in order to have a frame sync | ||
717 | * signal every 32 bits instead of 16 bits | ||
718 | */ | ||
719 | if (fsl_ssi_is_i2s_cbm_cfs(ssi_private) && sample_size == 16) | ||
720 | i2smode = CCSR_SSI_SCR_I2S_MODE_NORMAL | | ||
721 | CCSR_SSI_SCR_NET; | ||
722 | else | ||
723 | i2smode = ssi_private->i2s_mode; | ||
724 | |||
725 | regmap_update_bits(regs, CCSR_SSI_SCR, | ||
726 | CCSR_SSI_SCR_NET | CCSR_SSI_SCR_I2S_MODE_MASK, | ||
727 | channels == 1 ? 0 : i2smode); | ||
728 | } | ||
729 | |||
708 | /* | 730 | /* |
709 | * FIXME: The documentation says that SxCCR[WL] should not be | 731 | * FIXME: The documentation says that SxCCR[WL] should not be |
710 | * modified while the SSI is enabled. The only time this can | 732 | * modified while the SSI is enabled. The only time this can |
@@ -724,11 +746,6 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream, | |||
724 | regmap_update_bits(regs, CCSR_SSI_SRCCR, CCSR_SSI_SxCCR_WL_MASK, | 746 | regmap_update_bits(regs, CCSR_SSI_SRCCR, CCSR_SSI_SxCCR_WL_MASK, |
725 | wl); | 747 | wl); |
726 | 748 | ||
727 | if (!fsl_ssi_is_ac97(ssi_private)) | ||
728 | regmap_update_bits(regs, CCSR_SSI_SCR, | ||
729 | CCSR_SSI_SCR_NET | CCSR_SSI_SCR_I2S_MODE_MASK, | ||
730 | channels == 1 ? 0 : ssi_private->i2s_mode); | ||
731 | |||
732 | return 0; | 749 | return 0; |
733 | } | 750 | } |
734 | 751 | ||
@@ -780,6 +797,7 @@ static int _fsl_ssi_set_dai_fmt(struct fsl_ssi_private *ssi_private, | |||
780 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | 797 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
781 | case SND_SOC_DAIFMT_I2S: | 798 | case SND_SOC_DAIFMT_I2S: |
782 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | 799 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
800 | case SND_SOC_DAIFMT_CBM_CFS: | ||
783 | case SND_SOC_DAIFMT_CBS_CFS: | 801 | case SND_SOC_DAIFMT_CBS_CFS: |
784 | ssi_private->i2s_mode |= CCSR_SSI_SCR_I2S_MODE_MASTER; | 802 | ssi_private->i2s_mode |= CCSR_SSI_SCR_I2S_MODE_MASTER; |
785 | regmap_update_bits(regs, CCSR_SSI_STCCR, | 803 | regmap_update_bits(regs, CCSR_SSI_STCCR, |
@@ -853,6 +871,11 @@ static int _fsl_ssi_set_dai_fmt(struct fsl_ssi_private *ssi_private, | |||
853 | case SND_SOC_DAIFMT_CBM_CFM: | 871 | case SND_SOC_DAIFMT_CBM_CFM: |
854 | scr &= ~CCSR_SSI_SCR_SYS_CLK_EN; | 872 | scr &= ~CCSR_SSI_SCR_SYS_CLK_EN; |
855 | break; | 873 | break; |
874 | case SND_SOC_DAIFMT_CBM_CFS: | ||
875 | strcr &= ~CCSR_SSI_STCR_TXDIR; | ||
876 | strcr |= CCSR_SSI_STCR_TFDIR; | ||
877 | scr &= ~CCSR_SSI_SCR_SYS_CLK_EN; | ||
878 | break; | ||
856 | default: | 879 | default: |
857 | return -EINVAL; | 880 | return -EINVAL; |
858 | } | 881 | } |