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.c93
1 files changed, 62 insertions, 31 deletions
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index e69397f40f72..9e95e5117c88 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,27 +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 clk_enable(priv->dev.ssp->clk); 158 clk_enable(ssp->clk);
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);
142 164
165 ssp_disable(ssp);
166 clk_disable(ssp->clk);
143 return 0; 167 return 0;
144} 168}
145 169
146static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai) 170static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai)
147{ 171{
148 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;
175
176 clk_enable(ssp->clk);
149 177
150 clk_enable(priv->dev.ssp->clk); 178 __raw_writel(sssr, ssp->mmio_base + SSSR);
151 ssp_restore_state(&priv->dev, &priv->state); 179 __raw_writel(priv->cr0 & ~SSCR0_SSE, ssp->mmio_base + SSCR0);
180 __raw_writel(priv->cr1, ssp->mmio_base + SSCR1);
181 __raw_writel(priv->to, ssp->mmio_base + SSTO);
182 __raw_writel(priv->psp, ssp->mmio_base + SSPSP);
152 183
153 if (cpu_dai->active) 184 if (cpu_dai->active)
154 ssp_enable(&priv->dev); 185 ssp_enable(ssp);
155 else 186 else
156 clk_disable(priv->dev.ssp->clk); 187 clk_disable(ssp->clk);
157 188
158 return 0; 189 return 0;
159} 190}
@@ -203,7 +234,7 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
203 int clk_id, unsigned int freq, int dir) 234 int clk_id, unsigned int freq, int dir)
204{ 235{
205 struct ssp_priv *priv = cpu_dai->private_data; 236 struct ssp_priv *priv = cpu_dai->private_data;
206 struct ssp_device *ssp = priv->dev.ssp; 237 struct ssp_device *ssp = priv->ssp;
207 int val; 238 int val;
208 239
209 u32 sscr0 = ssp_read_reg(ssp, SSCR0) & 240 u32 sscr0 = ssp_read_reg(ssp, SSCR0) &
@@ -244,11 +275,11 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
244 /* The SSP clock must be disabled when changing SSP clock mode 275 /* The SSP clock must be disabled when changing SSP clock mode
245 * on PXA2xx. On PXA3xx it must be enabled when doing so. */ 276 * on PXA2xx. On PXA3xx it must be enabled when doing so. */
246 if (!cpu_is_pxa3xx()) 277 if (!cpu_is_pxa3xx())
247 clk_disable(priv->dev.ssp->clk); 278 clk_disable(ssp->clk);
248 val = ssp_read_reg(ssp, SSCR0) | sscr0; 279 val = ssp_read_reg(ssp, SSCR0) | sscr0;
249 ssp_write_reg(ssp, SSCR0, val); 280 ssp_write_reg(ssp, SSCR0, val);
250 if (!cpu_is_pxa3xx()) 281 if (!cpu_is_pxa3xx())
251 clk_enable(priv->dev.ssp->clk); 282 clk_enable(ssp->clk);
252 283
253 return 0; 284 return 0;
254} 285}
@@ -260,7 +291,7 @@ static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
260 int div_id, int div) 291 int div_id, int div)
261{ 292{
262 struct ssp_priv *priv = cpu_dai->private_data; 293 struct ssp_priv *priv = cpu_dai->private_data;
263 struct ssp_device *ssp = priv->dev.ssp; 294 struct ssp_device *ssp = priv->ssp;
264 int val; 295 int val;
265 296
266 switch (div_id) { 297 switch (div_id) {
@@ -311,7 +342,7 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id,
311 int source, unsigned int freq_in, unsigned int freq_out) 342 int source, unsigned int freq_in, unsigned int freq_out)
312{ 343{
313 struct ssp_priv *priv = cpu_dai->private_data; 344 struct ssp_priv *priv = cpu_dai->private_data;
314 struct ssp_device *ssp = priv->dev.ssp; 345 struct ssp_device *ssp = priv->ssp;
315 u32 ssacd = ssp_read_reg(ssp, SSACD) & ~0x70; 346 u32 ssacd = ssp_read_reg(ssp, SSACD) & ~0x70;
316 347
317#if defined(CONFIG_PXA3xx) 348#if defined(CONFIG_PXA3xx)
@@ -380,7 +411,7 @@ static int pxa_ssp_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
380 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width) 411 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
381{ 412{
382 struct ssp_priv *priv = cpu_dai->private_data; 413 struct ssp_priv *priv = cpu_dai->private_data;
383 struct ssp_device *ssp = priv->dev.ssp; 414 struct ssp_device *ssp = priv->ssp;
384 u32 sscr0; 415 u32 sscr0;
385 416
386 sscr0 = ssp_read_reg(ssp, SSCR0); 417 sscr0 = ssp_read_reg(ssp, SSCR0);
@@ -415,7 +446,7 @@ static int pxa_ssp_set_dai_tristate(struct snd_soc_dai *cpu_dai,
415 int tristate) 446 int tristate)
416{ 447{
417 struct ssp_priv *priv = cpu_dai->private_data; 448 struct ssp_priv *priv = cpu_dai->private_data;
418 struct ssp_device *ssp = priv->dev.ssp; 449 struct ssp_device *ssp = priv->ssp;
419 u32 sscr1; 450 u32 sscr1;
420 451
421 sscr1 = ssp_read_reg(ssp, SSCR1); 452 sscr1 = ssp_read_reg(ssp, SSCR1);
@@ -437,7 +468,7 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
437 unsigned int fmt) 468 unsigned int fmt)
438{ 469{
439 struct ssp_priv *priv = cpu_dai->private_data; 470 struct ssp_priv *priv = cpu_dai->private_data;
440 struct ssp_device *ssp = priv->dev.ssp; 471 struct ssp_device *ssp = priv->ssp;
441 u32 sscr0; 472 u32 sscr0;
442 u32 sscr1; 473 u32 sscr1;
443 u32 sspsp; 474 u32 sspsp;
@@ -532,7 +563,7 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
532 struct snd_soc_pcm_runtime *rtd = substream->private_data; 563 struct snd_soc_pcm_runtime *rtd = substream->private_data;
533 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 564 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
534 struct ssp_priv *priv = cpu_dai->private_data; 565 struct ssp_priv *priv = cpu_dai->private_data;
535 struct ssp_device *ssp = priv->dev.ssp; 566 struct ssp_device *ssp = priv->ssp;
536 int chn = params_channels(params); 567 int chn = params_channels(params);
537 u32 sscr0; 568 u32 sscr0;
538 u32 sspsp; 569 u32 sspsp;
@@ -642,12 +673,12 @@ static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
642 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 673 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
643 int ret = 0; 674 int ret = 0;
644 struct ssp_priv *priv = cpu_dai->private_data; 675 struct ssp_priv *priv = cpu_dai->private_data;
645 struct ssp_device *ssp = priv->dev.ssp; 676 struct ssp_device *ssp = priv->ssp;
646 int val; 677 int val;
647 678
648 switch (cmd) { 679 switch (cmd) {
649 case SNDRV_PCM_TRIGGER_RESUME: 680 case SNDRV_PCM_TRIGGER_RESUME:
650 ssp_enable(&priv->dev); 681 ssp_enable(ssp);
651 break; 682 break;
652 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 683 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
653 val = ssp_read_reg(ssp, SSCR1); 684 val = ssp_read_reg(ssp, SSCR1);
@@ -666,7 +697,7 @@ static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
666 else 697 else
667 val |= SSCR1_RSRE; 698 val |= SSCR1_RSRE;
668 ssp_write_reg(ssp, SSCR1, val); 699 ssp_write_reg(ssp, SSCR1, val);
669 ssp_enable(&priv->dev); 700 ssp_enable(ssp);
670 break; 701 break;
671 case SNDRV_PCM_TRIGGER_STOP: 702 case SNDRV_PCM_TRIGGER_STOP:
672 val = ssp_read_reg(ssp, SSCR1); 703 val = ssp_read_reg(ssp, SSCR1);
@@ -677,7 +708,7 @@ static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
677 ssp_write_reg(ssp, SSCR1, val); 708 ssp_write_reg(ssp, SSCR1, val);
678 break; 709 break;
679 case SNDRV_PCM_TRIGGER_SUSPEND: 710 case SNDRV_PCM_TRIGGER_SUSPEND:
680 ssp_disable(&priv->dev); 711 ssp_disable(ssp);
681 break; 712 break;
682 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 713 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
683 val = ssp_read_reg(ssp, SSCR1); 714 val = ssp_read_reg(ssp, SSCR1);
@@ -707,8 +738,8 @@ static int pxa_ssp_probe(struct platform_device *pdev,
707 if (!priv) 738 if (!priv)
708 return -ENOMEM; 739 return -ENOMEM;
709 740
710 priv->dev.ssp = ssp_request(dai->id + 1, "SoC audio"); 741 priv->ssp = ssp_request(dai->id + 1, "SoC audio");
711 if (priv->dev.ssp == NULL) { 742 if (priv->ssp == NULL) {
712 ret = -ENODEV; 743 ret = -ENODEV;
713 goto err_priv; 744 goto err_priv;
714 } 745 }
@@ -727,7 +758,7 @@ static void pxa_ssp_remove(struct platform_device *pdev,
727 struct snd_soc_dai *dai) 758 struct snd_soc_dai *dai)
728{ 759{
729 struct ssp_priv *priv = dai->private_data; 760 struct ssp_priv *priv = dai->private_data;
730 ssp_free(priv->dev.ssp); 761 ssp_free(priv->ssp);
731} 762}
732 763
733#define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ 764#define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\