Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Fabio Falzoi and committed by
Mark Brown
cf4f7fc3 ae34a78c

+28 -5
+28 -5
sound/soc/fsl/fsl_ssi.c
··· 259 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 268 * fsl_ssi_isr: SSI interrupt handler 264 269 * ··· 710 705 } 711 706 } 712 707 708 + if (!fsl_ssi_is_ac97(ssi_private)) { 709 + u8 i2smode; 710 + /* 711 + * Switch to normal net mode in order to have a frame sync 712 + * signal every 32 bits instead of 16 bits 713 + */ 714 + if (fsl_ssi_is_i2s_cbm_cfs(ssi_private) && sample_size == 16) 715 + i2smode = CCSR_SSI_SCR_I2S_MODE_NORMAL | 716 + CCSR_SSI_SCR_NET; 717 + else 718 + i2smode = ssi_private->i2s_mode; 719 + 720 + regmap_update_bits(regs, CCSR_SSI_SCR, 721 + CCSR_SSI_SCR_NET | CCSR_SSI_SCR_I2S_MODE_MASK, 722 + channels == 1 ? 0 : i2smode); 723 + } 724 + 713 725 /* 714 726 * FIXME: The documentation says that SxCCR[WL] should not be 715 727 * modified while the SSI is enabled. The only time this can ··· 745 723 else 746 724 regmap_update_bits(regs, CCSR_SSI_SRCCR, CCSR_SSI_SxCCR_WL_MASK, 747 725 wl); 748 - 749 - if (!fsl_ssi_is_ac97(ssi_private)) 750 - regmap_update_bits(regs, CCSR_SSI_SCR, 751 - CCSR_SSI_SCR_NET | CCSR_SSI_SCR_I2S_MODE_MASK, 752 - channels == 1 ? 0 : ssi_private->i2s_mode); 753 726 754 727 return 0; 755 728 } ··· 797 780 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 798 781 case SND_SOC_DAIFMT_I2S: 799 782 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 783 + case SND_SOC_DAIFMT_CBM_CFS: 800 784 case SND_SOC_DAIFMT_CBS_CFS: 801 785 ssi_private->i2s_mode |= CCSR_SSI_SCR_I2S_MODE_MASTER; 802 786 regmap_update_bits(regs, CCSR_SSI_STCCR, ··· 869 851 scr |= CCSR_SSI_SCR_SYS_CLK_EN; 870 852 break; 871 853 case SND_SOC_DAIFMT_CBM_CFM: 854 + scr &= ~CCSR_SSI_SCR_SYS_CLK_EN; 855 + break; 856 + case SND_SOC_DAIFMT_CBM_CFS: 857 + strcr &= ~CCSR_SSI_STCR_TXDIR; 858 + strcr |= CCSR_SSI_STCR_TFDIR; 872 859 scr &= ~CCSR_SSI_SCR_SYS_CLK_EN; 873 860 break; 874 861 default: