diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-03-22 13:23:46 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-03-22 13:23:46 -0400 |
commit | 74511020dde10252f8b8e648690d99dba721de14 (patch) | |
tree | 04fc22bc7dd5d5b8d9294b2e57985b093858bd84 /sound/soc/pxa | |
parent | 69266866a5790080d7fe80094b28d670ff8aa765 (diff) | |
parent | 3cc4e53f86dab635166929bfa47cc68d59b28c26 (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.c | 93 |
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 | */ |
44 | struct ssp_priv { | 44 | struct 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 | ||
67 | static 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 | |||
75 | static 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 | |||
64 | struct pxa2xx_pcm_dma_data { | 83 | struct 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, | |||
130 | static int pxa_ssp_suspend(struct snd_soc_dai *cpu_dai) | 149 | static 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 | ||
143 | static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai) | 167 | static 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 |\ |