diff options
author | Takashi Iwai <tiwai@suse.de> | 2013-04-25 07:02:35 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2013-04-25 07:02:35 -0400 |
commit | 2fc565e4eaf8fc633bfc741b90e1f28dba732ee1 (patch) | |
tree | 98c994692f84aee07cf1c7b4cda245ae5235a94d /sound/soc/soc-generic-dmaengine-pcm.c | |
parent | 7fc7d047216aa4923d401c637be2ebc6e3d5bd9b (diff) | |
parent | 5cc50fc858a5ab37dc2744d72d7ffed96f23afd8 (diff) |
Merge tag 'asoc-v3.10-3' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-next
ASoC: More updates for v3.10
A few more fixes, nothing too major though the DMA changes fix modular
builds.
Diffstat (limited to 'sound/soc/soc-generic-dmaengine-pcm.c')
-rw-r--r-- | sound/soc/soc-generic-dmaengine-pcm.c | 44 |
1 files changed, 30 insertions, 14 deletions
diff --git a/sound/soc/soc-generic-dmaengine-pcm.c b/sound/soc/soc-generic-dmaengine-pcm.c index ae0c37e66ae0..e29ec3cd84b1 100644 --- a/sound/soc/soc-generic-dmaengine-pcm.c +++ b/sound/soc/soc-generic-dmaengine-pcm.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <sound/soc.h> | 21 | #include <sound/soc.h> |
22 | #include <linux/dma-mapping.h> | 22 | #include <linux/dma-mapping.h> |
23 | #include <linux/of.h> | 23 | #include <linux/of.h> |
24 | #include <linux/of_dma.h> | ||
25 | 24 | ||
26 | #include <sound/dmaengine_pcm.h> | 25 | #include <sound/dmaengine_pcm.h> |
27 | 26 | ||
@@ -29,7 +28,7 @@ struct dmaengine_pcm { | |||
29 | struct dma_chan *chan[SNDRV_PCM_STREAM_CAPTURE + 1]; | 28 | struct dma_chan *chan[SNDRV_PCM_STREAM_CAPTURE + 1]; |
30 | const struct snd_dmaengine_pcm_config *config; | 29 | const struct snd_dmaengine_pcm_config *config; |
31 | struct snd_soc_platform platform; | 30 | struct snd_soc_platform platform; |
32 | bool compat; | 31 | unsigned int flags; |
33 | }; | 32 | }; |
34 | 33 | ||
35 | static struct dmaengine_pcm *soc_platform_to_pcm(struct snd_soc_platform *p) | 34 | static struct dmaengine_pcm *soc_platform_to_pcm(struct snd_soc_platform *p) |
@@ -128,6 +127,9 @@ static struct dma_chan *dmaengine_pcm_compat_request_channel( | |||
128 | { | 127 | { |
129 | struct dmaengine_pcm *pcm = soc_platform_to_pcm(rtd->platform); | 128 | struct dmaengine_pcm *pcm = soc_platform_to_pcm(rtd->platform); |
130 | 129 | ||
130 | if ((pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX) && pcm->chan[0]) | ||
131 | return pcm->chan[0]; | ||
132 | |||
131 | if (pcm->config->compat_request_channel) | 133 | if (pcm->config->compat_request_channel) |
132 | return pcm->config->compat_request_channel(rtd, substream); | 134 | return pcm->config->compat_request_channel(rtd, substream); |
133 | 135 | ||
@@ -148,7 +150,7 @@ static int dmaengine_pcm_new(struct snd_soc_pcm_runtime *rtd) | |||
148 | if (!substream) | 150 | if (!substream) |
149 | continue; | 151 | continue; |
150 | 152 | ||
151 | if (!pcm->chan[i] && pcm->compat) { | 153 | if (!pcm->chan[i] && (pcm->flags & SND_DMAENGINE_PCM_FLAG_COMPAT)) { |
152 | pcm->chan[i] = dmaengine_pcm_compat_request_channel(rtd, | 154 | pcm->chan[i] = dmaengine_pcm_compat_request_channel(rtd, |
153 | substream); | 155 | substream); |
154 | } | 156 | } |
@@ -215,6 +217,25 @@ static const char * const dmaengine_pcm_dma_channel_names[] = { | |||
215 | [SNDRV_PCM_STREAM_CAPTURE] = "rx", | 217 | [SNDRV_PCM_STREAM_CAPTURE] = "rx", |
216 | }; | 218 | }; |
217 | 219 | ||
220 | static void dmaengine_pcm_request_chan_of(struct dmaengine_pcm *pcm, | ||
221 | struct device *dev) | ||
222 | { | ||
223 | unsigned int i; | ||
224 | |||
225 | if ((pcm->flags & SND_DMAENGINE_PCM_FLAG_NO_DT) || !dev->of_node) | ||
226 | return; | ||
227 | |||
228 | if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX) { | ||
229 | pcm->chan[0] = dma_request_slave_channel(dev, "rx-tx"); | ||
230 | pcm->chan[1] = pcm->chan[0]; | ||
231 | } else { | ||
232 | for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_CAPTURE; i++) { | ||
233 | pcm->chan[i] = dma_request_slave_channel(dev, | ||
234 | dmaengine_pcm_dma_channel_names[i]); | ||
235 | } | ||
236 | } | ||
237 | } | ||
238 | |||
218 | /** | 239 | /** |
219 | * snd_dmaengine_pcm_register - Register a dmaengine based PCM device | 240 | * snd_dmaengine_pcm_register - Register a dmaengine based PCM device |
220 | * @dev: The parent device for the PCM device | 241 | * @dev: The parent device for the PCM device |
@@ -225,23 +246,15 @@ int snd_dmaengine_pcm_register(struct device *dev, | |||
225 | const struct snd_dmaengine_pcm_config *config, unsigned int flags) | 246 | const struct snd_dmaengine_pcm_config *config, unsigned int flags) |
226 | { | 247 | { |
227 | struct dmaengine_pcm *pcm; | 248 | struct dmaengine_pcm *pcm; |
228 | unsigned int i; | ||
229 | 249 | ||
230 | pcm = kzalloc(sizeof(*pcm), GFP_KERNEL); | 250 | pcm = kzalloc(sizeof(*pcm), GFP_KERNEL); |
231 | if (!pcm) | 251 | if (!pcm) |
232 | return -ENOMEM; | 252 | return -ENOMEM; |
233 | 253 | ||
234 | pcm->config = config; | 254 | pcm->config = config; |
255 | pcm->flags = flags; | ||
235 | 256 | ||
236 | if (flags & SND_DMAENGINE_PCM_FLAG_COMPAT) | 257 | dmaengine_pcm_request_chan_of(pcm, dev); |
237 | pcm->compat = true; | ||
238 | |||
239 | if (!(flags & SND_DMAENGINE_PCM_FLAG_NO_DT) && dev->of_node) { | ||
240 | for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_CAPTURE; i++) { | ||
241 | pcm->chan[i] = of_dma_request_slave_channel(dev->of_node, | ||
242 | dmaengine_pcm_dma_channel_names[i]); | ||
243 | } | ||
244 | } | ||
245 | 258 | ||
246 | if (flags & SND_DMAENGINE_PCM_FLAG_NO_RESIDUE) | 259 | if (flags & SND_DMAENGINE_PCM_FLAG_NO_RESIDUE) |
247 | return snd_soc_add_platform(dev, &pcm->platform, | 260 | return snd_soc_add_platform(dev, &pcm->platform, |
@@ -272,8 +285,11 @@ void snd_dmaengine_pcm_unregister(struct device *dev) | |||
272 | pcm = soc_platform_to_pcm(platform); | 285 | pcm = soc_platform_to_pcm(platform); |
273 | 286 | ||
274 | for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_CAPTURE; i++) { | 287 | for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_CAPTURE; i++) { |
275 | if (pcm->chan[i]) | 288 | if (pcm->chan[i]) { |
276 | dma_release_channel(pcm->chan[i]); | 289 | dma_release_channel(pcm->chan[i]); |
290 | if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX) | ||
291 | break; | ||
292 | } | ||
277 | } | 293 | } |
278 | 294 | ||
279 | snd_soc_remove_platform(platform); | 295 | snd_soc_remove_platform(platform); |