diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2009-03-13 10:26:08 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2009-03-14 07:37:46 -0400 |
commit | 0ce36c5f7f87632f26c8fbefe68b5116eda152d2 (patch) | |
tree | 16c74e694d5b8f418c0384c8079bbc9a8c2689aa /sound/soc/pxa | |
parent | 72d7466468b471f99cefae3c5f4a414bbbaa0bdd (diff) |
ASoC: Fix non-networked I2S mode for PXA SSP
Two issues are fixed here:
- I2S transmits the left frame with the clock low but I don't seem to
get LRCLK out without SFRMDLY being set so invert SFRMP and set a
delay.
- I2S has a clock cycle prior to the first data byte in each channel
so we need to delay the data by one cycle.
Tested-by: Daniel Mack <daniel@caiaq.de>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/pxa')
-rw-r--r-- | sound/soc/pxa/pxa-ssp.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c index 4dd0d7c57220..b0bf40973d5b 100644 --- a/sound/soc/pxa/pxa-ssp.c +++ b/sound/soc/pxa/pxa-ssp.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define DEBUG | ||
2 | /* | 1 | /* |
3 | * pxa-ssp.c -- ALSA Soc Audio Layer | 2 | * pxa-ssp.c -- ALSA Soc Audio Layer |
4 | * | 3 | * |
@@ -561,14 +560,15 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
561 | sscr0 |= SSCR0_PSP; | 560 | sscr0 |= SSCR0_PSP; |
562 | sscr1 |= SSCR1_RWOT | SSCR1_TRAIL; | 561 | sscr1 |= SSCR1_RWOT | SSCR1_TRAIL; |
563 | 562 | ||
563 | /* See hw_params() */ | ||
564 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | 564 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { |
565 | case SND_SOC_DAIFMT_NB_NF: | 565 | case SND_SOC_DAIFMT_NB_NF: |
566 | sspsp |= SSPSP_SFRMP; | ||
566 | break; | 567 | break; |
567 | case SND_SOC_DAIFMT_NB_IF: | 568 | case SND_SOC_DAIFMT_NB_IF: |
568 | sspsp |= SSPSP_SFRMP; | ||
569 | break; | 569 | break; |
570 | case SND_SOC_DAIFMT_IB_IF: | 570 | case SND_SOC_DAIFMT_IB_IF: |
571 | sspsp |= SSPSP_SFRMP | SSPSP_SCMODE(3); | 571 | sspsp |= SSPSP_SCMODE(3); |
572 | break; | 572 | break; |
573 | default: | 573 | default: |
574 | return -EINVAL; | 574 | return -EINVAL; |
@@ -691,8 +691,17 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream, | |||
691 | #else | 691 | #else |
692 | return -EINVAL; | 692 | return -EINVAL; |
693 | #endif | 693 | #endif |
694 | } else | 694 | } else { |
695 | sspsp |= SSPSP_SFRMWDTH(width); | 695 | /* The frame width is the width the LRCLK is |
696 | * asserted for; the delay is expressed in | ||
697 | * half cycle units. We need the extra cycle | ||
698 | * because the data starts clocking out one BCLK | ||
699 | * after LRCLK changes polarity. | ||
700 | */ | ||
701 | sspsp |= SSPSP_SFRMWDTH(width + 1); | ||
702 | sspsp |= SSPSP_SFRMDLY((width + 1) * 2); | ||
703 | sspsp |= SSPSP_DMYSTRT(1); | ||
704 | } | ||
696 | 705 | ||
697 | ssp_write_reg(ssp, SSPSP, sspsp); | 706 | ssp_write_reg(ssp, SSPSP, sspsp); |
698 | break; | 707 | break; |