diff options
author | guoyh <guoyh@marvell.com> | 2012-05-07 03:34:24 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-05-07 07:55:35 -0400 |
commit | d93ca1ae61adf67104a78739b793b27a7886c489 (patch) | |
tree | 61fcf6336da0d5331fb4beb5d376fc7b5329b9d6 /sound/soc/pxa | |
parent | 3cb81651d070edfbea83eef763c3ca3c6f3848fd (diff) |
ASoC: pxa: allocate the SSP DMA parameters in startup
Allocating the SSP DMA parameters in startup, freeing it in
shutdown instead of freeing and re-allocating it in hw_params.
After doing that, the logic is clear and more safe.
Signed-off-by: guoyh <guoyh@marvell.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/pxa')
-rw-r--r-- | sound/soc/pxa/pxa-ssp.c | 28 |
1 files changed, 11 insertions, 17 deletions
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c index fd04ce139031..1c2aa7fab3fd 100644 --- a/sound/soc/pxa/pxa-ssp.c +++ b/sound/soc/pxa/pxa-ssp.c | |||
@@ -85,14 +85,12 @@ struct pxa2xx_pcm_dma_data { | |||
85 | char name[20]; | 85 | char name[20]; |
86 | }; | 86 | }; |
87 | 87 | ||
88 | static struct pxa2xx_pcm_dma_params * | 88 | static void pxa_ssp_set_dma_params(struct ssp_device *ssp, int width4, |
89 | pxa_ssp_get_dma_params(struct ssp_device *ssp, int width4, int out) | 89 | int out, struct pxa2xx_pcm_dma_params *dma_data) |
90 | { | 90 | { |
91 | struct pxa2xx_pcm_dma_data *dma; | 91 | struct pxa2xx_pcm_dma_data *dma; |
92 | 92 | ||
93 | dma = kzalloc(sizeof(struct pxa2xx_pcm_dma_data), GFP_KERNEL); | 93 | dma = container_of(dma_data, struct pxa2xx_pcm_dma_data, params); |
94 | if (dma == NULL) | ||
95 | return NULL; | ||
96 | 94 | ||
97 | snprintf(dma->name, 20, "SSP%d PCM %s %s", ssp->port_id, | 95 | snprintf(dma->name, 20, "SSP%d PCM %s %s", ssp->port_id, |
98 | width4 ? "32-bit" : "16-bit", out ? "out" : "in"); | 96 | width4 ? "32-bit" : "16-bit", out ? "out" : "in"); |
@@ -103,8 +101,6 @@ pxa_ssp_get_dma_params(struct ssp_device *ssp, int width4, int out) | |||
103 | (DCMD_INCTRGADDR | DCMD_FLOWSRC)) | | 101 | (DCMD_INCTRGADDR | DCMD_FLOWSRC)) | |
104 | (width4 ? DCMD_WIDTH4 : DCMD_WIDTH2) | DCMD_BURST16; | 102 | (width4 ? DCMD_WIDTH4 : DCMD_WIDTH2) | DCMD_BURST16; |
105 | dma->params.dev_addr = ssp->phys_base + SSDR; | 103 | dma->params.dev_addr = ssp->phys_base + SSDR; |
106 | |||
107 | return &dma->params; | ||
108 | } | 104 | } |
109 | 105 | ||
110 | static int pxa_ssp_startup(struct snd_pcm_substream *substream, | 106 | static int pxa_ssp_startup(struct snd_pcm_substream *substream, |
@@ -112,6 +108,7 @@ static int pxa_ssp_startup(struct snd_pcm_substream *substream, | |||
112 | { | 108 | { |
113 | struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai); | 109 | struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai); |
114 | struct ssp_device *ssp = priv->ssp; | 110 | struct ssp_device *ssp = priv->ssp; |
111 | struct pxa2xx_pcm_dma_data *dma; | ||
115 | int ret = 0; | 112 | int ret = 0; |
116 | 113 | ||
117 | if (!cpu_dai->active) { | 114 | if (!cpu_dai->active) { |
@@ -119,8 +116,10 @@ static int pxa_ssp_startup(struct snd_pcm_substream *substream, | |||
119 | pxa_ssp_disable(ssp); | 116 | pxa_ssp_disable(ssp); |
120 | } | 117 | } |
121 | 118 | ||
122 | kfree(snd_soc_dai_get_dma_data(cpu_dai, substream)); | 119 | dma = kzalloc(sizeof(struct pxa2xx_pcm_dma_data), GFP_KERNEL); |
123 | snd_soc_dai_set_dma_data(cpu_dai, substream, NULL); | 120 | if (!dma) |
121 | return -ENOMEM; | ||
122 | snd_soc_dai_set_dma_data(cpu_dai, substream, &dma->params); | ||
124 | 123 | ||
125 | return ret; | 124 | return ret; |
126 | } | 125 | } |
@@ -573,18 +572,13 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream, | |||
573 | 572 | ||
574 | dma_data = snd_soc_dai_get_dma_data(cpu_dai, substream); | 573 | dma_data = snd_soc_dai_get_dma_data(cpu_dai, substream); |
575 | 574 | ||
576 | /* generate correct DMA params */ | ||
577 | kfree(dma_data); | ||
578 | |||
579 | /* Network mode with one active slot (ttsa == 1) can be used | 575 | /* Network mode with one active slot (ttsa == 1) can be used |
580 | * to force 16-bit frame width on the wire (for S16_LE), even | 576 | * to force 16-bit frame width on the wire (for S16_LE), even |
581 | * with two channels. Use 16-bit DMA transfers for this case. | 577 | * with two channels. Use 16-bit DMA transfers for this case. |
582 | */ | 578 | */ |
583 | dma_data = pxa_ssp_get_dma_params(ssp, | 579 | pxa_ssp_set_dma_params(ssp, |
584 | ((chn == 2) && (ttsa != 1)) || (width == 32), | 580 | ((chn == 2) && (ttsa != 1)) || (width == 32), |
585 | substream->stream == SNDRV_PCM_STREAM_PLAYBACK); | 581 | substream->stream == SNDRV_PCM_STREAM_PLAYBACK, dma_data); |
586 | |||
587 | snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); | ||
588 | 582 | ||
589 | /* we can only change the settings if the port is not in use */ | 583 | /* we can only change the settings if the port is not in use */ |
590 | if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) | 584 | if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) |