aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2009-03-17 15:07:26 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-03-17 15:07:26 -0400
commitda88b48b84e1a504b6a19aff9d5b8236a59e228a (patch)
tree1ec0fc6ecf51c7baf7bf6cfbd9250c3fee16a09b /sound
parentd2314e0e27566f8830ebed3587cc049e07e6a4ee (diff)
parent85fab7802a4bc00cc752f430e22a0d9fc41fe199 (diff)
Merge branch 'pxa-ssp' into for-2.6.30
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/pxa/pxa-ssp.c55
-rw-r--r--sound/soc/pxa/zylonite.c55
2 files changed, 68 insertions, 42 deletions
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index d3fa6357a9fd..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 *
@@ -558,18 +557,18 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
558 557
559 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 558 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
560 case SND_SOC_DAIFMT_I2S: 559 case SND_SOC_DAIFMT_I2S:
561 sscr0 |= SSCR0_MOD | 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_FSRT; 566 sspsp |= SSPSP_SFRMP;
567 break; 567 break;
568 case SND_SOC_DAIFMT_NB_IF: 568 case SND_SOC_DAIFMT_NB_IF:
569 sspsp |= SSPSP_SFRMP | SSPSP_FSRT;
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_SCMODE(3);
573 break; 572 break;
574 default: 573 default:
575 return -EINVAL; 574 return -EINVAL;
@@ -655,33 +654,65 @@ 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 /* 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 }
705
675 ssp_write_reg(ssp, SSPSP, sspsp); 706 ssp_write_reg(ssp, SSPSP, sspsp);
676 break; 707 break;
677 default: 708 default:
678 break; 709 break;
679 } 710 }
680 711
681 /* We always use a network mode so we always require TDM slots 712 /* When we use a network mode, we always require TDM slots
682 * - complain loudly and fail if they've not been set up yet. 713 * - complain loudly and fail if they've not been set up yet.
683 */ 714 */
684 if (!(ssp_read_reg(ssp, SSTSA) & 0xf)) { 715 if ((sscr0 & SSCR0_MOD) && !(ssp_read_reg(ssp, SSTSA) & 0xf)) {
685 dev_err(&ssp->pdev->dev, "No TDM timeslot configured\n"); 716 dev_err(&ssp->pdev->dev, "No TDM timeslot configured\n");
686 return -EINVAL; 717 return -EINVAL;
687 } 718 }
diff --git a/sound/soc/pxa/zylonite.c b/sound/soc/pxa/zylonite.c
index 9f6116edbb84..9a386b4c4ed1 100644
--- a/sound/soc/pxa/zylonite.c
+++ b/sound/soc/pxa/zylonite.c
@@ -96,42 +96,35 @@ static int zylonite_voice_hw_params(struct snd_pcm_substream *substream,
96 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 96 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
97 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 97 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
98 unsigned int pll_out = 0; 98 unsigned int pll_out = 0;
99 unsigned int acds = 0;
100 unsigned int wm9713_div = 0; 99 unsigned int wm9713_div = 0;
101 int ret = 0; 100 int ret = 0;
102 101 int rate = params_rate(params);
103 switch (params_rate(params)) { 102 int width = snd_pcm_format_physical_width(params_format(params));
103
104 /* Only support ratios that we can generate neatly from the AC97
105 * based master clock - in particular, this excludes 44.1kHz.
106 * In most applications the voice DAC will be used for telephony
107 * data so multiples of 8kHz will be the common case.
108 */
109 switch (rate) {
104 case 8000: 110 case 8000:
105 wm9713_div = 12; 111 wm9713_div = 12;
106 pll_out = 2048000;
107 break; 112 break;
108 case 16000: 113 case 16000:
109 wm9713_div = 6; 114 wm9713_div = 6;
110 pll_out = 4096000;
111 break; 115 break;
112 case 48000: 116 case 48000:
113 default:
114 wm9713_div = 2; 117 wm9713_div = 2;
115 pll_out = 12288000;
116 acds = 1;
117 break; 118 break;
119 default:
120 /* Don't support OSS emulation */
121 return -EINVAL;
118 } 122 }
119 123
120 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | 124 /* Add 1 to the width for the leading clock cycle */
121 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); 125 pll_out = rate * (width + 1) * 8;
122 if (ret < 0)
123 return ret;
124
125 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
126 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
127 if (ret < 0)
128 return ret;
129 126
130 /* Use network mode for stereo, one slot per channel. */ 127 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_AUDIO, 0, 1);
131 if (params_channels(params) > 1)
132 ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0x3, 2);
133 else
134 ret = snd_soc_dai_set_tdm_slot(cpu_dai, 1, 1);
135 if (ret < 0) 128 if (ret < 0)
136 return ret; 129 return ret;
137 130
@@ -139,14 +132,6 @@ static int zylonite_voice_hw_params(struct snd_pcm_substream *substream,
139 if (ret < 0) 132 if (ret < 0)
140 return ret; 133 return ret;
141 134
142 ret = snd_soc_dai_set_clkdiv(cpu_dai, PXA_SSP_AUDIO_DIV_ACDS, acds);
143 if (ret < 0)
144 return ret;
145
146 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_AUDIO, 0, 1);
147 if (ret < 0)
148 return ret;
149
150 if (clk_pout) 135 if (clk_pout)
151 ret = snd_soc_dai_set_clkdiv(codec_dai, WM9713_PCMCLK_PLL_DIV, 136 ret = snd_soc_dai_set_clkdiv(codec_dai, WM9713_PCMCLK_PLL_DIV,
152 WM9713_PCMDIV(wm9713_div)); 137 WM9713_PCMDIV(wm9713_div));
@@ -156,6 +141,16 @@ static int zylonite_voice_hw_params(struct snd_pcm_substream *substream,
156 if (ret < 0) 141 if (ret < 0)
157 return ret; 142 return ret;
158 143
144 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
145 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
146 if (ret < 0)
147 return ret;
148
149 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
150 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
151 if (ret < 0)
152 return ret;
153
159 return 0; 154 return 0;
160} 155}
161 156