diff options
author | Lars-Peter Clausen <lars@metafoo.de> | 2013-04-20 13:29:03 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2013-04-22 06:27:29 -0400 |
commit | a8956908bf03418d7264de79e1e988628183f537 (patch) | |
tree | dc5ea7e32d2e4f1615f807ee4f9f8e061ac672c7 | |
parent | 8c1bb4ecbca575ec89310a50c3d3dd475bf81fd0 (diff) |
ASoC: mxs: Use generic dmaengine PCM
Use the generic dmaengine PCM driver instead of a custom implementation.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Tested-by: Shawn Guo <shawn.guo@linaro.org>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r-- | sound/soc/mxs/Kconfig | 2 | ||||
-rw-r--r-- | sound/soc/mxs/mxs-pcm.c | 136 |
2 files changed, 12 insertions, 126 deletions
diff --git a/sound/soc/mxs/Kconfig b/sound/soc/mxs/Kconfig index b6fa77678d97..78d321cbe8b4 100644 --- a/sound/soc/mxs/Kconfig +++ b/sound/soc/mxs/Kconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | menuconfig SND_MXS_SOC | 1 | menuconfig SND_MXS_SOC |
2 | tristate "SoC Audio for Freescale MXS CPUs" | 2 | tristate "SoC Audio for Freescale MXS CPUs" |
3 | depends on ARCH_MXS | 3 | depends on ARCH_MXS |
4 | select SND_SOC_DMAENGINE_PCM | 4 | select SND_SOC_GENERIC_DMAENGINE_PCM |
5 | help | 5 | help |
6 | Say Y or M if you want to add support for codecs attached to | 6 | Say Y or M if you want to add support for codecs attached to |
7 | the MXS SAIF interface. | 7 | the MXS SAIF interface. |
diff --git a/sound/soc/mxs/mxs-pcm.c b/sound/soc/mxs/mxs-pcm.c index 907cdb1f989d..b41fffc056fb 100644 --- a/sound/soc/mxs/mxs-pcm.c +++ b/sound/soc/mxs/mxs-pcm.c | |||
@@ -18,27 +18,18 @@ | |||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | 18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/clk.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include <linux/device.h> | 21 | #include <linux/device.h> |
24 | #include <linux/dma-mapping.h> | ||
25 | #include <linux/init.h> | 22 | #include <linux/init.h> |
26 | #include <linux/interrupt.h> | ||
27 | #include <linux/module.h> | 23 | #include <linux/module.h> |
28 | #include <linux/platform_device.h> | ||
29 | #include <linux/slab.h> | ||
30 | #include <linux/dmaengine.h> | ||
31 | 24 | ||
32 | #include <sound/core.h> | 25 | #include <sound/core.h> |
33 | #include <sound/initval.h> | ||
34 | #include <sound/pcm.h> | 26 | #include <sound/pcm.h> |
35 | #include <sound/pcm_params.h> | ||
36 | #include <sound/soc.h> | 27 | #include <sound/soc.h> |
37 | #include <sound/dmaengine_pcm.h> | 28 | #include <sound/dmaengine_pcm.h> |
38 | 29 | ||
39 | #include "mxs-pcm.h" | 30 | #include "mxs-pcm.h" |
40 | 31 | ||
41 | static struct snd_pcm_hardware snd_mxs_hardware = { | 32 | static const struct snd_pcm_hardware snd_mxs_hardware = { |
42 | .info = SNDRV_PCM_INFO_MMAP | | 33 | .info = SNDRV_PCM_INFO_MMAP | |
43 | SNDRV_PCM_INFO_MMAP_VALID | | 34 | SNDRV_PCM_INFO_MMAP_VALID | |
44 | SNDRV_PCM_INFO_PAUSE | | 35 | SNDRV_PCM_INFO_PAUSE | |
@@ -56,7 +47,6 @@ static struct snd_pcm_hardware snd_mxs_hardware = { | |||
56 | .periods_max = 52, | 47 | .periods_max = 52, |
57 | .buffer_bytes_max = 64 * 1024, | 48 | .buffer_bytes_max = 64 * 1024, |
58 | .fifo_size = 32, | 49 | .fifo_size = 32, |
59 | |||
60 | }; | 50 | }; |
61 | 51 | ||
62 | static bool filter(struct dma_chan *chan, void *param) | 52 | static bool filter(struct dma_chan *chan, void *param) |
@@ -74,129 +64,25 @@ static bool filter(struct dma_chan *chan, void *param) | |||
74 | return true; | 64 | return true; |
75 | } | 65 | } |
76 | 66 | ||
77 | static int snd_mxs_pcm_hw_params(struct snd_pcm_substream *substream, | 67 | static const struct snd_dmaengine_pcm_config mxs_dmaengine_pcm_config = { |
78 | struct snd_pcm_hw_params *params) | 68 | .pcm_hardware = &snd_mxs_hardware, |
79 | { | 69 | .compat_filter_fn = filter, |
80 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); | 70 | .prealloc_buffer_size = 64 * 1024, |
81 | |||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | static int snd_mxs_open(struct snd_pcm_substream *substream) | ||
86 | { | ||
87 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
88 | |||
89 | snd_soc_set_runtime_hwparams(substream, &snd_mxs_hardware); | ||
90 | |||
91 | return snd_dmaengine_pcm_open_request_chan(substream, filter, | ||
92 | snd_soc_dai_get_dma_data(rtd->cpu_dai, substream)); | ||
93 | } | ||
94 | |||
95 | static int snd_mxs_pcm_mmap(struct snd_pcm_substream *substream, | ||
96 | struct vm_area_struct *vma) | ||
97 | { | ||
98 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
99 | |||
100 | return dma_mmap_writecombine(substream->pcm->card->dev, vma, | ||
101 | runtime->dma_area, | ||
102 | runtime->dma_addr, | ||
103 | runtime->dma_bytes); | ||
104 | } | ||
105 | |||
106 | static struct snd_pcm_ops mxs_pcm_ops = { | ||
107 | .open = snd_mxs_open, | ||
108 | .close = snd_dmaengine_pcm_close_release_chan, | ||
109 | .ioctl = snd_pcm_lib_ioctl, | ||
110 | .hw_params = snd_mxs_pcm_hw_params, | ||
111 | .trigger = snd_dmaengine_pcm_trigger, | ||
112 | .pointer = snd_dmaengine_pcm_pointer_no_residue, | ||
113 | .mmap = snd_mxs_pcm_mmap, | ||
114 | }; | ||
115 | |||
116 | static int mxs_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) | ||
117 | { | ||
118 | struct snd_pcm_substream *substream = pcm->streams[stream].substream; | ||
119 | struct snd_dma_buffer *buf = &substream->dma_buffer; | ||
120 | size_t size = snd_mxs_hardware.buffer_bytes_max; | ||
121 | |||
122 | buf->dev.type = SNDRV_DMA_TYPE_DEV; | ||
123 | buf->dev.dev = pcm->card->dev; | ||
124 | buf->private_data = NULL; | ||
125 | buf->area = dma_alloc_writecombine(pcm->card->dev, size, | ||
126 | &buf->addr, GFP_KERNEL); | ||
127 | if (!buf->area) | ||
128 | return -ENOMEM; | ||
129 | buf->bytes = size; | ||
130 | |||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | static u64 mxs_pcm_dmamask = DMA_BIT_MASK(32); | ||
135 | static int mxs_pcm_new(struct snd_soc_pcm_runtime *rtd) | ||
136 | { | ||
137 | struct snd_card *card = rtd->card->snd_card; | ||
138 | struct snd_pcm *pcm = rtd->pcm; | ||
139 | int ret = 0; | ||
140 | |||
141 | if (!card->dev->dma_mask) | ||
142 | card->dev->dma_mask = &mxs_pcm_dmamask; | ||
143 | if (!card->dev->coherent_dma_mask) | ||
144 | card->dev->coherent_dma_mask = DMA_BIT_MASK(32); | ||
145 | |||
146 | if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { | ||
147 | ret = mxs_pcm_preallocate_dma_buffer(pcm, | ||
148 | SNDRV_PCM_STREAM_PLAYBACK); | ||
149 | if (ret) | ||
150 | goto out; | ||
151 | } | ||
152 | |||
153 | if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { | ||
154 | ret = mxs_pcm_preallocate_dma_buffer(pcm, | ||
155 | SNDRV_PCM_STREAM_CAPTURE); | ||
156 | if (ret) | ||
157 | goto out; | ||
158 | } | ||
159 | |||
160 | out: | ||
161 | return ret; | ||
162 | } | ||
163 | |||
164 | static void mxs_pcm_free(struct snd_pcm *pcm) | ||
165 | { | ||
166 | struct snd_pcm_substream *substream; | ||
167 | struct snd_dma_buffer *buf; | ||
168 | int stream; | ||
169 | |||
170 | for (stream = 0; stream < 2; stream++) { | ||
171 | substream = pcm->streams[stream].substream; | ||
172 | if (!substream) | ||
173 | continue; | ||
174 | |||
175 | buf = &substream->dma_buffer; | ||
176 | if (!buf->area) | ||
177 | continue; | ||
178 | |||
179 | dma_free_writecombine(pcm->card->dev, buf->bytes, | ||
180 | buf->area, buf->addr); | ||
181 | buf->area = NULL; | ||
182 | } | ||
183 | } | ||
184 | |||
185 | static struct snd_soc_platform_driver mxs_soc_platform = { | ||
186 | .ops = &mxs_pcm_ops, | ||
187 | .pcm_new = mxs_pcm_new, | ||
188 | .pcm_free = mxs_pcm_free, | ||
189 | }; | 71 | }; |
190 | 72 | ||
191 | int mxs_pcm_platform_register(struct device *dev) | 73 | int mxs_pcm_platform_register(struct device *dev) |
192 | { | 74 | { |
193 | return snd_soc_register_platform(dev, &mxs_soc_platform); | 75 | return snd_dmaengine_pcm_register(dev, &mxs_dmaengine_pcm_config, |
76 | SND_DMAENGINE_PCM_FLAG_NO_RESIDUE | | ||
77 | SND_DMAENGINE_PCM_FLAG_NO_DT | | ||
78 | SND_DMAENGINE_PCM_FLAG_COMPAT | | ||
79 | SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX); | ||
194 | } | 80 | } |
195 | EXPORT_SYMBOL_GPL(mxs_pcm_platform_register); | 81 | EXPORT_SYMBOL_GPL(mxs_pcm_platform_register); |
196 | 82 | ||
197 | void mxs_pcm_platform_unregister(struct device *dev) | 83 | void mxs_pcm_platform_unregister(struct device *dev) |
198 | { | 84 | { |
199 | snd_soc_unregister_platform(dev); | 85 | snd_dmaengine_pcm_unregister(dev); |
200 | } | 86 | } |
201 | EXPORT_SYMBOL_GPL(mxs_pcm_platform_unregister); | 87 | EXPORT_SYMBOL_GPL(mxs_pcm_platform_unregister); |
202 | 88 | ||