aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/pxa
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2010-03-22 13:23:46 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2010-03-22 13:23:46 -0400
commit74511020dde10252f8b8e648690d99dba721de14 (patch)
tree04fc22bc7dd5d5b8d9294b2e57985b093858bd84 /sound/soc/pxa
parent69266866a5790080d7fe80094b28d670ff8aa765 (diff)
parent3cc4e53f86dab635166929bfa47cc68d59b28c26 (diff)
Merge branch 'for-2.6.34' into for-2.6.35
Diffstat (limited to 'sound/soc/pxa')
-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 5d65a00e4bc0..6959c5199160 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 kfree(snd_soc_dai_get_dma_data(cpu_dai, substream)); 124 kfree(snd_soc_dai_get_dma_data(cpu_dai, substream));
@@ -115,10 +133,11 @@ static void pxa_ssp_shutdown(struct snd_pcm_substream *substream,
115 struct snd_soc_pcm_runtime *rtd = substream->private_data; 133 struct snd_soc_pcm_runtime *rtd = substream->private_data;
116 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 134 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
117 struct ssp_priv *priv = cpu_dai->private_data; 135 struct ssp_priv *priv = cpu_dai->private_data;
136 struct ssp_device *ssp = priv->ssp;
118 137
119 if (!cpu_dai->active) { 138 if (!cpu_dai->active) {
120 ssp_disable(&priv->dev); 139 ssp_disable(ssp);
121 clk_disable(priv->dev.ssp->clk); 140 clk_disable(ssp->clk);
122 } 141 }
123 142
124 kfree(snd_soc_dai_get_dma_data(cpu_dai, substream)); 143 kfree(snd_soc_dai_get_dma_data(cpu_dai, substream));
@@ -130,27 +149,39 @@ static void pxa_ssp_shutdown(struct snd_pcm_substream *substream,
130static int pxa_ssp_suspend(struct snd_soc_dai *cpu_dai) 149static int pxa_ssp_suspend(struct snd_soc_dai *cpu_dai)
131{ 150{
132 struct ssp_priv *priv = cpu_dai->private_data; 151 struct ssp_priv *priv = cpu_dai->private_data;
152 struct ssp_device *ssp = priv->ssp;
133 153
134 if (!cpu_dai->active) 154 if (!cpu_dai->active)
135 clk_enable(priv->dev.ssp->clk); 155 clk_enable(ssp->clk);
136 156
137 ssp_save_state(&priv->dev, &priv->state); 157 priv->cr0 = __raw_readl(ssp->mmio_base + SSCR0);
138 clk_disable(priv->dev.ssp->clk); 158 priv->cr1 = __raw_readl(ssp->mmio_base + SSCR1);
159 priv->to = __raw_readl(ssp->mmio_base + SSTO);
160 priv->psp = __raw_readl(ssp->mmio_base + SSPSP);
139 161
162 ssp_disable(ssp);
163 clk_disable(ssp->clk);
140 return 0; 164 return 0;
141} 165}
142 166
143static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai) 167static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai)
144{ 168{
145 struct ssp_priv *priv = cpu_dai->private_data; 169 struct ssp_priv *priv = cpu_dai->private_data;
170 struct ssp_device *ssp = priv->ssp;
171 uint32_t sssr = SSSR_ROR | SSSR_TUR | SSSR_BCE;
172
173 clk_enable(ssp->clk);
146 174
147 clk_enable(priv->dev.ssp->clk); 175 __raw_writel(sssr, ssp->mmio_base + SSSR);
148 ssp_restore_state(&priv->dev, &priv->state); 176 __raw_writel(priv->cr0 & ~SSCR0_SSE, ssp->mmio_base + SSCR0);
177 __raw_writel(priv->cr1, ssp->mmio_base + SSCR1);
178 __raw_writel(priv->to, ssp->mmio_base + SSTO);
179 __raw_writel(priv->psp, ssp->mmio_base + SSPSP);
149 180
150 if (cpu_dai->active) 181 if (cpu_dai->active)
151 ssp_enable(&priv->dev); 182 ssp_enable(ssp);
152 else 183 else
153 clk_disable(priv->dev.ssp->clk); 184 clk_disable(ssp->clk);
154 185
155 return 0; 186 return 0;
156} 187}
@@ -200,7 +231,7 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
200 int clk_id, unsigned int freq, int dir) 231 int clk_id, unsigned int freq, int dir)
201{ 232{
202 struct ssp_priv *priv = cpu_dai->private_data; 233 struct ssp_priv *priv = cpu_dai->private_data;
203 struct ssp_device *ssp = priv->dev.ssp; 234 struct ssp_device *ssp = priv->ssp;
204 int val; 235 int val;
205 236
206 u32 sscr0 = ssp_read_reg(ssp, SSCR0) & 237 u32 sscr0 = ssp_read_reg(ssp, SSCR0) &
@@ -241,11 +272,11 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
241 /* The SSP clock must be disabled when changing SSP clock mode 272 /* The SSP clock must be disabled when changing SSP clock mode
242 * on PXA2xx. On PXA3xx it must be enabled when doing so. */ 273 * on PXA2xx. On PXA3xx it must be enabled when doing so. */
243 if (!cpu_is_pxa3xx()) 274 if (!cpu_is_pxa3xx())
244 clk_disable(priv->dev.ssp->clk); 275 clk_disable(ssp->clk);
245 val = ssp_read_reg(ssp, SSCR0) | sscr0; 276 val = ssp_read_reg(ssp, SSCR0) | sscr0;
246 ssp_write_reg(ssp, SSCR0, val); 277 ssp_write_reg(ssp, SSCR0, val);
247 if (!cpu_is_pxa3xx()) 278 if (!cpu_is_pxa3xx())
248 clk_enable(priv->dev.ssp->clk); 279 clk_enable(ssp->clk);
249 280
250 return 0; 281 return 0;
251} 282}
@@ -257,7 +288,7 @@ static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
257 int div_id, int div) 288 int div_id, int div)
258{ 289{
259 struct ssp_priv *priv = cpu_dai->private_data; 290 struct ssp_priv *priv = cpu_dai->private_data;
260 struct ssp_device *ssp = priv->dev.ssp; 291 struct ssp_device *ssp = priv->ssp;
261 int val; 292 int val;
262 293
263 switch (div_id) { 294 switch (div_id) {
@@ -308,7 +339,7 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id,
308 int source, unsigned int freq_in, unsigned int freq_out) 339 int source, unsigned int freq_in, unsigned int freq_out)
309{ 340{
310 struct ssp_priv *priv = cpu_dai->private_data; 341 struct ssp_priv *priv = cpu_dai->private_data;
311 struct ssp_device *ssp = priv->dev.ssp; 342 struct ssp_device *ssp = priv->ssp;
312 u32 ssacd = ssp_read_reg(ssp, SSACD) & ~0x70; 343 u32 ssacd = ssp_read_reg(ssp, SSACD) & ~0x70;
313 344
314#if defined(CONFIG_PXA3xx) 345#if defined(CONFIG_PXA3xx)
@@ -377,7 +408,7 @@ static int pxa_ssp_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
377 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width) 408 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
378{ 409{
379 struct ssp_priv *priv = cpu_dai->private_data; 410 struct ssp_priv *priv = cpu_dai->private_data;
380 struct ssp_device *ssp = priv->dev.ssp; 411 struct ssp_device *ssp = priv->ssp;
381 u32 sscr0; 412 u32 sscr0;
382 413
383 sscr0 = ssp_read_reg(ssp, SSCR0); 414 sscr0 = ssp_read_reg(ssp, SSCR0);
@@ -412,7 +443,7 @@ static int pxa_ssp_set_dai_tristate(struct snd_soc_dai *cpu_dai,
412 int tristate) 443 int tristate)
413{ 444{
414 struct ssp_priv *priv = cpu_dai->private_data; 445 struct ssp_priv *priv = cpu_dai->private_data;
415 struct ssp_device *ssp = priv->dev.ssp; 446 struct ssp_device *ssp = priv->ssp;
416 u32 sscr1; 447 u32 sscr1;
417 448
418 sscr1 = ssp_read_reg(ssp, SSCR1); 449 sscr1 = ssp_read_reg(ssp, SSCR1);
@@ -434,7 +465,7 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
434 unsigned int fmt) 465 unsigned int fmt)
435{ 466{
436 struct ssp_priv *priv = cpu_dai->private_data; 467 struct ssp_priv *priv = cpu_dai->private_data;
437 struct ssp_device *ssp = priv->dev.ssp; 468 struct ssp_device *ssp = priv->ssp;
438 u32 sscr0; 469 u32 sscr0;
439 u32 sscr1; 470 u32 sscr1;
440 u32 sspsp; 471 u32 sspsp;
@@ -529,7 +560,7 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
529 struct snd_soc_pcm_runtime *rtd = substream->private_data; 560 struct snd_soc_pcm_runtime *rtd = substream->private_data;
530 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 561 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
531 struct ssp_priv *priv = cpu_dai->private_data; 562 struct ssp_priv *priv = cpu_dai->private_data;
532 struct ssp_device *ssp = priv->dev.ssp; 563 struct ssp_device *ssp = priv->ssp;
533 int chn = params_channels(params); 564 int chn = params_channels(params);
534 u32 sscr0; 565 u32 sscr0;
535 u32 sspsp; 566 u32 sspsp;
@@ -643,12 +674,12 @@ static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
643 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 674 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
644 int ret = 0; 675 int ret = 0;
645 struct ssp_priv *priv = cpu_dai->private_data; 676 struct ssp_priv *priv = cpu_dai->private_data;
646 struct ssp_device *ssp = priv->dev.ssp; 677 struct ssp_device *ssp = priv->ssp;
647 int val; 678 int val;
648 679
649 switch (cmd) { 680 switch (cmd) {
650 case SNDRV_PCM_TRIGGER_RESUME: 681 case SNDRV_PCM_TRIGGER_RESUME:
651 ssp_enable(&priv->dev); 682 ssp_enable(ssp);
652 break; 683 break;
653 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 684 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
654 val = ssp_read_reg(ssp, SSCR1); 685 val = ssp_read_reg(ssp, SSCR1);
@@ -667,7 +698,7 @@ static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
667 else 698 else
668 val |= SSCR1_RSRE; 699 val |= SSCR1_RSRE;
669 ssp_write_reg(ssp, SSCR1, val); 700 ssp_write_reg(ssp, SSCR1, val);
670 ssp_enable(&priv->dev); 701 ssp_enable(ssp);
671 break; 702 break;
672 case SNDRV_PCM_TRIGGER_STOP: 703 case SNDRV_PCM_TRIGGER_STOP:
673 val = ssp_read_reg(ssp, SSCR1); 704 val = ssp_read_reg(ssp, SSCR1);
@@ -678,7 +709,7 @@ static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
678 ssp_write_reg(ssp, SSCR1, val); 709 ssp_write_reg(ssp, SSCR1, val);
679 break; 710 break;
680 case SNDRV_PCM_TRIGGER_SUSPEND: 711 case SNDRV_PCM_TRIGGER_SUSPEND:
681 ssp_disable(&priv->dev); 712 ssp_disable(ssp);
682 break; 713 break;
683 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 714 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
684 val = ssp_read_reg(ssp, SSCR1); 715 val = ssp_read_reg(ssp, SSCR1);
@@ -708,8 +739,8 @@ static int pxa_ssp_probe(struct platform_device *pdev,
708 if (!priv) 739 if (!priv)
709 return -ENOMEM; 740 return -ENOMEM;
710 741
711 priv->dev.ssp = ssp_request(dai->id + 1, "SoC audio"); 742 priv->ssp = ssp_request(dai->id + 1, "SoC audio");
712 if (priv->dev.ssp == NULL) { 743 if (priv->ssp == NULL) {
713 ret = -ENODEV; 744 ret = -ENODEV;
714 goto err_priv; 745 goto err_priv;
715 } 746 }
@@ -728,7 +759,7 @@ static void pxa_ssp_remove(struct platform_device *pdev,
728 struct snd_soc_dai *dai) 759 struct snd_soc_dai *dai)
729{ 760{
730 struct ssp_priv *priv = dai->private_data; 761 struct ssp_priv *priv = dai->private_data;
731 ssp_free(priv->dev.ssp); 762 ssp_free(priv->ssp);
732} 763}
733 764
734#define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ 765#define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\