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.c141
1 files changed, 88 insertions, 53 deletions
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index d11a6d7e384a..544fd9566f4d 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -16,6 +16,7 @@
16 16
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/slab.h>
19#include <linux/platform_device.h> 20#include <linux/platform_device.h>
20#include <linux/clk.h> 21#include <linux/clk.h>
21#include <linux/io.h> 22#include <linux/io.h>
@@ -42,11 +43,14 @@
42 * SSP audio private data 43 * SSP audio private data
43 */ 44 */
44struct ssp_priv { 45struct ssp_priv {
45 struct ssp_dev dev; 46 struct ssp_device *ssp;
46 unsigned int sysclk; 47 unsigned int sysclk;
47 int dai_fmt; 48 int dai_fmt;
48#ifdef CONFIG_PM 49#ifdef CONFIG_PM
49 struct ssp_state state; 50 uint32_t cr0;
51 uint32_t cr1;
52 uint32_t to;
53 uint32_t psp;
50#endif 54#endif
51}; 55};
52 56
@@ -61,6 +65,22 @@ static void dump_registers(struct ssp_device *ssp)
61 ssp_read_reg(ssp, SSACD)); 65 ssp_read_reg(ssp, SSACD));
62} 66}
63 67
68static void ssp_enable(struct ssp_device *ssp)
69{
70 uint32_t sscr0;
71
72 sscr0 = __raw_readl(ssp->mmio_base + SSCR0) | SSCR0_SSE;
73 __raw_writel(sscr0, ssp->mmio_base + SSCR0);
74}
75
76static void ssp_disable(struct ssp_device *ssp)
77{
78 uint32_t sscr0;
79
80 sscr0 = __raw_readl(ssp->mmio_base + SSCR0) & ~SSCR0_SSE;
81 __raw_writel(sscr0, ssp->mmio_base + SSCR0);
82}
83
64struct pxa2xx_pcm_dma_data { 84struct pxa2xx_pcm_dma_data {
65 struct pxa2xx_pcm_dma_params params; 85 struct pxa2xx_pcm_dma_params params;
66 char name[20]; 86 char name[20];
@@ -94,19 +114,17 @@ static int pxa_ssp_startup(struct snd_pcm_substream *substream,
94 struct snd_soc_pcm_runtime *rtd = substream->private_data; 114 struct snd_soc_pcm_runtime *rtd = substream->private_data;
95 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 115 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
96 struct ssp_priv *priv = cpu_dai->private_data; 116 struct ssp_priv *priv = cpu_dai->private_data;
117 struct ssp_device *ssp = priv->ssp;
97 int ret = 0; 118 int ret = 0;
98 119
99 if (!cpu_dai->active) { 120 if (!cpu_dai->active) {
100 priv->dev.port = cpu_dai->id + 1; 121 clk_enable(ssp->clk);
101 priv->dev.irq = NO_IRQ; 122 ssp_disable(ssp);
102 clk_enable(priv->dev.ssp->clk);
103 ssp_disable(&priv->dev);
104 } 123 }
105 124
106 if (cpu_dai->dma_data) { 125 kfree(snd_soc_dai_get_dma_data(cpu_dai, substream));
107 kfree(cpu_dai->dma_data); 126 snd_soc_dai_set_dma_data(cpu_dai, substream, NULL);
108 cpu_dai->dma_data = NULL; 127
109 }
110 return ret; 128 return ret;
111} 129}
112 130
@@ -116,16 +134,15 @@ 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 kfree(snd_soc_dai_get_dma_data(cpu_dai, substream));
126 kfree(cpu_dai->dma_data); 145 snd_soc_dai_set_dma_data(cpu_dai, substream, NULL);
127 cpu_dai->dma_data = NULL;
128 }
129} 146}
130 147
131#ifdef CONFIG_PM 148#ifdef CONFIG_PM
@@ -133,25 +150,39 @@ static void pxa_ssp_shutdown(struct snd_pcm_substream *substream,
133static int pxa_ssp_suspend(struct snd_soc_dai *cpu_dai) 150static int pxa_ssp_suspend(struct snd_soc_dai *cpu_dai)
134{ 151{
135 struct ssp_priv *priv = cpu_dai->private_data; 152 struct ssp_priv *priv = cpu_dai->private_data;
153 struct ssp_device *ssp = priv->ssp;
136 154
137 if (!cpu_dai->active) 155 if (!cpu_dai->active)
138 return 0; 156 clk_enable(ssp->clk);
157
158 priv->cr0 = __raw_readl(ssp->mmio_base + SSCR0);
159 priv->cr1 = __raw_readl(ssp->mmio_base + SSCR1);
160 priv->to = __raw_readl(ssp->mmio_base + SSTO);
161 priv->psp = __raw_readl(ssp->mmio_base + SSPSP);
139 162
140 ssp_save_state(&priv->dev, &priv->state); 163 ssp_disable(ssp);
141 clk_disable(priv->dev.ssp->clk); 164 clk_disable(ssp->clk);
142 return 0; 165 return 0;
143} 166}
144 167
145static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai) 168static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai)
146{ 169{
147 struct ssp_priv *priv = cpu_dai->private_data; 170 struct ssp_priv *priv = cpu_dai->private_data;
171 struct ssp_device *ssp = priv->ssp;
172 uint32_t sssr = SSSR_ROR | SSSR_TUR | SSSR_BCE;
148 173
149 if (!cpu_dai->active) 174 clk_enable(ssp->clk);
150 return 0;
151 175
152 clk_enable(priv->dev.ssp->clk); 176 __raw_writel(sssr, ssp->mmio_base + SSSR);
153 ssp_restore_state(&priv->dev, &priv->state); 177 __raw_writel(priv->cr0 & ~SSCR0_SSE, ssp->mmio_base + SSCR0);
154 ssp_enable(&priv->dev); 178 __raw_writel(priv->cr1, ssp->mmio_base + SSCR1);
179 __raw_writel(priv->to, ssp->mmio_base + SSTO);
180 __raw_writel(priv->psp, ssp->mmio_base + SSPSP);
181
182 if (cpu_dai->active)
183 ssp_enable(ssp);
184 else
185 clk_disable(ssp->clk);
155 186
156 return 0; 187 return 0;
157} 188}
@@ -201,7 +232,7 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
201 int clk_id, unsigned int freq, int dir) 232 int clk_id, unsigned int freq, int dir)
202{ 233{
203 struct ssp_priv *priv = cpu_dai->private_data; 234 struct ssp_priv *priv = cpu_dai->private_data;
204 struct ssp_device *ssp = priv->dev.ssp; 235 struct ssp_device *ssp = priv->ssp;
205 int val; 236 int val;
206 237
207 u32 sscr0 = ssp_read_reg(ssp, SSCR0) & 238 u32 sscr0 = ssp_read_reg(ssp, SSCR0) &
@@ -242,11 +273,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 273 /* The SSP clock must be disabled when changing SSP clock mode
243 * on PXA2xx. On PXA3xx it must be enabled when doing so. */ 274 * on PXA2xx. On PXA3xx it must be enabled when doing so. */
244 if (!cpu_is_pxa3xx()) 275 if (!cpu_is_pxa3xx())
245 clk_disable(priv->dev.ssp->clk); 276 clk_disable(ssp->clk);
246 val = ssp_read_reg(ssp, SSCR0) | sscr0; 277 val = ssp_read_reg(ssp, SSCR0) | sscr0;
247 ssp_write_reg(ssp, SSCR0, val); 278 ssp_write_reg(ssp, SSCR0, val);
248 if (!cpu_is_pxa3xx()) 279 if (!cpu_is_pxa3xx())
249 clk_enable(priv->dev.ssp->clk); 280 clk_enable(ssp->clk);
250 281
251 return 0; 282 return 0;
252} 283}
@@ -258,7 +289,7 @@ static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
258 int div_id, int div) 289 int div_id, int div)
259{ 290{
260 struct ssp_priv *priv = cpu_dai->private_data; 291 struct ssp_priv *priv = cpu_dai->private_data;
261 struct ssp_device *ssp = priv->dev.ssp; 292 struct ssp_device *ssp = priv->ssp;
262 int val; 293 int val;
263 294
264 switch (div_id) { 295 switch (div_id) {
@@ -305,11 +336,11 @@ static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
305/* 336/*
306 * Configure the PLL frequency pxa27x and (afaik - pxa320 only) 337 * Configure the PLL frequency pxa27x and (afaik - pxa320 only)
307 */ 338 */
308static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, 339static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id,
309 int pll_id, unsigned int freq_in, unsigned int freq_out) 340 int source, unsigned int freq_in, unsigned int freq_out)
310{ 341{
311 struct ssp_priv *priv = cpu_dai->private_data; 342 struct ssp_priv *priv = cpu_dai->private_data;
312 struct ssp_device *ssp = priv->dev.ssp; 343 struct ssp_device *ssp = priv->ssp;
313 u32 ssacd = ssp_read_reg(ssp, SSACD) & ~0x70; 344 u32 ssacd = ssp_read_reg(ssp, SSACD) & ~0x70;
314 345
315#if defined(CONFIG_PXA3xx) 346#if defined(CONFIG_PXA3xx)
@@ -378,7 +409,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) 409 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
379{ 410{
380 struct ssp_priv *priv = cpu_dai->private_data; 411 struct ssp_priv *priv = cpu_dai->private_data;
381 struct ssp_device *ssp = priv->dev.ssp; 412 struct ssp_device *ssp = priv->ssp;
382 u32 sscr0; 413 u32 sscr0;
383 414
384 sscr0 = ssp_read_reg(ssp, SSCR0); 415 sscr0 = ssp_read_reg(ssp, SSCR0);
@@ -413,7 +444,7 @@ static int pxa_ssp_set_dai_tristate(struct snd_soc_dai *cpu_dai,
413 int tristate) 444 int tristate)
414{ 445{
415 struct ssp_priv *priv = cpu_dai->private_data; 446 struct ssp_priv *priv = cpu_dai->private_data;
416 struct ssp_device *ssp = priv->dev.ssp; 447 struct ssp_device *ssp = priv->ssp;
417 u32 sscr1; 448 u32 sscr1;
418 449
419 sscr1 = ssp_read_reg(ssp, SSCR1); 450 sscr1 = ssp_read_reg(ssp, SSCR1);
@@ -435,7 +466,7 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
435 unsigned int fmt) 466 unsigned int fmt)
436{ 467{
437 struct ssp_priv *priv = cpu_dai->private_data; 468 struct ssp_priv *priv = cpu_dai->private_data;
438 struct ssp_device *ssp = priv->dev.ssp; 469 struct ssp_device *ssp = priv->ssp;
439 u32 sscr0; 470 u32 sscr0;
440 u32 sscr1; 471 u32 sscr1;
441 u32 sspsp; 472 u32 sspsp;
@@ -530,25 +561,29 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
530 struct snd_soc_pcm_runtime *rtd = substream->private_data; 561 struct snd_soc_pcm_runtime *rtd = substream->private_data;
531 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 562 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
532 struct ssp_priv *priv = cpu_dai->private_data; 563 struct ssp_priv *priv = cpu_dai->private_data;
533 struct ssp_device *ssp = priv->dev.ssp; 564 struct ssp_device *ssp = priv->ssp;
534 int chn = params_channels(params); 565 int chn = params_channels(params);
535 u32 sscr0; 566 u32 sscr0;
536 u32 sspsp; 567 u32 sspsp;
537 int width = snd_pcm_format_physical_width(params_format(params)); 568 int width = snd_pcm_format_physical_width(params_format(params));
538 int ttsa = ssp_read_reg(ssp, SSTSA) & 0xf; 569 int ttsa = ssp_read_reg(ssp, SSTSA) & 0xf;
570 struct pxa2xx_pcm_dma_params *dma_data;
571
572 dma_data = snd_soc_dai_get_dma_data(dai, substream);
539 573
540 /* generate correct DMA params */ 574 /* generate correct DMA params */
541 if (cpu_dai->dma_data) 575 kfree(dma_data);
542 kfree(cpu_dai->dma_data);
543 576
544 /* Network mode with one active slot (ttsa == 1) can be used 577 /* Network mode with one active slot (ttsa == 1) can be used
545 * to force 16-bit frame width on the wire (for S16_LE), even 578 * to force 16-bit frame width on the wire (for S16_LE), even
546 * with two channels. Use 16-bit DMA transfers for this case. 579 * with two channels. Use 16-bit DMA transfers for this case.
547 */ 580 */
548 cpu_dai->dma_data = ssp_get_dma_params(ssp, 581 dma_data = ssp_get_dma_params(ssp,
549 ((chn == 2) && (ttsa != 1)) || (width == 32), 582 ((chn == 2) && (ttsa != 1)) || (width == 32),
550 substream->stream == SNDRV_PCM_STREAM_PLAYBACK); 583 substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
551 584
585 snd_soc_dai_set_dma_data(dai, substream, dma_data);
586
552 /* we can only change the settings if the port is not in use */ 587 /* we can only change the settings if the port is not in use */
553 if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) 588 if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE)
554 return 0; 589 return 0;
@@ -640,12 +675,12 @@ static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
640 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 675 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
641 int ret = 0; 676 int ret = 0;
642 struct ssp_priv *priv = cpu_dai->private_data; 677 struct ssp_priv *priv = cpu_dai->private_data;
643 struct ssp_device *ssp = priv->dev.ssp; 678 struct ssp_device *ssp = priv->ssp;
644 int val; 679 int val;
645 680
646 switch (cmd) { 681 switch (cmd) {
647 case SNDRV_PCM_TRIGGER_RESUME: 682 case SNDRV_PCM_TRIGGER_RESUME:
648 ssp_enable(&priv->dev); 683 ssp_enable(ssp);
649 break; 684 break;
650 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 685 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
651 val = ssp_read_reg(ssp, SSCR1); 686 val = ssp_read_reg(ssp, SSCR1);
@@ -664,7 +699,7 @@ static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
664 else 699 else
665 val |= SSCR1_RSRE; 700 val |= SSCR1_RSRE;
666 ssp_write_reg(ssp, SSCR1, val); 701 ssp_write_reg(ssp, SSCR1, val);
667 ssp_enable(&priv->dev); 702 ssp_enable(ssp);
668 break; 703 break;
669 case SNDRV_PCM_TRIGGER_STOP: 704 case SNDRV_PCM_TRIGGER_STOP:
670 val = ssp_read_reg(ssp, SSCR1); 705 val = ssp_read_reg(ssp, SSCR1);
@@ -675,7 +710,7 @@ static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
675 ssp_write_reg(ssp, SSCR1, val); 710 ssp_write_reg(ssp, SSCR1, val);
676 break; 711 break;
677 case SNDRV_PCM_TRIGGER_SUSPEND: 712 case SNDRV_PCM_TRIGGER_SUSPEND:
678 ssp_disable(&priv->dev); 713 ssp_disable(ssp);
679 break; 714 break;
680 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 715 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
681 val = ssp_read_reg(ssp, SSCR1); 716 val = ssp_read_reg(ssp, SSCR1);
@@ -705,8 +740,8 @@ static int pxa_ssp_probe(struct platform_device *pdev,
705 if (!priv) 740 if (!priv)
706 return -ENOMEM; 741 return -ENOMEM;
707 742
708 priv->dev.ssp = ssp_request(dai->id + 1, "SoC audio"); 743 priv->ssp = ssp_request(dai->id + 1, "SoC audio");
709 if (priv->dev.ssp == NULL) { 744 if (priv->ssp == NULL) {
710 ret = -ENODEV; 745 ret = -ENODEV;
711 goto err_priv; 746 goto err_priv;
712 } 747 }
@@ -725,7 +760,7 @@ static void pxa_ssp_remove(struct platform_device *pdev,
725 struct snd_soc_dai *dai) 760 struct snd_soc_dai *dai)
726{ 761{
727 struct ssp_priv *priv = dai->private_data; 762 struct ssp_priv *priv = dai->private_data;
728 ssp_free(priv->dev.ssp); 763 ssp_free(priv->ssp);
729} 764}
730 765
731#define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ 766#define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
@@ -760,13 +795,13 @@ struct snd_soc_dai pxa_ssp_dai[] = {
760 .resume = pxa_ssp_resume, 795 .resume = pxa_ssp_resume,
761 .playback = { 796 .playback = {
762 .channels_min = 1, 797 .channels_min = 1,
763 .channels_max = 2, 798 .channels_max = 8,
764 .rates = PXA_SSP_RATES, 799 .rates = PXA_SSP_RATES,
765 .formats = PXA_SSP_FORMATS, 800 .formats = PXA_SSP_FORMATS,
766 }, 801 },
767 .capture = { 802 .capture = {
768 .channels_min = 1, 803 .channels_min = 1,
769 .channels_max = 2, 804 .channels_max = 8,
770 .rates = PXA_SSP_RATES, 805 .rates = PXA_SSP_RATES,
771 .formats = PXA_SSP_FORMATS, 806 .formats = PXA_SSP_FORMATS,
772 }, 807 },
@@ -780,13 +815,13 @@ struct snd_soc_dai pxa_ssp_dai[] = {
780 .resume = pxa_ssp_resume, 815 .resume = pxa_ssp_resume,
781 .playback = { 816 .playback = {
782 .channels_min = 1, 817 .channels_min = 1,
783 .channels_max = 2, 818 .channels_max = 8,
784 .rates = PXA_SSP_RATES, 819 .rates = PXA_SSP_RATES,
785 .formats = PXA_SSP_FORMATS, 820 .formats = PXA_SSP_FORMATS,
786 }, 821 },
787 .capture = { 822 .capture = {
788 .channels_min = 1, 823 .channels_min = 1,
789 .channels_max = 2, 824 .channels_max = 8,
790 .rates = PXA_SSP_RATES, 825 .rates = PXA_SSP_RATES,
791 .formats = PXA_SSP_FORMATS, 826 .formats = PXA_SSP_FORMATS,
792 }, 827 },
@@ -801,13 +836,13 @@ struct snd_soc_dai pxa_ssp_dai[] = {
801 .resume = pxa_ssp_resume, 836 .resume = pxa_ssp_resume,
802 .playback = { 837 .playback = {
803 .channels_min = 1, 838 .channels_min = 1,
804 .channels_max = 2, 839 .channels_max = 8,
805 .rates = PXA_SSP_RATES, 840 .rates = PXA_SSP_RATES,
806 .formats = PXA_SSP_FORMATS, 841 .formats = PXA_SSP_FORMATS,
807 }, 842 },
808 .capture = { 843 .capture = {
809 .channels_min = 1, 844 .channels_min = 1,
810 .channels_max = 2, 845 .channels_max = 8,
811 .rates = PXA_SSP_RATES, 846 .rates = PXA_SSP_RATES,
812 .formats = PXA_SSP_FORMATS, 847 .formats = PXA_SSP_FORMATS,
813 }, 848 },
@@ -822,13 +857,13 @@ struct snd_soc_dai pxa_ssp_dai[] = {
822 .resume = pxa_ssp_resume, 857 .resume = pxa_ssp_resume,
823 .playback = { 858 .playback = {
824 .channels_min = 1, 859 .channels_min = 1,
825 .channels_max = 2, 860 .channels_max = 8,
826 .rates = PXA_SSP_RATES, 861 .rates = PXA_SSP_RATES,
827 .formats = PXA_SSP_FORMATS, 862 .formats = PXA_SSP_FORMATS,
828 }, 863 },
829 .capture = { 864 .capture = {
830 .channels_min = 1, 865 .channels_min = 1,
831 .channels_max = 2, 866 .channels_max = 8,
832 .rates = PXA_SSP_RATES, 867 .rates = PXA_SSP_RATES,
833 .formats = PXA_SSP_FORMATS, 868 .formats = PXA_SSP_FORMATS,
834 }, 869 },