aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/pxa/pxa-ssp.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/pxa/pxa-ssp.c')
-rw-r--r--sound/soc/pxa/pxa-ssp.c90
1 files changed, 61 insertions, 29 deletions
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index 3bd7712f029b..cf00df9c40f4 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -42,11 +42,14 @@
42 * SSP audio private data 42 * SSP audio private data
43 */ 43 */
44struct ssp_priv { 44struct ssp_priv {
45 struct ssp_dev dev; 45 struct ssp_device *ssp;
46 unsigned int sysclk; 46 unsigned int sysclk;
47 int dai_fmt; 47 int dai_fmt;
48#ifdef CONFIG_PM 48#ifdef CONFIG_PM
49 struct ssp_state state; 49 uint32_t cr0;
50 uint32_t cr1;
51 uint32_t to;
52 uint32_t psp;
50#endif 53#endif
51}; 54};
52 55
@@ -61,6 +64,22 @@ static void dump_registers(struct ssp_device *ssp)
61 ssp_read_reg(ssp, SSACD)); 64 ssp_read_reg(ssp, SSACD));
62} 65}
63 66
67static void ssp_enable(struct ssp_device *ssp)
68{
69 uint32_t sscr0;
70
71 sscr0 = __raw_readl(ssp->mmio_base + SSCR0) | SSCR0_SSE;
72 __raw_writel(sscr0, ssp->mmio_base + SSCR0);
73}
74
75static void ssp_disable(struct ssp_device *ssp)
76{
77 uint32_t sscr0;
78
79 sscr0 = __raw_readl(ssp->mmio_base + SSCR0) & ~SSCR0_SSE;
80 __raw_writel(sscr0, ssp->mmio_base + SSCR0);
81}
82
64struct pxa2xx_pcm_dma_data { 83struct pxa2xx_pcm_dma_data {
65 struct pxa2xx_pcm_dma_params params; 84 struct pxa2xx_pcm_dma_params params;
66 char name[20]; 85 char name[20];
@@ -94,13 +113,12 @@ static int pxa_ssp_startup(struct snd_pcm_substream *substream,
94 struct snd_soc_pcm_runtime *rtd = substream->private_data; 113 struct snd_soc_pcm_runtime *rtd = substream->private_data;
95 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 114 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
96 struct ssp_priv *priv = cpu_dai->private_data; 115 struct ssp_priv *priv = cpu_dai->private_data;
116 struct ssp_device *ssp = priv->ssp;
97 int ret = 0; 117 int ret = 0;
98 118
99 if (!cpu_dai->active) { 119 if (!cpu_dai->active) {
100 priv->dev.port = cpu_dai->id + 1; 120 clk_enable(ssp->clk);
101 priv->dev.irq = NO_IRQ; 121 ssp_disable(ssp);
102 clk_enable(priv->dev.ssp->clk);
103 ssp_disable(&priv->dev);
104 } 122 }
105 123
106 if (cpu_dai->dma_data) { 124 if (cpu_dai->dma_data) {
@@ -116,10 +134,11 @@ static void pxa_ssp_shutdown(struct snd_pcm_substream *substream,
116 struct snd_soc_pcm_runtime *rtd = substream->private_data; 134 struct snd_soc_pcm_runtime *rtd = substream->private_data;
117 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 135 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
118 struct ssp_priv *priv = cpu_dai->private_data; 136 struct ssp_priv *priv = cpu_dai->private_data;
137 struct ssp_device *ssp = priv->ssp;
119 138
120 if (!cpu_dai->active) { 139 if (!cpu_dai->active) {
121 ssp_disable(&priv->dev); 140 ssp_disable(ssp);
122 clk_disable(priv->dev.ssp->clk); 141 clk_disable(ssp->clk);
123 } 142 }
124 143
125 if (cpu_dai->dma_data) { 144 if (cpu_dai->dma_data) {
@@ -133,26 +152,39 @@ static void pxa_ssp_shutdown(struct snd_pcm_substream *substream,
133static int pxa_ssp_suspend(struct snd_soc_dai *cpu_dai) 152static int pxa_ssp_suspend(struct snd_soc_dai *cpu_dai)
134{ 153{
135 struct ssp_priv *priv = cpu_dai->private_data; 154 struct ssp_priv *priv = cpu_dai->private_data;
155 struct ssp_device *ssp = priv->ssp;
136 156
137 if (!cpu_dai->active) 157 if (!cpu_dai->active)
138 return 0; 158 return 0;
139 159
140 ssp_save_state(&priv->dev, &priv->state); 160 priv->cr0 = __raw_readl(ssp->mmio_base + SSCR0);
141 clk_disable(priv->dev.ssp->clk); 161 priv->cr1 = __raw_readl(ssp->mmio_base + SSCR1);
162 priv->to = __raw_readl(ssp->mmio_base + SSTO);
163 priv->psp = __raw_readl(ssp->mmio_base + SSPSP);
164
165 ssp_disable(ssp);
166 clk_disable(ssp->clk);
142 return 0; 167 return 0;
143} 168}
144 169
145static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai) 170static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai)
146{ 171{
147 struct ssp_priv *priv = cpu_dai->private_data; 172 struct ssp_priv *priv = cpu_dai->private_data;
173 struct ssp_device *ssp = priv->ssp;
174 uint32_t sssr = SSSR_ROR | SSSR_TUR | SSSR_BCE;
148 175
149 if (!cpu_dai->active) 176 if (!cpu_dai->active)
150 return 0; 177 return 0;
151 178
152 clk_enable(priv->dev.ssp->clk); 179 clk_enable(ssp->clk);
153 ssp_restore_state(&priv->dev, &priv->state); 180
154 ssp_enable(&priv->dev); 181 __raw_writel(sssr, ssp->mmio_base + SSSR);
155 182
183 __raw_writel(priv->cr0 & ~SSCR0_SSE, ssp->mmio_base + SSCR0);
184 __raw_writel(priv->cr1, ssp->mmio_base + SSCR1);
185 __raw_writel(priv->to, ssp->mmio_base + SSTO);
186 __raw_writel(priv->psp, ssp->mmio_base + SSPSP);
187 __raw_writel(priv->cr0 | SSCR0_SSE, ssp->mmio_base + SSCR0);
156 return 0; 188 return 0;
157} 189}
158 190
@@ -201,7 +233,7 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
201 int clk_id, unsigned int freq, int dir) 233 int clk_id, unsigned int freq, int dir)
202{ 234{
203 struct ssp_priv *priv = cpu_dai->private_data; 235 struct ssp_priv *priv = cpu_dai->private_data;
204 struct ssp_device *ssp = priv->dev.ssp; 236 struct ssp_device *ssp = priv->ssp;
205 int val; 237 int val;
206 238
207 u32 sscr0 = ssp_read_reg(ssp, SSCR0) & 239 u32 sscr0 = ssp_read_reg(ssp, SSCR0) &
@@ -242,11 +274,11 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
242 /* The SSP clock must be disabled when changing SSP clock mode 274 /* The SSP clock must be disabled when changing SSP clock mode
243 * on PXA2xx. On PXA3xx it must be enabled when doing so. */ 275 * on PXA2xx. On PXA3xx it must be enabled when doing so. */
244 if (!cpu_is_pxa3xx()) 276 if (!cpu_is_pxa3xx())
245 clk_disable(priv->dev.ssp->clk); 277 clk_disable(ssp->clk);
246 val = ssp_read_reg(ssp, SSCR0) | sscr0; 278 val = ssp_read_reg(ssp, SSCR0) | sscr0;
247 ssp_write_reg(ssp, SSCR0, val); 279 ssp_write_reg(ssp, SSCR0, val);
248 if (!cpu_is_pxa3xx()) 280 if (!cpu_is_pxa3xx())
249 clk_enable(priv->dev.ssp->clk); 281 clk_enable(ssp->clk);
250 282
251 return 0; 283 return 0;
252} 284}
@@ -258,7 +290,7 @@ static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
258 int div_id, int div) 290 int div_id, int div)
259{ 291{
260 struct ssp_priv *priv = cpu_dai->private_data; 292 struct ssp_priv *priv = cpu_dai->private_data;
261 struct ssp_device *ssp = priv->dev.ssp; 293 struct ssp_device *ssp = priv->ssp;
262 int val; 294 int val;
263 295
264 switch (div_id) { 296 switch (div_id) {
@@ -309,7 +341,7 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id,
309 int source, unsigned int freq_in, unsigned int freq_out) 341 int source, unsigned int freq_in, unsigned int freq_out)
310{ 342{
311 struct ssp_priv *priv = cpu_dai->private_data; 343 struct ssp_priv *priv = cpu_dai->private_data;
312 struct ssp_device *ssp = priv->dev.ssp; 344 struct ssp_device *ssp = priv->ssp;
313 u32 ssacd = ssp_read_reg(ssp, SSACD) & ~0x70; 345 u32 ssacd = ssp_read_reg(ssp, SSACD) & ~0x70;
314 346
315#if defined(CONFIG_PXA3xx) 347#if defined(CONFIG_PXA3xx)
@@ -378,7 +410,7 @@ static int pxa_ssp_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
378 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width) 410 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
379{ 411{
380 struct ssp_priv *priv = cpu_dai->private_data; 412 struct ssp_priv *priv = cpu_dai->private_data;
381 struct ssp_device *ssp = priv->dev.ssp; 413 struct ssp_device *ssp = priv->ssp;
382 u32 sscr0; 414 u32 sscr0;
383 415
384 sscr0 = ssp_read_reg(ssp, SSCR0); 416 sscr0 = ssp_read_reg(ssp, SSCR0);
@@ -413,7 +445,7 @@ static int pxa_ssp_set_dai_tristate(struct snd_soc_dai *cpu_dai,
413 int tristate) 445 int tristate)
414{ 446{
415 struct ssp_priv *priv = cpu_dai->private_data; 447 struct ssp_priv *priv = cpu_dai->private_data;
416 struct ssp_device *ssp = priv->dev.ssp; 448 struct ssp_device *ssp = priv->ssp;
417 u32 sscr1; 449 u32 sscr1;
418 450
419 sscr1 = ssp_read_reg(ssp, SSCR1); 451 sscr1 = ssp_read_reg(ssp, SSCR1);
@@ -435,7 +467,7 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
435 unsigned int fmt) 467 unsigned int fmt)
436{ 468{
437 struct ssp_priv *priv = cpu_dai->private_data; 469 struct ssp_priv *priv = cpu_dai->private_data;
438 struct ssp_device *ssp = priv->dev.ssp; 470 struct ssp_device *ssp = priv->ssp;
439 u32 sscr0; 471 u32 sscr0;
440 u32 sscr1; 472 u32 sscr1;
441 u32 sspsp; 473 u32 sspsp;
@@ -530,7 +562,7 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
530 struct snd_soc_pcm_runtime *rtd = substream->private_data; 562 struct snd_soc_pcm_runtime *rtd = substream->private_data;
531 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 563 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
532 struct ssp_priv *priv = cpu_dai->private_data; 564 struct ssp_priv *priv = cpu_dai->private_data;
533 struct ssp_device *ssp = priv->dev.ssp; 565 struct ssp_device *ssp = priv->ssp;
534 int chn = params_channels(params); 566 int chn = params_channels(params);
535 u32 sscr0; 567 u32 sscr0;
536 u32 sspsp; 568 u32 sspsp;
@@ -640,12 +672,12 @@ static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
640 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 672 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
641 int ret = 0; 673 int ret = 0;
642 struct ssp_priv *priv = cpu_dai->private_data; 674 struct ssp_priv *priv = cpu_dai->private_data;
643 struct ssp_device *ssp = priv->dev.ssp; 675 struct ssp_device *ssp = priv->ssp;
644 int val; 676 int val;
645 677
646 switch (cmd) { 678 switch (cmd) {
647 case SNDRV_PCM_TRIGGER_RESUME: 679 case SNDRV_PCM_TRIGGER_RESUME:
648 ssp_enable(&priv->dev); 680 ssp_enable(ssp);
649 break; 681 break;
650 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 682 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
651 val = ssp_read_reg(ssp, SSCR1); 683 val = ssp_read_reg(ssp, SSCR1);
@@ -664,7 +696,7 @@ static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
664 else 696 else
665 val |= SSCR1_RSRE; 697 val |= SSCR1_RSRE;
666 ssp_write_reg(ssp, SSCR1, val); 698 ssp_write_reg(ssp, SSCR1, val);
667 ssp_enable(&priv->dev); 699 ssp_enable(ssp);
668 break; 700 break;
669 case SNDRV_PCM_TRIGGER_STOP: 701 case SNDRV_PCM_TRIGGER_STOP:
670 val = ssp_read_reg(ssp, SSCR1); 702 val = ssp_read_reg(ssp, SSCR1);
@@ -675,7 +707,7 @@ static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
675 ssp_write_reg(ssp, SSCR1, val); 707 ssp_write_reg(ssp, SSCR1, val);
676 break; 708 break;
677 case SNDRV_PCM_TRIGGER_SUSPEND: 709 case SNDRV_PCM_TRIGGER_SUSPEND:
678 ssp_disable(&priv->dev); 710 ssp_disable(ssp);
679 break; 711 break;
680 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 712 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
681 val = ssp_read_reg(ssp, SSCR1); 713 val = ssp_read_reg(ssp, SSCR1);
@@ -705,8 +737,8 @@ static int pxa_ssp_probe(struct platform_device *pdev,
705 if (!priv) 737 if (!priv)
706 return -ENOMEM; 738 return -ENOMEM;
707 739
708 priv->dev.ssp = ssp_request(dai->id + 1, "SoC audio"); 740 priv->ssp = ssp_request(dai->id + 1, "SoC audio");
709 if (priv->dev.ssp == NULL) { 741 if (priv->ssp == NULL) {
710 ret = -ENODEV; 742 ret = -ENODEV;
711 goto err_priv; 743 goto err_priv;
712 } 744 }
@@ -725,7 +757,7 @@ static void pxa_ssp_remove(struct platform_device *pdev,
725 struct snd_soc_dai *dai) 757 struct snd_soc_dai *dai)
726{ 758{
727 struct ssp_priv *priv = dai->private_data; 759 struct ssp_priv *priv = dai->private_data;
728 ssp_free(priv->dev.ssp); 760 ssp_free(priv->ssp);
729} 761}
730 762
731#define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ 763#define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\