diff options
-rw-r--r-- | sound/soc/pxa/pxa-ssp.c | 44 |
1 files changed, 33 insertions, 11 deletions
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c index d3fa6357a9fd..4dd0d7c57220 100644 --- a/sound/soc/pxa/pxa-ssp.c +++ b/sound/soc/pxa/pxa-ssp.c | |||
@@ -558,18 +558,17 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
558 | 558 | ||
559 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | 559 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
560 | case SND_SOC_DAIFMT_I2S: | 560 | case SND_SOC_DAIFMT_I2S: |
561 | sscr0 |= SSCR0_MOD | SSCR0_PSP; | 561 | sscr0 |= SSCR0_PSP; |
562 | sscr1 |= SSCR1_RWOT | SSCR1_TRAIL; | 562 | sscr1 |= SSCR1_RWOT | SSCR1_TRAIL; |
563 | 563 | ||
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_FSRT; | ||
567 | break; | 566 | break; |
568 | case SND_SOC_DAIFMT_NB_IF: | 567 | case SND_SOC_DAIFMT_NB_IF: |
569 | sspsp |= SSPSP_SFRMP | SSPSP_FSRT; | 568 | sspsp |= SSPSP_SFRMP; |
570 | break; | 569 | break; |
571 | case SND_SOC_DAIFMT_IB_IF: | 570 | case SND_SOC_DAIFMT_IB_IF: |
572 | sspsp |= SSPSP_SFRMP; | 571 | sspsp |= SSPSP_SFRMP | SSPSP_SCMODE(3); |
573 | break; | 572 | break; |
574 | default: | 573 | default: |
575 | return -EINVAL; | 574 | return -EINVAL; |
@@ -655,33 +654,56 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream, | |||
655 | sscr0 |= SSCR0_FPCKE; | 654 | sscr0 |= SSCR0_FPCKE; |
656 | #endif | 655 | #endif |
657 | sscr0 |= SSCR0_DataSize(16); | 656 | sscr0 |= SSCR0_DataSize(16); |
658 | /* use network mode (2 slots) for 16 bit stereo */ | ||
659 | break; | 657 | break; |
660 | case SNDRV_PCM_FORMAT_S24_LE: | 658 | case SNDRV_PCM_FORMAT_S24_LE: |
661 | sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(8)); | 659 | sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(8)); |
662 | /* we must be in network mode (2 slots) for 24 bit stereo */ | ||
663 | break; | 660 | break; |
664 | case SNDRV_PCM_FORMAT_S32_LE: | 661 | case SNDRV_PCM_FORMAT_S32_LE: |
665 | sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(16)); | 662 | sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(16)); |
666 | /* we must be in network mode (2 slots) for 32 bit stereo */ | ||
667 | break; | 663 | break; |
668 | } | 664 | } |
669 | ssp_write_reg(ssp, SSCR0, sscr0); | 665 | ssp_write_reg(ssp, SSCR0, sscr0); |
670 | 666 | ||
671 | switch (priv->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | 667 | switch (priv->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
672 | case SND_SOC_DAIFMT_I2S: | 668 | case SND_SOC_DAIFMT_I2S: |
673 | /* Cleared when the DAI format is set */ | 669 | sspsp = ssp_read_reg(ssp, SSPSP); |
674 | sspsp = ssp_read_reg(ssp, SSPSP) | SSPSP_SFRMWDTH(width); | 670 | |
671 | if (((sscr0 & SSCR0_SCR) == SSCR0_SerClkDiv(4)) && | ||
672 | (width == 16)) { | ||
673 | /* This is a special case where the bitclk is 64fs | ||
674 | * and we're not dealing with 2*32 bits of audio | ||
675 | * samples. | ||
676 | * | ||
677 | * The SSP values used for that are all found out by | ||
678 | * trying and failing a lot; some of the registers | ||
679 | * needed for that mode are only available on PXA3xx. | ||
680 | */ | ||
681 | |||
682 | #ifdef CONFIG_PXA3xx | ||
683 | if (!cpu_is_pxa3xx()) | ||
684 | return -EINVAL; | ||
685 | |||
686 | sspsp |= SSPSP_SFRMWDTH(width * 2); | ||
687 | sspsp |= SSPSP_SFRMDLY(width * 4); | ||
688 | sspsp |= SSPSP_EDMYSTOP(3); | ||
689 | sspsp |= SSPSP_DMYSTOP(3); | ||
690 | sspsp |= SSPSP_DMYSTRT(1); | ||
691 | #else | ||
692 | return -EINVAL; | ||
693 | #endif | ||
694 | } else | ||
695 | sspsp |= SSPSP_SFRMWDTH(width); | ||
696 | |||
675 | ssp_write_reg(ssp, SSPSP, sspsp); | 697 | ssp_write_reg(ssp, SSPSP, sspsp); |
676 | break; | 698 | break; |
677 | default: | 699 | default: |
678 | break; | 700 | break; |
679 | } | 701 | } |
680 | 702 | ||
681 | /* We always use a network mode so we always require TDM slots | 703 | /* When we use a network mode, we always require TDM slots |
682 | * - complain loudly and fail if they've not been set up yet. | 704 | * - complain loudly and fail if they've not been set up yet. |
683 | */ | 705 | */ |
684 | if (!(ssp_read_reg(ssp, SSTSA) & 0xf)) { | 706 | if ((sscr0 & SSCR0_MOD) && !(ssp_read_reg(ssp, SSTSA) & 0xf)) { |
685 | dev_err(&ssp->pdev->dev, "No TDM timeslot configured\n"); | 707 | dev_err(&ssp->pdev->dev, "No TDM timeslot configured\n"); |
686 | return -EINVAL; | 708 | return -EINVAL; |
687 | } | 709 | } |