diff options
author | Bo Shen <voice.shen@atmel.com> | 2013-07-03 04:38:00 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2013-07-15 06:07:56 -0400 |
commit | 95e0e07e710e24a240f2c9645ecaad3559d6040d (patch) | |
tree | 05aef6424b4b67f43eee5e926a90c91b474ede95 | |
parent | 10175b3b2fdd287515db4c103d96b323bb4cd690 (diff) |
ASoC: atmel-pcm: use generic dmaengine framework
Align atmel pcm to use ASoC generic dmaengine framework
DMA is fully device tree based
Signed-off-by: Bo Shen <voice.shen@atmel.com>
Reviewed-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@linaro.org>
-rw-r--r-- | sound/soc/atmel/Kconfig | 1 | ||||
-rw-r--r-- | sound/soc/atmel/atmel-pcm-dma.c | 104 |
2 files changed, 17 insertions, 88 deletions
diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig index 3fdd87fa18a9..1c0b1858638c 100644 --- a/sound/soc/atmel/Kconfig +++ b/sound/soc/atmel/Kconfig | |||
@@ -13,6 +13,7 @@ config SND_ATMEL_SOC_PDC | |||
13 | config SND_ATMEL_SOC_DMA | 13 | config SND_ATMEL_SOC_DMA |
14 | tristate | 14 | tristate |
15 | depends on SND_ATMEL_SOC | 15 | depends on SND_ATMEL_SOC |
16 | select SND_SOC_GENERIC_DMAENGINE_PCM | ||
16 | 17 | ||
17 | config SND_ATMEL_SOC_SSC | 18 | config SND_ATMEL_SOC_SSC |
18 | tristate | 19 | tristate |
diff --git a/sound/soc/atmel/atmel-pcm-dma.c b/sound/soc/atmel/atmel-pcm-dma.c index 5a57803cb180..3ff5601eef10 100644 --- a/sound/soc/atmel/atmel-pcm-dma.c +++ b/sound/soc/atmel/atmel-pcm-dma.c | |||
@@ -89,124 +89,52 @@ static void atmel_pcm_dma_irq(u32 ssc_sr, | |||
89 | } | 89 | } |
90 | } | 90 | } |
91 | 91 | ||
92 | /*--------------------------------------------------------------------------*\ | ||
93 | * DMAENGINE operations | ||
94 | \*--------------------------------------------------------------------------*/ | ||
95 | static bool filter(struct dma_chan *chan, void *slave) | ||
96 | { | ||
97 | struct at_dma_slave *sl = slave; | ||
98 | |||
99 | if (sl->dma_dev == chan->device->dev) { | ||
100 | chan->private = sl; | ||
101 | return true; | ||
102 | } else { | ||
103 | return false; | ||
104 | } | ||
105 | } | ||
106 | |||
107 | static int atmel_pcm_configure_dma(struct snd_pcm_substream *substream, | 92 | static int atmel_pcm_configure_dma(struct snd_pcm_substream *substream, |
108 | struct snd_pcm_hw_params *params, struct atmel_pcm_dma_params *prtd) | 93 | struct snd_pcm_hw_params *params, struct dma_slave_config *slave_config) |
109 | { | 94 | { |
95 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
96 | struct atmel_pcm_dma_params *prtd; | ||
110 | struct ssc_device *ssc; | 97 | struct ssc_device *ssc; |
111 | struct dma_chan *dma_chan; | ||
112 | struct dma_slave_config slave_config; | ||
113 | int ret; | 98 | int ret; |
114 | 99 | ||
100 | prtd = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); | ||
115 | ssc = prtd->ssc; | 101 | ssc = prtd->ssc; |
116 | 102 | ||
117 | ret = snd_hwparams_to_dma_slave_config(substream, params, | 103 | ret = snd_hwparams_to_dma_slave_config(substream, params, slave_config); |
118 | &slave_config); | ||
119 | if (ret) { | 104 | if (ret) { |
120 | pr_err("atmel-pcm: hwparams to dma slave configure failed\n"); | 105 | pr_err("atmel-pcm: hwparams to dma slave configure failed\n"); |
121 | return ret; | 106 | return ret; |
122 | } | 107 | } |
123 | 108 | ||
124 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 109 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
125 | slave_config.dst_addr = (dma_addr_t)ssc->phybase + SSC_THR; | 110 | slave_config->dst_addr = ssc->phybase + SSC_THR; |
126 | slave_config.dst_maxburst = 1; | 111 | slave_config->dst_maxburst = 1; |
127 | } else { | 112 | } else { |
128 | slave_config.src_addr = (dma_addr_t)ssc->phybase + SSC_RHR; | 113 | slave_config->src_addr = ssc->phybase + SSC_RHR; |
129 | slave_config.src_maxburst = 1; | 114 | slave_config->src_maxburst = 1; |
130 | } | ||
131 | |||
132 | dma_chan = snd_dmaengine_pcm_get_chan(substream); | ||
133 | if (dmaengine_slave_config(dma_chan, &slave_config)) { | ||
134 | pr_err("atmel-pcm: failed to configure dma channel\n"); | ||
135 | ret = -EBUSY; | ||
136 | return ret; | ||
137 | } | ||
138 | |||
139 | return 0; | ||
140 | } | ||
141 | |||
142 | static int atmel_pcm_hw_params(struct snd_pcm_substream *substream, | ||
143 | struct snd_pcm_hw_params *params) | ||
144 | { | ||
145 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
146 | struct atmel_pcm_dma_params *prtd; | ||
147 | struct ssc_device *ssc; | ||
148 | struct at_dma_slave *sdata = NULL; | ||
149 | int ret; | ||
150 | |||
151 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); | ||
152 | |||
153 | prtd = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); | ||
154 | ssc = prtd->ssc; | ||
155 | if (ssc->pdev) | ||
156 | sdata = ssc->pdev->dev.platform_data; | ||
157 | |||
158 | ret = snd_dmaengine_pcm_open_request_chan(substream, filter, sdata); | ||
159 | if (ret) { | ||
160 | pr_err("atmel-pcm: dmaengine pcm open failed\n"); | ||
161 | return -EINVAL; | ||
162 | } | ||
163 | |||
164 | ret = atmel_pcm_configure_dma(substream, params, prtd); | ||
165 | if (ret) { | ||
166 | pr_err("atmel-pcm: failed to configure dmai\n"); | ||
167 | goto err; | ||
168 | } | 115 | } |
169 | 116 | ||
170 | prtd->dma_intr_handler = atmel_pcm_dma_irq; | 117 | prtd->dma_intr_handler = atmel_pcm_dma_irq; |
171 | 118 | ||
172 | return 0; | 119 | return 0; |
173 | err: | ||
174 | snd_dmaengine_pcm_close_release_chan(substream); | ||
175 | return ret; | ||
176 | } | ||
177 | |||
178 | static int atmel_pcm_open(struct snd_pcm_substream *substream) | ||
179 | { | ||
180 | snd_soc_set_runtime_hwparams(substream, &atmel_pcm_dma_hardware); | ||
181 | |||
182 | return 0; | ||
183 | } | 120 | } |
184 | 121 | ||
185 | static struct snd_pcm_ops atmel_pcm_ops = { | 122 | static const struct snd_dmaengine_pcm_config atmel_dmaengine_pcm_config = { |
186 | .open = atmel_pcm_open, | 123 | .prepare_slave_config = atmel_pcm_configure_dma, |
187 | .close = snd_dmaengine_pcm_close_release_chan, | 124 | .pcm_hardware = &atmel_pcm_dma_hardware, |
188 | .ioctl = snd_pcm_lib_ioctl, | 125 | .prealloc_buffer_size = ATMEL_SSC_DMABUF_SIZE, |
189 | .hw_params = atmel_pcm_hw_params, | ||
190 | .trigger = snd_dmaengine_pcm_trigger, | ||
191 | .pointer = snd_dmaengine_pcm_pointer_no_residue, | ||
192 | .mmap = atmel_pcm_mmap, | ||
193 | }; | ||
194 | |||
195 | static struct snd_soc_platform_driver atmel_soc_platform = { | ||
196 | .ops = &atmel_pcm_ops, | ||
197 | .pcm_new = atmel_pcm_new, | ||
198 | .pcm_free = atmel_pcm_free, | ||
199 | }; | 126 | }; |
200 | 127 | ||
201 | int atmel_pcm_dma_platform_register(struct device *dev) | 128 | int atmel_pcm_dma_platform_register(struct device *dev) |
202 | { | 129 | { |
203 | return snd_soc_register_platform(dev, &atmel_soc_platform); | 130 | return snd_dmaengine_pcm_register(dev, &atmel_dmaengine_pcm_config, |
131 | SND_DMAENGINE_PCM_FLAG_NO_RESIDUE); | ||
204 | } | 132 | } |
205 | EXPORT_SYMBOL(atmel_pcm_dma_platform_register); | 133 | EXPORT_SYMBOL(atmel_pcm_dma_platform_register); |
206 | 134 | ||
207 | void atmel_pcm_dma_platform_unregister(struct device *dev) | 135 | void atmel_pcm_dma_platform_unregister(struct device *dev) |
208 | { | 136 | { |
209 | snd_soc_unregister_platform(dev); | 137 | snd_dmaengine_pcm_unregister(dev); |
210 | } | 138 | } |
211 | EXPORT_SYMBOL(atmel_pcm_dma_platform_unregister); | 139 | EXPORT_SYMBOL(atmel_pcm_dma_platform_unregister); |
212 | 140 | ||