aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/soc/pxa/pxa-ssp.c44
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 }