diff options
author | Lars-Peter Clausen <lars@metafoo.de> | 2013-05-28 13:22:17 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2013-05-30 07:33:41 -0400 |
commit | cc37961b21eb3d57d421ca34ffec9bbe0a6096c0 (patch) | |
tree | 3a10e59aae5e9788b8920e9acaafbfe7cb3f8223 /sound/soc/blackfin/bf5xx-tdm-pcm.c | |
parent | 34f4095564ff334adae5ab4a9904f8d66d03e994 (diff) |
ASoC: blackfin: Remove bf5xx-tdm driver
Now that the bf5xx-i2s driver supports TDM mode and all users of the bf5xx-tdm
driver have been switch over to using the bf5xx-i2s driver there is no need to
keep the b5fxx-tdm driver around.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/blackfin/bf5xx-tdm-pcm.c')
-rw-r--r-- | sound/soc/blackfin/bf5xx-tdm-pcm.c | 343 |
1 files changed, 0 insertions, 343 deletions
diff --git a/sound/soc/blackfin/bf5xx-tdm-pcm.c b/sound/soc/blackfin/bf5xx-tdm-pcm.c deleted file mode 100644 index a6b5457036ef..000000000000 --- a/sound/soc/blackfin/bf5xx-tdm-pcm.c +++ /dev/null | |||
@@ -1,343 +0,0 @@ | |||
1 | /* | ||
2 | * File: sound/soc/blackfin/bf5xx-tdm-pcm.c | ||
3 | * Author: Barry Song <Barry.Song@analog.com> | ||
4 | * | ||
5 | * Created: Tue June 06 2009 | ||
6 | * Description: DMA driver for tdm codec | ||
7 | * | ||
8 | * Modified: | ||
9 | * Copyright 2009 Analog Devices Inc. | ||
10 | * | ||
11 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License as published by | ||
15 | * the Free Software Foundation; either version 2 of the License, or | ||
16 | * (at your option) any later version. | ||
17 | * | ||
18 | * This program is distributed in the hope that it will be useful, | ||
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
21 | * GNU General Public License for more details. | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with this program; if not, see the file COPYING, or write | ||
25 | * to the Free Software Foundation, Inc., | ||
26 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
27 | */ | ||
28 | |||
29 | #include <linux/module.h> | ||
30 | #include <linux/init.h> | ||
31 | #include <linux/platform_device.h> | ||
32 | #include <linux/dma-mapping.h> | ||
33 | #include <linux/gfp.h> | ||
34 | |||
35 | #include <sound/core.h> | ||
36 | #include <sound/pcm.h> | ||
37 | #include <sound/pcm_params.h> | ||
38 | #include <sound/soc.h> | ||
39 | |||
40 | #include <asm/dma.h> | ||
41 | |||
42 | #include "bf5xx-tdm.h" | ||
43 | #include "bf5xx-sport.h" | ||
44 | |||
45 | #define PCM_BUFFER_MAX 0x8000 | ||
46 | #define FRAGMENT_SIZE_MIN (4*1024) | ||
47 | #define FRAGMENTS_MIN 2 | ||
48 | #define FRAGMENTS_MAX 32 | ||
49 | |||
50 | static void bf5xx_dma_irq(void *data) | ||
51 | { | ||
52 | struct snd_pcm_substream *pcm = data; | ||
53 | snd_pcm_period_elapsed(pcm); | ||
54 | } | ||
55 | |||
56 | static const struct snd_pcm_hardware bf5xx_pcm_hardware = { | ||
57 | .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
58 | SNDRV_PCM_INFO_RESUME), | ||
59 | .formats = SNDRV_PCM_FMTBIT_S32_LE, | ||
60 | .rates = SNDRV_PCM_RATE_48000, | ||
61 | .channels_min = 2, | ||
62 | .channels_max = 8, | ||
63 | .buffer_bytes_max = PCM_BUFFER_MAX, | ||
64 | .period_bytes_min = FRAGMENT_SIZE_MIN, | ||
65 | .period_bytes_max = PCM_BUFFER_MAX/2, | ||
66 | .periods_min = FRAGMENTS_MIN, | ||
67 | .periods_max = FRAGMENTS_MAX, | ||
68 | }; | ||
69 | |||
70 | static int bf5xx_pcm_hw_params(struct snd_pcm_substream *substream, | ||
71 | struct snd_pcm_hw_params *params) | ||
72 | { | ||
73 | size_t size = bf5xx_pcm_hardware.buffer_bytes_max; | ||
74 | snd_pcm_lib_malloc_pages(substream, size * 4); | ||
75 | |||
76 | return 0; | ||
77 | } | ||
78 | |||
79 | static int bf5xx_pcm_hw_free(struct snd_pcm_substream *substream) | ||
80 | { | ||
81 | snd_pcm_lib_free_pages(substream); | ||
82 | |||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | static int bf5xx_pcm_prepare(struct snd_pcm_substream *substream) | ||
87 | { | ||
88 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
89 | struct sport_device *sport = runtime->private_data; | ||
90 | int fragsize_bytes = frames_to_bytes(runtime, runtime->period_size); | ||
91 | |||
92 | fragsize_bytes /= runtime->channels; | ||
93 | /* inflate the fragsize to match the dma width of SPORT */ | ||
94 | fragsize_bytes *= 8; | ||
95 | |||
96 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | ||
97 | sport_set_tx_callback(sport, bf5xx_dma_irq, substream); | ||
98 | sport_config_tx_dma(sport, runtime->dma_area, | ||
99 | runtime->periods, fragsize_bytes); | ||
100 | } else { | ||
101 | sport_set_rx_callback(sport, bf5xx_dma_irq, substream); | ||
102 | sport_config_rx_dma(sport, runtime->dma_area, | ||
103 | runtime->periods, fragsize_bytes); | ||
104 | } | ||
105 | |||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | static int bf5xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | ||
110 | { | ||
111 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
112 | struct sport_device *sport = runtime->private_data; | ||
113 | int ret = 0; | ||
114 | |||
115 | switch (cmd) { | ||
116 | case SNDRV_PCM_TRIGGER_START: | ||
117 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
118 | sport_tx_start(sport); | ||
119 | else | ||
120 | sport_rx_start(sport); | ||
121 | break; | ||
122 | case SNDRV_PCM_TRIGGER_STOP: | ||
123 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
124 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
125 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
126 | sport_tx_stop(sport); | ||
127 | else | ||
128 | sport_rx_stop(sport); | ||
129 | break; | ||
130 | default: | ||
131 | ret = -EINVAL; | ||
132 | } | ||
133 | |||
134 | return ret; | ||
135 | } | ||
136 | |||
137 | static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream) | ||
138 | { | ||
139 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
140 | struct sport_device *sport = runtime->private_data; | ||
141 | unsigned int diff; | ||
142 | snd_pcm_uframes_t frames; | ||
143 | |||
144 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | ||
145 | diff = sport_curr_offset_tx(sport); | ||
146 | frames = diff / (8*4); /* 32 bytes per frame */ | ||
147 | } else { | ||
148 | diff = sport_curr_offset_rx(sport); | ||
149 | frames = diff / (8*4); | ||
150 | } | ||
151 | return frames; | ||
152 | } | ||
153 | |||
154 | static int bf5xx_pcm_open(struct snd_pcm_substream *substream) | ||
155 | { | ||
156 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
157 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
158 | struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai); | ||
159 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
160 | struct snd_dma_buffer *buf = &substream->dma_buffer; | ||
161 | |||
162 | int ret = 0; | ||
163 | |||
164 | snd_soc_set_runtime_hwparams(substream, &bf5xx_pcm_hardware); | ||
165 | |||
166 | ret = snd_pcm_hw_constraint_integer(runtime, | ||
167 | SNDRV_PCM_HW_PARAM_PERIODS); | ||
168 | if (ret < 0) | ||
169 | goto out; | ||
170 | |||
171 | if (sport_handle != NULL) { | ||
172 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
173 | sport_handle->tx_buf = buf->area; | ||
174 | else | ||
175 | sport_handle->rx_buf = buf->area; | ||
176 | |||
177 | runtime->private_data = sport_handle; | ||
178 | } else { | ||
179 | pr_err("sport_handle is NULL\n"); | ||
180 | ret = -ENODEV; | ||
181 | } | ||
182 | out: | ||
183 | return ret; | ||
184 | } | ||
185 | |||
186 | static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel, | ||
187 | snd_pcm_uframes_t pos, void *buf, snd_pcm_uframes_t count) | ||
188 | { | ||
189 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
190 | struct sport_device *sport = runtime->private_data; | ||
191 | struct bf5xx_tdm_port *tdm_port = sport->private_data; | ||
192 | unsigned int *src; | ||
193 | unsigned int *dst; | ||
194 | int i; | ||
195 | |||
196 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | ||
197 | src = buf; | ||
198 | dst = (unsigned int *)substream->runtime->dma_area; | ||
199 | |||
200 | dst += pos * 8; | ||
201 | while (count--) { | ||
202 | for (i = 0; i < substream->runtime->channels; i++) | ||
203 | *(dst + tdm_port->tx_map[i]) = *src++; | ||
204 | dst += 8; | ||
205 | } | ||
206 | } else { | ||
207 | src = (unsigned int *)substream->runtime->dma_area; | ||
208 | dst = buf; | ||
209 | |||
210 | src += pos * 8; | ||
211 | while (count--) { | ||
212 | for (i = 0; i < substream->runtime->channels; i++) | ||
213 | *dst++ = *(src + tdm_port->rx_map[i]); | ||
214 | src += 8; | ||
215 | } | ||
216 | } | ||
217 | |||
218 | return 0; | ||
219 | } | ||
220 | |||
221 | static int bf5xx_pcm_silence(struct snd_pcm_substream *substream, | ||
222 | int channel, snd_pcm_uframes_t pos, snd_pcm_uframes_t count) | ||
223 | { | ||
224 | unsigned char *buf = substream->runtime->dma_area; | ||
225 | buf += pos * 8 * 4; | ||
226 | memset(buf, '\0', count * 8 * 4); | ||
227 | |||
228 | return 0; | ||
229 | } | ||
230 | |||
231 | static struct snd_pcm_ops bf5xx_pcm_tdm_ops = { | ||
232 | .open = bf5xx_pcm_open, | ||
233 | .ioctl = snd_pcm_lib_ioctl, | ||
234 | .hw_params = bf5xx_pcm_hw_params, | ||
235 | .hw_free = bf5xx_pcm_hw_free, | ||
236 | .prepare = bf5xx_pcm_prepare, | ||
237 | .trigger = bf5xx_pcm_trigger, | ||
238 | .pointer = bf5xx_pcm_pointer, | ||
239 | .copy = bf5xx_pcm_copy, | ||
240 | .silence = bf5xx_pcm_silence, | ||
241 | }; | ||
242 | |||
243 | static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) | ||
244 | { | ||
245 | struct snd_pcm_substream *substream = pcm->streams[stream].substream; | ||
246 | struct snd_dma_buffer *buf = &substream->dma_buffer; | ||
247 | size_t size = bf5xx_pcm_hardware.buffer_bytes_max; | ||
248 | |||
249 | buf->dev.type = SNDRV_DMA_TYPE_DEV; | ||
250 | buf->dev.dev = pcm->card->dev; | ||
251 | buf->private_data = NULL; | ||
252 | buf->area = dma_alloc_coherent(pcm->card->dev, size * 4, | ||
253 | &buf->addr, GFP_KERNEL); | ||
254 | if (!buf->area) { | ||
255 | pr_err("Failed to allocate dma memory - Please increase uncached DMA memory region\n"); | ||
256 | return -ENOMEM; | ||
257 | } | ||
258 | buf->bytes = size; | ||
259 | |||
260 | return 0; | ||
261 | } | ||
262 | |||
263 | static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm) | ||
264 | { | ||
265 | struct snd_pcm_substream *substream; | ||
266 | struct snd_dma_buffer *buf; | ||
267 | int stream; | ||
268 | |||
269 | for (stream = 0; stream < 2; stream++) { | ||
270 | substream = pcm->streams[stream].substream; | ||
271 | if (!substream) | ||
272 | continue; | ||
273 | |||
274 | buf = &substream->dma_buffer; | ||
275 | if (!buf->area) | ||
276 | continue; | ||
277 | dma_free_coherent(NULL, buf->bytes, buf->area, 0); | ||
278 | buf->area = NULL; | ||
279 | } | ||
280 | } | ||
281 | |||
282 | static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32); | ||
283 | |||
284 | static int bf5xx_pcm_tdm_new(struct snd_soc_pcm_runtime *rtd) | ||
285 | { | ||
286 | struct snd_card *card = rtd->card->snd_card; | ||
287 | struct snd_pcm *pcm = rtd->pcm; | ||
288 | int ret = 0; | ||
289 | |||
290 | if (!card->dev->dma_mask) | ||
291 | card->dev->dma_mask = &bf5xx_pcm_dmamask; | ||
292 | if (!card->dev->coherent_dma_mask) | ||
293 | card->dev->coherent_dma_mask = DMA_BIT_MASK(32); | ||
294 | |||
295 | if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { | ||
296 | ret = bf5xx_pcm_preallocate_dma_buffer(pcm, | ||
297 | SNDRV_PCM_STREAM_PLAYBACK); | ||
298 | if (ret) | ||
299 | goto out; | ||
300 | } | ||
301 | |||
302 | if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { | ||
303 | ret = bf5xx_pcm_preallocate_dma_buffer(pcm, | ||
304 | SNDRV_PCM_STREAM_CAPTURE); | ||
305 | if (ret) | ||
306 | goto out; | ||
307 | } | ||
308 | out: | ||
309 | return ret; | ||
310 | } | ||
311 | |||
312 | static struct snd_soc_platform_driver bf5xx_tdm_soc_platform = { | ||
313 | .ops = &bf5xx_pcm_tdm_ops, | ||
314 | .pcm_new = bf5xx_pcm_tdm_new, | ||
315 | .pcm_free = bf5xx_pcm_free_dma_buffers, | ||
316 | }; | ||
317 | |||
318 | static int bf5xx_soc_platform_probe(struct platform_device *pdev) | ||
319 | { | ||
320 | return snd_soc_register_platform(&pdev->dev, &bf5xx_tdm_soc_platform); | ||
321 | } | ||
322 | |||
323 | static int bf5xx_soc_platform_remove(struct platform_device *pdev) | ||
324 | { | ||
325 | snd_soc_unregister_platform(&pdev->dev); | ||
326 | return 0; | ||
327 | } | ||
328 | |||
329 | static struct platform_driver bfin_tdm_driver = { | ||
330 | .driver = { | ||
331 | .name = "bfin-tdm-pcm-audio", | ||
332 | .owner = THIS_MODULE, | ||
333 | }, | ||
334 | |||
335 | .probe = bf5xx_soc_platform_probe, | ||
336 | .remove = bf5xx_soc_platform_remove, | ||
337 | }; | ||
338 | |||
339 | module_platform_driver(bfin_tdm_driver); | ||
340 | |||
341 | MODULE_AUTHOR("Barry Song"); | ||
342 | MODULE_DESCRIPTION("ADI Blackfin TDM PCM DMA module"); | ||
343 | MODULE_LICENSE("GPL"); | ||